Zum Test der Sensoren bzw. der Sensorkonfiguration sowie der Sleep-Funktionen beim beelogger-Solar und beelogger-Universal (erweiterte Ausbaustufe) und zur Kalibrierung der Spannungsüberwachung stehen mehrere Sketche zur Verfügung.
Hierzu gehören die Einstellung und Alarmfunktion der RTC (Echtzeituhr), der Test des Temperatursensors der RTC, der Sleep-Mode des ATmega, welcher durch den Alarm der RTC über einen Interrupt aufgeweckt wird, das Auslesen der Akku- und Solarspannung, sowie die Akku-Schutzfunktion. Für den Test-Programmcode werden daher keine Sensoren oder Module benötigt.
Der System-Check-Sketch testet Sensoren und konfigurierbar diverse Systemfunktionen.
Der Test-Programmcode ermöglicht es die speziellen Funktionen des beelogger-Solar und beelogger-Universal (erweiterte Ausbaustufe) für den Sleep-Mode zu testen.
Der Kalibrierung-Programmcode dient dazu, die fertigungsbedingten Toleranzen der verwendeten Bauteile eines beelogger-Solar und beelogger-Universal (erweiterte Ausbaustufe) bei der Spannungsmessung von Akku und Solarzelle auszugleichen. Da die Akkuspannung für eine Software-Funktion zum Akku-Schutz verwendet wird, ist die Kalibrierdung zwingen notwendig, damit der Test- und Haupt-Programmcode lauffähig ist.
Libraries
<Wire.h>
– in der Arduino-Software bereits enthalten
<Sodaq_DS3231.h>
– https://github.com/SodaqMoja/Sodaq_DS3231
<LowPower.h>
– https://github.com/rocketscream/Low-Power
Kalibrierung-Programmcode
für beelogger-Solar und beelogger-Universal (erweiterte Ausbaustufe)
Alle elektronischen Komponenten des beeloggers mit seinen Spannungsreglern, Widerständen und dem ATmega unterliegen fertigungsbedingten Toleranzen. Um diese Toleranzen bei der Messung der Spannung von Akku und Solarzelle möglichst gut zu kompensieren, muss eine Kalibrierung für jeden beelogger-Solar durchgeführt werden. Hierfür sind zwei Werte zu ermitteln:
- Kalib_Spannung
- Kalib_Bitwert
Für die Variable ‘Kalib_Spannung’ sollte mit einem möglichst hochwertigen Multimeter die Spannung des Akkus direkt gemessen und in Millivolt hinterlegt werden. Der Akku sollte bei dieser Messung gut geladen und nicht eingebaut sein.
Der Wert der Variable ‘Kalib_Bitwert’ wird über den Kalibrierung-Programmcode ermittelt. Dieser Wert gibt die mit allen Toleranzen gemessene Akku-Spannung durch den beelogger-Solar wieder.
Kalibrieriert wird mit diesem Sketch der Spannungsteiler bestehend aus B-R1 und B-R2. Ein Wechsel des LiIon-Akku erfordert keine neue Kalibrierung.
Für die Messung der Solarspannung werden die gleichen Werte zur Kompensation verwendet, da diese Messung ohnehin nur eine Momentaufnahme darstellt und auch keine weiteren Auswirkungen auf den Programmablauf hat.
Der Programmcode zur Kalibrierung initialisiert auch die RTC, so dass diese über den RTC-Batterieanschluß automatisch weiterläuft, wenn die normale Spannungsversorgung fehlt.
Bevor der Kalibrierung-Programmcode aufgespielt wird, muss die Spannung des Akkus in Millivolt in der Variable ‘Kalib_Spannung’ hinterlegt werden. Wenn der FTDI-Adapter das System zusätzlich mit Strom versorgt, könnte dieser das Ergebnis der Spannungsmessung bzw. Kalibrierung beeinflussen. Daher sollte nach dem Upload und vor der Ausführung des Kalibrierung-Programmcode, VCC des FTDI-Adapters vom beelogger-Solar getrennt werden, damit das System ausschließlich vom Akku versorgt wird. Die serielle Konsole wird hierbei weiterhin funktionieren.
Hinweis: Je nach Ausführung des FTDI-Adapters, kann durch Entfernen des Spannungsjumpers am FTDI-Adapter die Versorgung durch den FTDI getrennt werden.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
/* * (C) 2018 R.Schick / Thorsten Gurzan - beelogger.de * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * Version 2.0 */ // beelogger.de - Arduino Datenlogger für Imker // Erläuterungen dieses Programmcodes unter https://beelogger.de #include <Sodaq_DS3231.h> #include <Wire.h> int Kalib_Spannung = 1000; //Hier ist der gemessene Wert der Akkuspannung in Millivolt einzutragen int Kalib_Bitwert = 0; float Batteriespannung = 999.99; byte Power_Pin=4; void setup() { Serial.begin(9600); Serial.println("beelogger Kalibrierung 09.10.2019"); pinMode(Power_Pin, OUTPUT); digitalWrite(Power_Pin, HIGH); delay(5); Serial.println("Starte Uhrbaustein:"); Serial.flush(); rtc.begin(); rtc.setDateTime(1); digitalWrite(Power_Pin, LOW); Serial.println("Uhrbaustein initialisiert."); Serial.flush(); if (Kalib_Spannung == 0) { Serial.println("Kein Wert fuer 'Kalib_Spannung' eingetragen."); Serial.println("Die Kalibrierung kann nicht durchgefuehrt werden."); while(true){}; } Kalib_Bitwert = analogRead(A6); Kalib_Bitwert = 0; for(byte j=0 ;j < 16; j++) { Kalib_Bitwert += analogRead(A6); } Kalib_Bitwert = Kalib_Bitwert >>2; Serial.print("Hinterlegter Wert fuer 'Kalib_Spannung': "); Serial.println(Kalib_Spannung); Serial.println(); Serial.print("Gemessener Wert fuer 'Kalib_Bitwert': "); Serial.println(Kalib_Bitwert); Serial.println(); Batteriespannung = (map(Kalib_Bitwert, 0, Kalib_Bitwert, 0, Kalib_Spannung)) / 1000.0; Serial.print("Die mit dieser Kalibrierung ermittelte Akkuspannung betraegt:"); Serial.print(Batteriespannung); Serial.println(" V"); Serial.println(); } void loop() { } |
Ausgabe des seriellen Monitors (9600 baud):
1 2 3 4 5 6 7 8 9 |
beelogger Kalibierung Starte Uhrbaustein: Uhrbaustein initialisiert. Hinterlegter Wert fuer 'Kalib_Spannung': 3754 Gemessener Wert fuer 'Kalib_Bitwert': 1483 Die mit dieser Kalibrierung ermittelte Akkuspannung betraegt:3.75 V |
Programmcode downloaden:
Download
Test-Programmcode
für beelogger-Solar und beelogger-Universal (erweiterte Ausbaustufe)
Im Programmcode ist zunächst das Weckintervall in Stunden und Minuten anzugeben. Mit diesem regelmäßigen Intervall wird der ATmega aus dem Schlafmodus geweckt, um Messungen und den Versand der Daten vorzunehmen. Hierfür stehen die Variablen ‘WeckIntervallStunden’ und ‘WeckIntervallMinuten’ zur Verfügung.
Der Test-Programmcode wurde mit einem Intervall von einer Minute vorkonfiguriert. Generell ist es bei einem regelmäßigen Intervall nicht notwenig, zuvor die korrekte Uhrzeit einzustellen. Für eigene Entwicklungen oder zukünftige Erweiterungen wurde diese Option jedoch im Programmcode aufgenommen. Hierfür übernimmt die RTC die Uhrzeit aus dem Programmcode, die automatisch während der Compilierung im Rahmen des Uploads auf den ATmega hinterlegt wird. Voraussetzung ist natürlich eine korrekt eingestellte Uhrzeit am PC.
Der Programmcode stellt zudem sicher, dass zukünftig automatisch mit dem Upload des Test- oder Haupt-Programmcodes, die korrekte Uhrzeit der RTC eingestellt werden kann.
Der Programmcode enthält zudem zwei besondere Funktionen, die speziell für den Akku- bzw. Solarbetrieb entwickelt wurden:
- Um den Akku zu schonen und ihm somit eine lange Lebensdauer zu ermöglichen, kann über die Variable ‘VMinimum’ die maximale Spannung eingestellt werden, ab der keine Messungen und auch kein Versand von Daten mehr erfolgt. Aber auch um den korrekten Betrieb des GSM-Moduls, welches eine minimale Spannung von 3,8V benötigt, sicherzustellen, kann die Funktion eingesetzt werden. Diese Lösung ersetzt natürlich keine im Akku integrierte Schutzschaltung vor Tiefenentladung
- Damit der beelogger auch während einer längeren Zeitspanne ohne Aufladung (beispielsweise im Winter mit zugescheiten Solarzellen) Sensordaten ermittelt und versendet, kann über die Variable ‘VAlternativ’ die maximale Spannung eingestellt werden, ab der das Weckintervall verändert bzw. verlängert wird. Die Länge dieses temporären Weckintervalls wird über ‘AlternativIntervallStunden’ und ‘AlternativIntervallMinuten’ eingestellt.
Beispiel:
WeckIntervallMinuten = 30
VMinimum = 3.75 // 11.5 – 12V Akku
VAlternativ = 3.8 // 11.9 – 12V Akku
AlternativIntervallMinuten = 180
Bei einer Spannung die höher ist als 3,8V, werden die Messwerte wie in den Intervallen konfiguriert (hier 30 min) abgefragt und versendet. Ab einer Spannung von 3,8V und geringer, werden Messungen und Versand der Daten nur noch alle 3 Stunden (180min) durchgeführt. Bei einer Spannung die kleiner oder gleich 3,75V ist, werden weder Messungen vorgenommen, noch Daten versendet. Solabld der Akku durch die Solarzelle aufgeladen wird und die Akkuspannung die eingestellten Werte erreicht bzw. überschreitet, nimmt der beelogger seinen Betrieb wieder auf.
Da der Test-Programmcode weder Sensoren, noch einen nRF24L01 oder ein GSM-Modul verwendet, dient diese Erläuterung primär der Konfiguation des Haupt-Programmcodes für den beelogger.
Die Batterie CR1220 des DS3231 muss für den Test eingelegt sein, da auch die RTC während der Schlafphase von der Stromversorgung getrennt wird, um eine weitere Stromeinsparung zu erreichen. Alternativ kann mit Hilfe der Lötfelder, wie unter Aufbau beschrieben, der Batterieanschluss der RTC mit dem LiIon-Akku verbunden werden.
Diese Option nicht bei EE-Prom-Systemen verwenden.
Die RTC verfügt zudem über einen eingebauten Temperatursensor. Sofern kein oder nur ein Temperatursensor aktiviert ist und keine andere Konfiguration vorgenommen wurde, liefert die RTC im Haupt-Programmcode die Daten für ‘TempOut’, welche auch für die Temperaturkompensation der Stockwaage verwendet wird.
Ohne die Werte der Kalibrierung für die Spannungsmessung, wird immer eine Batteriespannung von 0V ermittelt. Dadurch greift der Programmcode zum Schutz des Akkus und es wird nach der Messung der Akkuspannung keine weitere Aktion mehr vorgenommen. Diese zuvor ermittelten Werte sind somit vor dem Upload einzutragen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
/* * (C) 2019 R.Schick / Thorsten Gurzan - beelogger.de * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // beelogger.de - Arduino Datenlogger für Imker // Erläuterungen dieses Programmcodes unter https://beelogger.de #include <Sodaq_DS3231.h> #include <Wire.h> #include <LowPower.h> // Intervalle //---------------------------------- byte WeckIntervallMinuten = 1; byte AlternativIntervallMinuten = 6; float VAlternativ = 3.8; // Minimale Spannung ab der automatisch das alternative Intervall aktiviert wird float VMinimum = 3.75; // Minimale Spannung ab der keine Messungen und auch kein Versand von Daten erfolgt //---------------------------------- // Kalibrierung //---------------------------------- int Kalib_Spannung = 1000; // Hier muss der Wert aus der Kalibrierung eingetragen werden int Kalib_Bitwert = 100; // Hier muss der Wert aus der Kalibrierung eingetragen werden //---------------------------------- float Batteriespannung = 999.99; float Solarspannung = 999.99; float RTCTemp; volatile bool ok_sleep = false; #define USB_RX 0 // Pin 0 RX-USB #define USB_TX 1 // Pin 1 TX-USB #define DS3231_Interrupt_Pin 2 #define Power_Pin 4 #define Batterie_messen A6 #define Solarzelle_messen A7 void setup() { Serial.begin(9600); Serial.println("beelogger Test 08.11.2019 "); Serial.println("beelogger Test Uhr, Kalibrierwerte und On/Off: "); pinMode(Power_Pin, OUTPUT); digitalWrite(Power_Pin, HIGH); if ( Kalib_Bitwert == 100) { Serial.println(); Serial.println(); Serial.println("Bitte Kalibrierwerte eintragen! "); Serial.println("Bitte Kalibrierwerte eintragen! "); Serial.println("Bitte Kalibrierwerte eintragen! "); Serial.println(); Serial.println(); WeckIntervallMinuten = 10; } Spannungen_messen(); delay(5); rtc.begin(); DateTime pc_tim = DateTime(__DATE__, __TIME__); long l_pczeit = pc_tim.get(); DateTime aktuell = rtc.now(); long l_zeit = aktuell.get(); if (l_pczeit > l_zeit) rtc.setDateTime(pc_tim.get()); rtc.clearINTStatus(); pinMode(DS3231_Interrupt_Pin, INPUT_PULLUP); ok_sleep = true; delay(5); display_time(); display_interval(); Alarm_konfigurieren(); SleepNow(false); } void loop() { Spannungen_messen(); display_time(); display_temp(); display_interval(); Alarm_konfigurieren(); SleepNow(true); } void display_time() { DateTime aktuell = rtc.now(); Serial.print("Datum und Uhrzeit: "); Serial.print(aktuell.date(), DEC); Serial.print('.'); Serial.print(aktuell.month(), DEC); Serial.print('.'); Serial.print(aktuell.year(), DEC); Serial.print(' '); Serial.print(aktuell.hour(), DEC); Serial.print(':'); Serial.print(aktuell.minute(), DEC); Serial.print(':'); Serial.print(aktuell.second(), DEC); Serial.println(); Serial.flush(); } void display_temp() { RTCTemp = rtc.getTemperature(); Serial.print("Temperatur ueber Sensor in RTC: "); Serial.println(RTCTemp); Serial.println(); Serial.flush(); } void display_interval() { Serial.println(); Serial.print("Eingestelltes Weckintervall: "); Serial.print(WeckIntervallMinuten); Serial.println(" Minute(n)"); Serial.flush(); } void Spannungen_messen() { Batteriespannung = Messe_Spannung(Batterie_messen); Serial.print(F(" Batterie [V]: ")); Serial.println(Batteriespannung); Serial.flush(); if (Batteriespannung > VMinimum) { Solarspannung = Messe_Spannung(Solarzelle_messen); Serial.print(F(" Solarspannung [V]: ")); Serial.println(Solarspannung); Serial.flush(); } } float Messe_Spannung (byte Pin) { int Messung_Spannung; float Spannung; Messung_Spannung = analogRead(Pin); Messung_Spannung = 0; for (byte j = 0 ; j < 16; j++) { Messung_Spannung += analogRead(Pin); } Messung_Spannung = Messung_Spannung >> 2; Spannung = (float)map(Messung_Spannung, 0, Kalib_Bitwert, 0, Kalib_Spannung) / 1000.0; return (Spannung); } void Alarm_konfigurieren() { byte Minute, IntervallMinuten; if (Batteriespannung > VAlternativ) { IntervallMinuten = WeckIntervallMinuten; } else { Serial.println("Batteriespannung unter Grenzwert, alternatives Intervall aktiviert"); Serial.println(); IntervallMinuten = AlternativIntervallMinuten; } DateTime aktuell = rtc.now(); long timestamp = aktuell.get(); aktuell = timestamp + IntervallMinuten * 60; rtc.enableInterrupts(aktuell.hour(), aktuell.minute(), 0); } void WakeUp() { detachInterrupt(0); ok_sleep = false; } void SleepNow(byte power_off) { delay(100); if (power_off) { Serial.println("Sleep-Modus mit Power-Off ist aktiviert, bitte warten ... "); digitalWrite(Power_Pin, LOW); delay(5); } else { Serial.println("Sleep-Modus mit Power-ON started, bitte warten ... "); } Serial.flush(); Serial.end(); // Serial aus delay(50); digitalWrite(USB_RX, LOW); // Port aus pinMode(USB_TX, INPUT); digitalWrite(USB_TX, LOW); // Port aus TWCR &= ~(bit(TWEN) | bit(TWIE) | bit(TWEA)); digitalWrite (A4, LOW); digitalWrite (A5, LOW); delay(1); attachInterrupt(0, WakeUp, LOW); if (ok_sleep) { LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); } else { Serial.begin(9600); Serial.println("Sleep-Modus konnte nicht aktiviert werden"); } digitalWrite(Power_Pin, HIGH); delay (5); rtc.begin(); rtc.clearINTStatus(); while (digitalRead(DS3231_Interrupt_Pin) == false) {}; ok_sleep = true; Serial.begin(9600); Serial.println("Sleep-Modus wurde beendet"); Serial.println(); delay(5); } |
Ausgabe des seriellen Monitors (9600 baud):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
beelogger Solar Test Uhr und Kalibrierwerte: Datum und Uhrzeit: 22.12.2018 12:9:25 Eingestelltes Weckintervall: 1 Minute(n) Sleep-Modus mit Power-ON gestartet, bitte warten ... Sleep-Modus wurde beendet Batteriespannung: 4.11 V Solarspannung: 1.20 V Datum und Uhrzeit: 22.12.2018 12:10:0 Temperatur ueber Sensor in RTC: 21.25 Eingestelltes Weckintervall: 1 Minute(n) Sleep-Modus mit Power-Off ist aktiviert, bitte warten ... Sleep-Modus wurde beendet Batteriespannung: 4.12 V Solarspannung: 1.25 V Datum und Uhrzeit: 22.12.2018 12:11:0 Temperatur ueber Sensor in RTC: 21.00 |
Programmcode downloaden:
Download
System-Check und Testprogramm zur Sensorkonfiguration:
Neben den nachstehenden Einstellungen der Sensoren kann es auch notwendig sein zu prüfen welche Sensoren im System aktiv sind.
Dazu haben wir ein kleines Testprogramm erstellt, welches
– eine Auflistung aller DS18B20 durchführt,
– die Belegung der I2C-Adressen anzeigt,
– die DHT 22 testet,
– den beelogger nach dem Systemtest in den Sleep-Mode versetzt,
– und, wenn konfiguriert:
– einen separaten Test für den Uhrbaustein DS3231 macht
– die schaltbare Stromversorgung abschaltet
– eine angeschlossene SD-Karte testet (benötigt SDFat-Bibliothek)
1 2 3 4 5 |
#define System_with_DS3231 0 // 0 = ohne oder 1 = mit DS3231 #define Power_off_at_End 0 // 0 = aus, 1= Power an #define Test_SD_Card 0 // 0 = aus, 1= Power an |
System Check 08.12.2019
Beispiel der Monitorausgabe:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
System Check 180819 Suche One-Wire-Bus, I2C-Bus Looking for 1-Wire devices... (i.e. DS18B20) at Pin: D3 Found '1-Wire' device with address: 0x28, 0xFF, 0xAB, 0x84, 0xA1, 0x16, 0x05, 0xF8 One-Wire scan done. I2CScanner ready! starting scanning of I2C bus from 8 to 119... addr: 0x8 addr: 0x9 addr: 0xA addr: 0xB addr: 0xC addr: 0xD addr: 0xE addr: 0xF addr: 0x10 addr: 0x11 addr: 0x12 addr: 0x13 addr: 0x14 ... ... ... addr: 0x51 addr: 0x52 addr: 0x53 addr: 0x54 addr: 0x55 addr: 0x56 addr: 0x57 found! addr: 0x58 addr: 0x59 addr: 0x5A addr: 0x5B addr: 0x5C addr: 0x5D addr: 0x5E addr: 0x5F addr: 0x60 addr: 0x61 addr: 0x62 addr: 0x63 addr: 0x64 addr: 0x65 addr: 0x66 addr: 0x67 addr: 0x68 found! addr: 0x69 addr: 0x6A addr: 0x6B addr: 0x6C addr: 0x6D addr: 0x6E addr: 0x6F addr: 0x70 addr: 0x71 addr: 0x72 addr: 0x73 addr: 0x74 addr: 0x75 addr: 0x76 found! addr: 0x77 I2C scan done Info: BH1750 - 0x23, 0x5C Si7021 - 0x40 SHT31 - 0x44, 0x45 AT24C32 - 0x57 DS3231 - 0x68 BME280 - 0x76, 0x77 MCP23017 - 0x20, 0x21, 0x22, 0x23 DHT 1: DHT nicht installiert oder fehlerhaft DHT 2: DHT nicht installiert oder fehlerhaft Sleep forever! |
Testprogramm für EE-Prom und Interrupt Niederschlagsmesser:
Dieses kleine Testprogramm prüft ein optional vorhandes EE-Prom bei Adresse 0x53 oder 0x57 auf Größe und gibt den Zählerstand eines Niederschlagsmessers (Interrupt an D3) aus.
Der komplette Programmcode für den Arduino Datenlogger mit Stockwaage für Imker ist unter Programmcode zu finden.