Hallo zusammen,
ich hab folgendes Problem und bin mir fast sicher das Ihr mir helfen
könnt:
Ich habe einen µC R8C/13 mit einem BTM-222 über UART verschaltet. Ich
versende über den µC Befehle an den BTM (siehe Code Funktion: Senden).
Über ein Hyperterminal verbinde ich den BTM über Bluetooth mit meinem PC
und sehe das die gesendeten Befehle einbandfrei ankommen. Wenn man den
BTM über Bluetooth verbunden hat, reicht dieser nur die empfangenen
Daten einfach weiter, also unterbreche ich erstmal die Verbindung. Wenn
ich jetzt eine bestimmte Antwort vom BTM erwarte(siehe Funktion ganz
unten: Init_BTM) soll erstmal zur Kontrolle der Ausgang Out_3_0 auf 1
gesetzt werden, doch es passiert nicht das was ich eigentlich erwarte.
Ich sende über die Funktion Init_BTM: "atp=14051982\n\r" + 1 sek.
Verzögerung und will das, das solange in der Schleife läuft bis die
Antwort "OK" ist. Das komische ist, EGAL was ich als Antwort gebe, der
µC geht zum nächsten Befehl als wäre ich Bedingung erfühlt. Hat jemand
eine Idee warum ???
Zur Verschaltung:
Der µC arbeitet mit einem 5V-Pegel, der BTM mit 3,3V.
µC-Tx---Spannungsteiler---BTM-Rx
µC-Rx---------------------BTM-Tx
Laut Datenblatt müsste der High-Pegel vom BTM-222 für ein High-Pegel des
µC mit 3,3V reichen.
Würde mich über Eure Hilfe sehr freuen.
Gruss
Anfänger schrieb:> Klär mich auf....was ist daran falsch ?
1. In einfache Hochkommata kann man nur ein einzelnes Zeichen packen und
keinen String.
2. Die Variable Empfangsdaten kann ein einzelnes Zeichen speichern,
keinen String.
3. Stringvergleich geht nicht über den Vergleichsoperator '=='
Dir fehlt grundlegendes Basiswissen zur Stringverarbeitung. Dieses wirst
Du Dir nicht in einem Forumsthread aneignen können, indem Du hier die
Leute löcherst, sondern nur durch Lektüre eines C-Buchs.
Kurz: So wird dat nix.
Gruß,
Frank
Ok danke erst mal.
Nur mal vorab:
Ich hab mal irgendwann C in der Schule gelernt, bin nur stark
eingerostet. Ich habe C-Bücher zuhause und lese auch diese. Ich habe den
kompletten Code selbst geschrieben, mit Hilfe dem internet und aus
meinen Büchern. Nun komme ich nicht weiter, bitte um Hilfe und bekomme
Vorwürfe das ich C lernen soll. Wenn ich das richtig verstanden habe,
sind genau solche Threads dafür da wenn man irgendwo mal einen
Denkfehler oder Wissenslücken hat. Also was sollen die ganzen Vorwürfe
???
...zurück zur Frage, was genau muss ich ändern ?
Anfänger schrieb:> meinen Büchern.
dann schlag da mal Zeichenverarbeitung, Datentypen, Strings nach
und sonst Frank hat alles gesagt was jmd mit ein bißchen C auf die
richtige Fährte bringen sollte
Anfänger schrieb:> Wenn ich das richtig verstanden habe,> sind genau solche Threads dafür da wenn man irgendwo mal einen> Denkfehler oder Wissenslücken hat.
In diesem Forum hier sind solche Threads dafür da, dass sich Leute wie
oben profilieren können und zeigen können wie toll sie doch sind.
Lass dich einfach nicht drauf ein und nimm dir nur die (wenigen)
Informationen raus die sinnvoll scheinen.
Michael H. schrieb:> Lass dich einfach nicht drauf ein und nimm dir nur die (wenigen)> Informationen raus die sinnvoll scheinen.
Ja so sehe ich das jetzt auch, so mache ich das auch.
Anfänger schrieb:> Also was sollen die ganzen Vorwürfe ???
Dir hat weder jemand etwas vorgeworfen noch hat Dich jemand
runtergemacht. Die Antworten waren lediglich Hilfe zur Selbsthilfe. Und
das ist die beste Hilfe, die man sich denken kann.
Was bringt es jetzt, wenn jemand versucht, Dein Programm zu verstehen
und Dir dann ein fertiges Programm hinrotzt? Davon hast Du gar nichts.
Wenn Du dann später noch eine Änderung machen möchtest, stehst Du wieder
wie der Ochs vorm Berg.
Lies Dir in Deinem C-Buch das Kapitel zur Stringverarbeitung durch.
Du brauchst dafür:
1. Syntax: Wie definiert man Strings? Wie formuliert man konstante
Zeichenketten?
2. Speichermodell: wie werden Strings gespeichert?
3. Stringvergleich: wie vergleicht man Strings?
Wenn Du das verinnerlicht hast, wird es ein leichtes sein, Dein obiges
Programm anzupassen. Bei Verständnisproblemen empfiehlt sich immer mal
ein Test mit einem kleinen C-Programm auf dem PC. Da kann man wesentlich
komfortabler spielen/testen/debuggen als auf einem µC.
Gruß,
Frank
Tut mir Leid aber "Lern C" und "mit löchern der Leute kommst Du nicht
weiter" sind nicht gerade die Antworten die man erwartet wenn man
eigentlich welche braucht die einfach nur mitdenken.
...trotzdem danke für die Tipps.
Der Punkt hierbei ist jedoch das dein Fehler bereits in der ersten
Antwort nach 8 Minuten gefunden wurde. Da es ein absoluter
Grundlagen-Fehler ist, brauchtest du ab diesem Moment niemanden mehr der
mit dir denkt, sondern wie bereits angemerkt eher ein C-Buch.
EDIT: Noch eine Kleinigkeit, gewöhne dir einfach an mit -Wall zu
kompilieren, dann sagt dir der Compiler sogar was falsch ist.
Anfänger schrieb:> Tut mir Leid aber "Lern C" und "mit löchern der Leute kommst Du nicht> weiter" sind nicht gerade die Antworten die man erwartet wenn man> eigentlich welche braucht die einfach nur mitdenken.
Das Problem ist, das es hier mit "einfach ein wenig mitdenken" nicht
getan ist. Stringverarbeitung in C ist zwar nicht so schwierig, wenn man
die Grundlagen kennt, aber diese muss man erst einmal kennen.
Nicht umsonst ist dem Thema "Grundlagen der Stringverarbeitung" in den
meisten Büchern ein eigenes Kapitel gewidmet. Du erwartest doch nicht
ernsthaft, dass dir hier jemand eine Einführung dazu schreibt.
In deinem Programm ist es nicht mit dem Ändern von 1 oder 2 Zeichen
getan, das grundlegende Prinzip ist schon falsch und muss geändert
werden. Dazu muss man aber verstehen, wie das eigentlich funktioniert
bzw. funktionieren sollte.
Man erkennt das zb hier ziemlich deutlich
1
}while(Empfangsdaten=='OK');
in dieser simpel anmutenden Zeile sind 3 schwere Fehler "versteckt". Für
jemanden, der mit Strings in C umgehen kann, sind sie jedoch nicht
versteckt. Für den rufen 2 von ihnen "hier, bitte ich, schau auf mich".
Der 3te ist mit ein wenig Sorgfalt ebenfalls in weniger als 10 Sekunden
zu finden, wenn man sich mal kurz nach dem Datentyp von Empfangsdaten
fragt (ein naheliegendes Vorgehen, wenn man die ersten beiden Fehler
gesehen hat).
Alleine diese Zeile zeigt mehr als deutlich auf, dass es hier an
Grundlagen mangelt. Selbst dann, wenn du eine schöne String-Senderoutine
in deinem Programm hast (die du ziemlich offensichtlich nicht selbst
geschrieben hast).
Für eine minimale Einführung lies erst mal hier:
http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F
Dieses Pamphlet soll kein Buch ersetzen, sondern aufzeigen, dass hier
mehr dahinter steckt und das ganze nicht so einfach ist, wie sich
Neulinge das gerne vorstellen.
Hallo zusammen,
ich hab das ganze mal ausprobiert und hab mir erstmal damit verholfen in
dem ich einfach nur nach den ersten Zeichen frage, das funktioniert auch
erstmal, wenn das ganze komplett läuft, ersetzte ich dann auch mal die
Abfrage eines einzelnen Zeichens mit "string.h". Damit nicht genug, wenn
ich jetzt den BTM z.B. "at" sende müsste er mit "OK" antworten was er
nicht tut oder ich empfange es einfach nicht. Wenn ich das Modul wieder
mit Bluettoth mit meinen PC und einem Hyperterminal verbinden, sehe ich
das ich aber das "at" wirklich sende. Ich habe in einem älteren Theards
gelesen, dass die zeichen an den BTM einzeln und mit gewissen Pausen
verschickt werden müssen, doch auch das ist ohne Erfolg.
Hat jemand eine Idee, wo ich jetzt wieder Wissenslücken habe ???
Gruss
Anfänger schrieb:> Hat jemand eine Idee, wo ich jetzt wieder Wissenslücken habe ?
Also ich hab jetzt auch mal was zu kritisieren, das ist einfach schwer
zu lesen wenn jemand die Sätze nicht strukturiert, überall Kommas
reinhaut, dann wild schreibt wie er spricht, wenn man am Ende dann
ankommt, meint alles verstanden zu haben, dann bleibt als erste Idee, so
wie es da beschrieben steht, was wie gesagt schwer zu lesen ist:
Das Ding ist im Kommunikationsmodus. Dort werden die Daten transparent
durchgereicht (auch "at"). Befehle nimmt das Gerät im Kommandomodus
entgegen. Dieser wird, glaub mit senden von +++ (mit Abständen
dazwischen) aufgerufen.
-Gast_XIV schrieb:> Das Ding ist im Kommunikationsmodus.
Das Modul ist im Kommandomodus. Über Bluetooth wird das Teil nur dann
mit dem Hyperterminal verbunden, um zu testen ob die Befehle auch
ankommen. Und das tun Sie.
> Dieser wird, glaub mit senden von +++ (mit Abständen> dazwischen) aufgerufen.
Wie meinst Du das ?
Gruß
Anfänger schrieb:> Das Modul ist im Kommandomodus.
Sicher?
> Über Bluetooth wird das Teil nur dann> mit dem Hyperterminal verbunden, um zu testen ob die Befehle auch> ankommen. Und das tun Sie.
Kann sein das wir uns falsch verstehen, zur Klärung:
Die Befehle können nicht über die "Luftschnittstelle" = Bluetooth
eingegeben werden. Wenn du sendest und auf der anderen Seite via
Bluetooth und Hyperterminal "AT" siehst ist das Gerät definitiv im
Kommunikationsmodus.
Es hat "Connected" und die serielle transparent durchgeschaltet.
>>> Dieser wird, glaub mit senden von +++ (mit Abständen>> dazwischen) aufgerufen.>> Wie meinst Du das ?
So wie es (nicht) im Datenblatt steht. + + + getippt beendet die
Verbindung und geht in den Kommandomodus zurück.
Ohne Gewähr aus'm Kopf
>> Gruß
zurück
-Gast_XIV schrieb:> Sicher?
Ja bin ich.
- ich verbinde meinen µC mit dem Modul per Kupferleitung (Connect-LED
blinkt)
- verbinde dann das Modul über Bluetooth zum Hyperterminal des PC's
(Connect-LED leuchtet dauerhaft)
- dann versende ich per µC die Befehle und sehe diese 1:1 im
Hyperterminal
- dann trenne ich wieder die Bluetoothverbindung zum Hyperterminal
(Connect-LED blinkt wieder)
- jetzt versende ich die selben Befehle wieder per µC und erwarte eine
Antwort, auf die der µC reagieren soll. Doch es tut sich nichts.
Ich weiß nicht genau wo das Problem liegt. Entweder ich verarbeite die
Antwort des Moduls im Quellcode falsch oder der antwortet gar nicht
erst. Hilfe !!!
PS: Danke für die Sequenzen, doch das konfigurieren per Com-Port des
PC's funktioniert bei mir tadelos.
Gruß
Anfänger schrieb:> Ich weiß nicht genau wo das Problem liegt. Entweder ich verarbeite die> Antwort des Moduls im Quellcode falsch oder der antwortet gar nicht> erst. Hilfe !!!
Dann solltest du das rausfinden
Welche Möglichkeiten hast du noch, um Ausgaben zu machen?
Karl heinz Buchegger schrieb:> Dann solltest du das rausfinden
Das versuche ich gerade.
Wenn hier das Problem nicht bekannt ist und sonst keiner eine Idee zur
Lösung des Porblems hat, dann wäre mein nächster Schritt mir eine Art
eigenes Hyperterminal in VB oder C zu schreiben, um zu sehen wie der BTM
auf meine Befehle reagiert. Meine Hoffnung ist, dass ich dann genau
verfolgen kann was, wie, und wann das Modul reagiert und wie ich die
Zeichen versenden muss.
Anfänger schrieb:> Ja bin ich.>> - ich verbinde meinen µC mit dem Modul per Kupferleitung (Connect-LED> blinkt)> - verbinde dann das Modul über Bluetooth zum Hyperterminal des PC's> (Connect-LED leuchtet dauerhaft)> - dann versende ich per µC die Befehle und sehe diese 1:1 im> Hyperterminal
Das widerspricht sich. Du sendest keine Befehle sonder Daten. Befehle
sendest du an das Modul im Command Modus, die werden aber nicht via
Bluetooth übertragen. Das Modul an den Hyperterminal anschließen +++
Enter drücken, dann AT Enter es muss! ein Ok zurückkommen.
Das ist der Wechsel von Data to Command mode mit Prüfung ob Baudrate
usw. stimmen.
Was auf der Luftstrecke passiert ist da ziemlich wumpe, selbst bei
falsche eingestellter Baudrate im Command Modus überträgt das Ding
teilweise einwandfrei. Es ist ihm halt egal was du sendest und schiebt
alles durch.
> - dann trenne ich wieder die Bluetoothverbindung zum Hyperterminal> (Connect-LED blinkt wieder)> - jetzt versende ich die selben Befehle wieder per µC und erwarte eine> Antwort, auf die der µC reagieren soll. Doch es tut sich nichts.
Da liegt der casus knacktus. Command und Data Modus sind nicht wirklich
verstanden.
Spiel die Sache erstmal am Hyperterminal durch, Brück dabei Rx- und TxD
am Modul so das du im Terminal ein Echo bekommst.
Wenn das sitzt kannst du den µP Teil machen.
>> Ich weiß nicht genau wo das Problem liegt. Entweder ich verarbeite die> Antwort des Moduls im Quellcode falsch oder der antwortet gar nicht> erst. Hilfe !!!
s.o.
Anfänger schrieb:> Wenn hier das Problem nicht bekannt ist und sonst keiner eine Idee zur> Lösung des Porblems hat,
Das Problem ist bekannt, es sitzt vor dem Monitor ;-).
Die Dinger laufen Punkt aus Ende. Es ist aber ein wenig aufwendig sich
durchzufummeln. Systematik ist angesagt bis man da drauf hat. Teilweise
musst du z.B. einfach die Kommandos langsamer übertragen (außer du
wertest RTS CTS aus) usw.
> dann wäre mein nächster Schritt mir eine Art> eigenes Hyperterminal in VB oder C zu schreiben, um zu sehen wie der BTM> auf meine Befehle reagiert. Meine Hoffnung ist, dass ich dann genau> verfolgen kann was, wie, und wann das Modul reagiert und wie ich die> Zeichen versenden muss.
Probier es erstmal mit Hyperterminal, (auch die µP Kommunikation)
wahrscheinlich hast du eine falsche Baudrate (z.B ganz falsch, keinen
Baudratenquartz usw. usf.)
-Gast_XIV schrieb:> Da liegt der casus knacktus. Command und Data Modus sind nicht wirklich> verstanden.
Ich hab das schon verstanden, mich aber viellicht falsch ausgedrückt.
Wenn ich das Modul mit Bluetooth ans Hyperterminal verbinde, dann sende
ich keine Befehle, sondern es werden nur die Daten weitergereicht. Ich
verbinde nur um zu sehen ob die Daten oder Befehle oder wie auch immer
beim Modul ankommen und weitergereicht werden. Wenn ich das Modul dann
konfigurieren will, kappe ich die Bluetoothverbindung wieder.
> Spiel die Sache erstmal am Hyperterminal durch, Brück dabei Rx- und TxD> am Modul so das du im Terminal ein Echo bekommst.
Das habe ich doch schon alles hinter mir, ich hab schon alles
durchprobiert.
Tests mit Hyperterminal:
- Verbindung vom Com-Port des PC's zum BTM erfolgreich. Ich kann
konfigurieren und bekomme antworten.
- Zusätzliche Verbindung mit Bluetooth erfolgreich. Im Hyperterminal
steht "Connect" und die Daten werden weitergereicht.
Tests mit µC:
- Verbindung zum µC + zusätzliche Bluetoothverbindung zum Hyperterminal
erfolgreich. Ich versende Daten vom µC die weitergereicht werden.
- Verbindung zum µC + zusätzliche Bluetoothverbindung zum Hyperterminal
erfolgreich. Ich versende Daten vom µC die weitergereicht werden. Der µC
erwartet eine Antwort ("O" von "OK"), ich tippe manuel im Hyperterminal
ein "O" ein und der µC reagiert auch darauf. Bei anderen manuel
eingetippten Werten z.B. kleines "o" reagiert der µC nicht, so soll es
auch sein. D.h. die Hardwarestrecke funktioniert tadelos.
- Und jetzt: Verbindung zum µC OHNE zusätzliche Bluetoothverbindung zum
Hyperterminal, also Kommandomodus. Ich versende Befehle die mit "OK"
beantwortet werden müssten, damit der µC genauso reagiert wie bei
manueller Eingabe. Doch es tut sich nicht.
Anfänger schrieb:> - Und jetzt: Verbindung zum µC OHNE zusätzliche Bluetoothverbindung zum> Hyperterminal, also Kommandomodus.
Bluetooth ist also ausgeschaltet.
> Ich versende Befehle die mit "OK"> beantwortet werden müssten, damit der µC genauso reagiert wie bei> manueller Eingabe. Doch es tut sich nicht.
Und jetzt kommt die Prüfung µC an Hyperterminal, Connect kannst du mit
Copy/Paste simulieren.
Wenn`s da funzt 1000ms zwischen den Zeichen warten.
Ich hab eine Wartezeit von 100ms zwischen den Zeichen, also...
Senden ("a");
Wartezeit(100);
Senden ("t");
Wartezeit(100);
Senden ("\n\r");
Wartezeit(100);
Muss ich den Zeichelumbruch so Senden ???
...ich probier das mal mit 1s.
Anfänger schrieb:> Ich hab eine Wartezeit von 100ms zwischen den Zeichen, also...>> Senden ("a");> Wartezeit(100);> Senden ("t");> Wartezeit(100);> Senden ("\n\r");> Wartezeit(100);>> Muss ich den Zeichelumbruch so Senden ???
AT-kompatible Modems (und sowas ähnliches ist ja auch Dein BT-Modul)
wollen (vom vermeintlichen) Terminal lediglich ein CR am Ende der Zeile
sehen. Das CR ist Deine RETURN bzw. ENTER-Taste.
Du solltest also lediglich ein "\r" schicken. Wenn Du auch ein Newline
schicken möchtest (ich würde es nicht machen, Du drückst nach der
RETURN-Taste ja auch nicht noch STRG-J in der Terminal-Emulation), dann
solltest Du erst \r, dann \n schicken, also "\r\n". Die umgekehrte
Reihenfolge macht keinen Sinn.
Ausserdem würde ich das A und das T in Großbuchstaben schicken, nicht
alle AT-kompatiblen "Modems" akzeptier(t)en das auch in Kleinbuchstaben.
Die Wartezeit kannst Du weglassen, zwischen <A> <T> <CR> braucht
normalerweise keine Pause zu sein.
Summa summarum bleibt da nur eine Zeile übrig:
Senden ("AT\r");
Anfänger schrieb:> Ich hab eine Wartezeit von 100ms zwischen den Zeichen, also...>> Senden ("a");> Wartezeit(100);> Senden ("t");> Wartezeit(100);> Senden ("\n\r");> Wartezeit(100);>> Muss ich den Zeichelumbruch so Senden ???
Also ich würde mal Großbuchstaben versuchen.
>> ...ich probier das mal mit 1s.
Besser ist das.
Es kann auch die Baudrate sein. Selbst wenn du das im PC Terminal
korrekt siehst heißt das noch lange nicht das Sie auch korrekt (im Sinne
von in der Toleranz vom BTM Modul) ist.
Es empfiehlt sich die Baudrate mit dem kleinsten Fehler einzustellen.
Hier mal eine Liste und Calculator für nen Pic, für andere Controller
wird es das auch geben
http://www.piclist.com/techref/microchip/spbrgcalc.asp?fOSCILLATOR=48&fErr=3
Hallo Anfänger.
Hast Du denn schon mal versucht mit anderen Mitteln auszuwerten, was das
BTM anwortet, wenn es vom Microcontroller angesprochen wird? Oszilloskop
um den Pegel und eventuell die Datenrate zu erkennen, oder auch über
einen Pegelwandler direkt in den COM port und mit Hyperterminal
anzeigen, was da zuürückkommt?
Grüße Hartmut
-Gast_XIV schrieb:> Der "Anfänger" hat das Modem auch> schon sehr systematisch getestet.
Danke, so komme ich mir nicht ganz so dumm vor.
Also ich werde die Tage mal alles durchtesten:
- mit 1s Pause
- zusammenhängenede Zeichen ohne Pause
- großschreibung
- mal mit "\r"
- mal mit "\r\n"
...und ich gehe mal am besten alle Bauraten durch.
Erstmal danke, ich melde mich wenn ich etwas erreicht habe.
Gruß
Hartmut schrieb:> Hallo Anfänger.>> Hast Du denn schon mal versucht mit anderen Mitteln auszuwerten, was das> BTM anwortet, wenn es vom Microcontroller angesprochen wird? Oszilloskop> um den Pegel und eventuell die Datenrate zu erkennen, oder auch über> einen Pegelwandler direkt in den COM port und mit Hyperterminal> anzeigen, was da zuürückkommt?>> Grüße Hartmut
Hallo Hartmut,
ich hab schon ziemlich alles ausgetestet, ausser die Version mit den
Oszi, hab nämlich keinen.
Tests mit Hyperterminal:
- Verbindung vom Com-Port des PC's zum BTM erfolgreich. Ich kann
konfigurieren und bekomme antworten.
- Zusätzliche Verbindung mit Bluetooth erfolgreich. Im Hyperterminal
steht "Connect" und die Daten werden weitergereicht.
Tests mit µC:
- Verbindung zum µC + zusätzliche Bluetoothverbindung zum Hyperterminal
erfolgreich. Ich versende Daten vom µC die weitergereicht werden.
- Verbindung zum µC + zusätzliche Bluetoothverbindung zum Hyperterminal
erfolgreich. Ich versende Daten vom µC die weitergereicht werden. Der µC
erwartet eine Antwort ("O" von "OK"), ich tippe manuel im Hyperterminal
ein "O" ein und der µC reagiert auch darauf. Bei anderen manuel
eingetippten Werten z.B. kleines "o" reagiert der µC nicht, so soll es
auch sein. D.h. die Hardwarestrecke funktioniert tadelos.
- Und jetzt: Verbindung zum µC OHNE zusätzliche Bluetoothverbindung zum
Hyperterminal, also Kommandomodus. Ich versende Befehle die mit "OK"
beantwortet werden müssten, damit der µC genauso reagiert wie bei
manueller Eingabe. Doch es tut sich nicht.
-Gast_XIV schrieb:> Frank M. schrieb:>> Senden ("AT\r");>> Das macht das BTM nicht (sicher) mit.
Laut Beitrag "Re: Bluetoothmodul BTM-222"
hast Du recht. Man muss tatsächlich auf das Echo des Zeichens warten.
Das konnten die damaligen Modems in den 80ern schon besser, da konnte
man die AT-Kommandos einfach Full-Speed draufpumpen.
Der obige Link zeigt auch, dass man lediglich ein einzelnes CR (\r)
schicken sollte. Es kommt dann ein CRLF (\r\n) zurück.
Also:
1
Senden("A");// 'A' senden
2
Empfangen();// Auf Echo 'A' warten
3
Senden("T");// 'T' senden
4
Empfangen();// Auf Echo 'T' warten
5
Senden("\r");// CR senden
6
Empfangen();// Auf Echo CR '\r' warten
7
Empfangen();// Auf Echo LF '\n' warten
Damit müsste es gehen. Der Aufruf von Empfangen() hat den Vorteil, dass
die Zeichen, die vom BTM-Modul zurückkommen, auch weggefressen werden
und nicht in der Input-Queue "herumlungern". Den Aufruf von Wartezeit()
finde ich suboptimal.
Gruß,
Frank
Frank M. schrieb:> hast Du recht. Man muss tatsächlich auf das Echo des Zeichens warten.> Das konnten die damaligen Modems in den 80ern schon besser, da konnte> man die AT-Kommandos einfach Full-Speed draufpumpen.
Nur, die haben aber auch eher selten 115kBaud gemacht ihren kompletten
RF Teil integriert und waren dann auch noch Klitzeklein. und FTZ und >DM
1000.- war auch eher selten.
Anfänger schrieb:> Erstmal danke, ich melde mich wenn ich etwas erreicht habe.
Beliebter Fehler ist auch immer die Masse zu vergessen. Die wird beim PC
dann "hintenrum" über die Gehäuserdung bzw wenn USB erledigt. Kaum zieht
man den COMx Stecker ab geht nix mehr. Ich weiss wovon ich schreibe ;-).
> ...und ich gehe mal am besten alle Bauraten durch.
Kauf dir einen Baudratenquartz, das schließt es sicher aus.
-Gast_XIV schrieb:>> ...und ich gehe mal am besten alle Bauraten durch.>> Kauf dir einen Baudratenquartz, das schließt es sicher aus.
So jetzt hab ich noch mal nachgeschaut. Bei mir sind definitiv
Baudratenquartze drin. Ob das Endgerät sie brauchte oder das Modem weiß
ich nicht mehr.
Eingegrenzt hab ich das mit einer Serial Software Emulation (gibts wohl
für jeden µP) die Baudraten genauer einstellt.
So....hab mich mal dran gesetzt und rumprobiert, jetzt funktioniert das
endlich.
Mit:
1
do
2
{
3
Senden("a");
4
Empfangen();
5
6
Senden("t");
7
Empfangen();
8
9
Senden("\r");
10
Empfangen();
11
}while(Empfangsdaten!='O');
D.h. ohne Pausen, direkt nach dem senden abfragen und weitersenden, die
Groß und- und Kleinschreibung ist scheinbar egal. Ich habe mal zu
Testzwecken auch andere Abfragen gestartet, um zu sehen ob der BTM
einfach nur auf irgendwelche Zeichen reagiert oder wirklich vergleicht.
Eine Abfrage z.B. nach dem Passwort (atp?) hat dieser auch nur wirklich
dann reagiert, wenn im den Vergleich 'while (Empfangsdaten != '2')'
auch die erste Ziffer des Passwortes stand.
Also habt vielen Dank.
Das ist Mist, denn es funktioniert nur zufällig.
1. Du sendest 'a'
2. Du empfängst 'a'
3. Du sendest 't'
4. Du empfängst 't'
5. Du sendest '\r'
6. Du empfängst '\r'
7. Du sendest 'a' NOCHMAL!
8. Du empfängst '\n' vom vorherigen Befehl!
9. Du sendest 't' NOCHMAL!
10. Du empfängst 'O' vom OK!
usw. usw.
Deine while-Schlife hämmert solange AT\r raus, bis irgendwann mal nach
dem Senden des \r zufällig das 'O' vom OK kommt.
Das solltest Du komplett anders machen, damit kommst Du nicht weit.
Gruß,
Frank
Anfänger schrieb:> ...achso...den Echo vom BTM (ate) musste ich auch wieder einschalten> sonst tut sich da gar nichts
Wundert mich nicht da deine Schleife ja darauf wartet ;-).
Ist prinzipiell ja nicht falsch so (eigentlich genial da RTS CTS
emulation und dabei die Leitungen sparen) aber wenn dein Modul
"connected" hängt der Prozessor fest.
Wahrscheinlich hast du dem Modul zu wenig Zeit zwischen den einzelnen
Buchstaben gelassen.
Frank M. schrieb:> 6. Du empfängst '\r'> 7. Du sendest 'a' NOCHMAL!
Stimmt nicht, bei Vergleich auf != 'O' bricht das Ding hier ab. Aber Du
kannst Dir die while-Schleife schenken, Du wirst an dieser Stelle in der
Variablen "Empfangsdaten" immer das \r stehen haben.
Gruß,
Frank
Frank M. schrieb:> Du wirst an dieser Stelle in der> Variablen "Empfangsdaten" immer das \r stehen haben.
Warum funktioniert das dann ?
Der wiederholt die while-Schleife solange, bis der Vergleich passt. Ich
frage nach 'O' der µC reagiert auf 'O' und verlässt die Schleife. Beim
anderen Zeichen sendet er die Befehle erneut. Ich frage nach '2' der µC
reagiert auf '2', mit anderen Zeichen sendet er die Befehle erneut. Das
funktioniert doch also...
1. Vermutlich musst du nach dem BTM Reset ein bischen warten, bevor du
sendest, damit das Ding zuverlässig bereit ist.
2. Es fehlen mehrere "volatile"
3. Die Funktion Wartezeit() ist kaputt.
4. Es macht keinen Spass den Code anzusehen.
Marcus Overhagen schrieb:> 1. Vermutlich musst du nach dem BTM Reset ein bischen warten, bevor du> sendest, damit das Ding zuverlässig bereit ist.
Stimmt. Bevor ich die Befehle sende, habe ich eine Wartezeit von 5s
eingelegt, sonst ragiert das Modul nicht. Womit wir beim Punkt 3 wären.
> 3. Die Funktion Wartezeit() ist kaputt.
Häh ? Das Teil funktioniert. Das ist garantiert nicht kapuut. Das ist
ein Interrupt des µC der mir eine schönen stabile Zeiten bringt.
> 4. Es macht keinen Spass den Code anzusehen.
Ich will damit auch keinen Schönheitspreis gewinnen. Erstmal will ich
das der Code seinen Zweck erfüllt und funktioniert und das tut er
momentan. Ich muss mich step by step mit den Programm vertraut machen
und auseinander setzten bevor ich alles "schön" mache und nichts
funktioniert.
Anfänger schrieb:> Frank M. schrieb:>> Du wirst an dieser Stelle in der>> Variablen "Empfangsdaten" immer das \r stehen haben.>> Warum funktioniert das dann ?>> Der wiederholt die while-Schleife solange, [...]
Nein, der wiederholt nix. Der Vergleich ist beim ersten mal schon TRUE,
denn Du prüfst '\r' != 'O'. Damit wird die do-while-Schleife schon beim
ersten mal beendet. Sie ist also hyperfluid.
Übrig bleiben im Input 6 Zeichen, die Du nicht abholst: \nOK\r\n.
Später willst Du doch Daten übertragen, nicht wahr? Wenn Du Dich da
nicht um jedes einzelne Zeichen kümmerst, wird das mit der Kommunikation
nie was.
Erstmal würde ich eine Funktion KommandoSenden() schreiben, die ein
komplettes AT-Kommando absendet und die Antwort in einem Buffer
bereitstellt.
Ein erster Prototyp könnte so aussehen:
}while(Empfangsdaten!='\n');// alles Lesen bis Zeilenende
35
36
*antwort='\0';// terminieren!
37
}
Dann kann man folgendermaßen ein Kommando senden:
1
charantwort[32];
2
3
KommandoSenden("AT",antwort,32);// oder "ATZ" oder wasweissich
4
5
if(strcmp(antwort,"OK")==0)
6
{
7
// antwort war "OK"
8
}
9
else
10
{
11
// antwort war was anderes als "OK", z.B. "ERROR"
12
}
Ich habe den Code mal einfach so hingerotzt. Da das Interface der
Funktionen Senden() und Empfangen() einfach Schei*e ist, waren da einige
Klimmzüge notwendig, z.B. der Zwischenpuffer buf, der eigentlich nicht
notwendig wäre, wenn Senden() nur ein Zeichen senden würde. Würde Senden
direkt das empfangene Zeichen als Return-Wert zurückliefern, dann würden
sich diese do-while-Schleifen vereinfachen.
Ausserdem hat das Ganze einen Schwachpunkt: Sobald ein erwartetes
Zeichen nicht kommt, hängt die Funktion Empfangen(). Das wars dann. Hier
ist dringend die Implementierung eines Timeouts notwendig.
Da hat Anfänger noch viele Kilometer vor sich, bis er dieses Projekt
einigermaßen laufen hat....
Anfänger schrieb:> Stimmt. Bevor ich die Befehle sende, habe ich eine Wartezeit von 5s> eingelegt, sonst ragiert das Modul nicht. Womit wir beim Punkt 3 wären.
Das war im von dir zuletzt geposteten Code am 13.09. nicht enthalten.
Warum willst du eigentlich Punkt 2 übergehen?
Ich sags mal so: bis jetzt hast du entweder Glück,
oder die Optimierung des Compilers abgeschaltet.
Da Counter nicht volatile ist, darf der Compiler
Counter = 0;
Pause = Pause /20;
while (Counter <= Pause)
{
}
optimieren zu:
while (1) ;
> Häh ? Das Teil funktioniert. Das ist garantiert nicht kapuut. Das ist> ein Interrupt des µC der mir eine schönen stabile Zeiten bringt.
Ja hab ich schon gesehen. Aber stabil ist das nicht. So wie du das
implementiert hast, kann ein Warten von 40 ms auch mal nur 20,1 ms
dauern. Warten von 39ms kann im Extremfall unter 0,1 ms dauern.
Außerdem ist der Zugriff auf Counter bei dir nicht atomar.
Ob das ein Problem sein kann, hängt vom Compiler und uC ab.
Das kann ich in diesem Fall nicht beurteilen.
> Ich will damit auch keinen Schönheitspreis gewinnen.
Aber du suchtest Hilfe.
Ich wünsch dir noch viel Spass und verabschiede mich.
Eins verstehe ich nicht. Wenn ich dies laufen lasse
1
do
2
{
3
Senden("a");
4
Empfangen();
5
6
Senden("t");
7
Empfangen();
8
9
Senden("\r");
10
Empfangen();
11
12
}while(Empfangsdaten!='O');
13
14
Out_3_0=1;//Testzwecke
15
Senden("FERTIG\n\r");//Testzwecke
und das aber angeblich nicht funktionieren soll, warum verlässt das
Programm die Schleife dann, wenn der erste Buchstabe von "OK" also 'O',
erscheint. Zufall kann es ja schlecht sein, weil bei anderen Buchstaben
die Schleife es immer und immmerwieder wiederholt und es sich solange
nichts tut, bis ein 'O' ankommt.
Gruß
Anfänger schrieb:> Eins verstehe ich nicht. Wenn ich dies laufen lasse>>
1
>do
2
>{
3
>Senden("a");
4
>Empfangen();
5
>
6
>Senden("t");
7
>Empfangen();
8
>
9
>Senden("\r");
10
>Empfangen();
11
>
12
>}while(Empfangsdaten!='O');
13
>
14
>Out_3_0=1;//Testzwecke
15
>Senden("FERTIG\n\r");//Testzwecke
16
>
>> und das aber angeblich nicht funktionieren soll, warum verlässt das> Programm die Schleife dann, wenn der erste Buchstabe von "OK" also 'O',> erscheint.
Weil nach dem Senden von \r ein \r als Echo empfangen wird. Anschließend
wird geprüft, ob Empfangsdaten ungleich 'O' ist. In Empfangsdaten
steht das \r (das Echo vom Senden). Das ist ungleich 'O', also wird
die Schleife sofort verlassen -> Das ist keine Schleife!
> Zufall kann es ja schlecht sein, weil bei anderen Buchstaben> die Schleife es immer und immmerwieder wiederholt und es sich solange> nichts tut, bis ein 'O' ankommt.
Du hast es immer noch nicht kapiert: die Schleife wird niemals
wiederholt, bis zum Lesen des 'O' kommt es gar nicht. Beim '\r' ist
bereits Schluss.
Frank M. schrieb:> Weil nach dem Senden von \r ein \r als Echo empfangen wird. Anschließend> wird geprüft, ob Empfangsdaten ungleich 'O' ist. In Empfangsdaten> steht das \r (das Echo vom Senden). Das ist ungleich 'O', also wird> die Schleife sofort verlassen -> Das ist keine Schleife!
Sorry wenn ich mich da einmische.
Aber das stimmt nicht.
Aus dieser Schleife kommt man nur mit einem 'O' raus.
Eben durch das ungleich
Versuche ich auf dem selben Wege in einen anderen Editor den Wert an
"Senden" zu übergeben, meldet
Frank M. schrieb:> Das ist ungleich 'O', also wird> die Schleife sofort verlassen ->
Ebene nicht. Guckst Du hier
http://www.c-programmieren.com/C-Lernen.html#Die%20do%20while-Schleife
Wenn die Bedingung bei while wahr ist (ungleich 'O', also z.B. '\n'),
werden die Anweisungen innerhalb der Do Klammern wiederholt. D.h. er
wiederholt das ganz sollange bis while ein false zurück gibt (also: "Ist
Empfangsdaten ungleich 'O'" Nein, weil Empfangsdaten gleich 'O'....also
while-schleife verlassen.
Karl heinz Buchegger schrieb:> Aus dieser Schleife kommt man nur mit einem 'O' raus.> Eben durch das ungleich
Danke. Also zurück zu meiner Frage:
Wenn ich dies laufen lasse
do
{
Senden ("a");
Empfangen();
Senden ("t");
Empfangen();
Senden ("\r");
Empfangen();
} while (Empfangsdaten != 'O');
Out_3_0 = 1; //Testzwecke
Senden ("FERTIG\n\r"); //Testzwecke
und das aber angeblich nicht funktionieren soll, warum verlässt das
Programm die Schleife dann, wenn der erste Buchstabe von "OK" also 'O',
erscheint. Zufall kann es ja schlecht sein, weil bei anderen Buchstaben
die Schleife es immer und immmerwieder wiederholt und es sich solange
nichts tut, bis ein 'O' ankommt.
Karl heinz Buchegger schrieb:> Frank M. schrieb:> Sorry wenn ich mich da einmische.> Aber das stimmt nicht.> Aus dieser Schleife kommt man nur mit einem 'O' raus.aufdiestirnklatsch ... stimmt. Da hatte ich einen Knoten im Gehirn.
Also läuft es doch wie ich es gestern abend in
Beitrag "Re: µC reagiert auf falsche Antwort"
schrieb: es wird solange "AT" rausgeschickt, bis irgendwann ein 'O' zu
sehen ist.
Warum ich mich kurz darauf umentschied... keine Ahnung. Da ist irgendein
invertierender Transistor in meinem Kopf angesprungen und hat die Logik
umgedreht.
Gruß,
Frank
Frank M. schrieb:> schrieb: es wird solange "AT" rausgeschickt, bis irgendwann ein 'O' zu> sehen ist.
Ich habs nicht geschafft.
Vielleicht schaffst du es ihn dazu zu bringen, sich endlich mal einen
2-ten Ausgabepfad zu errichten, auf dem man mitschreiben kann, was denn
vom BT-Modul so zurückkommt.
Was mich an der ganzen Sache stört: Da wird wie wild im Nebel gestochert
anstatt sich endlich einmal die paar Stunden zu nehmen und sich einen
Ausgabekanal zu errichten (und sei es nur ein 1-zeiliges LCD) auf dem
man mitlesen kann, was das Modem so von sich gibt.
Wie gesagt: Ich habs nicht hingekriegt diese Debug-Strategie zu
vermitteln.
Vielleicht schaffst du es.
Gut, dann war das nur ein schwacher Moment. Also der Tipp: nach jedem
Senden prüfen ob was angekommen ist, war genau richtig. Danke.
Werde noch ein bisschen rumprobieren und dann noch den String-Vergleich
mit einbauen.
Gruß
Karl heinz Buchegger schrieb:> Da wird wie wild im Nebel gestochert> anstatt sich endlich einmal die paar Stunden zu nehmen und sich einen> Ausgabekanal zu errichten (und sei es nur ein 1-zeiliges LCD) auf dem> man mitlesen kann, was das Modem so von sich gibt.
Wie geht das denn ?
Anfänger schrieb:> Karl heinz Buchegger schrieb:>> Da wird wie wild im Nebel gestochert>> anstatt sich endlich einmal die paar Stunden zu nehmen und sich einen>> Ausgabekanal zu errichten (und sei es nur ein 1-zeiliges LCD) auf dem>> man mitlesen kann, was das Modem so von sich gibt.>> Wie geht das denn ?
Nichts und niemand hindert dich daran, das Zeichen welches bei
Empfangen() reinkommt auf einer anderen UART zur Kontrolle wieder
auszugeben oder auf ein LCD zu schreiben.
Karl heinz Buchegger schrieb:> Nichts und niemand hindert dich daran, das Zeichen welches bei> Empfangen() reinkommt auf einer anderen UART zur Kontrolle wieder> auszugeben oder auf ein LCD zu schreiben.
Achso, das meinst Du. Könnte ich den TxD vom BTM über ein Pedelwandler
auf einen COM-PORT des PC's legen und diesen über ein 2ten Hyperterminal
auslesen ???
Anfänger schrieb:> Karl heinz Buchegger schrieb:>> Nichts und niemand hindert dich daran, das Zeichen welches bei>> Empfangen() reinkommt auf einer anderen UART zur Kontrolle wieder>> auszugeben oder auf ein LCD zu schreiben.>> Achso, das meinst Du. Könnte ich den TxD vom BTM über ein Pedelwandler> auf einen COM-PORT des PC's legen und diesen über ein 2ten Hyperterminal> auslesen ???
Auch das müsste gehen.
Du verlierst dann zwar die Kontrolle darüber, was dein µC eigentlich
einliest (da könnte ja auch ein Bug sitzen), aber es ist schon mal
besser als nichts darüber zu wissen, was sich auf den Leitungen
abspielt.
Karl heinz Buchegger schrieb:> Wie gesagt: Ich habs nicht hingekriegt diese Debug-Strategie zu> vermitteln.
Ich glaube auch nicht, dass er sein "Projekt" erfolgreich bewältigt,
wenn er so weitermacht wie bisher. Er stochert die ganze Zeit im Nebel -
da hast Du vollkommen recht.
> Vielleicht schaffst du es.
Ich wollte eigentlich gar nichts mehr hier schreiben - schon gar nicht
einen Beispiel-Code, wie man AT-Kommandos schickt und auswertet.
Trotzdem hat mich diese Sache schon gejuckt, ich habe sogar gestern mal
nach diesen BT-Modulen geschaut und überlegt, ob ich mir spaßeshalber
mal 2 davon zum Spielen zulegen sollte. Nicht wegen diesem Thread,
sondern weil ich die Thematik spannend finde.
Die Chancen, ihm systematisches Arbeiten zu vermitteln, sehe ich als
ziemlich gering an. Man könnte ihm zwar ein komplettes Programm,
schreiben, aber genau das wäre eigentlich der falsche Weg. Vielleicht
sollte ich mich ruhiger verhalten und erstmal abwarten wie er (bzw. sein
Projekt) sich entwickelt. Dann kann ich auch nicht so Klöpse bauen wie
die mit der while-Bedingung, die mir ja richtig peinlich ist. ;-(
(Ja, ich sitze hier mit rotem Kopf und schäme mich. Da programmiere ich
in C seit Mitte der 80er Jahre und plötzlich drehe ich im Kopf die Logik
einer simplen while-Bedingung rum. Ich frage mich echt, wie so etwas
passieren kann, wo while-Schleifen zu meinem täglichen Brot gehören.)
Anfänger schrieb:> Werde noch ein bisschen rumprobieren und dann noch den String-Vergleich> mit einbauen.
Eben genau das "Rumprobieren" bringt Dich nicht weiter. Du musst da viel
systematischer rangehen. Erstmal musst Du ein "Gespür" für das BT-Modul
entwickeln: "wie verhält es sich, wenn ich dies und das tue". Das geht
nur mit entsprechender Ausrüstung, z.B. einem LCD-Modul oder einem
weiteren (Soft-)UART-Ausgang, damit Du auch "siehst", wie es sich
verhält. Ich würde auch viel mehr mit dem PC und einem (geeigneten)
Terminal-Emulationsprogramm testen. Wenn dieses die empfangenen Zeichen
in Hex- oder anderer Schreibweise ausgibt, kannst Du solche Zeichen wie
\r oder \n direkt "sehen". Notfalls kann man einen Hex-Dump auf eine
Log-Datei des Terminal-Emulationsprogramms machen.
Dann solltest Du Dir Gedanken zur Kommunikation machen: welche
Software-Module (Funktionen) brauche ich? Wie baue ich die Software
aufeinander auf? Wie kann ich die einzelnen Teile austesten bzw.
debuggen? Baue die Software in Stufen auf und teste jede Stufe
ausführlich. Ein fertiggestelltes (großes) Programm erst am Ende zu
testen (also alles auf einmal) ist wesentlich mühseliger, weil es viel
schwieriger ist, dann noch den Fehler einzukreisen.
Aus Deinem bisherigen Code lese ich auch heraus, dass Du sehr wenig
Programmiererfahrung hast und auch nicht gerade in den Techniken, die
einem die Sprache C bietet, belesen bist. Da hast Du Nachholbedarf.
Ich werde mich jetzt erstmal zurückhalten und schauen, wie sich das hier
weiter entwickelt. Sollte es beim "Rumprobieren" bleiben, sehe ich da
keine Chance.
Diese AT Kommunikation (auf Kommando Ebene) ist doch im Grunde nichts
anderes als 'Zeile hinschicken' - 'Zeile empfangen'.
Und genau damit würde ich anfangen. Mir Routinen zu schreiben, die eine
Zeile zum Modem hinschicken und eine Zeile als ganzes empfangen. Und das
wird dann getestet. Bis zum Exzess. Dazu brauch ich aber ein
Ausgabemedium auf dem ich sichtbar machen kann, was vom Modem
zurückgekommen ist.
Dieses Rumgefrickel mit Zeichen hin, Zeichen her, wenn der richtige
Buchstabe ... das führt doch zu nichts. Das verallgemeinert doch nicht.
Für mich und meine Arbeitsweise ist es einer der wichtigsten Punkte, mir
immer möglichst frühzeitig ein Ausgabemedium zu schaffen. Ich will so
schnell wie möglich aus dem Stadium raus, in dem ich Dinge annehmen muss
weil ich sie nicht weiß. Ich will wissen was vom Modem daherkommt. Ich
will wissen, ob in der Empfangsroutine unter Umständen ein \r sein
trauriges Dasein fristet, weil ich ihn vergessen habe auszufiltern. Ich
will wissen, ob die UART Pufferung im Interrupt funktioniert. Ich will
wissen und nicht raten.
Das ist meine Arbeitsweise. Und so wie es scheint ist die nicht so
schlecht. Bis jetzt hat sich noch kein Gerät mit zeilenorienterter
Kommandoübertragung länger als ein paar Stunden gewehrt, die Kommandos
anzunehmen und zu bearbeiten.
Anfänger schrieb:> Ok, danke für den Tipp. Ich probier das mal.
Eine RS232 Weiche geht ohne Probleme, hab ich schon öfter gemacht. Gibt
sogar Y-Adapter zu kaufen.
Ich kenne deine Möglichkeiten nicht, aber du kannst auch eine Led
blinken lassen wenn du dieses oder jenes Zeichen empfängst.
Off Topic:
Frank M. schrieb:> Eben genau das "Rumprobieren" bringt Dich nicht weiter.Karl heinz Buchegger schrieb:> Für mich und meine Arbeitsweise
Ehrlich, ich als C-Novize steh vor dem gleichen Problem wie der
Threaderöffner. Hab zwar schon tausend von Zeile in anderen Sprchen
geschrieben aber auch da ist Versuch und Irrtum angesagt.
Schon vergessen wie etwas selbst gelernt wurde? Ohne Irrtum geht das
einfach nicht. Niemand kann wissen kann WIE er etwas verstanden hat
(falsch richtig ist da nur eine Möglichkeit) und Arbeitsstil (z.B. extra
Kanal zum prüfen) und Beurteilungsraster bilden sich auch nicht in einer
Woche. Unser mutiger Anfänger ( mutig bei den (ex cathedra?) Koryphäen
hier so zu posten und dann noch mit einer seriell bluetooth Anwendung
zu beginnen -) ist doch schon ganz schön weit gekommen oder?
Bankswitch operator from hell schrieb:> Schon vergessen wie etwas selbst gelernt wurde? Ohne Irrtum geht das> einfach nicht.
Richtig. Aber wie kann man einen Irrtum ohne entsprechendes Instrument
überhaupt erkennen? anfänger schrieb, dass die do-while-Schleife
funktioniert und damit fertig.
> Niemand kann wissen kann WIE er etwas verstanden hat> (falsch richtig ist da nur eine Möglichkeit) und Arbeitsstil (z.B. extra> Kanal zum prüfen) und Beurteilungsraster bilden sich auch nicht in einer> Woche.
Selbstverständlich nicht.
> Unser mutiger Anfänger ( mutig bei den (ex cathedra?) Koryphäen> hier so zu posten und dann noch mit einer seriell bluetooth Anwendung> zu beginnen -) [...]
Mutig ist er, ja. Vielleicht hat er sich da aber auch zuviel
vorgekommen.
> [...] ist doch schon ganz schön weit gekommen oder?
Er kann momentan die Zeichenfolge "AT" versenden - mehr nicht. Aber wie
schon die Chinesen sagen: "Auch der längste Weg beginnt mit dem ersten
Schritt".
Frank M. schrieb:> Richtig. Aber wie kann man einen Irrtum ohne entsprechendes Instrument> überhaupt erkennen?
Nur kurz, sonst gleitet das ab.
Das ist doch das schöne beim erlernen technischer Systeme. Es gibt immer
eine Kontrolle, namentlich die der Funktion des ganzen.
> Mutig ist er, ja. Vielleicht hat er sich da aber auch zuviel> vorgekommen.
Nun das kann jeder für sich entscheiden, mir steht das jedenfalls nicht
zu.
Frank M. schrieb:> Er kann momentan ...
Alles braucht seine Zeit.
Bankswitch operator from hell schrieb:> Schon vergessen wie etwas selbst gelernt wurde?
Nein. Durchaus nicht vergessen.
Auf dem Grossrechner die Programm mit Ausgabeanweisungen gespickt um
rauszufinden warum das Programm wann in welchen Programmzweig reinkommt
und wie die Variablen stehen.
Programme auf einem Grossrechner, die irgendwann in der Nacht im Batch
unbeaufsichtigt laufen und alles was du hast ist der Output den du dir
selber produzierst, sind eine ausgezeichnete Schule, wie man auch mit
einfachen Mitteln debuggen kann.
Das erste was man lernt:
Wenn man etwas nicht nachvollziehen kann, dann muss das Programm eben
aushelfen, indem es mitprotokolliert was es tut, welche Daten es zur
Verfügung hat, wie Variablen stehen, etc. Dazu brauch ich aber eine
Ausgabefläche.
Ich hab das bei Neulingen schon oft beobachtet: Die haben eine
unglaubliche Scheu davor, Anweisungen ins Programm zu schreiben (wie
zusätzliche Kontrollausgaben) die nachher wieder rausfallen. So
funktioniert Programmieren nicht. Kaum eine Anweisung ist im Endprodukt
noch so, wie sie ursprünglich in der ersten Version war. Die Zeit, die
man sich nimmt um sich Hilfsmittel zu schaffen um dem Programm über die
Schulter sehen zu können, kriegt man hundertfach durch kürzere Bug-Fix
Zeiten wieder rein.
> Es gibt immer> eine Kontrolle, namentlich die der Funktion des ganzen.
Das reicht aber in der Programmierung nicht.
In einem halbwegs ernstzunehmenden Programm gibt es hunderte
Möglichkeiten für das Versagen des "technischen Systems" auf allen
möglichen Ebenen (inklusive Fehlbedienung).
Was du hier im Grunde sagst, kann man mit einer Analogie aus dem Bereich
Medizin beschreiben: Wenn "es" weh tut, dann bist du krank.
Super. Von dieser Erkentniss hab ich jetzt was.
Karl heinz Buchegger schrieb:> Auf dem Grossrechner die Programm mit Ausgabeanweisungen gespickt um> rauszufinden warum das Programm wann in wel...
Is ja alles Ok. Aber der Weg ist rückblickend entstanden, das konnte man
damals nicht wissen. Außerdem hat der Anfänger keine Nachtschicht im
Rechenzentrum D;-). Deine Tips sind gut keine Frage, auch die Erfahrung
weitergeben ist super. Aber es gibt auch Information Overload.
> Das reicht aber in der Programmierung nicht ..
Klar reicht es nicht, ist aber die eigene Geschichte, der eigene (auch
Irr-) Weg. Es ist zwar löblich diesen bei anderen abkürzen zu wollen,
aber - jetzt pack ich den großen philosophischen Hammer aus- wenn das
ginge sähe die Welt wahrlich anders aus. Erfahrungen macht halt jeder
selber.
Bankswitch operator from hell schrieb:> Karl heinz Buchegger schrieb:>> Auf dem Grossrechner die Programm mit Ausgabeanweisungen gespickt um>> rauszufinden warum das Programm wann in wel...>> Is ja alles Ok. Aber der Weg ist rückblickend entstanden, das konnte man> damals nicht wissen.
Ähm.
Doch. Den 'Trick' hatte man nach der ersten Übung raus. Und wenn nicht
haben einem das die älteren Semester gesagt.
> Außerdem hat der Anfänger keine Nachtschicht im> Rechenzentrum D;-).
Ich als Student im ersten Semester auch nicht :-)
Das lief so:
Ein Programm wurde ins Rechenzentrum übertragen (mit deinen
Account-Daten). Dort wurde das Programm (genannt 'der Job') in eine
Queue eingereiht. Gelaufen, im Sinne von Compiler/Linker/Programm läuft,
ist es dann irgendwann in der Nacht. Output vom Programm wurde
automatisch gedruckt, die Ausdrucke wurden vom Operator früh morgens in
Ausgabefächer einsortiert, von wo man sich den Output abholen und
studieren konnte.
Wenn du also nur 1 Programmlauf pro Tag hast und nicht mehr als 14 Tage
bis zur Abgabe deiner Übungsaufgabe hast, dann hast du de facto nur 14
Compiler Läufe bzw. 14 Anläufe dein Programm fehlerfrei zu bekommen. Da
entwickelst du ganz schnell Methoden, wie du aus einem Lauf maximal viel
Information raus holen kannst :-) Ins Blaue raten kannst du dir nicht
leisten.
(Gott sei Dank sind die Zeiten vorbei, auch wenn es eine gute Schule in
der Methodik war)
Meine Güte, da wird hier philosophiert und das weil ich nicht der Crack
in C bin und mich nicht scheue mir anderweitig Informationen zu holen.
Nur mal damit das ganze endlich mal ein Ende hat und wir beim Thema
bleiben:
Ich bin Elektrotechniker und hatte das letzte mal vor ca. 4-5 Jahren
C-Programmierung oder etwas tiefere Grundkenntnisse der Elektronik.
Gelernt habe ich nur die Grundfunktionen, max. Pointer und
Funktionsaufrufe. Die Ansteuerung eines µC per C hab ich nie gesehen,
geschweige denn eine selbstgebaute Ansteuerung per µC an ein
Bluetoothmodul. Ich beschäftige mich (zwischendurch) seit ca. 6 Monaten
etwas intensiver mit µC und der UART-Schnittstelle in Verbindung mit dem
BTM. Meiner Meihnung nach (und danke für die klaren Worte Bankswitch
operator from hell), habe ich in der Zeit schon mehr als erwartet nur
mit Hilfe von Büchern und dem Internet zum laufen bekommen. Ich bin ja
eurer Meihnung nach total unsystematisch an die Sache ran gegangen, habe
es aber erstsaunlicherweise, mit meinen sehr wenigen Erfahungen, schon
weit in meinen "Projekt" erreicht. Zudem musste ich sogar als
Grünschnabel, einen angeblich erfahrenen C-Programmierer der seit ca. 25
Jahre anscheinend nicht anderes macht, erklären wie eine Fußgesteuerte
While-Schleife funktioniert.
Wie schon Michael H. sagte, ist das keine Hilfe sondern:
>In diesem Forum hier sind solche Threads dafür da, dass sich Leute wie>oben profilieren können und zeigen können wie toll sie doch sind.
Ich arbeite seit ca. 5 Jahren in der Planung der Prozessleittechnik und
schreibe auch nicht in Foren für Anfänger der PLT, wie blöd die sich
doch anstellen (im Übertragenen Sinne)...also bitte meine Herren,
plustet euch nicht so auf sondern bleibt beim Thema.
Anfänger schrieb:> Meine Güte, da wird hier philosophiert
Ok, hier sind ein paar ins Plaudern über die gute alte Zeit gekommen. Zu
meiner Ehrenrettung muss ich sagen das ich mir die Geschichten über alte
Kollegen die Lochkarten noch ohne Hilfsmittel gelesen und korrigiert
haben verkniffen habe.
> und das weil ich nicht der Crack> in C bin und mich nicht scheue mir anderweitig Informationen zu holen.
Nee, das ging um die "gute alte zeit"
> Ich arbeite seit ca. 5 Jahren in der Planung der Prozessleittechnik und> schreibe auch nicht in Foren für Anfänger der PLT, wie blöd die sich> doch anstellen (im Übertragenen Sinne)...
Nimm's nicht persönlich.
Das trifft jetzt nicht auf dich zu, aber so ein Forum wie dieses ist
auch immer ein Spannungsbogen zwischen denen die gern helfen und
Schlaumeiern die ihre Hausaufgaben gemacht haben wollen, einige prägt
das negativ und Sie unterscheiden nicht mehr.
> Ich bin ja> eurer Meihnung nach total unsystematisch an die Sache ran gegangen,
das stimmt in meine Augen nicht. Selbst wenn, diese sinnlose Kritik an
Stilfragen "nicht mal ignorieren" ist einfach.
> einen angeblich erfahrenen C-Programmierer der seit ca. 25> Jahre anscheinend nicht anderes macht, erklären wie eine Fußgesteuerte> While-Schleife funktioniert.
Es juckte mich die ganze Zeit auch in de ´n Fingern das auf Tablett zu
bringen, aber wozu?
> also bitte meine Herren,> plustet euch nicht so auf sondern bleibt beim Thema.
Ähhhmmmm wie lautete das noch gleich ;-).
Bankswitch operator from hell schrieb:> Ähhhmmmm wie lautete das noch gleich ;-).
Hehe....also. Ich habe per µC Befehle an das BTM geschickt und hatte
Probleme die Antworten und Echos abzufangen bzw diese weiter zu
verarbeiten. Der Frank M. hat mich auf eine Idee gebracht, dass die
Befehle die ich an das BTM schicke erstmal 1:1 zurückkommen.
Also:
- ich sende ein "a"
- ich empfange ein "a"
- ich sende ein "t"
- ich empfange ein "t"
...usw
Ich wollte aber, dass ich genau das sehen kann und habe gestern
folgendes ausprobiert. Zuerst habe ich das Programm so umgeschrieben,
dass alle empfangenen Daten in der globalen Array 'Empfangsdaten[]'
geschrieben werden (siehe Code, letzte Funktion). Dann hab ich das
Problem gehabt, dass ich keine Möglichkeit hatte, die Befehle die ich
ans BTM sende zu beobachten, ohne wieder aus dem Kommandomodus zu
fliegen. Also habe ich mir mit folgendem verholfen. Nach dem ich alle
Zeichen gesendet und alle erwarteten Echos im Array abgelegt habe, legte
ich eine kleine Warteschleife von 3s ein. In der Zeit hatte ich genug
Zeit das Hyperterminal über Bluetooth mit den BTM zu verbinden und
konnte so die Echos die normalerweise auf den µC landen würden im
Terminal beobachten (Ausgabe des Arrays). Nun sah ich genau das der BTM
genau das macht, was der Frank M. schon gesagt hatte, ich empfing genau
das zeichen zurück was ich gesendet hatte. Dies habe ich vor dem Array
auch mal mit einzelnen Variablen probiert und nach jedem senden eine
Ausgabe gefordert.
Um jetzt auszuschließen, dass dies nicht die selben Zeichen sind die ICH
sende, also Zeichen die "aus meinen Befehlen" kommen, sondern wirklich
die Echos des BTM's sind, habe ich über den Befehl "ATE0" die Echos im
BTM probeweise ausgeschaltet und die ganze Sende-Empfange-Prozedur
wiederholt. Und siehe da, es kommt nichts zurück. Somit hatte ich die
Gewissheit, dass das wirklich Echos des BTM's waren.
So weit, so gut. Jedenfalls habe ich es (nach einen kleinen Tipp von
Frank M.) geschafft die einzeln Echos abzufangen. Mein Problem besteht
aber jetzt darin, dass ich immernoch keine Antowrt "OK" abfange. Ich
habe nach meinen Befehlen ein "\n", "\r" oder sogar ein "0x0D" (soll
anscheinend der ASCII-Code für Enter sein) gesendet, aber ein "OK" bzw
'O' und 'K' konnte ich nicht abgreifen. Ich habs mit Pausen dazwischen
versucht und mir das komplette Array anzeigen lassen, doch es war kein
'O' und / oder 'K' dabei.
Was mache ich falsch ?
Gruss
Deine Routine Empfangen() holt sich gerade mal 1 Zeichen von der UART.
* Lass doch dem BT ein bischen Zeit, damit es reagieren kann
* Woher weißt du, dass nach deinem letzten Aufruf von Empfangen()
nicht noch etwas vom Modem gekommen wäre?
Empfangen per Polling, und dann immer nur ein einzelnes Zeichen.
Das ist meiner Meinung nach ganz großer Müll!
Aber ich zitiere hier gerne nochmal den Anfänger:
> Ich will damit auch keinen Schönheitspreis gewinnen. Erstmal will ich> das der Code seinen Zweck erfüllt und funktioniert und das tut er> momentan.
Anfänger schrieb:
> Mein Problem besteht aber jetzt darin, dass ich immernoch keine> Antowrt "OK" abfange.
Warum benutzt Du nicht einfach die Funktion KommandoSenden aus
Beitrag "Re: µC reagiert auf falsche Antwort"
wie Frank M. vorschlug? Die speichert Dir doch die Antwort vom BT als
Zeichenkette. Da brauchst Du doch nur noch mit strcmp zu checken, welche
Antwort gekommen ist. Du kannst sie auch ausgeben, z.B. auf einem LCD
oder UART. Da war auch noch eine Korrektur von ihm:
Beitrag "Re: µC reagiert auf falsche Antwort"
NochnGast schrieb:> Anfänger schrieb:>>> Mein Problem besteht aber jetzt darin, dass ich immernoch keine>> Antowrt "OK" abfange.>> Warum benutzt Du nicht einfach die Funktion KommandoSenden aus>> Beitrag "Re: µC reagiert auf falsche Antwort">> wie Frank M. vorschlug?
Die ist zwar schon besser (nichts für ungut Frank) aber im Grunde immer
noch schlecht.
Solange das Empfangen nicht von Polling auf Interrupt Betrieb umgestellt
wird, ist das alles eher sinnlos.
Da bin ich mit Marcus Overhagen einer Meinung.
Der µC hat es nun mal nicht unter Kontrolle, wann das Modem mit der
Übertragung loslegt, wie schnell das Modem reinpfeift. Er muss sich an
das Modem anpassen und nicht das Modem an ihn.
Mittels Polling ist das zwar möglich, aber umständlich. Umständlich
deshalb, weil man an allen Ecken und Enden zwischendurch mal schnell die
UART abfragen muss, ob ein Zeichen eingetroffen ist. Dann das kann zu
jedem beliebigen Zeitpunkt kommen! Ganz fies wird es dann erst, wenn man
dann auch noch Fehlerfälle berücksichtigen muss. Denn dann kommt unter
Umständen nämlich gar kein Zeichen daher und die Polling-Schleife hängt.
Oder auf dem Modem ist das Echo abgedreht und es sendet das Empfangene
nicht retour. Oder das Modem wartet seinerseits bis die Zeile
vollständig ist um sie dann als Ganzes zu echon. Da gibt es viele
Möglichkeiten. Oder aber die ganze Übertragung dauert zu lange und
während man auf das Echo wartet, beschliest das Modem das der halb
übertragene Kommandostring ins Timeout gelaufen ist. Oder ...
Das ganze ist nicht so banal, wie man sich das am Anfang gerne
vorstellt. Und mittels Polling wird es sogar noch einen Tick schlechter,
als wie wenn man einen Interrupt an die UART hängt, die eingehende
Zeichen erst einmal in einem genügend großen Buffer zwischenspeichert.
Dann muss man beim Senden nicht ständig die UART zwischendurch abfragen.
Eingehende Zeichen wandern erst mal automatisch in diesen Buffer, von wo
sich der µC nach dem Senden in aller Ruhe 1 Zeichen nach dem anderen
holt bis er den \n sieht (oder ein Timeout aufgetreten ist). Die
Programmstruktur wird so in Summe viel einfacher, auch wenn es zunächst
komplizierter klingt.
Karl heinz Buchegger schrieb:> Die ist zwar schon besser (nichts für ungut Frank) aber im Grunde immer> noch schlecht.
Ich weiß, dass sie wenig bis nichts taugt. Ich hatte sie auch nur
geschrieben, um anfänger in die richtige Richtung zu schubsen. Selbst
würde ich so eine Funktion für eigene Zwecke niemals schreiben. Ich
dachte nur "Er kann ja seine ersten Erfahrungen mit Polling machen.
Später wird er nicht umhin kommen, das anders über Interrupts zu lösen".
Ich wollte ihm eigentlich nur ein "Gespür" für die Komminikation für so
ein BT-Dingens vermitteln - mehr nicht.
(EDIT: Ich hatte die Funktion KommandoSenden() auch bewusst als
"Prototyp" deklariert und widerwillig anfängers Empfangen() und
Senden()-Funktionen benutzt, um ihn nicht komplett aus der Bahn zu
werfen)
Die Nachteile des Pollings deutete ich auch schon im obigen Beitrag an,
nämlich dass er ohne Timeout-Behandlung da schnell einen hängenden
Prozessor hat. Aber ich dachte mir einfach "eins nach dem andern, Rom
ist auch nicht an einem Tag gebaut worden". Schließlich glaubte ich auch
nicht, dass anfänger auch jemals schon eine ISR geschrieben hat. First
make it wörk, then make it better. At least make it fine ;-)
Auch ich stimme da mit Marcus Overhagen überein: Das Konzept per Polling
ist so einfach Murks.
> Der µC hat es nun mal nicht unter Kontrolle, wann das Modem mit der> Übertragung loslegt, wie schnell das Modem reinpfeift. Er muss sich an> das Modem anpassen und nicht das Modem an ihn.
Ja, so ist es.
> Und mittels Polling wird es sogar noch einen Tick schlechter,> als wie wenn man einen Interrupt an die UART hängt, die eingehende> Zeichen erst einmal in einem genügend großen Buffer zwischenspeichert.> Dann muss man beim Senden nicht ständig die UART zwischendurch abfragen.
Eben, allein die andauernden Senden-Empfangen-Senden-Empfangen-Sequenzen
zeigen schon, dass da am Code etwas nicht stimmen kann.
@anfänger: ich wünsche Dir noch alles Gute bei Deinem Vorhaben.
Gruß,
Frank
Karl heinz Buchegger schrieb:> Deine Routine Empfangen() holt sich gerade mal 1 Zeichen von der UART.> * Lass doch dem BT ein bischen Zeit, damit es reagieren kann
Ja. Dies legt er aber in Array und holt sich das nächste. Auf den ersten
Blick sieht das ja erstmal ganz gut aus, doch wie gesagt fehlt mir noch
das 'OK'. Meinst Du etwa ich sollte noch ein bisschen warten bis ich mir
das 'OK' abholen kann ?
Karl heinz Buchegger schrieb:> * Woher weißt du, dass nach deinem letzten Aufruf von Empfangen()> nicht noch etwas vom Modem gekommen wäre?
Gute Frage. Weiß ich nicht.
NochnGast schrieb:> Warum benutzt Du nicht einfach die Funktion KommandoSenden aus
Ganz einfach. Jeder bringt hier seine Vorschläge und Code-Schnipsel ein.
Wenn ich deshalb jedesmal mein Code komplett über den Haufen werfen
würde, hätte ich bis jetzt gar nichts erreicht. Ich hab ein bestehenden
Code den ich Schritt für Schritt durchkaue und gucke ob auch das
passiert das ich damit erreichen will. Wenn ich nun an einen Punkt
angekommen bin an den ich nicht mehr weiter weiß, versuche ich erstmal
der Sache auf den Grund zu gehen und nicht direkt alles über den Haufen
zu werfen.
Karl heinz Buchegger schrieb:> Warten_ms (1000);> Senden ("a");> Empfangen();> Senden ("t");> Empfangen();> Senden ("p");
Da kann das arme BT Modul aber auch nicht gerade gemütlich den Befehl
verstehen abarbeiten und OK senden.
Du wartest zwar auf dein Echo (schon mal löblich) aber dadurch ist
warten abhängig von der Baudrate.
Bei 57 600 sind das z.B. gerde mal 1/57600 *10 (1/ Baud * Bits) was
nicht gerad auf 1s rausläuft.
Das arme Modul bekommt also gerade mal ein Zeichen auf die serielle
gequetscht (das dann ja "gleichzeitig" bei dir im Empfangspuffer
auftaucht) ist damit fertig und schon knallst du ihm das nächste vor den
Latz.
kein Wunder das da "nur" das Echo empfangen wird.
Anfänger schrieb:> Blick sieht das ja erstmal ganz gut aus, doch wie gesagt fehlt mir noch> das 'OK'. Meinst Du etwa ich sollte noch ein bisschen warten bis ich mir> das 'OK' abholen kann ?
Du machst einen grundlegenden Denkfehler.
Du kannst dir das OK überhaupt nicht abholen.
Das BT schickt dir das OK. Nur weißt du nicht wann!
Du lebst immer noch in einer Welt, die sich synchron abspielt. Zuerst
mach das, dann mach das und zu guter letzt mach das.
UART Empfang funktioniert aber in den wenigsten Fällen so. Von der UART
kriegst du Zeichen asynchron rein. Zu jeden beliebigen Zeitpunkt. Du
weisst nicht genau wann.
Du schickst ein Kommando zu einem Gerät und irgendwann später kommt die
Antwort.
Die beste Methode um dem zu begegnen ist es, die USART nicht zu pollen,
sondern die USART einen Interrupt auslöen zu lassen, wenn ein Zeichen
rein kommt. Das Zeichen wandert erst einmal in einen großen Buffer. Dort
sammeln sich die Zeichen und von dort kannst du dir dann dein OK
abholen, sofern es schon da ist. Wenn es noch nicht da ist, dann wartet
man eben maximal (hausnummer) 3 Sekunden und erklärt danach die
Übertragung für gescheitert.
Mit deiner Poll-Strategie wirst du nicht sehr weit kommen.
> Ganz einfach. Jeder bringt hier seine Vorschläge und Code-Schnipsel ein.> Wenn ich deshalb jedesmal mein Code komplett über den Haufen werfen> würde, hätte ich bis jetzt gar nichts erreicht. Ich hab ein bestehenden> Code den ich Schritt für Schritt durchkaue und gucke ob auch das> passiert das ich damit erreichen will. Wenn ich nun an einen Punkt> angekommen bin an den ich nicht mehr weiter weiß, versuche ich erstmal> der Sache auf den Grund zu gehen und nicht direkt alles über den Haufen> zu werfen.
Deine Grundstrategie ist schon falsch. Drum läufst du in ein Problem
nach dem anderen.
Du hast 2 Möglichkeiten: Entweder du klebst ein Pflaster nach dem
anderen auf das Leck oder du machst es gleich richtig.
Bankswitch operator from hell schrieb:> Das arme Modul bekommt also gerade mal ein Zeichen auf die serielle> gequetscht (das dann ja "gleichzeitig" bei dir im Empfangspuffer> auftaucht) ist damit fertig und schon knallst du ihm das nächste vor den> Latz.
OK. Ich habe das ganze mal zwischen Senden und Empfangen mit einer Pause
versucht. Bei 10ms funktioniert das ganze noch, doch wenn ich sogar hoch
auf 1s gehe hängt sich das Programm auf (wahrscheinlich , weil der Code
auf ein Echo wartet, es aber "verpasst" hat).
Anfänger schrieb:> Ganz einfach. Jeder bringt hier seine Vorschläge und Code-Schnipsel ein.> Wenn ich deshalb jedesmal mein Code komplett über den Haufen werfen> würde, hätte ich bis jetzt gar nichts erreicht.
Du steckst in einer Sackgasse und merkst es nicht einmal.
Wenn Du von Punkt A nach Punkt B kommen willst, hilft nicht immer der
kürzeste Weg. Da braucht nur ein Fluss dazwischen zu sein. Gibt es keine
Brücke, musst Du umkehren und Dir einen neuen Weg suchen.
> Ich hab ein bestehenden> Code den ich Schritt für Schritt durchkaue und gucke ob auch das> passiert das ich damit erreichen will.
Mit Deinem Code drehst Du Dich nur im Kreis. Du nimmst keine Ratschläge
an und verbohrst Dich nur weiter in Deinen Code... und steckst immer
tiefer fest im Schlamm.
> Wenn ich nun an einen Punkt> angekommen bin an den ich nicht mehr weiter weiß, versuche ich erstmal> der Sache auf den Grund zu gehen und nicht direkt alles über den Haufen> zu werfen.
Mach es so, wie Du meinst. Ich frage mich ehrlich, was Du hier willst
bzw. erwartest. Ich bin damit raus. Eins nehme ich aus diesem Thread
mit: Ich weiss endlich, wie while-Schleifen funktionieren. Danke Dir
dafür.
Eventuell könnte man das so retten.
Das heißt nicht das das eine gute Lösung ist!
1
// sowohl UART als auch den Empfangsbuffer ausleeren
2
// damit wir mal gesicherte Verhältnisse haben
3
// na ja, löschen ist gut gesagt
4
while(ri_u0c1)
5
Empfangen();
6
Global_i=0;
7
8
// den String rausgeben
9
// falls in der Zwischenzeit was reinkommt, dann einfach mal von
10
// der UART abholen
11
Senden("a");
12
if(ri_u0c1)
13
Empfangen();
14
15
Senden("t");
16
if(ri_u0c1)
17
Empfangen();
18
19
Senden("p");
20
if(ri_u0c1)
21
Empfangen();
22
23
Senden("?");
24
if(ri_u0c1)
25
Empfangen();
26
// Senden (&test);
27
// Senden ("\r\);
28
29
//
30
// jetzt gilts: mit dem \n beginnt das Gerät das Kommando zu bearbeiten
31
// falls da noch ein Echo vom \n kommt, dann wollen wir den noch haben
32
// ehe der ganze Eingansgbuffer verworfen wird. Allerdings warten wir
33
// auch nicht ewig
34
Senden("\n");
35
for(i=0;i<1000;++i){
36
if(ri_u0c1)
37
Empfangen();
38
}
39
40
// Irgendwann ist das Gerät mit seiner Arbeit fertig und schickt sein OK
41
// Dazu leeren wir den Buffer erst mal aus (das möglicherweise
42
// empfangene Echo der Kommandos interessiert keinen
43
Global_i=0;
44
45
// an dieser Stelle können wir nur hoffen, dass das Echo vom
46
// vorher gesendete \n schon da ist (falls es überhaupt eines gegeben hat)
47
48
// Als Timeout fragen wir die UART 30000 mal ab. Ist bis dahin kein
49
// OK eingetrudelt, dann wird das als Timeout gewertet
50
for(i=0;i<30000;++i){
51
if(ri_u0c1)
52
Empfangen();
53
}
54
55
if(Global_i==0)
56
;Timeoutbehandeln
57
58
if(strncmp(Empfangsdaten,"OK",2)==0){
59
// das OK ist da
60
}
der Code ist voll mit Timingannahmen. Und das ist schlecht.
Aber ich bin jetzt auch raus.
Polling, so wie du das durchdrücken willst, funktioniert halbwegs
vernünftig, wenn an der Gegenstelle ein Mensch sitzt, der
vergleichsweise langsam tippt. Aber selbst dann ist man mit einer
Interrupt-Lösung besser bedient. Einfach deswegen weil man sich
ansonsten mit der UART den µC ständig blockiert. Ausser auf Zeichen
warten, macht der sonst nichts anderes mehr. Das geht in manchen
Applikationen. Aber mit einem asynchronen Empfangsverfahren in einen
großen Buffer und Benachrichtigung wenn eine Zeile komplett im Buffer
vorliegt, ist man deutlich flexibler wenn alles auf zeilenweiser
Kommunikation aufbaut.
Anfänger schrieb:> OK. Ich habe das ganze mal zwischen Senden und Empfangen mit einer Pause> versucht.
1s?
> Bei 10ms funktioniert das ganze noch,> doch wenn ich sogar hoch> auf 1s gehe hängt sich das Programm auf (wahrscheinlich , weil der Code> auf ein Echo wartet, es aber "verpasst" hat).
So wird es sein, da kommen noch Zeichen und du siehst gar nichts.
Kathedermodus ein:
Das ist genau das was Karl Heinz mit der Interruptlösung beschrieben
hat, er wird da auch schon mal drauf reingefallen sein.
Kathedermodus aus
Ist schwierig, du wartest auf Empfang, willst aber gleichzeitig gucken
was Empfangen wird.
Mit Interrupt anzufangen ist erst nächstes Semester auf der mikro.net
Uni dran, ich würde mal prüfen ob der UART nicht ein Receiver Ready Flag
oder ähnliches hat. Das kannst du dann prüfen und zwischendurch was
anderes machen.
Frank M. schrieb:> Du steckst in einer Sackgasse und merkst es nicht einmal.>> Wenn Du von Punkt A nach Punkt B kommen willst,
Das ist in meine Augen vollkommen sinnlos so etwas zu schreiben.
Eine globale Zustandsanalyse des Probanden ist vielleicht bei
medizinischer Forschung sinnvoll, bei konkreten technischen Problemen
führt es nicht weiter.
Das war jetzt auch mein letzter Kommentar zu einem "Subthena" das sich
meiner bescheidenen Meinung nach mehr verrannt hat als der Anfänger
selbst.
Bankswitch operator from hell schrieb:> Kathedermodus ein:> Das ist genau das was Karl Heinz mit der Interruptlösung beschrieben> hat, er wird da auch schon mal drauf reingefallen sein.> Kathedermodus aus
Ich denke, jeder fällt da einmal rein.
Schreibt man sich aber ein Log der empfangenen Zeichen auf einer anderen
UART oder einem LCD mit, dann sieht man, dass da ein Zeichen oder zwei
fehlt. Womit wir wieder bei effizienten Debug-Methoden und Stochern im
Nebel wären :-)
(@TO: Was glaubst du eigentlich warum ich da so darauf rumreite? Weil
mir das Spass macht?)
> Mit Interrupt anzufangen ist erst nächstes Semester auf der mikro.net> Uni dran,
Weißt du etwas, was wir anderen nicht wissen?
Karl heinz Buchegger schrieb:> UART Empfang funktioniert aber in den wenigsten Fällen so. Von der UART> kriegst du Zeichen asynchron rein. Zu jeden beliebigen Zeitpunkt. Du> weisst nicht genau wann.> Du schickst ein Kommando zu einem Gerät und irgendwann später kommt die> Antwort.
Ok, ich glaube das war der entscheidende Tipp. Du hast recht, wenn ich
das richtig gelesen habe, senden und empfang die Geräte asychron.
Karl heinz Buchegger schrieb:> Die beste Methode um dem zu begegnen ist es, die USART nicht zu pollen,> sondern die USART einen Interrupt auslöen zu lassen, wenn ein Zeichen> rein kommt.
Interrupt ist eine gut Idee, das probier ich mal.
Ich muss mich jetzt nochmal einmischen...
Karl heinz Buchegger schrieb:> Eventuell könnte man das so retten.> Senden ("a");> if( ri_u0c1 )> Empfangen();
Das geht so nicht. Das Echo kommt etwas verspätet vom BT zurück. Dein if
wird daher immer FALSE sein. Und damit macht man sich genau das
"Ausbremsen" kaputt: Man muss auf das Echo warten, bevor man das nächste
Zeichen senden darf. Ein Senden mit voller Geschwindigkeit funktioniert
nicht, siehe auch Beitrag von "Travel Rec." im Thread "Bluetoothmodul
BTM-222":
http://www.mikrocontroller.net/topic/goto_post/690276
Der Aufruf von Empfangen() unmittelbar nach Senden() ist einzig und
allein dazu da, sich selbst auszubremsen und so das nächste Zeichen erst
dann zu schicken, wenn das BTM-Modul auch wieder bereit ist, das nächste
Zeichen anzunehmen.
Den Trick hat "Bankswitch operator from hell" auch noch nicht
durchschaut, er will trotzdem immer noch einen Sleep einbauen, obwohl
der (hängende) Aufruf von Empfangen() gerade die perfekte
Synchronisation bedeutet. Nur das Timeout fehlt - wie schon öfters
gesagt.
> Senden ("\n");
Bei AT-kompatiblen Modems (und auch beim BT-220) schickt man nach dem
eigentlichen Kommando nur ein CR, kein Newline. Diese "Modems" warten
auf Deine CR-Taste - beim Benutzen eines Terminals oder einer
Terminalemulation. Diese Taste sendet beim Drücken ein CR, kein LF. Du
musst daher senden: A T P \r und nichts weiter. Allerdings sendet ein
AT-Modem (und auch das BT-Modul) in der Antwort ein CRLF zurück, d.h.
man muss dann auf \r und \n warten.
Frank M. schrieb:>> Senden ("a");>> if( ri_u0c1 )>> Empfangen();>> Das geht so nicht. Das Echo kommt etwas verspätet vom BT zurück. Dein if> wird daher immer FALSE sein. Und damit macht man sich genau das> "Ausbremsen" kaputt: Man muss auf das Echo warten, bevor man das nächste> Zeichen senden darf. Ein Senden mit voller Geschwindigkeit funktioniert> nicht, siehe auch Beitrag von "Travel Rec." im Thread "Bluetoothmodul> BTM-222":
Ich weiß jetzt nicht wie das bei dem BT-MOdem konkret ist.
Aber was, wenn das Echo abgeschaltet ist?
Man kann das Drehen und wenden wie man will, mit diesem Pollen wird das
nichts. Das Modem soll seine Antwort, wenn es eine sendet, asynchron zu
meinem Programmlauf reinschieben können und die wird in einem Buffer
zwischengepeichert. Alles andere führt immer wieder in Timing und Race
Condition Probleme, die man nicht vernünftig in den Griff kriegt.
> der (hängende) Aufruf von Empfangen() gerade die perfekte> Synchronisation bedeutet.
Sofern überhaupt ein Echo kommt
> Nur das Timeout fehlt - wie schon öfters> gesagt.
OK. Hier hast du dann ein fehlendes Echo berücksichtigt. Damit ist dann
aber auch wieder die Timeout Zeit verantwortlich für die
Synchronisation. Ein Teufelskreis.
> Terminalemulation. Diese Taste sendet beim Drücken ein CR, kein LF. Du> musst daher senden: A T P \r und nichts weiter. Allerdings sendet ein> AT-Modem (und auch das BT-Modul) ein CRLF zurück, d.h. man muss auf \r> und \n warten.
Ja.
Bei einem Zigarettchen hab ich auch gemerkt, dass die Idee den
bisherigen Empfangsbuffer nach dem Senden des \n (oder \r) auszuleeren
nicht unbedingt eine Glückliche ist.
Karl heinz Buchegger schrieb:> Ich weiß jetzt nicht wie das bei dem BT-MOdem konkret ist.> Aber was, wenn das Echo abgeschaltet ist?
Dann hängt der µC bis in alle Ewigkeit.
Man könnte zunächst ATE1 ins "Blinde" schicken (dann tatsächlich mit
Delays), um das Echo auf dem Ding einzuschalten. Besser sogar noch ein
"+++" (mit Abständen zwischen den Pluszeichen im Sekundenbereich) davor
senden, um erstmal zu garantieren, dass man einen definierten
Ausganszustand hat, nämlich den Kommandomodus und nicht den
(transparenten) Datenmodus.
> Man kann das Drehen und wenden wie man will, mit diesem Pollen wird das> nichts.
Ja, retten kann man da nichts.
>> der (hängende) Aufruf von Empfangen() gerade die perfekte>> Synchronisation bedeutet.>> Sofern überhaupt ein Echo kommt
Eben.
> Ein Teufelskreis.
Nett gesagt, ich beschrieb es als "Sackggasse". Der Effekt ist aber
derselbe: es geht nicht weiter´;-)