0

嗨,我在编码方面没有太多经验,只是一个基本的员工,所以我需要帮助

但我需要修改如下:首先,当用户按下“#”键时,他必须写出类似于产品价格的数字,其次,当用户按下“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);
}
4

2 回答 2

0

好的,谢谢 JSC,你一直很有帮助,我接受了你的建议,最后我的代码应该这样做:
1)用户输入密码“###”
2)LCD 显示 4 个产品“价格表”(价格应该来自 EEPROM)
3) 用户按下“1”键
4) LCD 上:“请输入新价格1”,用户为“newPrice1”设置一些新数字
5) 用户按下“A”键,“newPrice1”在一小段延迟后保存到 EEPROM在 LCD 上再次有一个“PriceList”,有 4 个价格,但有“newPrice1”
6)用户按下键“2”
7)在 LCD 上:“请输入新价格 2”,用户为新的“newPrice2”设置一些新数字
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);
    }
  }
}
于 2019-08-28T17:46:40.020 回答
0

让我们分析一下你的循环代码:

  1. 循环的开始看起来不错。静态变量userinput, count将保留其值(重要)和变量countnumber并将在每个新循环(OK)时归零。
  2. case '#'中,您可能想清除所有内容并准备接收新号码。擦除该number=(userinput, 0, sizeof(userinput));行,因为这不是您设置变量值的方式,而且您不想将“#”作为输入数字。新输入的数字将保存到您的userinput阵列中,default以防万一。
  3. case 'A'中,您将变量写入 EEPROM。正确的(基本)方法是(在你的情况下)EEPROM.write(count, key)。您还应该在写入 EEPROM 存储器后延迟 4 毫秒(在 EEPROM 存储器中写入一个字节需要 3.3 毫秒)。我还建议使用 functionEEPROM.update(0)而不是EEPROM.write(0). 看这里为什么。我的另一个建议是在输入所有 10 位数字后执行 EEPROM 写入操作——如果用户没有正确输入数字(例如按“#”),您将节省一些 EEPROM 写入周期...
  4. 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;
    

    我还没有测试过这个,更多的是关于如何去做的想法。

  5. case '*', 我不确定你想做什么 - 从你的描述中不清楚。我认为您只想打印出userinput数组中的数字。这可以通过与 类似的方式完成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;
    
  6. case 'default'中,您将最后输入的数字保存到userinput数组中。还行吧。
于 2019-08-26T19:00:57.280 回答