Archivio mensile:luglio 2012

Indicatore gpl v1

Finalmente ho trovato un pò di tempo e il materiale giusto!
Ho collegato un piccolo display a 7 segmenti / voltimetro che indica esattamente il valore in volts del sensore di quantità di gpl del ruotino.
Funziona davvero bene, l’unica particolarità è che nei momenti in cui l’auto è un sballottolata (accellerate, fossi, dossi, curve) il valore cambia di un bel pò.

L’ideale sarebbe installare un arduino con display bello grosso, in modo tale da indicare tanti valori ad esempio: km percorsi, km parziali, km al litro con gas etc etc

Per ora posto le foto del mio piccolo progetto.

Da notare che:
1. ho installato un piccolo switch nascosto, nel caso in cui mia sia stufato di vedere il display acceso lo spengo
2. il display si accende solo quando si gira l’auto
20120719185455 catturabj

Inviare dati da Arduino ad una pagina web ASP.Net 4 / C#

Uno dei modi più semplice per inviare dati sul web è sicuramente usare le query string.

La query string è quella parte dell’url che contiente dati da passare in input ad un programma.

Una volta scritta il nostro sketch in arduino è estremamente semplice inviare i dati ad una webpage da noi scritta.

Avremo bisogno di un modulo aggiuntivo alla nostra board: l’ethernet shield.

Questo shield ha tutto il necessario per trasformare arduino in un client o in un piccolo webservice.

Le librerie ufficiali sfruttano in modo quasi ottimale le potenzialità del suo chipset.

ethshield

Con l’ausilio di richieste HTTP 1.1, quali la GET, riusciamo agilmente nel nostro obiettivo.

Arduino sketch:

#include <SPI.h>
#include <Ethernet.h>
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //assegnamo un mac addres alla nostra arduino
byte ip[] = {
192,168,2,20 }; //assegnamo un ip
byte server[] = {
46,16,168,17 }; //l’ip del web service
Client client(server, 80);
//istanziamo un client che lavora sull’ip del web service sulla porta 80
void setup() {
    Ethernet.begin(mac, ip);
    //istanziamo l’ethernet shield con mac ed ip
    Serial.begin(9600);
}
void loop()
{
    delay(1000);
    Serial.println(“connecting…”);
    client.connect(); //ci colleghiamo con i parametri di cui sopra
    if (client.connected()) {
        Serial.println(“connected”);
        //la nostra GET:
        client.println(“GET http://www.QUALCOSA.com/acquire.aspx?username=USERFROMARDUINO&password=PASSFROMARDUINO&
                        datastream=DATASTREAMFROMARDUINO&value=VALUEFROMARDUINO HTTP/1.1″);
        client.println ( “Host: http://www.QUALCOSA.com” ) ;
        client.println(); //chiudere sempre con uno spazio vuoto
    }
    else {
        Serial.println(“connection failed”);
    }
    if (client.available()) {
        //stampiamo tutti i caratteri in risposta dal web service
        do {
            char c = client.read();
            Serial.print(c);
        }
        while (client.available());
    }
    if (!client.connected()) { //stoppiamo il nostro client
        Serial.println();
        Serial.println(“disconnecting.”);
        client.stop();
    }
}

Il nostro frontend acquire.aspx:

<%@ Page Language=”C#” AutoEventWireup=true” CodeFile=”acquire.aspx.cs”
Inherits=”acquire” %>
    <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
    <html xmlns=”http://www.w3.org/1999/xhtml”>
        <head runat=server”>
            <title></title>
        </head>
        <body>
            <form id=”form1″ runat=server”>
                <div>
                    <asp:TextBox ID=”TextBox1″ runat=server”></asp:TextBox>
                    <asp:TextBox ID=”TextBox2″ runat=server”></asp:TextBox>
                    <asp:TextBox ID=”TextBox3″ runat=server”></asp:TextBox>
                    <asp:TextBox ID=”TextBox4″ runat=server”></asp:TextBox>
                </div>
            </form>
        </body> 
    </html>

Il backend in C# con il parsing della query string:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class acquire : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        TextBox1.Text = Request.QueryString["username"];
        TextBox2.Text = Request.QueryString["password"];
        TextBox3.Text = Request.QueryString["datastream"];
        TextBox4.Text = Request.QueryString["value"];
    }
}

