hallo,
gibt es in bascom irgendwie die möglichkeit zu sagen, dass wenn ich auf
ein byte vom uart warte dass in der zeit x aber nicht eintrift.Das das
programm wenn die zeit x verstrichen ist, etwas anderes macht?
ich hoffe man versteht was ich mein.
gruß
xeus
Mehr Informationen.
So kann ich ein halbes Dutzend mögliche Problemszenarien annehmen.
Was soll genau gemacht werden.
Ist es ein Problem des Ablaufes oder eines der Sprache.(ggf.
Codeausschnitt)
Welcher Controller (Mit oder ohne Hardware-Uart ist von Interesse)
So wie es da steht kann ich nur sagen:
Zeit merken und bei Differenz X (Dein gewünschter Zeitraum) die
UART-Abfrage einstellen.
soryy also hier die fakten,
ich verwende einen ATmega16 mit einem max232.
dieser sendet an einen pc eine anfrage mit printbin x
daraufhin antwortet der pc.dermc liest dieses paket mit inputbin wieder
ein und verarbeitet diese infos. nun ist es aber so, dass es mal sein
kann, dass der pc auf eine anfrage des mc nicht reagiert. das bedeutet
dass der mc solange auf eine antwort wartet bis er eine vom pc
bekommt.
nun meine frage:
ist es nicht moglich dem mc zu sagen wenn die input routine nicht
inerhalb von 5 s erfolgreich ist, abzubrechen oder eine andere sub
aufzurufen.
ich hoffe jetzt wirds deutlicher
Yo,jetzt hab ich mehr Infos und kann mir auch nen Bild machen.
Wenn ich richtig verstehe schickst du Daten an den PC und erwartest
eine Antwort in einer bestimmten Zeit.
Bleibt die aus dann wird die Aktion Abgebrochen und normal
weitergemacht.
Eigentlich ist das einfach zu lösen.
Lass die Komunikation doch einfach über den Inteupt laufen (Wenigatens
den Empfang).
so kann ds Programm erstmal weiterlaufen und man verschwendet keine
Zeit mit Abfragen.
Den Timeout kannste dann über den Timer laufen lassen wie Crazy Horse
schon angedeutet hat.
So ist die Komunikation (fast) völlig losgelöst vom Rest.
Das wichtigste ist das du nicht mehr hängenbleiben kannst weil
irgendein Input auf ein Zeichen wartet das nie kommt.
>ok, erstmal danke, und wie realisiere ich in bascom einen solchen>timeout?
Schau mal in die Samples rein da ist es etrklärt
"Timer0/1" geben die Grundlagen als Beispiel und in "Timeout" gibt
es dann noch den etwas einfachen Weg mittels Befehl (Kostet Zeit weil
hier nur die Eingabe abgebrochen wird)
Also ich glaub nicht, dass das mit timeout funzt:
'$timeout Does Not Work With Buffered Serial Input
ich habe gepuffert.
gibts nicht irgendeine andre lösung, dass der mc eine bestimmte zeit
auf den input wartet wenn keiner in dieser zeit kommt, soll er die
anfrage wieder stellen, solange bis er input kriegt.
wär schon wenn mir jemand dazu einen bascom codeschnipsl geben könnte
gruß
xeus
>Also ich glaub nicht, dass das mit timeout funzt:>>'$timeout Does Not Work With Buffered Serial Input
Sicher funktioniert der nicht mit Puffer.
Es geht ja darum wie du auf deine Daten wartest.
Darüber hast du ja noch nix gesagt.
Wie wie ich auf meine daten wart?
das ist meine ganze sub zum empfangen
sub empf
Inputbin Packete(1) , 8
end sub
nun will ich dass er z.b vom aufruf der sub 10 s zählt, wenn die zeit
abgelaufen ist soll er gosub sende ausführen und vielleicht in einer
variablen einen wert hinterlegen kann dass ich das missglückte
empfangen regestriere.
das ist alles
>das ist meine ganze sub zum empfangen
Ja und genau da bleibste hängen wenn die Übertragung nicht kommt oder
Verstümmelt ist und sie deswegen nicht empfangen wird (8 Zeichen).
Mit abschalten des Puffers und $Timeout (und "Err" für die
abbrucherkennung.) kannste das schnell und einfach lösen.
Da du ja sofort nach Senden der Daten auf antwort wartest ist das nicht
Zeitkritisch.
Wie gesagt,eleganter wäre es den Puffer zu nutzen und ihn abzufragen
also in der Form:
Schleife
Abfrage ob Puffer 8 Zeichen hat,wenn ja dann Eingabe
Zeitnahme mit abbruchbedingung,Flag für Fehlererkennung
Schleifenende
So kannste das Universell einsetzen ungeachtet des Datenformates.
da solltest du gar nicht erst rein :-)
Dazu gibts die segensreiche Erfindung des Interrupts. Erst wenn
wirklich ein Zeichen empfangen wurde, wird was aus der UART gelesen.
Komplexe Aufgaben, wie das Empfangen eines Strings definierter Länge,
kann man nicht "mal so" mit einem Interrupt erschlagen.
Du musst also diese komplexe Aufgabe in kleine Einzeljobs zerlegen und
diese dann selbst verwalten.
Dies wäre z.B. in der UART-RX-ISR:
- das Empfangen eines Bytes im UART-Interrupt,
- das Anhängen dieses Bytes an den bisher bestehenden String,
- das Prüfen der Stringlänge,
- das schnellste Verlassen der ISR bei zu kurzem String,
- das Übergeben des Strings bei korrekter Länge an das Hauptprogramm
(ein Flag setzen, das dem Hauptprogramm mitteilt, dass der String
im SRAM gültig ist),
- das Setzen der Stringlänge (für neuen Empfang) auf 0,
- schnellstes Verlassen der ISR
Als Vorbereitung im Hauptprogramm muss mann dann eigentlich nur die
UART mit Int vorbereiten und die bereits vorhandene Stringlänge auf 0
setzen. Wenn die UART dann irgendwann mal n Bytes empfangen hat,
erkennt das Hauptprogramm das am gesetzten Flag.
Dies erfordert allerdings einen etwas anderen Programmierstiel als
input a$
b$=irgendwas(a$)
print b$
...
@Xeus
>wie sieht den ein solches interrupt in bascom aus?
Ist auch in der Hilfe und bei den Samples mit Beispielen erklärt.
Einfach mal laden und anschauen.
Dazu empfehle ich die Hilfe durchzustöbern.
Wie oft will er denn noch nachfragen ?
Offensichtlich will er hier durch beharrliches nachfragen einen
passenden Codeschnipsel ohne Eigenarbeit abgreifen.
Pisa läst grüßen
Hehe
Hi Zeus,
mein Namensvetter kam mir zuvor ;-)
Mit Ischarwaiting geht es am elegantesten.
Geht aber auch nur gepuffert (wichtig sonst funzt es nicht).
Du sendest ein Startbyte zum PC und fragst dann im Polling z.b. in der
Hauptschleife mit Ischarwaiting, ob eine Antwort vom PC vorliegt.
Über Interrupt wird es schwieriger, weil dann die UART Routinen
eigenhändig programmieren darfst.
lg Ralf
hab nun ischarwaiting eingebaut, und er erhöt nun immer wenn kein byte
vom pc vorliegt die geräte adresse +1
und sendet das paket an die neue adresse. wenn er aber nun einmal etwas
empfangen hat wars das, und bleibt bei einem erneutem nicht empfang
einfach stehen und wartet wieder so lange bis er was kriegt.
muss ich vielleicht den buffer nach dem erfolgreichen empfangen
löschen, damit er das ischarwaiting wieder von neuem richtig abfragen
kann.
gruß
xeus
Hi Zeus,
nö eigentlich nicht.
Es könnte mit der Syntax von Bascom zusammenhängen.
Wenn die nicht peinlich genau einhälst, dann kann Mist bei rauskommen.
Denke die haben ein paar Compilerfehlermeldungen vergessen ;-)
Hier ein kleiner Auszug der so funktioniert:
Config Serialin = Buffered , Size = 20
Dim B as Byte ' z.b.
Do ' z.b. Mainloop
B = Ischarwaiting()
If B = 1 Then ' ist was im Puffer?
Inputbin B ' Byte einlesen und auswerten
end if
Loop
Der Puffer wird beim Einlesen geleert, brauchst also nix löschen.
Hoffe, es klappt jetzt.
lg Ralf
entwerfe ein softwareuart in bascom und hänge den an int0 oder int1 und
schon geht die post ab.
oder mach so etwas:
Dim I As Byte
Do
If Usr.rxc = 1 Then
I = Udr
Select Case I
Case "H"
Print "Hallo AVR"
Case "h"
Print "hallo avr"
Case Else
Print "Unbekannter Befehl"
End Select
End If
Loop
End
mfg pebisoft
> ...da ich ein datenpaket von 8 bytes empfange.
Das ist ja dein Problem. Denn du weißt ja vorher nicht, ob du ein
Datenpacket empfangen kannst oder ob überhaupt kein Datenpacket mehr
kommt.
Du musst die Bytes also einzeln empfangen (falls welche ankommen) und
selbst zum Packet (String oder Array) zusammensetzen. Denn wie willst
du sonst bei nicht vorhandenem Zeichen die Einleseroutine verlassen und
zur "Tagesordnung" übergehen?
Also:
- schaun ob Zeichen da ist
- wenn ja, dann an String anhängen
- wenn nicht, dann andere Arbeit erledigen
- wenn Stringlänge korrekt ist, dann Daten auswerten und Stringlänge
für nächsten Empfang auf 0 setzen.
Da ein Hauptprogramm üblicherweise in einer Schleife läuft, kann das
auch in dieser Schleife erledigt werden. Besser und sicherer ist der
Empfang allerdings im Interrupt der UART.
...