Sorry in advance for any mistakes as this is my first post. I only learned about Arduino a few months ago and have been watching many YouTube tutorials. I have an electrical/mechanical engineering background, but programming is mostly new to me.
I'm working on a code to measure charge lengths of various products as they fall downward past a sensor. To help paint you a picture, imagine taking a handful of candy (M&Ms, Skittles, etc), hold out your hand and quickly open it, dropping them in front of a sensor which is facing toward you. I want to measure the time from the first to last piece as they pass the sensor. I'd like to do this at a rate of up to 200 times per minute. This frequency can change at any time and the code should measure the charge length the same way at 50 cycles per minute as 200 (user does not need to input a speed). I'm using a light which is facing the sensor so the candy casting a shadow is what the sensor is reading as "product" - Sort of like a light curtain sensor.
Right now, I'm turning on an LED when the photo resistor is below threshold (seeing candy) and using a push button to calibrate the threshold value by averaging 5 resistor readings and subtracting 10. Photo resistor reads about 750 in my house during daylight hours.
The part of my code that measures the "charge length" is currently able to measure only one item at a time. The code does not have to measure every piece of candy, but it does have to read when the sensor goes below threshold after the first piece and above threshold after the last piece. My lack of understanding is preventing me from continuing to develop this and I'm wondering:
Is this why Interrupts are used?
Because this is somewhat fast, is a photodiode the better option than a photo resistor?
Anyway, here's the charge length measuring part of my code. I'd like to learn how to do this myself but if you want to solve it for me, that's fine too. (This is a work project) Use code tags to format code for the forum` Please let me know if this post is missing anything.
Millis1=millis(); //start of charge length measuring code
if(Millis2-Millis1>300 && buttonValue==1){
//this only allows the while loop to cycle at a maximum rate of 200/min (not true 1/24/24)
while
(Rval<Rthreshold){
digitalWrite(Rled,HIGH); //increment timer -- no longer needed bc of using oldMillis
and millis() functions
Rval=analogRead(Rpin); //exit while loop when Rval rises above Rthreshold
-- now just reads Rval continuously and drops out of while loop when Rval>Rthreshold
}
chargeLength=millis()-Millis1;
digitalWrite(Rled,LOW);
Millis2=millis();
}
if(chargeLength>0){ //sets the charge
length timer back to 0 to prepare for next charge
Serial.println(chargeLength);
}
chargeLength=0;
}
You can assume Yes, they will all fall in a straight line past the sensor. Eventually I will incorporate more sensors or a longer light source in an attempt to capture all pieces regardless of where they fall in that cross-sectional area (picture a 10" diameter tube for example)
This is part of the challenge and I don't know the best way to go about it. The only method I can think of to accomplish this is to constantly store the time of the last "seen" piece and if 100ms passes without seeing another piece, assume that's the end of that charge, subtract "last seen piece" time from "first seen piece" time, and serial print that value as the "charge length". That's okay if the charge length isn't printed immediately - I can afford to wait a few hundred milliseconds or more if needed. Ultimately, I want to get about 100 these values sequentially exported to a spreadsheet, but I haven't got there yet.
If the pieces are always less than 100ms apart, start a 100ms timer and a total timer when the first piece is detected, if another piece is detected before 100ms timer expires, reset 100ms timer. If the 100ms timer expires, stop the total timer, subtract 100ms from the total time. That should be the "charge" time.
I'm not totally sure how long the pulses will be but they can go up to one second. So if the charges are one second long, the interval would be much slower just because of how the machine above it functions - like 40 cycles per minute.
If a charge measures 40ms long, I think 5ms accuracy/precision would be sufficient. Think that means I should be using micros()?
I got the idea it is a skittle train of skittles passing by a sensor.
So my question means what does one skittle passing by the sensor look like, that is to ask how long the sesnor is HIGH when a skittle passes by.
Or LOW, whatever is opposite to no skittle in range.
So it's a combination of how fast a skittle moving, how long it is in the direction of motion the distance from the sensor and the width or angle of the sensor's range.
Thanks, I think I understand your questions a little better now.
This is all using math to estimate what these values would be since there's no off-the-shelf device (to my knowledge) to get these types of measurements to any useful degree of accuracy.
I'm really trying to measure "string-out". When you drop a handful of something, it slowly gets strung out as it falls downward. In other words, the distance between each piece increases while falling - so, the greater the fall distance, the greater the string-out will be. Lets assume the hand-full of Skittles is dropped from a height of 1.5m before passing the sensor. That would be a speed of about 5.5m/s when passing the sensor. Keep in mind there may be more than one piece passing the sensing area simultaneously. This doesn't matter too much to me but just something to think about - product seen is product seen.
So, here's my thinking trying to solve for "how long is the sensor HIGH when a skittle passes by" assuming a skittle (I'm using M&M measurements because that's what I could find) measures 7mm (.007m) in the short direction (diameter would be larger so i'm using the worst case scenario):
5.5m / 1second = .007m / X
X=1.27ms
If that's right, than wow - that's way shorter than I expected. It sounds like in order to run small pieces like in this example, a photo diode would be the better choice.
THX for the more words. I prefer M&Ms anyway, so let's just talk about those.
Nothing like the back of the envelope for a bit of reality checking.
The relatively brief sensor reading means that using polling, just sitting in a loop looking for M&Ms might not work so well.
But an uncompromised loop() can run at many thousands of times a second, and as has been pointed out, all you have to do in the observation phase is to keep bumping ahead the timer which will cause the observation phase to end, like kicking the can down the road.
So I would yeah use the fastest sensor, and give the simple approach a shot. Even if it demonstrates the unsuitable nature of that method, you'd have had to string up and wire and play with a buncha things all of which may present side issues, and improve the other parts of the apparatus that will find themselves in any solution - mechanical arrangements and ambient light and who ate all the M&Ms those were for testing, not snacking &c.
In a well designed sketch that isn't taxing the resources of whatever board is being used, there should be nothing that keeps the loop() function so busy for so long that it can't finish its code and loop again at a high frequency.
Killer: any use of delay().
Killer: for or while or do loops that, say, calculate 1000 digits of π.
Killer: protracted serial printing.
Since you don't need to do anything like that ever, at least not during the data gathering phase, you should be able to take a reading from the sensor often enough so that at least once in the 1.7 ms window each provides you see any M&Ms or gaggles thereof that would reset the timing out timer that is going to say the charge is past.
I think #6, #7 and #8 upthread descrive a thing to try.
I happen to be working on something else, this may help. It illuminates an LED when the button is pressed and keeps the LED on until a fixed period with no buttons presses elapses.
I hope you can see the similarity. All you'd need to do is tinker with the time constants and note first press (M&M) and most recent press, try it here: