SD card als geheugen steuntje voor data

Arduino specifieke Software
Berichten: 78
Geregistreerd: 03 Okt 2014, 17:16

SD card als geheugen steuntje voor data

Berichtdoor ilioSS » 06 Jan 2020, 15:24

Goede dag,

Vraagje?
Wat zijn de mogelijkheden om data weg te schrijven en weer op te halen na reset en/of re-start na powerdown.
Dit ivm gegevens uitlezen van mijn slimme meter dmv een fotocel op de puls LED. Dit werkt.

Data zoals zijnde kWh hoog en laag . De klok voor de datum loopt op z,n eigen backup batterij.

De eeprom gebruik ik al om de dag wissel te detecteren.

Het gebruik van een battery back-up wil ik voorkomen als het even kan.

Dus de laatste waarde wegschrijven en na start weer ophalen.

Graag een duw in de goede richting.

Alvast hartelijk dank.
BTW nog de allerbeste wensen voor 2020
Met vriendelijke groet,
ilioSS

Advertisement

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: SD card als geheugen steuntje voor data

Berichtdoor Koepel » 06 Jan 2020, 19:06

Hoe vaak valt bij jou de stroom uit ?

Welke RTC heb je ?
Die hebben meestal een paar tot een paar honderd byte om gegevens op te slaan.
Zelfs RTC chips die geen opslag hebben (DS3231) die hebben toch een paar byte. Bij de DS3231 kunnen de alarm registers gebruikt worden als normale lees- en schrijfbare bytes volgens mij.

De interne EEPROM is vaak voldoende. Maar iedere seconde gegevens in de EEPROM updaten is teveel. Dan wordt de levensduur flink korter.

Een SD kaartje kan handig zijn om bijvoorbeeld gegevens te loggen. Dan ontstaan er grote bestanden met gegevens die je op de computer weer kunt inlezen.

Als je weinig gegevens hebt, maar die steeds wilt updaten, dan is er FRAM: https://opencircuit.nl/Product/I2C-Non-Volatile-FRAM-Breakout-256Kbit-32KByte.

Ik zie voor jouw project geen voordeel van een SD kaartje boven de EEPROM. Ook de FRAM module is niet nodig, dan kun je beter een RTC kopen die meer bytes kan opslaan.

Dit probleem is ingewikkelder dan je zou denken. Als de Arduino uitvalt terwijl het gegevens naar EEPROM/RTC/SD/FRAM aan het schrijven is, dan zijn die gegevens misschien corrupt. Er is dus iets nodig dat je kunt zien dat je gegevens goed zijn, bijvoorbeeld met een checksum. Daarnaast kun je twee sets van je gegevens opslaan. Als de ene corrupt is, dan heb je de andere nog. Kortom: een heleboel programmeerwerk. Een accu als backup is eenvoudiger. Bijvoorbeeld een Arduino MKR met aansluiting voor een Lipo batterij.

Berichten: 78
Geregistreerd: 03 Okt 2014, 17:16

Re: SD card als geheugen steuntje voor data

Berichtdoor ilioSS » 07 Jan 2020, 17:09

Hallo Koepel,

Hartelijk dank voor je reactie.
De FRAM zal ik eens gaan bestuderen mogelijk is dat wat.

Bijgaand mijn listing volgens deze methode wil ik ook de slimme meter uitlezen.
Daar er een slimme meter is geïnstalleerd heb ik dit project weer opgepakt. De oude meter had een te slappe LED puls.
De nieuwe meter heeft een meer krachtiger LED puls die beter uit te lezen is. ( ben een beetje voorzichtig op de P1 poort te gebruiken )
Inderdaad valt de stroom niet vaak uit maar als ik de opnemer wil programmeren oid dan is het handig de waardes weer in te kunnen lezen.

Nu gebruik ik het volgend e systeem niet betrouwbaar,
1) promini met ana LDR (genereerd zijn eigen pulsen) met een 433Mhz cheap Charly radio
2) uno met radio en 16x2 display

Je ziet de EEprom gebruik ik om de dag wissel te signaleren.



Dus het e.e.a. is voor verbetering onder handen.

