Loggning av solenergi

Har du ett projekt gå gång - Berätta gärna!

Loggning av solenergi

Inläggav Fritte 21 jan 2015 19:28

Jag har länge sneglat på Arduino men aldrig tidigare haft något bra projekt för att motivera mig till att ta steget och lära mig.
Men nu har jag bestämt mig för att bygga en "logger" för solelen i sommarstugan.
Data kommer att samlas in direkt från denna regulator och lagras på ett SD-kort för att sedan kunna föras över till datorn för lite fina grafer. Jag funderar även på att logga temperatur och luftfuktighet i huset under året.
Jag kommer även koppla in en display som ska visa aktuella värden samt medelvärden för laddning och förbrukning.

Men hur ofta ska jag logga informationen? För ofta och det blir nästan ohanterliga mängder information på ett år och för sällan så säger det nästan inget.
Ni som redan loggar er produktion. Med vilka intervaller loggar ni?
Fritte
 
Inlägg: 209
Blev medlem: 09 sep 2008 18:13
Ort: Linköping

Re: Loggning av solenergi

Inläggav rolle50 21 jan 2015 21:46

Så här gör jag:
Jag loggar sol el förbrukning och vad panelerna ger.En gång dagligen så har jag koll på batteribanken
Vindkraften loggar jag en gång i veckan.MVH//Roland
Användarvisningsbild
rolle50
 
Inlägg: 210
Blev medlem: 01 okt 2011 11:45
Ort: Trollhättan

Re: Loggning av solenergi

Inläggav Fritte 21 jan 2015 22:36

Min spontana tanke är att om man loggar så sällan som en gång om dagen så missar man information om t.ex. när på dygnet man producerar eller förbrukar mest energi. Jag trodde snarare att man loggade 1 gång i timmen eller oftare.
Fritte
 
Inlägg: 209
Blev medlem: 09 sep 2008 18:13
Ort: Linköping

Re: Loggning av solenergi

Inläggav McB 22 jan 2015 22:43

Det är inte lätt att säga hur ofta.
Men du kan styra loggningen med kriterier i programmet om du vill,
tex ingen inkommande ström och ingen utgående ström = ingen loggning på dom 5 kommande programcyklerna, om det kvarstår loggas den 6:e cykeln men inte dom kommande 5 osv.
Det finns massor med sätt att styra det på, frågan är ju vad du vill ha ut och vilken upplösning du behöver på din data.

Man bör ju ha i tanke att programet gås igenom på millisekunder så någon form av delay blir ju ett måste om du inte bara vill logga förändringar som skett sen den senaste cykeln.
Om Jesus Kristus skulle återuppstå och se allt som görs i hans namn, så skulle han aldrig sluta spy.

- Woody Allen
Användarvisningsbild
McB
 
Inlägg: 683
Blev medlem: 19 jun 2009 11:48
Ort: Några mil väster om Vättern.

Re: Loggning av solenergi

Inläggav Fritte 23 jan 2015 01:04

Tanken är att displayen ska uppdateras med aktuella värden varje sekund och att dessa värden sedan lagras i variabler för att sedan vid loggning skriva in medelvärdet under perioden. Tror jag ska börja med att logga var 10 minut så får jag sen se hur ohanterligt det blir. Det blir då 52560 rader på ett år och om jag inte missminner mig så kan excel hantera upp till ~65000 rader.

Jag har nu iaf kommit ganska långt i koden (klar med funktioner för knappar, display och loggning) men har stött på ett litet frågetecken gällande uträkning av Ah och Wh. Vet inte om jag bara är för trött just nu eller vad det beror på men min hjärna vill just nu inte reda ut det för mig.
Jag har gjort en "vy" på displayen som ska visa laddning och förbrukning under det aktuella dygnet (00:00 till 00:00) presenterat i Ah och Wh. Men hur räknar jag ut dessa vid varje uppdatering? Jag kan ju inte ta ström*tid sedan 00:00. För då är det många sollösa timmar som räknas in. Kan man ta den aktuella strömmen under den sekund man uppdaterar och multiplicera med 1 sekund och sedan addera värdet till summan för dygnet? Eller hur ska jag lösa det?


Såhär ser det ut än så länge.
logger.jpg
logger.jpg (123.05 KB) Visad 11546 gånger

Siffrorna som visas på displayen är ännu bara fiktiva för att kunna positionera allt där jag vill ha det.
IR-sensorn tänder och släcker displayen för att spara ström.
Fritte
 
Inlägg: 209
Blev medlem: 09 sep 2008 18:13
Ort: Linköping

Re: Loggning av solenergi

Inläggav Bittämjaren 23 jan 2015 20:43

