[RISOLTO] Gestione scrittura su SD senza odiosi scroll

Salve a tutti!

In questi giorni stavo provando lo shield Ethernet ed in particolare, alcune funzioni che gestiscono l'SD. Non ho incontrato particolari difficoltà nello scrivere alcuni file, anche grazie l'aiuto del forum e degli esempi allegati, ma l'unico neo che non riesco a risolvere è la registrazione di una singola istanza sull' SD, senza ritrovarmi ogni volta la stessa scritta ripetuta all'infinito.

L'esempio al quale faccio riferimento, potrebbe essere la registrazione della variazione di uno stato logico e di conseguenza, vorrei campionare solo una volta quello stato magari sul fronte di salita, per poi registrare il cambio stato sul fronte di discesa, senza però avere come risultato uno "scroll" su SD.

Il diagramma di "flusso" dovrebbe essere questo: stato "x" alto---> registro su SD "stato alto" (senza scroll!!eheh)nel frattempo controllo se "x" è cambiato di stato e se vero---->registro "stato basso" (senza scroll!!)e così via

Mi servirebbe solo qualche dritta, per sbloccare questa volta, il mio loop mentale eheh :sweat_smile:

Ciao a tutti e buona serata!

cosa intendi per scroll io per esempio non riesco a scrivere all'inizio del file e come te sto facendo pratica tra eth e file sd intendi che ti scrive in sequenza ....tipo log delle variazioni di stato ? ciao

alessanddrob: cosa intendi per scroll io per esempio non riesco a scrivere all'inizio del file e come te sto facendo pratica tra eth e file sd intendi che ti scrive in sequenza ....tipo log delle variazioni di stato ? ciao

Ciao, si esatto, trattandosi di un ciclo di loop, la scritta viene registrata all'infinito, ma per adesso non so come dire al software di scrivere lo stato solo una volta.

Senza vedere lo sketch non so cosa fai. Mi viene da pensare che non resetti la condizione per cui scrivi sulla SD, quindi ad ogni loop il codice scrive (giustamente) sulla schedina.

Se potessi pubblicare il programma forse si capirebbe meglio l’errore.

memorizza lo stato precedente ed a ogni ciclo lo compari con quello attuale, se è differente lo scrivi altrimenti no. pseudodomanda-->pseudorisposta :grin:

BrainBooster: memorizza lo stato precedente ed a ogni ciclo lo compari con quello attuale, se è differente lo scrivi altrimenti no. pseudodomanda-->pseudorisposta :grin:

Ciao, si hai ragione, te lo farei con un plc, ma con Arduino non riesco

leo72: Senza vedere lo sketch non so cosa fai. Mi viene da pensare che non resetti la condizione per cui scrivi sulla SD, quindi ad ogni loop il codice scrive (giustamente) sulla schedina.

Se potessi pubblicare il programma forse si capirebbe meglio l'errore.

Ecco le due righe stupide di codice:

