gbm
Comunicazione wireless a LED bidirezionale
Tutorials -
Mercoledì 14 Settembre 2011 07:30
Scritto da gbm

 

 

Ciao a tutti.

Questo è articolo è in evoluzione.

Lo usero' per comunicare i progressi di LEDcom

 

Dopo i vari test con il sensore analogico basato su un LED utilizzato come se fosse un pannello solare / fotodiodo ho iniziato a lavorare su un protocollo di comunicazione basato su questo principio che rende possibile comunicare bidirezionalmente con:

  • 2x Arduino Duemilanove / UNO
  • 2x LED qualsiasi tipologia e colore

Il costo veramente irrisorio e la semplicità insuperabile di questo sistema lo rendono il migliore per i primi passi tra i protocolli di comunicazione, i bit e i bytes.

 

 

LEDcom

Questo software che a breve trasformero' in una libreria Arduino e Pico85 compatible permette di comunicare un pacchetto composto da 10 bits, 1 largo alto iniziale (che è l'init), 8 bit che compongono il byte vero e proprio e l'ultimo bit basso. Il primo e l'ultimo hanno un periodo di 3.5 volte maggiore dei bit standard. Questo aiuta l'arduino che riceve l'informazione a inquadrare il pacchetto e riceverlo. I due bit divisori uno alto iniziale e uno basso finale sono studiati per permettere di stimare la distanza e il possibile valore dell'input all'inizio e basso alla fine per poter avere un valore puro di sola luce ambientale da poter percepire e salvare. Allo stesso modo la parte finale potrà essere utilizzata per avvisare il mittente di una non corretta ricezione.

Il sistema è pensato per essere scalabile tramite la variabile BITwidth e lo studio dei middlePoints, grazie a cio' è possibile variare la durata di ogni bit da 10000 microsecondi per bit (1 secondo cioè 1bit al secondo) a 500 microsecondi per bit (0.0005 secondi cioè 133bytes al secondo) avendo una connessione ancora funzionante e piuttosto pulita senza crc.

Questo software non è finito, manca tutta la parte del CRC e una buona revisione dei tempi di attuazione del codice e magari l'uso degli interrupt. Sarei felice di ricevere consigli e o critiche. Per commentare iscrivetevi, nei prossimi giorni vi mostrero' test piu' precisi sulla velocità e sul massimo range di utilizzo. Come vedete siamo ancora agli albori, visto l'uso di soglie.

 

int BITwidth = 5000; //bit width in micros (max tested 500 (not so reliable)
int analogReadTime = 100; //acquistion time of analogRead function (from arduino website, not sure)
float BITstart = 0;
float time = 0;
int BITValue = 0;
int BITsReceived[8];
int ambient = 0;
int ambientIndex = 0;
int possibleInput = 138;
int input = 0;
int BITspacerWidth = 3.5;
int BITspacer = BITwidth * BITspacerWidth;
int BITspacerMiddlePoint = (BITspacer / 2) - (analogReadTime / 2);
int BITmiddlePoint = (BITwidth / 2) - (analogReadTime / 2);
int acquisitionWindow = BITspacer * 1.1;
int presumption = 150;

void setup() {                
 pinMode(12, OUTPUT); 
 for(int i = 0; i < 10; i++) { ambient = analogRead(0) + ambient; }
 Serial.begin(115200);
}

// ACTIVE MODE///////////////////////////////////////////////////////////////
void startCOM() {
 BITstart = micros();
 while((micros() - BITstart) < BITspacer) { digitalWrite(12, HIGH);  }
}

void endCOM() {
 BITstart = micros();
 while((micros() - BITstart) < BITspacer) { digitalWrite(12, LOW); }
}

void BIT(int b) {
 if(b == 1) {  
  BITstart = micros();
  while((micros() - BITstart) < BITwidth) {
   digitalWrite(12, HIGH);
  }
 }
 if(b == 0) { 
  BITstart = micros();
  while((micros() - BITstart) < BITwidth) {
   digitalWrite(12, LOW);
  }
 }
}

