Forum: Mikrocontroller und Digitale Elektronik µC reagiert auf falsche Antwort


von Anfänger (Gast)


Angehängte Dateien:

Lesenswert?

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

von ... .. (docean) Benutzerseite


Lesenswert?

Empfangsdaten == 'OK'

geht nicht ist ja nur eine unsigned char, LERN C!

von Anfänger (Gast)


Lesenswert?

Klär mich auf....was ist daran falsch ? Der Name "Anfänger" sagt doch 
schon alles oder ?

Gruss

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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

von Stephan H. (stephan-)


Lesenswert?

suche mal nach "Parser" !!

von Anfänger (Gast)


Lesenswert?

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 ?

von ... .. (docean) Benutzerseite


Lesenswert?

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

von Michael H. (morph1)


Lesenswert?

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.

von Anfänger (Gast)


Lesenswert?

Stephan Henning schrieb:
> suche mal nach "Parser" !!

Danke, ich lese mir das mal durch.

von Anfänger (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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

von Anfänger (Gast)


Lesenswert?

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.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Anfänger (Gast)


Angehängte Dateien:

Lesenswert?

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

von -Gast_XIV (Gast)


Lesenswert?

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.

von Anfänger (Gast)


Lesenswert?

-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ß

von -Gast_XIV (Gast)


Lesenswert?

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

von -Gast_XIV (Gast)


Angehängte Dateien:

Lesenswert?

Hier eine quick and dirty aber getestete Demo für Code Sequenzen

von Anfänger (Gast)


Lesenswert?

-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ß

von Karl H. (kbuchegg)


Lesenswert?

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?

von Anfänger (Gast)


Lesenswert?

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.

von -Gast_XIV (Gast)


Lesenswert?

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.

von -Gast_XIV (Gast)


Lesenswert?

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.)

von Anfänger (Gast)


Lesenswert?

-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.

von -Gast_XIV (Gast)


Lesenswert?

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.

von -Gast_XIV (Gast)


Lesenswert?

Anfänger schrieb:
> Tests mit µC:

Überlesen (obwohl gleich 2x gepostet), Sorry

Lass dir Zeit (zwischen den Zeichen)

