| Electronics > Beginners |
| Arduino Code - volts/amps/power monitor |
| << < (9/10) > >> |
| metrologist:
So, I was having trouble with the SD card writes stopping after 7 or so hours. I slowed down the SD card writes with more averaging of the logged data. --- Code: ---/* SD card datalogger * SD card attached to SPI bus as follows: ** MOSI - pin 11 ** MISO - pin 12 ** CLK - pin 13 ** CS - pin 4 created 24 Nov 2010 modified 9 Apr 2012 by Tom Igoe This example code is in the public domain. */ #include <SD.h> // On the Ethernet Shield, CS is pin 4. Note that even if it's not // used as the CS pin, the hardware CS pin (10 on most Arduino boards, // 53 on the Mega) must be left as an output or the SD library // functions will not work. const int chipSelect = 4; #include "U8glib.h" U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI //U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST); // Fast I2C / TWI //U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK); // Display which does not send AC float count = 0.0; float volts = 0.0; float minVolts = 100.0; float maxVolts = 0.0; float amps = 0.0; float minAmps = 100.0; float maxAmps = 0.0; float ah = 0.0; float watts = 0.0; float whr = 0.0; long v = 0; long a = 0; unsigned long time0 = 0; unsigned long time1 = 0; unsigned long time2 = 0; unsigned long time3 = 0; #define ADC_AMPS(a,count) (((float)((float)a)*26.7)/(((float)count)*1024.0)); #define ADC_VOLTS(v,count) (((float)((float)v)*52.6)/(((float)count)*1024.0)); void setup(void) { Serial.begin(9600); Serial.print("Initializing SD card..."); // make sure that the default chip select pin is set to // output, even if you don't use it: pinMode(4, OUTPUT); // see if the card is present and can be initialized: if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); // don't do anything more: return; } Serial.println("card initialized."); // flip screen, if required // u8g.setRot180(); // assign default color value if ( u8g.getMode() == U8G_MODE_R3G3B2 ) { u8g.setColorIndex(255); // white } else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) { u8g.setColorIndex(3); // max intensity } else if ( u8g.getMode() == U8G_MODE_BW ) { u8g.setColorIndex(1); // pixel on } else if ( u8g.getMode() == U8G_MODE_HICOLOR ) { u8g.setHiColorByRGB(255,255,255); } pinMode(A0, INPUT); pinMode(A1, INPUT); delay(300); } void loop() { if (millis() - time0 >= 100) adc(); // set adc sample rate if (millis() - time1 >= 1000) tally(); // compute average adc result on interval } void adc(){ time0 = millis(); count++; a = a+analogRead(A0)-509; v = v+analogRead(A1); } void tally(){ amps = ADC_AMPS(a,count); volts = ADC_VOLTS(v,count); watts = amps * volts; ah = ah + ((amps) * (millis() - time1)) / 3600000.0; whr = whr + ((watts) * (millis() - time1)) / 3600000.0; time1 = millis(); maxAmps = max(maxAmps, amps); maxVolts = max(maxVolts, volts); minAmps = min(minAmps, amps); minVolts = min(minVolts, volts); lcd(); if (millis() - time3 >= 10000){ time3 = millis(); serial(); sdc(); count = 0.0; a = 0; v = 0; } if (millis()-time2 >= 86400000){ time2=millis(); maxAmps=0.0; maxVolts=0.0; } } void serial(){ Serial.print(count); Serial.print(",averages,"); Serial.print(minVolts); Serial.print(",Vmin,"); Serial.print(volts); Serial.print(",V,"); Serial.print(maxVolts); Serial.print(",Vmax,"); Serial.print(minAmps); Serial.print(",Amin,"); Serial.print(amps); Serial.print(",A,"); Serial.print(maxAmps); Serial.print(",Amax,"); Serial.print(ah); Serial.print(",Ah,"); Serial.print(watts); Serial.print(",W,"); Serial.print(whr); Serial.print(",Whr,"); Serial.print(time1/60000.0); Serial.println(",min"); } void sdc(){ File dataFile = SD.open("datalog.txt", FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.print(count); dataFile.print(",averages,"); dataFile.print(minVolts); dataFile.print(",Vmin,"); dataFile.print(volts); dataFile.print(",V,"); dataFile.print(maxVolts); dataFile.print(",Vmax,"); dataFile.print(minAmps); dataFile.print(",Amin,"); dataFile.print(amps); dataFile.print(",A,"); dataFile.print(maxAmps); dataFile.print(",Amax,"); dataFile.print(ah); dataFile.print(",Ah,"); dataFile.print(watts); dataFile.print(",W,"); dataFile.print(whr); dataFile.print(",Whr,"); dataFile.print(time1/60000.0); dataFile.println(",min"); dataFile.close(); } } void lcd(){ // picture loop u8g.firstPage(); do { draw1(); } while( u8g.nextPage() ); } void draw1() { //graphic commands to redraw the complete screen should be placed here // u8g.setFontPosTop(); u8g.setFont(u8g_font_unifontr); u8g.setPrintPos(0, 14); u8g.print(volts); u8g.print("V"); u8g.setPrintPos(66, 14); u8g.print(amps); u8g.print("A"); u8g.setPrintPos(0, 31); u8g.print(ah); u8g.print("AHr"); u8g.setPrintPos(0, 48); u8g.print(watts); u8g.print("W "); u8g.print(maxAmps*maxVolts); u8g.setPrintPos(0, 64); u8g.print(whr); u8g.print("WHr "); u8g.print(time1/60000.0); } --- End code --- |
| paulca:
What is the maximum file size? Will probably be found in the SDC driver/library documentation. |
| metrologist:
I read the file size is limited by the FAT file system, or around 4GB. My file had around 30k records (lines of data) and was about 2800kB. I think that if there is any glitch to the SD card, the bus shuts down. At least it will not write to the card if it's removed and reinserted. It needs to restart the SD Card bus in Setup(), so it won't recover. I hope slowing down the data logs to about 6 per minute will alleviate the symptom. |
| metrologist:
--- Quote from: Rick Law on March 14, 2018, 02:57:52 am ---Your serial print appears to be always printing a value then a literal such as this snip I took from your code: void serial(void){ Serial.print(amps); Serial.print("A "); Serial.print(ah); Serial.print("Ah "); You have a lot of such pairs, so you will save a lot of space by creating a subroutine that print a pair like this: void serialPrintPair(float value,char *label) { Serial.print(value); Serial.print(label); } --- End quote --- If I implemented that correctly, I saved ~80 bytes converting 22 serial print calls into 11 serialprintpair function calls. I will do the same for the SD card writes, and that is still presenting a problem for me with stopping logging after a few days, around 2-3MB. Maybe the consecutive writes are happening too fast and hanging the card? Or I should try a different card. I'm using Kingston 2GB micro SD in an adapter. Oh, and I just read about using SDFormatter instead of Windows so am trying that now...I've added an error counter if the file is not. I also moved my CS pin to 10, rather that what was specified in the header notes. I also downloaded the SDfat lib that I'll try if this is still failing. --- Code: ---void sdc(){ time3 = millis(); File dataFile = SD.open("datalog.txt", FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.print(count); dataFile.print(",averages,"); dataFile.print(minVolts); dataFile.print(",Vmin,"); dataFile.print(volts); dataFile.print(",V,"); dataFile.print(maxVolts); dataFile.print(",Vmax,"); dataFile.print(minAmps); dataFile.print(",Amin,"); dataFile.print(amps); dataFile.print(",A,"); dataFile.print(maxAmps); dataFile.print(",Amax,"); dataFile.print(ah); dataFile.print(",Ah,"); dataFile.print(watts); dataFile.print(",W,"); dataFile.print(whr); dataFile.print(",Whr,"); dataFile.print(time1/60000.0); dataFile.println(",min"); dataFile.close(); err = 0; } err=err+1; } void serial(){ serialPrintPair(count,",averages,"); serialPrintPair(minVolts,",Vmin,"); serialPrintPair(volts,",V,"); serialPrintPair(maxVolts,",Vmax,"); serialPrintPair(minAmps,",Amin,"); serialPrintPair(amps,",A,"); serialPrintPair(maxAmps,",Amax,"); serialPrintPair(ah,",Ah,"); serialPrintPair(watts,",W,"); serialPrintPair(whr,",Whr,"); serialPrintPair(time1/60000.0,",min"); } void serialPrintPair(float value,char *label) { Serial.print(value); Serial.print(label); } --- End code --- |
| paulca:
I have had a few devices that stall on SD card errors, rather than just retrying. SD card writers are supposed to skip over errored sectors, marking them as such, but my dash cam for one get's hung up on errored sectors and goes into a loop speaking to me, "Please check the SD card, Please check the SD card, Please check the SD card". If I depower and repower it, it goes back to normal. I changed the card and this finally stopped. |
| Navigation |
| Message Index |
| Next page |
| Previous page |