# Arduino Break Beam GOAL: use arduino to implement a break beam sensor so we can time things in physics experiments <img width="25%" src="view-20201205_171837.jpg"> <img width="36%" src="viewc-20201205_182222.jpg"> <img width="25%" src="adjust-20201205_171334.jpg"> <img width="25%" src="measure-20201205_171343.jpg"> <img width="10%" src="sensor-20201206_075129_HDR.jpg"> ================================ # Basis - Use a light sensitive detector to detect when something breaks a light beam and start / stop a timer. - Using an Arduino makes sense as the clock speed is 16Mhz. So a micro-second timer counting ticks might be feasible. Let's see... - A very similar project but with unadjustable sensor, so dealing with ambient light is more of a problem. https://learn.adafruit.com/toy-car-speed-timer/software</a> ================================ # CdS Photoresistor - https://learn.adafruit.com/photocells/overview - Respose Curves <img width="40%" src="light_graph.gif"> <img width="40%" src="light_cdsspectrum.gif"> - Measure resistance using a voltage divider between LightDetectingResistor and Resistor: ``` V5+----XXXX----+----XXXX---GND LDR | R | +-> VADC VADC = V5 * R / (LDR+R) ``` - What value of R should we use? ``` png("voltageDivider.png") x=seq(0,1,len=32) c=1; plot(x,c/(c+x),ylim=c(0,1),type="b",xlab="c/(c+x)=down or x/(c+x))=up") c=0.1; points(x,c/(c+x),type="b",col="red") c=10; points(x,c/(c+x),type="b",col="blue") c=1; points(x,x/(c+x),type="b") c=0.1; points(x,x/(c+x),type="b",col="red") c=10; points(x,x/(c+x),type="b",col="blue") title("volatage divider across variable 0:1\nR: bl=equal. red=0.1. blue=10") dev.off() ``` <img src="voltageDivider.png"> - This shows for the variable LDR in [0,1] how VADC responds for fixed R={0.1, 1, 10}. Down-sloping curve if LDR is on V5+ side; up-sloping curves if LDR is on GND side. - If we want this to tigger a digital read, then safe logical lows are 0.9V and safe logical highs are 4.2V out of 5V reference. This is 0.18 low and 0.84 high on a [0,1] scale. https://learn.sparkfun.com/tutorials/logic-levels/all - Thus we want a fast downsloping curve that will quickly go from 0.84 down to 0.18 to catch quick breaks in the light beam. This is a fixed R of less than 0.1*(LDR). So if in a normal room LDR is 1k-10k then R might be about 500 ohms. - This will be adjustable with a potentiometer so that the beam is just high and any quick break brings it to below 0.18. This will change sensitivity. Too sensitive and changes in the room light will falsely trip sensor. Not sensitive and quick breaks might not trigger. - Here are plots for 5%, 1%, and 0.5% in addition to the 10% (red) above showing how it drops off faster: ``` png("voltageDividerSET.png") x=seq(0,1,len=32) c=0.05; plot(x,c/(c+x),ylim=c(0,1),type="b",xlab="c/(c+x)=down",col="red") c=0.01; points(x,c/(c+x),ylim=c(0,1),type="b") c=0.005; points(x,c/(c+x),ylim=c(0,1),type="b",col="blue") abline(h=0.18) abline(h=0.5) abline(h=0.84) title("volatage divider across variable 0:1\nR: red=0.05 bl=0.01 blue=0.005") dev.off() ``` <img width="40%" src="voltageDividerSET.png"> - NOTE: Adafruit points out using more than one high impedence sensor using ADC can give bad results https://blog.adafruit.com/2010/01/29/how-to-multiplex-analog-readings-what-can-go-wrong-with-high-impedance-sensors-and-how-to-fix-it/. The arduino multiplexes a single ADC between multiple pins and weird things can happen. The devil is in the details! - https://learn.adafruit.com/photocells/arduino-code shows how to use a capacitor charing time on a digital line to figure out resistance. ================================ # Building - Arduino Uno $12 https://amazon.com/Arduino-ATmega328P-Development-Board-Oc52/dp/B087R7QH26/ - CdS cells $5 https://amazon.com/Gikfun-Photoresistor-GL5516-Resistors-Arduino/dp/B00RLGFIEY/ - Potentiometers $ 7 https://amazon.com/MCIGICM-Breadboard-Trim-Potentiometer-Arduino/dp/B07S69443J - Display $9 https://amazon.com/gp/product/B00O2LLT30 - breadboard or bare PCB board kit $14 https://amazon.com/gp/product/B07CK3RCKS - LEDs, wire, switch - laser pointers x2 $9 - Simple wiring: voltage divider on sensors, LED with current limiting resistor, plug in display ================================ # Software - <a href="breakBeam.ino">breakBeam.ino</a> - It has two phases: - Adjust: shows sensor states on screen and LED so you can adjust pots to make them just on. <video width="36%" controls><source src="breakbeam-adjust-20201205_171018.mp4"></video> - Time: wait for break beam to measure and show time. Animated clock faces! video <video width="50%" controls><source src="breakbeam-test-20201205_171458.mp4"></video> - Results are also written to serial port - I _vastly_ prefer the Arduino CLI over the GUI: https://github.com/arduino/arduino-cli ================================ # Usage - See ** <a href="README_RESULT_arduino-break-beam-gravity.html">README_RESULT_arduino-break-beam-gravity.html</a> ** to measure gravity. - NOTE: You can access the usb-serial port through Linux or windows and WSL (linux under windows). - COM4 windows port shows as /dev/ttyS4 under windows-linux. - Find the windows COM port by looking at device manager "Ports Com and Lpt". - Running miniterm (that is part of pyserial) shows the port! - I believe Bluetooth Serial should also show as a "RFCOMM" port. ================================ # What Does Not Work - I tried using a "vs-1838B" IR receiver used with IR remote controllers. - Most IR remotes use a modulation of a carrier signal to transmit information. This would seem like a great way to deal with the "ambient light" problem without a calibration step. You are detecting modulations of the carrier, not the raw light, so you might automatically calibrate. - However when I tried it with an uninterrupted carrier frequency (38kz), I found I got a LOT of false "no signal" readings. This is not good as I want to interpret these "no signal" readings as breaks in the beam. I could get it to work with my TV remote, so the hardware does work in general. Perhaps this works well with short carrier pulses where information is presence/absence of individual pulses and not "always-on" carrier. Plus breaks shorter than 1/carrierFreq wouldn't be detectible... - <a href="README_RESULT_arduino-break-beam-NOTWORK.html">README_RESULT_arduino-break-beam-NOTWORK.html</a>