Forum: Mikrocontroller und Digitale Elektronik C String an Terminal ausgeben


von Da H. (darko91)


Lesenswert?

Hallo Zusammen,

...BITTE NICHT ABSCHRECKEN VON DER LÄNGE DES BEITRAGS...

Bitte um eure Hilfe zu folgendem Punkt, da ich schon fast am Verzweifeln 
bin:

Ich schreibe manuell einen String, wie unten "Hallo Welt", in die 
Variable c rein. Diese wird in diesem Fall auch richtig im Terminal 
(TeraTerm) ausgegeben.
1
char c[] = {"Hallo Welt "};
2
3
while(1)
4
{
5
  int i;
6
  for(i = 0; i <= sizeof(c); i++)
7
  {
8
    UDR0 = c[i]; _delay_ms(200);
9
  }
10
}

Nun will ich das Ganze über Bluetooth steuern. LEDs zum leuchten bringen 
funktioniert mal einwandfrei, einen von einem Smartphone gesendeten 
String im Terminal auszugeben bereitet mir aber schon Kopfschmerzen.

Angefangen von einfachen Characters:
Wenn ich diese 1:1 ans Terminal weitergebe, kommen irgendwelche Symbole 
raus. Ich habe mit Hilfe der Ascii Tabelle die Zahlen um 128 Stellen 
nach hinten verschoben.
Nun werden mir zwar Zahlen von 1-9 sowie manche Sonderzeichen richtig 
angezeigt (Ascii Tabelle, Nr. 34 (") bis inkl. 63 (?)), jedoch kommen 
die Buchstaben falsch raus (z.B. Statt "a" kommt ein "!" raus oder statt 
"z" ein ":" - also 64 Stellen nach hinten verschoben).
1
if(blueToothSerial.available()){
2
    int i;
3
    for(i = 0; i <= sizeof(c); i++)
4
    {
5
        c[i] = blueToothSerial.read()-128;  // um 128 Stellen nach hinten verschieben
6
    }
7
          
8
    UDR0 = c[i]; _delay_ms(200);
9
}
Wenn ich noch eine if-Bedingung rein haue, ist nur jede 2. Eingabe 
richtig (sowohl Ziffer, als auch Buchstabe). Woran könnte das liegen? 
Logischer Denkfehler?
1
if(blueToothSerial.available()){
2
   int i;
3
   for(i = 0; i <= sizeof(c); i++)
4
   {
5
  
6
        if(c[i] >= '@' && c[i] <= 'z')              // lt. Ascii Tabelle alles zw. "@" und "z"
7
           c[i] = blueToothSerial.read()-64;   // um 64 Stellen nach hinten verschieben
8
        else
9
           c[i] = blueToothSerial.read()-128;  // um 128 Stellen nach hinten verschieben
10
        }
11
          
12
        UDR0 = c[i]; _delay_ms(200);
13
}

Wie gebe ich danach einen String aus zB 10 Characters richtig ans 
Terminal?

btw: Die Implementierung vom Bluetooth Modul füge ich hier nicht hinzu, 
der Code wäre viel zu lang. Falls es jedoch nötig ist, bitte Bescheid 
geben.

von TestX (Gast)


Lesenswert?

Sizeof ist die falsche funktion. Was du willst heißt strlen ....

von Uwe (de0508)


Lesenswert?

Hallo,

wer kommt den auf diese Idee?
1
UDR0 = c[i]; _delay_ms(200);
Das geht doch gegen alle Regeln der Programmierkunst!

Ich verwende je eine Interrupt gesteuerte Sende- und Empfangsroutine mit 
FiFos.

von Walter S. (avatar)


Lesenswert?

TestX schrieb:
> Sizeof ist die falsche funktion. Was du willst heißt strlen ....

und strlen hilft da leider auch nix

von Da H. (darko91)


Lesenswert?

Uwe S. schrieb:
> Hallo,
>
> wer kommt den auf diese Idee?
>
1
UDR0 = c[i]; _delay_ms(200);
> Das geht doch gegen alle Regeln der Programmierkunst!
>
> Ich verwende je eine Interrupt gesteuerte Sende- und Empfangsroutine mit
> FiFos.

Kannst du mir ein Beispiel in C-Code zeigen?

von STK500-Besitzer (Gast)


Lesenswert?

Darko Jen schrieb:
> Kannst du mir ein Beispiel in C-Code zeigen?

Du programmierst ja offensichtlich mit Arduino.
Guck dir einfach mal die Serial-Bespiele an!

von Falk B. (falk)


Lesenswert?

@Darko Jen (darko91)

>> Ich verwende je eine Interrupt gesteuerte Sende- und Empfangsroutine mit
>> FiFos.

>Kannst du mir ein Beispiel in C-Code zeigen?

Ist für dich im Moment viel zu kompliziert, du musst erst mal die 
Grundlagen lernen. Man kann einen UART problemlos ohne Interrupts 
betreiben, aber ganz sicher NICHT mit DERARTIGEN Wartezeiten!

Ausserdem solltes du dir mal ansehen, wie Strings normalerweise 
verarbeitet werden.

https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART

von Da H. (darko91)


Lesenswert?

Falk Brunner schrieb:
> @Darko Jen (darko91)
>
>>> Ich verwende je eine Interrupt gesteuerte Sende- und Empfangsroutine mit
>>> FiFos.
>
>>Kannst du mir ein Beispiel in C-Code zeigen?
>
> Ist für dich im Moment viel zu kompliziert, du musst erst mal die
> Grundlagen lernen. Man kann einen UART problemlos ohne Interrupts
> betreiben, aber ganz sicher NICHT mit DERARTIGEN Wartezeiten!
>
> Ausserdem solltes du dir mal ansehen, wie Strings normalerweise
> verarbeitet werden.
>
> https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART

Danke Falk für die Hilfe. Ich werde mir das noch in Ruhe durchlesen, hab 
es ehrlich gesagt bisher nur überflogen.
Es handelt sich hierbei nämlich um eine Abgabe, die sehr dringend ist 
und mir der Kopf wegen verschiedensten Sachen schon raucht. Ich wäre 
sehr dankbar, wenn mir jemand mit dem Code weiterhilft - ich werde es 
mir im Anschluss, wenn ich mehr Zeit habe, bestimmt detailliert ansehen. 
Wegen Zeitdrucks schaffe ich es zur Zeit leider nicht.

Vielen Dank!
D.

von Falk B. (falk)


Lesenswert?

@ Darko Jen (darko91)

>mir im Anschluss, wenn ich mehr Zeit habe, bestimmt detailliert ansehen.

Naja, wer's glaubt wird seelig.

Wenn du Hilfe willst, musst du schon ein wenig die Netiquette 
beachten und ein paar wichtige Informationen rüber wachsen lassen.

Welcher Controller? (AVR?)
Welche Umgebung (Arduino?)
Welcher Hardwareaufbau?
WAS soll denn KONKRET gemacht werden?

>Nun will ich das Ganze über Bluetooth steuern. LEDs zum leuchten bringen
>funktioniert mal einwandfrei, einen von einem Smartphone gesendeten
>String im Terminal auszugeben bereitet mir aber schon Kopfschmerzen.

???
Deine Hardware hat einen Bluetooth Empfänger UND eine Terminalanbindung 
per Kabel?

>raus. Ich habe mit Hilfe der Ascii Tabelle die Zahlen um 128 Stellen
>nach hinten verschoben.

Dazu braucht man keine ASCII-Tabelle. Ausserdem ist alles >127 KEIN 
ASCII mehr.

>Nun werden mir zwar Zahlen von 1-9 sowie manche Sonderzeichen richtig
>angezeigt (Ascii Tabelle, Nr. 34 (") bis inkl. 63 (?)), jedoch kommen
>die Buchstaben falsch raus (z.B. Statt "a" kommt ein "!" raus oder statt
>"z" ein ":" - also 64 Stellen nach hinten verschoben).

>    UDR0 = c[i]; _delay_ms(200);

Lass den Käse und verwende die ganz normalen Arduino Sendefunktionen! 
Denn sonst spuckt du denen dazwischen, das mögen die nicht wirklich!

1
  char c;
2
3
  c = blueToothSerial.read();
4
  serial.print(c);

reicht vollkommen, um ein Zeichen auszugeben.

Einen STRING c zu nennen ist recht ungünstig, c kling wie char und das 
ist ein EINZELNES Zeichen.

>Logischer Denkfehler?

Mangelnde Grundlagen.

>Wie gebe ich danach einen String aus zB 10 Characters richtig ans
>Terminal?

char string[]="Ich bin ein echt toller String";
serial.print(string);

http://www.arduino.cc/en/Serial/Print

>btw: Die Implementierung vom Bluetooth Modul füge ich hier nicht hinzu,
>der Code wäre viel zu lang. Falls es jedoch nötig ist, bitte Bescheid
>geben.

Es reicht, den Namen des Shields zu nennen und ggf. einen Link auf eine 
Seite, wo der beschrieben ist. Siehe Netiquette.

von Da H. (darko91)


Lesenswert?

Falk Brunner schrieb:
> @ Darko Jen (darko91)
>
>>mir im Anschluss, wenn ich mehr Zeit habe, bestimmt detailliert ansehen.
>
> Naja, wer's glaubt wird seelig.

Mein Ziel ist es natürlich, zumindest die Grundlagen in C zu 
beherrschen. Durch mehr Hilfe lerne ich mehr dazu

> Wenn du Hilfe willst, musst du schon ein wenig die Netiquette
> beachten und ein paar wichtige Informationen rüber wachsen lassen.
>
> Welcher Controller? (AVR?)
ATMEGA328P
> Welche Umgebung (Arduino?)
Nein, in Atmel Studio direkt (gcc), es wird jedoch ein Arduino Board 
verwendet
> Welcher Hardwareaufbau?
Arduino Uno R3 Board
+ Bluetooth Modul von Seeedstudio (es gibt eh nur 1, die Implementierung 
habe ich von ihrer HP 
(http://www.seeedstudio.com/wiki/index.php?title=Bluetooth_Shield) 
übernommen und umgeändert, sodass Atmel es auch versteht. Habe bereits 
erste Ergebnisse erzielt, z.B. die Ansteuerung von LEDs per Bluetooth.
Die 3. Hardware ist ein LCD Display - auch hier erhielt ich bereits 
erste Ergebnisse.

> WAS soll denn KONKRET gemacht werden?

Es soll ein über Bluetooth gesendeter String von einem Smartphone am LCD 
Display (DOGM162L-a) zu sehen sein

>>Nun will ich das Ganze über Bluetooth steuern. LEDs zum leuchten bringen
>>funktioniert mal einwandfrei, einen von einem Smartphone gesendeten
>>String im Terminal auszugeben bereitet mir aber schon Kopfschmerzen.
>
> ???
> Deine Hardware hat einen Bluetooth Empfänger UND eine Terminalanbindung
> per Kabel?
Bluetooth Shield, Das Terminal dient als Zusatz, damit ich nicht unnötig 
das LCD Display belaste.

>>raus. Ich habe mit Hilfe der Ascii Tabelle die Zahlen um 128 Stellen
>>nach hinten verschoben.
>
> Dazu braucht man keine ASCII-Tabelle. Ausserdem ist alles >127 KEIN
> ASCII mehr.
>
>>Nun werden mir zwar Zahlen von 1-9 sowie manche Sonderzeichen richtig
>>angezeigt (Ascii Tabelle, Nr. 34 (") bis inkl. 63 (?)), jedoch kommen
>>die Buchstaben falsch raus (z.B. Statt "a" kommt ein "!" raus oder statt
>>"z" ein ":" - also 64 Stellen nach hinten verschoben).
>
>>    UDR0 = c[i]; _delay_ms(200);
>
> Lass den Käse und verwende die ganz normalen Arduino Sendefunktionen!
> Denn sonst spuckt du denen dazwischen, das mögen die nicht wirklich!

Würde ich gerne, die Aufgabe ist aber leider Gottes, dies ohne den 
Arduino Befehlen zu schaffen.
>
>
>
1
>   char c;
2
> 
3
>   c = blueToothSerial.read();
4
>   serial.print(c);
5
>
>
> reicht vollkommen, um ein Zeichen auszugeben.
>
> Einen STRING c zu nennen ist recht ungünstig, c kling wie char und das
> ist ein EINZELNES Zeichen.
Ich taufe es gerne um :) , ich brauche nur einen richtigen Weg, den 
String eben auszugeben
>
>>Logischer Denkfehler?
>
> Mangelnde Grundlagen.
>
>>Wie gebe ich danach einen String aus zB 10 Characters richtig ans
>>Terminal?
>
> char string[]="Ich bin ein echt toller String";
> serial.print(string);

Das klappt natürlich, ich will den per Bluetooth empfangenen String in 
eine Variable abspeichern und dann erneut ausgeben
>
> http://www.arduino.cc/en/Serial/Print
>
>>btw: Die Implementierung vom Bluetooth Modul füge ich hier nicht hinzu,
>>der Code wäre viel zu lang. Falls es jedoch nötig ist, bitte Bescheid
>>geben.
>
> Es reicht, den Namen des Shields zu nennen und ggf. einen Link auf eine
> Seite, wo der beschrieben ist. Siehe Netiquette.

von Falk B. (falk)


Lesenswert?

@Darko Jen (darko91)

>Bluetooth Shield, Das Terminal dient als Zusatz, damit ich nicht unnötig
>das LCD Display belaste.

Denkst du, dass es dadurch verschleißt? ;-)

>Würde ich gerne, die Aufgabe ist aber leider Gottes, dies ohne den
>Arduino Befehlen zu schaffen.

Dann musst du es so wie im Tutorial machen.

>Ich taufe es gerne um :) , ich brauche nur einen richtigen Weg, den
>String eben auszugeben

Siehe oben. Einfacher geht es nicht.

>Das klappt natürlich, ich will den per Bluetooth empfangenen String in
>eine Variable abspeichern und dann erneut ausgeben

Sollte ja nicht soo schwer sein.
Welche Funktionen bietet deine Bluetooth-Lib?

Das Grundprinzip ist einfach.

Man prüft, ob Daten vom Bluetooth verfügbar sind
Wenn ja, holt man eins ab.
Ist es ein normales Zeichen, speichert man es im String, dazu muss man 
sich die aktuelle Speicherposition merken.
Ist es das Zeichen \r, ist der String zu Ende, es wird nicht \r 
gespeichgert sondern 0 (Stringterminator).
Dann kann man den String normal ausgeben.

von D. (Gast)


Lesenswert?

> Das Grundprinzip ist einfach.
>
> Man prüft, ob Daten vom Bluetooth verfügbar sind
> Wenn ja, holt man eins ab.
> Ist es ein normales Zeichen, speichert man es im String, dazu muss man
> sich die aktuelle Speicherposition merken.
> Ist es das Zeichen \r, ist der String zu Ende, es wird nicht \r
> gespeichgert sondern 0 (Stringterminator).
> Dann kann man den String normal ausgeben.

Danke für die Info.

kannst du mir noch mitteilen, wie vom empfangenen String aus 
bluetoothSerial.read() einzelne characters bekomme? Ich kriege ja per 
Bluetooth einen ganzen String, der in bluetoothSerial.read() 
eingespeichert wird.
Danke

von Falk B. (falk)


Lesenswert?

@ D. (Gast)

>kannst du mir noch mitteilen, wie vom empfangenen String aus
>bluetoothSerial.read() einzelne characters bekomme?

RTFM?

http://www.arduino.cc/en/Serial/Read

Dein bluetoothSerial.read() ist nur ein anderer Name für serial.read()

>Ich kriege ja per
>Bluetooth einen ganzen String, der in bluetoothSerial.read()
>eingespeichert wird.

Nein, die Funktion liefert exakt ein Zeichen pro Aufruf.

von D. (Gast)


Lesenswert?

http://www.arduino.cc/en/Serial/Read
>
> Dein bluetoothSerial.read() ist nur ein anderer Name für serial.read()
>
> Ich kriege ja per >Bluetooth einen ganzen String, der in
> bluetoothSerial.read() >eingespeichert wird.
>
> Nein, die Funktion liefert exakt ein Zeichen pro Aufruf.
Sorry. Wie kann ich durch die Funktion jedes Zeichen nach der Reihe 
lesen?

von Falk B. (falk)


Lesenswert?

@ D. (Gast)

>> Nein, die Funktion liefert exakt ein Zeichen pro Aufruf.
>Sorry. Wie kann ich durch die Funktion jedes Zeichen nach der Reihe
>lesen?

Hast du das nicht schon ansatzweise programmiert?
Oder nur kopiert, ohne es zu verstehen?

1
if(blueToothSerial.available()){
2
    int i;
3
    for(i = 0; i <= sizeof(c); i++)
4
    {
5
        c[i] = blueToothSerial.read()-128;  // um 128 Stellen nach hinten verschieben
6
    }
7
          
8
    UDR0 = c[i]; _delay_ms(200);
9
}

Da ist zwar noch viel falsch, aber das Grundgerüst stimmt.

if(blueToothSerial.available()){

Sind Daten im Puffer verfügbar?

Wenn ja, dann

c = blueToothSerial.read();

usw.

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.