PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RS-232 problem. Programm stürzt abundzu ab. Bitte um Hilfe!



Accenter
17.07.2010, 10:48
Ich habe meine Wohnungssteuerung erweitert um von unterwegs über das Iphone (Terminalprogramm und Ethernet/RS-232 Adapter) ein Logfile abrufen zu können.

Seit ich das eingefügt habe, kommt es zu Abstürzen. Ich vermute, dass mir der Input Puffer überläuft und das mit dem Befehl "Input" nicht wirklich gut gelöst ist in meinem Programm. Ich habe alles unwichtige aus dem Code gelöscht und hoffe, dass mir jemand sagen kann woran es liegen könnte.

Eventuell kommt es durch die Interrupts zu einem Problem. Das ist alles noch Neuland für mich. Habe auch einige Timer im Programm die interruptgesteuert beim überlauf Dinge erledigen. Eventuell kommt es hier zu konflikten?

Die Anforderung ist eigentlich ganz einfach. Kommt etwas über RS-232 rein (mit Enter abgeschlossen) soll per Interrupt in eine Subschleife gesprungen werden. Dort wird nachgesehen ob dieser Befehl bekannt ist.

Falls jemand einen Lauffägigen Code aus einer ähnlichen Anwendung hat würde ich mich sehr darüber freuen.


$regfile = "m128def.dat"
$crystal = 14745600
$hwstack = 650
$swstack = 650
$framesize = 650
$baud = 9600

Config Graphlcd = 240 * 128 , Dataport = Porta , Controlport = Portc , Ce = 3 , Cd = 5 , Wr = 6 , Rd = 7 , Reset = 2 , Fs = 4 , Mode = 6
Waitms 200
Cursor Off
Cls

Config Debounce = 50 'mit 30 gabs nach Kabeländerung auf ungeschirmt Probleme, Selbsttriggerung der Glocken'
Config Watchdog = 2048

Config Porte.3 = Output 'ledrot'
Config Portc.1 = Output 'ledgrün'
'Config Portd.4 = Output 'software uart'
'Config Portd.5 = Output 'software uart'
Config Portd.6 = Output 'Sprechanlagenrelais'
Config Porte.2 = Output 'speaker'
Config Portb.6 = Output 'TFT/Cam'
Config Portb.7 = Output 'Display Beleuchtung PWM'
Config Portd.7 = Output 'Alarm scharf (Bewegungsmelder an)'
Config Porte.4 = Output 'Alarmblinklicht'

Config Pind.4 = Input 'Rauchmelderempfänger''
Config Ping.0 = Input 'Magnetschalter Türe'
Config Ping.1 = Input 'Transponder'
Config Ping.2 = Input 'Glockentasteroben'
Config Ping.4 = Input 'Optokoppler Glocke unten'
Config Pine.6 = Input 'Panzerriegel'
Config Pine.7 = Input 'Regensensor'
Config Pinb.3 = Input 'Fenster Wohnzimmer'
Config Pinb.4 = Input 'Fenster Küche'
Config Pinb.0 = Input 'Bewegungsmelder'

Ledrot Alias Porte.3 'Ausgänge Namenszuweisung'
Alarmblinklicht Alias Porte.4
Ledgruen Alias Portc.1
Sprechanlagenrelais Alias Portd.6
Tft Alias Portb.6
Speaker Alias Porte.2
Displaybeleuchtung Alias Portb.7
Alarmscharf Alias Portd.7

Magnetschalter Alias Ping.0 'Eingänge Namenszuweisung'
Transponder Alias Ping.1
Glockentasteroben Alias Ping.2
Glockentasterunten Alias Ping.4
Panzerriegel Alias Pine.6
Regensensor Alias Pine.7
Fensterwohnzimmer Alias Pinb.3
Fensterkueche Alias Pinb.4
Bewegungsmelder Alias Pinb.0
Rauchmelder Alias Pind.4

Portg.0 = 1 'Magnetschalter Türe' 'Pullupwiderstände'
Portg.1 = 1 'Transponder'
Portg.2 = 1 'Glockentaster oben'
Portg.4 = 1 'Optokoppler Glocke unten'
Porte.6 = 1 'Panzerriegel magnetschalter'
Porte.7 = 1 'Regensensor'
Portb.3 = 1 'Fenster Wohnzimmer'
Portb.4 = 1 'Fenster Küche'
Portb.0 = 1 'Bewegungsmelder'


Config Adc = Single , Prescaler = Auto , Reference = Internal

Config Timer0 = Timer , Prescale = 256 : Config Timer1 = Timer , Prescale = 256
Config Timer2 = Timer , Prescale = 256 : Config Timer3 = Timer , Prescale = 256
Const Timer0preload = 100 'Texteinblendezeit Timer'
Const Timer1preload = 3036 'Warteschleifentimer, zum Hauptmenue zurück'
Const Timer3preload = 3036 'Kameraeinschaltzeit nach Glocke'

Const True = 1 'PWM Konfiguration für Displaybeleuchtung'
Const False = 0
Dim Hi As Byte , Lo As Byte , Phase As Bit
Lo = 150 'Defaultwerte für Beleuchtung 0=hell 255=dunkel'
Phase = True

