Go Down

Topic: [RISOLTO]SD >richiamare una variabile int . (Read 835 times) previous topic - next topic

WinGamesyun

May 25, 2019, 09:20 pm Last Edit: May 31, 2019, 02:29 pm by WinGamesyun
Salve avrei un paio di domande:


1)Come posso richiamare una variabile salvata sulla SD quando riaccendo arduino mkr 1010 ?

2)Ho scritto bene il codice nel loop per salvare la variabile?
Code: [Select]
switch (pin[i])
        {
          case BANCONOTA5:
            banconota5 = banconota5 + 5;
            sommapar =  banconota5 +  banconota10 + banconota20 + banconota50 + banconota100;
           
            SD.begin();
            myFile = SD.open("totali.txt", FILE_WRITE);


            if (myFile) {
              myFile.println(sommapar);
              myFile.close();

              Serial.println(sommapar);
            }

            else {
              Serial.println("error.txt");
            }

            break;



Silente

#1
May 26, 2019, 07:36 am Last Edit: May 26, 2019, 07:38 am by Silente
1) ti basta rileggere il pezzo di file che contiene in valore della variabile, caricarlo in una stringa e assegnare alla variabile il ritorno della funzione atoi() di quella stringa

2) ni, ovvero, il codice che hai scritto ha un senso e fa cose, ma quello che fa é scrivere sul file il valore, in cifre, della variabile, ma lo scrive alla fine del file. Ora, se non hai altre variabili salvate su quel file é perfetto, all'occorrenza hai anche lo storico dei valori, se ne hai ritrovare l'ultimo valore non é cosa semplice

Ah, non ho capito il Serial.println ("error.txt"), per come é scritto ti scrive quella scritta. Vuoi che ri scriva il contenuto del file error.txt? Devi lavorare in altro modo
Dove va un numero va una variabile o una funzione. E dove va una boolean va un insieme di test.

Se vuoi ottenere devi saper spiegare

In pochi capiscono l'importanza di formattare, sii tra di essi

WinGamesyun

#2
May 26, 2019, 09:16 am Last Edit: May 26, 2019, 09:35 am by WinGamesyun
Buongiorno.
Cercherò di  essere più chiaro possibile nelle domande, come si vede dal mio codice parliamo di un contatore di impulsi, a me serve il salvataggio e lo  storico della variabile sul SD fin qua ci siamo, ma quando riparte dopo lo spegnimento vorrei che arduino mi vada a caricare l'ultimo valore della variabile per proseguire nel conteggio . 

gpb01

#3
May 26, 2019, 09:36 am Last Edit: May 26, 2019, 09:36 am by gpb01
La cosa migliore è strutturare la scrittura in modo che OGNI salvataggio occupi esattamente lo stesso numero di bytes così da pter effettuare calcoli sulla posizione.

Ad esempio, se tu devi scrivere sempre degli "int", sai che essi occupano 2 bytes quindi, ad ogni salvataggio sulla SD, farai una scrittura con SD.write(&tuoInt, 2); ovvero scriverai, in binario (la cosa è comunque anche fattibile in ASCII con altri metodi) i 2 bytes del tuo "int".

Alla partenza del programma, per recuperare l'ultimo valore "int" scritto, ti basterà posizionarti alla fine del file, leggere la posizione corrente nel file (con la SD.position()), decrementare la posizione di DUE (la lunghezza di un "int"), posizionarsi su tale nuova posizione (con la SD.seek()) e leggere i DUE bytes che compongono il tuo ultimo "int".

Se invece che lavorare in binario vuoi lavorare in ASCII, devi solo considerare che un "int" va da -32768 a 32767 e che quindi devi fare in modo che OGNI salvataggio del valore occupi SEMPRE i 6 caratteri necessari (quindi, ad esempio, il valore 12 lo dovrai salvare come +00012 ed il valore -12 come -00012, così che siano sempre occupati 6 caratteri) e poi applicare la stessa logica di prima solo che lo spostamento per recuperare l'ultimo valore dovrà essere di 6 caratteri invece che di 2 bytes.

Guglielmo
Search is Your friend ... or I am Your enemy !

Silente

#4
May 26, 2019, 09:43 am Last Edit: May 26, 2019, 09:47 am by Silente
Ok, quindi il punto 2 ha per risposta "si". Ora il punto 1.
1) apri il file in lettura, il puntatore é alla posizione 0
2) riposizioni il puntatore alla posizione file.size()-2, DOVRESTI essere sull'ultima cifra del numero
3) torni indietro di 1 carattere alla volta fino a che trovi una cosa che NON é una cifra, sei prima dell'inizio dell'ultimo numero (non leggere con la read(), ma con la pick(), così non sposti avanti il punto di lettura ogni lettura)
4) vai avanti di 1 carattere, sei sulla prima cifra del numero
5) variabile=0
6) finché pick() una cifra
6.1)  variabile=variabile*10+(read()-'0')

Dovrebbe andare bene

Ps, il (Guglielmo.modestia==TRUE?m:g)od ha dato una risposta migliore
Dove va un numero va una variabile o una funzione. E dove va una boolean va un insieme di test.

Se vuoi ottenere devi saper spiegare

In pochi capiscono l'importanza di formattare, sii tra di essi

gpb01

>Silente: non ho capito il tuo punto 3 ... perché diavolo ti vuoi spostare di un byte e cosa cerchi? Se i bytes sono scritti in BINARIO, come ho scritto, sono tutte sequenze di 2 bytes, senza nulla in mezzo e non ci sono caratteri cifra o non cifra ... sei in BINARIO !!!

Guglielmo
Search is Your friend ... or I am Your enemy !

WinGamesyun

#6
May 26, 2019, 10:15 am Last Edit: May 26, 2019, 10:51 am by WinGamesyun
Sono un  principiante  per capire tutte le cose che mi suggerite di fare ma servirebbe un esempio ,
noi andiamo avanti modificando esempi di codice adattandoli  alle nostre esigenze ,proprio per questo arduino piace a tantissima persone .

nid69ita

#7
May 26, 2019, 02:29 pm Last Edit: May 26, 2019, 02:50 pm by nid69ita
Parli di int, ma un int al massimo accetta   -32768 a 32767  sicuro che basta ?

come già detto da Guglielmo:
Su un file puoi scrivere e accodare i valori in due modi, in formato binario, quindi un int è 2 byte
oppure scrivi in formato testo, ma qui c'e' il problema che 123 occupa 3 byte (anzi 3 char) mentre 12345 occupa 5 byte.

Il file lo puoi aprire su PC con un notepad, ma se formato testo lo leggi facile, se binario i valori sono scritti come nella memoria del micro (byte per byte)

Quindi prima di tutto devi decidere se formato testo o binario.
 Binario è più semplice da gestire perché un int ad esempio occupa sempre 2 byte

Per un file testo dovresti scrivere occupando sempre lo stesso numero di caratteri, lo si può fare
"formattando" il valore   con snprintf()    (ma non funziona con i float)
La snprintf()  converte il valore in testo, quindi devi avere un array di char che contenga il valore convertito.
Code: [Select]
  char buf[10];
  snprintf(buf,10,"%05d",sommapar);  // 123 => "00123"
  myFile.print(buf);
  myFile.print(' ');    // separatore      SCRIVIAMO QUINDI 6 byte per ogni valore  NO println!!
  myFile.close();


Lo stesso array lo puoi usare per poi leggere l'ultimo dato dal file. Le indicazioni sono quelle di Guglielmo per un file di testo al post#3
Ma fatta la scrittura, poi vediamo la lettura.
my name is IGOR, not AIGOR

gpb01

#8
May 26, 2019, 04:54 pm Last Edit: May 26, 2019, 04:55 pm by gpb01
Nid, io questo:

Code: [Select]
snprintf(buf,10,"%05d",sommapar);  // 123 => "00123"
lo scriverei invece:

Code: [Select]
snprintf(buf,10,"%+06d",sommapar);  // 123 => "+00123"
così da non avere problemi tra segnati e non segnati ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

WinGamesyun

Salve, grazie ancora per tutti i consigli ma non riesco a leggere i vostri esempi, ho provato a

modificare il mio  così nel loop per salvare solo l'ultima scritte così è più gestibile.. almeno credo,
 
il file viene cancellato e riscritto solo l ultimo valore ma comunque non riesco a richiamarlo al momento
 
di ripartenza di arduino .

Code: [Select]
  switch (pin[i])
        {
          case BANCONOTA5:
            banconota5 = banconota5 + 5;
            sommapar =  banconota5 +  banconota10 + banconota20 + banconota50 + banconota100;

            SD.begin();
            SD.remove("totali.txt");
            myFile = SD.open("totali.txt", FILE_WRITE);


            if (myFile) {

              myFile.print(sommapar);
              myFile.close();

              Serial.println(sommapar);
              Serial.println("salvata");
              delay(50);
            }

            else {
              Serial.println("error.txt");
            }

            break;

nid69ita

#10
May 27, 2019, 09:00 am Last Edit: May 27, 2019, 03:00 pm by nid69ita
il file viene cancellato e riscritto solo l ultimo valore ma comunque non riesco a richiamarlo al momento
di ripartenza di arduino .
La lettura alla partenza la devi fare nel setup()
Se esiste il file, lo apri in lettura.  Poi leggi in un array di char e lo converti con atoi()
Logicamente leggi il primo valore, dici che c'e' solo 1 valore ora (ma la FILE_WRITE accoda)

Code: [Select]
char buf[20];
int i=0;
while (myFile.available()) {
 buf[i]=myFile.read();
 i++;
 if(i>=19) break;
}
buf[i]='\0';

valore=atoi(buf);


my name is IGOR, not AIGOR

WinGamesyun

Buongiorno,
ho fatto un copia e incolla nel setup modificando solo la variabile..sembra che
ci sia una parentesi in più mi da questo errore .

apr21a_POSTA_PORTA:89:27: error: expected ';' before ')' token

     buf = myFile.read());

Togliendo  una parentesi dopo il read mi fa compilare il codice
ma comunque non mi aggiorna la variabile    >sommapar<
ho ricontrollato il file txt si aggiorna sempre con il nuovo valore cancellando il vecchio .

 
Code: [Select]
char buf[20];
  int i = 0;
  while (myFile.available()) {
    buf[i] = myFile.read());
    i++;
    if (i >= 19) break;
  }
  buf[i] = '\0';
  sommapar = atoi(buf);
  Serial.println(sommapar);

Ho anche aggiunto  myFile.close();

gpb01

... magari se riportassi sempre il codice completo invece che dei pezzi, sarebbe più facile capire il perché!

Guglielmo
Search is Your friend ... or I am Your enemy !

WinGamesyun

#13
May 27, 2019, 02:25 pm Last Edit: May 27, 2019, 02:32 pm by gpb01
Eccolo  :o

Code: [Select]
[code]
#include <SD.h>
#include <RTClib.h>
#include <Wire.h>
RTC_DS1307 rtc;
#include <LiquidCrystal_PCF8574.h>
LiquidCrystal_PCF8574 lcd(0x27);
#define BLYNK_PRINT Serial
#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
WidgetRTC blynk_rtc;
char auth[] = "";
char ssid[] = "Vodafone";
char pass[] = "xxxx";
char server[] = "blynk-cloud.com";
int port = 8080;
WidgetLCD blynk_lcd(V31);
WidgetLCD blynk1_lcd(V10);

BlynkTimer timer;
#define PORTA         1
#define POSTA         2
#define RESET         3
#define BANCONOTA5    5
#define BANCONOTA10   6
#define BANCONOTA20   7
#define BANCONOTA50   8
#define BANCONOTA100  10


