Forum: Mikrocontroller und Digitale Elektronik Luxmeter mit Bereichsumschaltung


von Denis B. (tulip_denis)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich muss ein Luxmeter mit Bereichsumschaltung programmieren. Die 
Hardware dazu ist bereits fertig. Allerdings quäle ich mich mit der 
Programmierung, da ich es überhaupt nicht drauf habe. Deswegen schreibe 
ich mal hier rein, mit der Hoffung dass mir jemand helfen könnte.

Verwendet wird ein ATmega48, 3 MOSFETS des Typ's IRF7314(P-Kanal) und 
eine Fotodiode BPW34.
Es sollen folgende Bereiche berücksichtigt werden.
1-10 Lx Vollmond
10-100 Lx Straßenbeleuchtung
100-1000 Lx Arbeitsplatzbeleuchtung

R=4V/80mA=500 Ohm
R=4V/80µA=5 kOhm
R=4V/80nA=50 kOhm

80 mA -> 1000 Lux

Soviel ich mich erinnern kann wird der jeweilige mosfet eingeschaltet, 
wenn prozessor low ist.

Die Details habe ich leider nicht mehr in Erinnergung. Nun muss die 
Software dazu fertiggestellt werden.

Wäre sehr Dankbar wenn jemand mir helfen könnte.
Vielen Dank im Voraus.

von MaWin (Gast)


Angehängte Dateien:

Lesenswert?

Denis B. schrieb:
> Die Details habe ich leider nicht mehr in Erinnergung

So was.

Hast du damit vor 10 Jahren angefangen,,oder warum konntest du es 
vergessen ?

Deine Schaltung misst nichts.

Einfach(er) machst du es dir mit einen digitalen Helligkeitssensor mit 
eingebauter Bereichsumschaltung, z.B. TSL230, im Photo damals gebaut als 
der TDL billig war.

https://www.mikrocontroller.net/attachment/115876/TSL230_ReadMe_110717.pdf

Wenn es unbedingt deine BPW34 sein soll, informiere dich was ein 
Transimpedanzverstärker ist und besorge dir einen Rail-To-Rail 
Operationsverstärker mit geringem Eingangsstrom und Messfehler (AD821?).

https://de.wikipedia.org/wiki/Transimpedanzverst%C3%A4rker

Die Bereichsumschaltung erfolgt dabei über den Rückkopplungswiderstand. 
Den kann man mit Analogschaltern umschalten (Achtung Leckstrom), oder 
als T-Netz Spannungsteiler über Ausgangspins (open oder low) nach Masse 
schalten.
1
GND--|+\
2
     |  >--+-- Analogeingang
3
  +--|-/   |
4
  |        R1
5
  |        |
6
  |        +--R2--PD0
7
  |        |
8
  |        R3   Bereichsumschaltung
9
  |        |
10
  +--R5----+--R4--PD1
11
 _|_
12
 /_\
13
  |
14
 GND

von Stefan F. (Gast)


Lesenswert?

MaWin schrieb:
> Deine Schaltung misst nichts.

Wieso das?
Für mich sieht der Schaltplan schlüssig aus.

von Stefan F. (Gast)


Lesenswert?

Denis B. schrieb:
> Verwendet wird... eine Fotodiode BPW34.

Im Schaltplan wird aber ein Fotowiderstand gezeigt und ich denke dass 
eine Fotodiode ohne Verstärkung an dieser Stelle nicht gut funktionieren 
wird.

Beim LC-Display fehlt im Plan die Stromversorgung.
Beim Mikrocontroller fehlt ein 100nF Kondensator an der Stromversorgung.

Welche Messwerte bei soundso viel Lux entstehen, kann ich nicht 
einschätzen. Das hängt ja auch stark vom Fotowiderstand ab. Da würde ich 
einfach mit einem guten Gerät vergleichen, das bereits funktioniert. 
Langzeitstabil sind Fotowiderstände eh nicht, als aber Schätzeisen kann 
es wohl taugen.

Denis B. schrieb:
> Soviel ich mich erinnern kann wird der jeweilige mosfet eingeschaltet,
> wenn prozessor low ist.

Ja

Denis B. schrieb:
> Nun muss die Software dazu fertiggestellt werden.
> Wäre sehr Dankbar wenn jemand mir helfen könnte.

Gerne, wie lautet denn deine Frage?

von Martin (Gast)


Lesenswert?

Denis B. schrieb:
> Nun muss die
> Software dazu fertiggestellt werden.
>
> Wäre sehr Dankbar wenn jemand mir helfen könnte.
> Vielen Dank im Voraus.

Soll heißen "Wer schreibt mir die komplett" ?

