Need Arduino to be Faster.

Hey all,

I am building a proximity capacitive sensor for my dissertation. Currently I using the capsense library for capacitive sensors code. I am currently running about 11 sensor from my Arduino Mega 2560. When I run about 3 or 4 sensors the reading are fast. But now that I am running 11 sensor the reading are extremely slow. Is there anyway to counter the issues ? here’s the sketch

#include <CapacitiveSensor.h>
#include <SPI.h>



CapacitiveSensor   cs_4_6 = CapacitiveSensor(4,6);
CapacitiveSensor   cs_30_28 = CapacitiveSensor(30,28);


CapacitiveSensor   cs_31_49 = CapacitiveSensor(31,49);
CapacitiveSensor   cs_31_47 = CapacitiveSensor(31,47);
CapacitiveSensor   cs_31_45 = CapacitiveSensor(31,45);
CapacitiveSensor   cs_31_43 = CapacitiveSensor(31,43);
CapacitiveSensor   cs_31_41 = CapacitiveSensor(31,41);
CapacitiveSensor   cs_31_39 = CapacitiveSensor(31,39);
CapacitiveSensor   cs_31_37 = CapacitiveSensor(31,37);
CapacitiveSensor   cs_31_35 = CapacitiveSensor(31,35);
CapacitiveSensor   cs_31_33 = CapacitiveSensor(31,33);


int cvout = 0;

int pitch = 0;




void setup()                    
{
   
    Serial.begin(9600);
    pinMode(10, OUTPUT);
    pinMode(26, OUTPUT);
    pinMode(42, OUTPUT); 
    SPI.begin();
    SPI.setBitOrder(MSBFIRST);
    
      
}


void loop()                    
{
    long start = millis();
    long total1 =  cs_4_6.capacitiveSensor(30);
    long total5 =  cs_30_28.capacitiveSensor(30);
    
     long c =  cs_31_49.capacitiveSensor(30);
      long d =  cs_31_47.capacitiveSensor(30);
       long e =  cs_31_45.capacitiveSensor(30);
        long f =  cs_31_43.capacitiveSensor(30);
         long g =  cs_31_41.capacitiveSensor(30);
          long a =  cs_31_39.capacitiveSensor(30);
           long b =  cs_31_37.capacitiveSensor(30);
            long cc =  cs_31_35.capacitiveSensor(30);
             long dd =  cs_31_33.capacitiveSensor(30);
    

    
 


    Serial.print(millis() - start);       
    Serial.print("\t");                   

    Serial.print(total1);
    Serial.print("\t");                   
 
    Serial.print(total5);   
    Serial.print("\t");  
    Serial.print(c);   
    Serial.print("\t");  
    Serial.print(d);   
    Serial.print("\t");  
    Serial.print(e);   
    Serial.print("\t");  
    Serial.print(f);   
    Serial.print("\t");  
    Serial.print(g);   
    Serial.print("\t");  
    Serial.print(a);   
    Serial.print("\t");  
    Serial.print(b);   
    Serial.print("\t");  
    Serial.print(cc);   
    Serial.print("\t");  
    Serial.print(total5);   
    Serial.println(dd);  

    
     
   int range = map(total5, 0, 3000, 0, 7);
   
   int pitch = 0;
   
   switch (range) {
  case 0:    // your hand is on the sensor
    pitch = 999;
    break;
  case 1:    // your hand is close to the sensor
    pitch = 1200;
    break;
  case 2:    // your hand is a few inches from the sensor
    pitch = 1500;
    break;
  case 3:    // your hand is nowhere near the sensor
    pitch = 2000;
    break;
    case 4:    // your hand is nowhere near the sensor
    pitch = 500;
    break;
    case 5:    // your hand is nowhere near the sensor
    pitch = 1400;
    break;
    case 6:    // your hand is nowhere near the sensor
    pitch = 4000;
    break;
    case 7:    // your hand is nowhere near the sensor
    pitch = 3500;
    break;
 
 } 
 
  
    byte commandByte = 0b00010000;
    int cv = 0x0FFF;
    cv = pitch;
   
    
    byte commandByte3 = 0b00010000;
    int led2 = 0x0FFF;
    led2 = total1;
    
    digitalWrite(10, LOW);
    SPI.transfer(commandByte | (highByte(cv) ) );
    SPI.transfer (lowByte (cv) ); 
    digitalWrite (10, HIGH);
 
    digitalWrite(26,LOW);
    SPI.transfer(commandByte3 | (highByte(led2) ) );
    SPI.transfer(lowByte(led2) );
    digitalWrite(26, HIGH);     

}

You do a lot of serial prints. Raise your baud rate (in begin) to 115200. May speed things up.

Alright thanks, I forgot to add that my arduino would work as a standalone. It's only for now that I'm using the serial print for the purpose of testing. Later on I would remove all the Serial.print.

Also do you think by setting a maximum and minumum values for the total(1,2,3,4,5) would help with the speed issues.

int cv = 0x0FFF;
    cv = pitch;

What's the point of that?

Increase your serial baud rate
Increase the SPI speed to 8MHz by using the SPI_CLOCK_DIV2 command (I think it defaults to 4MHz)
Direct port manipulation may shave a few ms too.

You are reading all the sensors in sequence, one at a time. It would be quicker to read them all in parallel. To do this, you will have to understand how the CapacitiveSense library works, then modify it to read all 11 sensors in the same loop, with just one timeout for all of them.

