I am sending message thru Bluetooth, getting it on LCD.
I got this part working, all good.
Now I want to store that message on EEPROM.
And when device powered up , it should show that message.
Everything working but message is not showing. for some reason its showing 152.
Could you please help me to find mistake?
Here is my code
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
#include <EEPROM.h>
hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip
int addr = 0;
byte value;
char terminalRead;
// LCD geometry
// while 16x2 will work on most displays even if the geometry is different,
// for actual wrap testing of a particular LCD it is best to use the correct
// geometry.
const int LCD_COLS = 20;
const int LCD_ROWS = 4;
void setup() {
Serial.begin(9600);
int status;
status = lcd.begin(LCD_COLS, LCD_ROWS);
if(status) // non zero status means it was unsuccesful
{
status = -status; // convert negative status value to positive number
// begin() failed so blink error code using the onboard LED if possible
// hd44780::fatalError(status); // does not return
}
// turn on automatic line wrapping
// which automatically wraps lines to the next lower line and wraps back
// to the top when at the bottom line
// NOTE:
// noLineWrap() can be used to disable automatic line wrapping.
// _write() can be called instead of write() to send data bytes
// to the display bypassing any special character or line wrap processing.
lcd.lineWrap();
value = EEPROM.read(addr);
lcd.setCursor(0, 0);
lcd.print("EEPROM");
lcd.setCursor(0, 1);
lcd.print(value);
//char terminalRead;
}
void loop() {
terminalRead=Serial.read();
int i=0;
char commandbuffer[100];
if(Serial.available()){
delay(1000);
while( Serial.available() && i< 99) {
commandbuffer[i++] = Serial.read();
}
commandbuffer[i++]='\0';
if(i>0)
Serial.println((char*)commandbuffer);
lcd.clear();
lcd.cursor();
char c = ((char*)commandbuffer);
for(int i=2*LCD_COLS*LCD_ROWS; i; i--)
lcd.print(c);
lcd.setCursor(0, 0);
lcd.print((char*)commandbuffer);
// if(c > 0x7e) // wrap back to beginning of printable ASCII chars
// c = '!';
EEPROM.write(addr, (char*)commandbuffer);
delay(1000);
// lcd.clear();
}
}
What you are writing to EEPROM is not correct. You are reading in a series of chars into your commandbuffer array but then you are writing the address of that variable to EEPROM. The write() function only writes one byte, not an entire string like lcd.print() does.
If you want to write just one byte, you would use EEPROM.write(addr, commandbuffer[0]);
If you want to interpret what is in the commandbuffer as a number (e.g. "123"), then you need to use atoi() to convert it and then write that value.
you are reading only one byte from your eeprom. if you want a character representation instead of the byte value then you need to cast it to string or char array before you print.
I tried arrays.
I used
value = EEPROM.get(0, myArray[X]);
and I used EEPROM.put
I arranged my array from serial reading -
if(Serial.available()>0){
myArray[X]=Serial.available();
And somehow I still get exactly the same result. LCD showing "152" after I turn it on.
Could you please point me where I should look for mistake
Also I was thinking - EEPROM has some kind of read/wright limit. So I don't want to write in it every second. What kind of solution could save EEPROM in my project?
Here is my current code
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
#include <EEPROM.h>
hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip
int addr = 0;
byte value;
int myArray[100];
int X = 0;
char terminalRead;
// LCD geometry
// while 16x2 will work on most displays even if the geometry is different,
// for actual wrap testing of a particular LCD it is best to use the correct
// geometry.
const int LCD_COLS = 20;
const int LCD_ROWS = 4;
void setup() {
Serial.begin(9600);
int status;
status = lcd.begin(LCD_COLS, LCD_ROWS);
if(status) // non zero status means it was unsuccesful
{
status = -status; // convert negative status value to positive number
// begin() failed so blink error code using the onboard LED if possible
// hd44780::fatalError(status); // does not return
}
// turn on automatic line wrapping
// which automatically wraps lines to the next lower line and wraps back
// to the top when at the bottom line
// NOTE:
// noLineWrap() can be used to disable automatic line wrapping.
// _write() can be called instead of write() to send data bytes
// to the display bypassing any special character or line wrap processing.
lcd.lineWrap();
value = EEPROM.get(0, myArray[X]);
lcd.setCursor(0, 0);
lcd.print("EEPROM");
lcd.setCursor(0, 1);
lcd.print(value);
//char terminalRead;
}
void loop() {
terminalRead=Serial.read();
int i=0;
char commandbuffer[100];
if(Serial.available()){
delay(1000);
while( Serial.available() && i< 99) {
commandbuffer[i++] = Serial.read();
}
commandbuffer[i++]='\0';
if(i>0)
Serial.println((char*)commandbuffer);
lcd.clear();
lcd.cursor();
char c = ((char*)commandbuffer);
for(int i=2*LCD_COLS*LCD_ROWS; i; i--)
lcd.print(c);
lcd.setCursor(0, 0);
lcd.print((char*)commandbuffer);
// if(c > 0x7e) // wrap back to beginning of printable ASCII chars
// c = '!';
if(Serial.available()>0){
myArray[X]=Serial.available();
X = X + 1;
}
}
// EEPROM.write(addr, (char*)commandbuffer);
//
EEPROM.put(0, myArray[X]);
//EEPROM.put(addr, (char*)commandbuffer);
delay(1000);
// lcd.clear();
}
Try this code. Basically, you need to loop over your array of char (not int) and read/write each char to/from EEPROM
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
#include <EEPROM.h>
hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip
int addr = 0;
byte value;
const int maxMessageLength = 100;
char myMsg[maxMessageLength];
// LCD geometry
// while 16x2 will work on most displays even if the geometry is different,
// for actual wrap testing of a particular LCD it is best to use the correct
// geometry.
const int LCD_COLS = 20;
const int LCD_ROWS = 4;
void setup() {
Serial.begin(9600);
int status;
status = lcd.begin(LCD_COLS, LCD_ROWS);
if (status) // non zero status means it was unsuccesful
{
status = -status; // convert negative status value to positive number
// begin() failed so blink error code using the onboard LED if possible
// hd44780::fatalError(status); // does not return
}
// turn on automatic line wrapping
// which automatically wraps lines to the next lower line and wraps back
// to the top when at the bottom line
// NOTE:
// noLineWrap() can be used to disable automatic line wrapping.
// _write() can be called instead of write() to send data bytes
// to the display bypassing any special character or line wrap processing.
lcd.lineWrap();
// copy existing message from EEPROM
// copy until we get a nul (0) or any char above 127 or max message length
for ( int i = 0; i < maxMessageLength; ++i ) {
char c = EEPROM[i];
if ( c > 127 or c == 0 ) {
myMsg[i] = '\0';
break;
}
myMsg[i] = c;
}
lcd.setCursor(0, 0);
lcd.print("EEPROM");
lcd.setCursor(0, 1);
lcd.print(myMsg);
}
void loop() {
char terminalRead = Serial.read();
int idx = 0;
char commandbuffer[maxMessageLength];
if (Serial.available()) {
delay(1000);
while ( Serial.available() && i < maxMessageLength - 1) {
commandbuffer[idx++] = Serial.read();
}
commandbuffer[idx] = '\0';
if (idx > 0) {
Serial.println(commandbuffer);
}
lcd.clear();
lcd.cursor();
lcd.setCursor(0, 0);
lcd.print(commandbuffer);
for ( int i = 0; i < idx; ++i ) {
EEPROM[i] = commandbuffer[i];
}
delay(1000);
// lcd.clear();
}
}
what happens now:
everything working.
message is showing on LCD from EEPROM. However only for a split second.
here is current code:
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
#include <EEPROM.h>
hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip
int addr = 0;
byte value;
const int maxMessageLength = 100;
char myMsg[maxMessageLength];
// LCD geometry
// while 16x2 will work on most displays even if the geometry is different,
// for actual wrap testing of a particular LCD it is best to use the correct
// geometry.
const int LCD_COLS = 20;
const int LCD_ROWS = 4;
int i = 0;
void setup() {
Serial.begin(9600);
int status;
status = lcd.begin(LCD_COLS, LCD_ROWS);
if (status) // non zero status means it was unsuccesful
{
status = -status; // convert negative status value to positive number
// begin() failed so blink error code using the onboard LED if possible
// hd44780::fatalError(status); // does not return
}
// turn on automatic line wrapping
// which automatically wraps lines to the next lower line and wraps back
// to the top when at the bottom line
// NOTE:
// noLineWrap() can be used to disable automatic line wrapping.
// _write() can be called instead of write() to send data bytes
// to the display bypassing any special character or line wrap processing.
lcd.lineWrap();
// copy existing message from EEPROM
// copy until we get a nul (0) or any char above 127 or max message length
for ( int i = 0; i < maxMessageLength; ++i ) {
char c = EEPROM[i];
if ( c > 127 or c == 0 ) {
myMsg[i] = '\0';
break;
}
myMsg[i] = c;
}
lcd.setCursor(0, 0);
lcd.print("EEPROM");
lcd.setCursor(0, 1);
lcd.print(myMsg);
}
void loop() {
char terminalRead = Serial.read();
int idx = 0;
char commandbuffer[maxMessageLength];
if (Serial.available()) {
delay(1000);
while ( Serial.available() && i < maxMessageLength - 1) {
commandbuffer[idx++] = Serial.read();
}
commandbuffer[idx] = '\0';
if (idx > 0) {
Serial.println(commandbuffer);
}
lcd.clear();
lcd.cursor();
lcd.setCursor(0, 0);
lcd.print(commandbuffer);
for ( int i = 0; i < idx; ++i ) {
EEPROM[i] = commandbuffer[i];
}
delay(1000);
// lcd.clear();
}
}
Based on your questions and attempts at code, I would really suggest you look at some of the examples that come with the IDE and really learn how they work and why.
As a way of debugging your code, you can do everything you did in your setup() function but then leave your loop() function empty so your code will only read from EEPROM and print to the LCD and do nothing else. If there still is a problem, then it may be with reading in the message. You can also print your message out to Serial with some sort of marker before it and after it to see if it is what you expect.
Thank you so much blh64
I am learning a lot from you! You right, I need to go back to basics. Working on it now.
I just really need that project coz its a part of other project. Its digital label.
I changed to idx.
Its working, however after powering it up, I get just some of the text
here is two pictures: first pic is showing when text message sent thru Bluetooth terminal (sometimes it looses first symbols);
and second picture is showing LCD after powering Arduino up.
I tried arrays.
I used
value = EEPROM.get(0, myArray[X]);
If you used
EEPROM.get(0, myArray);
It would read the value at EEPROM 0 into the array all at once. There is no need to iterate through addresses and array levels
Could you please help with debagging
I tried to make loop function empty but I was getting too many error messages. I don't think I did it right.
What other ways to find where the program is failing?
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
#include <EEPROM.h>
hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip
//int addr = 0;
//byte value;
const int maxMessageLength = 100;
char myMsg[maxMessageLength];
// LCD geometry
// while 16x2 will work on most displays even if the geometry is different,
// for actual wrap testing of a particular LCD it is best to use the correct
// geometry.
const int LCD_COLS = 20;
const int LCD_ROWS = 4;
void setup() {
Serial.begin(9600);
int status;
status = lcd.begin(LCD_COLS, LCD_ROWS);
if (status) // non zero status means it was unsuccesful
{
status = -status; // convert negative status value to positive number
// begin() failed so blink error code using the onboard LED if possible
// hd44780::fatalError(status); // does not return
}
// turn on automatic line wrapping
// which automatically wraps lines to the next lower line and wraps back
// to the top when at the bottom line
// NOTE:
// noLineWrap() can be used to disable automatic line wrapping.
// _write() can be called instead of write() to send data bytes
// to the display bypassing any special character or line wrap processing.
lcd.lineWrap();
// copy existing message from EEPROM
// copy until we get a nul (0) or any char above 127 or max message length
for ( int idx = 0; idx < maxMessageLength; ++idx ) {
char c = EEPROM[idx];
if ( c > 127 or c == 0 ) {
myMsg[idx] = '\0';
break;
}
myMsg[idx] = c;
}
// lcd.setCursor(0, 0);
// lcd.print("EEPROM");
lcd.setCursor(0, 0);lcd.clear();
lcd.print(myMsg);
}
void loop() {
char terminalRead = Serial.read();
int idx = 0;
char commandbuffer[maxMessageLength];
if (Serial.available()) {
delay(1000);
while ( Serial.available() && idx < maxMessageLength - 1) {
commandbuffer[idx++] = Serial.read();
}
commandbuffer[idx] = '\0';
if (idx > 0) {
Serial.println(commandbuffer);
}
lcd.clear();
lcd.cursor();
lcd.setCursor(0, 0);
lcd.print(commandbuffer);
for ( int i = 0; i < idx; ++i ) {
EEPROM[i] = commandbuffer[i];
}
delay(1000);
// lcd.clear();
}
}
I moved loop function to the end, so the whole program run one time only.
But cant compile code. Getting error message - expected unqualified-id before 'if'
highlighted line:
if (Serial.available()) {
I tried to move brackets.
I did more reading. I found that it happens when statement is outside the function. But I still don't understand how to change it, and what.
Could you please tell me where to look. I really want to get good at Arduino
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
#include <EEPROM.h>
hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip
//int addr = 0;
//byte value;
const int maxMessageLength = 100;
char myMsg[maxMessageLength];
// LCD geometry
// while 16x2 will work on most displays even if the geometry is different,
// for actual wrap testing of a particular LCD it is best to use the correct
// geometry.
const int LCD_COLS = 20;
const int LCD_ROWS = 4;
void setup() {
Serial.begin(9600);
int status;
status = lcd.begin(LCD_COLS, LCD_ROWS);
if (status) // non zero status means it was unsuccesful
{
status = -status; // convert negative status value to positive number
// begin() failed so blink error code using the onboard LED if possible
// hd44780::fatalError(status); // does not return
}
// turn on automatic line wrapping
// which automatically wraps lines to the next lower line and wraps back
// to the top when at the bottom line
// NOTE:
// noLineWrap() can be used to disable automatic line wrapping.
// _write() can be called instead of write() to send data bytes
// to the display bypassing any special character or line wrap processing.
lcd.lineWrap();
// copy existing message from EEPROM
// copy until we get a nul (0) or any char above 127 or max message length
for ( int idx = 0; idx < maxMessageLength; ++idx ) {
char c = EEPROM[idx];
if ( c > 127 or c == 0 ) {
myMsg[idx] = '\0';
break;
}
myMsg[idx] = c;
}
// lcd.setCursor(0, 0);
// lcd.print("EEPROM");
lcd.setCursor(0, 0);lcd.clear();
lcd.print(myMsg);
}
char terminalRead = Serial.read();
int idx = 0;
char commandbuffer[maxMessageLength];
if (Serial.available()) {
delay(1000);
while ( Serial.available() && idx < maxMessageLength - 1) {
commandbuffer[idx++] = Serial.read();
}
commandbuffer[idx] = '\0';
if (idx > 0) {
Serial.println(commandbuffer);
}
lcd.clear();
lcd.cursor();
lcd.setCursor(0, 0);
lcd.print(commandbuffer);
for ( int i = 0; i < idx; ++i ) {
EEPROM[i] = commandbuffer[i];
}
delay(1000);
// lcd.clear();
}
void loop() {
}