void printByte(char b) {
 int BITcount = 8;
 startCOM();
 while(BITcount >= 0) {
 int value = bitRead(b, BITcount);
 if(value <= 1) {BIT(value); BITcount--;}
 }
 endCOM();
}

// PASSIVE MODE//////////////////////////////////////////////////////////////

void getBYTE() {
  time = micros();
  presumption = (possibleInput - ambient) / 5;
 while(analogRead(0) > 150) { }
  if((micros() - time >= BITspacerMiddlePoint) && (micros() - time) <= acquisitionWindow) { possibleInput = analogRead(0); /*Serial.print(" "); Serial.print(possibleInput);*/ }         //non fare niente (da rivedere)
  if((micros() - time) >= BITspacer && (micros() - time) <= acquisitionWindow) { 
   if( analogRead(0) <= 150) {
    getBIT();
    time = micros();  //presumibilmente avremo ottenuto il nostro byte
    ambient = 0; 
    while(micros() - time <= BITspacerMiddlePoint) { //Nel periodo di 2.5bit LOW a fine comunicazione
     ambient = analogRead(0) + ambient;   //aggiorna la luce ambientale
     ambientIndex++;
    }
   }
   ambient = ambient / ambientIndex; 
   /*Serial.print(ambient);
   Serial.print(" ");
   Serial.print(presumption);*/
   ambientIndex = 0;
  }
 }


void getBIT() {
 int BITcount = 8;
 while(BITcount >= 0) {
  time = micros();
  while((micros() - time) <= BITmiddlePoint) {}
   input = analogRead(0);
  while((micros() - time) <= BITwidth) {}
   if(input > 150) { BITsReceived[BITcount] = 1; /*Serial.print(" ' "); Serial.print(analogRead(0)); Serial.print(" ' ");*/}
   if(input <= 150) { BITsReceived[BITcount] = 0; }
   /*Serial.print(" ");
   Serial.print(BITsReceived[BITcount]);*/
  
   BITcount--;
  }
  int somma = ((BITsReceived[7] * pow(2 , 7)) + (BITsReceived[6] * pow(2 , 6)) + (BITsReceived[5] * pow(2 , 5)) + 
               (BITsReceived[4] * pow(2 , 4)) + (BITsReceived[3] * pow(2 , 3)) + (BITsReceived[2] * pow(2 , 2)) + 
               (BITsReceived[1] * pow(2 , 1)) + (BITsReceived[0] * pow(2 , 0))); 
  Serial.print(somma, BYTE);
  Serial.print(" ");
  if(somma == 41) { Serial.println(); }
 }
//////////////////////////////////////////////////////////////////////////////

void loop() {
getBYTE();
/*printByte('B');
printByte('I');
printByte('-');
printByte('D');
printByte('I');
printByte('R');
printByte('E');
printByte('C');
printByte('T');
printByte('O');
printByte('N');
printByte('A');
printByte('L');
printByte(' ');
printByte('L');
printByte('E');
printByte('D');
printByte(' ');
printByte('C');
printByte('O');
printByte('M');
printByte(' ');
printByte('B');
printByte('Y');
printByte(' ');
printByte(' ');
printByte('G');
printByte('I');
printByte('O');
printByte('B');
printByte('L');
printByte('U');
printByte('.');
printByte('C');
printByte('O');
printByte('M');
printByte(' ');
printByte(':');
printByte(')');*/
}

 

Creative Commons License
Bidirectional ANALOG LED communication by Giovanni Blu Mitolo is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
Based on a work at www.gioblu.com.

 

Gioblu Robotics © 2010 - 2012 · Sitemap · privacy

gioscarab@gmail.com

Gioblu BOTServer è online dal 10 Aprile 2010 - 319.232 Visite - 1.027.175 Pagine visualizzate - 182.309 Visitatori unici - 536 utenti attivi