Frugal Motion Sensor - nolanhergert/HeadlightBlocker GitHub Wiki

While for now it's very convenient to have a camera module as opposed to DIYing it with deconvolution of a photodiode array with a pinhole lens (might get to it at some point though) the camera draws a significant amount of current (40mA) when on. So, I need to have the camera shut off as long as possible to conserve power, but still need to detect when various things in the scene change, like:

  1. A new bright object has entered the scene
  2. The user's head has rotated
  3. A bright object has moved or changed size
  4. Stretch: #2 or #3, but figure out by how much...(no camera update needed)

While #1, #2, and #3 are fairly easily solvable with one light sensor and a pinhole lens, #4 is tricky, but required to get super low power use that enables a compact size.

Cheap light sensing

What I want is a tiny, cheap, noise-resistant, sensitive (1-10 lux), high dynamic range (up to 100000 lux), and very-low-power method of sensing when the scene has moved in various ways. No big deal :)

The current method I'm looking into now:

  • Try to use LEDs instead of photodiodes. They are much smaller, cheaper, double as visible light emitters, and hopefully will be sensitive enough.
  • Reverse bias
    • This increases the depletion region, making them more sensitive at the cost of increased (minimal) dark current. Not sure how much more sensitive yet over using no-bias. https://www.youtube.com/watch?v=KgKcbW77txY is a good intro video, as well as the solar panel IV curve explainer.
  • Method: Reverse bias, then remove voltage on high side, and wait some time before reading their decreased voltage with an ADC.
    • Well-explained here: https://community.silabs.com/s/article/using-adc-to-measure-a-current-source-with-no-external-components?language=en_US
    • A higher-resolution variant than the MERL paper: Very Low-Cost Sensing and Communication Using Bidirectional LEDs. Another more detailed paper: A Low-cost Optical Sensing Device Based on Paired Emitter-detector Light Emitting Diodes
    • While this is much slower than using an op-amp, it's much lower power and looks to complete within 5ms or so for a dark scene, which is enough.
    • This is harder to do if you need to detect a comparatively dim source in a bright sunlit scene. I think requires increasing bit depth by oversampling.
  • Noise resistance
    • I am hearing the problem is the floating pin during decay. But I'm not sure.
    • I get pretty good results by having a "dark" LED (painted) that captures similar EMI due to placement and measures dark current and does temperature compensation. Although I don't think it's strictly necessary for the latter (I am just sensing motion on a 10s time scale), but probably there's a better solution for EMI.
  • Algorithm for determining motion
  • Algorithm for determining head movement amount (assuming constant scene)
    • Can't make perfectly precise sizes for pinhole lenses. So some amount of nonlinearity (small motion in center of sensor with imprecise hole size does not produce a change in brightness level), but other sensors will pick up on it.
    • Only need to solve the problem of optical flow between two adjacent frames. (how much angle did it move?). It won't jump a bunch.

Firmware/electrical

GPIO reverse bias

Nice, as you can wait for decay while the microcontroller is asleep. Also, it's fairly robust to noise as the electromagnetic noise average is 0 long-term but very much not 0 short-term.

  • Reverse bias an LED or two before going to sleep. Set wakeup source to be those GPIO pins or a timer
  • On wakeup, check the source of the wakeup
  • Rotate amongst the LEDs that you go to reverse bias, so that you can continually detect light even though it takes 250ms for an individual LED to decay in worst-case darkness.

ADC reverse bias

Similar to above, except instead of waiting for GPIO to flip to negative, you can do an ADC reading after some time (50ms barely works) and see the 10 or 12-bit ADC value! Also works well! And doesn't require amplification and is still low power! And will probably have lower capacitance on real board with shorter wires, smaller LED, etc.

Algorithm

To detect motion, I think the best way to do this is to have tiny pinholes on a dark surface covering the LEDs (such as black electrical tape for now) with the pinholes staggered on different relative spots for each LED. By having the holes roughly the size of the active LED surface and by changing the positions, you should be able to calculate motion with some precision by the change in sensed light on each LED. image

In the easy case, this produces a ring of uncertainty around the center of each sensor relative to the hole. You know the angle of displacement, but you don't know what direction it is! By having multiple sensors, you can trilaterate the solution (same as GPS or wireless relative signal strength calculation).

However, this is further complicated by the fact that I am imaging a scene, with potentially multiple sources of light. Assuming a good camera picture at the start, I basically need to estimate what the scene would be on the sensor, from different angles. Maybe requires dumber gradient descent?

However note that this method doesn't replace having a camera. It still is really nice to have lens-focused pixels to accurately picture the scene with. And much more straightforward to use an already-done CMOS camera sensor for now.

Calibration

Can do with cheap LEDs on a PCB, spread out. Much easier to control than a phone or LCD. Should be quite bright too. Can do through hole focused beam if necessary, but it should be necessary.

I think just need to calibrate pinhole lenses and photodiode characteristics, right? Maybe the user can even do that initial calibration....

Sensor

I also prefer LEDs over photodiodes as they come in 0402 sizes and are easily 1/10 the price. And I want multiple sensors for motion detection.

Let's use LEDs instead.

LED measurements

Don't plug in the microcontroller into a breadboard or have extra wires! (or touch it) It adds ... capacitance? Something...it thinks there is light when there isn't.

I'm observing with a red 0805 led at 3.3V or 5V, not sure. Will be smaller on 1.0V, although can be higher with aperture.

Situation Lux Time to GPIO toggle
Pitch black .0001 250ms +/- .5ms
Pitch black with simulated headlight ?? 150ms
Rear red lights on Model 3, not braking 11 ??
Sunny/cloudy day inside 30 80ms +/- 2ms
Pitch black Tesla Model 3 Daytime Running Lights ?? feet away 40 ??
Pitch black Tesla Model 3 Headlights in beam 60 feet away, still painful! 45 ??
Pitch black Tesla Model 3 Headlights in beam 30 feet away 250 ??
Pitch black Tesla Model 3 Headlights in beam 10 feet away 1500 ??
Direct sun 100000 0.3 ms +/- .01ms

I tried measuring the current generated in the forward current way, it was too small to measure with multimeter.

Using ADC

Forward bias directly into adc pin on an arduino is very noisy. From 60 hz noise, etc. Also doesn't seem to be sensitive enough, somehow, even after averaging.

LED Color

Based on testing with 5mm leds:

  • Red led is very responsive to red, green and a daylight LED light source, but not really blue.
  • Green and blue were not sensitive at all to red light, but are somewhat responsive to bright daylight LED light.
  • I don't trust white, since it's actually a UV led with a phosphor in front that will convert UV to visible light. I don't imagine it works well in reverse :)

Other Methods

It is theoretically possible to do this by having surface variations on the LED lens (similar to PIR fresnel lens), which will cast positionally-dependent shadows. You don't want matte, and on the other extreme one giant scratch isn't good either.

  • I did some tests by shining my phone LED onto the led and slightly rotating the microcontroller, to keep the source lighting constant but rotating the LED. It didn't look like there was significant change.
  • Plus the math is annoying

Dyneye did a custom camera chip. Crazy! >$10K today, and maybe ideal, but also rigid. Not sure about power draw yet either.

Gyro

30 fps camera is .5mA average. Lowest gyro I can see is 3 mA minimum. So no way!