Forum: Mikrocontroller und Digitale Elektronik Uhrzeit + serielle verbindung + Display = Verwirrung.


von DAVID B. (bastler-david)


Lesenswert?

Hallo
Wie kann ich am besten ein 2 Zeichen int Register seriell weiter leiten?
Ich rufe die Uhrzeit mit dem arduino 2560 + LAN Schild ab.(das geht)
Speicher die Rohdaten, (geht auch)
teile sie in:

---------------------------------
int S = (12);
int M = (59);
--------------------------------
(geht auch)
zb auf und möchte sie über tx weiter senden zum Display mit einem atmega 
48.
Der atmega48 bekommt aber von den zb S = nur noch die letzte zahl mit 
und zeigt diese an.

Wie kann ich int = 12 ohne aufteilen senden ?
Oder wie kann ich die zahlen werte einzeln abfragen ?
Oder geht das einfacher ?

Zurzeit versuche ich die zahlen mit Buchstaben gekennzeichnet zusenden.
Soll heißen ich sende ein A und 50 ms dann zb eine 1 dann sende ich B 
wieder 50ms dann eine 2 dann C3 und D4 so kann ich das auf dem Display 
auch gut zuordnen. 12:34  ( : wird nicht übertragen sondern stelle ich 
selber da.
Wäre ja auch Unsinn das auch noch zu übertragen.
Aber alles was jetzt ankommt ( A = stunden ) (M = Minuten) ist  2: 9
Es fehlen also die ersten Zeichen immer Wie kann ich das lösen?

Vielen lieben dank.

: Bearbeitet durch User
von Thomas E. (thomase)


Lesenswert?

Caste die beiden Werte nach unsigned char und du hast nur noch zwei 
8-Bit Werte. Größer als 59 wird es ja nicht. Da ist int ohnehin die pure 
Verschwendung.

von Loran (Gast)


Lesenswert?

Wer (außer Leuten, die noch Entfernungen in FUSS angeben)
benutzt 12-Stunden-Zeitangaben in der Datenverarbeitung???
Da fehlt doch noch das PM und AM.
Aber 0 Uhr früh ist 12 Uhr spät (PM)... grusel

Scherz beiseite:

Entweder sendest du 12 in einem Byte (0...255) und
dekodierst für die Anzeige daraus den Anzeigecode:
die Zehnerstelle + '0' und die Einerstelle + '0'.

Oder du machst das schon auf der Sendeseite und sendest
nacheinander den Anzeige-Code für '1' und für '2'.

von DAVID B. (bastler-david)


Lesenswert?

Ok vielen dank euch 2.
Ich nehme natürlich 24 stunden zeit.
Wenn ich anstelle int unsigned char nutze wird nur noch müll gesendet.
Oder ich mache es falsch.

Das mit in byte umrechnen habe ich nicht ganz verstanden wie das geht. 
könnstes du das bitte genauer ausführen ?
Mein test sende gebastel ist zurzeit;

int S = (12);
int M = (34);

void loop()
{
  delay(1000);
  Serial.print("A");
  delay(70);
  Serial.print(S);
  delay(1000);
  Serial.print("B");
  delay(70);
  Serial.print(M);
}

Und der Empfänger schnipsel ist :

char i; // (1)

void loop() {
  if (Serial.available())
  { i = Serial.read();
  }

  lcd.setCursor(0, 0);
  lcd.print(F("Zeit"));

  if (i == 'A')
  {
    delay(100);
    i = Serial.read();
    lcd.setCursor(6, 0);
    lcd.print(i);
  }

  lcd.setCursor(8, 0);
  lcd.print(":");

  if (i == 'B')
  {
    delay(100);
    i = Serial.read();
    lcd.setCursor(10, 0);
    lcd.print(i);
  }
}


Was platz angeht da ich habe ich noch Reserven da stört das nicht so.
Mir gehts nicht um so platzsparend wie möglich,
sondern um Einfachheit und zum am besten lernen ist mir lieber.

: Bearbeitet durch User
von Oppa (Gast)


Lesenswert?

Ja ne is klar..
Ein Arduino Mann kann nur so verwirrt sein???

von Peter D. (peda)


Lesenswert?

Vermutlich erwartet lcd.print einen String (Pointer auf Text), d.h. Du 
mußt eine Zahl erstmal in einen String umwandeln, z.B. mit itoa oder 
sprintf.

von Horst (Gast)


Lesenswert?

DAVID -. schrieb:
> delay(1000);

Ist sowas immernoch nicht verboten?

von Dennis R. (Gast)


Lesenswert?

die print Funktion erwartet einen Zeiger auf eine null terminierte 
Zeichenkette.
Du musst das selber zusammenbauen.

ich empfehle dir ein char [] und sprintf

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

DAVID -. schrieb:
> Wie kann ich am besten ein 2 Zeichen int Register seriell weiter leiten?
Am besten in lesbarem ASCII. Abgeschlossen mit CR und LF. Denn dann 
kannst du mit jedem beliebigen Terminal sehen, was da gerade läuft.

Horst schrieb:
>> delay(1000);
> Ist sowas immernoch nicht verboten?
Nein. Aber es ist immer noch ein Programmierfehler. Oder deutet auf 
einen hin.

von W.S. (Gast)


Lesenswert?

Lothar M. schrieb:
> Aber es ist immer noch ein Programmierfehler

per se nicht wirklich, aber - um mal nen Vergleich zu ziehen - wird von 
jedem, der sich hinters Steuer setzt, verlangt, daß er die Fahrschule 
erfolgreich abgeschlossen hat. Wenn ich diesen Thread und einige andere 
Threads hier lese, dann kommt in mir der Wunsch auf, auch in der 
Elektronik etwas Vergleichbares haben zu wollen.

Kurzum, bei dieser Schere zwischen Kenntnisstand und Vorhaben weiß ich 
nicht, wie man da helfen könnte. Stichworte: serielle E/A-Treiber und 
Pufferung, Kommandosystem, Systemuhr, Ein- und Ausgabekonverter, 
Protokolle zum Synchronisieren zweier unabhängiger Systeme.

Ob die Maker-Szene aud lange Sicht etwas Gutes ist, oder eher das 
Gegenteil, wäre noch zu diskutieren. Denn wer sich dran gewöhnt hat, 
irgendwas eben MACHEN zu wollen (und dank der Vorarbeit anderer auch tun 
zu können), ohne sich um das eigene Verstehen dessen, was er da 
anrichten will, kümmern zu wollen, wird irgendwann mal glauben, ein 
vorzüglicher Entwickler zu sein und zugleich den eigenen Anspruch auf 
die Zu- und Vorarbeit durch Andere als etwas Selbstverständliches zu 
erachten. Aber ich würde sowas nicht als MACHER bezeichnen, sondern eher 
als BENUTZER.

W.S.

von Loran (Gast)


Lesenswert?

Ich würde gern helfen, aber deine (vielleicht durch die
neue Grundschulpädagogik hervorgerufene) Schreibweise,
bei der man sich geschriebene Buchstabenfolgen mit, oder
auch ohne Leerzeichen dazwischen, zu Worten und Sätzen
zusammensetzen muss, erschwert das gewaltig!

Probieren wir es also beim Programm-Code:

01 void loop() {
02   if (Serial.available())
03  { i = Serial.read();
04  }
05
06   lcd.setCursor(0, 0);
07   lcd.print(F("Zeit"));
08
09   if (i == 'A')
10   {
11     delay(100);
12     i = Serial.read();
13     lcd.setCursor(6, 0);
14     lcd.print(i);
15   }
16
...

01:
02: wenn ein Zeichen empfangen wurde
03: i = empfangenes Zeichen
04:
05:
06: Setze LCD-Cursor auf Anfangsposition
07: Schreibe "Zeit" in's LCD
08:
09: wenn 'A' empfangen wurde:
10:
11: warte 100 ms (?)
12: i = nächstes empfangenes Zeichen
13: Setze LCD-Cursor auf Anfangsposition + 6
14: Schreibe den Wert von i in's LCD
15:

- - - - - - - - - - - - - - - - - - - - - - - - - - - -

So ein Standard LCD schreibt aber die Zeichen, die
in seiner Code-Tabelle hinterlegt sind, in's Display.

07   lcd.print(F("Zeit")); könnte klappen (ich kenne den
Parameter F nicht), weil "Zeit" die Abfolge von ASCII-Codes
für die Buchstaben Z, e, i und t ist.

14     lcd.print(i); klappt aber nicht, weil z.B. für die
Zahl 1 nicht der Code zur Anzeige von '1' hinterlegt ist.
0...7 sind meist für selbst zu programmierende Sonderzeichen
freigehalten.

Wenn du weißt, dass Ziffern kommen, musst du lcd.print(i+'0')
in's Programm schreiben, damit der ASCII-Code für 0...9
zum Display übermittelt wird.

Schon kannst du dir den ganzen A-B-C-D-Quatsch sparen.

von DAVID B. (bastler-david)


Lesenswert?

Ich danke euch allen sehr fürs lesen ihr habt auch viele gute Tipps 
gegeben.
Jetzt liegt es nur noch an mir die auch zu verstehen.
Ich brauche da immer sehr viel zeit (schäm).
Ein delay habe ich vorgesehen damit der Empfänger eine gewisse ruhe zeit 
hat in der er die Daten speicher und verarbeiten kann. Ich bin auf 3 
Leitungen festgesetzt +5volt,gnd,RX und kann nicht abfragen ob alles 
fertig verarbeitet ist.
Sicher gibt es bessere Wege.

Der befehl (F) hat nur zusagen das es nicht im RAM gelegt wird sondern 
im Programmspeicher (mehr freier RAM)

Auch ist es richtig das ich aus arbeiten anderer Lerne aber machen wir 
das nicht alle ? ein Lehrer muss auch erst was Lernen bevor er es weiter 
geben kann.
Ich würde auch nie mals von mir behaupten das ich alles kann oder alles 
weiß.
um Himmels willen ich kann nur das was ich selber WEIß und KANN wenn man 
teile anderer verwendet ist das natürlich KEIN können.
Ich will es für MICH lernen und wenn ich beispiele oder fertige Ansätze 
sehe kann ich mir das eher vorstellen.
Heist aber nicht das ich alles einbaue und weiter mache.

ich habe eure Tipps mal versucht umzusetzen mit mäßigen erfolgt( sicher 
mein Fehler)
Wo mit ich am besten gekommen bin ist mit einen char String da kann ich 
ganze Sätze ans Display senden welche ich auch angezeigt bekomme.
Das Problem da ist aber wie bei in den String eine 2 Zeichen ZAHL 
bekomme (also eine zahl ÜBER 9) Eine zahl geht gut bei 2 zeichnen wird 
nur das letzte Zeichen gespeichert / gesendet.
Dazu Kahm mir folgende Idee.
wenn ich die zahl die als int gespeichert wird auslese und durch 10 
teile würde ich beide zahlen erhalten nur wie kann ich die zahl vor und 
nach dem Koma einzeln speichern?

von Loran (Gast)


Lesenswert?

Variable: Typ = BYTE = uint8 = ... also Wert = 0...255

Bei Stunden und Minuten ist der Wert < 60, also zweistellig.

Dann sende mal den Zahlenwert   S = 0...23 (Stunden)
und anschließend den Zahlenwert M = 0...59 (Minuten)

Probier mal:

while ( ! Serial.available() )
{
}

Variable = Serial.read();
lcd.print((Variable/10 + '0');
lcd.print((Variable%10 + '0');
lcd.print(':');

while ( ! Serial.available() )
{
}

Variable = Serial.read();
lcd.print((Variable/10 + '0');
lcd.print((Variable%10 + '0');


Sollte erst mal ohne den A-B-C-D-Kram gehen.

Aber das Warten mit while() ist doof - und das Warten mit
delay(1000) noch dämlicher, wenn der µC noch was anderes
machen soll.

Wenn das erst mal funktioniert, dann schau mal nach
Interrupts...

von DAVID B. (bastler-david)


Lesenswert?

VIELEN dank für deine mühe auch noch um die zeit!
also ich sende S und 1 sek später M werden auch zusammen gesendet sehe 
ich ja am PC.(S = 12 und M= 34)
Das Display allerdings zeigt nur zahlen müll an.
Glaube liegt an der mal und durch 10 Rechnung.

Du meinst das doch genau so oder ?

#include "LiquidCrystal.h"
LiquidCrystal lcd(10, 9, 8, 7, 6, 5);
byte Variable;

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
}

void loop()
{

  while ( ! Serial.available() )
  {
  }
  Variable = Serial.read();
  lcd.print((Variable / 10 + '0'));
  lcd.print((Variable % 10 + '0'));
  lcd.print(F(':'));
  while ( ! Serial.available() )
  {
  }

  Variable = Serial.read();
  lcd.print((Variable / 10 + '0'));
  lcd.print((Variable % 10 + '0'));

}

Der Chip hat nur die Aufgabe die seriellen Daten auf dem Display 
anzuzeigen.(Uhrzeit und paar andere Sachen)

von Loran (Gast)


Lesenswert?

Anstatt dich dauernd zu entschuldigen, wäre es hilfreicher,
zu wissen, was du nun sendest!

Wie sendest du? RS232, oder TTL?

Was sendest du an den PC? (Wahrscheinlich mit RS232.)
Mit welchem Programm schaust du es dir an?
Mit einem Terminalprogramm kann man ein BYTE mit dem
Wert von 0...59 nicht als 0...59 lesen.

Was sendest du an den Arduino?
Hat der für serielle Verbindungen einen TTL-, oder
einen RS232 Anschluss?

Sendest du noch die A, B, ..., sind die auf dem LCD zu sehen?

von DAVID B. (bastler-david)


Lesenswert?

Ok war sehr undeutlich t...
Ich habe zum testen ein arduino nano bord mit einen 328 welches mit TTL 
über USB zur arduino Software sendet.

ich habe mir von nano den TX Pin zu atmega48 (mit Display) gelegt soll 
heißen ich sehe am PC genau was der atmega am RX Pin bekommt.

Ich versuche erst mal nur S (stunden) zusenden ohne irgendein 
Vorzeichen. also 2 zahlen.

Ich habe auch versucht mit dem:
void loop() {

  if (Serial.available()) {

    delay(100);
     lcd.clear();

    while (Serial.available() > 0) {

      lcd.write(Serial.read());
    }
  }
}

Mir alles anzeigen zulassen was am RX ankommt und es geht auch wenn ich 
ein String mit je einen Buchstaben sende kommen auch alle an und bilden 
ein Wort nur mit 2er zahlen (12) geht das nicht mehr auch nicht mit 
doppelbuchstaben (zb AA)

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

Diese '12' ist Das eine 0x0B oder eine 0x31 0x32-Folge?

Was passiert, wenn Du den Sender 'Hello world' senden lässt?
Wäre zumindest naheliegend, erst Mal was Einfaches zur Anzeige zu 
bringen, bevor man berechnete Werte zum Display schickt.

Kann es sein, daß jedes 2.te Zeichen als Befehl ans Display gesendet 
wird und deshalb nicht angezeigt wird?

MfG

PS: AA ist auch nicht sonderlich eindeutig :/

: Bearbeitet durch User
von DAVID B. (bastler-david)


Lesenswert?

ist die 12 nicht 0x0c ?
Wenn ich das so sende:

char text[16] = { 'E','i','n',' ','l','a','n','g','e','r',' 
','T','e','x','t','\0' };
int i = 1

Kommt das am Display auch genau so an.

Nur doppelt geht hier nicht also zb

char text[16] = { 'EE','ii','nn',' ','l','a','n','g','e','r',' 
','T','e','x','t','\0' };
int i = 12

Da wird nur ein Zeichen gesendet.

: Bearbeitet durch User
von DAVID B. (bastler-david)


Lesenswert?

Ich bedanke mich bei allen die mir geholfen haben.
Habe die Lösung selber finden können (eher durch Zufall)

Ein int senden ist in der Verbindung nicht machbar ABER wenn ich char 
anstelle von int nutze und bei der Display Ausgabe DEC setzte bekomme 
ich das was ich will.

Damit andere Auch was davon haben:

Sender;

int Stunden = 12;
int Minuten = 59;

char S ;
char M ;
void setup()
{
  Serial.begin(9600);
}

void loop()
{
 S = (char) Stunden; // Umlagern int zu char
 M = (char) Minuten; // Umlagern int zu char
  delay(1000);
  Serial.print("A");
  delay(70);
  Serial.print(S);
  delay(1000);
  Serial.print("B");
  delay(70);
  Serial.print(M);
}

Gegenstelle: atmega48 8MHz

#include "LiquidCrystal.h"
LiquidCrystal lcd(10, 9, 8, 7, 6, 5); //ok lcd
char i; // (1)

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.clear();
}

void loop() {
  if (Serial.available())
  { i = Serial.read();
  }

  lcd.setCursor(0, 0);
  lcd.print(F("Zeit"));

  if (i == 'A')
  {
    delay(100);
    i = Serial.read();
    lcd.setCursor(5, 0);
    lcd.print(F("  "));
    lcd.setCursor(5, 0);
    lcd.print(i, DEC);
  }

  lcd.setCursor(7, 0);
  lcd.print(":");

  if (i == 'B')
  {
    delay(100);
    i = Serial.read();
    lcd.setCursor(8, 0);
    lcd.print(F("  "));
    lcd.setCursor(8, 0);
    lcd.print(i, DEC);
  }
}
LOT ist an und das ergibt beim atmega48
3092 Bytes (75%) des Programmspeicherplatzes von 4096 Bytes.
127 Bytes(24%) des dynamischen Speichers von 512 Bytes.

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.