3,7V Li-Ion Spannungsüberwachung mit Atmel ATtiny85
sende Reset zu Heltec Lora32 V3 (oder anderer LoRaHArdware)
Projektbeschreibung für Heltec Lora32 V3
Problem:
Verschiedene Meshtastic kompatible Hardware wird häufig in „autarken“ Nodes mit Solarstrom betrieben. Wenn nun aber länger keine direkte Sonne auf das Solar Panel scheint, wie zB. im Winter, kann die Akkuspannung unter die erforderliche Betriebsspannung für das Meshtastic Gerät fallen und das Gerät schaltet aus und geht offline.
Wenn die Sonne wieder ausreichend scheint und die Akkuspannung wieder die Betriebsspannung erreicht, schaltet sich das Gerät nicht wieder automatisch ein. Es muss die POWER ON Taste bzw. die RESET Taste auf der Hardware manuell gedrückt werden.
Da die autarken Nodes meist auf erhöhten Positionen angebracht sind und meist schlecht erreichbar sind, soll sich das Gerät unbedingt selbstständig wieder einschalten und online gehen.
Es ist also eine Schaltung zu entwickeln, welche die Akkuspannung überwacht. Es soll festgestellt werden wenn die Akkuspannung unter 3,3 V fällt (unter 3,3V kann ein Heltec schon instabil werden) und wenn die Akkuspannung wieder auf mindestens 3,5V aufgeladen ist, soll die Schaltung am RESET Eingang des Meshtastic Geräts (Heltec Lora32 V3) einen Impuls geben damit das Meshtastic Gerät wieder startet und online geht.
Die Schaltung soll auf geringen Stromverbrauch ausgelegt werden. Es soll kein Spannungsabfall (0,6V) durch Einsatz eines Halbleiterschalters in der Versorgungsspannung des Meshtastic Geräts entstehen. Es soll wegen des hohen Stromverbrauchs kein Relais verwendet werden.
Lösung :
Ein Microcontroller der einen ADC Eingang besitzt soll die Akkuspannung mindestens alle 10 Minuten prüfen. In der Zwischenzeit soll im Idealfall der Microcontroller in einen Stromsparenden Modus fallen. Sobald die Akkuspannung unter 3,3V gefallen ist, soll dieser Zusstand im Microcontroller temporär gespeichert werden. Wenn nun die Spannung wieder steigt und 3,3V oder mehr erreicht hat, soll an einem Ausgang des Microcontrollers, der mit dem RESET Eingang oder POWER ON Eingang der Meshtastic Hardware verbunden ist, ein Impuls erzeugt werden, welcher den physischen Schalter am Gerät imitiert.
Der Microcontroller muss mit einer mindestens Versorgungsspannung von 3,15V betriebsfähig sein. Um eine korrekte Spannungsmessung im Microcontroller zu gewährleisten muss die Versorgungsspannung stabilisiert sein.
Eine stabile Spannung erfordert eine entsprechende Schaltung. Der Fixspannungsregler AMS 1117 erfüllt diese Herausforderung, jedoch besteht eine DropOff Spannung von 1,2V. Der Microcontroller kann also nur mit 3,2V – 1,2V = 1,95V versorgt werden. Dafür muss jedoch für die Spannungsüberwachung ein Spannungsteiler vorhanden sein, welcher nicht mehr als max. die Versorgungsspannung des µC an den ADC Eingang zur Messung bereitstellt.
Ein Atmel ATtiny85V in Verbindung mit einem Fixspannungsregler AMS1117-1.8 kann die Anforderungen abbilden denn er benötigt eine mindeste Versorgungsspannung von nur 1,8V bei 1MHz Taktfrequenz. Bei 1MHz Taktfrequenz benötigt der µC lediglich 300µA bzw. 0,1µA in Ruhephase und der AMS1117 hat einen Verluststrom von 5mA.
Berechnung Spannungsteiler für Messeingang ADC1 von Tiny85:
Der Spannungsteiler besteht aus zwei Widerständen, R1 und R2, die in Reihe geschaltet sind. Die Ausgangsspannung Vout wird am Verbindungspunkt der beiden Widerstände abgegriffen. Die Berechnungsformel lautet:
Vout = Vin * (R2 / (R1 + R2))
Hierbei ist:
Vin die Eingangsspannung der Plus Pol des Akkus (min. 3,1V bis max. 4,3V Li-Ion Akku)
R1 der obere Widerstand
Vout zwischen den beiden Widerständen (max. 2,5V)
R2 der untere Widerstand
GND ist die Masse also der Minus Pol des Akkus
R1 = 6,8kΩ
R2 = 4,9kΩ
Stückliste
1 Lochrasterplatine
1 Atmel ATtiny85V
1 AMS 1117 1.8
1 LED rot
je 1 6,8kΩ , 4,9kΩ Widerstand (10kΩ optional)
je 1 10µF, 22µF Keramik Kondensator
1 (Taster Switch optional)
1 JST 2.0mm Lötsockel und 1 JST 2.0mm Crimp Stecker (Optional, anlöten tuts auch)
Ein paar Litzen
Atmel ATtiny85V

PIN 1 – Reset, ADC0, PB5
PIN 2 – CLKI, ADC 3, PB3
PIN 3 – ADC2, PB4
PIN 4 – GND
PIN 5 – MOSI, PB0
PIN 6 – MISO, PB1
PIN 7 – SCK, ADC1, PB2
PIN 8 – VCC
Stromaufnahme: 300µA
LM 1117 -1.8 TO220