Det finns ett annat sätt att minska antalet loggningar och ändå ha bra noggranhet på mätserien.
Istället för att hitta en optimalt tidsintervall mellan mellan mätningarna i förhållande till den ohanterligt stora totala mängden insamlad data att ta hand om efter en tid.
Man loggar med tidsstämpel och mätvärde och låter mätutrustningen mäta med täta intervall och jämför med föregående lagrade mätning och när det nya mätvärdet avviker mer än gränsvärdet så sker en ny lagring i loggen som nu blir den senaste lagringen, och det hela upprepas.
Har du ett mätvärde som ändrar sig mycket så blir det blir det täta lagringar i loggen och ett mätvärde som ändrar sig långsamt så blir det långa tidsmellanrum mellan lagringarna i loggen och ändå kan du uppnå en god noggranhet över tiden i loggen.

Här ett exempel på hur det kan bli med en gemensam loggfil från flera källor (datorer), filnamnet innehåller datuminformationen, då blir det en fil om dygnet.
03:10:00* PELV: Inhämtat ny tid: 2007-04-01 03:10:02
03:43:29 Temperatur utomhus är -2.6 °C
03:53:01 Ljusnivå utomhus är 0.011 Lux
03:13:15* VÄRME: Inhämtat ny tid: 2007-04-01 03:13:15
04:50:34 Temperatur utomhus är -2.9 °C
05:34:01 Ljusnivå utomhus är 0.012 Lux
05:52:32 Ljusnivå utomhus är 0.048 Lux
05:53:04 Temperatur utomhus är -3.3 °C
05:56:00 Nattsänkning inne upphört
05:59:40 Ljusnivå utomhus är 0.193 Lux
06:08:30 Ljusnivå utomhus är 0.775 Lux
06:10:00 Nattljus ute frånkopplat
06:13:34 Ljusnivå utomhus är 3.22 Lux
06:19:35 Ljusnivå utomhus är 12.8 Lux
06:40:01 Ljusnivå utomhus är 44.9 Lux
06:42:47 Temperatur utomhus är -3.8 °C
06:46:00 Nattljus inne frånkopplat
07:21:47 Ljusnivå utomhus är 141 Lux
07:27:59 Temperatur utomhus är -3.2 °C
07:51:39 Temperatur utomhus är -2.5 °C
07:59:31 Ljusnivå utomhus är 423 Lux
08:11:36 Temperatur utomhus är -1.7 °C
08:18:40 Temperatur utomhus är -0.8 °C
08:20:00 Ljusnivå utomhus är 1380 Lux
08:22:53 Temperatur utomhus är +0.1 °C
08:30:03 Temperatur utomhus är +1.0 °C
08:35:28 Temperatur utomhus är +2.0 °C
08:42:22 Ljusnivå utomhus är 4160 Lux
08:43:43 Temperatur utomhus är +2.9 °C
09:15:04 Temperatur utomhus är +3.6 °C
09:27:59 Temperatur utomhus är +4.5 °C
09:35:41 Temperatur utomhus är +5.4 °C
09:42:08 Temperatur utomhus är +6.3 °C
09:47:28 Temperatur utomhus är +7.3 °C
09:52:50 Temperatur utomhus är +8.2 °C
09:57:40 Ljusnivå utomhus är 8330 Lux
09:59:03 Temperatur utomhus är +9.1 °C
10:05:45 Temperatur utomhus är +10.1 °C
10:13:15 Temperatur utomhus är +11.0 °C
10:29:15 Temperatur utomhus är +11.8 °C
10:39:57 Fotocell över väg blinkat
10:43:27 Temperatur utomhus är +12.7 °C
10:59:06 Temperatur utomhus är +13.5 °C
11:38:01 Ljusnivå utomhus är 8170 Lux
12:09:06 Temperatur utomhus är +13.8 °C
Är det inte elektriskt !?!... Då är inte jag inblandad
Användarvisningsbild
Bittämjaren
 
Inlägg: 332
Blev medlem: 23 maj 2013 19:15
Ort: FRISTAD

Re: Loggning av solenergi

Inläggav McB 25 jan 2015 20:00

Om du bara vill logga förändringar men uppdatera lcd:n varje sekund så behöver du en bunt med integer för att jämföra då med nu.
Släng upp en kopia av din kod, kan vara en inspiration och ögon öppnare :shock: :D

En försmak av min finns HÄR
Om Jesus Kristus skulle återuppstå och se allt som görs i hans namn, så skulle han aldrig sluta spy.

- Woody Allen
Användarvisningsbild
McB
 
Inlägg: 683
Blev medlem: 19 jun 2009 11:48
Ort: Några mil väster om Vättern.

Re: Loggning av solenergi

Inläggav Fritte 26 jan 2015 00:41

