Pages: [1]   Go Down
Author Topic: Caricare parametri da SD  (Read 975 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao a tutti.

Ho creato (copiando codice qua e là e adattandolo alle mie esigenze) un semplice sketch che ad una certa ora inizia un ciclo di funzionamento di 8 relè e ad una ora successiva lo disattiva (mi serve per comandare delle elettrovalvole per irrigazione). L'ora, per adesso, è presa tramite server NTP (ma in futuro passerò ad un RTC per evitare di dover usare lo shield ethernet).

Il codice, postato qui di seguito, funziona.

Ora vorrei semplificarne un pochino il funzionamento facendogli caricare i parametri di funzionamento (le parti indicate come // Config DURATA e // Config PARTENZA e FINE all'interno del codice) da una scheda SD, scrivendole in un file txt di configurazione apposito, in modo poi da poter installare il device nel suo posto definitivo e dovendo semplicemente inserire la SD e resettare per cambiare il programma di irrigazione.

Per le prove userei il lettore sd presente sullo shield ethernet.

Qualche idea o suggerimento su come fare? (link, guide, librerie)
Commenti o idee per il codice?

Grazie in anticipo per tutto l'aiuto.

Code:

// Prova comando elettrovalvole con ora presa da NTP

#include <SPI.h>         
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>
#include <TimeAlarms.h>

//CONFIG RELAY BOARD
#define RELAY_ON 0
#define RELAY_OFF 1
#define Relay_1  3 // Stazione 1
#define Relay_2  4 // Stazione 2
#define Relay_3  5 // Stazione 3
#define Relay_4  6 // Stazione 4
#define Relay_5  8 // Stazione 5
#define Relay_6  2 // Stazione 6
#define Relay_7  7 // Stazione 7
#define Relay_M  9 // VALVOLA MASTER


// Configurazione di rete e NTP
byte mac[] = { 0x90, 0xA2, 0xDA, 0x06, 0x00, 0x5A }; //Mac Adress Arduino
unsigned int localPort = 8888;      // Porta UDP
IPAddress timeServer(199,167,198,163); // pool.ntp.org NTP server
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
EthernetUDP Udp;
int timeZoneHour = +2; // Timezone (+1 inverno - +2 Estate)
long timeZoneOffset = (timeZoneHour * -1) * 60 * 60 ;
int NTP_Update_Interval = 86400; // Intervallo update NTP in secondi (86400 = una volta al giorno)

// Config DURATA
int var;
int attive; // Numero Stazioni attive (per il calcolo della pausa)
int durata1 = 10; //in secondi
int durata2 = 0; //in secondi
int durata3 = 0; //in secondi
int durata4 = 0; //in secondi
int durata5 = 10; //in secondi
int durata6 = 10; //in secondi
int durata7 = 0; //in secondi
long intervallo = 60; //in secondi

// Config PARTENZA e FINE
int orapartenza = 8;
int minutopartenza = 00;
int orafine = 18;
int minutofine = 00; //Dare tempo di fare un ulteriore giro se necessario

// Void Setup - Esecuzione solo all'avvio
void setup()
{
  digitalWrite(Relay_1, RELAY_OFF);
  digitalWrite(Relay_2, RELAY_OFF);
  digitalWrite(Relay_3, RELAY_OFF);
  digitalWrite(Relay_4, RELAY_OFF);
  digitalWrite(Relay_5, RELAY_OFF);
  digitalWrite(Relay_6, RELAY_OFF);
  digitalWrite(Relay_7, RELAY_OFF);
  digitalWrite(Relay_M, RELAY_OFF);
  Serial.begin(9600);
  Serial.println("Starting");
  // start Ethernet and UDP
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;);
  }
  Udp.begin(localPort);
  Serial.print("Got IP:");
  Serial.println(Ethernet.localIP());
  setSyncProvider(getNTPTime);
  Serial.println("Looking for a time");
  while(timeStatus()== timeNotSet);
  Serial.println("Got a Time");
  setSyncInterval(NTP_Update_Interval);
  // SVEGLIE 
  Alarm.alarmRepeat(orapartenza,minutopartenza,0, MorningAlarm);  // Partenza
  Alarm.alarmRepeat(orafine,minutofine,0,EveningAlarm);  // Fine
  //LED
  pinMode(Relay_1, OUTPUT);   
  pinMode(Relay_2, OUTPUT); 
  pinMode(Relay_3, OUTPUT);
  pinMode(Relay_4, OUTPUT);
  pinMode(Relay_5, OUTPUT);   
  pinMode(Relay_6, OUTPUT); 
  pinMode(Relay_7, OUTPUT);
  pinMode(Relay_M, OUTPUT);   
}


