two things i need help with.

Hello everybody!

First post here, :cold_sweat:.

Anyway, what i came here for is two things in my program that dosent execute as i think it should.

1. The program has to make a full repeat before it outputs the calculated values, why?
I want it to output them directly as they are called, but it returns zero until a another full program loop has occured. Does this have to do with the getnumbers() function?

2. As you might see, i have changed the "*" on the keypad to represent "." for my float values. but the calculations i've tried with a "." end up skewed, eg 1,25 + 135 / 2 should equal 1,3 but gave me 830~ something. does this have to do with char representation or am i missing something?

Everything else works just as i want it.

#include <Keypad.h>
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

const byte rows = 4; //four rows
const byte cols = 3; //three columns
char keys[rows][cols] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'.','0','#'}
};
byte rowPins[rows] = {1, 2, 3, 4}; //connect to the row pinouts of the keypad
byte colPins[cols] = {5, 6, 7}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols );

float startDensity;
float endDensity;
float startPulses;
float endPulses;
float avgPulses;
float avgDensity;

void setup() {
  // Give startup feedback 
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Densitet's");
  lcd.setCursor(0, 1);
  lcd.print("Kalibrering");
  delay(1000);
  lcd.print(".");
  delay(1000);
  lcd.print(".");
  delay(1000);
  lcd.print(".");
  delay(1000);
  lcd.print(".");
  delay(1000);
  lcd.print(".");
  delay(1000);
  lcd.clear();

}

void loop() {
  //display feedback for user
  lcd.setCursor(0, 0);
  lcd.print("Start");
  lcd.setCursor(0, 1);
  lcd.print("Densitet");
  delay(1500);
  lcd.clear();
  lcd.setCursor(0, 0);
  delay(500);
  lcd.print("G/CM3:"); 
  lcd.setCursor(0, 1);
  
  startDensity = getNumbers();
   
   lcd.setCursor(0, 0);
   lcd.print("Start");
   lcd.setCursor(0, 1);
   lcd.print("Pulser");
   delay(1500);
   lcd.clear();
   lcd.setCursor(0, 0);
   delay(500);
   lcd.print("CPS:");
   lcd.setCursor(5, 1);
  
  startPulses = getNumbers();
  
   lcd.clear();
   delay(500);  
   lcd.setCursor(0, 0);
   lcd.print("Slut");
   lcd.setCursor(0, 1);
   lcd.print("Pulser");
   delay(1500);
   lcd.clear();
   lcd.setCursor(0, 0);
   delay(500);
   lcd.print("CPS:");
   lcd.setCursor(5, 1);
   
  endPulses = getNumbers();
  
  lcd.clear();
  delay(500); 
  lcd.setCursor(0, 0);
  lcd.print("slut");
  lcd.setCursor(0, 1);
  lcd.print("Densitet");
  delay(1500);
  lcd.clear();
  lcd.setCursor(0, 0);
  delay(500);
  lcd.print("G/CM3:"); 
  lcd.setCursor(0, 1);
  
  endDensity = getNumbers();
  
  //Display calculated values for user
  lcd.clear();
  delay(2000);
  lcd.setCursor(0, 0);
  lcd.print("Medel densitet:");
  delay(1000);
  lcd.setCursor(0, 1);
  lcd.print(avgDensity);
  delay(10000);
  lcd.clear();
  lcd.setCursor(0, 0);
  delay(500);
  lcd.print("Medel Pulser:");
  delay(1000);
  lcd.setCursor(0, 1);
  lcd.print(avgPulses);
  delay(10000);
  lcd.clear();
  delay(3000);
  
}
//Keypad input for user
float getNumbers()
{

   float num = 0;
   char key = keypad.getKey();
   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;

         case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
         case '.':
            lcd.print(key);
            num = num * 10 + (key - '0');
            break;

         case '#':
            lcd.clear();
            break;
      }

      key = keypad.getKey();
   }

   return num;
   
}

the getNumbers() is from this forum :wink:
Appriciate any help i can get with understanding this, thanks!

         case '.':
            lcd.print(key);
            num = num * 10 + (key - '0');

What, exactly, is '.' - '0'? I seriously doubt that the . case should perform this action.

The program has to make a full repeat before it outputs the calculated values, why?

What does this mean?

         case NO_KEY:
            break;

Is this really what you want to do?

Well, the first you as you say i too doubt it, so i removed it from the rest of numbers and made it a seperate case, but i have no idea what to write in that case to get it to add a dot.

the thing with "that it needs a full rerun of the loop" meant that the values that i entered, got calculated the next time it went trough the inputs and displayed.

and somehow my calculated floats vanished in the posted code, but i fixed it, and that part works now

 endDensity = getNumbers();
  
  float avgDensity = (startDensity + endDensity)/2;
  float avgPulses = (startPulses + endPulses)/2;

it might have been that it had those variables at the top/start of the loop()?

the last thing you pointed out, i removed and it had no effect?
i've been googling like a maniac and i just dont get what NO_KEY means, i've seen several post by you on keypad's about it, but i cant seem to comprehend what it means :(. same thing with

char key = keypad.getKey():
if (key !=NO_KEY)

i would be glad if you could explain it to me, or atleast point me in the right direction.

Thanks for the help!

Well, the first you as you say i too doubt it, so i removed it from the rest of numbers and made it a seperate case, but i have no idea what to write in that case to get it to add a dot.

There is a lot more to processing floats than "adding a dot". You need to process the number in two parts - the part before the decimal point and the part after. The . simply tells you when to switch from processing the before part to processing the after part.

PaulS:

Well, the first you as you say i too doubt it, so i removed it from the rest of numbers and made it a seperate case, but i have no idea what to write in that case to get it to add a dot.

There is a lot more to processing floats than "adding a dot". You need to process the number in two parts - the part before the decimal point and the part after. The . simply tells you when to switch from processing the before part to processing the after part.

So i guess im out on thin ice, or deep waters.
i guess i could make it easy and just tell the user with the lcd to write the density without the dot.

any help on the NO_KEY part?

Big thanks again!

So i guess im out on thin ice, or deep waters.
i guess i could make it easy and just tell the user with the lcd to write the density without the dot.

Just collect all the key values in an char array, NULL terminated, and use atof().

any help on the NO_KEY part?

I'm not sure what help you need. I don't understand why you were breaking out of the loop when no key was pressed. That will be the most common condition when the loop is executed.

getKey is non blocking, so your sketch can do other things while periodically checking for activity on the keypad.

In consequence, it needs a way to tell you that nothing was pressed when you checked. NO_KEY is what is returned in this circumstance. Code that does something with keypad input therefore, tends to be guarded with something like the snippet you quoted above:

char key = keypad.getKey();
if (key !=NO_KEY)