Const Faktor = 4940 '4940 Faktor Batterie Messung. Achtung nur 0-5V Messbereich!!!'
Const Faktor2 = 19960 '19460 Faktor für 12V Spannungsmessung über Spannungsteiler 10k und 3,3k (0,1%)'


Config Sda = Portd.1 'DS1307 wird konfiguriert'
Config Scl = Portd.0
I2cinit
Waitms 50
Dim Ds1307w As Byte , Ds1307r As Byte : Ds1307w = &B11010000 : Ds1307r = &B11010001

Softwareversion = "16.07.10"

Enable Ovf1 : Enable Ovf2 : Enable Ovf0 : Enable Ovf3
On Timer1 Hauptmenuesprungzeit
On Timer2 Displaybeleuchtungszeit
On Timer0 Texteinblendezeit
On Timer3 Kamerawartezeit
Stop Timer0 : Stop Timer1 : Start Timer2 : Stop Timer3

Config Com2 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Serialin1 = Buffered , Size = 10 , Bytematch = 13
Config Serialout1 = Buffered , Size = 20
Declare Sub Serial1charmatch()
Open "Com2:" For Binary As #2
Empfang1 = "" : Empfang2 = ""
Clear Serialin1

Enable Interrupts
For Lo = 255 To 150 Step -1 'Display dimmt hoch'
Waitms 5
Hi = 255 - Lo
Next Lo
Wait 1



Gosub Linienaufbau
Gosub Hauptmenue
'Gosub Touchdisplaytest
Gosub Uhranzeige
Wait 4
Gosub Sendemailneuraufgefahren
Wait 1
'Gosub Logfile
Print #2 , "Bereit fuer Eingaben: " : Gosub Waitingtime
Print #2 , "" : Gosub Waitingtime
Start Watchdog


'------------------------------------------------------------------------------------------'
'-------------------------- Hauptschleife ----------------------------------------------'
'------------------------------------------------------------------------------------------'


Do


'Touchdisplayauswertung usw.'
Gosub Uhrzeitlesen
Reset Watchdog
Loop


'------------------------------------------------------------------------------------------'
'-------------------------- Sub Schleifen ----------------------------------------------'
'------------------------------------------------------------------------------------------'


Sub Serial1charmatch() 'Datenempfang Von Uart2 Putty Terminal iPhone von Unterwegs'
Pushall
Disable Int1
Reset Watchdog
Input #2 , Empfang2 Noecho 'Wenn über den UART was empfangen wird springt das Programm hier her über den Interrupt'
Popall
Waitms 50
Reset Watchdog
Print #2 , "Eingabe durch Benutzer : " ; Empfang2 : Gosub Waitingtime
Print #2 , "" : Gosub Waitingtime
Gosub Loginauswertung
Clear Serialin1
Enable Int1
Empfang2 = ""
End Sub

Loginauswertung:
If Empfang2 = "1234" Then
If Menue = 1 And Empfang2 = "1234" Then
Textauswahl = 32 : Clearstatusfeld = 1 : Gosub Statustextanzeige : Gosub Timer0start
End If
Print #2 , "Administrator angemeldet" : Gosub Waitingtime
Print #2 , "Logfile wird geladen:" : Gosub Waitingtime
Print #2 , "" : Gosub Waitingtime
Gosub Logfile
Unberechtigterzugrifsszaehler = 0
Else
Incr Unberechtigterzugrifsszaehler
If Unberechtigterzugrifsszaehler < 4 Then
If Menue = 1 Then
Textauswahl = 31 : Clearstatusfeld = 1 : Gosub Statustextanzeige : Gosub Timer0start
End If
Print #2 , "Unberechtigte Zugriffsversuche: " ; Unberechtigterzugrifsszaehler : Gosub Waitingtime
Print #2 , "" : Gosub Waitingtime
Else
Print #2 , "Alarm Mail nach " ; Unberechtigterzugrifsszaehler : Gosub Waitingtime
Print #2 , "unberechtigten Eingaben geschickt." : Gosub Waitingtime
Print #2 , "" : Gosub Waitingtime
If Menue = 1 Then
Textauswahl = 33 : Clearstatusfeld = 1 : Gosub Statustextanzeige : Gosub Timer0start
End If
Gosub Unberechtigtezugriffsversuche
Unberechtigterzugrifsszaehler = 0
End If
End If
Return

