Parameter Edit, Save, Recall

When building instruments using MCUs one of the most common requirement is to provide a functionality for the user to call up a value, change it and save it back to EEPROM for further use in the code.

Lets say i want to edit a value like 1234.5 And lets assume i have a LCD for user interface. And editing is done with only three buttons : INCREMENT / SHIFT / ENTER

Option A :

I define a Union of a Long and char array in the EEPROM with 8 elements. When required read all eight elements, discard three elements and display with a simulated decimal. Index the cursor to the MSB of the value and blink it there. User uses the INCREMENT button to change the value. Rolls over to 0 after 9. User then uses SHIFT to change the next digit and so on. Finally when ENTER is pressed i save all the five elements to EEPROM. And in the code I just read the long variable from EEPROM and do something with it.

Option B : Use INCREMENT / DECREMENT / ENTER buttons

Store the required variable as a float in the EEPROM. To edit value, call the variable and display it. User uses the INCREMENT or DECREMENT button to modify. Each step is 0.1 in value. Save the displayed value upon ENTER. The only problem with this method is the time taken for large changes - user has to keep the button pressed. Or i have to implement a multispeed increment logic - if the user keeps a button pressed for more than 5 seconds i double the rate of change and so on.

Apart from above are there any other methods which are simple to use ? Particularly for large numbers. Normally for single or two digit parameters , the INC /DEC/ENT method is just fine.

Any ideas welcome.

Thanks

I define a Union of a Long and char array in the EEPROM with 8 elements.

Why 8? Why char? Why long? A float, on most Arduinos, is 4 bytes. So is a long.

Finally when ENTER is pressed i save all the five elements to EEPROM.

After reading 8? Why?

And in the code I just read the long variable from EEPROM and do something with it.

If you write characters to the EEPROM, you can't read them as a long with any existing function in the EEPROM class. In any case, 1234.5 is not a long.

Hmmm… lots of why !! Sorry … many mistakes in framing the post… was messing with nibbles on another code.

I do have done a code with such a concept of saving a value as an integer and then while editing calling each digit separately … its part of a big code but providing the EDIT mode alone here… its pretty simple though. Uses the INC/SHIFT/ENTER buttons only . User selection of button passed via ValidDIN :

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

//Function to convert an int to char array and store .
//Range is 1 digit to 4 digits.
void int_to_byte0( int intValue) {
  Par0_Array[0] = (intValue / 1000) + 48; // Add decimal 48 to convert numeric to ASCII
  Par0_Array[1] = ((intValue % 1000) / 100) + 48;
  Par0_Array[2] = (((intValue % 1000) % 100) / 10) + 48;
  Par0_Array[3] = (((intValue % 1000) % 100) % 10) + 48;
  Par0_Array[4] = '\n';                // Null terminate to use in atoi()
}

void int_to_byte1( int intValue) {
  Par1_Array[0] = (intValue / 1000) + 48; // Add decimal 48 to convert numeric to ASCII
  Par1_Array[1] = ((intValue % 1000) / 100) + 48;
  Par1_Array[2] = (((intValue % 1000) % 100) / 10) + 48;
  Par1_Array[3] = (((intValue % 1000) % 100) % 10) + 48;
  Par1_Array[4] = '\n';                // Null terminate to use in atoi()
}

void int_to_byte2( int intValue) {
  Par2_Array[0] = (intValue / 1000) + 48; // Add decimal 48 to convert numeric to ASCII
  Par2_Array[1] = ((intValue % 1000) / 100) + 48;
  Par2_Array[2] = (((intValue % 1000) % 100) / 10) + 48;
  Par2_Array[3] = (((intValue % 1000) % 100) % 10) + 48;
  Par2_Array[4] = '\n';                // Null terminate to use in atoi()
}
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

// FUNCTION TO VALIDATE USER PARAMS READ FROM EEPROM
boolean validateParams() {
  boolean faultState = false;
  EEPROM.get(eeAdd, userParam);
  if ( userParam.minPress < 10 || userParam.minPress > 50) {
    lcd.clear();
    lcd.print ( "MIN PRESS FAULT");
    lcd.setCursor(0, 1);
    lcd.print ( "CHOOSE EDIT MODE");
    faultState = true ;
  }
  if ( userParam.maxPress < 20 || userParam.maxPress > 200 && faultState == false) {
    lcd.clear();
    lcd.print ( "MAX PRESS FAULT");
    lcd.setCursor(0, 1);
    lcd.print ( "CHOOSE EDIT MODE");
    faultState = true ;
  }
  if ( userParam.wdtInterval < 500 || userParam.wdtInterval > 9500 && faultState == false) {
    lcd.clear();
    lcd.print ( "WDT INTVL FAULT");
    lcd.setCursor(0, 1);
    lcd.print ( "CHOOSE EDIT MODE");
    faultState = true ;
  }
  if (faultState == true) return 1;
  else return 0;
}

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