I contributed to another Thread a while back which had a sensor library (for weight, I think) that was slow to respond. It turned out that the sensor library blocked until data was available from the sensor but if you did not ask for the reading until after the data was ready it would send the answer back instantly. (I hope this makes sense).

Maybe the same logic applies to your system. Have look inside the Library code.

And this is probably closely consistent with @dc42 has suggested.

...R

It's only for now that I'm using the serial print for the purpose of testing. Later on I would remove all the Serial.print.

Is it still "slow" if you remove the Serial.print calls? Serial printing is very slow indeed if you are generating output faster than the serial port runs (at 9600bps, you're talking about 1ms per character output, or 40+ ms for the ten+ values you're printing.)

Wrap your Serial.print() calls in scaffolding code. For example:

#define DEBUG      // Place at top, just after all #includes

// ...more code...

void setup() {
  #ifdef DEBUG
    Serial.begin(115200);
  #endif

  // ...more code...

  #ifdef DEBUG
    Serial.print(millis() - start);       
    Serial.print("\t");                   

    Serial.print(total1);
    Serial.print("\t");          
  // ...more Serial.print() calls...
  #endif

Now, if you comment out the #define DEBUG at the top of the file, the Serial object is no longer compiled into the program. You can get better timing and code size data without having to search/add/remove a bunch of comment characters.

Hey all,

Thanks for all your inputs.

To AWOL

int cv = 0x0FFF;
    cv = pitch;

This is to send out the range of pitches to the DAC. The DAC is connected to an analog oscillator. Pitch gets its value from the switch function. So depending how far your hand is from the sensor it would decide which pitch to play. The switch function gets its value from total5( which is a proximity capacitive sensor).

I'm still pretty new to Arduino, so I'll see what I can do. Also another small question, is the anyway to write this code in a more efficient way. I have 24 switch cases. each to represent one note. So there are 24 switch cases to cover a range of two octaves on a keyboard. By implementing this code(see below), My arduino has decrease a little in speed.

switch (range) {
  case 0:    // your hand is on the sensor
    pitch = 0; //c
    break;
  case 1:    // your hand is close to the sensor
    pitch = 87;//c-
    break;
  case 2:    // your hand is a few inches from the sensor
    pitch = 171;//d
    break;
  case 3:    // your hand is nowhere near the sensor
    pitch = 255;//d-
    break;
    case 4:    // your hand is nowhere near the sensor
    pitch = 340;//e
    break;
    case 5:    // your hand is nowhere near the sensor
    pitch = 420;//f
    break;
    case 6:    // your hand is nowhere near the sensor
    pitch = 502;//f-
    break;
    case 7:    // your hand is nowhere near the sensor
    pitch = 587;//g
    break;
 case 8:    // your hand is nowhere near the sensor
    pitch = 670;//g-
    break;
 case 9:    // your hand is nowhere near the sensor
    pitch = 752;//a
    break;
 case 10:    // your hand is nowhere near the sensor
    pitch = 835;//a-
    break;
 case 11:    // your hand is nowhere near the sensor
    pitch = 916;//b
    break;
 case 12:    // your hand is nowhere near the sensor
    pitch = 1000;//c
    break;
 case 13:    // your hand is nowhere near the sensor
    pitch = 1085;//c-
    break;
 case 14:    // your hand is nowhere near the sensor
    pitch = 1167;//d
    break;
 case 15:    // your hand is nowhere near the sensor
    pitch = 0;//d-
    break;
 case 16:    // your hand is nowhere near the sensor
    pitch = 651;
    break;
 case 17:    // your hand is nowhere near the sensor
    pitch = 709;
    break;
    case 18:    // your hand is nowhere near the sensor
    pitch = 751;
    break;
    case 19:    // your hand is nowhere near the sensor
    pitch = 792;
    break;
    case 20:    // your hand is nowhere near the sensor
    pitch = 801;
    break;
 case 21:    // your hand is nowhere near the sensor
    pitch = 875;
    break;
 case 22:    // your hand is nowhere near the sensor
    pitch = 915;
    break;
 case 23:    // your hand is nowhere near the sensor
    pitch = 916;
    break;
 case 24:    // your hand is nowhere near the sensor
    pitch = 1001;
    break;

Furthermore I was wondering If I were to give my capacitive sensor maximum and minimum values would it make the processing faster. So that it doesn't process unnecessary information. The proximity sensor can give a range from 30 to 8000, but when it gets to 8000 the Arduino starts getting slow. So I imagine if I were to only allow the number to go from 0 to 4000, I would then prevent the Arduino from slowing down? Am i right ? and If I am, how would I write the code for it ? I tried looking around the internet but I haven't found anything yet.

Cheers, Ashvin.

This is to send out the range of pitches to the DAC

So, why set a variable to 0xFFF, and then immediately set it to the value held in "pitch"?
That doesn't make sense.

So basically your saying I should be like this instead ?

 byte commandByte = 0b00010000;
 pitch = 0x0FFF;

Ashvin:
So basically your saying I should be like this instead ?

 byte commandByte = 0b00010000;

pitch = 0x0FFF;

No, obviously that's not what I'm saying.

 byte commandByte = 0b00010000;
    int cv = 0x0FFF;
    cv = pitch;

should be

 byte commandByte = 0b00010000;
    int cv = pitch;

if that's what you intended.