Logfile:
Gosub Spannungsmessung
Gosub Spannungsmessung2
Print #2 , " Letzter Login......: " ; Letzterlogin : Gosub Waitingtime
Letzterlogin = _wochentag + " " + Day_str + "." + _monat + " " + Hour_str + ":" + Min_str 'erst nach dem print neu berechnen da immer der letzte login angezeigt werden soll und nicht der diesmalige'
Print #2 , " Systemuhrzeit......: " ; Hour_str ; ":" ; Min_str ; ":" ; Sec_str : Gosub Waitingtime
Print #2 , " Datum..............: " ; _wochentag ; " " ; Day_str ; "." ; _monat ; " 20" ; Year_str : Gosub Waitingtime
Print #2 , " Letzter Start......: " ; Hochgefahrenseit : Gosub Waitingtime
Print #2 , " Gesendete Mails....: " ; Mailzaehler : Gosub Waitingtime
Print #2 , " Letzte Mail........: " ; Mailuhrzeitspeicher : Gosub Waitingtime
If Magnetschalter = 0 Then : Temp_str = "geschlossen" : Else : Temp_str = "offen" : End If
Print #2 , " Eingangstuere......: " ; Temp_str : Gosub Waitingtime
If Fensterwohnzimmer = 0 Then : Temp_str = "geschlossen" : Else : Temp_str = "offen" : End If
Print #2 , " Fenster Wohnz......: " ; Temp_str : Gosub Waitingtime
If Fensterkueche = 0 Then : Temp_str = "geschlossen" : Else : Temp_str = "offen" : End If
Print #2 , " Fenster Kueche.....: " ; Temp_str : Gosub Waitingtime
If Regensensor = 0 Then : Temp_str = "nass" : Else : Temp_str = "trocken" : End If
Print #2 , " Regensensor........: " ; Temp_str : Gosub Waitingtime
Print #2 , " Glocke in Abwesenh.: " ; Glockenlogrs232 : Gosub Waitingtime
If Panzerriegel = 0 Then : Temp_str = "verriegelt" : Else : Temp_str = "entriegelt" : End If
Print #2 , " Panzerriegel.......: " ; Temp_str : Gosub Waitingtime
If Alarmdisarmed = 0 Then : Temp_str = "scharf" : Else : Temp_str = "deaktiviert" : End If
Print #2 , " Alarmanlage........: " ; Temp_str : Gosub Waitingtime
Print #2 , " Letzte Alarmausl...: " ; Letztealarmausloesung_str : Gosub Waitingtime
Print #2 , " Batteriespannung...:" ; Spannunggesamt_str ; " V" : Gosub Waitingtime
Print #2 , " Versorgungssp......:" ; Spannunggesamt2_str ; " V" : Gosub Waitingtime
Print #2 , "" : Gosub Waitingtime
Empfang2 = ""
Return

Waitingtime: 'aufblinken der roten LED bei Empfang'
Reset Watchdog
Ledgruen = 0 : Ledrot = 1 : Waitms 20 : Ledrot = 0
Return

Rs232portbefehl: 'UART 3 Senden zum Empfaengerbaord'
Disable Int1
Open "comd.4:9600,8,n,1" For Output As #5 'Port d.4 Software UART'
Print #5 , Portbefehl
Portbefehl = ""
Close #5
Enable Int1
Return

Rs232mailsenden: 'UART 4 Mailtext zum Crumb644'
Gosub Mailuhrzeit
Disable Int1 'disable interrupt nötig! sonst fehlerhafte zeichen in der mail'
Open "comd.5:115200,8,n,1" For Output As #7 'UART 4 Port d.5 Software UART' '115200 Baudarte nötig für Crumb644 Modul'
Print #7 , "M" ; ";" ; Mailbetreff ; ";" ; " Datum und Zeit des Ereignis: " ; Mailuhrzeitspeicher ; " " ; Mailtext
Close #7
Enable Int1
Return

Uhrzeitschreiben: 'Schreibe zeit und Datum in den DS1307'
_sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour) : _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)
I2cstart : I2cwbyte Ds1307w : I2cwbyte 0 : I2cwbyte _sec : I2cwbyte _min : I2cwbyte _hour : I2cstop : I2cstart : I2cwbyte Ds1307w
I2cwbyte 3 : I2cwbyte _weekday : I2cwbyte _day : I2cwbyte _month : I2cwbyte _year : I2cstop
_sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour) : _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
Return

Uhrzeitlesen: 'Lese Zeit und Datum aus dem DS1307'
I2cstart
I2cwbyte Ds1307w : I2cwbyte 0 : I2cstop : I2cstart : I2cwbyte Ds1307r : I2crbyte _sec , Ack : I2crbyte _min , Ack : I2crbyte _hour , Ack 'zusätzliches stop eingebaut 0710'
I2crbyte _weekday , Ack : I2crbyte _day , Ack : I2crbyte _month , Ack : I2crbyte _year , Nack : I2cstop
_sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour) : _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
Return



Displaybeleuchtungszeit: 'Displaybeleuchtung'
If Phase = True Then
Displaybeleuchtung = 1
Timer2 = Lo
Phase = False
Else
Displaybeleuchtung = 0
Timer2 = Hi
Phase = True
End If
Return

Hauptmenuesprungzeit: 'wartezeit in Sekunden um zum Hauptmenue zurückzukehren'
Incr Timecount
If Timecount > Menue1sprungzeit Then
Cleardisplay = 1 : Menue = 1
Stop Timer1 : Timecount = 0
Gosub Hauptmenue
Else
Timer1 = Timer1preload
End If
Return

Resettimer:
Stop Timer1 : Timer1 = Timer1preload : Timecount = 0
Return

Resettimer0:
Stop Timer0 : Timer0 = Timer0preload : Timecount0 = 0 : Clearstatusfeld = 0
Return

Timer0start: 'Texteinlbendezeit-Timer'
Start Timer0 : Timer0 = Timer0preload : Timecount0 = 0
Return

