Forum: Mikrocontroller und Digitale Elektronik Absturz nach Spannungsabschaltung


von P. F. (pfuhsy)


Lesenswert?

Hallo zusammen,

folgende Situation:
Ich habe 2 Platinen mit dem RFM12-Modul. Einer dient als Sender der 
andere als Empfänger.
1
//----------------------------------------------------------------------
2
// Titel       : RFM12-Reedkontakt für Hausalarmanlage
3
//----------------------------------------------------------------------
4
// Schaltung   : Pinbelegung siehe unten 
5
// Beschreibung  : Überwacht den Batteriestatus und einen Reedkontakt.
6
//          Sendet nach Anfrage einen Statusbericht.
7
//----------------------------------------------------------------------
8
// Prozessor   : ATmega8L
9
// Takt       : 1MHz, intern
10
// Frequenz    : 434MHz
11
// Datenrate  : 4.8kbps
12
// Datum       : 21.09.2015
13
// Version     : 1.0
14
// Autor       : P. Fuhsy
15
// Fuses      : lfuse=0xD0, hfuse=0xC9 (TODO: muss an externen Takt angepasst werden)
16
//        : lfuse=0xD4, hfuse=0xC9 (beim Testen)
17
18
/****************************Pinbelegung********************************
19
------------------------------------------------------------------------
20
Controller      Anschluss      Beschreibung
21
------------------------------------------------------------------------
22
PB0        Reserve
23
PB1        Reserve
24
PB2-SS      RFM - nSEL      Select Chip
25
PB3-MOSI    RFM - SDI      Serial Data In
26
PB4-MISO        RFM - SDO      Serial Data Out
27
PB5-SCK         RFM - SCK      Serial-Clock
28
PB6-XTAL1    Osc 8MHz      externer Quarz
29
PB7-XTAL2    Osc 8MHz      externer Quarz
30
31
PC0        ADC UBAT      Messung der Batterie-Spannung
32
PC1        UOUT        Messung der Versorgsspannung vorbereitet
33
PC2        DIP-Schalter 1    Dip-Schalter 1 zur Adressierung
34
PC3        DIP-Schalter 2    Dip-Schalter 2 zur Adressierung
35
PC4        DIP-Schalter 3    Dip-Schalter 3 zur Adressierung
36
PC5        DIP-Schalter 4    Dip-Schalter 4 zur Adressierung
37
38
PD0-RXD      Reserve        
39
PD1-TXD      Reserve  
40
PD2-INT0        RFM - nIRQ      Interrupt Output
41
PD3-INT1    Ext. Interrupt    Reedkontakt
42
PD4             LED-Rot        Rot, Low Current LED
43
PD5             RFM - NINT      am RFM - NINT vorbereitet
44
PD6             RFM - DCLK      am RFM - DCLK vorbereitet
45
PD7             Reserve
46
**********************************************************************/
47
#define F_CPU 8000000UL          //CPU festlegen TODO: auf 1MHz ändern
48
49
#include <avr/io.h>          //allg. Ports
50
#include <util/delay.h>        //TODO kann später wegfallen wenn Zeitbasis vorhanden
51
#include <string.h>          //zum Vergleichen von Strings
52
#include <stdbool.h>        //für Bool-Variablen
53
#include <avr/interrupt.h>      //für Interrupts
54
#include <inttypes.h>
55
56
#include "uart.h"          //eigene Header
57
#include "ports.h"          //eigene Header
58
#include "rfm12.h"          //eigene Header
59
#include "haa_bus.h"        //eigene Header
60
61
//------------------------------Funktionsaufruf-----------------------------
62
void initPorts();
63
void initInterrupt();
64
void initADC();
65
void Power_On();
66
char *Wert0_in_str (uint16_t wert);
67
void Sleep();
68
unsigned char RFM_recv_xxx(void);
69
70
void initPorts() //Ports deklarieren
71
{
72
  //Outputs
73
  DDRB |= (1<<RFM_SEL);  //SEL_OUTPUT
74
  DDRB |= (1<<RFM_SDI);  //SDI_OUTPUT
75
  DDRB |= (1<<RFM_SCK);  //SCK_OUTPUT  
76
  DDRD |= (1<<LED_ROT);  //LED für allg. Statuszustand    
77
78
  //Ports die nicht benutzt werden als Output deklariert
79
  DDRB |= (1<<RESB0);    //Reserve
80
  DDRB |= (1<<RESB1);    //Reserve
81
  DDRD |= (1<<RESD0);    //Reserve
82
  DDRD |= (1<<RESD1);    //Reserve
83
  DDRD |= (1<<RESD7);    //Reserve
84
  //Input
85
  DDRD &=~(1<<RFM_NINT);  //Reserve
86
  DDRD &=~(1<<RFM_DCLK);  //Reserve
87
88
  //Inputs
89
  DDRB &=~(1<<RFM_SDO);  //SDO_INPUT
90
  DDRC &=~(1<<UBAT);    //Batteriespannung
91
  DDRC &=~(1<<UOUT);    //Spannung am Controller
92
  DDRC &=~(1<<DIP1);    //Dip-Schalter 1
93
  DDRC &=~(1<<DIP2);    //Dip-Schalter 2
94
  DDRC &=~(1<<DIP3);    //Dip-Schalter 3
95
  DDRC &=~(1<<DIP4);    //Dip-Schalter 4
96
  DDRD &=~(1<<REED_0);  //Reed 0
97
  DDRD &=~(1<<RFM_IRQ);  //IRQ_IN  
98
99
  //interne Pull-Up-Widerstände einschalten
100
  PORTC |= (1<<DIP1);    //DIP-Schalter
101
  PORTC |= (1<<DIP2);    //DIP-Schalter
102
  PORTC |= (1<<DIP3);    //DIP-Schalter
103
  PORTC |= (1<<DIP4);    //DIP-Schalter
104
  PORTD |= (1<<REED_0);   //Reed-Kontakt
105
  PORTD |= (1<<RFM_IRQ);  //IRQ_IN
106
107
  //Ports initiaisieren, aus LOW setzten
108
  Led_Rot_Off();
109
}
110
111
void initInterrupt()  //Port Interrupt initialisieren
112
{
113
  MCUCR |= (1<<ISC01) | (0<<ISC00);   //fallende Flanke am INT0 Pin als Auslöser
114
  MCUCR |= (1<<ISC11) | (1<<ISC01);   //steigende Flanke am INT1 Pin als Auslöser
115
  GIMSK |= (1<<INT0)  | (1<<INT1);  //externen Interrupt 0, 1 einschalten
116
  sei();                //alle Interrups einschalten
117
}
118
119
void Power_On()
120
{  
121
  //POWER ON Prozedur, 3x blinken
122
  for(int i=0;i<3;i++)
123
  {
124
    _delay_ms(500);
125
    Led_Rot_On();
126
    _delay_ms(500);
127
    Led_Rot_Off();
128
  }
129
130
  _delay_ms(500);
131
}
132
133
void Sleep() 
134
{
135
/*   sei();
136
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);//Modus wählen
137
  sleep_enable();            //Sleep erlauben
138
  TIMSK0 = (0 << OCIE0A);        //Timer vorrübergehend ausschalten
139
    sleep_mode();            //schlafen gehen
140
*/
141
}
142
143
void Zustand_Anlage() //allg. Zustand des Kontakts abfragen
144
{
145
  //REEDkontakt ist geöffnet
146
  if (Reed0_ist_offen())
147
  {
148
    Reed_Alarm();    //Byte STA
149
  }
150
151
  //REEDkontakte sind geschlossen
152
  else
153
  {  
154
    Reed_OK();      //Byte STA
155
  }
156
}
157
158
void Status_Senden()  //Status der Anlage senden
159
{
160
  uint8_t commando[6] = {"000000"}; //Array für Daten
161
  
162
  //Zusammenstellung der Daten
163
  commando[0] = 99;      //Adresse 99
164
  commando[1] = 0b10000000;  //Funktionen
165
  commando[2] = STA;      //Status
166
  commando[3] = 255;      //Wert 0
167
  commando[4] = 1;      //Laufnummer
168
  commando[5] = 0b00010000;  //Software-Version
169
170
  RFM_Empf_Aus();
171
  Daten_senden(commando, 6);  //Daten senden
172
173
  Reed_OK();      //vorhandenen Alarm zurücksetzten falls vorhanden
174
}
175
176
177
int main(void) //Hauptprogramm
178
{
179
  initPorts();    //AVR-Ports initialisieren
180
  //initUART();    //zu Testzwecken
181
  //UCSRB = (0<<RXEN)|(0<<RXCIE);  //Receiver ausschalten
182
  //UCSRB = (1<<TXEN);  //Transmitter zulassen
183
  initInterrupt();  //Interrups initialisieren  
184
185
  Power_On();      //Powern On Prozedur von der LED
186
  _delay_ms(200);    //Etwas Zeit verbummeln bis das Modul bereit ist  
187
  initRFM_Ports();  //MOSI / MISO Ports initialisieren  
188
  initRFM();      //RFM Grundkonfiguration  
189
  
190
  while(true) //Hauptschleife
191
  {  
192
    _delay_ms(3000);  //TODO: durch Sleep ersetzten
193
    
194
    //Zustand der Anlage soll über INT1 gesetzt  werden
195
    //Zustand_Anlage();  //Anlagenzustand abfragen
196
    Status_Senden();  //Status der Anlage senden
197
    Led_Rot_On();
198
    _delay_ms(50);
199
    Led_Rot_Off();
200
    //Sleep();  //Controller schlafen legen
201
  }
202
}
203
204
ISR(INT0_vect)  //Interruptvektor für RFM12, wird bei jedem Byte aufgerufen
205
{  
206
  //wird beim Datenempfang benötigt
207
}
208
209
ISR(INT1_vect)  //Interruptvektor für Reedkontakt, fallende Flanke
210
{
211
  //Reed_Alarm();
212
}
213
214
ISR (TIMER2_COMP_vect)  //Time-Compare-Interrupt, wird jede ms ausgelöst
215
{
216
  //TODO
217
}

Zur Erklärung:
Beim starten blinkt eine Led zur Kontrolle 3x kurz auf (Power_On()). In 
der Hauptschleife sendet er ein Testprotokoll, welches ich beim 
Empfänger über UART einsehen kann. Nach dem senden blitzt die Led zur 
Kontrolle kurz auf. Das funktioiert schonmal alles.

Problem ist, wenn ich bei den Sender für ca. 15-20s die 
Versorgungsspannung abklemme und wieder anklemme, häng er sich auf. D.h. 
es erfolgt nur das 3x blitzen der Led (Power_On()). Ich sehe beim 
Empfänger jedoch keine Daten über Uart und das kurze aufblitzen der Led 
zur Kontrolle sehe ich auch nicht. Klemme ich die Spannung erneut kurz 
ab und wieder an, kommt das Kontrollblitzen aus der Hauptschleife zwar, 
jedoch kommen keine Daten beim Empäfnger an. Das einzige was hilft, ist 
den Controller nochmal neu zu flashen. Ab diesen Zeitpunkt sendet er 
wieder brav, bis die Spannung wieder abgeklemmt wird.

Wenn ich die Versorgungspannung abklemme dabei aber den ISP-Stecker 
gesteckt lasse, gibt es dieses Problem nicht. Ich denke, dass das damit 
zu tun haben könnte, dass die Schaltung über ISP noch mit Spannung 
versorgt wird.

Hat jemand eine Idee warum der sich aufhängt ?

von P. F. (pfuhsy)


Lesenswert?

Peter F. schrieb:
> Problem ist, wenn ich bei den Sender für ca. 15-20s die
> Versorgungsspannung abklemme und wieder anklemme, häng er sich auf. D.h.
> es erfolgt nur das 3x blitzen der Led (Power_On()). Ich sehe beim
> Empfänger jedoch keine Daten über Uart und das kurze aufblitzen der Led
> zur Kontrolle sehe ich auch nicht.

Ein weiterer Test hat ergeben, dass er sich in der Hauptschleife 
aufhängt, also bei "Staus_Senden()", was anderes gibt es ja dort nicht. 
Ich gehe davon aus, dass der RFM12 dabei Probleme macht.

von Stefan F. (Gast)


Lesenswert?

> Ich gehe davon aus, dass der RFM12 dabei Probleme macht.

Ich auch, hatte den selben Effekt schon öfters mit diversen Fuunk und 
Netzwerk-Modulen.

Du könntest das Program des µC so umschreiben, dass es beim Start die 
Reset-Leitung des Funkmodusl auf Low zieht, dann 500ms wartet und sie 
dann loslässt (nicht auf High ziehen, denn diese Leitung ist 
bidirektional!).

von Michael U. (amiga)


Lesenswert?

Hallo,

als ersten Zugriff nach Reset auf den RFM den Status lesen, war bei mir 
auch ein Problem, sowohl beim RFM12 als auch beim RFM02.
Außerdem je nach Aufbau und Spannungsversorgung dicht am Modul einen 
Elko 4,7-10µF, sonst gab es zumindest bei Versorgung durch 3V 
Lithiumbatterien das geliche Problem, er blieb beim Senden hängen, es 
kam keinen Antwort vom RFM.

Mit diesen Änderungen läuft der Kram hier jetzt schon ein paar Jahre 
stabil.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von P. F. (pfuhsy)


Lesenswert?

Stefan U. schrieb:
> Reset-Leitung

Meinst du die Reset-Leitung vom RFM12 ? Problem ist, die Platine ich 
schon fertig bestückt und die Reset-Leitung liegt frei. Auf den 
Steckboard ist dieses Problem nie aufgetaucht, da das Teil immer an 
Spannung hingt.
Ich würde gerne der Sache tatsächlich auf den Grund gehen und nicht nur 
umgehen.

von P. F. (pfuhsy)


Lesenswert?

Michael U. schrieb:
> als ersten Zugriff nach Reset auf den RFM den Status lesen,

Vor oder nach dem Konfiguieren des Moduls ???

von P. F. (pfuhsy)


Lesenswert?

Michael U. schrieb:
> als ersten Zugriff nach Reset auf den RFM den Status lesen, war bei mir
> auch ein Problem, sowohl beim RFM12 als auch beim RFM02.

Das mach ich eigentlich schon bei "initRFM", als letzten Befehl:
1
...
2
initRFM();      //RFM Grundkonfiguration
3
...
4
5
//Konfiguration des RFM
6
void initRFM()
7
{
8
  RFM_cmd_empf(0x80D7);  //Grundkonfiguration: EL,EF,11.5pF
9
  RFM_cmd_empf(0xA640);  //Frequenzeinstellung: 434MHz
10
  RFM_cmd_empf(0xC647);  //Bitrate: 4.8kbps
11
  RFM_cmd_empf(0x94A0);  //Empfängersteuerung: VDI,FAST,134kHz,0dBm,-103dBm
12
  RFM_cmd_empf(0xC2AC);  //Empfangsdatenrekonstruktion: AL,!ml,DIG,DQD4
13
  RFM_cmd_empf(0xCA81);  //Empfangsdatenrekonstruktion: FIFO8,SYNC,!ff,DR
14
  RFM_cmd_empf(0xC483);  //Empfangsdatenrekonstruktion: @PWR,NO RSTRIC,!st,!fi,OE,EN
15
  RFM_cmd_empf(0x9850);  //Senderkonfiguration: !mp,9810=30kHz,MAX OUT
16
  RFM_cmd_empf(0xE000);  //Zeitgeber für Wake-Up: NOT USE
17
  RFM_cmd_empf(0xC800);  //Automatisch zyklischer Empfänger (Low Duty-Cycle): NOT USE
18
  RFM_cmd_empf(0xC400);  //Automatische Frequenznachregelung: 1.66MHz,2.2V
19
  //RFM_cmd_empf(0xC000);  //Unterspannungs-Detektor und Taktausgangsteiler; 1Mhz, 2,25V
20
  RFM_cmd_empf(0x0000);  //NEU: Interruptanforderungen löschen
21
}

von P. F. (pfuhsy)


Lesenswert?

Hallo,

also wenn ich die Spannungsversorgung nach dem "Absturz" ein paar mal 
ab- und wieder anklemme funktioniert das ganze, das kann aber nicht die 
Lösung sein.

Ich habe die Konfiguartion auf
1
RFM_cmd_empf(0xCA80);  //Empfangsdatenrekonstruktion: FIFO8,SYNC,!ff,!DR
umgestellt und mich in den Software-Reset versucht
1
  Power_On();      //Powern On Prozedur von der LED
2
  _delay_ms(500);    //Etwas Zeit verbummeln bis das Modul bereit ist
3
  initRFM_Ports();  //MOSI / MISO Ports initialisieren  
4
  RFM_cmd_sender(0xFE00);  //Software-Reset
5
  initRFM();      //RFM Grundkonfiguration
Leider ohne Erfolg.
Hat jemand eine Idee ?

von Karl H. (kbuchegg)


Lesenswert?

Deine Problembeschreibung im Eroeffnungsposting klingt fuer mich danach, 
dass du den Modulen nach dem Power On einfach nicht genug Zeit gibst, 
die Verbindung aufzubauen. Waehrend des Flahens steht das System unter 
Strom und die Module koennen in Seelenruhe die Verbindung herstellen 
waehrend programmiert wird.
Verlaengere mal die Wartezeit am Anfang

von Karl H. (kbuchegg)


Lesenswert?

Im uebrigen vermisse ich jegliches Fehlerhandling. Die Module werden ja 
wohl irgendeine Form der Rueckmeldung mit einem Status haben.
Es hat sich noch nie ausgezahlt, solche Dinge zu ignorieren

von Stefan F. (Gast)


Lesenswert?

>> Du könntest das Program des µC so umschreiben, dass es beim Start
>> die Reset-Leitung des Funkmodusl auf Low zieht

>> dicht am Modul einen Elko 4,7-10µF