För att styra när det ska loggas och när data ska läsas från regulatorn så använder jag mig av klockan som finns på logger-kortet.
Displayen uppdateras varje varv i loopen vilket är 5ggr per sekund när displayen är tänd. Data hämtas varje sekund och loggning sker var 10:e minut.
Jag fick dessutom modifiera SD.h lite för att kunna ta ur och sätta i kortet under drift. Utan modifieringen så var man tvungen att starta om varje gång man tagit ut kortet.
Sen slog jag även i taket för SRAM så jag har fått spendera en hel del tid på att minnesoptimera så mycket jag kunnat. Så om du ser något jag kan optimera ännu mer så säg gärna till. Har nu iaf lite drygt 400 byte SRAM ledigt.

Här har du min kod.
Ursäkta blandningen av engelska och svenska. Det är en liten ovana jag har. :lol:
Kod: Markera allt
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
#include <RTClib.h>
#include <SPI.h>
#include <SD.h>
#include <DHT.h>

SoftwareSerial myserial(2, 3); // RX, TX
const byte logLEDpin = 5;

uint8_t buff[64];

//Defineing Temp Stuff
#define sensor1 1
#define sensor2 2
#define DHTTYPE DHT11
DHT dht1(sensor1, DHTTYPE);
DHT dht2(sensor2, DHTTYPE);

RTC_DS1307 RTC; // define the Real Time Clock object

//---For the LCD
#define I2C_ADDR    0x27  // Define I2C Address where the PCF8574A is
#define BACKLIGHT_PIN  3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

//SD-logging
const byte chipSelect = 10;
//const byte logLEDpin = 5;
byte logged = 0;
File logfile;

//Buttons
const byte resetBUTTONpin = 6;
const byte prevBUTTONpin = 7;
const byte nextBUTTONpin = 8;
//const byte ??BUTTONpin = 9;

//IR-sensor
const byte irPin = 4;

//Button-variables
byte displayNo = 0;
byte oldDisplayNo = 4;
byte lastResetButtonState = 0;
byte lastPrevButtonState = 0;
byte lastNextButtonState = 0;
//byte last??ButtonState = 0;

//Power variables
float battery_V = 0;  //Aktuell spänning på batteriet
float pv_V = 0;       //Aktuell spänning på solpaneler
float load_A = 0;     //Aktuell strömförbrukning
float loadAlog = 0;   //Använda för att beräkna medel-strömförbrukning under loggningsperiod
float charge_A = 0;   //Aktuell laddström
float chargeAlog = 0; //Använda för att beräkna medel-laddström under loggningsperiod
float chargeAs = 0;   //Laddade As för dygnet
float chargeWs = 0;   //Laddade Ws för dygnet
float loadAs = 0;     //Förbrukade As för dygnet
float loadWs = 0;     //Förbrukade Ws för dygnet
float startVbatt = 0; //Spänning på batt vid start på dygnet för att mäta +/-
float chargeAmax = 0; //Rekordladdström
float chargeWmax = 0; //Rekordladdeffekt
float loadAmax = 0;   //Rekordströmförbrukning
float loadWmax = 0;   //Rekordeffektförbrukning
int numberOfReadings = 0; //Antal avläsningar under loggperioden för att räkna ut medel.
DateTime powerMaxReset;

//Temp variables
float temp1 = 0;        //Aktuell temp inne
float temp2 = 0;        //Aktuell temp ute
byte h1 = 0;            //Aktuell luftfuktighet inne
byte h2 = 0;            //Aktuell luftfuktighet ute
float temp1max = 0;  //Inne-temp max
float temp1min = 0;  //Inne-temp min
float temp2max = 0;  //Ute-temp max
float temp2min = 0;   //Ute-temp min
DateTime tempReset;     //Senast nollställt temp

//Misc variables
byte lastSecond = 0;

