Jump to content
PLC Forum


Solideo

File su scheda SD

Recommended Posts

Solideo

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. 

 

Share this post


Link to post
Share on other sites

Livio Orsini

Bisognerebbe conoscere la funzione di libreria che stai usando

Share this post


Link to post
Share on other sites
Solideo

Purtroppo l'unica cosa che posso dire per la libreria è SD.h installata di default nell'ide.

Share this post


Link to post
Share on other sites
Livio Orsini
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

Share this post


Link to post
Share on other sites
Solideo

Scusa, gira sotto un arduino mini

Share this post


Link to post
Share on other sites
Livio Orsini

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.

Share this post


Link to post
Share on other sites
Solideo

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ò.

Share this post


Link to post
Share on other sites
Solideo

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" );
	}
}

 

Share this post


Link to post
Share on other sites
simuffa

e l'errore che dà al riavvio è questo?

Serial.println ( "Errore apertura File" );

Share this post


Link to post
Share on other sites
simuffa

Prova ad aggiungere questo:

Serial.println(FreeRam());

prima di MioFile = SD.open...

Magari è solo mancanza di ram

Share this post


Link to post
Share on other sites
ilguargua
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.

Share this post


Link to post
Share on other sites
simuffa

Oppure puoi provare a mettere un piccolo delay dopo l'open prima dell'if 

Share this post


Link to post
Share on other sites
Solideo

Stasera provo.

Grazie

 

Share this post


Link to post
Share on other sites
Solideo
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.

Share this post


Link to post
Share on other sites
Solideo
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?

 

Share this post


Link to post
Share on other sites
Livio Orsini

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

Share this post


Link to post
Share on other sites
ilguargua
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.

Share this post


Link to post
Share on other sites
Solideo

Grazie, approfondirò la cosa, e riscriverò lo sketch.

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...