2

I want to read ADC from the pin A0 and A1. I have written in this code, however.

I took this code came from Nick Gammon

Thank You //////////////////////////////////////////////////////////////////////////////

this is code

const byte adcPin = 0;  // A0

const int MAX_RESULTS = 256;

volatile int results [MAX_RESULTS];
volatile int resultNumber;

// ADC complete ISR
ISR (ADC_vect)
  {
  if (resultNumber >= MAX_RESULTS)
    ADCSRA = 0;  // turn off ADC
  else
    results [resultNumber++] = ADC;
  }  // end of ADC_vect

EMPTY_INTERRUPT (TIMER1_COMPB_vect);

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

  // reset Timer 1
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  TCCR1B = bit (CS11) | bit (WGM12);  // CTC, prescaler of 8
  TIMSK1 = bit (OCIE1B);  // WTF?
  OCR1A = 39;    
  OCR1B = 39;   // 20 uS - sampling frequency 50 kHz

  ADCSRA =  bit (ADEN) | bit (ADIE) | bit (ADIF);   // turn ADC on, want interrupt on completion
  ADCSRA |= bit (ADPS2);  // Prescaler of 16
  ADMUX = bit (REFS0) | (adcPin & 7);
  ADCSRB = bit (ADTS0) | bit (ADTS2);  // Timer/Counter1 Compare Match B
  ADCSRA |= bit (ADATE);   // turn on automatic triggering

  // wait for buffer to fill
  while (resultNumber < MAX_RESULTS)
    { }

  for (int i = 0; i < MAX_RESULTS; i++)
    Serial.println (results [i]);

  }  // end of setup

void loop () { }
8
  • What is the problem??
    – Dat Ha
    Commented Oct 11, 2016 at 15:15
  • Just change ADMUX in the ISR. Commented Oct 11, 2016 at 15:18
  • I want to read from a0 and a1, but the code read from a0 alone. Commented Oct 11, 2016 at 15:20
  • what change ADMUX ? Commented Oct 11, 2016 at 15:21
  • It is unclear what you are asking. Please improve your question.
    – sa_leinad
    Commented Oct 11, 2016 at 15:29

3 Answers 3

1

In the code you posted the first line is:

const byte adcPin = 0;  // A0

To read from A1 the change is simple:

const byte adcPin = 1;  // A1

i am sorry i come from thailand

Whatever country you are from does not excuse from you posting the same question many, many times.

I suggest you read the datasheet:

ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet

Scroll down to 24.9.1 ADMUX – ADC Multiplexer Selection Register

0

You can read two analog channels like this:

int first_reading = analogRead(A0);
int second_reading = analogRead(A1);

If this does not fit your purpose, then your question was not asked properly: rewrite it and clearly state your requirements. Explain why the simple solution does not work for you.

If this does work for you, then stop (for now) reading advanced tutorials, like the one where you found your code, and focus on the very basics: the Arduino examples in the 01.Basics section, then the 03.Analog section.

4
  • i want interrup ADC A0 and A1 Commented Oct 12, 2016 at 11:43
  • i am sorry i come from thailand Commented Oct 12, 2016 at 11:44
  • I am do Meter Ac. adcPin A0(measure Voltage) and adcPin A1(measure Current) Thank You Commented Oct 12, 2016 at 11:47
  • this code from Nick Gammon read adcPin = A0 Commented Oct 12, 2016 at 11:48
0
constexpr byte  adc_mux_setting = bit(REFS0) | bit(ADLAR); // Left alligment for ADC result, so ADCH contains 8b result.

volatile uint16_t         sum_u = 0;
volatile uint16_t         sum_i = 0;
volatile uint8_t   resultNumber = 0;

// ADC complete ISR
ISR (ADC_vect) {
    if (resultNumber & 1) {
        sum_u += ADCH-(sum_u>>8);                  // 8bit resolution, something like floating average
    } else {
        sum_i += ADCH-(sum_i>>8);                  // 8bit resolution, something like floating average
    }
    ADMUX  = adc_mux_setting | (++resultNumber&1); // Expecting pins A0 and A1 (otherwise offset must be added)

    TIFR1 |= bit(OCF1B);                           // clear the flag otherwise it never starts ADC conversion (not without ISR)
                                                   // it's here because I don't want to ADC starts conversion before switching channel
}

void setup () {
    Serial.begin(115200);
    Serial.println("Start");

    // reset Timer 1
    TCCR1A  = 0;
    TCCR1B  = bit(CS11) | bit(WGM12);              // CTC, prescaler of 8
    TCNT1   = 0;
    //TIMSK1 = bit (OCIE1B);                       // it doesn't work without clearing OCF1B
    OCR1A   = 80;                                  // it never reaches 80 so it never sets interrupt flag
    OCR1B   = 79;                                  // 40 uS - sampling frequency 25kHz for both (15kHz for each)

    ADCSRA  = bit(ADEN)  | bit(ADIE) | bit (ADIF); // turn ADC on, want      interrupt on completion
    ADCSRA |= bit(ADPS2);                          // Prescaler of 16
    ADMUX   = adc_mux_setting;                     // A0 goes first
    ADCSRB  = bit(ADTS0) | bit(ADTS2);             // Timer/Counter1 Compare Match B
    ADCSRA |= bit(ADATE);                          // turn on automatic triggering
}

void loop () {
    if (resultNumber == 0) {                       // print results after 128 measures for both channels 
        Serial.print(sum_u);
        Serial.print(' ');
        Serial.println(sum_i);
        while (resultNumber == 0);                 // I want to print it only once per iteration
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.