"Corso" Arduino presso biblioteca Cormano

Tra ottobre e dicembre 2015 ho organizzato, ospitato dalla biblioteca del Comune di Cormano, un mini “corso” (molto pratico) su Arduino, creo questa pagina solo per verbalizzare i risultati ottenuti :-)

Regolazione randa in funzione del vento

The Adobe Flash Plugin is needed to display this content.

(https://youtu.be/tE8bKx79tUA)

note di progetto

/*================================================================
progetto finale corso Arduino Cormano
CONTROLLER PER MANOVRARE LA RANDA DI UNA BARCA A VELA
dicembre 2015 - G.Bertoli, S.Curti, L.Ghelfi, A.Meroni, F.Romelli

dati in input:
- 1 sensore magnetico on/off ad uso anemometro
- 4 o 5 sensori hall ad uso banderuola

dati in output:
 - coordinate in gradi per movimento attuatore di posizionamento randa
===================================================================*/

#include <Servo.h>
Servo myservo;

// DICHIARAZIONE DELLE VARIABILI E DELLE COSTANTI GLOBALI.

// array che definisce le possibili posizione dell'attuatore della randa in funzione della forza (indice [4]) e della direzione (indice [7]) del vento
// PosRanda[forza][direzione]
int PosRanda[4][7] = {{90,120,150,180,10,25,60}, {90,140,160,180,10,15,40},{90,160,170,180,10,5,20},{90,180,180,180,10,10,10}};

// array che contiene i valori dei sensori della banderuola
int s[4] = {480,480,480,480}; //valori a riposo

// ultima posizione rilevata
int posizione = 90;

// variabili utilizzate per il calcolo della forza del vento
int anemometro;
int anemometroprec = HIGH;
float mediaane = 5 ;
float velocita;
float tempo = 0 ;
float tempoprec = 0 ;
int vento = 1; // forza del vento compreso tra 1 e 4


//--------------------------------------------------------
void setup() {
myservo.attach(9);
Serial.begin(9600);
pinMode(2, INPUT_PULLUP); //attiva il pin 2 in input con la resistenza di pullup collegata
}


//--------------------------------------------------------
void loop() {
int tmpPosRanda;
anemometroprec = anemometro;
anemometro = digitalRead(2);

// CALCOLO FORZA VENTO ----------
if ((anemometroprec == HIGH) && (anemometro == LOW))  {

// salvo tempo del precedente evento del  sensore
tempoprec = tempo ;

// e il tempo attuale
tempo = millis() ;

// calcolo la media della velocita facendo una media pesata con il valore precedente 
 velocita = ( velocita * (1-(1/mediaane)) + 1/(tempo - tempoprec)) ;

// converto velocita in intero e la rimappo per valori del vento da 1 a 4
vento= constrain(map(int(velocita*7000),0,100,1,4),1,4);
}

//CALCOLO DIREZIONE VENTO -------
// legge il valore dei sensori banderuola
s[0] = analogRead(A0);
s[1] = analogRead(A1);
s[2] = analogRead(A2);
s[3] = analogRead(A3);

tmpPosRanda = CalcolaPosRanda();

//stampa su monitor seriale il valore dei sensori
Serial.print ("anemometro:");
Serial.print (anemometro);
Serial.print ("dtempo:");
Serial.print (tempo - tempoprec);
Serial.print (" - velocità:");
Serial.print (velocita);
Serial.print("vento:");
Serial.print(vento);
Serial.print(" - s0:");
Serial.print(s[0]);
Serial.print(" - s1:");
Serial.print(s[1]);
Serial.print(" - s2:");
Serial.print(s[2]);
Serial.print(" - s3:");
Serial.print(s[4]);
Serial.print(" - pos.vela:");
Serial.println(tmpPosRanda);

delay(10);
}


//-------------------------------------------------
int CalcolaPosRanda () {

// funzione che individua la posizione (angolo) da assegnare alla randa
// in base ai segnali ricevuti in input dai sensori di forza e direzione del vento
// versione a 4 sensori su 180°

if (s[0]>700) {
  posizione = PosRanda[vento-1][0];
  }
else if (s[0] < 300) {
  posizione = PosRanda[vento-1][4];
  }
else if (s[1]>700) {
  posizione = PosRanda[vento-1][1];
  }
else if (s[1] < 300) {
  posizione = PosRanda[vento-1][5];
  }
else if (s[2]>700) {
  posizione = PosRanda[vento-1][2];
 }
else if (s[2] < 300) {
  posizione = PosRanda[vento-1][6];
  }
else if (s[3]>700) {
  posizione = PosRanda[vento-1][3];
  }
else if (s[3] < 300) {
  posizione = PosRanda[vento-1][0];
  }

  MuoviVela(posizione); //muove la vela fino alla posizione determinata
  
  //restituisce il valore della pasizione per la vela
  return posizione;
}

//--------------------------------------------------
void MuoviVela (int posizione) {

//attiva il servo per il movimento della vela, introducendo un ritardo che limita
//la velocità angolare del boma
//riceve in input la posizione in cui deve essere spostata la vela (0°-180°)
  
  int posprec = myservo.read(); //memorizza la posizione del boma prima di iniziare il movimento
  int ritardo =15; //imposta il ritardo in millisecondi per limitare la velocità del boma 
  
  if (posprec < posizione) {                    //se la posizione iniziale è inferiore a quella finale
    for (int i=posprec; i < posizione; i++){
      myservo.write(i);
      delay(ritardo);
    }
  }
  else {                                        //se la posizione iniziale è superiore a quella finale
    for (int i=posprec; i > posizione; i--){
      myservo.write(i);
      delay(ritardo);
    }
  }
}

Movimentazione telecamera su campo da calcio

Log temperatura e umidità su microSD

/* [ArduinoCormano] Progetto "Gol-fi-no" 
 -rudy69@tin.it Paolo -mauro.poiana@libero.it -luciano.mangiardi@fastwebnet.it
 "Gol" (log)
 "fi"    (wi-fi)
 "no"  (no.. non funziona )
- utilizzo della scheda Fishino, comprende già Rtc-Wi fi-SD ,
- 1-Lettura valore temperatura ogni 30" con lampeggio led durante acquisizione OK
- 2-registrazione file log con data/ora e temperatura, registrato su SD/microSD   OK
- 3-gestione del file di log da rete wi-fi (lettura-cancellazione)
     Optional se avanza tempo:
- 4- creazione del grafico andamento temperatura (calc/excel)
- 5- pulsante reset per inizio nuovo file log (all'accensione)                                   OK
- 6- effettuare 5 letture in 10" e registrare valore medio
- 7- sincronizzazione orologio alla prima esecuzione programma(non serve)          OK
- 8- visualizzazione su LCD data/ora temperatura                                                    OK
- 9- selezione tramite dip switch della frequenza registrazione (30" / 5' / 30' / 1h)  OK

punti da sistemare:
- sistemare visualizzazione  cifra delle decine nell'orologio

 */

/*
 *  analog LM35 on pin 0    Temperatura
 *  analog pot    on pin 1    Volt 0-5
 *  analog pot    on pin 2    Percentuale
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11  ** MISO - pin 12 ** CLK - pin 13 ** CS - pin 4
 */
#include <SPI.h>                        // synchronous serial data protocol 
#include <SD.h>                        // for reading and writing SD cards 
#include <TimeLib.h>                // TimeRTC - Time library with Real Time Clock.
#include <Wire.h>                    // Two Wire Interface (TWI/I2C)
#include <DS1307RTC.h>        // a basic DS1307 library that returns time as a time_t
#include <LiquidCrystal.h>  // liquid crystal displays (LCDs)
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd( 10,  9,    8,   7,   6,  5);    //pin arduino
         // LCD pin :   (RS  EN  D4  D5  D6 D7 )
//  utilizzare pin lcd(  4,   6,  11, 12, 13, 14) 
//  gnd=pin 1+5  vcc=pin 2 trimmer luminosità pin 3 trimmer 10K o al gnd

int campionamento;                     // variabile CAMPIONAMENTO in millisec
// collegare dip switch pin 3 e 2 corrispondenti a valore 01 e 02
const int chipSelect = 4;    // definizione pin CS scheda SD
                                                // variabili per temperatura / tensione  extra
int sensor0 = 0;                     // variabile sensore LM35
int sensor1 = 0;                    // variabile tensione
int sensor2 = 0;                   // variabile extra
float celsius = 0;                 // variabile temperatura
float volts = 0;                   // variabile tensione
int extra =0 ;                    // variabile extra
String LastFile;                //variabile nome del File,txt

void setup() {
  Serial.begin(9600);   // inizializza seriale
   while (!Serial) ; // Needed for Leonardo only

lcd.begin(16, 4);                                // set up the LCD's number of columns and rows:
  lcd.setCursor(0, 0);                        // imposta posizione cursore LCD
    lcd.write("SetUp..goL-Fi-no");       //scrive su LCD
         lcd.setCursor(0, 3);              // imposta posizione cursore LCD
           lcd.write(" Made In Italy "); //scrive su LCD
             delay (1000);                 //aspetta
             
  lcd.setCursor(0, 1);              // imposta posizione cursore LCD
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if (timeStatus() != timeSet) 
        {   Serial.println("Unable to sync with the RTC");  //scrive in seriale
                 lcd.write("OrologioNONdisp!");       }             //scrive su LCD
  else
        {     Serial.println("OrologioPresente");               //scrive in seriale
              lcd.write("OrologioPresente");          }           //scrive su LCD
 
 lcd.setCursor(0, 2);         // imposta posizione cursore LCD
    delay (1000);
  Serial.print("Verifica presenza SD card...");             //scrive in seriale
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
          Serial.println(" SD non presente");                 //scrive in seriale
                lcd.write("manca SD !");                            //scrive su LCD
                // don't do anything more:
                   delay (6000);                 //aspetta prima di cancellare LCD
                      lcd.clear();                    // cancella LCD
    return;
  }
  Serial.println("SD pronta");
   lcd.write("Log SD ogni ");    //scrive su LCD
   
     int diptot = digitalRead(3) +digitalRead(2) *2;    // legge dipswitch pin3 e pin4 e restituisce valore da 0 a 

     // imposta campionamento a seconda dei dipswitch e scrive i valori
      switch (diptot) {
    case 0:
      campionamento= 1000;
        Serial.println("Campionamento 1''");
         lcd.write("1''");    //scrive su LCD
      break; 
    case 1:
      campionamento= 30000;
        Serial.println("Campionamento 30''");
         lcd.write("30''");    //scrive su LCD
      break;
    case 2:
      campionamento= 60000;
        Serial.println("Campionamento 1'");
         lcd.write("1'");    //scrive su LCD
      break;
    case 3:
      campionamento= 600000;
        Serial.println("Campionamento 10'");
         lcd.write("10'");    //scrive su LCD
      break;
  }

   delay (4000);                 //aspetta prima di cancellare LCD
   lcd.clear();                    // cancella LCD
 nomeFile();                    //crea il nome del file solo al setup
}

