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.
Code:'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







Zitieren


Lesezeichen