Forum: Mikrocontroller und Digitale Elektronik Serielles Signal auf LCD (Arduino)


von Robin (Gast)


Lesenswert?

Hallo zusammen,

ich habe mir ein kleines Programm gebastelt mit welchem ich die 
Kommunikation zwischen PC und Arduino auswerten (erstmal nur durch 
blinken der LED) und zusätzlich auf dem LCD ausgeben möchte.

Leider funktioniert das Ganze nicht wie gewünscht. Die LED blinkt zwar 
korrekt allerdings gibt er mehrstellige Zahlen nicht korrekt aus. z.B. 
bei Übertragung von 21 blinkt die LED zweimal und das LCD zeigt die 1 
an...

hier der Code, hoffe mir kann jemand helfen:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int ledPin = 13;



void setup() {

  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);

lcd.begin(16, 2);

  }



void loop() {




  if (Serial.available()) {


   light(Serial.read() - '0');

}


delay(1000);
lcd.clear();

    }


  void light(int n){
  for (int i = 0; i < n; i++) {


    digitalWrite(ledPin, HIGH);
  delay(100);
  digitalWrite(ledPin, LOW);

  lcd.setCursor(1, 1);
  lcd.write(Serial.read());

  delay(1000);
}
}

von Max H. (hartl192)


Lesenswert?

Robin schrieb:
> Leider funktioniert das Ganze nicht wie gewünscht.
Ich gehe jetzt mal davon aus, dass du "21" als String überträgst, dann 
ist das beschriebene verhalten auch nachvollziehbar:

> light(Serial.read() - '0');
Liest den ersten Char ein, in deinem Fall '2', und übergibt dann 2 an 
die light() Funktion.

> lcd.write(Serial.read());
Liest dann den zweiten Char ein, in deinem Fall '1', und gibt ihn auf 
dem LCD aus.


Das ganze könnte man so lösen wenn man ein Trennzeichen, z.B. '\n', am 
Ende der Zahl hinzufügt, ohne wird es schwerig zu erkennen, wenn die 
Zahl vorbei ist.
1
unsigned int rx_num = 0;
2
3
loop()
4
{
5
6
  if (Serial.available())
7
  {
8
    char rx_chr = Serial.read();
9
    if(rx_chr = '\n')
10
    {
11
      light(rx_num);
12
      rx_num = 0;
13
      delay(1000);
14
      lcd.clear();
15
    }
16
    else
17
    {
18
      rx_num *= 10;
19
      rx_num += rx_chr - '0';
20
    }
21
  }
22
23
}
24
25
void light(unsigned int number)
26
{
27
  for (int i = 0; i < number; i++) 
28
  {
29
30
31
    digitalWrite(ledPin, HIGH);
32
    delay(100);
33
    digitalWrite(ledPin, LOW);
34
35
    lcd.setCursor(1, 1);
36
    lcd.writeInt(number); // K.A. wie man in Arduino eine int auf einem LCD ausgibt
37
38
    delay(1000);
39
  }
40
}

PS: Wenn du konsequent einrückst und die C-Code Tags* verwendest, kann 
man deinen Quellcode besser lesen.
1
* [c]C-Code[/c]

von Robin (Gast)


Lesenswert?

Hallo zusammen,

@Max: vielen Dank für deine schnelle Hilfe. Leider bin ich erst heute 
zum testen gekommen und habe gemerkt, dass es leider nicht funktioniert.

Weder die blinkende LED noch die Ausgabe am Bildschirm.

Hat jemand noch eine Idee was ich ändern könnte? Habe jetzt noch einiges 
hin und her probiert aber ohne Erfolg.

Viele Grüße

Robin

von grundschüler (Gast)


Lesenswert?

Robin schrieb:
> allerdings gibt er mehrstellige Zahlen nicht korrekt aus

jede lcd_bibliothek dürfte eine Funktion zur Ausgabe von Integer-Werten 
haben. Nimmdie richtige Funktion, dann klappt das auch. Oder schreib dir 
die Funktion selber: Zahl in Ziffern zerlegen und die Ziffern einzeln 
als ascii-Zeichen darstellen.

von Arduino_LCD (Gast)


Lesenswert?

Vielleicht hilft es, sich zunächst mit der Bibliothek und ihren 
Funktionen bekannt zu machen und nicht einfach irgendwas 
draufloszuschreiben:

http://www.arduino.cc/en/pmwiki.php?n=Reference/LiquidCrystal

PS: Es gibt da auch Code-Beispiele.

von Robin (Gast)


Lesenswert?

Also die reine Ausgabe funktioniert mittlerweile:
1
#include <LiquidCrystal.h>
2
3
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
4
const int ledPin = 13;
5
6
 
