Pro Mini oder Programm friert ein

Hallo, mein Arduino Pro Mini friert nach einer weile scheinbar ein. Dieser steuert ein Step-Down wandler, schaltet diesen ein wenn ein Gerät angesteckt wird und aus wenn eine weile kein Gerät erkannt wird. Das funktioniert wunderbar, aber irgendwann nach ein paar Wochen passiert nichts mehr. Sämtliche Workarounds für evtl. auftretene Probleme haben nicht geholfen. Der Arduino wird auch vom Stepdown versorgt, wenn aus dann von einem HIGH Cap. Da ich gelesen habe das der Atmega328p ggf. kein zuverlässigen Reset macht wenn es zu einer Unterspannung kommt und die Spannung zu langsam fällt/steigt habe ich eine Reset Schaltung hinzugefügt aber auch das hat nichts gebracht.
Mir fällt nichts mehr ein vielleicht findet jemand einen dummen fehler im Sketch oder kennt einen anderen Hardwarefehler der dazu führt?
Im "eingefroren" zustand ist der Stepdown immer eingeschaltet aber der Ausgang ist abgeschaltet. Die Spannung am Stepdown ist normal.

#include "GPIO.h"
#include <EnableInterrupt.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>

volatile int toggle = 1;
volatile uint8_t packet_available;

uint8_t count=10;
uint8_t myon=1;
uint8_t once=0;
uint8_t errorcount=0;
uint8_t errorcount2=0;

void Reset_A(void) { asm volatile ("jmp 0 \n"); }

ISR(WDT_vect) /* Watchdog timer Interrupt Service Routine */
  {
  if(toggle == 0)  { toggle = 1; }
  }

void setup() {
 pinMode(2, OUTPUT);
 digitalWrite(2, LOW);  //StepDownON
 pinMode(3, INPUT);
 pinMode(5, OUTPUT);
 digitalWrite(5, LOW);  //Disable Jumper
 pinMode(6, OUTPUT);
 digitalWrite(6, HIGH);  //Ausgang Ein
 
 packet_available = 0;


  delay(4000);
  analogReference(DEFAULT);
  pinMode(0, INPUT);
  pinMode(1, INPUT);   
  pinMode(4, INPUT);       

  MCUSR &= ~(1<<WDRF);       
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  WDTCSR = 1<<WDP0 | 1<<WDP3;      //Prescaler auf 8.0 s
  WDTCSR |= 1<<WDIE;             

 //Connect Pin 3&4 to disable the device
 digitalWrite(5, HIGH);
 if (digitalRead(4)==HIGH) {
  digitalWrite(5, LOW);
  if (digitalRead(4)==LOW)  {
     while(1) {
       enter_sleep();
     }
  }
 }
   power_spi_disable(); 
   power_twi_disable();  
}

void loop() {
 int a,b;
 if (packet_available&&myon==0) {  //Pinchange interrupt wenn aus
  pinMode(6, OUTPUT); //this both are if the arduino output registers crashed by undervoltage but the Arduino is still active  18092020
  pinMode(2, OUTPUT);
  digitalWrite(2, LOW);  //Stepdown An
  digitalWrite(6, HIGH);  //Ausgang Ein
  count=0;  myon=1;  packet_available=0;
  delay(5); 
  b=analogRead(A0);  //dummy read a/d startup
  delay(5);
  b=analogRead(A0);
  if (b>820||b<30) {myon=0; digitalWrite(2, HIGH);   digitalWrite(6, LOW);} //überspannung/kurzschluss wieder aus
 } //pinchange interrupt
  count++; if (count==16) count=0;
  if (count==15||(myon==0&&(count%2)==0)) { //2min wenn an, alle 16sek wenn aus  (38=5min)
  once=0;
  again: 
    pinMode(6, OUTPUT); //this both are if the arduino output registers crashed by undervoltage but the Arduino is still active
    pinMode(2, OUTPUT);
    digitalWrite(2, LOW);  //Stepdown An
    digitalWrite(6, HIGH);  //Ausgang Ein
   if (myon==0) {
    WDTCSR |= (1<<WDCE) | (1<<WDE);
    WDTCSR = (1<<WDP0) | (1<<WDP2);      //500ms  
    enter_sleep();
    //standard 8 sek wieder herstellen
    WDTCSR |= (1<<WDCE) | (1<<WDE); 
    WDTCSR = (1<<WDP0) | (1<<WDP3);      //Prescaler auf 8.0 s
    
   } else delay(5);  
   
   a=analogRead(A0);  delay(5); //dummy read a/d for stabilize conversion
   a=analogRead(A0); //originalspannung
   if (a<700) errorcount++; 
   if (errorcount>10) Reset_A();  //700=4.52V Softreset wenn mehr als 10x ungewöhnliche Spannung festgestellt wurde
   digitalWrite(2, HIGH);  //Stepdown OFF
   delay(2); //Elko discharge
   b=analogRead(A0); 
   if (a<(b+4)&&once<10&&myon==1) {  //no load found, try 10 times cause of "PWM" Charging of some devices
    digitalWrite(2, LOW);  delay(100); //Stepdown An   100ms warten
    once++; goto again;
  }  

   if (a>(b+3)) { //we have a load attached to the stepdown switch it fast on again before the capicator discharge
    if (a<820&&b>30) {digitalWrite(2, LOW); myon=1; count=0;} else myon=0; //ON only if no overvoltage detected, and no short 820 ca.5.29V
   } else myon=0;  //kein spannungsabfall -> aus
  } //count
  if (myon==0)  {
    digitalWrite(6, LOW);   packet_available=0; enableInterrupt(3, rf_available_int, RISING );
  } else {digitalWrite(6, HIGH); }   //Ausgang An
  

if (digitalRead(2)==LOW&&digitalRead(6)==LOW) errorcount2++; else errorcount2=0;
if (errorcount2==20&&myon!=0) {enableInterrupt(3, rf_available_int, RISING); myon=0;} //16032021
if (errorcount2>37)  {
 enableInterrupt(3, rf_available_int, RISING );
  WDTCSR &= ~(1<<WDIE);
  disableInterrupt(3);
  Reset_A();  //5 Min Stepdown an wärend Ausgang deaktiviert (01/2021 freeze problem)
}

  
 enter_sleep(); //power saving  8 sek
}



void enter_sleep(void) 
  {
  WDTCSR |= 1<<WDIE;       
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  
  sleep_enable();
  power_adc_disable();
  power_spi_disable();
  power_twi_disable(); 
  sleep_mode();
  sleep_disable();
  power_adc_enable();
  WDTCSR &= ~(1<<WDIE);               
  }

void rf_available_int(void) 
{
  disableInterrupt(3);
  sei();                                                           
  sleep_disable();
  WDTCSR &= ~(1<<WDIE);               
  power_adc_enable(); 
  packet_available = 1;                                
}

Ein Schaltbild deines Projektes und der Typ des Stepdowns sind hier auch wichtig. Zum Stepdown einen Link posten.

Solch einfachen Sachen löte ich direkt zusammen on the fly ohne Schaltplan.
Der Reset IC ist ein SGM809B-RXN3LG, der Stepdown ist ein XL4005 vor dem Stepdown Enable ist eine inverter schaltung so das LOW/NC=ON ist. An A0 ist ein 100K/100K Spannungsteiler weil Ausgangsspannung 5V und Arduino 3V.
Arduino bekommt 5V vom Stepdown/Highcap welche an internen Arduino regler gehen->3V3.
D3 ist sense. D6 geht an ein TSM2312 zum freischalten des Ausgangs (sense basiert auf die Spannungsänderung welche durch den Eingangskondensatoren der Geräte verursacht wird dafür muss der Ausgang abgetrennt sein).
Die Schaltung hat nicht wirklich mit dem einfrieren zu tun, wie gesagt es ist normal das der Arduino ggf. eine unterspannung bekommt, dann neu starten soll. Falls dieser dazu ggf. unfähig ist(wie ich gelesen habe) gibts die Resetschaltung.
Der Reset wird bei 2,63V extern ausgelösst, was im save operating area für 8MHZ sein sollte. Nach einem Reset ist der Stepdown an, also Arduino sofort wieder versorgt. Nur entwender stürzt der Arduino vorher ab und es kommt überhaupt nie zu einer Unterspannung/Reset oder dieser fährt nicht mehr hoch/reagiert nicht auf den Reset(150ms).

Dann mal den Watchdog aktivieren, wäre meine Idee.
Wenn nach der Rückkehr der Versorgung das Setup noch anspringt, ist der WDT ein probates Mittel...

Also watchdog permanent mit WDE laufen lassen:
WDTCSR |= 1<<WDIE | 1<<WDE;
Am loop Anfang, vor sleep, nach sleep wdt_reset(); ?
Danke, werde ich mal probieren. Dauert aber etwa 1 Monat bis ich weiss obs funktioniert hat.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.