Arduino sketchbook #3 - LDR di prossimità

Un test interessante sull'utilizzo di restistori LDR come "sensori di prossimità a basso costo". L'idea: sfruttare la variazione della luminosità in base alla riflessione della luce emessa da un LED prossimo al sensore LDR. Sostanzialmente vorrei utilizzare i resistori LDR per avere un feedback sull'avvicinarsi di un ostacolo: avvicinandosi la luce riflessa del LED sul LDR subirà una variazione.


Il feedback in questo caso è dato da due LED che si accenderanno solo nel caso in cui si rileva un "ostacolo".
Un paio di appunti:
1) il valore in risposta dei due LDR deve essere il più simile possibile;
2) i LED affiancati al LDR devono possibilmente non interferire con l'altro resistore LDR.
Per garantire una funzionalità apprezzabile del tutto bisogna tener presente che la risposta della resistenza dei due LDR non sarà mai uguale. Per questo ho previsto un valore di errore del 5% sul confronto fra le risposte dei due resistori entro il quale non succede nulla:
int max = R_val > L_val ? R_val : L_val;
if(R_val < max*(1+0.05) && R_val > max*(1-0.05))
    digitalWrite(R_LED, LOW);
else
     digitalWrite(R_LED, HIGH);
if(L_val < max*(1+0.05) && L_val > max*(1-0.05))
     digitalWrite(L_LED, LOW);
else
     digitalWrite(L_LED, HIGH);
In questo modo si riesce ad ottenere un feedback ad una distanza di < 10cm (non male!).
Lo schema circuitale leggermente complesso prevede:
- 2 resistenze da 220 Ohm
- 4 resistenze da 10 KOhm
- 2 LED Rosso (il feedback)
- 2 LED Blu
- 2 LDR


Di seguito il codice per Arduino:

/**
 * LDRsensor.ino
 * -----------------
 * LDR as cheap sensor of proximity
 *
 * <sabageek.blogspot.com>
**/

const int R_LED = 9;
const int L_LED = 10;
const int digitRled = 2;
const int digitLled = 4;
const int L_LDR = 0;
const int R_LDR = 1;
//methods
void activeLight(int R_val, int L_val);
void setup(){
  pinMode(R_LED, OUTPUT);
  pinMode(L_LED, OUTPUT);
  pinMode(digitRled, OUTPUT);
  pinMode(digitLled, OUTPUT);
}
void loop(){
  //LED check
  digitalWrite(digitRled, HIGH);
  digitalWrite(digitLled, HIGH);
  activeLight((int)analogRead(R_LDR),(int)analogRead(L_LDR));
}
void activeLight(int R_val, int L_val){
  int max = R_val > L_val ? R_val : L_val;
  if(R_val < max*(1+0.05) && R_val > max*(1-0.05))
    digitalWrite(R_LED, LOW);
  else
    digitalWrite(R_LED, HIGH);
  if(L_val < max*(1+0.05) && L_val > max*(1-0.05))
    digitalWrite(L_LED, LOW);
  else
    digitalWrite(L_LED, HIGH);
}

Arduino sketchbook #2

Il "sunday project" di questo fine settimana è stato un modo utile per capire il funzionamento della comunicazione seriale fra Arduino e il sistema operativo. Il funzionamento è semplice: i LED vengono illuminati convertendo il codice esadecimale passato attraverso la porta seriale in segnale analogico. Ad esempio per generare il colore giallo:

#FFFF00  -->  red = 255, green = 255, blue = 0

I componenti utilizzati per il circuito sono pochissimi:
- 3 resistenze da 220 Ohm;
- 3 LED (rosso, verde, blu)



Lo schema cicuitale e il codice utilizzato:




/**
 * color.ino
 * -----------------
 * Fetch a RGB hex color code and forward to Arduino
 *
 * <sabageek.blogspot.com>
**/

const int R_LED = 9;
const int G_LED = 10;
const int B_LED = 11;

char buffer[6] = {0,0,0,0,0,0};
int rgb[3] = {0,0,0};
int idx = 0;