Texteinblendezeit: 'Texteinblendezeit'
Incr Timecount0
If Timecount0 > 1100 Then
Stop Timer0 : Timecount0 = 0 : Clearstatusfeld = 0
Else
Timer0 = Timer0preload : Clearstatusfeld = 1
End If
Return

Kamerawartezeit:
Incr Kamerawartezeitcount
If Kamerawartezeitcount > 59 Then 'Cam nach einer Minute aus'
Stop Timer3 : Kamerawartezeitcount = 0 : Cam = 0
If Menue = 1 Then
Gosub Camknopfausspezial
Else
Timer3 = Timer3preload
End If
End If
Return



Statustextanzeige:
If Clearstatusfeld = 1 Then
Select Case Textauswahl
Case 0
Locate 15 , 1 : Lcd " "
Case 1
If Cam = 1 Then
Locate 15 , 1 : Lcd " Kamera wurde manuell aktiviert "
End If
If Cam = 0 Then
Locate 15 , 1 : Lcd " Kamera wurde manuell deaktiviert "
End If
Case 3
Locate 15 , 1 : Lcd " Setup Menue "
Case 5
Locate 15 , 1 : Lcd " Glocke dauerhaft Ein "
Case 6
Locate 15 , 1 : Lcd " Glocke dauerhaft Aus "
Case 9
Locate 15 , 1 : Lcd " Uhrzeit wurde erfolgreich gestellt "
Case 12
Locate 15 , 1 : Lcd " Glocke unten "
Case 15
Locate 15 , 1 : Lcd " Transponder erkannt "
Case 19
Locate 15 , 1 : Lcd " Triggere Videoserver Bildmail "
Case 25
Locate 15 , 1 : Lcd " Sende Intertechno Code "
Case 26
Locate 15 , 1 : Lcd " Sende Mail Glocke unten "
Case 31
Locate 15 , 1 : Lcd " Unberechtigter Zugriffsversuch RS-232 "
Case 32
Locate 15 , 1 : Lcd " Administrator ueber RS-232 erkannt "
Case 33
Locate 15 , 1 : Lcd " Mail geschickt nach 3 Zugr. versuchen "
Case 34
Locate 15 , 1 : Lcd " Empfang an UART 1 "
Case 35
Locate 15 , 1 : Lcd " Empfang an UART 2 "
End Select
End If
Clearstatusfeld = 0
Return

Uhranzeige: 'Blendet Uhr und Datum oben am Display ein'
Gosub Uhrzeitlesen 'hole zeit aus DS1307'
Gosub Uhrumrechnung
If _sec > 60 Or _hour > 23 Or _min > 60 Then
Locate 1 , 2 : Lcd "Bitte Uhrzeit stellen im Menue Setup"
Return
End If
Locate 1 , 1 : Lcd " " ; _wochentag ; " " ; Day_str ; "." ; _monat ; " 20" ; Year_str ; " " ; Hour_str ; ":" ; Min_str ; ":" ; Sec_str ; " "
Return


Readtouch:
Config Pinf.0 = Output
Config Pinf.2 = Output
Set Portf.0
Reset Portf.2
Ddrf.1 = 0
Ddrf.3 = 0
Waitms 2
Y = Getadc(3)
Y = 1024 - Y
Config Pinf.1 = Output
Config Pinf.3 = Output
Reset Portf.3
Set Portf.1
Ddrf.0 = 0
Ddrf.2 = 0
Waitms 2
X = Getadc(2)
X = 1024 - X
If Y > 305 Then
Displayberuehrt = 1
Y3 = Y - 346
Y2 = Y3 / 2.95
Y4 = Y2
Else
Y4 = 0
End If
If X > 155 Then
Displayberuehrt = 1
X3 = X - 149
X2 = X3 / 2.78
X4 = X2
Else
X4 = 0
Displayberuehrt = 0
End If
If Menue = 8 Then 'Im Touchfeldtest Menue wird ein Punkt gezeichnet und die koordinaten ausgegeben'
Locate 4 , 22
Lcd "Y-errechnet: " ; Y4 ; " "
Locate 5 , 22
Lcd "X-errechnet: " ; X4 ; " "
Locate 4 , 4
Lcd "Y-analog: " ; Y
Locate 5 , 4
Lcd "X-analog: " ; X
Pset X4 , Y4 , 255
End If
Return

Welchetastegross: 'wertet die grossen tasten aus'
Select Case X4
Case 20 To 80 : Zeile = 10
Case 90 To 150 : Zeile = 20
Case 160 To 220 : Zeile = 30
Case Else : Zeile = 0
End Select
Select Case Y4
Case 1 To 50 : Spalte = 1
Case 51 To 90 : Spalte = 2
Case 91 To 128 : Spalte = 3
Case Else : Spalte = 0
End Select
Gosub Keyarray
Return

Welchetasteklein: 'wertet die kleinen tasten aus'
Select Case X4
Case 15 To 44 : Zeile = 10
Case 45 To 74 : Zeile = 20
Case 75 To 104 : Zeile = 30
Case 105 To 134 : Zeile = 40
Case 135 To 164 : Zeile = 50
Case 165 To 193 : Zeile = 60
Case 195 To 224 : Zeile = 70
Case Else : Zeile = 0
End Select
Select Case Y4
Case 1 To 50 : Spalte = 4
Case 51 To 90 : Spalte = 5
Case 91 To 128 : Spalte = 6
Case Else : Spalte = 0
End Select
Gosub Keyarray
Return

