I am trying to use a led and photoresistor to measure the rpm of a fan with 3 blades attached to 3-6 v dc motor. I have everything working and getting the photoresistor to output according. However, I do not know how to code this to get the RPM. Currently I have tried an if statement, when the photoresistor passes a value, to calculate the period. However, with the way Millis works, it is not a correct Period and that does not account for speeding up or slowing down the fan blades. I am not asking for the answer but any direction to go from here would be much appreciated.
What I am trying to do with this code, is once the photoresistor breaks 300, I find the period which I used to find freq. and then RPM.The period is just the start of the program – 0, their forward, is just the new time of the program – the old timestamp when it found period last. However, period is just becoming time blocks in between resetting the fan blade. With that being said, the RPM always reads zero. The whole idea I had with this code feels wrong, but I am not sure where to turn to next.
Help us help you: please read the "How to get the best out of the forum" post, and post your code, using code tags. Explain what it should do, and what it does instead.
Note that photoresistors are very slow, and not suitable for measuring high RPMs by optical tecnniques. Most people use a photodiode.
LDR is quite slow compared to a phototransistor (both low cost’)
You could use a pin-change interrupt to tick off each blade passing.
Use millis() or micros() to determine the interval, divide by the number of fan blades, and carry on from there.
I can contorl the speed of the fan with a peoteometer, however, I can not give you a a speed but zero when it is off. Limiatation, this is a homework assignment and this is what was asked of us.
What are you using analogWrite() for?
For your original approach, it is not wrong to set a threshold and watch it being crossed in an upwards direction and keeping a timestamp when it crosses. The risk is that you get fluctuating or spurious readings so you may have to add some filtering/averaging.
I don't think the output of a photo resistor is suitable for triggering an interrupt unless you use say the built-in comparator available on a Uno, which may go beyond the scope of this assignment.
You can't mix millis() and delay() as you have done in your first code sample.
Edit
In your original code you should calculate the RPM and do the printing inside this if statement instead of every loop() iteration: if (curPR > 300 && oldPR <300 ){ }
A photo-resistor is really bad suited for this application.
If your teacher is not the most selfish-arrogant type of human beeing that is unable to say
"sorry my bad"
The first step of your work should be to measure how fast does the photoresistor react on the change from light ON to LIGHT OFF.
This is done with a code that switches ON the LED wait for 10 seconds then
switch off LED and store a time-stamp
then reading in the value of the photo-resistor in a fast running loop
always checking if value has changed over a threshold-value and if the value has changed
store a second timestamp into a second variable
Then you can calculate the difference to see how long it takes for the photo-resistor to change its value
By varying the physical conditions
how much ambient light
resistance-value of voltage-divider
distance between LED and photo-resistor
you will get a variaty of times it takes for the photo-resistor to change its value enough to be able to detect this as "light-beam interrupted"
I'm pretty sure that the maximum rpm that can be measured by a photo-resistor will be pretty low
I believe that this is an excellent exercise in specifying sub optimal components in order to test the student's ability to come up with a creative solution.
As many others have said a photoresistor is totally unsuitable for this application.
1: its not directional - so it will pick up ambient light
2: its SLOW
Also its a bad assignment because its "closed; it constrains you to doing something in a particular way; when really you should be asked to measure the speed of a fan, consider (and maybe research) alternative ways to do it, choose one, justify your choice, and implement the chosen solution.
Given the constaints your first step should be to read the LDR
1: with the fan blade blocking the light from the LED, then
2:m with the fan blade moved so the LDR is exposed to the LED.
If you dont see much difference you will need to think again.
circuitry used (simple voltage-divider, external analog chip (comparator like LM339)
@dangmidnight
not sure how much you know about electronic components and their names
please post a picture of your photo-resistor maybe it IS a photo-transistor
You're not actually counting the number of times the LDR is changing, you're using delay(500) so your code is checking the status of the LDR every 500 milliseconds. edit: in fact, you're not even using the status of the pin, just calculating the frequency which the loop runs at. With a 500 millisecond delay each time it'll probably always say the rpm is around 180?
You need to continue looping without delay and count all the pulses then after a certain number of counts you could work out the total time and calculate the frequency from that.