![]() |
|
|
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:
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(')');*/
}

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.