Keyarray:
Key = Zeile + Spalte
If Key > 0 Then
Keyarray(keylus) = Key
Incr Keylus
If Keylus > 7 Then
Keylus = 0
If Keyarray(1) = Keyarray(2) Then
If Keyarray(2) = Keyarray(3) Then
If Keyarray(3) = Keyarray(4) Then
If Keyarray(4) = Keyarray(5) Then
If Keyarray(5) = Keyarray(6) Then
If Keyarray(6) = Keyarray(7) Then
Keypressed = Key
End If
End If
End If
End If
End If
End If
End If
End If
Return

Spannungsmessung: 'Batteriespannungsmessung'
Spannungsmesser = Getadc(6) : Gesamtsumme = Spannungsmesser * Faktor : Gesamtsumme = Gesamtsumme / 10000
Vorkomma = Gesamtsumme / 100 : Nachkomma = Gesamtsumme Mod 100
Vorkomma_str = Str(vorkomma) : Nachkomma_str = Str(nachkomma)
If Nachkomma <= 9 Then
Spannunggesamt_str = " " + Vorkomma_str + ",0" + Nachkomma_str
Else
Spannunggesamt_str = " " + Vorkomma_str + "," + Nachkomma_str
End If
Return

for_ro
17.07.2010, 11:15
Hallo Accenter,
dein Code ist nur sehr schwer zu lesen, weil keine Einrückungen drin sind.
Warum hast du die abgeschaltet? Dein Code wird auch leichter lesbar, wenn du bestimmte Blöcke wie Config, Dims, Konstanten und Alias usw. zusammenhältst. Versetze dich mal in unsere Situation. Wir kennen den Code nicht und so ist es zeitraubend, ihn richtig zu verstehen. Ich war schon kurz davor, einfach rauszugehen und nicht zu antworten.

In deiner Serial1CharMatch Routine machst du gleich zu Anfang ein Pushall und dann mittendrin ein Popall. Wieso steht das nicht am Ende der Sub?
Da diese Routine kein Interrupt ist, kann sie jederzeit von Interrupts unterbrochen werden. Den Int1 hast du ja disabled, aber die Timer Ints unterbrechen trotzdem. Speziell, wo du so lange Wartezeiten drin hast.

Accenter
17.07.2010, 11:27
Wie schalte ich das einrücken ein? Habe nichts bewusst abgeschalten, sorry.

Ich hab mit pushall und popall viel experimentiert. hatte das schon überall stehen. Daran lag es scheinbar nicht. irgendwo hab ich glesen, dass zwischen pushall und popall in keine Subroutinen gesprungen werden sollte, drum hab ich das dann so geändert. daran lags aber auch nicht.

Richard
17.07.2010, 13:11
Pop und push gehören immer als erster und letzter Befehl in einen
IRQ und auch nur in einer IRQ. Basic verwendet selber etliche
Register für seine Befehle man sollte daran denken...

Ich (glaube(?)) so etwas wie " ON com " ähnliches gelesen zu
haben, also einen IRQ durch die Serielle Schnittstelle auslösen.
Finde das aber nicht wieder. Input ist sehr schlecht weil das
ganze Programm Blockiert wird bin ein CR kommt besser
währe z.B. WAITKEY , ISCHARWAITING, INKEY.....

Gruß Richard

Richard
17.07.2010, 13:22
Alarmschleifen sollten immer mit einen Endwiderstand am Ende
der Alarmschleife versehen werden, so kann geprüft werden ob die
Linie Überbrückt (Kurzschluss) worden ist. Im der "Zentrale" kommt dann
ein 2. R der mit den Endwiderstand einen Spannungsteiler bildet.
Die Linie wird dann mittels ADC Eingang überwacht, am besten als
Komparator Eingang (geht aber auch softwaremäßig). Etwas "Spiel"
sollte eingeplant werden, ebenso eine kleine Verzögerung sonst
nervt das Teil dauernd.

Gruß Richard

Accenter
17.07.2010, 13:30
In meinem Fall springt das Programm nach dem CR sofort zu Serial1CharMatch und wertet aus was im Puffer ist. Zumindest verstehe ich das so. Das Programm wird also nicht wirklich angehalten dadurch.

Ich hatte jetzt mal alle Timmer aus dem Programm genommen, um zu sehen ob es daran lag. Leider besteht das Problem immer noch. Der Watchdog löst aus und ich hab nen Neustart.

Ich hatte gehofft, dass meine RS232 Auswertung eigentlich nichts besonderes ist und mir jemand mit einem Code helfen könnte.

Das ganze mit dem Input Befehl zu realisieren ist für mich deshalb wichtig, da ich mehrstellige Eingaben auswerten möchte.

Accenter
17.07.2010, 13:34
Die Alarmschleifen kann ich als Fehlerquelle ausschliessen (Die Alarmroutine ist deaktiviert bei meinen Tests) aber danke für den Tipp.