[list=]
//******************************** algemeen ******************************
#include <SPI.h>
#include "Wire.h"
#include <EEPROM.h>
//*************************** SHT75 ****************************************
#include <Sensirion.h> // sensirion simple
const uint8_t dataPin = 30;
const uint8_t clockPin = 31;
float temperature;
float humidity;
float dewpoint;

Sensirion tempSensor = Sensirion(dataPin, clockPin);

//******************************BMP085 ================================================
#include "bmp085.h"
#include <Wire.h>
struct bmp085 b;
int ppa; // om b.ppa te bewerken naar 4 digit,s en geen comma.

byte een[8] = { B00000, B00000, B00000, B00000, B00000, B00000, B00000, B11111}; // voor steepjes in display
byte twee[8] = { B00000, B00000, B00000, B00000, B00000, B00000, B11111, B00000};
byte drie[8] = { B00000, B00000, B00000, B00000, B00000, B11111, B00000, B00000};
byte vier[8] = { B00000, B00000, B00000, B00000, B11111, B00000, B00000, B00000};
byte vijf[8] = { B00000, B00000, B00000, B11111, B00000, B00000, B00000, B00000};
byte zes[8] = { B00000, B00000, B11111, B00000, B00000, B00000, B00000, B00000};
byte zeven[8] = { B00000, B11111, B00000, B00000, B00000, B00000, B00000, B00000};
byte acht[8] = { B11111, B00000, B00000, B00000, B00000, B00000, B00000, B00000};

int myarray[16]; // array voor gemeten waardes op te slaan voor trend 16 = 17 waardes

//************************* DISPLAY*************************************
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 10, 5, 4, 3, 2);// select the pins used on the LCD panel
int hoog = 11; // D11 van arduino naar enable signal van het display

//*************************Klok*****************************************
#define DS3231_I2C_ADDRESS 0x68 // I2C
byte decToBcd(byte val) // Convert normal decimal numbers to binary coded decimal uit klok signaal?????
{
return( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val) // Convert binary coded decimal to normal decimal numbers uit klok signaal ???????
{
return( (val/16*10) + (val%16) );
}

//****************************ALGEMEEN ****************************************
int dd;
int mm;
int yy;
int hr;
int mi;
int se;
int dayOfMonth;
int dag;
int mem = 0;// in eeprom om dag te kunnen onderschijden
int addr = 0;
int y;
int x;
int i;
int t;
int z;
//*********************SD*********************************
#include <SD.h>
const int chipSelect = 53; // was 4???en 10 nu 53 ivm mega
File dataFile;
File filename;

void setup()
{
t=0;
SPI.begin();
Wire.begin();
Serial.begin(9600);


//******************LCD*****************
pinMode(hoog, OUTPUT);// om display te enabelen
digitalWrite(hoog, LOW);
lcd.begin(16, 4);
lcd.setCursor(0,0);
lcd.print("logger");
delay(1500);
lcd.clear();

lcd.createChar(1, een); // voor streepjes in display
lcd.createChar(2, twee);
lcd.createChar(3, drie);
lcd.createChar(4, vier);
lcd.createChar(5, vijf);
lcd.createChar(6, zes);
lcd.createChar(7, zeven);
lcd.createChar(8, acht);
//********************Klok***************************
// set the initial time here:
// DS3231 clockmodule (werkt ook) seconds, minutes, hours, day, date, month, year
// setDS3231time(30,9,11,1,19,10,19); // uncommand en set time/date

//*****************************SD*******************************
Serial.print("Initializing SD card...");
pinMode(SS, OUTPUT);
if (!SD.begin(chipSelect))
{
Serial.println("Card failed, or not present"); // see if the card is present and can be initialized:
// while (1) ; // don't do anything more: nu mag door ook als er geen kaart is
}
Serial.println("card initialized.");



//******************BMP085*******************************
bmp085_init(&b);

}



////////////////////////////// voids///////////////////////////
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
// sets time and date data to DS3231
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set next input to start at the seconds register
Wire.write(decToBcd(second)); // set seconds
Wire.write(decToBcd(minute)); // set minutes
Wire.write(decToBcd(hour)); // set hours
Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
Wire.write(decToBcd(month)); // set month
Wire.write(decToBcd(year)); // set year (0 to 99)
Wire.endTransmission();
}
void readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set DS3231 register pointer to 00h
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // request seven bytes of data from DS3231 starting from register 00h
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f);
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
void displayTime()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, // retrieve data from DS3231
&year);