void loop() {
    lcd.setCursor(0, 0);                              // imposta posizione cursore LCD
    lcd.write("goL-Fi-no ");                          // scrive su LCD
      sensor0 = analogRead(0);                // lettura input 0 chip LM35
      sensor1 = analogRead(1);                // lettura input 1 potenziometro
      sensor2 = analogRead(2);                // lettura input 2 potenziometro
       
          celsius = (sensor0/1023.0)*486;               // Calibrare con lm35 (506)
          volts = (analogRead(1)/1023.0)*5.060;  // Calibrare tensione con potenziometro
          extra = (sensor2/1023.0)*100;             // Calcola valore %
              lcd.print(celsius);                               // visualizza temperatura 
                 lcd.setCursor(14, 0);            // imposta posizione cursore LCD
              lcd.print("c.");                                     // visualizza '
               
  // make a string for assembling the data to log:
String dataString = "";   // assegna a dataString ""
  
dataString += day();                            // giorno
dataString += "/";                               //     /
dataString += month();                     // mese
dataString += "/";                             //     /
dataString += year();                      // anno
     lcd.setCursor(0, 1);                    // imposta posizione cursore LCD
     lcd.write("Data            ");           // con gli spazi sovrascrive la data
     lcd.setCursor(6, 1);                   // imposta posizione cursore LCD
     lcd.print(dataString);                // scrive la data
dataString += ";";                         //     ;
dataString += hour();                  // ora
dataString += ":";                       //     :
dataString += minute();            // minuti
dataString += ":";                     //     :
dataString += second();          // secondi
    lcd.setCursor(0, 2);              // imposta posizione cursore LCD
    lcd.write("Ora                 ");  // con gli spazi sovrascrive l' ora
    lcd.setCursor(6, 2);            // imposta posizione cursore LCD
    lcd.print (hour());              // scrive l' ora
    lcd.write(":");                     //     :
    lcd.print (minute());         // scrive i minuti
    lcd.write(":");                   //     :
    lcd.print (second());       // scrive i secondi
dataString += ";";              //     ;
dataString += (celsius);   // aggiunge gradi
dataString += " gradi;";   //     gradi
dataString += (volts);     // aggiunge volt
dataString += " volt;";    //     volt
dataString += (extra);  // aggiunge percentuale
dataString += " %;";    //     %

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open(LastFile, FILE_WRITE); //scrive il file su SD nome yy-mm-dd-hhmm.txt (8.3)
    Serial.println(dataString);                            // scrivi in seriale la stringa dei valori letti:
    
  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.print("Errore apertura file: ");     //scrive in seriale
     Serial.println(LastFile);                       //scrive in seriale
  }
  
   lcd.setCursor(0, 3);              // imposta posizione cursore LCD
   lcd.write("Log ");                  // scrive  "Log "
   lcd.print(LastFile);              // scrive il nome del file.txt
   delay (campionamento);        //aspetta prima di ripete il ciclo/frequenza letture
  
}

  
void nomeFile() {           // crea stringa con nome file yy mm dd hh mm.txt --max 8.3
//  LastFile += year();               // commentare se non desiderato
    LastFile += month();          // commentare se non desiderato
    LastFile += day();             // commentare se non desiderato
    LastFile += hour();          // commentare se non desiderato
    LastFile += minute();     // commentare se non desiderato
    LastFile += ".txt";          // completa il nome con .txt
      Serial.print("Il file  ");                             //scrive in seriale
      Serial.print (LastFile);                           //scrive in seriale
      Serial.println(" verrà scritto su SD  "); //scrive in seriale
  }