Accenter
17.07.2010, 13:35
Ich denke es hat was mit dem Puffer zu tun. Wenn ich eine zu lange Zeichenkette schicke hab ich sofort eine Watchdogauslösung. Sende ich nichts kommt es unvorhersehbar in unterschiedlichen zeitabständen zu Abstürzen.

for_ro
17.07.2010, 13:50
Wie schalte ich das einrücken ein? Habe nichts bewusst abgeschalten, sorry.
Kannst du unter Options -> Environment -> Editor und dort Autoindent einschalten.


Ich hab mit pushall und popall viel experimentiert. hatte das schon überall stehen. Daran lag es scheinbar nicht. irgendwo hab ich glesen, dass zwischen pushall und popall in keine Subroutinen gesprungen werden sollte, drum hab ich das dann so geändert. daran lags aber auch nicht.
Dann nimm doch mal die ganzen Auswertebefehle aus der Sub raus.


'------------------------------------------------------------------------------------------'
'-------------------------- Hauptschleife ----------------------------------------------'
'------------------------------------------------------------------------------------------'


Do
'Touchdisplayauswertung usw.'
Gosub Uhrzeitlesen
Reset Watchdog
If Received_flag = 1 Then
Received_flag = 0
Waitms 50
Reset Watchdog
Print #2 , "Eingabe durch Benutzer : " ; Empfang2 : Gosub Waitingtime
Print #2 , "" : Gosub Waitingtime
Gosub Loginauswertung
Clear Serialin1
Enable Int1
Empfang2 = ""
End If
Loop


'------------------------------------------------------------------------------------------'
'-------------------------- Sub Schleifen ----------------------------------------------'
'------------------------------------------------------------------------------------------'


Serial1charmatch: 'Datenempfang Von Uart2 Putty Terminal iPhone von Unterwegs'
Pushall
Disable Int1
Reset Watchdog
Input #2 , Empfang2 Noecho 'Wenn über den UART was empfangen wird springt das Programm hier her über den Interrupt'
Received_flag = 1
Popall
Return

Declare Sub Serial1charmatch()
kannst du dann übrigens weglassen und dann die Sub so schreiben wie oben.
Brauchst du eigentlich die ganzen Wartezeiten?
Warum benutzt du so viele :? Musst du Zeilen sparen?

Uhrzeitschreiben: 'Schreibe zeit und Datum in den DS1307'
_sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour) : _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)
I2cstart : I2cwbyte Ds1307w : I2cwbyte 0 : I2cwbyte _sec : I2cwbyte _min : I2cwbyte _hour : I2cstop : I2cstart : I2cwbyte Ds1307w
I2cwbyte 3 : I2cwbyte _weekday : I2cwbyte _day : I2cwbyte _month : I2cwbyte _year : I2cstop
_sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour) : _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)
Return
ich finde dies viel leichter zu lesen

Uhrzeitschreiben: 'Schreibe zeit und Datum in den DS1307'
_sec = Makebcd(_sec)
_min = Makebcd(_min)
_hour = Makebcd(_hour)
_day = Makebcd(_day)
_month = Makebcd(_month)
_year = Makebcd(_year)

I2cstart
I2cwbyte Ds1307w
I2cwbyte 0
I2cwbyte _sec
I2cwbyte _min
I2cwbyte _hour
I2cstop
I2cstart
I2cwbyte Ds1307w
I2cwbyte 3
I2cwbyte _weekday
I2cwbyte _day
I2cwbyte _month
I2cwbyte _year
I2cstop

_sec = Makedec(_sec)
_min = Makedec(_min)
_hour = Makedec(_hour)
_day = Makedec(_day)
_month = Makedec(_month)
_year = Makedec(_year)
Return


Wenn ich eine zu lange Zeichenkette schicke hab ich sofort eine Watchdogauslösung. Sende ich nichts kommt es unvorhersehbar in unterschiedlichen zeitabständen zu Abstürzen.
Ein Watchdog ist ja kein Absturz, sondern eine vorgegebene Aktion im Falle einer Zeitüberschreitung.
Dein Watchdog steht auf 2048. D.h. wenn 2000ms kein Reset Watchdog kommt, resettet der µC. Schau dir mal die Länge deiner Auswertung, speziell die Lofile Routine. Die braucht doch bestimmt länger als 2s zur Ausführung.
Wo sind eigentlich die ganzen Dims und die fehlenden Deklarationen wie Spannungsmessung2?


Pop und push gehören immer als erster und letzter Befehl in einen
IRQ und auch nur in einer IRQ. Basic verwendet selber etliche
Register für seine Befehle man sollte daran denken...
Serial1CharMatch ist keine IRQ, aber er hat schon recht, so steht es in der Hilfe zu Config Serialin.

Richard
17.07.2010, 13:57
In meinem Fall springt das Programm nach dem CR sofort zu Serial1CharMatch und wertet aus was im Puffer ist. Zumindest verstehe ich das so. Das Programm wird also nicht wirklich angehalten dadurch.



