Serial->Eeprom->7Segment (Ein letzter Versuch)

Nach wie vor habe ich Probleme damit, einen Text über die serielle Schnittstelle ins interne EEprom (ATMega328p) zu schreiben, und im Anschluss als Zeichenfolge auf einer (1!) 7-Segment Anzeige darzustellen. Die Bibliothek für die 7-Segment Anzeige heißt "SMH_7SD" und ist hier zu finden. Der display.print Befehl erwartet einen char.
Mögliche Texte die angezeigt werden "Code 2764".

#include <EEPROM.h>
#include <SMH_7SD.h>



int d;
char i;




//Create the object that control the display
SMH_7SD display((int[]){7,9,8,6,4,5,3,10},SMH_7SD_COMMON_ANODE);

void setup(){ 
  Serial.begin(9600);

  
}

void loop(){

  
                                                                               
  delay (100);

  if ( Serial.available() != 0 ) {
    delay(50); // waiting for the end of data reception

    // write to eeprom
    i= 0; while(i < 20) { 
      d= Serial.read();
      //if (d == -1) d= ' '; // if characters are out, fill in with spaces 
      EEPROM.write(i, (byte)d); // write to eeprom
      i++;
    } 
  }



 
 
  
  for (int l=0; l<2; l++){             
    i= 0; while(i < 20) { 
    display.print((char*)EEPROM.read(i));
    i++; 
  //display.print(d);
  delay(2000);
  }
}

Wenn ich jetzt anstatt "display.print((char*)EEPROM.read(i));" "Serial.println((char*)EEPROM.read(i));" einsetze um auszulesen welche Zeichen ich bekomme, erscheint sowas....:

'a⸮⸮⸮
b⸮⸮⸮'a⸮⸮⸮
b'a

Und auf der 7 Segment Anzeige erscheint das Symbol für ein unbekanntes Zeichen (laut SMH_7SD Bibliothek.

Ändere ich den Text, ändert sich auch der Inhalt im Eeprom. Scheinbar ist bloß irgendwo ein "Formatierungsfehler"?

Über Hilfe bin ich Dankbar.

PS: Lieber Uwefed, ich hoffe, dieses mal alles beachtet zu haben.

Wenn ich jetzt anstatt "display.print((char*)EEPROM.read(i));" "Serial.println((char*)EEPROM.read(i));" einsetze um auszulesen welche Zeichen ich bekomme, erscheint sowas....:

Was tust du da?
Für mich sieht das voll irre aus!

Also anders rum:
Was willst du erreichen?

Also anders rum:
Was willst du erreichen?

Ich möchte den Text aus dem Eeprom auslesen und auf der 7-Segment-Anzeige als Zeichenfolge darstellen.

RaffaySH:
Ich möchte den Text aus dem Eeprom auslesen und auf der 7-Segment-Anzeige als Zeichenfolge darstellen.

Verstehe ich!

"Dann musst du das auch tun!"
Ist dir vermutlich nicht recht, oder?

OK, ok...
Bevor man liest, muss man auch "richtig schreiben"!

Das ist vielleicht sogar noch wichtiger.
Denn wer Mist schreibt, liest auch Mist.

Also, eine Reihe von Buchstaben schreiben.
Mit einer Null abschließen.

Ebenso beim lesen:
Einen Buffer bereit stellen. (groß genug sollte er sein)
Aus dem EEPROM die Zeichenkette in den Buffer schreiben.
Mit einer Null abschließen.

Dann dem Print übergeben.

Der display.print Befehl erwartet einen char.

Falsch. Das ist kein Befehl, sondern eine Methode. Und die erwartet einen char*. Das heißt einen C-String. Also ein Null-terminiertest Array aus char. Array Variablen zerfallen bei der Übergabe zu Zeigern auf das erste Element. Deshalb ist der Parameter ein Zeiger auf char

Wenn du irgendetwas naiv auf char* castest ohne zu verstehen was tu tust, dann schluckt das der Compiler. Du brauchst dich aber nicht zu wundern wenn da Müll angezeigt wird

Vielen Dank für die Antworten.
Das klingt auch plausibel. Ich kann mich aber noch soviel in das Thema reinlesen. Es bleibt nichts hängen. Ehrlich gesagt "lebe" ich nur von Beispielen die ich im Netz finde.

Mein Traum, einen überarbeiteten Sketch hier vorzufinden, ist leider nicht wahr geworden.

Hi

Mein Traum ist, nie mehr arbeiten gehen zu müssen ... aber auch Das würde wohl recht schnell langweilig werden.
Wenn Du auf C&P stehst, bist Du hier wohl eh falsch - ein klein Wenig Eigeninitiative sollte schon erkennbar sein.

Bisher (meines Wissen) hier veröffentliche 'fertige' Sketche, weil Es eben driiiiiiingend war: 1
Bin aber auch erst ein paar Jahre hier dabei, könnten also doch mehr sein.
Von dem Protagonisten wurde, ebenfalls wieder meines Wissen, nie wieder was gehört - was wohl auch die rasant steigende Anzahl erklärt: Darauf hat Keiner Lust.

Wenn aus Deinem EEprom nur Das raus kommt, was Du rein packst und Das eben nciht passt, wird die Fehlerquelle VOR dem Monitor sitzen.

Vll. Mal einen Kopf machen, wie das einzelne Zeichen im EEprom gespeichert ist - da Du mit 'char' und 'char*' um Dich geworfen hast, rate ich blind: char.
Da ist der Vorrat 256 Zeichen, der 'ganz normale ASCII-Satz'.
Was Dein Display daraus macht, kannst nur DU (ja, zwei große Buchstaben, kann ich auch) herausfinden - schätze, gute drei Minuten sollten für diese Schlauheit ausreichend sein.
(Arbeitszeit, das Zusammenstöppeln des Test-Sketch, Der Dir alle 256 Zeichen ans Display schickt, darin nicht enthalten - nur die reine Ausgabe Zeichen für Zeichen, ca. Sekundentakt)

MfG

PS:letzter Versuch

Warum willst du die Zeichenkette in ein EEPROM speichern wenn diese ohnehin nur auf dem 7Segment ausgeben ausgegeben werden soll?

Wenn das was werden soll ala "beim Einschalten soll der im EEPROM gespeicherte Text angezeigt werden" dann fehlt a) deine Programmbeschreibung dazu und b) im Code ist dazu auch nichts zu finden.

Ich denke ein sauberer Programmablaufplan würde dir helfen die Aufgaben deines Programms in kleine Teile zu zerteilen und so schrittweise zu lösen.

Wenn du dir mal als Beispiel diese Anzeige mit Serial Eingabe ansiehst: MD_MAX72XX/MD_MAX72xx_Message_Serial.ino at main · MajicDesigns/MD_MAX72XX · GitHub
, da siehst du wie jemand seine Schritte klar strukturiert:

Am Ende des Setups wird am Display etwas ausgegeben,
die einzelnen Aufgaben sind klar in eigenen Funktionen definiert
und im loop werden nur mehr die einzelnen Aufgaben/Funktionen aufgerufen:

  readSerial();
  scrollText();

wenn es keine besseren Beispiele im Netz gibt, kannst dich an diesen Ablauf anhalten.
Das abspeichern des Texts würde ich mit https://www.arduino.cc/en/Reference/EEPROMPut machen, und zwar immer dann, wenn eine neue Zeile über die Serielle gekommen ist (auch das ist im obigen Beispiel klar erkennbar ca Zeile 62.

Das (nicht angeforderte!) Auslesen bei Programmstart würde ich mit https://www.arduino.cc/en/Reference/EEPROMGet machen.

Edit 9:22 Uhr:
ich sehe du bist online - antwortest aber nicht mehr. Alles klar soweit oder brauchst noch ein Beispiel?

noiasca:
Edit 9:22 Uhr:
ich sehe du bist online - antwortest aber nicht mehr. Alles klar soweit oder brauchst noch ein Beispiel?

Alles klar ist es leider nicht. Werde es mal mit put und get versuchen. Sollte das auch nicht mit Beispielen funktionieren fliegt das Projekt in die Ecke.

Traurig.

Hi

Einsicht ist der erste Weg zur Besserung. Traurig. Aber wahr!

Wenn's noch etwas mehr Rumgeheule sein soll, gerne. Zumindest ich werde mir meinen Teil denken ... Das wiederum könnte sogar lustig werden - und wahr.

MfG

da ich 7 segment displays nur mit dem MAX7219 betreibe kommt bei mir sowas raus:

/*******************************************************************************
  LCDemoNoiascaSerialEeprom

  Receive text to be displayed over Serial and store text to EEPROM
  Retrive text from EEPROM on startup

  credits to MajicDesigns for the idea of his MD_MAX72xx_Message_Serial.ino
  name=LCDemoNoiascaSerialEeprom
  version=1.0.0
  author=Werner Rothschopf
  date=2019-07-27
 *******************************************************************************/

//We always have to include the library
#include <NoiascaLedControl.h>        // get the library here http://werner.rothschopf.net/201904_arduino_ledcontrol_max7219.htm
#include <EEPROM.h>

/*  ***** These pin numbers will probably need to be adopted to your hardware ***** */
#define LEDCS_PIN             8       // LED CS or LOAD
#define LEDCLK_PIN            7       // LED Clock
#define LEDDATA_PIN           9       // LED DATA IN
#define LED_MODULES           2       // Number of LED Modules - total length of chain

LedControl lc = LedControl  (LEDDATA_PIN, LEDCLK_PIN, LEDCS_PIN, LED_MODULES);  // create a LED Control display object