7
8
9
void setup() {
10
  // put your setup code here, to run once:
11
12
13
  pinMode(ledPin, OUTPUT);
14
  Serial.begin(9600);
15
  
16
lcd.begin(16, 2);
17
18
19
}
20
21
void loop() {
22
  // put your main code here, to run repeatedly:
23
if (Serial.available()) {
24
    // wait a bit for the entire message to arrive
25
    delay(50);
26
    // clear the screen
27
    lcd.clear();
28
    // read all the available characters
29
    while (Serial.available() > 0) {
30
      // display each character to the LCD
31
      lcd.write(Serial.read());
32
}
33
}
34
}

Auch das blinken alleine funktioniert:
1
#include <LiquidCrystal.h>
2
3
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
4
const int ledPin = 13;
5
6
 
7
8
void setup() {
9
10
  pinMode(ledPin, OUTPUT);
11
  Serial.begin(9600);
12
  
13
lcd.begin(16, 2);
14
15
  }
16
17
 
18
19
void loop() {
20
21
  
22
    
23
    
24
  if (Serial.available()) {
25
  
26
   
27
   light(Serial.read() - '0');
28
 
29
}
30
31
32
delay(1000);
33
//lcd.clear();
34
35
    }
36
  
37
  
38
  void light(int n){
39
  for (int i = 0; i < n; i++) {
40
41
  
42
    digitalWrite(ledPin, HIGH);
43
  delay(100);
44
  digitalWrite(ledPin, LOW);
45
  
46
  lcd.setCursor(1, 1);
47
  
48
  
49
  delay(1000);
50
}
51
}

Allerdings keine Kombination aus beidem (blinken und Ausgabe auf dem 
Display).
Mit lcd.write() gibt er nun auch mehrstellige Zahlen aus

von Cyblord -. (cyblord)


Lesenswert?

Ich liebe dieses völlig wissens- und talentfreie stochern im Nebel der 
Arduino-Freunde.

Versuchst doch wenigstens mal zwischendurch zu verstehen was du da 
machst und warum. Womöglich mit den Nachschlagen in der API Referenz 
oder gar mit einer Quelle über C-Grundlagen. Wie wärs?

von Max H. (hartl192)


Lesenswert?

Robin schrieb:
> dass es leider nicht funktioniert.
Hast du das Trennzeichen '\n' am Ende mitgesendet?

Robin schrieb:
> Allerdings keine Kombination aus beidem
Das liegt daran, dass die Daten weg sind, wenn du sie einmal liest und
nicht speicherst. Versuch mal in deinem ersten Code das zu machen:
1
// Untested
2
if (Serial.available()) 
3
{
4
  // wait a bit for the entire message to arrive
5
  delay(50);
6
  // clear the screen
7
  lcd.clear();
8
  // read all the available characters
9
  
10
  int rx_number = 0;
11
  char rx_char = 0;
12
  while (Serial.available() > 0)
13
  {
14
    // display each character to the LCD
15
    rx_char = Serial.read();
16
    lcd.write(rx_char);
17
    rx_number *= 10;
18
    rx_number += rx_char - '0';
19
  }
20
  light(rx_number);
21
}

von Arduino_LCD (Gast)


Lesenswert?

Zum Nachdenken:

Geh Dein Programm Schritt für Schritt durch. Schreib oder mal Dir auf, 
was sich in jeder Zeile verändert oder sonst passiert. Noch besser, mal 
oder schreib Dir auf, was passieren muß, damit das geschieht, was Du 
willst und vergleiche das dann mit Deinem Programm.

Jeder Aufruf von Serial.read liest ein Byte von der seriellen 
Schnittstelle. Überleg Dir, was passiert, wenn Du Serial.read einmal in 
Deiner Funktion "light" und anschließend nochmals in der Funktion 
lcd.write aufrufst. Hier ist Handlungsbedarf in Deinem Programm.

Du willst also die Bytes einzeln, so wie sie kommen, sofort wieder 
ausgeben, dafür ist lcd.write gut. Wenn Du die einzelnen Zeichen jedoch 
sammeln und gesammelt ausgeben willst, (alias "mehrstellig ausgeben") 
mußt Du lcd.print nehmen. Lies Dir im link zur Referenz durch, wie die 
beiden Funktionen arbeiten und welche Voraussetzungen für ihre Nutzung 
bestehen. Wenn Du Zeichen sammelst, wird die Struktur/Ablauf Deines 
Programmes u. U. jedoch anders sein. Überlege Dir, was Du ändern mußt.

Cyblord, halt Dich bitte raus, Dein Dummgelaber ist null hilfreich.

von Robin (Gast)


Lesenswert?

Vielen, vielen Dank an Max und LCD!

Werde heute Abend wenn ich von der Arbeit zurück bin alles nochmal 
durchgehen und eure Ratschläge umsetzen. Mal sehen was dann rauskommt :)

Viele Grüße und besten Dank

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.