Reading analog values during interrupt

What I'm trying to do is set up an interrupt where when the pin's digital value is high, I get an analog read of that pin's value. The pin I'm using for this is A0, so it should be able to read both analog and digital. I am doing a project with a custom Arduino board, but it's pretty similar to an M0.
Here's what I've done to troubleshoot so far and what has happened. I just get a digital read of the pin, that works fine. I just get an analog read of the pin, that works fine. I use an interrupt on the pin to print out a serial message, that works fine. The problem comes up when I try to use an interrupt to get the analog value. What happens then is that I don't get the value, but if I serial print the digital value while I do that, all the digital values just go to zero.
Can the Arduino just not switch between analog and digital fast enough for this to work?

Not likely. Using Serial with interrupts disabled is a big no-no.

Also, you ignored the forum guidelines that ask you to post your code, and describe how to format it correctly.

1 Like

This is a diagram of the general setup of the circuit if that helps at all.

It's a start, but obviously we need to see your code, in code tags please.

1 Like

Here's the code:

#define wheelPos     A2
#define wheelV       A0
#define wheelGnd     A1

void setup() {
  pinMode(wheelPos, OUTPUT);       
  digitalWrite(wheelPos, HIGH);    
  pinMode(wheelGnd, OUTPUT);       
  digitalWrite(wheelGnd, LOW);     
 
  pinMode(wheelV, INPUT);          
 
  serial.begin(9600);
  serial.println("Start")
 
  serial.println("Serial check");
  attachInterrupt(wheelV, readpinstop, RISING);
}

void loop() {

wheelturnR();
uint16_t wheel = digitalRead(wheelV );
serial.print("digital wheel value ");
serial.println(wheel);
}

void readpinstop(){
  serial.println("It did it!");
  uint16_t analogWheel=analogRead(wheelV);
  serial.print("analog wheel value ");
  serial.println(analogWheel);

in the interrupt routine
1.read the information from analogue/digital and store the values in global volatile variables
2. set a global volatile flag to indicate new data available
3. no Serial IO calls!

in loop() wait for the flag to indicate new data

  1. clear the flag
  2. process the analogue/digital data
  3. print information to Serial

That's not different from any other button connections. Why don't you want to poll and debounce the analog value?

1 Like

What drives you to use an interrupt? Is there some reason you can't just poll the input?

The thing this is actually for is a motorized color wheel that I need to stop and start at specific points. In the diagram I showed above, the wheel completes the circuit to one of those resistors. Because of this, I need to be able to read the analog values very quickly to determine the position of the wheel. This is also a much smaller part of the overall progam I need for my project, so I don't want to take up much of the computing power.

Same computing power whether you use interrupts or not.

If you know the RPM of the wheel you can calculate how fast you would have to poll.

A couple of things to consider:

  1. I assume there is some sort of mechanical wiper on the wheel to complete the circuit. Not sure how much that will bounce.
  2. Not sure how fast an ADC conversion is on this device. May or may not be an issue.

You have probably considered all of this. I have never done anything like this I'm just throwing out ideas.

Hardware note: "The ADC is optimized for analog signals with an output impedance of approximately 10 kļ— or less." You should probably use a 10k pull-down resistor. You will then need to adjust your pull-up resistors to make sure the voltage goes above the minimum for a HIGH signal. That's 0.6 Vcc (3V at Vcc = 5V). That would require pull-ups of no greater than 6.6k.

1.0k = 0.91 Vcc = 930
1.8k = 0.85 Vcc = 868
3.3k = 0.75 Vcc = 770
5.6k = 0.64 Vcc = 656

"Serial" is miscapitalized "serial".
The closing '}' is missing at the end of the file.
The function wheelturnR() is not defined.
There is a ';' missing at the end of Serial.println("Start")

Does the problem still occur when you run the corrected version?

#define wheelPos A2
#define wheelV A0
#define wheelGnd A1

void setup()
{
  pinMode(wheelPos, OUTPUT);
  digitalWrite(wheelPos, HIGH);
  pinMode(wheelGnd, OUTPUT);
  digitalWrite(wheelGnd, LOW);

  pinMode(wheelV, INPUT);

  Serial.begin(9600);
  Serial.println("Start");
  Serial.println("Serial check");
  attachInterrupt(wheelV, readpinstop, RISING);
}

void wheelturnR() {}

void loop()
{
  wheelturnR();
  uint16_t wheel = digitalRead(wheelV);
  Serial.print("digital wheel value ");
  Serial.println(wheel);
}

void readpinstop()
{
  Serial.println("It did it!");
  uint16_t analogWheel = analogRead(wheelV);
  Serial.print("analog wheel value ");
  Serial.println(analogWheel);
}

Yeah, the code I posted here is just the portion of it that actually pertains to the interrupt. The missing things are just due to my own inability to copy and paste things correctly and don't show up in my real code. The wheelturnR() function is the function that turns the motor, which is defined in my larger code and the way we have it configured "serial" doesn't have to be capitalized.

The IDE has a semi-prominent "copy for forum" button on the screen.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.