int hex2dec(char c);

void setup(){
  Serial.begin(115200);
}

void loop(){
  if(Serial.available()){
    if((char)Serial.read()=='#')
      while(idx<6)
        buffer[idx++]=toupper((char)Serial.read());
  } else {
    idx=0;
    for(int i=0; i<6; i+=2)
      rgb[i/2] = hex2dec(buffer[i+1])+hex2dec(buffer[i])*16;
    analogWrite(R_LED, rgb[0]);
    analogWrite(G_LED, rgb[1]);
    analogWrite(B_LED, rgb[2]);
    delay(100);
  }
}

int hex2dec(char c){
  if(c>='A' && c<='F')
    return (int)(c - 'A')+10;
  else if (c >= '0' && c<='9')
    return (int)(c - '0');
}

Arduino sketchbook #1


Un seplice esercizio per prendere confidenza con Arduino UNO. Lo scopo: far accendere i LED in base ad una soglia di temperatura misurata dal sensore e farci restituire il valore in Celsius sulla porta seriale. Necessario, oltre la solita breadboard e cavetteria di vario genere:
- 1 sensore di temperatura LM35
- 2 resistenze 220 Ohm
- 2 LED



Per scrivere lo sketch è possibile utilizzare l'IDE di Arduino (IDE - Arduino.cc) oppure scrivere e compilare tramite Emacs configurandolo come spiegato nei post precedenti. In entrambi i casi, si consiglia di utilizzare l'estensione .ino del file poiché dalla versione 1.0 è diventato lo standard per gli sketch di Arduino (Arduino 1.0 - ReleaseNotes).

La parte più sottile di tutto è la conversione del segnale ricevuto dal sensore LM35 in unità leggibili. 



Se il pin Vin viene collegato alla tensione di 5V sulla scheda Arduino UNO allora la tensione in out Vout:
Tensione al pin [mV] = (valore letto dal ADC) * (5000/1024)
Pertanto, la temperatura sarà data:
T [°C] = (Tensione al pin [mV] - 500)/10

Il semplice schema circuitale che ho utilizzato e il codice per lo sketch di Arduino*:



/*
  An open-source LM35DZ Temperature Sensor for Arduino. This project will be enhanced on a regular basis and based on work that is (cc) Daniel Spillere Andrade implementation.

(cc) Andrea Cirillo
*/

int pin = 0; // analog pin
float tempc = 0,tempf=0; // temperature variables
float samples[8]; // variables to make a better precision
int maxi = -100, mini = 100; // to start max/min temperature
int i;
//LED
const int G_LED = 9;
const int Y_LED = 10;

void setup()
{
  Serial.begin(9600); // start serial communication
  //LED
  pinMode(G_LED, OUTPUT);
  pinMode(Y_LED, OUTPUT);
}

void loop()
{
  for(i = 0; i<8; i++){ // gets 8 samples of temperature
    samples[i] = analogRead(pin) * (500.0 / 1024.0);
    tempc = tempc + samples[i];
    delay(100);
  }
  tempc = tempc/8.0; // better precision
  if(tempc > maxi) {
    maxi = tempc;
  } // set max temperature
  if(tempc < mini) {
    mini = tempc;
  } // set min temperature
  //LED
  if(analogRead(pin)<41){
    analogWrite(G_LED, 255);
    analogWrite(Y_LED, 0);
  }
  else {
    analogWrite(G_LED, 0);
    analogWrite(Y_LED, 255);
  }
  Serial.print(tempc,DEC);
  Serial.print(" Celsius, ");
  Serial.print(maxi,DEC);
  Serial.print(" Max, ");
  Serial.print(mini,DEC);
  Serial.println(" Min");
  Serial.print(" Analog Output = ");
  Serial.println(analogRead(pin),DEC);
  Serial.println("==============================");
  tempc = 0;
  delay(1000); // delay before loop
}



*Qualunque suggerimento o miglioria sono ovviamente più che apprezzati.


[Fonte: http://www.ladyada.net/learn/sensors/tmp36.html]