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