My apologies if this has been answered before, but I am struglling to find the precise information I need being relatively inexperienced in this area.
I am invovled in a project where we are trying to measure an objects (ball) velocity and trajectory using laser / photosensor arrays. The object will have an initial velocity of 30 m/s and will pass through a first and second array (0.4 m apart) each of 50 single column, vertcially spaced, LDRs of 6mm diameter. Depending on which sensors are triggered in the arrays, we should be able to determine the current velocity (from the points in time at which the object trips each array) and the x/y trajectory of the object (through differences in the height of the triggered sensors in each array).
The project requires an accuracy of at least 0.01 m/s, and given the diameter of the object, up to 5 LDRs could be blocked at any one time. If my maths is correct (if!) the system would have to be capable of polling 100 LDRs at least once every 0.0002 s and therefore a minimum system speed (including interface latency) of 0.5 Mhz. My conclusion was that the 16 Mhz arduino board would afford us more than enough resolution to aborb the latency of serial data and therefore still provide more than enough accuracy.
I see that the aurdino board inputs can easily be expanded and there are a number of options for this including shift registers, multiplexers and I2C. Can anyone comment on the feasibility of this project using arduino, and which if any of the input expansion approaches would provide the lowest latency in measurements, lowest complexity in circuitry and best price point? My initial thoughts are that cascaded shift registers would do the job on a budget, and that the centipede shield combined with the mega board would be the least work, but I would welcome any more specific ssuggestions.
If I understand correctly a ball passes some sensors that will generate a pulse, and you want to get the timing of those pulses.
you could connect them all to one IRQ line of the arduino (though OR port) and have the IRQ routine fill an array with timestamps.
#define ARRAYSIZE 2
volatile unsigned long timeStamps[ARRAYSIZE ]; // can be larger of course
volatile byte idx = 0;
void IRQ()
{
if (idx < ARRAYSIZE )
{
timeStamp[idx] = micros(); // millis();
idx++;
}
}
at 30m/sec the distance of 0.4 m will be in the order of 13333 microsec. As micros() makes steps of 4 microseconds you can in theory see the difference between
I ask because it will make a huge difference to what needs to be done. For example if that's the case you don't really need to poll the sensors at all, just OR them all together so you have a start pulse from one array and a stop pulse from the other.
I think LDRs are a bit slow to respond (might be wrong there), if so what about using photo transistors?
There will only be one ball, but as we are also looking at trajectory, we need to know which of the sensors have been triggered, which could be up to 5 simultaneously in each array. If we know that 5 sensors will be triggered a bit of calcualtion would be done in the arduino to find the centre point of the ball when passing each array. The difference in centre point between arrays would allow calculation of the trajectory.
I may be wrong, but I think due to the fact that multiple sensors need to be recorded simulatneously, a single IRQ would not work (perhaps 5 would?), although tthe idea of timestamping is interesting. The arrays will fixed in a solid frame so the 400 mm (including construction tolerance) will be constant and should not be a problem.
How would I efficiently OR the sensors togther in terms of circuitry?
How would I efficiently OR the sensors togther in terms of circuitry?
What are the sensors? Data sheet?
LDRs would be difficult to OR I think.
Transistors could all be wired open collector to produce a single INT pulse per array then run something like robtillaart's code to find the mid point.
Use 50 (can you get by with 48, that's a much better number for hardware) photo transistors all wired open collector.
When Any one of them is triggered it interrupts the Arduino and at the same time latches all 50 inputs into 5 shift registers.
The Arduino notes the time then waits for the pulse from the second array which is wired the same.
On getting the second pulse you read the data from all 10 shift regs, By finding the 1-5 high bits you can determine the centre for your trajectory.
You can halve the number of shift regs needed by putting both arrays in parallel and making sure you scan the bits from the first pulse before you get the second.
So just thinking aloud, if you use a Mega (54 inputs) you can probably do the lot without the shift regs. You only need the trigger timestamp and the bits that were set at the time of the trigger.
You can halve the number of shift regs needed by putting both arrays in parallel and making sure you scan the bits from the first pulse before you get the second.
As my math above shows you have only 13 millis for clocking the bits for objects at 30m/sec ... should be enough.
However if distance is made smaller or the speed is increased or multiple arrays are used - trajectories seldom are a line - I think the extra shift regs keep the system more flexible.
To be honest I haven't speced sensors yet. We will use some sort of photosensor - I realise now LDRs are not going to do it. A laser has been intially speced, so we need to spend a bit of time setting up that part of the system.
Greynomad that sounds like an excellent idea! You are of course right that the positioninal data does not need to be dealt with simulatneously or at low latency. We may also get away with 48 in the array - something we'd have to try in paractice. Am I correct in understanding that wired "open collector" would mean I can connect all transistors to the same pin without a multiplexer?
Would taking this approach mean a 16 Mhz arduino board has more than enough resolution to make decent measurements at these kinds of velocity? (Grumpy_Mike?)
Am I correct in understanding that wired "open collector" would mean I can connect all transistors to the same pin without a multiplexer?
That's right, but I just thought of a fault in that idea.
If you connect all the sensor outputs together of course you can no longer read the individual bits. So the ORing has to be done another way, 50/100 diodes and 50/100 resistors, logic gates or whatever. Either way it's getting bigger than Ben Hur.
I reckon it's worth looking at doing it all with a Mega, depending on the pins available you might get 50 that can cause a PC interrupt. If so there's your ORing with no hardware.
The code I posted above can read the ports and you can sort it out later.
It's > 1AM here so I'll sleep on it and look at the Mega schematic and 2560 data sheet tomorrow if nobody has had a better idea before then.
Well this is a much more difficult project than you think, especially the calculation of results from your sensors.
If it were me I would use each sensor to trip an RS flip flop. The outputs of the flip flops feed into a port expander (you could use three MCP23S17), this chip can generate a pulse when any input changes. Use that to start your timer. Have the same on the second array and use that pulse to stop your timer. That way you get a time for the first sensor to be triggered on each array. This will give you a rough velocity but this can be refined later when you know the trajectory.
Once the stop pulse has been received you can clock in the inputs of your port expander to find the shadow profile of the ball through each of the sensor arrays. This can then be used to work out the center of the ball and approximately correct the velocity calculation.
Finally all the RS flip flops are reset and the system is ready for another ball.
Doing it this way you don't have to continuously scan all the sensors and it reduces the error in the time between a sensor being trigger and you knowing about it. It is also easy to extend this to many sensor arrays without overloading the processors capability.
AWOL:
I'm a little unclear about the use of a laser - are you using a line projector?
I have inherited some items from a previous and far from complete attempt at getting this working, incluidng a pile of brass barrel laser pointing diodes (1 mW, 650 nm wavelength). Im not 100 % if there was good rationale for selecting these, but I think we can safely say the LDRs that happen to be on hand will not do the job. It seems the sensible option would be to spec the sensors first in terms of their response time and then find a laser source to complement.
Rob, your input is much appreciated. Shame the open collector idea wouldn't work, I guess to good to be true. If it could be done with the mega that would be great, but Robtillaart's point is valid in this case. Ulitmately we may want to add another couple of arrays. If 2 megas could be synced this may do, otherwise a design with some flexibility would be ideal.
Grumpy_Mike thanks for the input. I do realise this is a difficult project and that I am on a steep learning curve. I will need to do a bit of reading up to understand how the expander can feed the shadow profile to the arduino - Im not really familiar with these parts yet.
Just looking at the data sheet I think you can use the interrupt flag register to save you from having to wire the sensors into RS flip flops before the port expander, that will simplify the construction tremendously. That then should hold the shadow path record.
I checked out the 2560 data sheet, it only has 3 PC interrupts, thats 24 pins so that won't work either without extra hardware. Personally I think it would work if there was 6 PC interrupts but there ain't so that's that.
I think Mike's IO expander is looking like the best option. The MCP23017 can be configured to interrupt on any change of state on the pins. I don't think it latches the inputs though so you still have to read them as the ball passes but that should be a pretty fast affair.
After that the code logic is as has been described to find the centre, do some trig to get the distance travelled etc.
It doesn't latch them but the interrupt flag register will indicate which pins generated an interrupt even if that is different to the pin's current state. This in effect is a latched input record if you enable all inputs to generate interrupts.
I am coming back to this now after obtaining an Uno board and some mcp23017. I have a newbie question which I hope one of you can explain.
With a ball travelling at 30 m/s pass a sensor (operating in the nano second range) of say, 4 mm dectectiona area, I need to be able to read inputs at least once every 133 microseconds (1 mm = 33 microseconds), which relates to a frequency of around 7.5 Khz. I have had trouble asertaining a whether the uno board can support an I2C sample rate of that value. The MCP chips are capable of 1.7 Mhz on I2C, can any one define the perforamnce of the uno (including API) with this chip?
The point about using the port expander is that you don't have to continually pole the inputs to see if anything has changed. There is an interrupt output that changes when ever any one of the inputs changes. All you have to do is to monitor this pin to see when the ball triggers an input. Then you read the interrupt register at your leisure to see what input was triggered. All the interrupt outputs can be connected together in what is called a wired OR configuration. This is because these outputs are open collector.
As the app is time critical, I would avoid generating an interrupt whenever a phototransistor output changes. Each interrupt takes quite a lot of time to switch context and save the old one. Why not just generate an interrupt when the first phototransistor senses the ball, then poll the whole array until the ball has passed? Or, if the processor isn't doing anything else while waiting for the ball, why use an interrupt at all?
As the app is time critical, I would avoid generating an interrupt whenever a phototransistor output changes
No one is using an interrupt, we are using the interrupt output of a port expander to indicate a trigger has occurred and to start a timer. Then the second bank of sensors will trigger the interrupt output to stop the timer. No actual interrupts will be generated these can be monitored on normal input pins.
When the second bank of sensors have been triggered, the interrupt register in the port expander can be read to detect the position / trajectory of the spherical object passing them.