Add more io

Hi guys, I would like to add more inputs to the arduino to read hall sensors of dc motors I need 40 inputs and the speed will be about 4000rpm, what will be my best option? Also it would be nice to determine the speed, I know codes for this I'm just Looking for a way to expand my io with reasonable timing.

What do you think would be the best approach?

I know some things like i2c, spi, shift registers and stuff but I have doubts about the timing.

but I have doubts about the timing

So do I. At 4000 RPM you have 66 rotations a second. For 40 motors you have 2666 pulses per second to time. Using SPI is the fastest way to get inputs into the arduino but measuring those similtainousyl is going to be tricky, if not impossible.

I'm with Mike. For a couple motors it's okay, but after that, you only have so many clock cycles, pins, ect.

The best thing I can say, is to use a dedicated encoder/counter IC for each motor, then have each IC report to the arduino.

I can use like 8 tiny's or something and then let them calculate for the arduino, how would you suggest to communicate then? Or do you think I should use something else?

kenny_-_: I can use like 8 tiny's or something and then let them calculate for the arduino, how would you suggest to communicate then? Or do you think I should use something else?

I forget what the term is called, but there are IC's out there, designed for quadrature interface, that will count pulses for 4 motors per IC, then you can feed the information from each of those IC's to the arduino over I2C on a request-get method.

I can use like 8 tiny's or something

Yes you can, I helped a mate do just this albeit with only 4 slave processors.

OTOH if there are chips designed for this they may be a better option.

Now the next thing to think about is how often do you need the data to be sampled? Can you just sample one motor at a time then move onto the next one and sample that? If so then all you need is a MUX.


Rob

Graynomad:

I can use like 8 tiny's or something

Yes you can, I helped a mate do just this albeit with only 4 slave processors.

OTOH if there are chips designed for this they may be a better option.

Now the next thing to think about is how often do you need the data to be sampled? Can you just sample one motor at a time then move onto the next one and sample that? If so then all you need is a MUX.


Rob

That was my other thought. For 66 rotations per second, you can poll the motor for 1/10 of a second, and capture 6.6 rotations. 40-1/10ths of a second is 4 seconds to poll all of them.

If a 4-pole magnet is used, that's 26.4 clicks in 1,600,000 cycles of the CPU. The clock would only capture the 26, so there'd be an error of (26 * 10 * 60) / 4 = 3900 RPM = 100 RPM error.

The risky part where the speed is important will last for about 1 minute each time so it will be importand to know if they are running every... Say 3-5seconds or so, I don't need to measure the rpm from all motors.

I can do like a hall input change on 95% and rpm calc on 5%.

The cheapest in my opinion will be muxing then, can you all recommend this? The good thing is that I don't need any communication.

The easiest way to MUX 40 signals is with five 4067 chips fed into a single digital input all controlled with a few outputs.

As this is a pretty slow signal you can drastically improve the response time by timing the waveform's period rather than counting pulses to get the frequency.

Do you need to know the actual RPM or just that it's out of a certain range?


Rob

I wan't to know the rpm because the motor will run at a lower speed with the max load and I don't wan't it below 3000 rpm. I'd also like to visualise it off course.

I measured the rpm with just counting the time it takes to make a round, how would you suggest your waveform calculation programmatically? Because I don't need 100% accuracy.

I don't think you really need to know 3000RPM as such, just that you get pulses faster than 1 every 20mS.

As such you could do something like

period = pulseIn(pin, HIGH);
period += pulseIn(pin, LOW);
if (period > 20000)
   // too slow

This would give you a reading for one channel in two revolutions, x 40 that's 800mS to read all motors.


Rob