Ich versuche gerade die allseits beliebte Anwendung von LEDs als
Lichtsensor nachzuvollziehen [1]. Dazu habe ich eine LED an die Pins PC0
und PC1 eines ATmega328p auf einem Arduino Duemilanove angeschlossen.
Mein Programm lädt die LED in Sperreichtung auf und misst dann
anschließen den Verlauf der Spannung über dem Eingang. Soweit
funktioniert das auch ganz gut - man kann deutlich sehen dass die
Spannung bei stärkerer Beleuchtung schneller abgebaut wird.
Allerdings ist mir eine systematische Streuung der Messwerte
aufgefallen. Nachdem ich die Messdaten über die Zeit geplottet habe
(Siehe Bilder, einmal mit und einmal ohne LED), ist auch relativ klar wo
dieses her kommt: Das Signal am offenen Pin wird von einem starken
Netzbrummen mit bis zu 500mV Vpp überlagert.
Das Board ist nur über ein USB-Kabel mit dem Computer verbunden. Der
Betrieb über einen USB-Hub bringt nur geringe Verbesserungen. Das
Ausschalten von Lampen und Moniteren und der Nähe hat nicht viel
geholfen.
- Ist die ein bekanntes Problem mit dem Arduino (konnte nichts finden)?
- Lässt sich das durch Hardwaremaßnahmen abstellen?
- Gibt es Ideen, dieses Problem Softwaremäßig zu beseitigen?
Mittelwertbildung über 20ms?
[1] http://www.merl.com/reports/docs/TR2003-35.pdf
1 |
|
2 |
|
3 | int i,k;
|
4 | int temp[64];
|
5 |
|
6 | DDRC = 0x01; // LED anode to gnd, float cathode
|
7 | PORTC = _BV(PC1); // Charge led cathode via pull up
|
8 | _delay_us(50);
|
9 | PORTC &=~(_BV(PC1)); // pull up off
|
10 |
|
11 | for (i=0; i<64; i++) {
|
12 | ADCSRA |=_BV(ADSC); // Start conversion
|
13 | while (!(ADCSRA&_BV(ADIF))); //~100 us
|
14 | ADCSRA |=_BV(ADIF); // Clear ADIF
|
15 |
|
16 | _delay_us(200);
|
17 |
|
18 | temp[i]=ADC;
|
19 | }
|