Go Down

Topic: ADC conversion time question - Arduino UNO rev.3 (Read 127 times) previous topic - next topic

Lucky-Luka

Hi all
I'm new here.
I've bought an Arduino starter kit.
I'm doing the third exercise: a TMP36 sensor is to be touched in order to light up a number of LEDs proportional to your temperature.
In the manual it's written: "The Analog-to-Digital Converter can only read so fast, so you
should put a small delay at the very end of your loop(). If you
read from it too frequently, your values will appear erratic."
In the sketch there's 1 second delay...
Isn't it too high?
Using a temperature sensor application it's no big deal having such a high delay but I was wondering what's the ADC minimum time in my Arduino UNO.
In other applications I would like to use less than 1 sec delay, is it possible?
Cheers

Railroader

Without being precise I think I'va been reading at least 10 times per second, without any trouble.
Here is a crazy fast loop that works:
Code: [Select]


//Pin                      Function
//Analog 0         Button (select, up, right, down and left)
//Digital 4        DB4
//Digital 5        DB5
//Digital 6        DB6
//Digital 7        DB7
//Digital 8        RS (Data or Signal Display Selection)
//Digital 9        Enable
//Digital 10       Backlight Control


//Sample using LiquidCrystal library
#include <LiquidCrystal.h>

/*******************************************************

  This program will test the LCD panel and the buttons
  Mark Bramwell, July 2010

********************************************************/

// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

unsigned long     update_time;
int last_read;

// read the buttons
int read_LCD_buttons()
{
  adc_key_in = analogRead(0);      // read the value from the sensor
  if (abs(last_read - adc_key_in) > 5)
  {
    last_read = adc_key_in;
    update_time = 0;//force printing
  }
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  // For V1.1 us this threshold
  if (adc_key_in < 50)   return btnRIGHT;
  if (adc_key_in < 250)  return btnUP;
  if (adc_key_in < 450)  return btnDOWN;
  if (adc_key_in < 650)  return btnLEFT;
  if (adc_key_in < 850)  return btnSELECT;

  // For V1.0 comment the other threshold and use the one below:
  /*
    if (adc_key_in < 50)   return btnRIGHT;
    if (adc_key_in < 195)  return btnUP;
    if (adc_key_in < 380)  return btnDOWN;
    if (adc_key_in < 555)  return btnLEFT;
    if (adc_key_in < 790)  return btnSELECT;
  */


  return btnNONE;  // when all others fail, return this...
}

void setup()
{
  lcd.begin(16, 2);              // start the library
  lcd.setCursor(0, 0);
  lcd.print("Push the buttons"); // print a simple message
}

void loop()
{
  lcd_key = read_LCD_buttons();  // read the buttons
  if (millis() > update_time)
  {
    update_time = millis()+ 333;//make seconds show up
    //  delay(333);
    lcd.setCursor(7, 1);           // move cursor to second line "1" and 9 spaces over
    lcd.print( analogRead(0));       // read the value from the sensor
    lcd.print("   ");
    lcd.setCursor(12, 1);           // move cursor to second line "1" and 9 spaces over
    lcd.print(millis() / 1000);    // display seconds elapsed since power-up
    lcd.setCursor(0, 1);           // move to the begining of the second line

    switch (lcd_key)               // depending on which button was pushed, we perform an action
    {
      case btnRIGHT:
        {
          lcd.print("RIGHT ");
          break;
        }
      case btnLEFT:
        {
          lcd.print("LEFT   ");
          break;
        }
      case btnUP:
        {
          lcd.print("UP    ");
          break;
        }
      case btnDOWN:
        {
          lcd.print("DOWN  ");
          break;
        }
      case btnSELECT:
        {
          lcd.print("SELECT");
          break;
        }
      case btnNONE:
        {
          lcd.print("NONE  ");
          break;
        }
    }
  }

}
Use Your knowledge. If that's not enough, look for education.
Having knowledge, think outside the box to gain more of it. Only trains run like the train, on the rails. The rest run between the rails.

DrDiettrich

In the manual it's written: "The Analog-to-Digital Converter can only read so fast, so you
should put a small delay at the very end of your loop(). If you
read from it too frequently, your values will appear erratic."
In the sketch there's 1 second delay...
IMO above sentence is misleading until wrong. The analogRead() returns only after completion. Reading the same channel multiple times is recommended, with the first reading after a channel switch discarded.

In fact a delay may be required for the Serial output, that transmits characters only at limited speed. Sending temperature values too frequently can result in lost characters hence erratic values. In advanced projects the logging of results should be restricted to a safe interval, e.g. one value per second, or only on a change, while the input of new values and lighting of the LEDs is not subject to any timely restriction.

The delay in the sketch is 1 ms, not 1 s.

Lucky-Luka

IMO above sentence is misleading until wrong. The analogRead() returns only after completion. Reading the same channel multiple times is recommended, with the first reading after a channel switch discarded.

In fact a delay may be required for the Serial output, that transmits characters only at limited speed. Sending temperature values too frequently can result in lost characters hence erratic values. In advanced projects the logging of results should be restricted to a safe interval, e.g. one value per second, or only on a change, while the input of new values and lighting of the LEDs is not subject to any timely restriction.
Now it's more clear... The delay is due to serial communication time restrictions more than ADC time restrictions, right?
Is there a way to set a proper time delay or is it just a rule of thumb thing?

The delay in the sketch is 1 ms, not 1 s.
It's written delay(1)... doesn't this mean 1 second?

DVDdoug

Quote
It's written delay(1)... doesn't this mean 1 second?
When in doubt check the language reference.   

...Actually, always check the language reference. ;)


BTW - You might want  a delay, or some "smoothing" or hysteresis so the display doesn't jitter when you're on the "hairy edge" between two digital readings.

Railroader

Here is another useful link I use more than often.
https://www.arduino.cc/reference/en/#page-title
Use Your knowledge. If that's not enough, look for education.
Having knowledge, think outside the box to gain more of it. Only trains run like the train, on the rails. The rest run between the rails.

DrDiettrich

The delay is due to serial communication time restrictions more than ADC time restrictions, right?
Is there a way to set a proper time delay or is it just a rule of thumb thing?
You should know how many characters your Serial.print's produce and the baudrate. Then you know how much you can send. Or check Serial.availableForWrite() before sending more.

Riva

You should know how many characters your Serial.print's produce and the baudrate. Then you know how much you can send. Or check Serial.availableForWrite() before sending more.
Or use Serial.flush
Don't PM me for help as I will ignore it.

DrDiettrich

Serial.flush() will block everything until the transmit buffer is empty, preventing any equally spaced data acquisition and timely reaction.

Go Up