LiquidCrystal_I2C       lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
//#####################################SETUP####################################
void setup() {
   Serial.begin(9600);

   myserial.begin(9600);
       
        lcd.begin (20,4,LCD_5x8DOTS);
        lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); // init the backlight
       
        pinMode(resetBUTTONpin, INPUT_PULLUP);
        pinMode(prevBUTTONpin, INPUT_PULLUP);
        pinMode(nextBUTTONpin, INPUT_PULLUP);
      //pinMode(??BUTTONpin, INPUT_PULLUP);
       
        pinMode(irPin, INPUT);
       
        Wire.begin(); 
       
        if (!RTC.begin()) {
          //Serial.println("RTC failed");
        }
       
        //SD-logging
        pinMode(logLEDpin, OUTPUT);
        pinMode(10, OUTPUT);
       
        dht1.begin();
        dht2.begin();
       
        powerMaxReset = RTC.now();
        tempReset = RTC.now();
}
//###################################END SETUP##################################
//#####################################LOOP#####################################
void loop() {   
        DateTime now;
        //Reads time
        now = RTC.now();
        Serial.println(freeRam());
        //Reads button presses
        readButtons();
        //Retrives data every second
        if(now.second() > lastSecond || (now.second() == 0 && lastSecond > 0)){
            lastSecond = now.second();
            readTracerData();
            Serial.println(freeRam());
        }
       
        //Checks that SD-card is inserted
        checkSDcard();
        Serial.println(freeRam());
       
       
        //Logs to SD-card every 10 min.
        if (now.minute() == 0 || now.minute() == 10 || now.minute() == 20 || now.minute() == 30 || now.minute() == 40 || now.minute() == 50) {
            if(logged == 0){
                readTemp();
                digitalWrite(logLEDpin, HIGH);
                doLogging(now); //Does the logging
                logged = 1;
            }
        }else{
            logged = 0;
         digitalWrite(logLEDpin, LOW);
        }
       
       
        //Check IR-sensor and turns on the display
        if(digitalRead(irPin) == HIGH){
            lcd.setBacklight(HIGH);
            //Show the selected display.
            selectDisplay(now);
            Serial.println(freeRam());
        }else{
            lcd.setBacklight(LOW);
            delay(800);
        }
        lcd.setCursor (9,1);
        lcd.print(freeRam());
   delay(200);
}
//###################################End LOOP#####################################
//###################################FUNKTIONS####################################
int freeRam ()
{
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
//-----------------------------Läs in knappar ------------------------------------
void readButtons(){   
      if(digitalRead(resetBUTTONpin) == LOW && lastResetButtonState == HIGH){
        //Reset min max temp data
        if(displayNo == 5){
          temp1max = 0;
          temp1min = 0;
          temp2max = 0;
          temp2min = 0;
          tempReset = RTC.now();
        }
        //Reset load/charge top records
        if(displayNo == 2){
          chargeAmax = 0;
          chargeWmax = 0;
          loadAmax = 0;
          loadWmax = 0;
          powerMaxReset = RTC.now();
        }
      }
      if(digitalRead(nextBUTTONpin) == LOW && lastNextButtonState == HIGH){
        displayNo++;
        lcd.clear();
        if(displayNo>5)
          displayNo=0;
      }
      if(digitalRead(prevBUTTONpin) == LOW && lastPrevButtonState == HIGH){
        displayNo--;
        lcd.clear();
        if(displayNo>5)
          displayNo=5;
      }
   
      lastResetButtonState = digitalRead(resetBUTTONpin);
      lastNextButtonState = digitalRead(nextBUTTONpin);
      lastPrevButtonState = digitalRead(prevBUTTONpin);
      //last??ButtonState = digitalRead(??BUTTONpin);
}

//---------------------------Select Screen to display -----------------------------
void selectDisplay(DateTime now){
      switch(displayNo){
          case 0:
            displayRealtime(now);
            break;
          case 1:
            displayAverage(now);
            break;
          case 2:
            displayMaxPower();
            break;
          case 3:
            displayMPPTgain();
            break;
          case 4:
            displayTemp();
            break;
          case 5:
            displayTempMinMax();
            break;
      }
      oldDisplayNo = displayNo;
}
//-------------------------------Check SD-card----------------------------------------
void checkSDcard(){
      if (!SD.begin(chipSelect)) {
          //Serial.println ("No card in slot!");
          lcd.clear(); // clear display, set cursor position to zero
          lcd.setBacklight(HIGH);     // Backlight on
          lcd.setCursor (2,0);
          lcd.print(F("No card in slot!"));
          while(!SD.begin(chipSelect));
          lcd.clear();
      }
}

//---------------------------Läser data från Tracer-----------------------------------
void readTracerData(){
   //Serial.println("Reading from Tracer");
       
   uint8_t start[] = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xEB, 0x90, 0xEB, 0x90, 0xEB, 0x90 };
   uint8_t id = 0x16;
   uint8_t cmd[] = { 0xA0, 0x00, 0xB1, 0xA7, 0x7F };
       

       
   myserial.write(start, sizeof(start));
   myserial.write(id);
   myserial.write(cmd, sizeof(cmd));

   int read = 0;

   for (int i = 0; i < 255; i++){
      if (myserial.available()) {
         buff[read] = myserial.read();
         read++;
      }
   }
        Serial.println(freeRam());
       
        battery_V = to_float(buff, 9);  //Batterispänning
        pv_V = to_float(buff, 11);      //Panelspänning
        load_A = to_float(buff, 15);    //Lastström
        charge_A = to_float(buff, 30);  //Laddström
       
        //För att räkna ut medel under loggperioden
        chargeAlog = chargeAlog + charge_A;
        loadAlog = loadAlog + load_A;
       
        //För att räkna ut effekten under dagen
        loadAs = loadAs + (load_A);
        loadWs = loadWs + (load_A*battery_V);
        chargeAs = chargeAs + (charge_A);
        chargeWs = chargeWs + (charge_A*battery_V);
       
        //Kolla rekord
        if(charge_A > chargeAmax)
          chargeAmax = charge_A;
        if((charge_A * battery_V) > chargeWmax)
          chargeWmax = charge_A * battery_V;
        if(load_A > loadAmax)
          loadAmax = load_A;
        if((load_A * battery_V) > loadWmax)
          loadWmax = load_A * battery_V;
       
        //Antal läsningar för att räkna ut medel till loggning 
        numberOfReadings++;

}
//----------------------------------Tracer-------------------------------------
float to_float(uint8_t* buffer, int offset){
   unsigned short full = buffer[offset+1] << 8 | buff[offset];

   return full / 100.0;
}
//---------------------------Reads temperatures-------------------------------------
void readTemp(){
      float h1 = dht1.readHumidity();
      float temp1 = dht1.readTemperature();
      float h2 = dht2.readHumidity();
      float temp2 = dht2.readTemperature();
     
      // Check if any reads failed.
      if (isnan(h1) || isnan(temp1) || isnan(h2) || isnan(temp2)) {
          return;
      }
}
//-----------------------------Logs to SD-card---------------------------------------
void doLogging(DateTime nu){
  char filename[]="2014.csv";
  //Sets filename to the year. eg. 2015.csv
  char extension[] = "CSV";
  sprintf(filename,"%04u.%s",nu.year(),extension);
  logfile = SD.open(filename, FILE_WRITE);
  if (logfile) {
    //digitalWrite(logLEDpin, HIGH);

    char dateBuffer[10];
    // log time
    sprintf(dateBuffer,"%04u-%02u-%02u",nu.year(),nu.month(),nu.day());
    logfile.print(dateBuffer);
    logfile.print(F(","));
    sprintf(dateBuffer,"%02u:%02u:%02u",nu.hour(),nu.minute(),nu.second());
    logfile.print(dateBuffer);
    logfile.print(F(","));
    logfile.print(battery_V);
    logfile.print(F(","));
    logfile.print((chargeAlog/numberOfReadings));
    logfile.print(F(","));
    logfile.print((loadAlog/numberOfReadings));
    logfile.print(F(","));
    logfile.print(temp1);
    logfile.print(F(","));
    logfile.print(h1);
    logfile.print(F(","));
    logfile.print(temp2);
    logfile.print(F(","));
    logfile.print(h2);
    logfile.println();
    numberOfReadings = 0;
    loadAlog = 0;
    chargeAlog = 0;
  }
  logfile.close();
}
//--------------------Skriver ut på lcd med formatet 000.0---------------------
void formatDigitsLCD(float digits){
  if(digits <= 999.96){
    if(digits <= 99.96)
      lcd.print(F(" "));
    if(digits < 9.96)
      lcd.print(F(" "));
    lcd.print(digits,1);
  }else{
    if(digits < 9999.96)
      lcd.print(F(" "));
    lcd.print((digits/1000),1);
    lcd.print(F("k"));
  }
}
//###################################END FUNKTIONS##################################
//#####################################DISPLAYS#####################################
//-----------------------------Visar RealtidsInfo----------------------------------
void displayRealtime(DateTime nu){
  char dateBuffer[10];
  sprintf(dateBuffer,"%02u:%02u:%02u",nu.hour(),nu.minute(),nu.second());
  lcd.setCursor (2,0);
  if(oldDisplayNo != displayNo)
      lcd.print(F("PV           LOAD"));
  lcd.setCursor (6,0);
  lcd.print(dateBuffer);
  lcd.setCursor (0,1);
  formatDigitsLCD(charge_A);
  if(oldDisplayNo != displayNo)
      lcd.print(F("A             A"));
  lcd.setCursor (14,1);
  formatDigitsLCD(load_A);
  lcd.setCursor (0,2);
  formatDigitsLCD((charge_A*battery_V));
  if(oldDisplayNo != displayNo)
      lcd.print(F("W  BATT       W"));
  lcd.setCursor (14,2);
  formatDigitsLCD((load_A*battery_V));
  lcd.setCursor (7,3);
  lcd.print(battery_V);
  if(oldDisplayNo != displayNo)
      lcd.print(F("V"));
}
//--------------------------------Visar Medel------------------------------
void displayAverage(DateTime nu){
  char dateBuffer[10];
  sprintf(dateBuffer,"%02u%02u%02u",nu.year()%100,nu.month(),nu.day());
  lcd.setCursor (0,0);
  if(oldDisplayNo != displayNo)
      lcd.print(F("CHARGE          LOAD"));
  lcd.setCursor (7,0);
  lcd.print(dateBuffer);
  lcd.setCursor (0,1);
  formatDigitsLCD((chargeAs/3600));
  if(oldDisplayNo != displayNo)
      lcd.print(F("Ah           Ah"));
  lcd.setCursor (13,1);
  formatDigitsLCD((loadAs/3600));
  lcd.setCursor (0,2);
  formatDigitsLCD((chargeWs/3600));
  if(oldDisplayNo != displayNo)
      lcd.print(F("Wh           Wh"));
  lcd.setCursor (13,2);
  formatDigitsLCD((loadWs/3600));
  lcd.setCursor (0,3);
  if(charge_A < 0){
    lcd.print(F("BATT: "));
    if((battery_V-startVbatt)>0){
      lcd.print(F("+"));
    }
    lcd.print((battery_V-startVbatt));
    lcd.print(F("V"));
  }else{
    lcd.print(F("             "));
  }
}
//---------------------------Visar Max Power----------------------------
void displayMaxPower(){
  lcd.setCursor (0,0);
  if(oldDisplayNo != displayNo)
      lcd.print(F("CHARGE   MAX    LOAD"));
  lcd.setCursor (0,1);
  formatDigitsLCD(chargeAmax);
  if(oldDisplayNo != displayNo)
      lcd.print(F("A             A"));
  lcd.setCursor (14,1);
  formatDigitsLCD(loadAmax);
  lcd.setCursor (0,2);
  formatDigitsLCD(chargeWmax);
  if(oldDisplayNo != displayNo)
      lcd.print(F("W             W"));
  lcd.setCursor (14,2);
  formatDigitsLCD(loadWmax);
  lcd.setCursor(1,3);
  if(oldDisplayNo != displayNo)
      lcd.print (F("Sedan:"));
  char dateBuffer[10];
  sprintf(dateBuffer,"%02u%02u%02u",powerMaxReset.year()%100,powerMaxReset.month(),powerMaxReset.day());
  lcd.setCursor (7,3);
  lcd.print(dateBuffer);
  lcd.print(F(" "));
  sprintf(dateBuffer,"%02u:%02u",powerMaxReset.hour(),powerMaxReset.minute());
  lcd.print(dateBuffer);
}
//---------------------------Visar MPPT Effekt----------------------------
void displayMPPTgain(){
  lcd.setCursor (1,0);
  if(oldDisplayNo != displayNo)
      lcd.print(F("VINST MPPT MOT PWM"));
  lcd.setCursor (1,1);
  if(oldDisplayNo != displayNo)
      lcd.print(F("Vinst i A:      A"));
  lcd.setCursor (12,1);
  formatDigitsLCD((charge_A-(charge_A*battery_V/pv_V)));
  lcd.setCursor (1,2);
  if(oldDisplayNo != displayNo)
      lcd.print(F("Vinst i W:      W"));
  lcd.setCursor (12,2);
  formatDigitsLCD(((charge_A*battery_V)-(charge_A*battery_V/pv_V*battery_V)));
  lcd.setCursor(1,3);
  if(oldDisplayNo != displayNo)
      lcd.print (F("Vinst i %:      %"));
  lcd.setCursor(12,3);
  formatDigitsLCD(((charge_A-(charge_A*battery_V/pv_V))/(charge_A*battery_V/pv_V)*100));
}
//-------------------------------Visar Temp------------------------------
void displayTemp(){
  lcd.setCursor (2,0);
  if(oldDisplayNo != displayNo)
      lcd.print(F("INNE  TEMP  UTE"));
  lcd.setCursor (0,1);
  lcd.print(F("T"));
  lcd.setCursor (2,1);
  lcd.print(temp1, 1);
  lcd.print(F(" C"));
  lcd.setCursor (12,1);
  lcd.print(F("T"));
  lcd.setCursor (14,1);
  lcd.print(temp2, 1);
  lcd.print(F(" C"));
  lcd.setCursor (0,2);
  lcd.print(F("H"));
  lcd.setCursor (2,2);
  lcd.print(h1);
  lcd.print(F("%"));
  lcd.setCursor (12,2);
  lcd.print(F("H"));
  lcd.setCursor (14,2);
  lcd.print(h2);
  lcd.print(F("%"));
}
//---------------------------Visar Max/Min Temp----------------------------
void displayTempMinMax(){
  lcd.setCursor (2,0);
  if(oldDisplayNo != displayNo)
      lcd.print(F("INNE  TEMP  UTE"));
  lcd.setCursor (0,1);
  lcd.print(F("M"));
  lcd.setCursor (1,1);
  formatDigitsLCD(temp1max);
  lcd.print(F(" C"));
  lcd.setCursor (12,1);
  lcd.print(F("M"));
  lcd.setCursor (13,1);
  formatDigitsLCD(temp2max);
  lcd.print(F(" C"));
  lcd.setCursor (0,2);
  lcd.print(F("m"));
  lcd.setCursor (1,2);
  formatDigitsLCD(temp1min);
  lcd.print(F(" C"));
  lcd.setCursor (12,2);
  lcd.print(F("m"));
  lcd.setCursor (13,2);
  formatDigitsLCD(temp2min);
  lcd.print(F(" C"));
  lcd.setCursor (1,3);
  if(oldDisplayNo != displayNo)
      lcd.print (F("Sedan:"));
  char dateBuffer[10];
  sprintf(dateBuffer,"%02u%02u%02u",tempReset.year()%100,tempReset.month(),tempReset.day());
  lcd.setCursor (7,3);
  lcd.print(dateBuffer);
  lcd.print(F(" "));
  sprintf(dateBuffer,"%02u:%02u",tempReset.hour(),tempReset.minute());
  lcd.print(dateBuffer);
}
//###################################END DISPLAYS#####################################
Fritte
 
