pdknsk wrote:Alright, I've built this (without LCD for now). It seems to work quite well, for a first draft.
Yay! Zen high-five!
pdknsk wrote:I couldn't make it work with a digital pin, because it didn't flip unless I put the photo transistor very close to a candle. I only had a 10k and 1k resistor, which is apparently not enough to get decent sensitivity. I've put a 100k potentiometer on the shopping list.
You'll probably want to go up to 1M or so, though doing an analogRead() was a great fallback strategy.
pdknsk wrote:To have a fixed frequency for comparison and calibration I've put another arduino and some LEDs on the shopping list. The internal PWM supposedly runs at 490Hz.
Somewhere around there. You can also use delayMicroseconds() or the internal timers to generate whatever frequency/duty cycle you want.
pdknsk wrote:What I've noticed though, is that the arduino can only analogRead() at a rate of about 8000 per second. Plenty for 1kHz, but still somewhat limiting. It seems that digitalRead() doesn't have this limitation.
Correct.
The analog input is a 'successive approximation' ADC, which means it has an built-in comparator and digital potentiometer. It sets the pot to Aref/2 and compares that to the input, then decides whether it needs to adjust upwards or downwards. The adjustment step size decreases by half with each test, and after 10 tests it's narrowed the range down to Aref/1024. It takes a certain amount of time to adjust the test voltage and do each comparison, and that limits the sampling rate.
You can increase the sampling rate by making the ADC clock faster and dropping to 8-bit accuracy rather than 10-bits, but that involves tweaking internal registers away from the Arduino's default settings.
digitalRead() just involves turning a mosfet on or off, which is as fast as the system clock.
pdknsk wrote:This does probably work, but only provides a few steps. So I had another idea, to make this seamless. What if there was sth. like a software controlled resistor. Like a regular resistor basically, but with an additional pin that connects to an arduino pin, which can be written to in order to set the resistance. It turns out such a device was already invented!

They called it a digital potentiometer.
Neat idea.
pdknsk wrote:If this doesn't work, I'll just use a normal potentiometer to manually adjust for different monitors.
You can also use a transistor, a capacitor, a couple of resistors, and the Arduino's PWM.
All transistors are voltage-controlled resistors. The term 'transistor' is a contraction of 'transconductance varistor', where 'transconductance' means 'a relationship between input current and output voltage' and 'varistor' means 'variable resistor'. The upshot is that increasing the current through the base decreases the resistance between collector and emitter. Mosfets are truly voltage-controlled resistors, while BJTs are current-controlled devices. Thing is, the voltage across the base-emitter junction rises as the current does, so we treat them as voltage-controlled devices anyway.
To make a PWM-controlled resistance, connect a 100k resistor between a PWM pin on your Arduino and a 1uF capacitor. They make a low-pass filter that averages the PWM down to a DC voltage. From that, connect a 1M resistor to the base of a BJT.
For an NPN phototransistor, an PNP bipolar would be the best load. As you raise or lower the PWM value, the resistance across the transistor will rise and fall as well, and the light sensor will become more or less sensitive.
When you void a product warrany, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.