interrupt and millis, have questions

Hi all!
I'm working on a project where I am working on hooking up three encoder wheels to monitor three roller shades driven by one motor.

I want to have the encoders count several times over a specific time range and compare the three counts.

I would like to repeat this action for 20 or so seconds, if during the time the counts are off by more than 1 or 2 (one encoder might start high, while another is low) I want to trigger a relay to open (this bit isn't an issue).

The three roller shades are connected together using two gearboxes between them, my friend spent a fortune getting the boxes made and they are too "fragile", once in a blue moon one will break and the shades will hang and rip, hence me building a little device to monitor the three rollers for him.

The average travel time is 20 seconds down and 20 seconds up, so during that time I want to watch their rotation speed to be sure they all match (they rotate at 20 RPM), I was looking at a sensor like the Cytron encoder from RobotShop, but others may be used.

I'm thinking a function that is called when the down or up is triggered on the shades, and if the counts are too far off when comparing, I kick the stop relay.
Does all this make sense?

My issue is that I'm looking at the interrupt and millis routines, and I see that the millis routine won't run when using and interrupt.

I was planning to:

  1. monitor the pulses from encoder A over x time (millis) & store value
  2. then encoder B over same range & store value
  3. then encoder C over same range & store value
  4. Compare the counts, if in tolerance repeat, otherwise kick the stop relay.

If Millis doesn't work during an interrupt, this course of action seems out the window.
Am I right? About it not working?

Then it dawned on me that there isn't a way to say (Xcount == Ycount == Zcount within 3) to see if we have a shade that is hung.

Or is there?

At 20 RPM, polling the encoders would be plenty fast enough, I would think. If you posted a link, we could determine how many pulses per revolution the encoder output, to know how long between pulses.

Having only two external interrupts will make it difficult to read three encoders using interrupts. On the other hand, interrupts may not be necessary.

Thanks for the quick reply!
Link to?
The encoder
http://www.robotshop.com/cytron-simple-rotary-encoder-kit.html

The shade motor

http://shop.floridautomatedshade.com/Somfy-ILT2-535A2-Star-Head-Network-Motor-1030075-1030075.htm

I can always make my own encoder wheel, having say, 4 cutouts to cut down on the number of pulses per rotation.
I was also thinking I could glue 4 magnets on the rollers and use a hall effect sensor.

Those encoders are only going to generate 8 pulses per revolution. At 20 RPM, that's only 160 pulses per minute, or 1.333 pulses per second.

With a 16MHz Arduino each instruction takes 62 nanoseconds to execute. Polling to read each pulse will make the pulses seem like an eternity apart.

It it turns out, though, that digitalRead is not fast enough, Arduino Reference - Arduino Reference will read the 3 pins faster, as long as all three pins are on the same port.

PaulS,
Thanks for your reply, but I'm confused, in the second sentence you say that polling the pins will seem like an eternity, the in the last sentence you say it turns out that it isn't fast enough.

I looked at the link you included, about Port Manipulation, looks interesting, but I don't have enough C programming experience to try it, especially after reading the warnings on the page about using it and debugging. But thanks for the pointer. Maybe when I get a little more confidence in my programming skills.

As I said, I can build a different wheel that will output fewer pulses per revolution, and I was only planning to poll one sensor at a time, then compare values.

Does that make a difference in your suggestions?

I said that the duration between changes will seem, to the Arduino like an eternity. There is the possibility that I am wrong. I was once. If it turns out that I am, there is a faster method than calling digitalRead three times.

I was only planning to poll one sensor at a time, then compare values.

You need to poll all three sensors. Otherwise, how would you know what to compare?

OK, change duration, got it.

AS to the second part of your reply, I was going to poll them sequentially, for a short time period, store the three values, compare the three values, make a decision, then repeat if I haven't gone past 20 seconds since the function was activated.

If the count doesn't match, then one of the gearboxes is broken. And I hit stop.

I figure at 20 RPM, running for 20 seconds, the motor is going to rotate less than 10 times, I thought the Arduino would be fast enough to go through four or five iterations during the 20 second motor run time.

That is why I was also asking if there was a way to compare within a range, like (X == Y == Z within 5) to account for one encoder or another starting high or low compared to the other two.

SO basically, you are saying that counting pulses isn't going to work for what I am trying to do? Or are you trying to get me to look at something completely different in your own way?

If so, please spell it out, my wife will tell you that even after 20 years I don't take hints very well at all.

I'm not asking you (or anyone) to write the code, but I am surely missing what you are trying to tell me.

SO basically, you are saying that counting pulses isn't going to work for what I am trying to do?

Counting pulses will work. You'll need to see if the absolute value of cnt1 - cnt2 is greater than some value, and if absolute value of cnt1 - cnt3 is greater than some value, and if absolute value of cnt2 - cnt3 is greater than some value. If so, panic.

Those fins are pretty wide. The encoder will stay high for a long time, so never mind about my concerns that you might miss a change. It isn't when the change occurs that is critical in your application. It is that a change has occurred that is important.