martedì 29 maggio 2012

Primo progetto completo

Un progetto completo
un sistema basato su una Arduino Ethernet che ricevi i segnali da tre sensori (una bussola+tiltmetro+accelerometro, un misuratore di temperatura ed un misuratore di umidita') e che il invia via Web.
In pratica questo progetto e' la somma di diversi dei post precedenti


Lato sottostante

Una volta collegato il cavo Ethernet sul computer dentro a Chrome si puo' leggere i valori dei sensori


Il codice da caricare sull'Arduino e' il seguente
-------------------------------
 #include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>

#define ADDRESS 0x60        // indirizzo I2C della bussola

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1, 2 };

Server server(80);

int acc_x0,acc_y0,acc_z0;                     // Valori di accelerazione

unsigned long tempo;

void setup()
{
  //inizializza il bus I2C
  Wire.begin();
  //inizializza il web server
  Ethernet.begin(mac, ip);
  server.begin();
  // per debug
  Serial.begin(9600);
}

void loop()
{
   byte highByte, lowByte, fine;              // Bearing (transi)
   char pitch, roll;                          // Pitch and roll
   int bearing;                               // Bearing
   byte high_x,low_x,high_y,low_y,high_z,low_z;
   int acc_x,acc_y,acc_z;                     // Valori di accelerazione


   Wire.beginTransmission(ADDRESS);           // inizia la comunicazione con la bussola
   Wire.send(2);                              // inizia a leggere dal secondo registro
   Wire.endTransmission();

   Wire.requestFrom(ADDRESS, 4);              // richiede 4 byte
   while(Wire.available() < 4);               // Wait for bytes to become available
   highByte = Wire.receive();         
   lowByte = Wire.receive();          
   pitch = Wire.receive();            
   roll = Wire.receive();             
 
   bearing = ((highByte<<8)+lowByte)/10;      // Calcola la parte intera del Bearing
   fine = ((highByte<<8)+lowByte)%10;         // Calcola la parte decimale del Bearing

   int fine2 = (int)fine;
   int pitch2 = (int)pitch;
   int roll2 = (int)roll;
 
   Wire.beginTransmission(ADDRESS);           //inizia lettura accelerometro
   Wire.send(16);                            
   Wire.endTransmission();

   Wire.requestFrom(ADDRESS, 6);              // Richiede i 6 byte dell'accelerazione
   while(Wire.available() < 6);             
   high_x = Wire.receive();         
   low_x = Wire.receive();          
   high_y = Wire.receive();         
   low_y = Wire.receive();          
   high_z = Wire.receive();         
   low_z = Wire.receive();          
 
   acc_x = ((high_x<<8)+low_x);      // Calcola accel_x
   acc_y = ((high_y<<8)+low_y);      // Calcola accel_y
   acc_z = ((high_z<<8)+low_z);      // Calcola accel_z

   delay(1000);
 
  Client client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c == '\n' && currentLineIsBlank) {

          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          //gestisce il refresh automatico della pagina per aggiornare
          //al valore dei sensori
          client.println("<meta http-equiv=\"refresh\" content=\"1\">");
        
          tempo = round(millis()/1000);
          client.print("Tempo trascorso (sec): ");
          client.print(tempo);
          client.print("</br></br><table border=1>");
        
          // Stampa il valore del bearing
            client.print("<tr><td>Bearing</td><td>");
            client.print(bearing);
            client.print(".");
            client.print(fine2);
            client.print("</td></tr>");

          // Stampa il valore di Pitch
            client.print("<tr><td>Pitch</td><td>");
            client.print(pitch2);
            client.print("</td></tr>");

          // Stampa il valore di Roll
            client.print("<tr><td>Roll</td><td>");
            client.print(roll2);
            client.print("</td></tr>");

          // Stampa il valore di Accelerazione su X
            client.print("<tr><td>Acc. Delta X (g)</td><td>");
            float acx = (acc_x-acc_x0)*0.000636364;
            client.print(acx);
            client.print("</td></tr>");

          // Stampa il valore di Accelerazione su Y
            client.print("<tr><td>Acc. Delta Y (g)</td><td>");
            float acy = (acc_y-acc_y0)*0.000636364;
            client.print(acy);
            client.print("</td></tr>");

          // Stampa il valore di Accelerazione su Z
          // il valore di acc su Z senza movimento e' 15400
          // quindi il fattore di correzione e' 9.8/15400 = 0.000636364
            client.print("<tr><td>Acc. Delta Z (g)</td><td>");
            float acz = (acc_z-acc_z0)*0.000636364;
            client.print(acz);
            client.print("</td></tr>");
          
            // salva i valori di accelerazione per il calcolo
            // del delta di accelerazione
            acc_x0 = acc_x;
            acc_y0 = acc_y;
            acc_z0 = acc_z;

          // Stampa il valore Temperatura
          // T = 68.033 exp(-0.2088*R(Kohm))
          // R_sensore = (10.000*5)/(
          int sensor_t = A0;
          int temp = analogRead(sensor_t);
          double v_temp = (temp*5.0)/1023.0; //voltaggio letto dal pin A0
          double r_temp = (50000.0/v_temp)-10000.0; //resistenza del sensore di temperatura
          double temperatura = 68.033*exp(-0.2088*r_temp/1000.0);
            client.print("<tr><td>Temp. (C)</td><td>");
            client.print(temperatura);
            client.print("</td></tr>");

          // Stampa il valore Umidita
          int sensor_u = A1;
          int umi = analogRead(sensor_u);
          double umidita = -((((umi/1023)*5)-0.8)/3.1)*100;
            client.print("<tr><td>RH (%)</td><td>");
            client.print(umidita);
            client.print("</td></tr>");


            client.print("</table>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    delay(1);
    client.stop();
  }
}

