How to generate an interrupt from an analog signal

I'm putting together a cat feeder and since the meal sizes are small (about an eighth of a cup), I am using relatively small pipes. Consequently, the food can get stuck and needs a little jolt to get it unstuck. I'm using a solenoid to wiggle a wire to get the food flowing again but I want to use a photo cell and a LED to sense when the solenoid needs to trip due to the absence of food. I can get all the components to work, but I want to use an interrupt to trip the solenoid when needed based on the photocell 'seeing' the LED. But since the output of the photocell is analog and not digital, I cannot use the interrupt directly. Any tricks anyone can think of that will let a higher level on the photocell trip the interrupt???

Thanks for your effort!

Doug

I would swear this is another student project.

There is nothing to prevent you using the output of the receiver (the photocell) to saturate a transistor which signal then drives an interrupt line. As a designer of circuits you get to set the bias level. (And the output level too!)

And you can still have your analog circuit to drive the paddle which pets the cat...

You are getting hung up on analog vs digital. Be one with the "ramp". They are ALL analog devices. I have never used a digital computer.

Use the bias curve Doug! Use the Bias curve! (or whatever it is called these days. I like ramp...)

you can have a free running ADC generate an interrupt upon the completion of a sample

during that interrupt, you can do your value comparison

if the comparison is true, then run a function

open up the atmega datasheet and read about the ADC

Use a comparator to generate a hi/lo signal - see the Vin vs Vusb cmparator on the Uno schematic & do the same. Set a trim pot as voltage divider and set the level you want the comparator to trip at.

Anywhere above 3 volts = high, anywhere below 2 volts = low.

frank26080115: you can have a free running ADC generate an interrupt upon the completion of a sample

during that interrupt, you can do your value comparison

if the comparison is true, then run a function

open up the atmega datasheet and read about the ADC

Actually chapter 24 of the ATMEGA2560 data sheet shows that a comparator with interrupt is built in... See ch 25 as well.

Another good library idea?

the advantage of using ADC over comparator in this application is that hysteresis can be implemented, and a comparator requires more external parts. Also in the the original poster's application, the higher speed of a comparator is not a requirement, and also reserving PORTC for digital use is also not a requirement

WillR:
I would swear this is another student project.

If a 62 year old, retired Mechanical Engineer can be called a student…

I know enough to be dangerous, but not enough to get myself out of a spot!

The info on ADC makes my head spin but this looks interesting:

pluggy:
Anywhere above 3 volts = high, anywhere below 2 volts = low.

Can you give me a hint on how to implement that in code??? Since I want to use an interrupt, I don’t want to write instructions in the ‘void loop’ section that will only be executed when that instruction comes up in the sequence.

Thanks for all your input.

Doug

Since you want to use an interrupt, and assuming your arduino is '328 based, one of the easiest ways is to create an external interrupt on pin D2 or D3:

/* Setup pin2 as an interrupt and attach handler. */
attachInterrupt(0, pin2Interrupt, LOW);

LOW can also be CHANGE, RISING, FALLING

So try putting the photocell output on an interrupt line with type RISING and see if you get interrupted.

http://arduino.cc/en/Reference/AttachInterrupt

Then you will have an ISR that sets a flag or something that you can monitor in your void loop, and when you see it change you do some action

// * Name: pin2Interrupt, “ISR” to run when interrupted by cat food dispenser jam
void pin2Interrupt()
{
Interrupted_flag = 1; // for example
}

CrossRoads: Thanks for the reply. Yes, I tried all that and did not get an interrupt. That's why I thought it needed a clear LOW or HIGH rather than the 200 to 400 increase I get from my photosensor when it first senses the LED. Is there a way to define what is considered LOW and HIGH?

Thanks,

Doug

DBB: If a 62 year old, retired Mechanical Engineer can be called a student....... ... The info on ADC makes my head spin but this looks interesting:

We are all students, right? Even us oldies!

Anyway, I was reading today about "op-amp comparators" - try Googling that. I suspect that suitably set up you could turn your analog signal into a clear on/off condition which you can then put onto one of the two pins (D2/D3?) which detect interrupts. Haven't tried it myself but it sounds good.

Nope - that’s why I suggested the comparator in the first place, to get you that defining line.
Any op-amp will do.
http://www.dipmicro.com/store/LM358N
Wire a trimpot from to 5V and Gnd, run the wiper into the +input.
Run your signal into the -input - when your signal exceeds the +input, the output will snap low creating a nice Low level interrupt for you.

At the same time, seems like you would have ages relatively speaking to react here, so just reading the level every 100mS and reacting when it got high enough would probably be sufficient also - is there a lot of other stuff going on?

I'm assuming from the post times that the "nope" wasn't directed at me. ;)

What do you use to generate all these fantastic circuit diagrams? Whatever it is I want one!

Plus, cat food detector ... nice idea.

Yes, the Nope was for reply #9.

Download the software from expresspcb.com, it's great for this quick explanation kind of stuff. Way simpler than eagle to create something quik. I do a screen capture, paste into powerpoint with some cropping, then save as .jpg. Might trim the .jpg down and/or resize also using office picture manager. Then I FTP up to my website, or attach directly here. I can turn the whole thing around very quickly, including looking up a part price somewhere.

Great, thanks!

Would I be correct in guessing that even without the pot, something like a 2K resistor between +5V and pin 3, and another 2K resistor from pin 3 to ground, would effectively put 2.5V on pin 3, and thus make it compare to below or above 2.5V?

I haven’t played with op-amps before but your posts are giving me confidence.

Yes.
Keep in mind that you will draw current thru those parts (5V/4K = 1.25mA), so go higher if you can and if battery consumption is an issue.

Thanks, CrossRoads! I think I have it now.

I made up an example based on your suggestions. Full description here:

http://www.gammon.com.au/forum/?id=11011

This screenshot shows the way that the op-amp "cleans up" the analog signal into a digital one:

This sketch takes the output from the op-amp and flashes the on-board LED when the light level goes over a certain amount, completely done by interrupts:

// Example of flashing pin 13 based on the value on pin 2, when an interrupt occurs

// Author: Nick Gammon
// Date: 27 March 2011

// interrupt service routine
void light_change ()
{
  digitalWrite (13, digitalRead (2));  
}

void setup()
{
  pinMode(13, OUTPUT);  
  attachInterrupt(0, light_change, CHANGE);
}  // end of setup

void loop() 
{

  // all done by interrupts
  
}  // end of loop

Nice writeup Nick. Nicely done.

Thanks!

Crossroads:

Thank you for the tip. It was exactly what I was looking for.

My CAD package is just too cumbersome for these quick one-off things -- and no PCB house interface.

This looks great. Schematics, PCB layout, simple and fast.