Tecnologia vestible

Per començar Elements d'entrada Programació CircuitPython   Recursos CITCEA
Elements no electrònics Elements de sortida Programació Arduino    
Projectes Elements de control Dades pràctiques   Inici

Comunicació mitjançant raigs infraroigs

La placa Circuit Playground Express incorpora un emissor i un receptor d'infraroigs que ens permeten comunicar dues plaques entre elles o un comandament a distància i una placa. La biblioteca Adafruit_CircuitPlayground.h incorpora la possibilitat de codificar i descodificar els missatges.

Atès que ja fem servir la biblioteca Adafruit_CircuitPlayground.h, hem aprofitat algunes de les facilitats que incorpora. Per exemple, ens estalviem de definir l'interruptor com a entrada o de crear un objecte per als NeoPixels. D'aquesta manera el programa queda més senzill. Existeix, però, la possibilitat de prescindir d'aquesta biblioteca i definir els elements en la forma habitual.

Cada protocol (segons el fabricant) té les seves característiques. Hi sol haver un inici de transmissió, una adreça (que identifica el fabricant) i unes dades (la comanda que s'envia). En aquesta pàgina de San Bergmans hi podeu trobar una descripció de la codificació NEC. En aquesta codificació s'envia una adreça de dos bytes i unes dades de dos bytes. Els dos bytes de dades són complementaris (la seva suma és 0xFF, o sigui 255). En la codificació original els dos bytes d'adreça també eren complementaris però en la codificació extesa ja no ho són (per donar espai a més fabricants).

Recepció de missatges

El següent programa ens permet veure el codi rebut. Podem posar el programa a la nostra placa, apuntar-hi el comandament, prémer una tecla i veure el codi que s'ha rebut.

#include <Adafruit_CircuitPlayground.h>
#if !defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS)
  // No serveix per a plaques Circuit Playground Classic
  #error "Només disponible a la placa Circuit Playground Express"
#endif
void setup() {
  CircuitPlayground.begin();
  Serial.begin(9600);
  while (!Serial); // Esperem tenir el canal sèrie obert
  CircuitPlayground.irReceiver.enableIRIn(); // Obrim la recepció
  Serial.println("Prem una tecla del comandament");
}
void loop() {
  bool mostra = CircuitPlayground.slideSwitch();
  if (CircuitPlayground.irReceiver.getResults()) {  // S'ha rebut un codi?
    CircuitPlayground.irDecoder.decode();           // Descodifiquem
    Serial.print("Codi rebut: ");
    Serial.println(CircuitPlayground.irDecoder.value, HEX);
    CircuitPlayground.irDecoder.dumpResults(mostra);  // Mostrem el que s'ha rebut
                                                      // L'interruptor controla el detall
    CircuitPlayground.irReceiver.enableIRIn();      // Tornem a obrir la recepció
  }
}

Fent servir el botó de decrementar el canal d'un comandament de televisor que m'han deixat he obtingut el següent:

Codi rebut: E0E048B7
Decoded NECx(7): Value:E0E048B7 Adrs:0 (32 bits)

La primera línia (que correspon a la instrucció CircuitPlayground.irDecoder.value) és el codi rebut sense més detalls. En el proper programa aquest codi ens permetrà fer coses. La segona línia (que correspon a la instrucció CircuitPlayground.irDecoder.dumpResults) ens dóna una mica més de detall. Si ens mirem el codi rebut, podem observar quatre bytes hexadecimals: E0 E0 08 F7 on els bytes d'adreça són iguals (casualment aquest fabricant té aquesta adreça) i els de dades són complementaris: 08 + F7 = FF.

Si l'interruptor de la placa està activat el programa demana al descodificador que doni un informe complet del senyal rebut. Prement la tecla d'incrementar el canal del mateix comandament he obtingut el següent:

Codi rebut: E0E048B7
Decoded NECx(7): Value:E0E048B7 Adrs:0 (32 bits) 
Raw samples(68): Gap:56220
  Head: m4495  s4561
0:m517 s1733       1:m515 s1736       2:m512 s1738       3:m520 s612               
4:m512 s607        5:m517 s609        6:m515 s610        7:m514 s612               
8:m512 s1738       9:m520 s1735       10:m513 s1733      11:m515 s611               
12:m513 s612       13:m512 s614       14:m520 s605       15:m519 s607               
16:m517 s609       17:m515 s1735      18:m513 s612       19:m512 s613               
20:m521 s1730      21:m518 s607       22:m517 s609       23:m515 s610               
24:m514 s1737      25:m511 s614       26:m520 s1730      27:m518 s1732               
28:m516 s610       29:m514 s1736      30:m512 s1738      31:m519 s1731               
32:m517
Extent=61336
Mark  min:511	 max:521
Space min:605	 max:1738

Veiem que hem rebut 68 semipolsos. La capçalera (que identifica al fabricant) té un primer semipols (mark) de 4495 microsegons i un segon semipols (space) de 4561 que s'assemblen als valors que corresponen a aquest fabricant (4500 i 4500). A continuació tenim els polsos que corresponen al codi. Mirem, per exemple, el primer (pols 0) i veiem uns valors de 517 i 1733 que es corresponen amb els valors teòrics d'un u (560 i 1690). El quart pols (pols 3) te uns valors de 520 i 612 que es corresponen amb un zero (560 i 560). Al final tenim només un semipols (pols 32) que és el final del missatge, veiem 517 que s'assembla al 560 que correspon a aquest fabricant. No és normal obtenir els valors exactes però el protocol és força robust i això permet fer servir marges del 20 o 25 % sobre els valors teòrics. Veiem que ens dóna alguna dada més, com els valors màxims i mínims dels semipolsos.

Agafem altre cop els valors rebuts:

  Head: m4495  s4561
0:m517 s1733       1:m515 s1736       2:m512 s1738       3:m520 s612               
4:m512 s607        5:m517 s609        6:m515 s610        7:m514 s612               
8:m512 s1738       9:m520 s1735       10:m513 s1733      11:m515 s611               
12:m513 s612       13:m512 s614       14:m520 s605       15:m519 s607               
16:m517 s609       17:m515 s1735      18:m513 s612       19:m512 s613               
20:m521 s1730      21:m518 s607       22:m517 s609       23:m515 s610               
24:m514 s1737      25:m511 s614       26:m520 s1730      27:m518 s1732               
28:m516 s610       29:m514 s1736      30:m512 s1738      31:m519 s1731               
32:m517

Els valors marcats en verd corresponen a la capçalera i el final, els marcats en groc corresponen a uns i els que estan en blanc seran els zeros. A continuació hem escrit els bits que corresponen, a cada parella de valors. N'hem posat vuit a cada filera, que es correspondran a un byte. Al costat hem escrit, en hexadecimal, els valors d'aquests quatre bytes.

 H
 1 1 1 0 0 0 0 0		E0
 1 1 1 0 0 0 0 0		E0
 0 1 0 0 1 0 0 0		48
 1 0 1 1 0 1 1 1		B7
 T

que, com era d'esperar, es correspon al codi rebut.

Podem fer que el nostre comandament ens serveixi per a activar alguna funció de la nostra placa Circuit Playground Express. Per exemple, en el programa següent anem a fer que la tecla d'incrementar el canal ens encenqui els NeoPixels de color verd i la de decrementar els encengui de color vermell. Els LED s'apagaran passat mig segon.

#include <Adafruit_CircuitPlayground.h>
#if !defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS)
  // No serveix per a plaques Circuit Playground Classic
  #error "Només disponible a la placa Circuit Playground Express"
#endif
void setup() {
  CircuitPlayground.begin();
  Serial.begin(9600);
  CircuitPlayground.irReceiver.enableIRIn(); // Obrim la recepció
  Serial.println("Prem una tecla del comandament");
}
byte R, G, B;
void loop() {
  R = 0;
  G = 0;
  B = 0;
  bool mostra = CircuitPlayground.slideSwitch();
  if (CircuitPlayground.irReceiver.getResults()) {  // S'ha rebut un codi?
    CircuitPlayground.irDecoder.decode();           // Descodifiquem
    Serial.print("Codi rebut: ");
    Serial.println(CircuitPlayground.irDecoder.value, HEX);
    if (CircuitPlayground.irDecoder.value == 0xE0E008F7){
      R = 128;
      G = 0;
    }
    if (CircuitPlayground.irDecoder.value == 0xE0E048B7){
      R = 0;
      G = 128;
    }
    for (int i = 0; i < 10; i++){
      CircuitPlayground.setPixelColor(i, R, G, B);
    }
    delay(500);
    CircuitPlayground.clearPixels();
    delay(500);
    CircuitPlayground.irReceiver.enableIRIn();      // Tornem a obrir la recepció
  }
}

Emissió de missatges

El següent programa envia els codis d'incrementar el canal i decrementar el canal amb la mateixa codificació que hem vist a l'apartat anterior. La nostra placa podrà, amb aquest programa, canviar els canals del televisor com si fos el comandament original. Si tenim una placa amb el programa anterior i una amb el següent podem fer que una d'elles encengui els LED de l'altra.

#include <Adafruit_CircuitPlayground.h>
#if !defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS)
  // No serveix per a plaques Circuit Playground Classic
  #error "Només disponible a la placa Circuit Playground Express"
#endif
#define protocol NECX
#define num_bits 32
#define ch_up 0xE0E048B7
#define ch_dwn 0xE0E008F7
void setup() {
  CircuitPlayground.begin();
  Serial.begin(9600);
}
void loop() {
  if (CircuitPlayground.leftButton()){
    Serial.println("CH +");
    CircuitPlayground.irSend.send(protocol, ch_up, num_bits);
    while (CircuitPlayground.leftButton()){
      ;  // Esperem que es deixi anar el botó
    }
  }
  if (CircuitPlayground.rightButton()){
    Serial.println("CH -");
    CircuitPlayground.irSend.send(protocol, ch_dwn, num_bits);
    while (CircuitPlayground.rightButton()){
      ;  // Esperem que es deixi anar el botó
    }
  }
}

 

 

 

En aquest web, les fotografies marcades amb [AF] són del web d'Adafruit, les marcades amb [SF] del web d'Sparkfun i les marcades amb [AU] del web d'Arduino.

 

 

 

 

 

 

 

 

 

 

Llicència de Creative Commons
Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.