Electrónica y Programación en Personal
«Si no se soluciona con un script en Python entonces no es viable»

por Yeison Cardona el 17 de septiembre de 2012 a las 18:30 UTC

Actualizaciones:
21/Septiembre/2012: Se modifica el código para 8bits, al parecer CDC y Serial no son compatibles en esta arquitectura.




La idea es sencilla, consiste en modificar este código para que «obedezca» a comandos enviados por un módulo de radiofrecuencia, es decir, controlar en tiempo real los estados de los pines de un Pinguino a distancia.


Primera parte:
Esta primera entrega está enfocada a la comunicación unidireccional (por el momento sólo tengo un módulo RF), un Pinguino envía el comando y otro Pinguino interpreta el comando.

Como siempre no se trata de un tutorial de «cómo usar un módulo RF con Pinguino», es mas bien un ejemplo práctico de su uso con Pinguino, si quieren un poco de ayuda con RF este documento es todo lo que necesitan.

Pinguino Receptor
Del lado del receptor el código no cambia mucho al original, incluso se hace mas corto.

Para arquitecturas de 8-bit.
/*-----------------------------------------------------
Author:  Yeison Cardona --
First release: 17/09/2012
Last release: 17/09/2012
Description: Control de la tarjeta pinguino mediante
comandos transparentes enviados por RF.
-----------------------------------------------------*/

#include 
#include 
#define TotalPines 17
 
char lectura[21], *bloque;
int par1, valor, cont, i;
 
void setup() {
    Serial.begin(2400);
 }
   
void loop() {

strcpy(lectura, Serial.getString());
cont=0;
 
if (strncmp(lectura, "pinMode", 7)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ",") ){ 
 switch (cont){
 case 0: break;
 case 1:
  par1=atoi(bloque);
  break;
 case 2:
  if (strncmp(bloque, "INPUT", 5)==0) pinMode(par1,INPUT);
  else if (strncmp(bloque, "OUTPUT", 6)==0) pinMode(par1,OUTPUT);
  break;
 } 
 cont+=1;
 }
}
 
else if (strncmp(lectura, "digitalWrite", 12)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ",") ){
 switch (cont){
 case 0: break;
 case 1:
  par1=atoi(bloque);
  break;
 case 2:
  if (strncmp(bloque, "HIGH", 4)==0) digitalWrite(par1,HIGH);
  else if (strncmp(bloque, "LOW", 3)==0) digitalWrite(par1,LOW);
  break;
 } 
 cont+=1;
 }
}
 
else if (strncmp(lectura, "analogWrite", 11)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ",") ){
 switch (cont){
 case 0: break;
 case 1:
  par1=atoi(bloque);
  break;
 case 2:
  analogWrite(par1,atoi(bloque));
  break;
 } 
 cont+=1;
 }
}
 
else if (strncmp(lectura, "digitalRead", 11)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ")") ){
 switch (cont){
 case 0: break;
 case 1:
  //CDC.printf("%d\n",digitalRead(atoi(bloque)));
  break;
 } 
 cont+=1;
 }
}
 
else if (strncmp(lectura, "analogRead", 10)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ")") ){
 switch (cont){
 case 0: break;
 case 1:
  //CDC.printf("%d\n",analogRead(atoi(bloque)));
  break;
 } 
 cont+=1;
 }
}

else if (strncmp(lectura, "eepromRead", 10)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ")") ){
 switch (cont){
 case 0: break;
 case 1:
  //CDC.printf("%d\n",EEPROM.read(atoi(bloque)));
  break;
 } 
 cont+=1;
 }
}

else if (strncmp(lectura, "eepromWrite", 11)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ",") ){
 switch (cont){
 case 0: break;
 case 1:
  par1=atoi(bloque);
  break;
 case 2:
  bloque = strtok(bloque,")");
  EEPROM.write(par1, atoi(bloque));
  break;
 } 
 cont+=1;
 }
}

else if (strncmp(lectura, "delay", 5)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ")") ){
 switch (cont){
 case 0: break;
 case 1:
  delay(atoi(bloque));
  break;
 } 
 cont+=1;
 }
}
  
else if (strncmp(lectura, "delayMicroseconds", 17)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ")") ){
 switch (cont){
 case 0: break;
 case 1:
  delayMicroseconds(atoi(bloque));
  //CDC.printf("Done\n");
  break;
 } 
 cont+=1;
 }
}
  
