I made myself a measuring device out of an Arduino with external ADC and LCD, EEPROM and Keypad.
I'm using the provided keypad-library for Arduino (arduino.cc/playground/uploads/Code/keypad.zip).
The problem is, that when measuring I'm havin lots of calculations in functions which slow the main loop down to about 0.8 seconds per loop.
The keypad gets irresposive because of that.
Could someone please show me a way to get around this? Fiddle with the debounce time?
Ok. I'm somewhat hesitant to actually present code, because I'm pretty messy when it comes to that. I'll only post the measuring function that gets called from the main loop plus its subfunctions.
In the main loop I check the keyboard like this:
char key = keypad.getKey();
if (key != NO_KEY){
lastkey=key;
The measuring function gets called from the main loop according to the menu point selected by pressing the corresponding key. Everything works fine, but obviously I'm having problems to leave the measuring menu point since I have to press the keyboard several times until it finally recognizes what I'm doing. All othe menu items are working easily, but they're not that loaded.
Here's the code. I know it's not beautiful - sorry about that.... I guess it's the for-loops that brake it down.
void measure (){
unsigned int maximum,minimum,messarray[100];
double helper;
cycleData(NULLP);
getoffset();
maximum = cycleData(MESS_1);
if(maximum>offset) maximum-=offset;
else maximum=0;
if ((maximum < (65000-offset))&&(switcher<50)){
minimum=cycleData(MESS_2);//mess1
if(minimum>offset) minimum-=offset;
else minimum=1;
if (minimum>5000)vfak=(double)maximum/(double)minimum;
else vfak=11.9;
for (int i=0;i<100;i++){
messarray[i]=cycleData(MESS_2);//mess2
if (messarray[i]<offset) messarray[i]=0;
else messarray[i]=messarray[i]-offset;
}
m_value=flatten(messarray,100);
helper=(double)m_value/vfak;
m_value=(unsigned long)(helper+.5);
cycleData(MESS_1);//mess2
}
else {
if (switcher==50)offset=0;
cycleData(MESS_1);//mess1
for (int i=0;i<100;i++){
messarray[i]=cycleData(MESS_1);//mess1
if (messarray[i]<offset) messarray[i]=0;
else messarray[i]=messarray[i]-offset;
}
m_value=flatten(messarray,100);
}
}
void getoffset(){
offset=0;
for (int i=0;i<19;i++){
offset+=cycleData(NULLP);
}
offset+=cycleData(MESS_2);
offset=offset/20;
}
unsigned int flatten(unsigned int *array, int length)
{
int i, j;
long helpval=0;
//Sort Array
for (i = 0; i < length -1; ++i)
{
for (j = 0; j < length - i - 1; ++j)
{
if (array[j] > array[j + 1])
{
int tmp = array[j];
array[j] = array[j + 1];
array[j + 1] = tmp;
}
}
}
//cut extremes
for (int i=31;i<71;i++){
helpval+=(array[i]);
}
helpval = (long)(helpval/40);
return((unsigned int)helpval);
}
void writetolcd(unsigned long mw){
double result;
byte digits;
if (mw>65535)mw=1;
result = (double)mw;
result = result/umfak;
lcd.setCursor(0,1);
if((result<10)||(result>999.994)){
lcd.print(" ");
}
digits=0;
if(result<1000) digits=1;
if(result<100) digits=2;
if(result<10) digits=3;//added
if ((umfak<666)&&(digits>2)) digits=2;
if ((umfak<66)&&(digits>1)) digits=1;
if (umfak<6.6) {
digits=0;
if (result<1000) lcd.print(" ");
if (result<100) lcd.print(" ");
}
lcdPrintDouble(result,digits);
lcd.print(" ");
}
void lcdPrintDouble( double val, byte precision){
if(val < 0.0){
lcd.print('-');
val = -val;
}
lcd.print (int(val));
if( precision > 0) {
lcd.print(".");
unsigned long frac;
unsigned long mult = 1;
byte padding = precision -1;
while(precision--)
mult *=10;
if(val >= 0)
frac = (val - int(val)) * mult;
else
frac = (int(val)- val ) * mult;
unsigned long frac1 = frac;
while( frac1 /= 10 )
padding--;
while( padding--)
lcd.print("0");
lcd.print(frac,DEC) ;
}
}
void writeunit(int nummer){
switch (nummer) {
case 0:
{
lcd.setCursor(8,1);
lcd.print("klx");
break;
}
case 9:
{
lcd.setCursor(8,1);
lcd.print("klx");
break;
}
case 3:
{
lcd.setCursor(8,1);
lcd.write(0);
lcd.print("W/m");
lcd.write(1);
break;
}
case 10:
{
lcd.setCursor(8,1);
lcd.print("lx");
break;
}
case 6:
{
lcd.setCursor(8,1);
lcd.write(0);
lcd.print("mol/sm");
lcd.write(1);
break;
}
case 50:
{
lcd.setCursor(8,1);
lcd.print(" ");
lcd.setCursor(8,1);
lcd.print("mV");
break;
}
default:
{
lcd.setCursor(8,1);
lcd.print("W/m");
lcd.write(1);
break;
}
}
}
unsigned int cycleData(byte channelNo) {
byte inByte = 0; // incoming byte from the SPI
unsigned int result = 0; // result to return
// take the chip select low to select the device:
digitalWrite(chipSelectPin, LOW);
delay(10);
result = SPI.transfer(channelNo); //Send request
result = result << 8; //shift byte
inByte = SPI.transfer(0x00);//send empty byte to fetch byte
result = result | inByte;//combine
digitalWrite(chipSelectPin, HIGH);//deselect slave
return(result);
}
Any time somebody posts a snippet, they post the working code which they understand. 90% of the time the problem is in the code they didn't post. We seriously have to see ALL the code to make a reasonable diagnosis.
If your code is messy, use the auto-format tool to clean it up. I used to be afraid of the tool because other ones I've seen in the past screw up my code. The Arduino one is actually EXTREMELY good at making your code conform to conventions without messing up anything.
If your code is long, make a new version that is stripped down to the minimum possible length which still exhibits the original problem. This method will often make the problem clear to you. There's probably a few dozen forum posts I HAVEN'T made because the process of writing the post showed me my own problem.
I'll also add, that cleaning up your code is a great first step toward debugging it. The process of methodically looking over your code, fixing comments, improving variable names, improving the style/structure, etc. will often lead you directly to the problem.
It can be like looking for a tool in a jumbled box of tools. Simply organizing them will help you find what you are looking for.