Inlägg: 209
Blev medlem: 09 sep 2008 18:13
Ort: Linköping

Re: Loggning av solenergi

Inläggav McB 26 jan 2015 20:12

Förstår att du lider minnes brist med alla float du har,
Floating-point numbers can be as large as 3.4028235E+38 and as low as -3.4028235E+38. They are stored as 32 bits (4 bytes) of information.

Mot integer: int stores a 16-bit (2-byte) value. This yields a range of -32,768 to 32,767 (minimum value of -2^15 and a maximum value of (2^15) - 1). Om du inte har Arduino Due för då integer 32 bit också.

Byte: stores an 8-bit unsigned number, from 0 to 255.

Undvik float om du inte måste exempelvis på temperatur då tiondelar av en grad sällan är viktiga.

Du kan alltid plocka ut värdet i float och runda av det med lite matte och lägga det i en int eller byte beroende på vad som passar.


Denna raden kan nog behöva ändras med tanke på integer
int numberOfReadings = 0; //Antal avläsningar under loggperioden för att räkna ut medel.

Beroende på körtid i ett svep kan den behöva vara "long"
Long variables are extended size variables for number storage, and store 32 bits (4 bytes), from -2,147,483,648 to 2,147,483,647.

Hur lång loggperioden är avgör det och hur länge en int räcker med nuvarande loggtäthet, behöver lite matte för för eller senare slår int om och vad händer då?
Om Jesus Kristus skulle återuppstå och se allt som görs i hans namn, så skulle han aldrig sluta spy.