else if (strcmp(lectura, "allOutput")==0){
 for (i=0;i<=TotalPines;i++){
  pinMode(i,OUTPUT);
  digitalWrite(i,LOW);
 }
}

else if (strcmp(lectura, "allInput")==0){
 for (i=0;i<=TotalPines;i++)
  pinMode(i,INPUT);
}

else if (strcmp(lectura, "allHigh")==0){
 for (i=0;i<=TotalPines;i++){
  pinMode(i,OUTPUT);
  digitalWrite(i,HIGH);
 }
}

else if (strcmp(lectura, "allLow")==0){
 for (i=0;i<=TotalPines;i++){
  pinMode(i,OUTPUT);
  digitalWrite(i,LOW);
 }
}
  
else if (strcmp(lectura, "reset")==0)
 reset();
  
}
Para arquitecturas de 32-bit:
/*-----------------------------------------------------
Author:  Yeison Cardona --
First release: 17/09/2012
Last release: 17/09/2012
Description: Control de la tarjeta pinguino mediante
comandos transparentes enviados por RF.
-----------------------------------------------------*/
 
char lectura[21], *bloque;
int par1, valor, cont, i;
 
#include 
#include 
#define TotalPines 21
 
void setup() {
    Serial.begin(2400);
 }
   
void loop() {

strcpy(lectura, Serial.getString());
cont=0;
 
if (strncmp(lectura, "pinMode", 7)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ",") ){ 
 switch (cont){
 case 0: break;
 case 1:
  par1=atoi(bloque);
  break;
 case 2:
  if (strncmp(bloque, "INPUT", 5)==0) pinMode(par1,INPUT);
  else if (strncmp(bloque, "OUTPUT", 6)==0) pinMode(par1,OUTPUT);
  break;
 } 
 cont+=1;
 }
}
 
else if (strncmp(lectura, "digitalWrite", 12)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ",") ){
 switch (cont){
 case 0: break;
 case 1:
  par1=atoi(bloque);
  break;
 case 2:
  if (strncmp(bloque, "HIGH", 4)==0) digitalWrite(par1,HIGH);
  else if (strncmp(bloque, "LOW", 3)==0) digitalWrite(par1,LOW);
  break;
 } 
 cont+=1;
 }
}
 
else if (strncmp(lectura, "analogWrite", 11)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ",") ){
 switch (cont){
 case 0: break;
 case 1:
  par1=atoi(bloque);
  break;
 case 2:
  analogWrite(par1,atoi(bloque));
  break;
 } 
 cont+=1;
 }
}
 
else if (strncmp(lectura, "digitalRead", 11)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ")") ){
 switch (cont){
 case 0: break;
 case 1:
  CDC.printf("%d\n",digitalRead(atoi(bloque)));
  break;
 } 
 cont+=1;
 }
}
 
else if (strncmp(lectura, "analogRead", 10)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ")") ){
 switch (cont){
 case 0: break;
 case 1:
  CDC.printf("%d\n",analogRead(atoi(bloque)));
  break;
 } 
 cont+=1;
 }
}

else if (strncmp(lectura, "delay", 5)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ")") ){
 switch (cont){
 case 0: break;
 case 1:
  delay(atoi(bloque));
  break;
 } 
 cont+=1;
 }
}
  
else if (strncmp(lectura, "delayMicroseconds", 17)==0){
 for (bloque = strtok(lectura,"("); bloque != NULL; bloque = strtok(NULL, ")") ){
 switch (cont){
 case 0: break;
 case 1:
  delayMicroseconds(atoi(bloque));
  CDC.printf("Done\n");
  break;
 } 
 cont+=1;
 }
}
  
else if (strcmp(lectura, "allOutput")==0){
 for (i=0;i<=TotalPines;i++){
  pinMode(i,OUTPUT);
  digitalWrite(i,LOW);
 }
}

else if (strcmp(lectura, "allInput")==0){
 for (i=0;i<=TotalPines;i++)
  pinMode(i,INPUT);
}

else if (strcmp(lectura, "allHigh")==0){
 for (i=0;i<=TotalPines;i++){
  pinMode(i,OUTPUT);
  digitalWrite(i,HIGH);
 }
}