//void loop - Programma sempre in esecuzione
void loop(){
if (var == 1)
{
   Azione();
}
else
{
  stampaorario();
  Alarm.delay(1000);
}
}

// Printdigits - Mette lo 0 davanti alle cifre
void printDigits(int digits){
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

//Accende i LED
void Azione(){
  // MASTER
  if ( durata1 > 0 || durata2 > 0 || durata3 > 0 || durata4 > 0 || durata5 > 0 || durata6 > 0 || durata7 > 0 )
  { 
  Serial.print("Partenza Stazione MASTER: ");
  stampaorario();
  digitalWrite(Relay_M, RELAY_ON);
  Alarm.delay(1000);
  attive++;
  }
  // Stazione 1
  if ( durata1 > 0 ){   
  Serial.print("Partenza Stazione 1: ");
  stampaorario();
  digitalWrite(Relay_1, RELAY_ON);
  Alarm.delay(durata1*1000);
  digitalWrite(Relay_1, RELAY_OFF);
  Alarm.delay(1000);
  attive++;
  }
  //Stazione 2
  if ( durata2 > 0 ){
  Serial.print("Partenza Stazione 2: ");
  stampaorario();
  digitalWrite(Relay_2, RELAY_ON);
  Alarm.delay(durata2*1000);
  digitalWrite(Relay_2, RELAY_OFF);
  Alarm.delay(1000);
  attive++;
  }
  //Stazione 3
  if ( durata3 > 0 ){
  Serial.print("Partenza Stazione 3: ");
  stampaorario();
  digitalWrite(Relay_3, RELAY_ON);
  Alarm.delay(durata3*1000);
  digitalWrite(Relay_3, RELAY_OFF);
  Alarm.delay(1000);
  attive++;
  }
  // Stazione 4
  if ( durata4 > 0 ){
  Serial.print("Partenza Stazione 4: ");
  stampaorario();
  digitalWrite(Relay_4, RELAY_ON);
  Alarm.delay(durata4*1000);
  digitalWrite(Relay_4, RELAY_OFF);
  Alarm.delay(1000);
  attive++;
  }
  // Stazione 5
  if ( durata5 > 0 ){
  Serial.print("Partenza Stazione 5: ");
  stampaorario();
  digitalWrite(Relay_5, RELAY_ON);
  Alarm.delay(durata5*1000);
  digitalWrite(Relay_5, RELAY_OFF);
  Alarm.delay(1000);
  attive++;
  }
  // Stazione 6
  if ( durata6 > 0 ){
  Serial.print("Partenza Stazione 6: ");
  stampaorario();
  digitalWrite(Relay_6, RELAY_ON);
  Alarm.delay(durata6*1000);
  digitalWrite(Relay_6, RELAY_OFF);
  Alarm.delay(1000);
  attive++;
  }
  // Stazione 7
  if ( durata7 > 0 ){
  Serial.print("Partenza Stazione 7: ");
  stampaorario();
  digitalWrite(Relay_7, RELAY_ON);
  Alarm.delay(durata7*1000);
  digitalWrite(Relay_7, RELAY_OFF);
  Alarm.delay(1000);
  attive++;
  }
  // Fine MASTER e Pausa
  if ( durata1 > 0 || durata2 > 0 || durata3 > 0 || durata4 > 0 || durata5 > 0 || durata6 > 0 || durata7 > 0 ) {
  digitalWrite(Relay_M, RELAY_OFF);
  Serial.print("Inizio Pausa: ");
  stampaorario();
  Serial.print("Durata Pausa: ");
  Serial.print(intervallo-durata1-durata2-durata3-durata4-durata5-durata6-durata7-attive);
  Serial.print(" Secondi ");
  Serial.println(); 
  Alarm.delay(intervallo*1000-durata1*1000-durata2*1000-durata3*1000-durata4*1000-durata5*1000-durata6*1000-durata7*1000-1000*attive);
  attive=0;
  }
}

// Stampaorario - Stampa l'ora come voglio io
void stampaorario() {
  printDigits(hour());
  Serial.print(":");
  printDigits(minute());
  Serial.print(":");
  printDigits(second());
  Serial.print(" ");
  printDigits(day());
  Serial.print("/");
  printDigits(month());
  Serial.print("/");
  Serial.print(year());
  Serial.println();
}

// functions to be called when an alarm triggers:
void MorningAlarm(){
  var = 1;   
}

void EveningAlarm(){
  var = 0;           
}

//Codice NTP
unsigned long getNTPTime()
{
  Serial.println("In getNTPTime");
  sendNTPpacket(timeServer);
  Alarm.delay(1000);
  if ( Udp.parsePacket() ) { 
    Serial.println("Got Time Packet");
    Udp.read(packetBuffer,NTP_PACKET_SIZE);
 
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); 
    unsigned long secsSince1900 = highWord << 16 | lowWord; 

    const unsigned long seventyYears = 2208988800UL + timeZoneOffset;     
    unsigned long epoch = secsSince1900 - seventyYears; 
 
    return epoch;   
  }
  Serial.println("No Time Packet Found");
  return 0;
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
{
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:    
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket();
}
Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 110
Posts: 6975
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Se ti serve uno shield con SD e RTC ti consiglio questo --> http://adafruit.com/products/243
E' da saldare.
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

BZ (I)
Offline Offline
Brattain Member
*****
Karma: 251
Posts: 21255
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Se Ti bastano 1kByte di dati puoi usare la EEPROM del Atmega. Cosí non devi usare la shield. La EEprom la leggi/scrivi con la libreria EEPROM.h

Ciao Uwe
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 38
Posts: 3262
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Config PARTENZA e FINE all'interno del codice) da una scheda SD, scrivendole in un file txt di configurazione apposito, in modo poi da poter installare il device nel suo posto definitivo e dovendo semplicemente inserire la SD e resettare per cambiare il programma di irrigazione.

@uwefed
Come pensi possa usare la eeprom, ogni volta dovrebbe collegarci un pc e riprogrammarlo. La sua domanda è chiara, caricare da SD


ciao



« Last Edit: August 17, 2012, 12:04:38 pm by pablos » Logged

no comment

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Però scrivere sulla Eeprom interna comporta il dover usare un programmatore e relativo PC da portarsi dietro mentre fradetti, da quel che ho capito, pensa all'uso di una SD proprio per la praticità del sistema: basta portarsi dietro una schedina con le impostazioni e modificare così l'intervento della scheda "giardiniere".

@fradetti:
allegati all'IDE ci sono diversi esempi sull'uso della libreria SD per accedere ai file di una schedina di memoria
Logged


Genova
Offline Offline
Faraday Member
**
Karma: 38
Posts: 3262
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Se lo fai con la ethernet shield, non devi nemmeno accedere alla SD, salvi i dati direttamente nello sketch senza riavviare, le modifiche sarebbero immediatamente effettive.
Logged

no comment

Offline Offline
Full Member
***
Karma: 4
Posts: 219
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

per quanti giorni devi programmare le fasi... per uno, per 30, per 365 ?

è chiaro che hai la necessità di implementare il file-system con FAT per inizializzare la sd-card, aprire il file e leggere i dati.

lo vuoi fare sequenzialmente ? o prelevare tutti i dati dal file e memorizzarli sulla memoria eeprom?

« Last Edit: August 15, 2012, 03:55:08 pm by cyclone » Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@pablos:
se non ho capito male col tempo vuole non usare più la ethernet, per cui resterebbe solo la SD da usare
Logged


BZ (I)
Offline Offline
Brattain Member
*****
Karma: 251
Posts: 21255
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@uwefed
Come pensi possa usare la eeprom, ogni volta dovrebbe collegarci un pc e riprogrammarlo. La sua domanda è chiara, caricare da SD

@pablos
Ho segnato una soluzione piú semplice. Per la programmazione puó aggiungere un LCD e 4 pulsanti.

Ciao Uwe
Logged

Pages: [1]   Go Up
Jump to: