Forum: Mikrocontroller und Digitale Elektronik Fehler im Reaktivlicht-Code ?


von Tom R. (torama)


Lesenswert?

Hallo, ich habe wohl einen Bug im Code, aber kann ihn nicht richtig 
lokalisieren. Grob baut der Code auf dem BASCOM auf lt. reaktivlicht.de

Die Eule soll nach dem kurzen Anleuchten 7x Blinken und wenns dunkel 
bleibt auch 7x wiederholen. Es funktioniert auch ABER

nach ca. 2 Tagen hängt sich die Eule auf und reagiert nicht mehr und 
jetzt nach 1 Woche funktioniert sie wieder von alleine. Ich vermutete 
einen Überlauf oder so aber wo ?

Bitte kann mal einer checken?
1
' **********************************************
2
' *** 
3
' *** Nachteule
4
' *** 
5
' **********************************************
6
7
$regfile = "ATtiny13.DAT"
8
$crystal = 16000                                            'Frequenz des internen Oszillators
9
10
Config Portb = &B00011001                                   'Pinb.3,4 und .5 auf 'Ausgang', Rest auf 'Eingang' schalten
11
Portb = &B11100110                                          'Pullups zuschalten, außer für Pinb.3,4 und .5
12
Stop Adc                                                    'A/D-Wandler abschalten (Strom sparen)
13
Stop Ac                                                     'Analog-Komparator abschalten (Stromsparwilli)
14
15
Wdtcr = &B11010101                                          'Watchdog definieren: 0.5 Sekunden, Interrupt auslösen, kein Reset
16
Enable Interrupts                                           'Interrupts freigeben
17
18
Dim A As Byte
19
Dim B As Byte
20
Dim C As Byte
21
Dim Led_ladezustand As Bit
22
Dim Hell As Bit
23
Dim Hell_2 As Byte
24
25
Do
26
 Gosub Led_abfrage
27
28
 If Led_ladezustand = 0 Then
29
  Hell = 1
30
  If B = 0 Then                                             
31
    Gosub Blinken                                           'Schon mal erstes Mal Blinken
32
  End If
33
 End If
34
35
 If Hell = 1 And B < 255 Then
36
  B = B + 1                                                 'Wenn Merker gesetzt wurde, Zähler für Lichtdauer erhöhen (bis max. 255)
37
 End If
38
 If B > 200 Then
39
  Gosub Abschalten                                          'Tagabschaltung
40
 End If
41
42
 If Led_ladezustand = 1 And Hell = 1 And B < 30 Then        'Wenn es wieder dunkel ist und der Lichtimpuls nur kurz war
43
  Hell_2 = 0                                                'zweiten Hell-Merker setzen
44
  For C = 0 To 3                                            'und 5 mal afragen
45
   Gosub Led_abfrage
46
   If Led_ladezustand = 0 Then
47
    Hell_2 = Hell_2 + 1                                     'ob es auch wieder dunkel ist
48
   End If
49
  Next C
50
  If Hell_2 = 0 Then
51
   Gosub Blinken                                            'erst dann blinken
52
  End If
53
  Hell = 0
54
  B = 0
55
 End If
56
 
57
 If Led_ladezustand = 1 Then                                'Bei Dunkelheit Merker und Zähler für Lichtdauer löschen
58
  Hell = 0                                                  'damit sich das Programm nicht aufhängt
59
  B = 0
60
 End If
61
62
Loop
63
64
Led_abfrage:
65
 Reset Watchdog
66
 Powerdown
67
 Portb.3 = 0
68
 Portb.4 = 1                                                'Portb.4 auf +Ub schalten, um die LED zu 'laden'
69
 Waitus 1                                                   'Ladezeit, kann ggf. noch verkleinert werden
70
 Config Portb.4 = Input                                     'Portb.4 nun zwecks Abfrage der LED-Ladung auf 'Eingang' schalten
71
 Portb.4 = 0                                                'Pullup abschalten, sonst geht's nicht!
72
 Waitms 4000
73
 Led_ladezustand = Pinb.4                                   'Ladezustand einlesen: '1' -> dunkel, '0' -> hell
74
 Config Portb.4 = Output                                    'Portb.4 wieder auf Ausgang schalten
75
 Portb.4 = 0
76
 Reset Watchdog
77
 Powerdown
78
Return
79
80
Blinken:
81
 For A = 1 To 7
82
  'Portb.3 = 1
83
  Portb.0 = 1                                               ' 2. Auge mitleuchten
84
  Reset Watchdog
85
  Powerdown
86
  'Portb.3 = 0
87
  Portb.0 = 0                                               ' 2. Auge mitleuchten
88
  Reset Watchdog
89
  Powerdown
90
 Next A
91
Return
92
93
Abschalten:
94
  Wdtcr = &B11110001
