PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Fehler bei Programmabarbeitung



Ruppi
19.08.2005, 12:51
Hallo,
bei meiner Anwendung tritt ein merkwürdiges Problem auf: Ich lese einen Bild-/Bewegungssensor mit einem Mega8 aus, dabei gibt es 2 Modi: Modus=1 -> Bewegungsdaten über RS232 an PC schicken, Modus=2 -> Bilddaten an PC schicken. Nach dem Flashen des Controllers ist der Modus 1 aktiv und alles läuft fehlerfrei. Auch das Umschalten in den Modus 2 läuft und der Sensor liefert mir Bilder an den PC. Ich kann es mir nach unzähligen Versuchen nicht mehr erklären, aber das erneute Umschalten in den Modus 1 geht nicht. Das Zeichen kommt über die RS232 definitiv an, aber scheinbar wird das Hauptprogramm nicht mehr abgearbeitet oder der Timer liegt lahm!?!
Ich hoffe, jemand kann mir helfen, danke.

Hier ein Ausschnitt aus meinem Code:


Do
If Modus = 2 Then
Call Get_picture()
Call Send_picture()
Else
Printbin Abspos_x ; Abspos_y ; Squal ; Motion ; Maximumpixel ; 13 ;
End If
Loop

'###############################################

'Timer-Routine zur Abfrage der Sensor-Werte mit etwa 6kHz
Ontimer:
If Modus = 1 Then
Call Read_motion()
End If
Timer1 = 65430
Return

'###############################################

'Interrupt für den Zeichenempfang
Onrts:
Modus = Udr
If Modus = 0 Then
Abspos_x = 0
Abspos_y = 0
Modus = 1
End If
If Modus = 1 Then Toggle Portb.1
If Modus = 2 Then Toggle Portb.0
Set Reset_chip
Waitms 300
Reset Reset_chip
Wait 1
Set Ncs
Return

PicNick
19.08.2005, 13:03
Bist du sicher, daß der PC werte die 0, 1 u. 2 schickt und nicht
Ascii '0', '1' od. '2' ?
da haut der Vergleich nie hin

Ruppi
19.08.2005, 14:43
Nein, das stimmt garantiert, habe die Werte zurückgeschickt und die kommen auch an. Des Weiteren habe ich bei Ankunft der Zeichen bestimmte Ports getoggelt und daran sieht man ja auch, dass es klappt. Hast Du sonst noch eine Idee? Ich kann einfach keinen Fehler finden...

Ruppi
19.08.2005, 14:51
Der Controller soll die Bewegungsdaten sehr oft (ca. 6kHz) abfragen und aufsummieren. Nur wenn er Zeit hat, soll er sie an den PC schicken, deswegen habe ich das Senden der Daten in die Hauptschleife und nicht in den Timerinterrupt gepackt.

PicNick
19.08.2005, 14:55
Bevor du nach "DO" kommst, welchen Wert hat da Modus ?
Setzt du den vorher auf 1 ?

Ruppi
19.08.2005, 14:59
Ja, ich habe vorher eine kleine Initialisierung, ich setze vor Programmbeginn Modus auf eins, deswegen läuft die Übertragung der Bewegungsdaten direkt nach dem Flashen.

PicNick
19.08.2005, 15:39
Ich seh so auch nix. Es stehen Get_picture & send_picture in Verdacht.
Sprechen die Toggles in gewünschter Weise an ?

PicNick
19.08.2005, 15:47
Noch was: Wenn du wieder in den Mode 1 schalten willst, was macht er da ? bleibt er beim Bilder senden oder stellt er den Betrieb überhaupt ein ?

19.08.2005, 20:26
Ich dachte auch erst, es würde an Get_picture oder Send_picture liegen, allerdings konnte ich den Fehler ausschließen. Die Toggles reagieren so wie sie sollen. Auf Deine zweite Frage: von Mode 1 auf 2 geht, aber nicht zurück, er scheint einfach stehen zu bleiben, als würde er sich aufhängen.
Ist es eigentlich ein Unterschied, wo ich die Hauptschleife des Programms platziere? Wenn die die Hauptschleife ans Ende meines Codes stelle, arbeitet das Programm völlig anders!

Trotzdem erstmal Dnake für Deine Hilfe...

chr-mt
19.08.2005, 23:12
Hi,
ich hatte schon Probleme, wenn der END Befehl nicht nach der Hauptschleife kommt.
Probiere doch mal das END direkt hinter dein Loop zu setzen.:

Do
...

Loop
END

Danach die Subs



Gruß
Christopher

PicNick
20.08.2005, 08:00
Hat vielleicht nix damit zu tun, aber ganz allgemein:
Seltsames Verhalten kann entstehen, wenn
$HWSTACK =
$SWSTACK =
$FRAMSIZE =
zu kleine Werte haben. Die Defaultwerte sind absolut miniwinz. Für einen Interrupt müssen z.B 64 Byte HWSTACK da sein, sonst scheppert's.

Ruppi
22.08.2005, 08:32
@chr_mt : Sowas hatte ich auch schon mal, hatte auch gehofft, es liegt vielleicht daran, aber leider nicht. Warum auch immer, aber die Do-Loop Schleife scheint man immer schreiben zu müssen. Bei mir liefen sogar rein Interruptgesteuerte Programme ohne die Do-Loop Schleife nicht korrekt.

