Keypad Output Selection Code

Hello all,

I have a project where I am using an Arduino with an LCD screen, and keypad. The idea is pretty simple, but my coding project is fairly weak. The idea is I want to have an Arduino capable of outputting multiple voltages to digital pins D10 - D13.

The user should be able to hit ‘A’ on the keypad which would bring him/her to a menu option to select which Output they would like to control (1-4). They should be able to hit 1 - 4 and it will control the corresponding pins. If they select anything other than the correct output value it should give them an error, and reset the selection.

Now, once the correct output is selected, then they should be able to input a voltage for that pin, something between 0 - 5, and again an error will appear if they select anything over 5.

They should also be able to run multiple outputs at once, for example:

If they want Output 1 and 4 on they should be able to select output 1, turn it on at a specific voltage, and go through and select 4 without turning 1 off.

I have this working with a single output, but incorporating additional controllable outputs is confusing me.

// include the library code:
#include <LiquidCrystal.h>
#include <Keypad.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','.'}
};

byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad



Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

// Global variables
byte index = 0;
char numbers[20]; // Plenty to store a representation of a float


long outPut = 10;      // LED connected to digital pin 9


void setup()
{
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Setting up...");
  delay(1000);
  lcd.clear();
  lcd.print("Initializing");
  lcd.setCursor(0,2);
  lcd.print("Voltage..."); 
  delay(5000);
  lcd.clear();
  lcd.print("Voltage Set.");
  
  delay(1000);
  lcd.clear();
  lcd.print("Ready to use.");
  delay(1000);
  lcd.clear();
 
  
 Serial.begin(9600);
 pinMode(outPut, OUTPUT);   // sets the pin as output
 
 delay(500);
 lcd.clear();
}

void loop()
{
 
   char key = keypad.getKey();
  
   if(key != NO_KEY)
   {
       Serial.println("Key Pressed: ");
       Serial.print(key);
       Serial.println();
       lcd.print(key);
       
    
       
      if(key == 'C')
      {
         index = 0;
         numbers[index] = '\0';
         lcd.clear();
      }
      else if(key == '.')
      {
         numbers[index++] = '.';
         numbers[index] = '\0';       
      }
      else if(key >= '0' && key <= '9')
      {
         numbers[index++] = key;
         numbers[index] = '\0';
      }
      else if(key == '#')
      {
         float len = atof(numbers);
         long voltage = (1023/5) * len;
         long voltage2 = voltage / 4;
         
         // Do whatever you need to with len
         if(len > 5)
         {
           lcd.clear();
           lcd.print("Error!");
           lcd.setCursor(0,1);
           lcd.print("Voltage reset.");
           analogWrite(outPut, 0);
         }
         else
         {
         Serial.print("Numbers: ");
         Serial.println(numbers);
         Serial.print("Len: ");
         Serial.println(len);
         lcd.clear();
         lcd.setCursor(0,1);
         lcd.print("Voltage: ");
         lcd.print(len);
         lcd.print("V");
         
         voltage = (1023/5) * len;
         voltage2 = voltage / 4;
         analogWrite(outPut, voltage2);
         
         index = 0;
         numbers[index] = '\0';
         lcd.setCursor(0,0);
         lcd.print("Entered: ");
         lcd.print(numbers);
         }


      }
   }
}

Single Output code above.

// include the library code:
#include <LiquidCrystal.h>
#include <Keypad.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','.'}
};

byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad



Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

// Global variables
byte index = 0;
char numbers[20]; // Plenty to store a representation of a float

int outPutChan;


long outPut1 = 10;     
long outPut2 = 11;
long outPut3 = 12;
long outPut4 = 13;


void setup()
{
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Setting up...");
  delay(1000);
  lcd.clear();
  lcd.print("Initializing");
  lcd.setCursor(0,2);
  lcd.print("Voltage..."); 
  delay(5000);
  lcd.clear();
  lcd.print("Voltage Set.");
  
  delay(1000);
  lcd.clear();
  lcd.print("Ready to use.");
  delay(1000);
  lcd.clear();
 
  
 Serial.begin(9600);
 pinMode(outPut1, OUTPUT);   // sets the pin as output
 pinMode(outPut2, OUTPUT);   // sets the pin as output
 pinMode(outPut3, OUTPUT);   // sets the pin as output
 pinMode(outPut4, OUTPUT);   // sets the pin as output
 
 delay(500);
 lcd.clear();
}

void loop()
{
 
   char key = keypad.getKey();
  
   if(key != NO_KEY)
   {
       Serial.println("Key Pressed: ");
       Serial.print(key);
       Serial.println();
       lcd.print(key);
       
    
         if(key == 'A')
      {
        int newLen = atof(numbers);
        lcd.clear();
        lcd.print("Select Output: ");
        //lcd.print(numbers);
        outPutChan = newLen;
        
        if(outPutChan > 4)
        {
          lcd.clear();
          lcd.print("Error, reset");
        }
        else
        {
          lcd.clear();
          lcd.print("Channel: ");
          lcd.print(newLen);
        }
        
      
      }
      
      if(key == 'C')
      {
         index = 0;
         numbers[index] = '\0';
         lcd.clear();
      }
      else if(key == '.')
      {
         numbers[index++] = '.';
         numbers[index] = '\0';       
      }
      else if(key >= '0' && key <= '9')
      {
         numbers[index++] = key;
         numbers[index] = '\0';
      }

      else if(key == '#')
      {
         float len = atof(numbers);
         long voltage = (1023/5) * len;
         long voltage2 = voltage / 4;
         
         // Do whatever you need to with len
         if(len > 5)
         {
           lcd.clear();
           lcd.print("Error!");
           lcd.setCursor(0,1);
           lcd.print("Voltage reset.");
           //analogWrite(outPut, 0);
         }
         else
         {
         Serial.print("Numbers: ");
         Serial.println(numbers);
         Serial.print("Len: ");
         Serial.println(len);
         lcd.clear();
         lcd.setCursor(0,1);
         lcd.print("Voltage: ");
         lcd.print(len);
         lcd.print("V");
         
         voltage = (1023/5) * len;
         voltage2 = voltage / 4;
         //analogWrite(outPut, voltage2);
         
         index = 0;
         numbers[index] = '\0';
         lcd.setCursor(0,0);
         lcd.print("Entered: ");
         lcd.print(numbers);
         }


      }
   }
}