Tutorial: data logging con Arduino – Parte 2

Nel precedente articolo abbiamo dato una prima ossatura al nostro data logger.
Questa volta andremo ad inserire nel nostro sketch l’LDR e andremo a mediare i nostri valori dando un output più preciso possibile.

Lo schema di massima del collegamento è il seguente:

ldr_nightlight_breadboard fetch.php

Un primo sketch di massima potrebbe essere questo:

int photocellPin = 1;     // LDR connesso al pin analogico 1
int photocellReading;     // variabile di conversione photocellReading = analogRead(photocellPin);  
 Serial.print("Luce = ");
Serial.print(photocellReading);     // scriviamo sulla seriale la quantità di luce percepita

if (photocellReading < 10) {
  Serial.println(" - Scuro");
} 
else if (photocellReading < 200) {
  Serial.println(" - Poca luce");
} 
else if (photocellReading < 500) {
  Serial.println(" - Luce");
} 
else if (photocellReading < 800) {
  Serial.println(" - Luminoso");
} 
else {
  Serial.println(" - Molto luminoso");
}

Minore è il valore percepito più sarà buio.
In questo caso il valore letto è stato spalmato su 5 print, ottimo per il debug sulla seriale.

Ora bisogna riorganizzare la nostra basetta e montare assieme LDR, LED e LM35 (sembra uno scoglilingua!) per ottenere questo:

wiringok

 

Ora riorganizziamo lo sketch iniziale ed introduciamo media su 20 letture consecutive per poi ottenere questo sketch finale:

#include <SD.h>
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;

const int chipSelect = 10;
short i=0;

void setup()
{
  //seriale aperta a 9600 baud
  Serial.begin(9600);
  Serial.println("Initializing SD card...");

  //inizializziamo i pin 3 e 4 per i led rosso-verde
  //pin 10 riservato al card reader
  pinMode(10, OUTPUT);
  pinMode(3, OUTPUT); 
  pinMode(4, OUTPUT); 

  //se il modulo sd non viene correttamente inizializzato
  if (!SD.begin(chipSelect)) {
    //messaggio di errore sul nostro monitor seriale
    Serial.println("Card failed, or not present");

    for (i=0;i<10;i++) {
      //blinking del led rosso
      digitalWrite(3, HIGH);   
      delay(100);              
      digitalWrite(3, LOW);     
      delay(100);
    }
    return;
  }

  //se correttamente inizializzata...
  Serial.println("card initialized.");
  //blinking led verde
  digitalWrite(4, HIGH);   
  delay(500);              
  digitalWrite(4, LOW);

  //inizializziamo l'RTC
  Wire.begin();
  RTC.begin();
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
}