PIN 1 – GND
PIN 2 – V OUT (1,8V max. 1000mA)
PIN 3 – V IN (min. 2,8V, max. 18V)
Programm für Tiny85 ( 10 Minuten Sleep pro loop)
//
//Spannungsteiler für tiny85 ADC1 Eingang (max. 2,5V Messspannung)
// _________ _________
// + Akku —–|_R1_4.9k_|————–|_R2_6.8k_| —– GND Akku
// |
// ADC1
//
// ATtiny85
// Reset — 1 | |8 — VCC (vom Li-ion Akku)
// LED PB3 — 2 | tiny |7 — ADC1 zum Spannungsteiler
// — 3 | 85 |6 —
//GND(Akku) — 4 | |5 — PB0 an HeltecV3 RST Pin anlöten
//
//
#include <avr/sleep.h>
#include <avr/wdt.h>
const int analogPin = 1; // ADC1 entspricht physischem Pin 7
const int pb0Pin = 0; // PB0 entspricht physischem Pin 5
const int pb3Pin = 3; // PB3 entspricht physischem Pin 2
const float referenceVoltage = 1.9; // Versorgungsspannung Tiny85 1,8V als Referenz
// Flag Variable Niedrige Spannung
volatile int lowV = 0;
// Watchdog-Timer Variable
volatile bool wakeup = false;
// Watchdog-Interrupt-Service-Routine
ISR(WDT_vect) {
wakeup = true; // Signalisiert das Aufwachen
}
// Funktion, um den Watchdog-Timer zu konfigurieren
void setupWatchdogTimer()
{
// Setzt den Watchdog-Timer auf 8 Sekunden
WDTCR = (1 << WDCE) | (1 << WDE); // Aktiviert Änderungen am WDT
WDTCR = (1 << WDIE) | (1 << WDP3) | (1 << WDP0); // 8s Intervall + Interrupt
}
// Sleep-Modus aktivieren
void enterSleepMode()
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Tiefster Energiesparmodus
sleep_enable();
sleep_cpu(); // Schlafmodus starten
// CPU wird nach Watchdog-Interrupt geweckt
sleep_disable(); // Schlafmodus deaktivieren
}
void setup()
{
cli(); // Interrupts deaktivieren
setupWatchdogTimer(); // Watchdog-Timer einrichten
sei();
pinMode(analogPin, INPUT); //ADC1 als Eingang konfigurieren
pinMode(pb0Pin, OUTPUT); // PB0 als Ausgang konfigurieren
pinMode(pb3Pin, OUTPUT); // PB3 als Ausgang konfigurieren
}
void loop()
{
digitalWrite(pb0Pin, HIGH); //Reset zurücksetzen
digitalWrite(pb3Pin, HIGH); //LED Heartbeat blinkt 1x kurz
delay(50);
digitalWrite(pb3Pin, LOW);
delay(50);
// Spannung an ADC1 messen
int adcValue = analogRead(analogPin);
// Spannung berechnen
float voltage = (adcValue / 1023.0) * referenceVoltage;
// Flag setzen oder zurücksetzen basierend auf der Spannung
//Spannung 3,21V; Spannungsteiler 1.34V; IfWert 1.35
//Spannung 3,28V; Spannungsteiler 1.36V; IfWert 1.42
//Spannung 3,30V; Spannungsteiler 1.37V; IfWert 1.45
if (voltage <= 1.45 && lowV == 0) //Spannung fällt unter 3,3V = mit Messspannungsteiler 1.37V = IfWert 1.45
{
digitalWrite(pb3Pin, HIGH); // LED blinkt 2x
delay(500);
digitalWrite(pb3Pin, LOW);
delay(500);
digitalWrite(pb3Pin, HIGH);
delay(500);
digitalWrite(pb3Pin, LOW);
delay(500);
lowV = 1; // Flag auf 1 setzen
}
else if (voltage > 1.55 && lowV == 1) //Spannung ist über 3,55V und LowV war auf 1, mit Spannungsteiler 1.48V = IfWert 1.55
//Spannung 3,52V; Spannungsteiler 1.48V; IfWert 1.55
//Spannung 3,73V; Spannungsteiler 1.55V; IfWert 1.65
{
lowV = 0; // Flag auf 0 zurücksetzen
// PB0 kurz auf LOW send Reset, und PB3 kurz auf HIGH LED an
//send reset
digitalWrite(pb0Pin, LOW);
digitalWrite(pb3Pin, HIGH); // LED blinkt 1x lang
delay(2000); //2 Sec pause
digitalWrite(pb0Pin, HIGH);
digitalWrite(pb3Pin, LOW);
}
// 10 Minuten in den Schlafmodus wechseln
// 10 Minuten = 75 x 8 Sekunden i < 75, !!! für debug i < 1 verwenden !!!
for (int i = 0; i < 75; i++)
{
enterSleepMode();
if (!wakeup)
{
continue; // Warten, bis der Watchdog-Interrupt ausgelöst wird
}
wakeup = false; // Interrupt-Flag zurücksetzen
}
// Kurze Pause vor der nächsten Messung
delay(500);
}
Schaltplan
