用键盘输入一个数字并将一个数字存储到 EEPROM
Posted
技术标签:
【中文标题】用键盘输入一个数字并将一个数字存储到 EEPROM【英文标题】:Input a number with Keypad and storing a number to EEPROM 【发布时间】:2019-12-29 23:03:50 【问题描述】:您好,我没有太多的编码经验,只是一个基本的员工,所以我需要帮助
但我需要修改如下: 首先,当用户按下“#”键时,他必须写出类似于产品价格的数字, 其次,当用户按下“A”键时,价格/数字必须存储到 EEPROM 存储器中, 第三,当用户按下“B”键时,必须从 EEPROM 存储器中读取价格/数字,
当我按“*”键时,它可以工作,但这不是内存中的数字,这只是 LCD 的打印数字,
我的问题是当我按下 LCD 上的“B”键时,我得到了一些奇怪的字符
我需要代码来使用 EEPROM
这是我的代码:
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <EEPROM.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
#include <Keypad.h> //include keypad library - first you must install library (library link in the video description)
const byte rows = 4; //number of the keypad's rows and columns
const byte cols = 4;
char keyMap [rows] [cols] = //define the cymbols on the buttons of the keypad
'1', '2', '3', 'A',
'4', '5', '6', 'B',
'7', '8', '9', 'C',
'*', '0', '#', 'D'
;
byte rowPins [rows] = 4, 5, 6, 7; //pins of the keypad
byte colPins [cols] = 8, 9, 10, 11;
Keypad myKeypad = Keypad( makeKeymap(keyMap), rowPins, colPins, rows, cols);
void setup()
// Setup size of LCD 16 characters and 2 lines
lcd.begin(16, 2);
// Back light on
lcd.backlight();
void loop()
// user input array; 10 digits and nul character
static char userinput[11];
// variable to remember where in array we will store digit
static int count = 0;
char number;
char key = myKeypad.getKey();
if (key != NO_KEY)
lcd.print(key);
switch (key)
case NO_KEY:
// nothing to do
break;
case '#':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Press a number:"));
// clear the current user input
lcd.setCursor(0, 2);
memset(userinput, 0, sizeof(userinput));
number=(userinput, 0, sizeof(userinput));
// reset the counter
count = 0;
break;
case 'A': //Store number to memory
EEPROM.write(0, number);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Saved"));
break;
case 'B': //Get number from memory and print to LCD
number = EEPROM.read(0);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Saved Number is:"));
lcd.setCursor(0, 2);
lcd.println(number);//print the stored number
break;
case '*':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Number:"));
lcd.setCursor(0, 2);
lcd.println(userinput);//print the stored number
break;
default:
// if not 10 characters yet
if (count < 10)
// add key to userinput array and increment counter
userinput[count++] = key;
break;
//delay(200);
【问题讨论】:
【参考方案1】:让我们分析一下你的循环代码:
-
循环的开头看起来不错。静态变量
userinput, count
将保留其值(重要),变量 count
和 number
将在每个新循环中归零(OK)。
在case '#'
,您可能想清除所有内容并准备接收新号码。删除number=(userinput, 0, sizeof(userinput));
行,因为这不是您设置变量值的方式,而且您不想将“#”作为输入数字。新输入的数字将保存到您的 userinput
数组中,以 default
为例。
在case 'A'
中,您将把变量写入EEPROM。正确的(基本)方法是(在你的情况下)EEPROM.write(count, key)
。您还应该在写入 EEPROM 存储器后延迟 4 毫秒(在 EEPROM 存储器中写入一个字节需要 3.3 毫秒)。我还建议使用函数EEPROM.update(0)
而不是EEPROM.write(0)
。看看here为什么。我的另一个建议是在输入所有 10 位数字后执行 EEPROM 写入操作——如果用户没有正确输入数字(例如按“#”),您将节省一些 EEPROM 写入周期...
在case 'B'
中,您想从 EEPROM 中读取数字。正确的实现是
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Saved Number is:"));
for (int i = 0; i <= count; i++)
lcd.setCursor(i, 2);
number = EEPROM.read(i);
lcd.println(number);//print the stored number
break;
我没有测试过这个,更多的是关于如何做的想法。
在case '*'
,我不确定你想做什么——从你的描述中看不清楚。我想你只想在userinput
array 中打印出数字。这可以通过与case 'B'
类似的方式完成,所以:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("userinput no:"));
for (int i = 0; i <= count; i++)
lcd.setCursor(i, 2);
number = userinput[i];
lcd.println(number);
break;
在case 'default'
中,您将最后输入的数字保存到userinput
数组中。没关系。
【讨论】:
谢谢你,我接受了你的建议,现在我遇到了这个问题......因为我不知道如何在这里发布这里是一个链接forum.arduino.cc/index.php?topic=633081.0 整个讨论帖的链接没有用,我不知道你的问题是什么。了解如何在此处发布...【参考方案2】:好的,谢谢 JSC,您对我们的帮助很大 我接受了您的建议,最后我的代码应该这样做: 1) 用户输入密码“###” 2) LCD 显示 4 个产品“价格表”(价格应来自 EEPROM) 3) 用户按下“1”键 4) 在 LCD 上:“请输入新价格 1”,用户为“新价格 1”设置一些新数字 5) 用户按下“A”键,“newPrice1”经过一小段延迟后被保存到 EEPROM LCD 上有一个“PriceList”,有 4 个价格,但有“newPrice1” 6) 用户按下“2”键 7) 在 LCD 上:“请输入新价格 2”,用户为新的“新价格 2”设置一些新数字 5) 用户再次按下“A”键,“newPrice2”在 LCD 上稍作延迟后被保存到 EEPROM,再次出现“PriceList”,其中包含 4 个价格但“newPrice2” 以此类推 price3 和 price4 这就是想法:) 但是我的代码不能正常工作,我不知道为什么? 这是到目前为止的代码
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <EEPROM.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
#include <Keypad.h> //include keypad library - first you must install library (library link in the video description)
const byte rows = 4; //number of the keypad's rows and columns
const byte cols = 4;
char keyMap [rows] [cols] = //define the cymbols on the buttons of the keypad
'1', '2', '3', 'A',
'4', '5', '6', 'B',
'7', '8', '9', 'C',
'*', '0', '#', 'D'
;
byte rowPins [rows] = 4, 5, 6, 7; //pins of the keypad
byte colPins [cols] = 8, 9, 10, 11;
Keypad myKeypad = Keypad( makeKeymap(keyMap), rowPins, colPins, rows, cols);
// user input array; 10 digits and nul character 1234567890
static char priceArrey1[4];
static char priceArrey2[4];
static char priceArrey3[4];
static char priceArrey4[4];
// variable to remember where in array we will store digit
static int count1 = 0;
static int count2 = 0;
static int count3 = 0;
static int count4 = 0;
int newrPrice1; //int Val za pretvoranje na od "char priceArry" vo "int number"
int newrPrice2;
int newrPrice3;
int newrPrice4;
char pressKey;
int passState = 0;
int productState = 0;
char* password = "###"; //create a password
int passLenght = 0; //keypad passLenght
void setup()
// Setup size of LCD 16 characters and 2 lines
lcd.begin(16, 2);
// Back light on
lcd.backlight();
void loop()
Serial.begin(115200);
pressKey = myKeypad.getKey();
if (pressKey != NO_KEY) // if any key is pressed
lcd.print(pressKey);
switch (pressKey)
case NO_KEY:
// nothing to do if no key is pressed Blank Screen
break;
case '1':
if (passState = 1)
productState = 1;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Set New Price P1"));
// clear the current user input
lcd.setCursor(0, 2);
memset(priceArrey1, 0, sizeof(priceArrey1));
// reset the counter
count1 = 0;
break;
case '2':
if (passState = 1)
productState = 2;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Set New Price P2"));
// clear the current user input
lcd.setCursor(0, 2);
memset(priceArrey2, 0, sizeof(priceArrey2));
// reset the counter
count2 = 0;
break;
case '3':
if (passState = 1)
productState = 3;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Set New Price P3"));
// clear the current user input
lcd.setCursor(0, 2);
memset(priceArrey3, 0, sizeof(priceArrey3));
// reset the counter
count3 = 0;
break;
case '4':
if (passState = 1)
productState = 4;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Set New Price P4"));
// clear the current user input
lcd.setCursor(0, 2);
memset(priceArrey4, 0, sizeof(priceArrey4));
// reset the counter
count4 = 0;
break;
case 'A': //Store number to memory
if (passState == 1 && productState == 1)
newrPrice1 = atoi(priceArrey1); // funkcioata atoi() pretvara od char to int
EEPROM.put(0, newrPrice1); //EEPROM.put (address, val) snima u memorijata pogolemi brojki od 255
delay(100); //it takes 3,3 ms to write a byte in an EEPROM memory)
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Saved P1"));
else if (passState == 1 && productState == 2)
newrPrice2 = atoi(priceArrey2); // funkcioata atoi() pretvara od char to int
EEPROM.put(3, newrPrice2); //EEPROM.put (address, val) snima u memorijata pogolemi brojki od 255
delay(100); //it takes 3,3 ms to write a byte in an EEPROM memory)
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Saved P2"));
else if ((passState == 1) && (productState == 3))
newrPrice3 = atoi(priceArrey3); // funkcioata atoi() pretvara od char to int
EEPROM.put(6, newrPrice3); //EEPROM.put (address, val) snima u memorijata pogolemi brojki od 255
delay(100); //it takes 3,3 ms to write a byte in an EEPROM memory)
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Saved P3"));
else if ((passState == 1) && (productState == 4))
newrPrice4 = atoi(priceArrey4); // funkcioata atoi() pretvara od char to int
EEPROM.put(9, newrPrice4); //EEPROM.put (address, val) snima u memorijata pogolemi brojki od 255
delay(100); //it takes 3,3 ms to write a byte in an EEPROM memory)
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Saved P4"));
delay(1500);
getSavedPrce();
printSavedPrceLCD(); //Price List
delay(1000);
break;
default:
// if not 10 characters yet
if (count1 < 3)
// add key to priceArrey array and increment counter
priceArrey1[count1++] = pressKey;
else if (count2 < 3)
// add key to priceArrey array and increment counter
priceArrey2[count2++] = pressKey;
else if (count3 < 3)
// add key to priceArrey array and increment counter
priceArrey3[count3++] = pressKey;
else if (count4 < 3)
// add key to priceArrey array and increment counter
priceArrey4[count4++] = pressKey;
break;
stateKeypad();
void getSavedPrce() //Reads savedPrice from EEPROM
newrPrice1 = EEPROM.get(0, newrPrice1);
delay(500);
newrPrice2 = EEPROM.get(3, newrPrice2);
delay(500);
newrPrice3 = EEPROM.get(6, newrPrice3);
delay(500);
newrPrice4 = EEPROM.get(9, newrPrice4);
delay(500);
/// Shows Price List from keypad on LCD
void printSavedPrceLCD () //"Price List keypad MODE" on lcd
lcd.clear(); //clears lcd sreen
//1
lcd.setCursor(0, 0);
lcd.print("P1");
lcd.setCursor(3, 0);
lcd.print(newrPrice1);
//2
lcd.setCursor(9, 0);
lcd.print("P2");
lcd.setCursor(12, 0);
lcd.print(newrPrice2);
//3
lcd.setCursor(0, 2);
lcd.print("P3");
lcd.setCursor(3, 2);
lcd.print(newrPrice3);
//4
lcd.setCursor(9, 2);
lcd.print("P4");
lcd.setCursor(12, 2);
lcd.print(newrPrice4);
void stateKeypad() //menu password
if (pressKey == password [passLenght])
passLenght ++;
if (passLenght == 3)
passState = 1;
productState = 0;
getSavedPrce();
printSavedPrceLCD(); //Price List
delay(1000);
【讨论】:
以上是关于用键盘输入一个数字并将一个数字存储到 EEPROM的主要内容,如果未能解决你的问题,请参考以下文章
用C#语言对于用户从键盘输入的一个数字,编程输出这一数字的人民币金