| @ -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. | |||||
|  | |||||
| ## 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 | |||||
| ``` | |||||