void loop()
{
  //chiediamo il tempo all'RTC
  DateTime now = RTC.now();
  int tempPin=0; //pin del sensore di temperatura
  int ldrPin=1; //pin del sensore di luce

  int campioni=20; //20 campioni
  int ii=0;
  float  tempc1=0; // variabile per la temperatura
  long unsigned int light=0; //variabile per la luce
  float samples1[campioni]; // array di campioni per la temperatura e luce
  int samples2[campioni];  

  //aspettiamo 3secondi
  delay(2900);

  for(ii = 0; ii <= campioni-1 ; ii++)
  {
    //nell'II-esimo elemento dell'array Samples1 inseriamo il valore convertito della temperatura
    samples1[ii] = (( 5.0 * analogRead(tempPin) * 100.0) / 1024.0);
    //sommiamo le temperature di volta in volta in un altra variabile
    tempc1 = tempc1 + samples1[ii];

    //non abbiamo bisogna di convertire il valore della quantità di luce, la recuperiamo direttamente
    samples2[ii] = analogRead(ldrPin);
    light=light + samples2[ii];
  }

  //dividiamo la sommatoria per N
  tempc1 = tempc1/campioni; 
  light = light /campioni;

  //stampiamo sul nostro monitor seriale per eventuale debugging
  Serial.print(tempc1);
  Serial.println(" C");
  Serial.print(light);
  Serial.println(" light"); 

  //apriamo in scrittura il file sulla sd
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  //Scriviamo: LUCE - TEMPERATURA - ORA:MINUTI:SECONDI
  if (dataFile) {
    dataFile.print(light);
    dataFile.print(" - ");
    dataFile.print(tempc1);
    dataFile.print(" - ");
    dataFile.print(now.hour(), DEC);
    dataFile.print(":");
    dataFile.print(now.minute(), DEC);
    dataFile.print(":");
    dataFile.println(now.second(), DEC);
    //chiudiamo il file
    dataFile.close(); 

    //blinking led verde
    digitalWrite(4, HIGH);   
    delay(100);              
    digitalWrite(4, LOW);
  }  
  else {

    //errore nell'apertura del file o card rimossa
    Serial.println("error opening datalog.txt");
    for (i=0;i<10;i++) {
      //blinkig led rosso
      digitalWrite(3, HIGH);   
      delay(100);              
      digitalWrite(3, LOW);     
      delay(100);
    }
  } 
}

Perchè mediare?

Nello sketch finale ho inserito questo codice:

  for(ii = 0; ii <= campioni-1 ; ii++)
  {
    //nell'II-esimo elemento dell'array Samples1 inseriamo il valore convertito della temperatura
    samples1[ii] = (( 5.0 * analogRead(tempPin) * 100.0) / 1024.0);
    //sommiamo le temperature di volta in volta in un altra variabile
    tempc1 = tempc1 + samples1[ii];

    //non abbiamo bisogna di convertire il valore della quantità di luce, la recuperiamo direttamente
    samples2[ii] = analogRead(ldrPin);
    light=light + samples2[ii];
  }

  //dividiamo la sommatoria per N
  tempc1 = tempc1/campioni; 
  light = light /campioni;

I motivi principali sono due:

  1. una precisione leggermente migliore della lettura fatta col codice del primo articolo
  2. in realtà, la media via software può essere evitata se venisse introdotto un piccolo circuito tra sensori e pin.

Campionare 20 volte successivamente, mi permette di evitare di introdurre altra circuiteria.
Questo workaround ci permette di non avere valori sballati dovuti ad un effetto collaterale, a livello hardware, del “Sample and Hold

Sul nostro file datalog.txt avremo finalmente i valori nel formato che ci eravamo prefissi di avere…

Arduino for dummies

Arduino è il nome di una piattaformahardware per lo sviluppo di applicazioni basate sui microcontrollori ATMEL.

Ideata in Italia nel 2005, è basata su una semplicissima scheda di I/O e su un ambiente di sviluppo che usa una libreria Wiring per semplifi care la scrittura di programmi in C e C++ da far girare sulla scheda.

Il progetto Arduino ha preso avvio in Italia ad Ivrea, nel 2005, con lo scopo di rendere disponibile a progettisti, studenti e semplici hobbisti, un dispositivo di sviluppo facile ed allo stesso tempo più economico rispetto a simili sistemi di prototipazione.

A ottobre 2008 erano già stati venduti più di 50.000 esemplari di Arduino in tutto il mondo.

Le schede uffi ciali usano i chip della serie megaAVR (nello specifi co, i modelli ATmega8, ATmega168, ATmega328, e ATmega1280) ma i loro cloni sono disponibili anche con altri microcontrollori.

atmega328

La scheda Arduino è pre-programmata con un bootloader che semplifi ca il caricamento dei programmi nella memoria Flash incorporata nel chip, rispetto ad altri dispositivi che richiedono, solitamente, un programmatore esterno.

