Serielles Signal auf LCD (Arduino)

Gast #4138162
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);
}
}
#4138201
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]
Gast #4141392
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
Gast #4141485
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.
Gast #4141554
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
#4141556
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?
#4141564
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
}
Gast #4141584
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.
Gast #4141656
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren