48ch pwm controlled by sound. (slow arduino)

Hi there! (this is my first post on this forum so please forgive me if I'm in the wrong section)

I'm currently working on a "module-led-strip-wall" controlled by sound. As of now I got 48ch pwm controlled with three TLC5940, an Arduino MEGA and the TLC5940 library. I'm planing on expanding the number of channels.

Everything works just fine beside one part. I need the program to run an cycle under 50 microseconds because I want to sample the sound up to 20kHz. The bad guy in this problem is the analogRead() function, it's takes about 110 microseconds which only gives me the ability to sample sound up to 9kHz :frowning:

I've tried with an due which works really great, the analogRead() only take 5 microseconds! :smiley: But... the library doesn't work with the due. I've tried another library ( this library Google Code Archive - Long-term storage for Google Code Project Hosting. ) but with no luck of getting the thing to work (I will try more when my exams are done).

I just want to check with you guys if you know anything better, etc. Do you know any better way on solving this?

Cheers!

What library does not work with the DUO?

You can increase the analogRead speed at the cost of some stability of results (more noise) if the exact value is not to important.

  // set ADC prescale to 16 to speed it up
  sbi(ADCSRA,ADPS2) ;
  cbi(ADCSRA,ADPS1) ;
  cbi(ADCSRA,ADPS0) ;

Adding the above code to setup will mean to read and store the analogue value will take about 18us.

I haven't done it myself, but I understand from the clever people here that it's possible to set the ADC up in a free-running mode where it will generate an interrupt as it completes each reading and then immediately start the next reading. If you can achieve that it would give you the maximum possible capture frequency and also leave the CPU free to do other things in the background.

(This sort of thing may well be processor-specific and I don't know whether it's possible with the processor you're using.)

Have you thought of using a SPI ADC ? (MCP3201)
SEE ATTACHED
Have you thought of using a I2C ADC ? (ADS1115)
SEE ATTACHED

MCP3201.pdf (493 KB)

ads1115.pdf (950 KB)

Thanks for all of your answers :slight_smile:

Riva:
What library does not work with the DUO?

You can increase the analogRead speed at the cost of some stability of results (more noise) if the exact value is not to important.

  // set ADC prescale to 16 to speed it up

sbi(ADCSRA,ADPS2) ;
 cbi(ADCSRA,ADPS1) ;
 cbi(ADCSRA,ADPS0) ;




Adding the above code to setup will mean to read and store the analogue value will take about 18us.

This library doesn't work with the ARM cpu Google Code Archive - Long-term storage for Google Code Project Hosting.

I've tried adding the code you wrote but I get this error msg:

sketch_may18a.ino: In function 'void setup()':
sketch_may18a:3: error: 'sbi' was not declared in this scope
sketch_may18a:4: error: 'cbi' was not declared in this scope

Edit:

I found this in another thread

// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

// set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;

Now it works just as you said! :slight_smile:

raschemmel:
Have you thought of using a SPI ADC ? (MCP3201)
SEE ATTACHED
Have you thought of using a I2C ADC ? (ADS1115)
SEE ATTACHED

this is above my understanding right now but I'll check up on it! :slight_smile:

Wasting:
I've tried adding the code you wrote but I get this error msg:

sketch_may18a.ino: In function 'void setup()':
sketch_may18a:3: error: 'sbi' was not declared in this scope
sketch_may18a:4: error: 'cbi' was not declared in this scope

Oops my bad. Forgot the macro definitions but you seem to have found then elsewhere.

this is above my understanding right now.....

Are you sure ?

 #include <Wire.h>
#include <Adafruit_ADS1015.h>
 
Adafruit_ADS1015 ads1015;
 
void setup(void)
{
  Serial.begin(9600);
  Serial.println("Hello!");
  
  Serial.println("Getting single-ended readings from AIN0..3");
  Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV)");
  ads1015.begin();
}
 
void loop(void)
{
  int16_t adc0, adc1, adc2, adc3;
 
  adc0 = ads1015.readADC_SingleEnded(0);
  adc1 = ads1015.readADC_SingleEnded(1);
  adc2 = ads1015.readADC_SingleEnded(2);
  adc3 = ads1015.readADC_SingleEnded(3);
  Serial.print("AIN0: "); Serial.println(adc0);
  Serial.print("AIN1: "); Serial.println(adc1);
  Serial.print("AIN2: "); Serial.println(adc2);
  Serial.print("AIN3: "); Serial.println(adc3);
  Serial.println(" ");
  
  delay(1000);
}

raschemmel:

this is above my understanding right now.....

Are you sure ?

Arduino Code | Adafruit 4-Channel ADC Breakouts | Adafruit Learning System

Ohhh! :smiley: Thanks! I've just ordered some samples from TI!