- Woody Allen
Användarvisningsbild
McB
 
Inlägg: 683
Blev medlem: 19 jun 2009 11:48
Ort: Några mil väster om Vättern.

Re: Loggning av solenergi

Inläggav Fritte 26 jan 2015 23:06

Jo, jag vet att jag har många float och att det förbrukar mycket minne. Men jag är lite (onödigt :roll: ) pedant när det gäller siffror och vill försöka undvika att avrunda så mycket som möjligt då varje avrundning skapar en större felmarginal i slutänden. Men om jag i framtiden behöver mer minne så får jag nog kompromissa lite. Gällande loggperioden och variabeln numberOfReadings så är jag medveten om begränsningen men det är inget problem så länge jag inte vill öka loggperioden.

Jag känner mig just nu hyfsat klar förutom lite småjusteringar i koden och att jag fortfarande väntar på att få hem temperatursensorerna.
Så i väntan på dessa så gav jag mig på att bygga in allt i en "liten" låda.
logger.jpg
logger.jpg (114.45 KB) Visad 11419 gånger

Det finns mycket luft i den lådan men den får duga för stunden.

Det har hittills varit ett mycket roligt och lärorikt projekt då jag inte har pysslat med Arduino eller mikroprocessorer tidigare.
Nu ska jag läsa på vad jag kan göra för att optimera strömförbrukningen också då den för tillfället mumsar i sig hela 76mA när displayen är släkt och 120mA med tänd skärm.
Fritte
 
