Hi! I'm trying to develop a "fake" thermometer for medical simulations with my nursing students. One LCD display, one a scan button that activates the device for 10 sec and displays a temperature, one "increase temp" button and one "decrease temp" button.
I want the displayed temperature to be saved to EEPROM and displayed the next time the scan button is pressed. I will 3D print the physical thing, but I can't figure out the coding part.
I can't code, but from time to time Copilot or Blackbox has helped me with what I needed and I managed to do what I want. But this time it doesn't work.
Is there someone out there who could have a look at "my" code and help me out? The wiring might just as well be less than ideal... thermometer - Wokwi ESP32, STM32, Arduino Simulator
Why? Does the device actually power down between uses? As long as it's powered up, data in RAM will be preserved, so no need to store it in EEPROM.
Could you indicate clearly how the code does not do what you intend it to do?
pinMode(button1Pin, INPUT_PULLUP);
pinMode(button2Pin, INPUT_PULLUP);
pinMode(button3Pin, INPUT_PULLUP);
Ditch the pulldown resistors. You're using internally pulled up GPIO's for the buttons after all. Also disconnect the +5V from the buttons.
This is the working principle:
Connect one pin of the button to the GPIO. Connect a diametrically opposing pin to GND. That's all. No resistors. Only two connections to a button. Like so:
Keep in mind that with your EEPROM experiment, the first time the system starts up, a virgin EEPROM is generally filled with all 0xFF. This routine will verify and ignore the EEPROM contents instead of trying to parse them into the 'temperature' variable.
// Retrieve the last stored temperature from EEPROM
bool virgin_eeprom = true;
for (uint8_t i=0; i < sizeof(float); i ++) {
if (EEPROM.read(i) != 0xff) virgin_eeprom = true;
}
if (!virgin_eeprom) {
EEPROM.get(0, temperature);
}
Try to reduce/eliminate the use of 'magic numbers' in your code. Instead of using '0' for the EEPROM address throughout your code, it's better to '#define' it or declare it as a constant and then use the human readable label. This also prevents problems if you want/need to address and forget to change it everywhere it's referenced.
#define EEPROM_ADDRESS_TEMPERATURE 0
or:
const uint16_t EEPROM_ADDRESS_TEMPERATURE = 0;
(They're more or less equivalent for your purpose.)
Then read like this:
EEPROM.get(EEPROM_ADDRESS_TEMPERATURE , temperature);
So learn. I suspect you can swim, and ride a bicycle, and walk. You learned those things. You can learn to code just the same.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int button2Pin = 7;
const int button3Pin = 8;
float temperature = 0.0;
void setup() {
lcd.begin(16, 2);
lcd.backlight();
pinMode(button1Pin, INPUT_PULLUP);
pinMode(button2Pin, INPUT_PULLUP);
pinMode(button3Pin, INPUT_PULLUP);
print();
lcd.setCursor(0, 1);
lcd.print("grader celcius");
}
void loop() {
if (digitalRead(button2Pin) == LOW) { // Check if button 2 is pressed
temperature += 0.8; // Increase the temperature by 0.8
print();
}
if (digitalRead(button3Pin) == LOW) { // Check if button 3 is pressed
temperature -= 0.8; // Decrease the temperature by 0.8
print();
}
}
void print() {
lcd.setCursor(0, 0);
lcd.print(temperature, 1);
lcd.print(" ");
delay(200);
}
Workable, but pressing either button will cause a very rapid increase or decrease in temp. An easy fix to avoid dealing with button edges would be to delay after the button's pressed and new temperature displayed.
yes
look this over
#include <EEPROM.h>
const byte pinsBut [] = { A1, A2, A3 };
#define N_BUT sizeof(pinsBut)
byte butState [N_BUT];
const unsigned TempAddr = 765;
int temp;
// -----------------------------------------------------------------------------
const int NoBut = -1;
int
chkButtons ()
{
for (unsigned n = 0; n < sizeof(pinsBut); n++) {
byte but = digitalRead (pinsBut [n]);
if (butState [n] != but) {
butState [n] = but;
delay (30); // debounce
if (LOW == but)
return n;
}
}
return NoBut;
}
// -----------------------------------------------------------------------------
enum { Up, Down, Save };
void
loop ()
{
switch (chkButtons ()) {
case Up:
temp++;
Serial.println (temp/10.0);
break;
case Down:
temp--;
Serial.println (temp/10.0);
break;
case Save:
EEPROM.put (TempAddr, temp);
break;
default:
break;
}
if (Serial.available ()) {
char buf [90];
int n = Serial.readBytesUntil ('\n', buf, sizeof(buf)-1);
buf [n] = '\0';
sscanf (buf, "%d", & temp);
}
}
// -----------------------------------------------------------------------------
void
setup ()
{
Serial.begin (9600);
for (unsigned n = 0; n < sizeof(pinsBut); n++) {
pinMode (pinsBut [n], INPUT_PULLUP);
butState [n] = digitalRead (pinsBut [n]);
}
EEPROM.get (TempAddr, temp);
if (0 == temp)
temp = 990;
Serial.println (temp / 10.0);
}
you can set the temp thru the serial monitor if far from the value you need
Do you have any Web link to this display unit?
Got bored, did this but then I got interrupted. I made the little Pico/OLED combo system a few months ago but the original need for it went away. Since I had it on hand, I figured I'd do something fun with it.
I'll get back to it later today!
Updated with code (in Python) in case anyone cares. No memory across power cycles though.
http://www.theselittlemachines.com/
Still figuring out how to do anchor links in Jekyll so sorry for posting the same link again.
That's an LED display...
Hey, I'm amazed with the prompt and helpful answers from you guys! I'll get back as soon as I have tried out your solutions. Thanks!
This seems to work. Thanks!