// FUNCTION TO MOVE THE CURSOR BASED ON SHIFT KEY INPUT

void movCursor(byte left , byte right) {
  if ( ValidDIN == 'S') {
    curPosition++ ;
    arrayLoc = curPosition - left;                        // Dynamic Array Location to increment
    if ( curPosition > right ) curPosition = left;
  }
}

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

// FUNCTION TO INCREMENT THE CHOSEN DIGIT

void incValue0() {
  if ( ValidDIN == 'I') {
    Par0_Array[arrayLoc]++;
    if ( Par0_Array[arrayLoc] > '9') Par0_Array[arrayLoc] = '0';
  }
}

void incValue1() {
  if ( ValidDIN == 'I') {
    Par1_Array[arrayLoc]++;
    if ( Par1_Array[arrayLoc] > '9') Par1_Array[arrayLoc] = '0';
  }
}

void incValue2() {
  if ( ValidDIN == 'I') {
    Par2_Array[arrayLoc]++;
    if ( Par2_Array[arrayLoc] > '9') Par2_Array[arrayLoc] = '0';
  }
}
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

// FUNCTION TO EDIT USER PARAMETERS AND SAVE TO EEPROM

void EditSysParams() {

  if ( editFlag0 == 1 ) {                                // EDIT PARAMETER 0
    HomeDisp_Gate = 0;
    EEPROM.get(eeAdd, userParam);                        // Read the UserParam from EEPROM
    copyMinPress = userParam.minPress;                   // Load into Temporary variables
    copyMaxPress = userParam.maxPress;
    copywdtInterval = userParam.wdtInterval;
    int_to_byte0( copyMinPress);                          // Convert the digits of first param to ASCII chars for editing.
    curPosition = 10;                                     // Move the cursor to right spot on LCD
    lcd.cursor();
    editFlag0 = 0;
    editFlag1 = 1;
  }

  if ( editFlag1 == 1) {
    movCursor(10, 13);
    lcd.clear();
    sprintf(LCDmsg, "MIN.BAR : %c%c%c%c", Par0_Array[0], Par0_Array[1], Par0_Array[2], Par0_Array[3]);
    lcd.print(LCDmsg);
    lcd.setCursor (curPosition, 0);                      // Display number and THEN position cursor
    incValue0();
    if ( ValidDIN == 'E') {
      ValidDIN = '0';
      userParam.minPress = atoi(Par0_Array);
      curPosition = 10;
      editFlag1 = 0;
      editFlag2 = 1;
      int_to_byte1( copyMaxPress);                        // Convert the digits of second param to ASCII chars for editing
    }
  }

  if ( editFlag2 == 1) {                                   // EDIT PARAMETER 1
    movCursor(10, 13);
    lcd.clear();
    sprintf(LCDmsg, "MAX.BAR : %c%c%c%c", Par1_Array[0], Par1_Array[1], Par1_Array[2], Par1_Array[3]);
    lcd.print(LCDmsg);
    lcd.setCursor (curPosition, 0);                      // Display number and THEN position cursor
    incValue1();
    if ( ValidDIN == 'E') {
      ValidDIN = '0';
      userParam.maxPress = atoi(Par1_Array);             // Convert back to int for saving
      curPosition = 10;
      editFlag2 = 0;
      editFlag3 = 1;
      int_to_byte2( copywdtInterval);                        // Convert the digits of Third param to ASCII chars for editing
    }
  }

  if ( editFlag3 == 1) {                                 // EDIT PARAMETER 2
    movCursor(10, 13);
    lcd.clear();
    sprintf(LCDmsg, "WDT.MSEC: %c%c%c%c", Par2_Array[0], Par2_Array[1], Par2_Array[2], Par2_Array[3]);
    lcd.print(LCDmsg);
    lcd.setCursor (curPosition, 0);                      // Display number and THEN position cursor
    incValue2();
    if ( ValidDIN == 'E') {
      ValidDIN = '0';
      userParam.wdtInterval = atoi(Par2_Array);
      EEPROM.put(eeAdd, userParam);                      // Save the values to EEPROM
      lcd.clear();
      lcd.print( "DATA SAVED !!");
      delay (2000);
      editFlag3 = 0;
      EM_Flag = 0;                                       // End of Edit Mode...
      HomeDisp_Gate = 1;
    }
  }
}