-------------------------------

a

giovedì 24 maggio 2012

Sensore Umidita' HIH-4030 ed Arduino

Il sensore HIH-4030 si connette direttamente all'Arduino sui pin 5V, terra e il segnale OUT ad un pin analogico


La curva di risposta e' sostanzialmente lineare ed e' compresa tra 0.8 e circa 3.9 V per il range di umidita' relativa da 0 a 100%


Formula con correzione di temperatura
%RH = ((0,0004*Temp_C + 0,149)*Analog_in)-(0,0617*Temp_C + 24,436)

Formula generica senza correzione di temperatura
RH = ((Volt_out-0.8)/3.1)*100;
dove
Volt_out = (Analog_in/1023)*5

Analog_in e'  il valore che viene letto direttamente sul pin analogico dell'Arduino
Lo sketch di misura e' estremamente semplice


--------------------------------

int sensorPin = A0;
int sensorValue = 0;

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

void loop() {
  Analog_in= analogRead(sensorPin);
Serial.println(Analog_in);
delay(1000);
}

---------------------------------

Termistore 4K7 su Arduino


Questa prova e' relativa all'uso del termistore 4K7 con Arduino.
La relazione tra resistenza e temperatura non e' di tipo lineare. Usando il valore di Beta di 3977 ed usando il seguente calcolatore on line si puo' avere la legge di correlazione

 T(°C) = 68.033 exp(-0.2088*R(KOhm))



Il montaggio del circuito e' come se fosse un divisore di corrente con una resistenza da 10 KOhm

Fonte Wikipedia
La resistenza R1 coincide con la resistenza data dal termistore, la resistenza R2 e' da 10 KOhm

Non trovando il simbolo del termistore nel disegno e' stato inserito un Led

Il valore di resistenza del termistore misurato fuori dal circuito a temperatura di circa 22-23 °C e' di 3860 Ohm

---------------------------------

int sensorPin = A0;  
int sensorValue = 0;

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

void loop() {
  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);   
  Serial.println(sensorValue);
  delay(1000);         
}