Attempted multiple output code

The idea is I want to have an Arduino capable of outputting multiple voltages to digital pins D10 - D13

This is not possible, the output of the digital pins is either LOW (0 V) or HIGH (5 V). AnalogWrite uses pwm which only works on specific pins and give an impression of a specific average voltage. If you have a led connected that's fine it will flicker at a certain pace which gives the illusion of more or less brightness.

J-M-L:
This is not possible, the output of the digital pins is either LOW (0 V) or HIGH (5 V). AnalogWrite uses pwm which only works on specific pins

Then how about using only pins 10 and 11, those are capable of PWM.

Where do you deal with the various modes (states) of your explanation? You need to memorize if you are waiting for a command, selecting a pin, entering a "voltage"

J-M-L:
Where do you deal with the various modes (states) of your explanation? You need to memorize if you are waiting for a command, selecting a pin, entering a "voltage"

Coding it out I am not so great, but I understand what you are saying...

Essentially the program will boot-up, and wait for a command.
I think maybe, I could assign 'A' and 'B' to outPut1 and outPut2, and based on which is select the user can control the output?

If I select 'A' I am assigning whatever input to that pin after I hit '#', and if I select 'B' I am assigning output 2 the same way. Will this be easier?

and could I use a case statement to do this?

switch (key)
           {
             case 'A':
                       Serial.print("Numbers: ");
                       Serial.println(numbers);
                       Serial.print("Len: ");
                       Serial.println(len);
                       lcd.clear();
                       lcd.setCursor(0,1);
                       lcd.print("Voltage: ");
                       lcd.print(len);
                       lcd.print("V");
         
                       voltage = (1023/5) * len;
                       voltage2 = voltage / 4;
                       analogWrite(outPut1, voltage2);
         
                       index = 0;
                       numbers[index] = '\0';
                       lcd.setCursor(0,0);
                       lcd.print("Entered: ");
                       lcd.print(numbers);
                       break;
              case 'B':
                    Serial.print("Numbers: ");
                       Serial.println(numbers);
                       Serial.print("Len: ");
                       Serial.println(len);
                       lcd.clear();
                       lcd.setCursor(0,1);
                       lcd.print("Voltage: ");
                       lcd.print(len);
                       lcd.print("V");
         
                       voltage = (1023/5) * len;
                       voltage2 = voltage / 4;
                       analogWrite(outPut2, voltage2);
         
                       index = 0;
                       numbers[index] = '\0';
                       lcd.setCursor(0,0);
                       lcd.print("Entered: ");
                       lcd.print(numbers);
                       break;
                default: 
                      // if nothing else matches, do the default
                      // default is optional
                      analogWrite(outPut1, 0);
                      analogWrite(outPut2, 0);
                      
                      break;
         }

Here I am trying to implement the switchcase statement in the code, but it is unsuccessful

  else if(key == '#')
      {
         float len = atof(numbers);
         long voltage = (1023/5) * len;
         long voltage2 = voltage / 4;
         
         
          switch (key)
           {
             case 'A':
                   
         // Do whatever you need to with len
         if(len > 5)
         {
           lcd.clear();
           lcd.print("Error!");
           lcd.setCursor(0,1);
           lcd.print("Voltage reset.");
           analogWrite(outPut1, 0);
         }
         else
         {
           
                       Serial.print("Numbers: ");
                       Serial.println(numbers);
                       Serial.print("Len: ");
                       Serial.println(len);
                       lcd.clear();
                       lcd.setCursor(0,1);
                       lcd.print("Voltage: ");
                       lcd.print(len);
                       lcd.print("V");
         
                       voltage = (1023/5) * len;
                       voltage2 = voltage / 4;
                       analogWrite(outPut1, voltage2);
         
                       index = 0;
                       numbers[index] = '\0';
                       lcd.setCursor(0,0);
                       lcd.print("Entered: ");
                       lcd.print(numbers);

          
         }

                       break;
              case 'B':
                         
         // Do whatever you need to with len
         if(len > 5)
         {
           lcd.clear();
           lcd.print("Error!");
           lcd.setCursor(0,1);
           lcd.print("Voltage reset.");
           analogWrite(outPut2, 0);
         }
         else
         {
           
                       Serial.print("Numbers: ");
                       Serial.println(numbers);
                       Serial.print("Len: ");
                       Serial.println(len);
                       lcd.clear();
                       lcd.setCursor(0,1);
                       lcd.print("Voltage: ");
                       lcd.print(len);
                       lcd.print("V");
         
                       voltage = (1023/5) * len;
                       voltage2 = voltage / 4;
                       analogWrite(outPut2, voltage2);
         
                       index = 0;
                       numbers[index] = '\0';
                       lcd.setCursor(0,0);
                       lcd.print("Entered: ");
                       lcd.print(numbers);

          
         }

                       break;
                default: 
                      // if nothing else matches, do the default
                      // default is optional
                      analogWrite(outPut1, 0);
                      analogWrite(outPut2, 0);
                      
                      break;
                      
           }
         


      }
      
      
   }