用键盘输入一个数字并将一个数字存储到 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 将保留其值(重要),变量 countnumber 将在每个新循环中归零(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 '*',我不确定你想做什么——从你的描述中看不清楚。我想你只想在userinputarray 中打印出数字。这可以通过与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#语言对于用户从键盘输入的一个数字,编程输出这一数字的人民币金

3、从键盘输入5个数到数组中,并将5个数倒序输出。

如何将由空格缩进的用户输入存储到 String 数组中并将数字转换为 int 数组?

用c语言从键盘输入两个数字,判断哪个数更大?

Android 软键盘:下一个按钮在 HTML5 数字输入之间不“跳动”