Inlägg: 209
Blev medlem: 09 sep 2008 18:13
Ort: Linköping

Re: Loggning av solenergi

Inläggav McB 27 jan 2015 15:19

Snyggt byggt :D

Finns ett sleepmode att nyttja men du kan inte logga något under tiden och den måste väckas med interrupt, en watchdog timer interrupt eller en händelse på USART.
Om du har 10 minuter mellan loggningar så kan den sova där emellan och kommer någon fram till den kan IR grunkan också väcka den via en interrupt.
Men ir tar ström liksom display så att väcka den och tända LCD kanske ska göras med en knapp istället?

Men det är inte säkert det ger särskilt mycket då det mesta går åt i strömregulatorn.
Vet ju inte vilket kort du har men vissa så som PRO går att få riktigt snåla.
Om Jesus Kristus skulle återuppstå och se allt som görs i hans namn, så skulle han aldrig sluta spy.

- Woody Allen
Användarvisningsbild
McB
 
Inlägg: 683
Blev medlem: 19 jun 2009 11:48
Ort: Några mil väster om Vättern.

Re: Loggning av solenergi

Inläggav Bittämjaren 27 jan 2015 21:27

Mitt program är skrivet i Q-BASIC som följde med DOS 5 en gång i tiden, om jag minns rätt. Jag har tittat i det men inte hittat hur jag har gjort. Jag hade en annan finess i det och principen var följande: Man läste in mätvärdet flera ggr i sekunden gjorde en del filtreringar och annat för att bli av med skräp (felläsningar, störningar mm) sedan jämfördes mätvärdet med föregående sparade värde och kollades mot en variabel innehållande värdet för maximal avvikelse och så länge mätvärdet är mindre än maximal avvikelse så sparas inget och värdet i maximal avvikelse minskas något, detta fortgår tills mätvärdet är större än maximal avvikelsevärde (som minskade hela tiden) och mätvärdet sparas med tidsstämpel och värdet i maximal avvikelse ställs på sitt maximala startvärde igen
Det man uppnår med detta är att mätvärden sparas ofta bara om de har ändrat i värde.
Genom att minska på det maximala avvikelsefönstret med tiden så kommar man förr eller senare att spara mätvärden som inte ändrar sig när fönstret har kommit ned till 0. När ett mätvärde sparas så ställs fönstret upp på sitt största värde igen.
Efter det att ett mätvärde (utetemperatur) sparades ställdes avvikelsefönstret på +-1,5°C som krympte till 0,0°C efter 90 min och resultatet kan ses i listan längre upp i tråden som visar 12 tim av ett dygn.
Är det inte elektriskt !?!... Då är inte jag inblandad
Användarvisningsbild
Bittämjaren
 