> Problem ist, die Platine ich schon fertig bestückt

Dumm gelaufen. Zuerst sollte man einen Prototypen entwicklen, bevor die 
Massenproduktion beginnt. Ich erinnere an den knappen Speicher beim 
Blinkmodul.

> also wenn ich die Spannungsversorgung nach dem "Absturz" ein paar
> mal ab- und wieder anklemme funktioniert das ganze, das kann aber
> nicht die Lösung sein.

Die beiden Lösungsvorschläge hast du wohl noch nicht versucht. Zumindest 
den Kondensator nachzurüsten sollte doch machbar sein, auch wenn die 
Platinen bereits produziert sind.

von P. F. (pfuhsy)


Lesenswert?

Karl H. schrieb:
> Verlaengere mal die Wartezeit am Anfang

Ich hab das jetzt mal mit 3s getestet, hilft auch nichts.

Karl H. schrieb:
> Im uebrigen vermisse ich jegliches Fehlerhandling. Die Module werden ja
> wohl irgendeine Form der Rueckmeldung mit einem Status haben.
> Es hat sich noch nie ausgezahlt, solche Dinge zu ignorieren

Ich taste mich momentan langsam an die Sache ran. Eine Fehlerbehandlung 
kommt auch noch.

Stefan U. schrieb:
> Die beiden Lösungsvorschläge hast du wohl noch nicht versucht. Zumindest
> den Kondensator nachzurüsten sollte doch machbar sein, auch wenn die
> Platinen bereits produziert sind.

Ist eine fertig SMD-Platine. Ich könnte den Kondensator mal direkt an 
das Modul löten, zu Testzwecken. Ich werde das mal testen und berichten.

Stefan U. schrieb:
> Dumm gelaufen. Zuerst sollte man einen Prototypen entwicklen, bevor die
> Massenproduktion beginnt.

So schlau war ich auch schon. Das ist der Prototyp !

von P. F. (pfuhsy)


Angehängte Dateien:

Lesenswert?

Michael U. schrieb:
> Außerdem je nach Aufbau und Spannungsversorgung dicht am Modul einen
> Elko 4,7-10µF,

Hab ich auch versucht, ohne Erfolg.

Michael U. schrieb:
> als ersten Zugriff nach Reset auf den RFM den Status lesen
Vielleicht sollte ich da nochmal ansetzen. Reicht das auslesen des 
Status unter "initRFM()" nicht aus ?
1
  Power_On();      //Powern On Prozedur von der LED  
2
  _delay_ms(500);    //Etwas Zeit verbummeln bis das Modul bereit ist
3
  initRFM_Ports();  //MOSI / MISO Ports initialisieren  
4
  initRFM();      //RFM Grundkonfiguration

Irgendwie stocher ich im dunkeln und weiß eiegtnlich gar nicht woran das 
wirklich liegt um dagegen gezielt was machen zu können.

von Stefan F. (Gast)


Lesenswert?

Vielleicht steigt die Spannungsversorgung beim Einschalten nicht schnell 
genug an. Könnte es daran liegen?

von P. F. (pfuhsy)


Lesenswert?

Ich benutze dafür ein Labornetzteil mit max. 3A und die Strombegrenzung 
ist auf maxium. Ich bezweifel das es daran liegen mag. Ich kann aber 
gerne mal eine Messung mit dem Osszi machen. Ich habe die selbe 
Schaltung nochmal auf meinen Breadborad. Lustigerweise besteht dort 
nicht das Problem. Der Unterschied ist aber, dass dort der RFM12 als 
SMD-Variante und auf der Platine ein steckbares Dip-Modul RFM12b ist. 
Hätte jetzt eigentlich erwartet, dass die Freiluft-Verdrahtung auf den 
Breadborad mehr Probleme macht wie eine sauber gelötet SMD-Variante.

von Stefan F. (Gast)


Lesenswert?

> Hätte jetzt eigentlich erwartet, dass die Freiluft-Verdrahtung auf
> den Breadborad mehr Probleme macht wie eine sauber gelötet SMD-Variante.

Hätte ich auch.

Schaltest du das ganze Netzteil aus und ein, oder trennst du nur die 
Zulietungen ab? Im ersten Fall kann es trotz der Größe des Netzteil 
sein, dass dessen Ausgangsspannung nur sehr langsam ansteigt.

von P. F. (pfuhsy)


Lesenswert?

Stefan U. schrieb:
> Schaltest du das ganze Netzteil aus und ein, oder trennst du nur die
> Zulietungen ab?

Ich ziehe nur die Zuleitung, das Netzteil bleibt dabei an.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.