von Anfänger (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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");

von -Gast_XIV (Gast)


Lesenswert?

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

von -Gast_XIV (Gast)


Lesenswert?

Frank M. schrieb:
> Senden ("AT\r");

Das macht das BTM nicht (sicher) mit. Der "Anfänger" hat das Modem auch 
schon sehr systematisch getestet.

von Hartmut (Gast)


Lesenswert?

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

von Anfänger (Gast)


Lesenswert?

-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ß

von Anfänger (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

-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

von -Gast_XIV (Gast)


Lesenswert?

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.

von -Gast_XIV (Gast)


Lesenswert?

-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.

von Anfänger (Gast)


Lesenswert?

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.

von Anfänger (Gast)


Lesenswert?

...achso...den Echo vom BTM (ate) musste ich auch wieder einschalten 
sonst tut sich da gar nichts.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Anfänger schrieb:
> 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');
12
> 
13
>

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

von Bankswitch operator from hell (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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

von Anfänger (Gast)


Lesenswert?

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...

von Marcus O. (marcus6100)


Lesenswert?

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.

von Anfänger (Gast)


Lesenswert?

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.

von Harald (Gast)


Lesenswert?

Ich hab auch schweres Projekt. Könnt Ihr mir auch helfen ? Dann kann ich 
jetzt Feierabend machen...

von Anfänger (Gast)


Lesenswert?

...was gibt es denn ?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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:
1
void
2
KommandoSenden (char * kommando, char * antwort, uint8_t * laenge)
3
{
4
  char buf[2];                    // Leider notwendig wegen schlechtem Interface von Senden()
5
6
  buf[1] = '\0';                  // Buffer hinten terminieren
7
8
  while (*kommando)
9
  {
10
    buf[0] = *kommando++;
11
    Senden (buf);                // Senden hat schlechtes Interface: besser 1-fache Zeichenausgabe!
12
    Empfangen();                 // Echo einlesen
13
  }
14
15
  buf[0] = '\r';
16
  Senden (buf);
17
18
  do
19
  {
20
    Empfangen ();
21
  } while (Empfangsdaten != '\n');  // alles Lesen bis Zeilenende
22
23
  // Jetzt die Antwort lesen:
24
25
  do
26
  {
27
    Empfangen();
28
29
    if (Empfangsdaten != '\n' && Empfangsdaten != '\r' && laenge > 1)
30
    {
31
      *antwort++ = Empfangsdaten;
32
      laenge--;
33
    }
34
  } while (Empfangsdaten != '\n');  // alles Lesen bis Zeilenende
35
36
  *antwort = '\0';                  // terminieren!
37
}

Dann kann man folgendermaßen ein Kommando senden:
1
    char antwort[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....

von Marcus O. (marcus6100)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Frank M. schrieb:
> KommandoSenden (char * kommando, char * antwort, uint8_t * laenge)

Ein Sternchen zuviel, es muss heissen:

KommandoSenden (char * kommando, char * antwort, uint8_t laenge)

von Anfänger (Gast)


Lesenswert?

Ok, ich probier es auch mal mit der letzten Variante.

von Anfänger (Gast)


Lesenswert?

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ß

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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

von Anfänger (Gast)


Lesenswert?

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.

von Anfänger (Gast)


Lesenswert?

Anfänger schrieb:
> Versuche ich auf dem selben Wege in einen anderen Editor den Wert an
> "Senden" zu übergeben, meldet

das bitte ignorieren.

von Anfänger (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Anfänger (Gast)


Lesenswert?

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ß

von Anfänger (Gast)


Lesenswert?

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 ?

von Karl H. (kbuchegg)


Lesenswert?

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.

von Anfänger (Gast)


Lesenswert?

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 ???

von Karl H. (kbuchegg)


Lesenswert?

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.

von Anfänger (Gast)


Lesenswert?

Ok, danke für den Tipp. Ich probier das mal.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Bankswitch operator from hell (Gast)


Lesenswert?

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?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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".

von Bankswitch operator from hell (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Bankswitch operator from hell (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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)

von Anfänger (Gast)


Lesenswert?

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.

von Bankswitch operator from hell (Gast)


Lesenswert?

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 ;-).

von Anfänger (Gast)


Angehängte Dateien:

Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

1
void Init_BTM (void)
2
{
3
  char test = \0x0D;    //Enter (CR) nach ASCII-Tabelle
4
5
  Reset_BTM = 0;    //BTM reseten (low-aktiv)
6
  Warten_ms (100);
7
  Reset_BTM = 1;    //BTM wieder aktivieren
8
  Warten_ms (5000);  //warten bis der BTM bereit ist
9
  Out_3_0 = 1;          //Testzwecke
10
  
11
  Warten_ms (1000);
12
  Senden ("a");
13
  Empfangen();
14
  Senden ("t");
15
  Empfangen();
16
  Senden ("p");
17
  Empfangen();
18
  Senden ("?");
19
  Empfangen();
20
//  Senden (&test);
21
//  Senden ("\r\);
22
  Senden ("\n");
23
  Empfangen();
24
    
25
  Out_3_0 = 0;
26
  Warten_ms (3000);
27
28
  Senden ("Daten: ");
29
  Senden (Empfangsdaten);
30
  Senden ("\n\r");

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?

von Marcus O. (marcus6100)


Lesenswert?

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.

von NochnGast (Gast)


Lesenswert?

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"

von Karl H. (kbuchegg)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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

von Anfänger (Gast)


Lesenswert?

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.

von Bankswitch operator from hell (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Anfänger (Gast)


Lesenswert?

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).

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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
    ; Timeout behandeln
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.

von Bankswitch operator from hell (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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?

von Bankswitch operator from hell (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Weißt du etwas, was wir anderen nicht wissen?

Ja, Spaß muss sein ;-).

von Anfänger (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Anfänger (Gast)


Lesenswert?

Gut....vielen Dank für die Ratschläge, ich werde versuchen so viel wie 
möglich in mein Code zu übernehmen damit das anständig läuft.

Gruss

von Karl H. (kbuchegg)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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´;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.