Hi all,
I am trying to do the temperature sensing system with the possibility to set alarm tresholds via 4x4 matrix keypad.
In the loop() function there is a lot of things going on: quering the temperature sensors, displaying the temperatures and time on LCD and so on.
But I want to add the functionality that when I press A, B, C or D at the keypad, the program goes to data collection function (to get and set the temperature alarm treshold values)
I discovered that even if I use keypadEvent, I have to have the button pressed on the very precise moment of the loop() when keypad.getKey() function is invoked, otherwise there will be no event noticed.
I can live with the delay (if I press the button during temperature mesurement function and then will go to data collection after whole loop() is completed), but it simply does not work if the button is not hit precisely during getKey().
Any advice?
Thanks.
My code fragments below:
void setup (){
//init stuff
//add keypad event
keypad.addEventListener(keypadEvent);
}
void loop (){
char key = keypad.getKey();
sensors.requestTemperatures();
//here goes the temp gathering, it takes about 500 ms
//here goes LCD display with the current temp values
}
void keypadEvent(KeypadEvent key){
switch (keypad.getState()){
case PRESSED :
switch (key){
case 'A': SetTempAlarms(); break;
case 'B': ResetTempAlarms(); break;
case 'C': SetTimeAlarms(); break;
case 'D': ResetTimeAlarms(); break;
break;
}
break;
}
}
sensors.requestTemperatures();
//here goes the temp gathering, it takes about 500 ms
Or add some diodes from the keypad such that when any key is pressed you generate an interrupt that you can use. You'll likely have to add to your code to set all the columns low, and pull the row inputs high, with a diode from the row pins (cathode) and the anodes connected together to an interrupt pin that is pulled up. When a button is pressed, the column low pulls the row signal low, causes an interrupt. The interrupt routine then writes the columns high, calls the keypad library which does the scanning to find the button press. Then you do whatever the button does, write the columns low again, and go back to them 500mS temperature conversion.
Normally, one would say that posting code fragments is not helpful, but I think this can all be fixed by yourself with the correct approach.
pk3arduino:
Any advice?
Yep. Here is the problem:
pk3arduino:
//here goes the temp gathering, it takes about 500 ms
Your loop(code) is wrongly designed. You need to break it up into alternate paths (switch) so that each pass of the loop gathers only one measurement at a time, thus the loop "cycles" hundreds if not thousands of times per second, and each time, polls the keyboard (which in itself is extremely fast though the library you cite may itself not be properly designed to do so - it should involve no delay either).
Part of the secret is to split time-consuming tasks "across" the loop - if for example you have to set up an analog read and wait for a result, then setting it up is the last thing you do in that part of the loop, and getting the result - if and only if it is ready - is the first thing you do on the next pass through that part of the loop.
Unfortunately, many of the libraries are "play" code, nice for simple demonstrations, but not necessarily suitable for the degree of performance you are expecting. Some of this is discussed in the "Blink without delay" discussion.