@PicNick : Habe es auch mit Veränderung des Stacksize probiert, leider funktioniert aber auch das nicht.

Sehr merkwürdig ist, dass das Programm tadellos läuft, wenn ich den Timer nicht verwende und alles in die Hauptschleife schreibe. Allerdings besteht dann eben das Problem, dass der Sensor nicht mit den geforderten 6kHz abgefragt wird. Irgendwas scheint nicht mit dem Timer zu stimmen.
Es muss doch einen Grund dafür geben...

Trotzdem Danke erstmal für die Hilfe!

PicNick
22.08.2005, 08:40
Moment: Was tut sich eigentlich bei get- und send-picture ?
Immerhin ist es so, daß bei JEDEM Zeichen von der UART dem Controller für fast 1.5 Sekunden das Licht ausgeht.
Vielleicht hat er einfach keine Zeit mehr für Dich ?

Ruppi
22.08.2005, 09:16
Interessant, ist es nicht so, dass ein Interrupt nicht durch einen anderen gestört werden kann? Ich habe trotzdem mal "Timer1=0" in die I-Routine für den Zeichenempfang geschrieben, damit der Timer nicht irgendwo dazwischenfunkt, es läuft aber trotzdem nicht.
Wenn ich vor Programmabarbeitung Modus auf 2 setze, ist alles umgekehrt: dann läuft der Kameramodus tadellos, jedoch ist eine Umschaltung auf den Bewegungsmodus nicht mehr möglich, das Programm scheint zu stoppen.

PicNick
22.08.2005, 10:11
So oder so, es scheint, daß der Kamera-Modus ein Umschalten einfach nicht zuläßt.
Mach statt get- sendpic irgendeinen print "ein bild", und schau, ob dann das Umschalten geht.

... allerdings konnte ich den Fehler ausschließen.
Ein Tipp: solange du nicht weißt, was es ist , kannst du auch nicht sagen, was es NICHT ist. Sowas verklebt die Augen.

Ruppi
22.08.2005, 11:10
Ok, habe statt Get_picture einfach einen Text ausgegeben, trotzdem lässt sich das ganze nicht umschalten. Get_picture braucht relativ lange (ca. 2ms), weil die einzelnen Pixel des Bildes seriell aus dem Sensor getaktet werden müssen. Noch sehr viel länger dauert natürlich die Übertragung der Bilddaten über die RS232. Die Sache mit der Bildübertragung ist nicht ganz so wichtig, muss aber funktionieren. Wichtiger ist die kontinuierliche Abfrage der Bewegungsdaten. Da der Sensor nur inkrementale Positionsdaten auswerten kann, verliert man leider schnell die Absolutposition, wenn ein paar Frames "nichts" mitbekommt, das ist das Problem an der Sache.

PicNick
22.08.2005, 12:21
Wenn du "send_pic" auch noch erstmal wegläßt, reden wir weiter.

By the way: Ich würde die positions-daten grundsätzlich in den Picture-stream einschleusen und garnicht umschalten.

Ruppi
22.08.2005, 12:25
Send_pic habe ich schon weggelassen. Die Positionsdaten kann ich nicht in den Picture-stream packen, weil dieser zu langam abgefragt wird. Außerdem kann der Sensor nur eine Sache gleichzeitig ausgeben.

PicNick
22.08.2005, 15:00
Nun, ich seh folgendes Problem:
DIe Wahrscheinlichkeit, daß beim Zurückschalten auf mode 1 gerade das get- oder Send- pic läuft, ist groß. d.h. nach dem Interrupt kommt er erstmal dorthin zurück. Mode ist aber inzwischen = 1
Daher wird auch sofort der Timer schnackeln und bevor get_ /send-pic reagieren kann, wird daher read-motion angeworfen.
Der fährt also ins volle Leben.
Versuch: setz einen Schalter BEVOR du get- send pic machst, und lösch ihn, wenn du rauskommst.
In timer-Interrupt machst du NUR dann Read-Motion, wenn Mode= 1 UND dieser Schalter = 0.

Noch was : tu dieses grauslichen Wait aus der Interrupt routine
Vorschlag



Modus = 0
Altmodus = Modus
Do
if Altmodus <> Modus then
If Modus = 0 Then
Abspos_x = 0
Abspos_y = 0
Modus = 1
End If

If Modus = 1 Then Toggle Portb.1
If Modus = 2 Then Toggle Portb.0
Set Reset_chip
Waitms 300
Reset Reset_chip
Wait 1
Set Ncs
Altmodus = Modus
End if

If Modus = 2 Then
schalter = 1
Call Get_picture()
Call Send_picture()
schalter = 0
Else
Printbin Abspos_x ; Abspos_y ; Squal ; Motion ; Maximumpixel ; 13 ;
End If
Loop

'###############################################
'Timer-Routine zur Abfrage der Sensor-Werte mit etwa 6kHz
Ontimer:
If Modus = 1 and schalter = 0 then
Call Read_motion()
End If
Timer1 = 65430
Return
'###############################################
'Interrupt für den Zeichenempfang
Onrts:
Modus = Udr
Return


Vielleicht hilft das auch nix, aber trotzdem ist es einfach sauberer.

Ruppi
23.08.2005, 14:47
Genau das war es, daran hat's gelegen. Ich danke Dir für Deine Hilfe, ohne Dich hätte ich das nicht hinbekommen, also nochmals vielen Dank!