1

I'm working on a project that will essentially become an oscilloscope in the long run. I am following this guide. My code is uploaded here for more reference.

In my .ino file I have called functions to set up register such that I have a timer ISR called at a frequency of 100 KHz, and an ADC clock rate of 2 MHz. The ADC is also set so that the result is left shifted so ADCH contains an 8-bit result. In a separate .h file I have an ADC ISR that looks like this:

ISR(ADC_vect)
{
  // Read 8-bit conversion result from ADCH.
  uint8_t byte0 = ADCL;
  uint8_t byte1 = ADCH;

  data_byte = byte1;
  flag = true;
}

The loop() function is the following:

void loop()
{
  if (flag == true)
  {
    //Serial.println("ISR HIT");
    Serial.println(data_byte);
    flag = false;
  }
}

So, when the ISR is called the flag is set to true, and in the loop() function I am notified with an "ISR HIT" printed on the serial monitor, this operation is successful.

However, I also have a volatile global variable in my .ino function called data_byte (also declared as an extern in the .h file) that I set byte1 to. When byte1 is printed to the serial monitor the result is:

255
255 
255 

Any ideas on why the value of ADCH is stuck at 255? My hardware is simply a light sensor connected to pin A0, 3.3 V, and GND.

  • At 9600 baud sending "ISR HIT" can be done 120 times per second. You want to send it 100000 times per second. – Jot Oct 5 '18 at 7:12
  • 1
    You never set nor print data_byte. Or maybe you do in a version of the program you didn't publish. If we cannot see the code, there is no point in trying to guess what could be wrong. – Edgar Bonet Oct 5 '18 at 7:35
  • @Jot Thank you! I did not take that into consideration. Ideally I would set the baud rate to ~800,000 bps (or higher) but right now I've just set it to 250,000 because my serial monitor on my computer isn't letting me go higher. – CookieMonster317 Oct 5 '18 at 18:18
  • @EdgarBonet My apologies, I had removed that bit of code for debugging purposes. The updated code is in github and I've updated the code snippets in this question. – CookieMonster317 Oct 5 '18 at 18:19
  • Your program works for me: connecting AREF to 5V and A0 to 3.3V gives a stream of numbers around 187. Please, show us the complete schematic of the circuit you are using. – Edgar Bonet Oct 5 '18 at 20:14
1

It would seem the problem lies here:

// Set Register to all zeros since Vref
// will be set to internal voltge and
// analog pin A0 is used.
ADMUX = 0x00;

According to the datasheet, the bits REFS[1:0] of the ADMUX register select the voltage reference as:

  • 00: AREF, Internal V ref turned off
  • 01: AVCC with external capacitor at AREF pin
  • 10: Reserved
  • 11: Internal 1.1V Voltage Reference with external capacitor at AREF pin

Settings those bits to zero means that you are now supposed to provide your own reference through the AREF pin. If you want to use the 5 V supply as a reference, you should set them to 01. This is confirmed by the block schematic. Here is the part of that schematic relative to the reference voltage:

partial schematic of the ADC

When REFS0 is zero, the highlighted transistor does not conduct, hence the only way to provide a voltage reference is through the AREF pin.

  • 1
    Answer accepted! Thank you again for such a through and well explained answer. – CookieMonster317 Oct 6 '18 at 20:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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