hello! I'm learning to program on Arduino, I'm making a money counter. Everything was going well until I started saving data to the EEPROM memory.
I want to reset the data of how many coins there are with a button, the only one that turns out well is $10, the other coins appear scattered values
I would also like you to tell me if I can further optimize saving values in the EEPROM so that it lasts longer.
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <EEPROM.h>
Adafruit_SSD1306 display(128, 64);
const int sMoneda1 = 2;
const int sMoneda2 = 3;
const int sMoneda5 = 4;
const int sMoneda10 = 5;
const int botonReset = 6;
int mon1;
int mon2;
int mon5;
int mon10;
int cuenta1 = 0;
int cuenta2 = 0;
int cuenta5 = 0;
int cuenta10 = 0;
void setup() {
Serial.begin(9600);
pinMode(sMoneda1,INPUT);
pinMode(sMoneda2,INPUT);
pinMode(sMoneda5,INPUT);
pinMode(sMoneda10,INPUT);
pinMode(botonReset,INPUT);
logoInicio();
delay(3000);
inicio();
delay(3000);
}
void loop() {
mon1 = digitalRead(sMoneda1);
mon2 = digitalRead(sMoneda2);
mon5 = digitalRead(sMoneda5);
mon10 = digitalRead(sMoneda10);
pantallaAhorro();
if (mon1 == 0) {
Serial.println("Se ha depositado una moneda de $1");
cuenta1 = EEPROM.get(0, cuenta1);
cuenta1++;
delay(400);
Serial.print("Hay ");
Serial.print(cuenta1);
Serial.println(" monedas de $1 peso");
EEPROM.put(0, cuenta1);
}
if (mon2 == 0) {
Serial.println("Se ha depositado una moneda de $2");
cuenta2 = EEPROM.get(1, cuenta2);
cuenta2++;
delay(400);
Serial.print("Hay ");
Serial.print(cuenta2);
Serial.println(" monedas de $2 pesos");
EEPROM.put(1, cuenta2);
}
if (mon5 == 0) {
Serial.println("Se ha depositado una moneda de $5");
cuenta5 = EEPROM.get(2, cuenta5);
cuenta5++;
delay(400);
Serial.print("Hay ");
Serial.print(cuenta5);
Serial.println(" monedas de $5 pesos");
EEPROM.put(2, cuenta5);
}
if (mon10 == 0) {
Serial.println("Se ha depositado una moneda de $10");
cuenta10 = EEPROM.get(3, cuenta10);
cuenta10++;
delay(400);
Serial.print("Hay ");
Serial.print(cuenta10);
Serial.println(" monedas de $10 pesos");
EEPROM.put(3, cuenta10);
}
if(digitalRead(botonReset) == HIGH) {
EEPROM.put(0, 0);
EEPROM.put(1, 0);
EEPROM.put(2, 0);
EEPROM.put(3, 0);
Serial.println("Cuenta Reiniciada :)");
}
}
Before you get into trouble, STOP writing to EEPROM on every pass through loop.
You’ll cook the memory cells before your project is complete.
Your cuenta integer variables are two or four bytes long (depending on processor)…
You need to set the EEPROM address based on this.
Single byte addresses won’t hold two-byte data.
2 Likes
This would be a good application for FRAM, the writing will not damage it and you will get over a billion cycles. Writing is also much faster then EEPROM. They are available in SPI and I2C. I use 32K by 8 parts. The FRAM library will allow to write words, bytes, strings, etc whatever you want.
Possibly too late. With the one byte offset on every write, every location was probably getting new values, unless all the writes were '0'. Put, instead of write, sort of saves you if you're writing the same value constantly, but in this case the offset-by-half-a-value means as soon as any value became non-zero, a location got hammered, by 0/1/0/1/0 writes in a tight loop.
Oh well.
dougp
October 20, 2023, 11:27pm
5
Following on to @lastchancename 's post.
ricardo_utd:
if(digitalRead(botonReset) == HIGH) {
EEPROM.put(0, 0);
EEPROM.put(1, 0);
EEPROM.put(2, 0);
EEPROM.put(3, 0);
Serial.println("Cuenta Reiniciada :)");
}
The values you are writing are ints, which require two bytes of storage each. So, the code should look like this:
if(digitalRead(botonReset) == HIGH) {
EEPROM.put(0, 0);
EEPROM.put(2, 0);
EEPROM.put(4, 0);
EEPROM.put(6, 0);
Serial.println("Cuenta Reiniciada :)");
}
If they were long ints (four bytes each) it'd look like this:
if(digitalRead(botonReset) == HIGH) {
EEPROM.put(0, 0);
EEPROM.put(4, 0);
EEPROM.put(8, 0);
EEPROM.put(12, 0);
Serial.println("Cuenta Reiniciada :)");
}
See the difference in the storage addresses?
dougp
October 20, 2023, 11:30pm
6
Luckily there are over 1000 locations remaining - assuming an UNO.
3 Likes
It is more common, and robust, to use sizeof() as a part of the indexing tool, to avoid these problems. Especially when, for example, a variable changes from uint_16t, to float, which would blow up all the fixed indexing.
1 Like
Ok, giving 2 bytes, what would be the limit of integers that could be saved?
And if you can help me with the issue, the reset button is okay, how am I doing it?
1024/2, minus however many locations have been chewed up by your previous efforts.
1 Like
dougp
October 21, 2023, 12:22am
10
Not sure how to answer. Something got lost in translation.
the reset button to clear the values saved in the eeprom memory, how can I do it?
What changes have you made to your code so far? Please show us the current code.
just change the address where the data will be saved
If I write the EEPROM.put in the if function in a void loop, will it be repeated even if the if function is not activated?
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <EEPROM.h>
#include "logo.h"
Adafruit_SSD1306 display(128, 64);
const int sMoneda1 = 2;
const int sMoneda2 = 3;
const int sMoneda5 = 4;
const int sMoneda10 = 5;
const int botonReset = 6;
int mon1;
int mon2;
int mon5;
int mon10;
int cuenta1 = 0;
int cuenta2 = 0;
int cuenta5 = 0;
int cuenta10 = 0;
void setup() {
Serial.begin(9600);
pinMode(sMoneda1,INPUT);
pinMode(sMoneda2,INPUT);
pinMode(sMoneda5,INPUT);
pinMode(sMoneda10,INPUT);
pinMode(botonReset,INPUT);
logoInicio();
delay(3000);
inicio();
delay(3000);
}
void loop() {
mon1 = digitalRead(sMoneda1);
mon2 = digitalRead(sMoneda2);
mon5 = digitalRead(sMoneda5);
mon10 = digitalRead(sMoneda10);
pantallaAhorro();
if (mon1 == 0) {
Serial.println("Se ha depositado una moneda de $1");
cuenta1 = EEPROM.get(0, cuenta1);
cuenta1++;
delay(400);
Serial.print("Hay ");
Serial.print(cuenta1);
Serial.println(" monedas de $1 peso");
EEPROM.put(0, cuenta1);
}
if (mon2 == 0) {
Serial.println("Se ha depositado una moneda de $2");
cuenta2 = EEPROM.get(2, cuenta2);
cuenta2++;
delay(400);
Serial.print("Hay ");
Serial.print(cuenta2);
Serial.println(" monedas de $2 pesos");
EEPROM.put(2, cuenta2);
}
if (mon5 == 0) {
Serial.println("Se ha depositado una moneda de $5");
cuenta5 = EEPROM.get(4, cuenta5);
cuenta5++;
delay(400);
Serial.print("Hay ");
Serial.print(cuenta5);
Serial.println(" monedas de $5 pesos");
EEPROM.put(4, cuenta5);
}
if (mon10 == 0) {
Serial.println("Se ha depositado una moneda de $10");
cuenta10 = EEPROM.get(6, cuenta10);
cuenta10++;
delay(400);
Serial.print("Hay ");
Serial.print(cuenta10);
Serial.println(" monedas de $10 pesos");
EEPROM.put(6, cuenta10);
}
if(digitalRead(botonReset) == HIGH) {
EEPROM.put(0, 0);
EEPROM.put(2, 0);
EEPROM.put(4, 0);
EEPROM.put(6, 0);
Serial.println("Cuenta Reiniciada :)");
}
}
void logoInicio() { // Muestra el logo al encender
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.drawBitmap(0, 0, logo, logoAncho, logoAlto, WHITE);
display.display();
}
void inicio() { // Pantalla que se muestra al encender
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.setRotation(0);
display.setTextColor(WHITE);
display.dim(false);
display.clearDisplay();
display.setTextSize(2);
display.setCursor(5, 0);
display.print("Bienvenido");
display.setCursor(22, 18);
display.println("Ricardo");
display.setCursor(31, 48);
display.print("(");
display.write(94);
display.write(95);
display.write(94);
display.print(")");
display.display();
}
void pantallaAhorro() { // Pantalla de ahorro
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0, 0);
display.print("Dinero:");
display.setTextSize(2);
display.setCursor(32, 46);
display.print("$");
display.print((EEPROM.read(0)*1) + (EEPROM.read(2)*2) + (EEPROM.read(4)*5) + (EEPROM.read(6)*10));
display.display();
}
With the changes I made it works as I expected, but I don't know if I'm killing the EEPROM memory
dougp
October 21, 2023, 4:44am
15
Slowly but, yes. What you are doing is asking 'is it pressed?' As long as a button is pressed for one of the sMoneda_x inputs the code in the corresponding if statement wil be executed. What you want is 'Is it pressed now and was not pressed before?' You want to detect the change from not pressed to pressed. Study the state change detection demo code in IDE->file/examples/digital to see how this is done.
Of course not. But as pointed out, your code doesn't sense change, just state, so when you press a button, the if statement is true many times. That said, the put statement saves you by not writing identical values, provided you don't make the mistake that started this thread. Look at the state change examples.
You might also want to improve your coding skills by researching structures. A struct would allow you to 'abstract' the indexing problems completely.
1 Like
system
Closed
April 18, 2024, 10:10am
17
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.