//Premo il pulsante e scrivo su SD
 if (!digitalRead(buttonPins[2])){
 Prova = SD.open("Prova.txt", FILE_WRITE);
 Prova.println("Test scrittura");
 Prova.close();

Mi viene da pensare che dovrei comparare lo stato precedente con l'attuale, dovrebbe suonare un po' come: "adesso il pulsante è premuto e scrivi, ma se è ancora premuto al ciclo successivo, non scrivi", ma non so come dirglielo.

Forse ci sono quasi: imposto una variabile a zero, ma con la pressione del pulsante, la porto a "1", al ciclo successivo, la scrittura avverrà, se lo stato della variabile è a zero, ma con il pulsante premuto, di conseguenza non verrà scritto nulla sulla scheda, dovrei essere sulla strada buona?

Esempio:

Questo funziona:

{
  //Premo il pulsante e scrivo su SD
 if (!digitalRead (buttonPins[2])&& (m == 0)){
 Prova = SD.open("Prova.txt", FILE_WRITE);
 Prova.println("Test scrittura");
 Prova.close();
 m = 1;

Ciao

prendi una variabile la imposti col valore del pin e la printi su sd poi ciclicamente la compari con lo stato del pin se ce variazione la riprinti

oppure usare l'interrupt delle porte per avviare la comparazione, l'interruput avviene solo se ce una variazione in generale su ttutti gli 8 bit non è specifico per un pin (almeno mi pare )

scritto in linguaggio scimmiesco :D ciao

Vuoi scrivere qualcosa sulla SD nel momento in cui viene premuto un pulsante e vuoi farlo solo per 1 volta, giusto?

  //Premo il pulsante e scrivo su SD
 if (!digitalRead (buttonPins[2])&& (m == 0)){
 Prova = SD.open("Prova.txt", FILE_WRITE);
 Prova.println("Test scrittura");
 Prova.close();
 m = 1;

Questo codice funziona però poi devi rimettere "m" a 0 per poter riscrivere sulla scheda. Oppure puoi fare un ciclo che, finché c'è la pressione del pulsante, non esce dal blocco che hai usato per scrivere:

if (!digitalRead (buttonPins[2])){
  Prova = SD.open("Prova.txt", FILE_WRITE);
  Prova.println("Test scrittura");
  Prova.close();
  while (!digitalRead(buttonPins[2]));
}

In questo modo dopo la scrittura ti metti in attesa del rilascio del pulsante. Questo ovviamente va bene se poi non devi fare altro.

Ovviamente senza sketch completo non so se la soluzione può fare al caso tuo oppure no. Comunque si tratta sempre di usare una delle molteplici soluzioni visto che in programmazione non c'è un unico modo per fare 1 cosa.

leo72: Vuoi scrivere qualcosa sulla SD nel momento in cui viene premuto un pulsante e vuoi farlo solo per 1 volta, giusto?

  //Premo il pulsante e scrivo su SD
 if (!digitalRead (buttonPins[2])&& (m == 0)){
 Prova = SD.open("Prova.txt", FILE_WRITE);
 Prova.println("Test scrittura");
 Prova.close();
 m = 1;

Questo codice funziona però poi devi rimettere "m" a 0 per poter riscrivere sulla scheda. Oppure puoi fare un ciclo che, finché c'è la pressione del pulsante, non esce dal blocco che hai usato per scrivere:

if (!digitalRead (buttonPins[2])){
  Prova = SD.open("Prova.txt", FILE_WRITE);
  Prova.println("Test scrittura");
  Prova.close();
  while (!digitalRead(buttonPins[2]));
}

In questo modo dopo la scrittura ti metti in attesa del rilascio del pulsante. Questo ovviamente va bene se poi non devi fare altro.

Ovviamente senza sketch completo non so se la soluzione può fare al caso tuo oppure no. Comunque si tratta sempre di usare una delle molteplici soluzioni visto che in programmazione non c'è un unico modo per fare 1 cosa.

Ciao Leo e grazie per il tuo gentile intervento, quello che vorrei fare è questo, ma ci sono degli errori:

{
  //Premo il pulsante e scrivo su SD
 if (!digitalRead (buttonPins[2]) && (m == 0)){
 Prova = SD.open("Prova.txt", FILE_WRITE);
 Prova.println("Test scrittura");
 Prova.close();
 m = 1;
    }
    if (!digitalRead(buttonPins[2], LOW) && (m == 1)){ //E' una riga errata, ma vorrei controllare la mancata pressione inserendo un secondo testo
 Prova = SD.open("Prova.txt", FILE_WRITE);
 Prova.println("Test scrittura2");
 Prova.close();
 m = 0;
    }
 }

Ecco il codice completo:

#include <SD.h>
#include <ColorLCDShield.h>
int m = 0;

File testFile;
File Prova;
int buttonPins[3] = {3, 4, 5};
void setup()
{
   for (int i=0; i<3; i++)
  {
    pinMode(buttonPins[i], INPUT);
    digitalWrite(buttonPins[i], HIGH);
  }
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
   pinMode(10, OUTPUT);
   
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
}

void loop()

{
  //Premo il pulsante e scrivo su SD
 if (!digitalRead (buttonPins[2]) && (m == 0)){
 Prova = SD.open("Prova.txt", FILE_WRITE);
 Prova.println("Test scrittura");
 Prova.close();
 m = 1;
    }
    if (!digitalRead(buttonPins[2], LOW) && (m == 1)){ //Riga errata, ma vorrei controllare il pulsante a zero comparandolo con lo stato
 Prova = SD.open("Prova.txt", FILE_WRITE);
 Prova.println("Test scrittura1");
 Prova.close();
 m = 0;
    }
 }

Questo test

if (!digitalRead(buttonPins[2], LOW) && (m == 1))

è errato.
L’operatore “!” è l’operatore NOT, quindi nega la successiva cosa.
!digitalRead(pin) è vero quando la lettura è LOW.
Togli il “!” così che il test sia vero con pulsante su HIGH (penso che sia lo stato logico di NON PREMUTO, giusto)?

leo72: Questo test

if (!digitalRead(buttonPins[2], LOW) && (m == 1))

è errato. L'operatore "!" è l'operatore NOT, quindi nega la successiva cosa. !digitalRead(pin) è vero quando la lettura è LOW. Togli il "!" così che il test sia vero con pulsante su HIGH (penso che sia lo stato logico di NON PREMUTO, giusto)?

Ok Leo adesso funziona!!:

void loop()

{
  //Premo il pulsante e scrivo su SD
 if (!digitalRead (buttonPins[2]) && (m == 0)){ //Premo il pulsante e scrivo lo stato
   Serial.println("PULSANTE PREMUTO");
 Prova = SD.open("Prova.txt", FILE_WRITE);
 Prova.println("PULSANTE PREMUTO");
 Prova.close();
   m = 1;
    }
    if (digitalRead (buttonPins[2]) && (m == 1)){ //Rilascio il pulsante e aggiorno lo stato
 Prova = SD.open("Prova.txt", FILE_WRITE);
 Prova.println("PULSANTE RILASCIATO");
 Serial.println("PULSANTE RILASCIATO");
 Prova.close();
 m = 0;
    }
 }

Ho inserito anche due righe per controllare in realtime lo stato di funzionamento.

Bene