int key[8] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH,};
int pin[8] = {BANCONOTA5, BANCONOTA10, BANCONOTA20, BANCONOTA50, BANCONOTA100, PORTA, POSTA, RESET,};
int  banconota5  = 0;
int  banconota10  = 0;
int  banconota20  = 0;
int  banconota50  = 0;
int  banconota100  = 0;
//int posta = 1;
int porta =  1;
int  sommapar =  0;

String postas = String (postas);
String posta = String ("VUOTO");
String posta1 = String ("PIENO");
File myFile;
File myFile1;
void setup()
{


  WiFi.begin(ssid, pass);
  Blynk.config(auth, server, port);

  Blynk.connect();
  Serial.begin(9600);

  // Blynk.email("dellipaolmail.com", "CAMBIA MARIO", "acceso e connesso.");
  timer.setInterval(90000L, leggidati );
  timer.setInterval(300000L, leggidati1 );

  Serial.println("Initializing SD card...");
  if (!SD.begin(4)) {
    Serial.println("SD non presente");
    lcd.begin(16, 2);
    lcd.setBacklight(255);
    lcd.home(); lcd.clear();
    lcd.setCursor(2, 0);
    lcd.print(">V1.0<SD>KO ");
    lcd.setCursor(0, 1);
    lcd.print("SD NON PRESENTE");

    while (1);
  }
  Serial.println("sd presente.");
  lcd.begin(16, 2);
  lcd.setBacklight(255);
  lcd.home(); lcd.clear();
  lcd.setCursor(4, 0);
  lcd.print("SD > OK ");
  lcd.setCursor(2, 1);
  lcd.print("ATTENDERE>V1.0");
  delay(3000);

  char buf[20];
  int i = 0;
  while (myFile.available()) {
    buf[i] = myFile.read());
    i++;
    if (i >= 19) break;
  }
buf[i] = '\0';
  sommapar = atoi(buf);
  Serial.println(sommapar);

  Wire.begin();
  Wire.beginTransmission(0x27);

  lcd.begin(16, 2);
  lcd.setBacklight(255);
  lcd.home(); lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("WIN GAMES");
  lcd.setCursor(0, 1);
  lcd.print("TOTALI");
  delay(1000);
  blynk1_lcd.clear();
  blynk1_lcd.print(0, 0, postas );
  blynk1_lcd.print(0, 1, "HOPPER,1" );


  blynk_lcd.clear();
  blynk_lcd.print(4, 0, sommapar );
  blynk_lcd.print(4, 1, " TOTALI ");


  for (int i = 0; i < 8 ; i++)

    pinMode(pin[i], INPUT_PULLUP);


}