unsigned long delaylong = 4000;       // waiting time between displayed text - milliseconds

// Global message buffers shared by Serial and Scrolling functions
#define BUF_SIZE  64                  // could be reduced if less then 64 characters are needed or LED_MODULES * 8 
char curMessage[BUF_SIZE];            // current Message to be displayed
char newMessage[BUF_SIZE];            // Buffer for new message comming in
bool newMessageAvailable = false;     // flag if new Message is available
const uint16_t addrMessage = 10;      // EEPROM start address where to store the message


/*
  Check Serial for new data
*/
void readSerial()
{
  static uint8_t  putIndex = 0;
  while (Serial.available())
  {
    newMessage[putIndex] = (char)Serial.read();
    if ((newMessage[putIndex] == '\n') || (putIndex >= BUF_SIZE - 3)) // end of message character or full buffer
    {
      // put in a message separator and end the string
      newMessage[putIndex++] = ' ';
      newMessage[putIndex] = '\0';
      // restart the index for next filling spree and flag we have a message waiting
      putIndex = 0;
      newMessageAvailable = true;
      EEPROM.put(addrMessage, newMessage);
    }
    else if (newMessage[putIndex] != '\r')
      // Just save the next char in next location
      putIndex++;
  }
}


/*
  Print new text to display 
  simple start without any fancy scrolling so far.
*/
void updateText()
{
  if (newMessageAvailable)
  {
    Serial.print(F("Print new message to display:")); Serial.println(newMessage);
    strcpy(curMessage, newMessage);
    lc.clearDisplay();
    lc.print(curMessage);
    newMessageAvailable=false;
  }
}


/*
  Print a welcome message to Display
*/
void printWelcomeOn7Segment() {
  Serial.println(F("Print a welcome message to Display"));
  lc.clearDisplay();
  lc.print("HELLO U2");
  delay(delaylong);
}


void setup() {
  Serial.begin(115200);
  Serial.println(F("Noiasca Led Control Serial EEPROM"));

  //Setup routines for MAX72xx
  for (byte i = 0; i < LED_MODULES; i++)
  {
    lc.shutdown(i, false);                // The MAX72xx is in power-saving mode on startup, we have to do a wakeup call
    lc.setIntensity(i, 8);                // Set the brightness to a medium value, possible is 0-15 
  }
  lc.clearDisplay();                      // and clear all displays

  // print welcome
  printWelcomeOn7Segment();

  // Read stored text from EEPROM and print to display
  EEPROM.get(addrMessage, newMessage);   
  newMessageAvailable = true;            
  updateText();                          // hint: if you use the sketch the first time and your EEPROM is not set, the display might get dark after the welcome message, if no printable characters are found
  Serial.println(F("\nnow, enter new text in Serial Monitor \n- to be displayed on LED \n- and to be stored to EEPROM for next startup "));
}


void loop() 
{
  readSerial();
  updateText();
}

du solltest eigentlich in der Lage sein, das für dein Display umzustricken.

RaffaySH:
Traurig.

Ja.
Dabei habe ich dir doch eine glasklare step for step Anleitung gebastelt....

Schade, wäre eine gute Gelegenheit für dich gewesen, die Programmiersprache C++ zu lernen.
Aber wenn du so schnell die Flinte in den Sand steckst und den Kopf ins Korn wirfst....

Das mit dem EEPROM verstehe ich auch nicht. Das solltest du vielleicht erst mal weglassen bis zu den Umgang mit C Strings verstanden hast

Wie man Text von der seriellen Schnittstelle einliest habe ich hier schon unendlich oft gezeigt:
https://forum.arduino.cc/index.php?topic=622530.msg4217397#msg4217397

Relevant ist die readSerial() Funktion. loop() kann erst mal nur das sein:

void loop()
{
  char* str = readLine(Serial);
  if (str != NULL) 
  {
     Serial.println(str);
  }
}

noiasca:
du solltest eigentlich in der Lage sein, das für dein Display umzustricken.

noiasca - Perfekt. Das umstricken funktioniert. Vielen vielen Dank dafür.

Wenn ich im Seriellen Monitor einen Text schreibe, und diesen mit return abschicke, wird doch nur ein \n am Ende mitgeschickt, oder bin ich da falsch?

Wenn ich im Seriellen Monitor einen Text schreibe, und diesen mit return abschicke, wird doch nur ein \n am Ende mitgeschickt, oder bin ich da falsch?

Jain!

RaffaySH:
Wenn ich im Seriellen Monitor einen Text schreibe, und diesen mit return abschicke, wird doch nur ein \n am Ende mitgeschickt, oder bin ich da falsch?

Was er nach dem Abschicken noch anhängt stellst Du in dem Dropdown-Menü unten links neben der Baudrateneinstellung ein, Das kann nichts, nur \r, nur \n oder beides sein.