else if (strcmp(lectura, "allLow")==0){
 for (i=0;i<=TotalPines;i++){
  pinMode(i,OUTPUT);
  digitalWrite(i,LOW);
 }
}
}
Es importante saber que se debe de conectar el el pin de DATA del módulo al pin RX de Pinguino. Pinguino Emisor Del lado del Pinguino emisor es donde enviaremos los comando para que sean interpretados por la otra tarjeta, ahora se deberá conectar el pin de DATA del emisor al pin TX de Pinguino.
/*-----------------------------------------------------
Author:  Yeison Cardona --
First release: 17/09/2012
Last release: 17/09/2012
Description: Control de la tarjeta pinguino mediante
comandos transparentes enviados por RF.
-----------------------------------------------------*/

void setup() {
    Serial.begin(2400);
    Serial.println("pinMode(13,OUTPUT)");
    Serial.println("pinMode(30,OUTPUT)");
    }

void loop() {
    Serial.println("digitalWrite(13,HIGH)");
    delay(100);
    Serial.println("digitalWrite(30,HIGH)");
    delay(100);
    Serial.println("digitalWrite(13,LOW)");
    delay(100);
    Serial.println("digitalWrite(30,LOW)");
    delay(100);
    }
Bastante fácil, ¿no?

NOTA:
Usar cualquier módulo de radiofrecuencia es muy simple desde Pinguino ya que se hace uso de la biblioteca Serial y de todas las funciones que allí se implementan (print, println, write, getString, read...), y ahora, ¿que se les ocurre que se pueda hacer?, yo por mi parte ya estoy pensando en un mundo de cosas sobre domótica :)

También podría interesarte:

Comentarios:
Pablo Antúnez dijo:
jun. 22, 2013, 5:19 p.m.
Buenas yeison. Te pido un poco de ayuda, pues tengo esos módulos de RF, tengo 2 pinguinos 18F2550 y nada de nada. He probado varios ejemplos, los más sencillos: Transmisor: void setup() { Serial.begin(9600); } void loop() { Serial.print("0"); delay(2000); Serial.print("1"); delay(2000); } Receptor: void setup() { pinMode(7,OUTPUT); //Led en pin 7 Serial.begin(9600); // He probado 2400 también } void loop() { if (Serial.available()) { if (Serial.read()=='0') digitalWrite(7,LOW); if (Serial.read()=='1') digitalWrite(7,HIGH); } }
Responder a Pablo Antúnez
Respuesta de Yeison Cardona:
jun. 26, 2013, 5:39 p.m.
Estas enviando una cadena "0" y leyendo un caracter '0'

usa Serial.write('0') para enviar un caracter. También quita los módulos y usa un par de cables para conectar los tx y rx (invertidos, no olvidar la tierra común) cuando funcione de ésta manera, añade los modulos rf.
Responder a Yeison Cardona
Respuesta de Pablo :
jun. 27, 2013, 12:23 a.m.
Gracias por tu respuesta Yeison. La verdad es que me ha ayudado bastante. Supongo que deben ser los módulos RF. Si comunico Pinguino_1_TX con Pinguino_2_RX a través de dos cables y GND común, el programa funciona, pero si le añado los módulos se comporta como quiere. Puedo intentar comprar otros nuevos (tu los comprastes por ebay?), o bien soldar éstos en lugar de usar placa board. También puedo soldarle unas antenas, pero no creía que fuera necesario ya que están pegados. De nuevo mi más sincero agradecimiento. Pablo ¿Qué te parece?
Responder a Pablo
luis morales dijo:
jun. 29, 2013, 4:04 p.m.
Este tema me encanta fui radio aficionado por muchos años hasta que en medellin empezaron a tumbar las casas para hacer edificios allí no cave una antena. conectar un micro con el mundo real es el camino para hacerlo mas inteligente.
Responder a luis morales
jxmpodhod dijo:
dic. 8, 2013, 8:04 p.m.
YlfKxm tmhncfqgjuep, [url=http://ieeybsenkltv.com/]ieeybsenkltv[/url], [link=http://egnpyujfvyzr.com/]egnpyujfvyzr[/link], http://fbslowkrbawt.com/
Responder a jxmpodhod
xtqtsfh dijo:
dic. 10, 2013, 3:23 a.m.
8y6kQP uvepzognrleh, [url=http://zeyybujqltne.com/]zeyybujqltne[/url], [link=http://efdrlzcythga.com/]efdrlzcythga[/link], http://cqxhqdlufwga.com/
Responder a xtqtsfh
Añadir un nuevo comentario:
Si desean una respuesta para su comentario sólo deben agregarme en G+ y hacer una mención a Yeison Cardona, así les podré responder lo antes posible.