Trying to read Analogue pins so fast as possible

Dear all!!

I'm using the Arduino UNO, and with the hope of read any analogue input pin in the fastest way, I'm trying to use quasi-assembly, as follows:

#include <avr/io.h>
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif

#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

char sensorValue;

void setup() {
  Serial.begin(115200);
}

void loop() {
  sbi(DIDR0,ADC0D);    // Deactivate as IO
  cbi(PRR,PRADC);      // Turn ON ADC
  sbi(ADCSRB,ACME);    // Activate ADMUX
  cbi(ADCSRA,ADEN);    // Deactivate ADC
  cbi(ADMUX,MUX2);     // Select analogic pin (A0)
  cbi(ADMUX,MUX1);
  cbi(ADMUX,MUX0);
  sbi(ADCSRA,ADEN);    // Turn ON ADC
  sbi(ADCSRA,ADSC);    // Initiate reading
  delay(3);
  
  sensorValue = ((int)ADCH<<8)|(int)ADCL;
  
  //int sensorValue = analogRead(A0);
  Serial.print("Data: ");
  Serial.println(sensorValue);
}

But the output is only " Data: ÿ ", and giving different voltages on the pin, the result not changes. Why?

I have read the datasheet, and these two webpages:

http://www.marulaberry.co.za/index.php/tutorials/code/arduino-adc/

I know, that I'm working rigt now with a prescaler of 128. In the future, I will reduce this value to get more velocity.

I'm triyng to reach the maximum reading rate for an accelerometer with this arduino board, knowing that the maxmum should be 200kHz, to ensure reading accuracy.

Thank you very much!!
StickFix

Should this

char sensorValue;

maybe be

int sensorValue;

Ok, done!

The resulting value is now always and forever "Data: 1023", what I do like more, buy I can't change it, putting different voltages. I suspect that the problem is a problen with the instructions order...
I will read the datasheet again.

Any other idea?
Thank you!

As fast as possible, huh?

  delay(3);

I'm calling bullshit on this!

I don't think you need to setup all the ADC stuff continually in loop() so moving some of it to setup may help.
I think you should use interrupts to ensure the ADC has finished though 3ms should be enough.
I wrote some code a while back for reading a CCD array and managed to get ADC read time down to about 18us by just altering the ADC prescale to 16. There would be a little more overhead to store the result but but maybe that would be fast enough, else you could alter the prescale even more.

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

I'm calling bullshit on this!

Yes, you are right, but it's not changing the result of the output value I think... that is my problem in this moment.

Another good webpage: analogRead()

Yes, Riva, I will see, if the timing is enough for my project, so the following code is only to continue discussing..

Mi code is now:

#include <avr/io.h>
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif

#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

int sensorValue;

void setup() {
  Serial.begin(115200);

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

  sbi(DIDR0,ADC0D);    // Deactivate IO Port
  cbi(PRR,PRADC);      // Energizar ADC
}


void loop() {
  ADMUX=B00000001;  //Analog A1 ?
  sbi(ADCSRA,ADSC);    // Init reading
  while(bit_is_set(ADCSRA,ADSC));
  
  sensorValue = ((int)ADCH<<8)|(int)ADCL;
  
  //int sensorValue = analogRead(A0);
  Serial.print("Data: ");
  Serial.println(sensorValue);
}

and the result now is always "Data: 0".

Thank you all!!!

I'm triyng to reach the maximum reading rate for an accelerometer with this arduino board, knowing that the maxmum should be 200kHz, to ensure reading accuracy.

The data sheet claims 89k conversions/sec and that's for 8 bit conversions and and free running mode - There's no way to get 200k conversions/sec out of any of these chips.

Don't use delay wait on conversion complete in stead (look in analogRead()) Some of the ode you have in loop() should be in setup.

assembly

Assembler is often slower than code written in c/c++ The compiler is far better than you at producing "optimal code"

Mark

but it's not changing the result of the output value

You need to change the value of the input voltage to get a change in reading.
Try testing it by just connecting the input pin to a pot.

Anyway as others have pointed out you are going about it all wrong. If you want to do it in machine code you have to loop until the end of conversion flag is set, then you can read the results. Do not use delay at all.

Hm, I'm not using delays anymore. If you see in my last code, it isn't any delay... only a while until the finish-flag is set.

To introduce a voltage, i have tried to connect the analog pin to the 5V or 3,3V and GND source of the arduino itself. That is not the problem...

Thank you!!