if (hour<10)
{
Serial.print("0");
}
Serial.print(hour, DEC); // send it to the serial monitor
Serial.print(":");
if (minute<10)
{
Serial.print("0");
}
Serial.print(minute, DEC);
Serial.print(":");
if (second<10)
{
Serial.print("0");
}
Serial.print(second, DEC);
Serial.print(" ");
Serial.print("20");
Serial.print(year, DEC);
Serial.print("/");
Serial.print(month, DEC);
Serial.print("/");
Serial.print(dayOfMonth, DEC);
Serial.print(" Dag v/d week: ");

switch(dayOfWeek){
case 1:
Serial.println("Zondag");
break;
case 2:
Serial.println("Maandag");
break;
case 3:
Serial.println("Dinsdag");
break;
case 4:
Serial.println("Woensdag");
break;
case 5:
Serial.println("Donderdag");
break;
case 6:
Serial.println("Vrijdag");
break;
case 7:
Serial.println("Zaterdag");
break;
}

dd=(dayOfMonth);
mm=(month);
yy=(year);
hr=(hour);
mi=(minute);
se=(second);
dag=dayOfWeek;
}

void loop()
{



Serial.begin(9600);
tempSensor.measure(&temperature, &humidity, &dewpoint); // read sensor
delay(10);
displayTime(); // om tijd uit te lezen en op display te zetten???????
delay(10);
bmp085_read_sensors(&b); // read sensor
delay(10);

ppa=(b.ppa/100); // omrekenen naar hPa


//***********************SD*****************************

mem = EEPROM.read(addr);

if ( mem != dd ) // new file aanmaken
{
Serial.print(yy);
Serial.print("#");
Serial.print(mm);
Serial.print("#");
Serial.println(dd);
delay(50);
char filename[12];
sprintf(filename,"%02d-%02d-%02d.csv",yy,mm,dd);
delay(30);
dataFile=SD.open(filename,FILE_WRITE);
delay(30);
dataFile.println("Date,Time,Hum,TempH,Dauwp,Luchtdruk,TempL");
delay(40);
dataFile.close();
Serial.print("log in nieuwe file..");
EEPROM.write(addr, dd);
Serial.println(filename);
}

else{

// if ( (mi %2 == 1) && (se == 59)) { // elke twee minuten loggen
if ( se == 59 ) { // elke 1 minuut loggen naar schijf
char filename[12];
sprintf(filename,"%02d-%02d-%02d.csv",yy,mm,dd);
dataFile=SD.open(filename,FILE_WRITE);
delay(10);
dataFile.print(yy);
dataFile.print("/");
if(mm<10){
dataFile.print("0");}
dataFile.print(mm);
dataFile.print("/");
if(dd<10){
dataFile.print("0");}
dataFile.print(dd);
dataFile.print(",");
if(hr<10){
dataFile.print("0");}
dataFile.print(hr);
dataFile.print(":");
if(mi<10){
dataFile.print("0");}
dataFile.print(mi);
dataFile.print(":");
if(se<10){
dataFile.print("0");}
dataFile.print(se);
dataFile.print(",");
dataFile.print(humidity,1);
dataFile.print(",");
dataFile.print(temperature,1);
dataFile.print(",");
dataFile.print(dewpoint,1);
dataFile.print(",");
dataFile.print(ppa);//ppa
dataFile.print(",");
dataFile.println(b.t,1);
dataFile.flush();
Serial.print("log in bestaande file ");
Serial.println(filename);
dataFile.close();
delay(800);
}

Serial.print("Humidity ");
Serial.print(humidity,1);
Serial.print(" %RH ");
Serial.print(" , ");
Serial.print("Dauwp ");
Serial.print(dewpoint,1);
Serial.print(" C ");
Serial.print(" , ");
Serial.print("Temp.Hum ");
Serial.print(temperature,1);
delay(30);
Serial.println(" C ");
Serial.print("Temp.Baro ");
Serial.print(b.t,1);
delay(30);
Serial.print(" C ");
Serial.print(" , ");
Serial.print("Baro ");
Serial.print(ppa);// huidige waarde in hPa
delay(30);
Serial.println(" hPa ");
delay(10);



if ( t == 0){

for ( i=0; i<16;i++) // na reset "opstart" eerste keer alles opvullen met ppa als uitgangspunt
{
if (i == 0); {myarray[0]=ppa; delay(10);
myarray[1] = myarray[0];}
if (i == 1); { myarray[2] = myarray[1];}
if (i == 2); { myarray[3] = myarray[2];}
if (i == 3); { myarray[4] = myarray[3];}
if (i == 4); { myarray[5] = myarray[4];}
if (i == 5); { myarray[6] = myarray[5];}
if (i == 6); { myarray[7] = myarray[6];}
if (i == 7); { myarray[8] = myarray[7];}
if (i == 8); { myarray[9] = myarray[8];}
if (i == 9); { myarray[10] = myarray[9];}
if (i == 10); { myarray[11] = myarray[10];}
if (i == 11); { myarray[12] = myarray[11];}
if (i == 12); { myarray[13] = myarray[12];}
if (i == 13); { myarray[14] = myarray[13];}
if (i == 14); { myarray[15] = myarray[14];}
if (i == 15); { myarray[16] = myarray[15];}

}
i=-1; // een keer bij opstarten doorlopen dan niet meer.
}

t=-1;

if ((( mi == 0 ) && ( se == 57 )) || (( mi == 10 ) && ( se == 57 )) || (( mi == 20 )&& ( se == 57)) || (( mi == 30 ) && ( se == 57 )) || (( mi == 40 ) && ( se == 57 )) || (( mi == 50 )&& ( se == 57 ))) {
//if ( se==50){


for ( i=0; i<2; i++){

if ( i == 0 ){

myarray[16] = myarray[15]; myarray[15] = myarray[14]; myarray[14] = myarray[13]; myarray[13] = myarray[12];// array[] doorschuiven voor dispaly graph en drie uur tijd
myarray[12] = myarray[11]; myarray[11] = myarray[10]; myarray[10] = myarray[9]; myarray[9] = myarray[8];
myarray[8] = myarray[7]; myarray[7] = myarray[6]; myarray[6] = myarray[5]; myarray[5] = myarray[4];
myarray[4] = myarray[3]; myarray[3] = myarray[2]; myarray[2] = myarray[1]; myarray[1] = myarray[0];
Serial.println(i);

delay(990);

myarray[0]=ppa;// achter delay zetten???
}
}
i=-1;
}

lcd.setCursor(0,0);
lcd.print("Datum");
lcd.setCursor(6,0);
lcd.print("20");
lcd.print(yy);
lcd.print("-");
if(mm<10){
lcd.print("0");
}
lcd.print(mm);
lcd.print("-");
if(dd<10){
lcd.print("0");
}
lcd.print(dd);
lcd.setCursor(0,1);
lcd.print("Tijd");
lcd.setCursor(6,1);
if(hr<10){
lcd.print("0");
}
lcd.print(hr);
lcd.print(":");
if(mi<10){
lcd.print("0");
}
lcd.print(mi);
lcd.print(":");
if (se<10){
lcd.print("0");
}
lcd.print(se);
lcd.print(" ");
if ( myarray[15] < ppa){lcd.write(1);} // stijgend
if ( myarray[15] = ppa){lcd.write(5);} // standvastig
if ( myarray[15] > ppa){lcd.write(8);} // dalende trend drie uur interval
delay(10);


if (mi %4 == 0){ // IN DEZE STAND EEN MINUUT DE BARO EN BARO TEMP
lcd.setCursor(0,2); // move to the beginning of the second line
lcd.print("Luchtd. ");
lcd.print(ppa);// ppa huidig gemeten waarde
lcd.print(" hPa");
lcd.setCursor(0,3);
lcd.print("Temp.B ");
lcd.print(b.t,1);
lcd.print(" C ");
delay(30);
}

if (mi %4 == 1){ // IN DEZE STAND HUMI EN HUMI TEMP VOOR EENMINUUT
lcd.setCursor(0,2);
lcd.print("Humidity ");
lcd.print(humidity,1);
lcd.print("%RH");
lcd.setCursor(0,3);
lcd.print("Temp.H ");
lcd.print(temperature,1);
lcd.print(" C ");
delay(30);
}


if ( mi %4 == 2) { // IN DEZE STAND REGEL 3 GEEFT TREND EN REGEL 4 GEEFT VERANDERLIJK, MOOI OF REGEN.
z=0;
lcd.setCursor(0,3);
lcd.print(" ");

if (ppa < 1000 ) { // ppa om huidig weer te geven.
Serial.println(" Regen ");
lcd.setCursor(0,2);
// 1234567890123456
lcd.print("Regen ");
}
if ( ppa >=1000 && myarray[0] <= 1025 ) {
Serial.println(" Veranderlijk ");
lcd.setCursor(0,2);
// 1234567890123456
lcd.print("Veranderlijk ");
}
if ( ppa >1025 ) {
Serial.println("Mooi ");
lcd.setCursor(0,2);
// 1234567890123456
lcd.print("Mooi ");
}
}

if ( mi %4 == 3 && z==0 ){
lcd.setCursor(0,2);
lcd.print(" ");
lcd.setCursor(0,3);
lcd.print(" ");

for ( z= 1; z <= 1; ) { // y is de plaats in display 0 is links 15 is rechts opvullen van rechts naar links x = waarde baro

for ( y = 15; y >-1; ) {

for( x = 0; x < 16; x++) {

if ( myarray[x] >=1034){lcd.setCursor(y,2); lcd.write(8);}
if ( myarray[x] <1034 && myarray[x] >=1030) {lcd.setCursor(y,2);lcd.write(7);}
if ( myarray[x] <1030 && myarray[x] >=1026) {lcd.setCursor(y,2);lcd.write(6); }
if ( myarray[x] <1026 && myarray[x] >=1023) {lcd.setCursor(y,2); lcd.write(5); }
if ( myarray[x] <1023 && myarray[x] >=1020) {lcd.setCursor(y,2); lcd.write(4); }
if ( myarray[x] <1020 && myarray[x] >=1017) {lcd.setCursor(y,2);lcd.write(3); }
if ( myarray[x] <1017 && myarray[x] >=1014) {lcd.setCursor(y,2); lcd.write(2);}
if ( myarray[x] <1014 && myarray[x] >=1011) {lcd.setCursor(y,2);lcd.write(1);}
if ( myarray[x] <1011 && myarray[x] >=1008) {lcd.setCursor(y,3);lcd.write(8);}
if ( myarray[x] <1008 && myarray[x] >=1005) {lcd.setCursor(y,3);lcd.write(7);}
if ( myarray[x] <1005 && myarray[x] >=1002) {lcd.setCursor(y,3);lcd.write(6); }
if ( myarray[x] <1002 && myarray[x] >=999) {lcd.setCursor(y,3); lcd.write(5); }
if ( myarray[x] <999 && myarray[x] >=996) {lcd.setCursor(y,3); lcd.write(4); }
if ( myarray[x] <996 && myarray[x] >=993) {lcd.setCursor(y,3);lcd.write(3); }
if ( myarray[x] <993 && myarray[x] >=991) {lcd.setCursor(y,3); lcd.write(2);}
if ( myarray[x] <991) {lcd.setCursor(y,3);lcd.write(1);}
/*
Serial.println(myarray[15]);
Serial.println(myarray[14]);
Serial.println(myarray[13]);
Serial.println(myarray[12]);
Serial.println(myarray[11]);
Serial.println(myarray[10]);
Serial.println(myarray[9]);
Serial.println(myarray[8]);
Serial.println(myarray[7]);
Serial.println(myarray[6]);
Serial.println(myarray[5]);
Serial.println(myarray[4]);
Serial.println(myarray[3]);
Serial.println(myarray[2]);
Serial.println(myarray[1]);
Serial.println(myarray[0]);
*/
y--;

}
}
z++;
}
z=-1;
}
}
}
[/list]

Met vriendelijke groet,
ilioSS

ps. Deze listing is erg lang kan dat beter als link naar de BB

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: SD card als geheugen steuntje voor data

Berichtdoor nicoverduin » 07 Jan 2020, 17:43

Die FRAM's zijn wel leuk hoor. En stel je zou elke milliseconde wegschrijven naar dat ding dan gaat ie 317 jaar mee:)
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: oyaselyeqot en 16 gasten