Vai al contenuto
PLC Forum


File su scheda SD


Solideo

Messaggi consigliati

Salve,

ho fatto un semplice datalogger costituito da un RTC, un sensore , HTU21D, della temperatura/umidità e un modulo per MicroSD, il tutto  funziona per come volevo, ogni 10 minuti interroga il sensore e scrive su file, all'interno della Sd, i valori di temperatura, umidità, data e ora.

Tutto questo quando la scheda SD è vuota, ma al momento che spengo e riaccendo il sistema, quindi dentro la scheda SD ha già creato il file, al momento di scrivere dentro il file mi restituisce un'errore, non è stato possibile aprire il file. 

Questo è il codice che uso per aggiornare il file ogni 10 minuti:

void ScritturaSD(){
	MioFile = SD.open ( "dati.log", FILE_WRITE );
	if ( MioFile ){
		MioFile.println ( String(giorno) + "/" +String(mese) + "/" +String(anno) );
		MioFile.println ( String(ora) + ":" +(minuti) + ":" +(secondi) );
		MioFile.println ( String("Umidità : ") +String(UmidHtu21d) + "%  Temperatura :" +String(TempHtu21d) +"°C" );
		MioFile.println ( String("Temperatura RTC : ") +String(TempRtc) +"°C" );
		MioFile.println ( String("Velocità Fan : ") +String(FanSpeed) +"%" );
		MioFile.println ( "**************************" );
		MioFile.close();
	} else {
		Serial.println ( "Errore apertura File" );
	}

 Se lascio il tutto acceso lui regolarmente aggiorna il file ogni 10 minuti.

L'unica cosa che pensavo è ad un posizionamento sbagliato del puntatore, leggevo del metodo 

available()

che restituisce il numero di byte, che quindi quando riaccendo il sistema e apre il file, il puntatore si posizioni su un valore già occupato generando l'errore.

 

Grazie a chiunque mi sappia indicare la via della risoluzione. 

 

Link al commento
Condividi su altri siti


2 ore fa, Solideo scrisse:

per la libreria è SD.h installata di default nell'ide.

 

 

Scusa ma su cosa gira il programma? Che dispositivo stai usando ed in quale ambiente?

Se non lo comunichi è un po' difficile capire di cosa si sta parlando

Link al commento
Condividi su altri siti

Guarda che stai usando male la libreria. Se la analizzi (basta aprire il file CPP con un editor) vedi come va gestita. Poi puoi sempre far riferimento ad uno degli esempi allegati.

Link al commento
Condividi su altri siti

Scusa ma dagli esempi, da li ho copiato il codice, funziona in questa maniera per quello che capisco.

Se saresti cosi gentile da dirmi quale esempio dovrei guardare o qual'è l'errore che fò.

Link al commento
Condividi su altri siti

Direttamente dall'esempio della libreria SD.

Questo è il listato completo:

Connessione SD Card
MOSI -> 11
MISO -> 12
SCK -> 13
CS -> 10

Connessione RTC e HTU21D I2C con resistenza di pullup da 4K7 
Disattivare pullup interno di SDA SLC

*/

/* Inclusione Librerie */
#include <SPI.h>
#include <SD.h>
#include <DS3232RTC.h>
#include <Wire.h>
#include <SparkFunHTU21D.h>

/* Definizione Variabili e Costanti */

int anno;
int mese;
int giorno;
int ora;
int minuti;
int secondi;
int old_minuti;
int Tempo_controllo;
float TempRtc;
float UmidHtu21d;
float TempHtu21d;
const int ChipSelect = 10; //Pin di Arduino per CS
const int Fan = 9;
int FanSpeed;

/* Definizione Istanze */

HTU21D MyHTU21D ;// Creo un'istanza per sensore temperatura chiamata MyHTU21D
File MioFile; // Creo un'istanza per SD Card

void setup(){
	
	Serial.begin ( 9600 );
	digitalWrite ( Fan, LOW );
	setSyncProvider ( RTC.get );
	/*if ( timeStatus () != timeSet )
		Serial.println ( "Non riuscita la sincronizzazione con RTC" );
	else
		Serial.println ( "RTC è settato come il sistema" );*/
	
	digitalWrite ( SDA, 0 ); //Disattivazione pullup interno SDA
	digitalWrite ( SCL, 0 ); //Disattivazione pullup interno SCL
	
	MyHTU21D.begin(); //Inizzializzo l'istanza
	
	Serial.print ( "Inizzializzazione SD Card...." );
	if ( !SD.begin ( ChipSelect) ){
		Serial.println ( "Inizzializzazione Fallita." );
		while (1);
	}
	Serial.println ( "Inizzializzazione Riuscita." );
	
	Tempo_controllo = minute() ;
	if ( Tempo_controllo <= 10 && Tempo_controllo > 0){ old_minuti = 10; }
	else if ( Tempo_controllo <= 20 && Tempo_controllo > 10 ) { old_minuti = 20; }
	else if ( Tempo_controllo <= 30 && Tempo_controllo > 20 ) { old_minuti = 30; }
	else if ( Tempo_controllo <= 40 && Tempo_controllo > 30 ) { old_minuti = 40; }
	else if ( Tempo_controllo <= 50 && Tempo_controllo > 40 ) { old_minuti = 50; }
	else { old_minuti = 0; }
}

void loop(){
	LetturaRTC();
	LetturaHtu21d();
	if ( minuti == old_minuti ){
		//if ( giorno < 10 ){ Serial.print ( "0" ); }
		Serial.print( giorno );
		Serial.print ( "/" );
		//if ( mese < 10 ){ Serial.print ( "0" ); }
		Serial.print ( mese );
		Serial.print ( "/" );
		Serial.print ( anno );
		Serial.print ( " ***** " );
		if ( ora < 10 ){ Serial.print ( "0" ); }
		Serial.print ( ora );
		Serial.print ( ":" );
		if ( minuti < 10 ){ Serial.print ( "0" ); }
		Serial.print ( minuti );
		Serial.print ( ":" );
		if ( secondi < 10 ){ ( "0" ); }
		Serial.print ( secondi );
		Serial.println();
		TempRtc = RTC.temperature() / 4. ;
		Serial.print ( "Temperatura RTC " );
		Serial.println ( TempRtc, DEC );
		Serial.print ( "Temperatura: " );
		Serial.print ( TempHtu21d, 1 );
		Serial.print ( "°C" );
		Serial.print ( " Umidità:" );
		Serial.print ( UmidHtu21d, 1 );
		Serial.println ("%");
		ScritturaSD();
		old_minuti = old_minuti + 10;
		if ( old_minuti == 60 ){ old_minuti = 0; }
	}
	if ( TempHtu21d > 30.0 && TempHtu21d < 50 ){ 
		analogWrite ( Fan, 127 );
		FanSpeed = 50;
		}
	if ( TempHtu21d > 50.0 ){ 
		digitalWrite ( Fan, HIGH );
		FanSpeed = 100;
		}
	if ( TempHtu21d < 30.0 ){
		digitalWrite ( Fan, LOW );
		FanSpeed = 0;
		}
}

void LetturaRTC(){
	
	anno = year() ;
	mese = month() ;
	giorno = day() ;
	ora = hour() ;
	minuti = minute() ;
	secondi = second() ;

	}
	
void LetturaHtu21d(){
	
	UmidHtu21d = MyHTU21D.readHumidity();
	TempHtu21d = MyHTU21D.readTemperature();
} 

void ScritturaSD(){
	MioFile = SD.open ( "dati.log", FILE_WRITE );
	if ( MioFile ){
		MioFile.println ( String(giorno) + "/" +String(mese) + "/" +String(anno) );
		MioFile.println ( String(ora) + ":" +(minuti) + ":" +(secondi) );
		MioFile.println ( String("Umidità : ") +String(UmidHtu21d) + "%  Temperatura :" +String(TempHtu21d) +"°C" );
		MioFile.println ( String("Temperatura RTC : ") +String(TempRtc) +"°C" );
		MioFile.println ( String("Velocità Fan : ") +String(FanSpeed) +"%" );
		MioFile.println ( "**************************" );
		MioFile.close();
	} else {
		Serial.println ( "Errore apertura File" );
	}
}

 

Link al commento
Condividi su altri siti

1 ora fa, simuffa scrisse:

Magari è solo mancanza di ram

Con tutte quelle String è anche possibile, strano però che accada solo al riavvio.

 

Ciao, Ale.

Link al commento
Condividi su altri siti

il 28/5/2019 at 18:26 , simuffa scrisse:

Serial.println(FreeRam());

Dopo aver inserito questa stringa funziona tutto.

 

Grazie.

 

p.s.

Ora cercherò di capire cosa fà la stringa in questione.

Link al commento
Condividi su altri siti

il 28/5/2019 at 19:34 , ilguargua scrisse:

Con tutte quelle String è anche possibile,

Questo mi interessa molto.

Quale possibile soluzione potrei adottare?

Concatenare più cose in una singola String, usare una board con più ram oppure cosa?

 

Link al commento
Condividi su altri siti

Potresti convertire le stringhe in bytes e memorizzare i dati in bytes; poi quando li leggi li riconverti.

Link al commento
Condividi su altri siti

1 ora fa, Solideo scrisse:

Quale possibile soluzione potrei adottare?

Usare le funzioni standard del C, qui trovi una panoramica completa. Nel tuo caso ti crei un buffer che possa contenere tutti i caratteri della stringa (es. char buffer[40];) e poi con le funzioni di formattazione , tipo sprintf(), o meglio ancora snprinf() scrivi nel buffer il tuo contenuto, lo stampi su display o SD o seriale, azzeri il buffer ( es. memcpy(buffer,0,40) ) e passi alla stringa successiva. Esempio :

void showFreq() 
{
  uint16_t f_int = cur_freq / 1000;
  uint16_t f_rem = cur_freq % 1000;
  char mod[10] = "%01d.%03d";
  char buf[6];
  if (f_int > 99) strncpy(mod,"%03d.%01d",9);
  else if (f_int > 9) strncpy(mod,"%02d.%02d",9);
  snprintf(buf,6,mod,f_int,f_rem);
  u8x8.setInverseFont(0);
  u8x8.draw2x2UTF8(0, 1, buf); 
}

In questo caso invio al display un numero con 1,2 o 3 decimali, a seconda del valore.

La classe String (con la s maiuscola) è meglio evitarla sui micro che, come l'Arduino UNO o simili, hanno poca RAM, perchè usando l'allocazione dinamica tendono a frammentare la memoria, e i 2Kb dell'ATMega328 finiscono velocemente!

 

Ciao, Ale.

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...