95
  Reset Watchdog
96
  Powerdown
97
  Wdtcr = &B11010101
98
Return
99
100
End

von Krapao (Gast)


Lesenswert?

Ich habe oft beobachtet, dass es mir hilft, wenn ich die Arbeitsweise 
meines Programms meinem Teddy in einfachen Worten erkläre. Wenn der 
Teddy dann die Erzählung mit dem meinem Code vergleicht, entwirrt sich 
meistens das Rätsel. Bei deinem Programm hat mein Teddy als erstes 
gefragt, wie die schlafende Eule sich um das kleine B kümmert.

von Tom R. (torama)


Lesenswert?

Hi danke fürs drüberschauen.

Na, die Eule pennt nur eine halbe Sekunde und wacht wieder auf. Wenns 
immer noch hell ist schläft sie weiter.

Und ist es dunkel, dann wird B (was max. 255 groß werden kann) wieder 
auf 0 (Wert) gesetzt.

Haut ja eigentlich auch hin :(

von Krapao (Gast)


Lesenswert?

>> Und ist es dunkel, dann wird B (was max. 255 groß werden kann)
>> wieder auf 0 (Wert) gesetzt.

Ist das so? Es sieht für mich wegen "Hell = 1" anders aus:

> If Led_ladezustand = 1 And Hell = 1 And B < 30 Then 'Wenn es wieder dunkel > 
'ist und der
>                                                     'Lichtimpuls nur kurz
>                                                     'war
>   ...
>   B = 0
> End If

Ich würde ein meinem Code die Variablen aussagekräftiger benennen und 
auch bessere Kommentare verwenden, so dass man den Code beim Lesen 
unmittelbar verstehen kann. Das verlängert die Kompilierzeit nicht 
signifikant und bläht den Code im µC garantiert nicht auf.

Ansonsten:
http://geekandpoke.typepad.com/geekandpoke/2012/01/coding-is-an-art.html

von Krapao (Gast)


Lesenswert?


von Michael (Gast)


Lesenswert?

Ich vermisse die Stack Angaben ...

Da es ein Tiny mit SRAM ist probier mal

$hwstack = 6


Da du Gosub und Interrupts verwendest sollte die Angabe auf keinen Fall 
fehlen!

von Tom R. (torama)


Lesenswert?

Danke, aber das hilft mir nicht viel. Evtl. sollte ich das Problem 
woanders mal posten. Der Code ist wie gesagt abgewandelt aus dem 
Backbuch für Reaktivlichter und die Variablen habe ich dann natürlich so 
belassen wie sie heißen.

Der Code funktioniert ja auch nur eben mal so 2 Tage und dann erst 
wieder nach ner Woche.

Da die Helligkeit mit einer LED gemessen wird, war meine Vermutung, dass 
es evtl. bei Temperaturen um 0°C eine Kennlinienverschiebung gibt, aber 
naja...

trotzdem danke

von bingo (Gast)


Lesenswert?

Was passiert denn, wenn der Watchdog anspricht und einen Interrupt 
auslöst?

von Tom R. (torama)


Lesenswert?

Es passiert nichts, der Prozessor wird nur schlafen gelegt und weiter 
gehts im Code.
1
If Led_ladezustand = 1 Then                                'Bei Dunkelheit Merker und Zähler für Lichtdauer löschen
2
  Hell = 0                                                  'damit sich das Programm nicht aufhängt
3
  B = 0
4
 End If

evtl. kommt er ja nicht in diese Abfrage rein, weils halt zu hell ist???

von bingo (Gast)


Lesenswert?

könnte ein Hardware-Problem sein, ändere mal den Widerstand am Eingang

von torama (Gast)


Lesenswert?

Michael schrieb:
> Ich vermisse die Stack Angaben ...
>
> Da es ein Tiny mit SRAM ist probier mal
>
> $hwstack = 6
>
>
> Da du Gosub und Interrupts verwendest sollte die Angabe auf keinen Fall
> fehlen!

Danke für diesen Tipp, Michael. Ich habs mal in den Code aufgenommen und 
bin am Testen.

Mich wunderte nur, das die Eule irgendwann immer mal wieder 
funktioniert. Wenn also der Stack überläuft, sollte der Chip doch 
eigentlich sich fest franzen. Aber wo durch kann er denn wieder 
funktionieren?

von torama (Gast)


Lesenswert?

Der Fehler wurde gefunden. Juhuuu. Der Code war in Ordnung. Nur die LED 
die kapazitiv als Lichtsensor fungiert, hat bei etwas zu hocher 
Luft-Feuchtigkeit in der Eule eine nicht vorhandene "Helligkeit" 
vorgetäuscht.
Hört sich komisch an, ist aber so ;-)

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.