Das Programm wartet nach dem Input Befehl aber sooooo lange bis
auch ein CR ankommt. INKEY z.B. braucht kein CR. Wenn dein Programm
input ausführt und es kommt kein CR weil Du halt nichts sedest..wird
Deine Alarmanlage und auch der rest vom Prog stillgelegt.

Einfach ein Reset auslösen halte ich für Overkill...

Der Hinweis auf die Alarmschleifen war nur allgemein, deshalb auch
als extra Post.

Gruß Richard

Accenter
17.07.2010, 14:01
Der Watchdog bekommt nach jedem Print einen Reset (Gosub Waitingtime, dort gibts nen reset immer). Somit überscheite ich die 2 Sekunden mit Sicherheit nie.

Ich habe alles im Zeilen gepackt um beim herumscrollen schneller am Ziel zu sein. Leichter zu lesen ist es so nicht da hast du völlig recht aber das sind Routinen die ich eh nie angreife weil die funktionieren seit Jahren schon gut.

Ich hatte die Auswertungen aus der Sub schon draussen um zu sehen ob es daran lag. Auch da kam es zu Abstürzen. Ich sitze seit einer Woche an diesem Problem und verzweifle schon langsam.

for_ro
17.07.2010, 14:06
Das Programm wartet nach dem Input Befehl aber sooooo lange bis
auch ein CR ankommt. INKEY z.B. braucht kein CR.

Config Serialin1 = Buffered , Size = 10 , Bytematch = 13
bedeutet, dass das Programm das Label Serial1CharMatch anspringt, wenn ein CR empfangen wurde. Dann funktioniert das Input natürlich schon.
Aber du hast Recht, ich würde auch nicht den Input Befehl benutzen. Es könnte sein, dass das Label auch angesprungen wird, wenn mehr als 10 Zeichen empfangen wurden und der Buffer überläuft. In dem Fall wäre noch kein CR da.
Ich würde einfach den Buffer _RS232INBUF0 wegkopieren und damit weiterarbeiten.

Richard
17.07.2010, 14:07
Das ganze mit dem Input Befehl zu realisieren ist für mich deshalb wichtig, da ich mehrstellige Eingaben auswerten möchte.

Lese Dir dazu mal INSTR durch, Damit werden z.B. bei den
RN Motortreiber die Befehle übermittelt/ausgewertet/verarbeitet.

Gruß Richard

Accenter
17.07.2010, 14:07
Ja Richard ich denke die Inputauswertung ist echt das Problem. Ich hab nur keine Ahnung wie ich mit INKEY mehrere Stellen abfragen kann. Also beim Login z.B. möchte ich nach Eingabe eines Passwortes alles nötige zurückbekommen. Ein einstelliges Passwort zu haben wäre nicht schlau :-) Auch wenn es keine sensiblen Daten sind die meine Wohnungssteuerung ausspuckt.

for_ro
17.07.2010, 14:08
Der Watchdog bekommt nach jedem Print einen Reset (Gosub Waitingtime, dort gibts nen reset immer). Somit überscheite ich die 2 Sekunden mit Sicherheit nie.
Kommt es denn auch zu "Abstürzen", wenn du den Watchdog deaktivierst?

Accenter
17.07.2010, 14:18
Bei langen RS-232 Befehlen kommt es nun nicht mehr zu Abstürzen ohne Watchdog!! Endlich mal was positives. Ich frage mich jetzt nur woran das liegen kann.

Richard
17.07.2010, 14:20
Ja Richard ich denke die Inputauswertung ist echt das Problem. Ich hab nur keine Ahnung wie ich mit INKEY mehrere Stellen abfragen kann. Also beim Login z.B. möchte ich nach Eingabe eines Passwortes alles nötige zurückbekommen. Ein einstelliges Passwort zu haben wäre nicht schlau :-) Auch wenn es keine sensiblen Daten sind die meine Wohnungssteuerung ausspuckt.



Dim S As String * 30
Dim I As Integer


Print "**** RN-CONTROL V1.4 *****"
Print "Demoprogramm zu RN-MotorControl"


Do
Wait 3
Print "##" ; Chr(3) ; Chr(5) ; Chr(3) ; Chr(0)
Dim S As String * 30
Dim I As Integer


Print "**** RN-CONTROL V1.4 *****"
Print "Demoprogramm zu RN-MotorControl"


Do
Wait 3
Print "##" ; Chr(3) ; Chr(5) ; Chr(3) ; Chr(0) 'Beide Motoren Links drehen
Input S
If Instr(s , "99") = 0 Then Beep





Input S
If Instr(s , "PASSWORD") = 0 Then Beep

Muss natürlich angepasst werden aber die Demos laufen gut. :-)

Gruß Richard

Accenter
17.07.2010, 14:33
Instr schaut dann also einfach nach ob im Puffer mein Passwort erhalten ist? In deinem Beispiel habe ich aber wieder ein Input. Ich fürchte da besteht das problem weiterhin. Oder hab ich da einen Denkfehler?

for_ro
17.07.2010, 15:05
Hallo Accenter,
kannst du nicht mal deine Dims einstellen. Dann könnte man dein Programm mal kompilieren.

Wenn du ByteMatch benutzt, steht deine Eingabe schon in einem Inputbuffer, nämlich _RS232INBUF1. Allerdings als Bytes.
Kopierst du einfach mit einer kleinen Schleife weg.