L’ambiente di programmazione integrato (IDE) di Arduino è un’applicazione multipiattaforma scritta in Java, ed è derivata dall’IDE creato per il linguaggio di programmazione Processing e adattato al progetto Wiring. È concepito per introdurre alla programmazione hobbisiti e neofiti, a digiuno di pratica nello sviluppo di software.

Per poterla programmare da remoto senza alcun specifico programmatore, il microcontrollore viene fornito preprogrammato con uno specifico bootloader che instraderà in modo corretto il firmware nell’apposita area di memoria EEPROM durante la fase di programmazione.

Collegare l’arduino al nostro pc è estremamente semplice, bisogna collegare tramite cavetto USB l’arduino al PC

usbplugged_t

Una volta collegata la nostra arduino alla porta usb avvengono due cose:
1. viene data alimentazione alla nostra scheda che eseguirà da subito l’ultimo codice da noi caricato.
Solitamente, la scheda arduino viene venduta con lo sketch “blink” già caricato su di essa, infatti un led smd post al di sotto del pin 13 inizierà a lampeggiare.

diecledplaced

2. arduino verrà riconosciuta dal nostro pc come periferica esterna: se si ha una duemilanove bisogna installare i driver del chipset (non open) FTDI, se è una UNO verrà riconosciuta automaticamente.

I programmi, nel mondo arduino, vengono chiamati “sketch”.
Gli sketch vengono scritti, compilati e caricati sulla nostra scheda tramite l’IDE ufficiale.

Una volta scaricata l’IDE dal sito ufficiale arduino.cc accertiamoci di aver selezionato la giusta porta COM della nostra arduino:

winportselect

E come target-board, la giusta scheda:

Arduino_IDE_Board_Select

Sulla nostra ide 1.0.1 avremo i seguenti pulsanti:

cattura3a
Verifica, Carica, Nuovo, Apri, Salva e Monitor Seriale.

Possiamo tradurre i tasti in questo modo:

Verifica: compila ma non carica il binario nel chip

Carica: compila e carica il binario

Nuovo: apre un nuovo file

Apri: un file salvato

Salva: un file da noi scritto

Monitor Seriale: apre un monitor in ascolto sulla seriale di arduino, sarà la nostra finestra di colloquio con arduino. Riceveremo e mandermo caratteri.

Avremo a disposizione decine di sketch già preconfezionati da poter testare da subito sulla nostra scheda:

immaginesui

Il primo sketch che andremo a compilare e caricare sulla nostra scheda è un pò come il nostro primo “hello world” scritto in C qualche anno fa.
In particolare apriremo l’esempio “blink”:

/*
  Blink
  Accende il LED per un secondo, lo spegne per un altro secondo, ripetutamente
 */

//Il pin 13 ha un LED smd già saldato sulla maggior parte delle schede Arduino
//diamogli un nome:
int led = 13;

//la routine setup gira una sola volta dopo aver dato alimentazione o premuto il tasto reset
void setup() {                
  // inizializza il pin digitale 13 come output
  pinMode(led, OUTPUT);     
}

// la routine loop esegue le istruzioni all'infinito
void loop() {
  digitalWrite(led, HIGH);   // accende il led (HIGH il massimo voltaggio 5v)
  delay(1000);               // wait per un secondo
  digitalWrite(led, LOW);    // spegne il led (LOW è la più bassa tensione)
  delay(1000);               // aspetta per un secondo
}

Premiamo sul pulsante “Carica” e….

myblinkupload

Eventualmente, si può innestare un led esterno (correttamente orientato) tra il pin GND e 13 come in molti esempi:

ngled_t

Non è propriamente corretto inserirlo direttamente in quanto il led verrebbe sovralimentato, andrebbe collegato con una resistenza da 1KOhm in serie, in questo modo:

led13bb_t lesson3sch4

 

Il nostro primo “hello world” è terminato!

 

fonti:
adafruit.com
elettronicaIN