von MaWin (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Wieso das?
> Für mich sieht der Schaltplan schlüssig aus.

Dieser Schaltplan funktioniert mit LDR (wobei die starken 
Temperatureinflüssen und Alterung unterliegen, also eher nicht messen 
sondern schätzen), aber nicht mit Photodioden. Er kann nicht mal den 
Photosperrstrom messen, da er keinen definierten shunt-Widerstand hat, 
sondern RDSon der MOSFETs mit eingeht. Ausserdem sperren MOSFETs nicht 
so gut, das gibt Mikroampere Fehler.

von Peter D. (peda)


Lesenswert?

Denis B. schrieb:
> 80 mA -> 1000 Lux

Dann schau mal ins Datenblatt der BPW34. Mehr als 100µA sind da nicht 
drin.

von Peter D. (peda)


Lesenswert?


von Michael U. (amiga)


Lesenswert?

Hallo,

MAX44009 kommt etwas weiter nach unten.

Gruß aus Berlin
Michael

von Denis B. (tulip_denis)


Angehängte Dateien:

Lesenswert?

Hallo nochmal,

ich durfte die schaltung nachbearbeiten und habe es zum laufen gebracht. 
Allerdings müsste ich die proportional steigende Spannung in Lux 
wandeln.
Da ich ein anfänger bin, fehlt mir dieses Teil. Wäre sehr nett wenn mir 
jemand weiterhelfen könnte.
Die Stromquellen sollen eine Fotodiode simulieren.

Bereich 1(mit 500Ohm):
0,00000 V-0,00036 V soll 0-9 Lux ausgeben

Bereich 2(mit 5kOhm):
0,004 V-0,0396 V soll 10-99 Lux ausgeben

Bereich 3(mit 50kOhm):
0,4 V-4,0 V soll 100-1000 Lux ausgeben

Wie muss ich ADC programmieren, damit ich diese Werte ausgeben kann?
1
#ifndef F_CPU          // optional definieren
2
#define F_CPU 18432000UL    // MiniMEXLE mit 18,432 MHz Quarz
3
#endif
4
5
#include <avr/io.h>        // Header-Dateien zum ATmega88
6
#include <stdbool.h>       // Header-Datei fuer Bit-Berechnung
7
#include <avr/interrupt.h>    // Header-Datei fuer Interrupts
8
#include <util/delay.h>      // Header-Datei fuer Wartezeit
9
#include "lcd_lib_de.h"      // Header-Datei fuer LCD-Anzeige
10
#include <stdint.h> 
11
12
void initTimer0 (void);
13
void adWandlerInit (void);
14
void adWandlung (void);
15
void umrechnung (void);
16
void anzeigeTreiber (void);
17
void initDisplay (void);
18
19
20
int main ()
21
{  
22
  initDisplay();        
23
  initTimer0();      
24
  adWandlerInit();    
25
  
26
sei();            
27
28
  DDRD &= ~(1 << PD0);    // PD0 Eingang
29
  DDRD &= ~(1 << PD1);    // PD1 Eingang
30
  DDRD &= ~(1 << PD2);    // PD2 Eingang
31
  DDRD &= ~(1 << PD3);    // PD3 Eingang
32
  
33
  DDRB |= (1 << PB0);      // PB0 Ausgang
34
  DDRB |= (1 << PB1);      // PB1 Ausgang
35
  DDRB |= (1 << PB2);      // PB2 Ausgang
36
37
  DDRC = 0x00;
38
  PORTC = 0x00;
39
40
  while(1)
41
  {
42
    if (!(PIND & (1<<PD0))) 
43
    {
44
      PORTB |= (1<<PB1);    //PB1 High
45
      PORTB &= ~(1 << PB0); //PB0 Low
46
      PORTB &= ~(1 << PB2); //PB2 Low
47
48
    }
49
    
50
    else if (!(PIND & (1<<PD1)))
51
    {
52
      PORTB |= (1<<PB0);    //PB0 High
53
      PORTB &= ~(1 << PB1); //PB1 Low
54
      PORTB &= ~(1 << PB2); //PB2 Low
55
56
    }
57
    
58
    else if (!(PIND & (1<<PD2)))
59
    {
60
      PORTB |= (1<<PB2);    //PB2 High
61
      PORTB &= ~(1 << PB0); //PB0 Low
62
      PORTB &= ~(1 << PB1); //PB1 Low
63
64
    }  
65
  }
66
67
void initTimer0()
68
{
69
  TCCR0A  |= (0<<WGM00)
70
      |  (0<<WGM01);            // Timer 0 auf "Normal Mode" schalten
71
  TCCR0B  |= (0<<WGM02)
72
      |  (1<<CS01 );            // mit Prescaler /8 betreiben
73
  TIMSK0  |= (1<<TOIE0);            // Overflow-Interrupt aktivieren
74
}
75
76
void initAdc()
77
{
78
  ADMUX   |= (1<<REFS0);        // Vref =AVCC; ADC0
79
  
80
  ADCSRA  |= (1<<ADPS0)
81
      |  (1<<ADPS1)
82
      |  (1<<ADPS2)
83
      |  (1<<ADEN);     // Teiler 128; ADC ON
84
  (void) ADCH;                // erster Wert ist "wegzuwerfen"
85
}
86
87
void initTaster(void)
88
{
89
  DDRD = DDRD & 0xE1;             // Port B auf Eingabe schalten
90
  PORTD |= 0x1E;                  // Pullup-Rs eingeschaltet
91
  _delay_us(1);                   
92
}
93
94
void initDisplay()          // Start der Funktion
95
{
96
  lcd_init();
97
  
98
  lcd_gotoxy(0,0);    
99
  lcd_putstr("Luxmeter");
100
101
  lcd_gotoxy(1,0);  
102
  lcd_putstr("von  XYZ");
103
104
  _delay_ms(2000);
105
  lcd_gotoxy(0,0);  
106
  lcd_putstr("      lx"); 
107
108
  lcd_gotoxy(1,0);             
109
  lcd_putstr(Bereich ");  
110
111
}

von DerEgon (Gast)


Lesenswert?

Denis B. schrieb:
> Allerdings müsste ich die proportional steigende Spannung in Lux
> wandeln.

Dreisatz?

von Denis B. (tulip_denis)


Lesenswert?

Ist mir klar. Ich weiss bloß nicht wie ich es machen kann, da ich ein 
Anfänger bin.

von Patrick C. (pcrom)


Lesenswert?

Guck dich bitte nochmal das Diagramm von 10.10.2022 14:35 an.
Das kann so nicht stimmen.
zB
- 0V signalen ???
- Wenn 6lux=0.6uA und 60lux=6uA wieso ist dann 10lux=0.8uA ???
- Weiters diagram versteh ich noch weniger....

Bist du sicher das bereich 500/5k/50k 10/100/1000 lux ist und nicht 
umgedreht ?

Patrick aus die Niederlande

von Michael B. (laberkopp)


Lesenswert?

Denis B. schrieb:
> ich durfte die schaltung nachbearbeiten und habe es zum laufen gebracht

Ähm, nein.

Es wurde dir sogar aufgezeichnet, was du bauen könntest, warum machst du 
es mit Gewalt immer noch falsch ?

Deine Photodiode, wohl durch die 7 umschaltbaren Stromquellen 
dargestellt, liefert zwar vielleicht Strom durch die 3 
relaisumschaltbaren Widerstände, aber der ATMega48 bekommt die Spannung 
nicht mit, die deine Simulationsinstrumente anzeigen.

Aber Photodioden als Stromquellen liefern entweder nur bis ca. 0.5V 
bevor es durch internen abfliessenden Strom zu ungenau wird und mehr als 
0.7V kommen sowieso nicht raus, oder reagieren im Sperrbetrieb abhängig 
vom Spannngsabfall an den shunt-Widerständen.

Man nutzt einen Transinpedanzverstärker mit gutem (kein LM358) OpAmp 
wenn man messen will.

Der Faktor, wie viel lux wie viel Strom und dann wie viel Strom zu wie 
viel Spannung am Widerstand führt, kann man nur schätzungsweise aus dem 
Datenblatt der Photodiode entnehmen (ich nehme an, das hast du gemacht 
bei der Beschriftung lux vs. uA), die Toleranz liegt bei -50%...+200%. 
Will man messen, muss man also kalibrieren mit einer bekannten 
Helligkeit. Zumal schon die Reflektion auf dem Plastikfenster der Diode 
den Messwert locker um 50% beeinflusst, eine Kuppel als Diffusor muss 
also drauf sein.

: Bearbeitet durch User
von Denis B. (tulip_denis)


Angehängte Dateien:

Lesenswert?

Danke für die Rückmeldung.
> - 0V signalen ???
Das Soll low Output simulieren.
> - Wenn 6lux=0.6uA und 60lux=6uA wieso ist dann 10lux=0.8uA ???
Sie haben recht. War ein Tipp Fehler. Habe angepasst(s.Anhang)
> - Weiters diagram versteh ich noch weniger....

> Bist du sicher das bereich 500/5k/50k 10/100/1000 lux ist und nicht
> umgedreht ?

Ja ist richtig, ich brauch nur den Code, mit dem ich die Spannung als 
Lux ausgeben kann. Dreisatz wäre eine möglichkeit. Habe es aber nicht 
hingekriegt, da ich ein Anfänger bin.
Wichtig ist, dass die Software in der Simulation läuft.

von Denis B. (tulip_denis)


Lesenswert?

Mit dem Hardware klappt es sowieso nichtmehr. Wichtig ist das die 
Software in  SimulIDE richtig läuft. Von daher bräuchte ich einen Code, 
der Spannung in Lux ausgibt.

von Patrick C. (pcrom)


Lesenswert?

Denis B. schrieb:
>> Bist du sicher das bereich 500/5k/50k 10/100/1000 lux ist und nicht
>> umgedreht ?
>
> Ja ist richtig, ich brauch nur den Code

Das kann nicht richtig sein. Fuer diesen hausaufgabe brauchst du 
vielleicht 'nur' den Code um es den Lehrer zeigen zu koennen, aber um es 
zu verstehen und weiter im studium/arbeit damit etwas zu koennen 
brauchst du auch zu verstehen was du machst.
Bestudiere dich mal wie ein Stromquelle funktioniert.

Denis B. schrieb:
>> - Wenn 6lux=0.6uA und 60lux=6uA wieso ist dann 10lux=0.8uA ???
> Sie haben recht. War ein Tipp Fehler. Habe angepasst(s.Anhang)
Dann bestudiere es nochmal....

Sorry

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.