Const Inputsize = 10
Const Inputsize1 = Inputsize + 1
Config Serialin1 = Buffered , Size = Inputsize , Bytematch = 13
Dim Myinputstr As String * Inputsize
Dim Myinputbyte(inputsize1) As Byte
...
Serial1charmatch: 'Datenempfang Von Uart2 Putty Terminal iPhone von Unterwegs'
Pushall
Disable Int1
Reset Watchdog
For I = 1 To Inputsize
Myinputbyte(i) = _rs232inbuf1(i)
Next I
Received_flag = 1
Clear Serialin1
Enable Int1
Popall
Return

Richard
17.07.2010, 15:49
Instr schaut dann also einfach nach ob im Puffer mein Passwort erhalten ist? In deinem Beispiel habe ich aber wieder ein Input. Ich fürchte da besteht das problem weiterhin. Oder hab ich da einen Denkfehler?

INSTR schaut IM String nach ob "xxxxx" enthalten ist. Mit input
hast Du leider recht ich hatte noch nichts gegessen und war erst
einmal beim Subway. :-)

Der Print befehl hängt ja automatich ein CR an, es gibt auch Terminals
die das können.Hterm z.B. kann man so einstellen. Mit ISCHARWAITING
kann man prüfen ob etwas im Eingangsbuffer ist, also mit nen Timer
IRQ aufrufen und nachsehen dann (enn ja) nach dem IRQ erst Gosub
input. Wenn mann alle xyz ms nachschaut soll das klappen.

Oder halt



DO
INKEY A$
if A$ =(irgendwas) then abbruch
B$ = B$+A$
abbruch
Print B$
LOOP


So kannst Du ohne CR beliebig lange Strings empfangen und
mit INSTR auswerten (irgendwas) kann z.B. ein ESC sein, nimmt
man gewöhnlich gerne zum Abbruch.

Accenter
17.07.2010, 16:05
kannst du nicht mal deine Dims einstellen. Dann könnte man dein Programm mal kompilieren


Das Programm ist echt endlos lange drum habe ich es gekürzt sonst hätte sich das keiner angetan zu lesen. Liegt auch wohl daran, dass es nicht perfekt programmiert ist. :-)

Ich werde eure Tipps mal alle durchtesten und dann bescheid geben. Ich bedanke mich schonmal für eure tolle Hilfe.

Accenter
18.07.2010, 11:15
Fehler gefunden! Es war ein Hardwarefehler. Eine zulange Resetleitung (trotz Pullup und 100nF Kondensator auf GND) war für die "Abstürze" verantwortlich. Es besteht nur weiterhin das problem mit dem Puffer. Bei zulangen Befehlen startet das programm neu.

Gibts auch ne Möglichkeit über den Watchdog keinen Reset auszulösen sondern in eine Sub zu springen? Dort könnte ich dann mit "Clear Serialin" den Puffer löschen. Wäre aber nur eine Zwischenlösung. Möchte das schon anders lösen mit dem Pufferüberlauf.

peterfido
18.07.2010, 17:50
Ich habe mir den Code nicht angesehen. RS232 frage ich über IsCharWaiting ohne IRQ ab. Wenn ein Zeichen wartet, wird geprüft, ob es ein chr(13) ist, oder nicht. Wenn nicht dann an den Eingangsstring angehangen und wenn ja, dann wird der Eingangsstring verarbeitet. chr(10) ignoriere ich bei RS232 ganz gern... Hier mal ein Auszug aus einem meiner älteren Projekte ( X300T Frontend):



Config Serialin = Buffered , Size = 88
Dim B As Byte
Dim Elaenge As Byte
Dim Seingang As String * 100
.
.
.
Do
.
.
.
If Ischarwaiting() = 1 Then
Gosub Empfangen

End If
Loop
End

Empfangen:



B = Inkey()
If B >= 13 Then
If B = 13 Then
Gosub Auswerten
Else
If Len(seingang) < 78 Then
Seingang = Seingang + Chr(b)
Elaenge = Elaenge + 1
Else
Seingang = ""
Elaenge = 0
' Print "error"
End If
End If
End If

Return

Accenter
18.07.2010, 20:41
Ich glaube das ist genau was ich brauche. Danke! Ich werde das gleich mal in meinen Code integrieren.

Accenter
20.07.2010, 14:54
Verstehe den Code soweit. Mir ist nur nicht klar was die Variable "Elaenge" genau macht.

Richard
20.07.2010, 16:09
So wie ich das sehe wird damit die Anzahl empfangener Bytes
gezählt und bei >79 also bei 80 auf Null gesetzt?

Gruß Richard

Accenter
20.07.2010, 16:19
Das wird schon mit "seingang" gemacht damit es keinen Überlauf gibt so wie ich das verstehe. "Ealaange" wird auch nirgends ausgewertet sondern nur auf 0 gesetzt.

peterfido
20.07.2010, 21:15
Das ist ein Überbleibsel und kann ignoriert werden...

Accenter
20.07.2010, 23:04
Läuft super bei mir! Danke für den code. Endlich keine abstürze mehr bei zulangen befehlen.