Inlägg: 332
Blev medlem: 23 maj 2013 19:15
Ort: FRISTAD

Re: Loggning av solenergi

Inläggav Fritte 27 jan 2015 23:48

Tack.
Det är en Uno jag använder.
Jag hittade sleepmode och använde mig av detta bibliotek för att implementera det.
Så nu kör jag en sleep på 1 sekund, läser värdena, sleep igen osv tills det är dax och logga. När skärmen är tänd så kör jag bara sleep i 200ms för att få bra respons på knapparna. Jag fick ner strömförbrukningen till 100mA med tänd skärm och 47mA med släkt skärm. Känner mig hyfsat nöjd där.
Så nu går jag bara och väntar på nästa tur till stugan så jag kan installera den nya regulatorn och mitt bygge.

Men... Varför blir man aldrig riktigt klar med projekt som dessa? :evil:
Jag har inte satt denna i drift än men har redan börjat att fundera på att bygga en version 2 med gsm-modul så den kan skicka loggarna till mig med jämna mellanrum. Kollade tidigare idag med Telia ang deras kontantkort med debiterbar datatrafik (10kr/Mb) om det fanns någon minimidebitering på dataförbrukningen, det fanns det tydligen inte utan de debiterar ören om man bara använder lite data. Och med den "mängden" data som jag loggar blir det inte många kronor per år för att sända allt till en webbsida med jämna mellanrum. Skulle räcka att ladda kortet 1 gång per år med 50kr som är den minsta avgiften.
Fritte
 
Inlägg: 209
Blev medlem: 09 sep 2008 18:13
Ort: Linköping

Re: Loggning av solenergi

Inläggav McB 29 jan 2015 18:50

Undrar hur stor förbrukningen blir utan IR???
Det kanske inte gör så mycket som man kan tro!!!

Så länge det finns minne att jobba med så vill man bygga vidare.
Du kan maila eller skicka upp loggen på en filtjänst hyffsat smidigt.
Om Jesus Kristus skulle återuppstå och se allt som görs i hans namn, så skulle han aldrig sluta spy.

- Woody Allen
Användarvisningsbild
McB
 
Inlägg: 683
Blev medlem: 19 jun 2009 11:48
Ort: Några mil väster om Vättern.

Re: Loggning av solenergi

Inläggav Fritte 29 jan 2015 22:24

Jo, det är ju det där med minne... Har just nu ungefär 200 byte ledigt för att utöka programmet. :|
Detta projekt har iaf gett mig blodad tand och jag beställt en Mega-klon och en gsm-sköld på ebay för sammanlagt 300kr. Får se om de används till en version 2 eller om jag hittar på något annat kul med det.
Fritte
 
Inlägg: 209
Blev medlem: 09 sep 2008 18:13
Ort: Linköping

Nästa

Återgå till Projekt

Vilka är online

Användare som besöker denna kategori: Inga registrerade användare och 7 gäster

cron