mercoledì 23 maggio 2012

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


WebServer su Arduino Ethernet

Un altro modo di presentare i dati dei sensori differente dall'UDP e' quello di mostrarli direttamente su un browser (senza dover quindi scrivere due applicazioni differenti ai due lati del cavo)
Un primo tentativo di installare un WebServer sull'Arduino Ethernet e' andato buca ma dopo le modifiche al file w5100.h effettuato in questo post tutto ha funzionato in modo corretto

Lo sketch impiegato e' quello presente negli esempi dell'Arduino (sotto File/Examples/Ethernet/Webserver) ed e' stato leggermente modificato per mostrare a video il tempo passato dall'accensione della scheda e con un tag html che permette il refresh automatico della pagina ogni secondo

(i valori letti sulle porte analogiche sono random in quanto al momento della prova non c'era nessun sensore connesso)

-----------------------------
#include <SPI.h>
#include <Ethernet.h>

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

Server server(80);

unsigned long tempo;

void setup()
{
  Ethernet.begin(mac, ip);
  server.begin();
}

void loop()
{
  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>");
         
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(analogRead(analogChannel));
            client.println("<br />");
          }
          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();
  }
}

lunedì 21 maggio 2012

Modem Analogici



Alcuni modem per linea analogica (nessuno e' mai stato usato da me prima di entrare nella collezione ma di fatto avevo un Aceex 2400 ed uno US Robotics Sposter 14.4K con cui andavo a giro per le BBS)
Sono ovviamente tutti seriali con porta DB25

Aceex 1200/2400/9600

US Robotics 56 K
USR Robotics Sporster Voice 33.6k

UDP tra Arduino e PC

Questo test e' per verificare lo scambio dati tra Arduino Ethernet e PC mediante pacchetti UDP (Arduino invia e PC riceve)


Da notare che l'Arduino funziona bene anche con una normale pila a 9V ricaricabile ed un cavo cross


Il Pc e' impostato come 192.168.1.120 ed ascolta su porta 5005
L'Arduino e' impostata come 192.168.1.2

Script Python per ricevere i dati
--------------------------------------------------------------------
import socket
UDP_IP="192.168.1.120"
UDP_PORT=5005

sock = socket.socket( socket.AF_INET, # Internet
                      socket.SOCK_DGRAM ) # UDP
sock.bind( (UDP_IP,UDP_PORT) )

while True:
    data, addr = sock.recvfrom( 1024 ) # buffer size is 1024 bytes
    print "Ricevuto: ", data

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

Sketch Arduino per inviare i dati
--------------------------------------------------------------------
#include <SPI.h>        
#include <Ethernet.h>
#include <Udp.h>        

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

byte remote_ip[] = {192,168,1,120};  
unsigned int remote_port = 5005;   

char sendBuffer [] = "Luca\0";
unsigned int sent=0;
int contatore = 0;

void setup() {
  Ethernet.begin(mac,ip);
  Udp.begin(8008);
}

void loop() {
  contatore = contatore + 1;
  dtostrf(contatore,4,0,sendBuffer);
  sent=Udp.sendPacket(sendBuffer, remote_ip, remote_port);
  delay(500);
}


--------------------------------------------------------------------
ATTENZIONE:
con le ultime due versioni del software Arduino (0.23 e 1.0) esiste un bug nella gestione di UDP che genera dei pacchetti pieni di spazzatura.
Per risolvere il problema si deve individuare il file w5100.h che si trova in /libraries/Ethernet/Utility e modificarlo secondo quanto riportato da questo post (vedi al termine del post)
Il problema dovrebbe risultare risolto nella versione 1.0.1 di prossima uscita




venerdì 18 maggio 2012

Bussola Pitch Roll ed Accelerometro

 Ad integrazione del post precedente si possono leggere i valori di accelerazione triassiale coil seguente sketch

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

#include <Wire.h>

#define ADDRESS 0x60        // Defines address of CMPS10


void setup(){
  Wire.begin();  // Conects I2C
  Serial.begin(9600);
}

void loop(){
   byte highByte, lowByte, fine;              

   char pitch, roll;                          
   int bearing;                              
   byte high_x,low_x,high_y,low_y,high_z,low_z;
   int acc_x,acc_y,acc_z;  
  
   Wire.beginTransmission(ADDRESS);           //starts communication with CMPS10
   Wire.send(2);                              //Sends the register we wish to start reading from
   Wire.endTransmission();

   Wire.requestFrom(ADDRESS, 4);              // Request 4 bytes from CMPS10
   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;      // Calculate full bearing
   fine = ((highByte<<8)+lowByte)%10;         // Calculate decimal place of bearing
  
   display_data(bearing, fine, pitch, roll);  // manda i dati alla seriale

   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

   display_acc(acc_x,acc_y,acc_z);
  
   delay(1000);
}

void display_data(int b, int f, int p, int r){    

 
  Serial.print("Bearing = ");                      

  Serial.print(b);                              
  Serial.print(".");
  Serial.println(f);
  Serial.print("Pitch = ");
  Serial.println(p);
  Serial.print("Roll = ");
  Serial.println(r);
}

void display_acc(int x, int y, int z){    //  manda a stampa le accelerazioni
 
  Serial.print("Acc.X = ");                     
  Serial.println(x);                              
  Serial.print("Acc.Y = ");
  Serial.println(y);
  Serial.print("Acc.Z = ");
  Serial.println(z);
}

Debugger integrato ESP32S3

Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede  nell'ID USB della porta Jtag. Nel modulo...