stfan1409
12.10.2016, 20:50
Hallo,
ich möchte kurz einen Code zur Verfügung stellen, weil ich nichts passendes gefunden habe:
Problem:
Wasseruhr im Keller auswerten bzw. Impulse zählen. Meine Wasseruhr hat einen Zeiger, der pro Liter eine Umdrehung macht. Am Ende des Zeigers ist eine Metallfläche.
Ich habe eine Reflexlichtschranke "CNY70" direkt über dem Zeiger befestigt, so dass die Lichtschranke die Metallfläche einmal pro Liter "sieht".
Leider "stört" manchmal die Sonne durch das Kellerfenster, sodass die Lichtschranke bei Sonneneinstrahlung immer eine Rückmeldung gibt. Deshalb gebe ich eine Frequenz von 1 kHz auf die Sende LED.
Der µC bekommt das Empfangssignal über den Analogeingang. Anhand der Eingangsspannung wird der Abstand - also Zeiger da, oder nicht da - ausgewertet. Außerdem wird die Frequenz ausgewertet.
Die Schaltung läuft nun ca. 4 Monate störungsfrei, ohne dass die Sonneneinstrahlung sich bemerkbar macht.
Wenn ich mal wieder Zeit habe, baue ich die Schaltung auf einem kleineren µC und lasse das Display weg. Allerdings ist das Display praktisch, um die Werte für die Schaltschwelle zu ermitteln, also wann der Zeiger erkannt wird und wann nicht.
Hierfür am Besten die Sende LED kostant und nicht gepulst ansteuern.
Der µC gibt pro Liter einen Impuls, ähnlich S0-Ausgang, an meine Hausautomatisierung.
'Lichtschranke um Wasserzähler auszuwerten
'CNY70 Reflexlichtschranke wird mit 1kHz gepulst angesteuert.
'Das empfangene Signal vom Analogeingang wird ausgewertet:
'd.h. Signalstärke - also der Abstand und zusätzlich die Frequenz
'um Störlicht zu filtern
'Sende-LED mit 100 OhmWiderstand(5V) an Portd.5 (angesteuert in der Timer0 Routine)
'Empfangstransistor an Analogeingang0 (+5V -> Kollektor; Emitter -> µC & 10k Widerstand an MASSE)
'-------------------------------------------------------------------------------
'Konfiguration µC:
$regfile = "m32def.dat" 'AT-Mega32
$crystal = 8000000 '14745600
$baud = 9600 'Baudrate definieren
'-------------------------------------------------------------------------------
'Ein- Ausgänge:
Ddra = &B0000000 '1 Ausgang, 0 Eingang = Pin PA7-0
Ddrb = &B1111111 '1 Ausgang, 0 Eingang = Pin PB7-0
Ddrc = &B1111111 '1 Ausgang, 0 Eingang = Pin PC7-0
Ddrd = &B1110111 '1 Ausgang, 0 Eingang = Pin PD7-0
Porta = &B0000000 '1 = Pullup
Portb = &B0000000 '1 = Pullup
Portc = &B0000000 '1 = Pullup
Portd = &B0000000 '1 = Pullup
'-------------------------------------------------------------------------------
'Timer:
'TIMER 0 1kHz Impulse für Sende LED
'Timer0 = 8Bit
Config Timer0 = Timer , Prescale = 64 'Teiler 1/8/64/256/1024
Enable Timer0 'timer einschalten
Const Timer0vorgabe = 193
Timer0 = Timer0vorgabe
On Timer0 Ontimer0overflow 'Unteprogramm aufrufen
'-------------------------------------------------------------------------------
'Analogmessung:
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc 'Starte analog Messung
'-------------------------------------------------------------------------------
'LCD konfiguration:
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5 , E2 = Portb.6
Config Lcd = 40 * 4
Cursor Off Noblink
Enable Interrupts
'-------------------------------------------------------------------------------
'Variablen:
'-------------------------------------------------------------------------------
Dim ___lcdno As Bit 'für DISPLAY
Dim Zaehler_out As Word 'Variable wird von Timer0 hochgezählt also mit ca. 1kHz
Dim Zaehler_in As Word 'Empfangene Impulse
Dim Lichtschranke As Bit
Dim Zaehler_wasser As Long 'Wasserzählerwert
Dim Analog0 As Word 'Analogeingang einlesen
Dim Merker0 As Bit
'-------------------------------------------------------------------------------
'Vor Programmstart:
'LCD initialisieren:
___lcdno = 0
Initlcd
___lcdno = 1
Initlcd
Enable Interrupts
Print "Lichtschranke_V03.1.bas"
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Do
Analog0 = Getadc(0) 'Analogeingang einlesen
'mit Analogeingang zählen:
If Analog0 > 500 And Merker0 = 0 Then 'wenn der Abstand zum Sensor stimmt, also Zeiger erkannt,
Merker0 = 1 'Hilfsmerker setzen, damit nicht mehrfach gezählt wird
Incr Zaehler_in 'und Variable(Frequenzauswertung eingehende Impulse) um eins hochzählen
End If
If Analog0 < 400 Then 'wenn Zeiger nicht erkannt bzw. Sende Led aus
Merker0 = 0 'Hilfsmerker zurücksetzen
End If
If Zaehler_out > 500 Then 'wenn gesendete Impulse von LED > 500, also ca. nach 0,5 Sekunden
If Zaehler_in > 200 Then 'prüfen, ob genug Impulse ( etwas weniger als Hälfte Zaehler_out) durchgekommen sind
If Lichtschranke = 0 Then 'prüfen, ob Variable noch nicht gesetzt ist, damit nicht doppelt gezählt wird
Incr Zaehler_wasser 'Zählerstand Wasserzähler hochzählen
End If
Lichtschranke = 1 'Hilfsmerker setzen
Else
Lichtschranke = 0
End If
Print Zaehler_out ; " " ; Zaehler_in ; " " ; Lichtschranke ; " Analog:" ; Analog0 'Status ausgeben über die serielle Schnittstelle
Locate 1 , 1
Lcd Lichtschranke ; " Ana:" ; Analog0 ; "+" ; Zaehler_wasser ; " " 'Status ausgeben Display
Zaehler_out = 0 'zähler zurücksetzen
Zaehler_in = 0 'zähler zurücksetzen
End If
Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'ENDE - Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
End
'-------------------------------------------------------------------------------
'TIMER SPRUNGMARKEN:
Ontimer0overflow:
Timer0 = Timer0vorgabe
Toggle Portd.5 'Ausgang für Sende LED
Incr Zaehler_out 'gesendete Impulse zählen
Return
ich möchte kurz einen Code zur Verfügung stellen, weil ich nichts passendes gefunden habe:
Problem:
Wasseruhr im Keller auswerten bzw. Impulse zählen. Meine Wasseruhr hat einen Zeiger, der pro Liter eine Umdrehung macht. Am Ende des Zeigers ist eine Metallfläche.
Ich habe eine Reflexlichtschranke "CNY70" direkt über dem Zeiger befestigt, so dass die Lichtschranke die Metallfläche einmal pro Liter "sieht".
Leider "stört" manchmal die Sonne durch das Kellerfenster, sodass die Lichtschranke bei Sonneneinstrahlung immer eine Rückmeldung gibt. Deshalb gebe ich eine Frequenz von 1 kHz auf die Sende LED.
Der µC bekommt das Empfangssignal über den Analogeingang. Anhand der Eingangsspannung wird der Abstand - also Zeiger da, oder nicht da - ausgewertet. Außerdem wird die Frequenz ausgewertet.
Die Schaltung läuft nun ca. 4 Monate störungsfrei, ohne dass die Sonneneinstrahlung sich bemerkbar macht.
Wenn ich mal wieder Zeit habe, baue ich die Schaltung auf einem kleineren µC und lasse das Display weg. Allerdings ist das Display praktisch, um die Werte für die Schaltschwelle zu ermitteln, also wann der Zeiger erkannt wird und wann nicht.
Hierfür am Besten die Sende LED kostant und nicht gepulst ansteuern.
Der µC gibt pro Liter einen Impuls, ähnlich S0-Ausgang, an meine Hausautomatisierung.
'Lichtschranke um Wasserzähler auszuwerten
'CNY70 Reflexlichtschranke wird mit 1kHz gepulst angesteuert.
'Das empfangene Signal vom Analogeingang wird ausgewertet:
'd.h. Signalstärke - also der Abstand und zusätzlich die Frequenz
'um Störlicht zu filtern
'Sende-LED mit 100 OhmWiderstand(5V) an Portd.5 (angesteuert in der Timer0 Routine)
'Empfangstransistor an Analogeingang0 (+5V -> Kollektor; Emitter -> µC & 10k Widerstand an MASSE)
'-------------------------------------------------------------------------------
'Konfiguration µC:
$regfile = "m32def.dat" 'AT-Mega32
$crystal = 8000000 '14745600
$baud = 9600 'Baudrate definieren
'-------------------------------------------------------------------------------
'Ein- Ausgänge:
Ddra = &B0000000 '1 Ausgang, 0 Eingang = Pin PA7-0
Ddrb = &B1111111 '1 Ausgang, 0 Eingang = Pin PB7-0
Ddrc = &B1111111 '1 Ausgang, 0 Eingang = Pin PC7-0
Ddrd = &B1110111 '1 Ausgang, 0 Eingang = Pin PD7-0
Porta = &B0000000 '1 = Pullup
Portb = &B0000000 '1 = Pullup
Portc = &B0000000 '1 = Pullup
Portd = &B0000000 '1 = Pullup
'-------------------------------------------------------------------------------
'Timer:
'TIMER 0 1kHz Impulse für Sende LED
'Timer0 = 8Bit
Config Timer0 = Timer , Prescale = 64 'Teiler 1/8/64/256/1024
Enable Timer0 'timer einschalten
Const Timer0vorgabe = 193
Timer0 = Timer0vorgabe
On Timer0 Ontimer0overflow 'Unteprogramm aufrufen
'-------------------------------------------------------------------------------
'Analogmessung:
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc 'Starte analog Messung
'-------------------------------------------------------------------------------
'LCD konfiguration:
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5 , E2 = Portb.6
Config Lcd = 40 * 4
Cursor Off Noblink
Enable Interrupts
'-------------------------------------------------------------------------------
'Variablen:
'-------------------------------------------------------------------------------
Dim ___lcdno As Bit 'für DISPLAY
Dim Zaehler_out As Word 'Variable wird von Timer0 hochgezählt also mit ca. 1kHz
Dim Zaehler_in As Word 'Empfangene Impulse
Dim Lichtschranke As Bit
Dim Zaehler_wasser As Long 'Wasserzählerwert
Dim Analog0 As Word 'Analogeingang einlesen
Dim Merker0 As Bit
'-------------------------------------------------------------------------------
'Vor Programmstart:
'LCD initialisieren:
___lcdno = 0
Initlcd
___lcdno = 1
Initlcd
Enable Interrupts
Print "Lichtschranke_V03.1.bas"
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Do
Analog0 = Getadc(0) 'Analogeingang einlesen
'mit Analogeingang zählen:
If Analog0 > 500 And Merker0 = 0 Then 'wenn der Abstand zum Sensor stimmt, also Zeiger erkannt,
Merker0 = 1 'Hilfsmerker setzen, damit nicht mehrfach gezählt wird
Incr Zaehler_in 'und Variable(Frequenzauswertung eingehende Impulse) um eins hochzählen
End If
If Analog0 < 400 Then 'wenn Zeiger nicht erkannt bzw. Sende Led aus
Merker0 = 0 'Hilfsmerker zurücksetzen
End If
If Zaehler_out > 500 Then 'wenn gesendete Impulse von LED > 500, also ca. nach 0,5 Sekunden
If Zaehler_in > 200 Then 'prüfen, ob genug Impulse ( etwas weniger als Hälfte Zaehler_out) durchgekommen sind
If Lichtschranke = 0 Then 'prüfen, ob Variable noch nicht gesetzt ist, damit nicht doppelt gezählt wird
Incr Zaehler_wasser 'Zählerstand Wasserzähler hochzählen
End If
Lichtschranke = 1 'Hilfsmerker setzen
Else
Lichtschranke = 0
End If
Print Zaehler_out ; " " ; Zaehler_in ; " " ; Lichtschranke ; " Analog:" ; Analog0 'Status ausgeben über die serielle Schnittstelle
Locate 1 , 1
Lcd Lichtschranke ; " Ana:" ; Analog0 ; "+" ; Zaehler_wasser ; " " 'Status ausgeben Display
Zaehler_out = 0 'zähler zurücksetzen
Zaehler_in = 0 'zähler zurücksetzen
End If
Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'ENDE - Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
End
'-------------------------------------------------------------------------------
'TIMER SPRUNGMARKEN:
Ontimer0overflow:
Timer0 = Timer0vorgabe
Toggle Portd.5 'Ausgang für Sende LED
Incr Zaehler_out 'gesendete Impulse zählen
Return