|
|
@ -0,0 +1,183 @@ |
|
|
|
# Control de LED de usuario por medio de script en C++ |
|
|
|
|
|
|
|
El objetivo de este script en lenguaje C++ es controlar uno de los LED's de usuario |
|
|
|
integrados en la BeagleBone Black por medio de los registros del sistema. |
|
|
|
|
|
|
|
![BeagleBone Black y sus LED's de usuario](bbled.png) |
|
|
|
|
|
|
|
|
|
|
|
## Header |
|
|
|
### Librerías |
|
|
|
En el encabezado **led.h** se importan las librerías necesarias para |
|
|
|
realizar las operaciones de entrada y salida en la terminal de la Beaglebone, manejo de archivos, |
|
|
|
así como otras operaciones estandar y el manejo de strings. |
|
|
|
|
|
|
|
```cpp |
|
|
|
#ifndef LED_H |
|
|
|
#define LED_H |
|
|
|
#include<iostream> |
|
|
|
#include<fstream> |
|
|
|
#include<string> |
|
|
|
#include<sstream> |
|
|
|
``` |
|
|
|
### Clases |
|
|
|
Se define la clase CLED que se usará en el main para nuestro objeto LED, junto |
|
|
|
con su destructor de clase y todos sus métodos. |
|
|
|
|
|
|
|
```cpp |
|
|
|
class CLED{ |
|
|
|
private: |
|
|
|
std::string path; |
|
|
|
int ledNumber; |
|
|
|
virtual void WriteLED(std::string filename, std::string value); |
|
|
|
virtual void RemoveTrigger(); |
|
|
|
public: |
|
|
|
CLED(int ledNumber); //class creator |
|
|
|
virtual ~CLED(); //class deconstructor |
|
|
|
virtual void TurnOn(); |
|
|
|
virtual void TurnOff(); |
|
|
|
virtual void BlinkLED(); |
|
|
|
}; |
|
|
|
|
|
|
|
#endif |
|
|
|
``` |
|
|
|
|
|
|
|
## Métodos |
|
|
|
En **led.cpp** se desarrollan los métodos definidos en el encabezado, primero |
|
|
|
se establece la dirección de los registros de los LED de usuario. |
|
|
|
|
|
|
|
```cpp |
|
|
|
#define LED_PATH "/sys/class/leds/beaglebone:green:usr" |
|
|
|
|
|
|
|
``` |
|
|
|
|
|
|
|
**CLED:** Es el creador de la clase y de nuestro objeto, nos entrega la dirección |
|
|
|
del LED de usuario que escojamos. |
|
|
|
|
|
|
|
```cpp |
|
|
|
CLED::CLED(int ledNumber){ |
|
|
|
this->ledNumber = ledNumber; //Solo para argumentos que sean numeros |
|
|
|
std::ostringstream s; |
|
|
|
s << LED_PATH << ledNumber; |
|
|
|
path =std::string(s.str()); //convert to string |
|
|
|
} |
|
|
|
``` |
|
|
|
**WriteLED:** Es el método que modifica los registros de nuestro LED. |
|
|
|
|
|
|
|
```cpp |
|
|
|
void CLED::WriteLED(std::string filename, std::string value){ |
|
|
|
std::ofstream fs; |
|
|
|
fs.open((path+filename).c_str()); |
|
|
|
fs << value; |
|
|
|
fs.close(); |
|
|
|
} |
|
|
|
``` |
|
|
|
**RemoveTrigger:** Método que desactiva el trigger. |
|
|
|
|
|
|
|
|
|
|
|
```cpp |
|
|
|
void CLED::RemoveTrigger(){ |
|
|
|
WriteLED("/trigger", "none"); |
|
|
|
} |
|
|
|
``` |
|
|
|
|
|
|
|
Los métodos **TurnOn** y **TurnOff** desactivan el trigger con RemoveTrigger, y |
|
|
|
con WriteLED cambian el registro *brightness* para encender o apagar el LED. |
|
|
|
**BlinkLED** solo utiliza WriteLED para cambiar el trigger a *timer* y |
|
|
|
así modificar los registros *delay_on* y *delay_off* para cambiar los tiempos de |
|
|
|
encendido y apagado. |
|
|
|
|
|
|
|
```cpp |
|
|
|
void CLED::TurnOn(){ |
|
|
|
std::cout << "LED Turn On: " << ledNumber << " on" << std::endl; |
|
|
|
RemoveTrigger(); |
|
|
|
WriteLED("/brightness", "1"); |
|
|
|
} |
|
|
|
|
|
|
|
void CLED::TurnOff(){ |
|
|
|
std::cout << "LED Turn Off: " << ledNumber << " off" << std::endl; |
|
|
|
RemoveTrigger(); |
|
|
|
WriteLED("/brightness", "0"); |
|
|
|
} |
|
|
|
|
|
|
|
void CLED::BlinkLED(){ |
|
|
|
std::cout << "LED blinking: " << ledNumber << " blinking" << std::endl; |
|
|
|
WriteLED("/trigger", "timer"); |
|
|
|
WriteLED("/delay_on", "50"); |
|
|
|
WriteLED("/delay_off", "50"); |
|
|
|
} |
|
|
|
``` |
|
|
|
|
|
|
|
Por último, el destructor de clase. |
|
|
|
```cpp |
|
|
|
CLED::~CLED(){ |
|
|
|
std::cout << "destroying LED " << path << std::endl; |
|
|
|
} |
|
|
|
``` |
|
|
|
|
|
|
|
## Main |
|
|
|
|
|
|
|
En **main.cpp** se incluye nuestro encabezado, y se utilizan los argumentos |
|
|
|
*argc* y *argv* para conocer lo que se ingresa en la terminal. Argc nos indicará |
|
|
|
si el número de argumentos es correcto. |
|
|
|
|
|
|
|
Se utiliza un ciclo if para seleccionar la acción del LED, comparando el valor |
|
|
|
de argumento en la terminal con unos comandos definidos: ***on***, ***off*** |
|
|
|
y ***blink***. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```cpp |
|
|
|
#include"led.h" |
|
|
|
#include<string> |
|
|
|
using namespace std; |
|
|
|
|
|
|
|
int main(int argc, char* argv[]){ |
|
|
|
CLED led1 = CLED(3); |
|
|
|
string cmd(argv[1]); |
|
|
|
|
|
|
|
if(argc!=2) |
|
|
|
std::cout << "Incorrect number of arguments" << std::endl; |
|
|
|
|
|
|
|
if(cmd=="on") |
|
|
|
led1.TurnOn(); |
|
|
|
|
|
|
|
else if(cmd=="off") |
|
|
|
led1.TurnOff(); |
|
|
|
|
|
|
|
else if(cmd=="blink") |
|
|
|
led1.BlinkLED(); |
|
|
|
|
|
|
|
else |
|
|
|
cout << "Invalid command" << endl; |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
``` |
|
|
|
|
|
|
|
## Ejecución |
|
|
|
|
|
|
|
Se creó un archivo makefile para compilar, eliminar archivos |
|
|
|
antiguos de salida y para hacer un debug. |
|
|
|
```console |
|
|
|
all: |
|
|
|
g++ main.cpp -o led led.cpp |
|
|
|
|
|
|
|
clean: |
|
|
|
rm led |
|
|
|
|
|
|
|
debug: |
|
|
|
g++ -g main.cpp -o led led.cpp |
|
|
|
|
|
|
|
``` |
|
|
|
|
|
|
|
Se cambian los permisos de nuestro ejecutable. |
|
|
|
``` |
|
|
|
sudo chmod u+x led |
|
|
|
``` |
|
|
|
|
|
|
|
Y se ejecuta con cualquiera de los argumentos mencionados anteriormente. |
|
|
|
|
|
|
|
``` |
|
|
|
./led blink |
|
|
|
``` |