Keypad not responsive, loop takes too long

Hi,

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?

Get rid of the delays. It's not the calculations that's taking the time.

Mark

Would be glad to help. But will need to see the code in order to figure out what's wrong with it.

Please use code tags when you do post it.

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);
}

Capture the millis() before and after you call the measure() function.
Then you will know how many milliseconds it takes to execute measure().

Where is your Loop() function?

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.

--Doug