---------------------------------
Una volta montato il circuito il valore letto sulla seriale durante la prova e' stato di 675. Considerando che il pin analogico dell'Arduino misura da 0 a 5 V con 1024 campioni attraverso una semplice proporzione si ha che il voltaggio misurato e' di 3.29 V.
Impiegando la formula del divisore di tensione

si ha che il valore (incognito) della resistenza del termistore e' di 5197 Ohm.
Impiegando la formula di calibrazione del termistore si ricava che la temperatura misurata e' di 23°C (il che corrisponde a quanto indica il termostato della stanza dove e' stato effettuato il test)

Soluzioni alternative possono essere basate su altri sensori come LM35/TMP35


mercoledì 23 maggio 2012

Servo Hitec HS-5485 HB ed Arduino

Ho provato a connettere il servo HS-5485 all'Arduino.
Per prima cosa si deve individuare la disposizione dei pin
Nero : Ground
Rosso : Positivo
Giallo : Segnale

A questo punto si puo' collegare il segnale del servo al PIN 9 e gli altri due all'alimentazione dell'Arduino


Lo sketch per pilotare e' piuttosto banale
---------------------------------

#include <Servo.h>

Servo myservo;  
int conta = 0;

void setup()
{
  myservo.attach(9);
  Serial.begin(9600); 
}

void loop()
{
  myservo.write(conta);  
  conta = conta + 1;
  if (conta >179) conta = 0;
  Serial.println(conta);
  delay(30); 
}

---------------------------------
ed ecco il risultato

Il problema e' che il programma dovrebbe impostare tutti gli angoli da 0 a 180 mentre la rotazione e' chiaramente limitata a circa 90°

Arduino Ethernet e scheda SD

Nelle schede Arduino Ethernet e' compreso un lettore di micro Sd card che puo' essere impiegato come datalogger
Un esempio semplice e' riportato nel seguente sketch
-------------------------
#include <SD.h>

const int chipSelect = 4;

void setup()
{
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  pinMode(10, OUTPUT);
 
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    return;
  }
  Serial.println("card initialized.");
}

void loop()
{
  String dataString = "Luca";

  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
  } 
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
}



-------------------------
il programmino funziona bene nel senso che crea (se non e' gia' presente) il file datalog.txt ed inserisce una stringa per ogni ciclo.
Aprendo da computer il file si ha pero' una situazione di questo tipo

-------------------

Luca
Luca
Luca
Luca
LucaLuca
Luca
Luca
Luca
-------------------
ovvero, senza una logica ben precisa, viene perso un ritorno a capo










martedì 22 maggio 2012

Sensore di flessione su Arduino

Questo test e' relativo al sensore di flessione identificato come A.G.E. Spectra Symbol patent  5.086.785. 
In pratica un sensore di flessione si comporta come una resistenza variabile con la flessione di una linguetta; nel nostro caso si passa da un valore di 9 KOhm in posizione distesa ad un valore di 23 KOhm in posizione piegata

Sensore piatto
Sensore piegato a circa 90°





ATTENZIONE: il verso della torsione e' importante; la resistenza aumenta solo se la flessione e' dal lato opposto a quello della scritta

Il circuito da montare e' piuttosto semplice (la resistenza di pull-off e' da 10 KOhm)





cosi' come lo e' lo sketch
------------------------------------
int SensorPin = A0;
int SensorValue = 0;

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

void loop() {
  SensorValue = map(analogRead(SensorPin),350,520,0,90);
  SensorValue = 90-SensorValue;
  Serial.println(SensorValue);
  delay(1000);
}

------------------------------------
da notare che prima di scrivere il programma ho annotato il valore letto sulla seriale ad angolo 0° e 90° cosi' con la funzione map e' stato possibile scalare al volo i risultati per mostrare direttamente l'angolo di piega
Digital Number 350  su Pin A0 = 0°
Digital Number 520 su Pin A0 = 90°

E' uscito Arduino 1.0.1


Change Detection with structural similarity

L'idea di base e' quella di cercare le differenze tra le due immagini sottostanti Non e' immediatamente visibile ma ci sono dei ...