void loop()
{

  int k;

  for (int i = 0; i < 8 ; i++)
  {
    k = digitalRead(pin[i]);
    if ( key[i] != k )
    {
      if ( key[i] == HIGH && k == LOW )
      {
        Serial.print("PIN");
        Serial.println(pin[i]);

        switch (pin[i])
        {
          case BANCONOTA5:
            banconota5 = banconota5 + 5;
            sommapar =  banconota5 +  banconota10 + banconota20 + banconota50 + banconota100;

            SD.begin();
            SD.remove("totali.txt");
            myFile = SD.open("totali.txt", FILE_WRITE);


            if (myFile) {

              myFile.print(sommapar);
              myFile.close();


              Serial.println("salvata");

            }

            else {
              Serial.println("error.txt");
            }
            myFile1 = SD.open("totali1.txt", FILE_WRITE);


            if (myFile1) {

              myFile1.print( "INSERITA BANCONOTA DA  5 EURO SOMMA PARZIALE  =  ");
              myFile1.println(sommapar);
              myFile1.close();


              Serial.println("salvata1");

            }

            else {
              Serial.println("error1.txt");
            }
            break;

          case BANCONOTA10:
            banconota10 = banconota10 + 10;
            sommapar = banconota5 +  banconota10 + banconota20 + banconota50 + banconota100;

            Serial.println(" BANCONOTA 10");
            break;
          case BANCONOTA20:
            banconota20 = banconota20 + 20;
            sommapar = banconota5 +  banconota10 + banconota20 + banconota50 + banconota100;
            Serial.println(" BANCONOTA 20");
            break;
          case BANCONOTA50:
            banconota50 = banconota50 + 50;
            sommapar = banconota5 +  banconota10 + banconota20 + banconota50 + banconota100;
            Serial.println(" BANCONOTA 50");
            break;
          case BANCONOTA100:
            banconota100 = banconota100 + 100;

            sommapar = banconota5 +  banconota10 + banconota20 + banconota50 + banconota100;

            Serial.println(" BANCONOTA 100");
            break;
          case POSTA:
            // Blynk.email("dellipaolil.com", "CAMBIO MARIO", "VUOTO");
            postas = posta;
            blynk1_lcd.print(0, 0, postas );
            Serial.println(" POSTA");
            break;
          case PORTA:
            Blynk.notify("ATTENZIONE PORTA APERTA ");
            // Blynk.email("dellip@gmail.com", "CAMBIO MARIO", " CAMBIA MONETE \n ATTENZIONE PORTA APERTA ");
            //blynk1_lcd.print(0, 0,stato );
            Serial.println(" PORTA APERTA ");
            break;
          case RESET:
            banconota5   = 0;
            banconota10  = 0;
            banconota20  = 0;
            banconota50  = 0;
            banconota100 = 0;
            sommapar     = 0;
            postas       = posta1 ;
            Serial.println(" AZZERAMENTO TOTALI");

            blynk_lcd.clear();
            blynk1_lcd.clear();
            lcd.home(); lcd.clear();
            lcd.setCursor(0, 1);
            lcd.print("TOTALI");
            lcd.setCursor(1, 0);
            lcd.print("AZZERAMENTO");
            delay(3000);
            lcd.home(); lcd.clear();
            lcd.setCursor(1, 0);
            lcd.print("WIN GAMES");
            lcd.setCursor(0, 1);
            lcd.print("TOTALI");
            break;
        }

        Serial.print("Totale = ");
        Serial.println(sommapar);
        blynk_lcd.print(4, 0, sommapar );
        blynk_lcd.print(4, 1, " TOTALI ");
        blynk1_lcd.print(0, 0, postas );
        blynk1_lcd.print(0, 1, "HOPPER,1" );

      }
      key[i] = k;
    }

    lcd.setCursor(8, 1);
    lcd.print(sommapar);
  }
  if (Blynk.connected()) {
    Blynk.run();
    lcd.setCursor(11, 0);
    lcd.print("CONN");
    lcd.setCursor(11, 0);
  }
  else {
   // Blynk.disconnect();
    lcd.setCursor(11, 0);
    lcd.print("DISC");
  }
  Blynk.run();
  timer.run();
}
void leggidati() {
  if (Blynk.connected()) {
    WiFi.begin(ssid, pass);
  Blynk.config(auth, server, port);
    Blynk.connect();

}
else{
  Blynk.connect();
  Serial.println(sommapar);
  blynk_lcd.print(4, 0, sommapar );
}
}
void leggidati1() {
  if (Blynk.connected()) {
    Serial.println("connesso");
  }
  else {
    Serial.println("no connesso");
  }
}
[/code]

nid69ita

#14
May 27, 2019, 03:02 pm Last Edit: May 27, 2019, 03:05 pm by nid69ita
1. La parentesi doppia è un mio errore di battitura (codice non provato, scritto di getto)   Togli la doppia
2. ti ho scritto quel pezzo di codice che legge ma ti ho scritto che nella setup() devi PRIMA aprire il file in lettura e verificare se esiste.   Se non fai open del file in FILE_READ quel pezzo non funziona.

Quindi quel pezzo di codice deve essere dentro a
Code: [Select]
myFile = SD.open("totali.txt", FILE_READ);
if (myFile)
{ // pezzo di lettura file
}
else
{ sommapar=0;
}
my name is IGOR, not AIGOR

Go Up