Geschwindigkeitsmesser für Kegelbahn

Hallo zusammen,

wie der Titel sagt, möchte ich für eine Kegelbahn eine mobile Geschwindigkeitsmessanlage bauen.

Im Netz habe ich bei www.elektronik-labor.de einen Aufbau gefunden, der für meine Zwecke genau
richtig ist, da sämtliche Kabel nur auf einer Seite verlaufen und es auch funktioniert, wenn Objekte
unterschiedlicher Größe die Lichtschranke unterbrechen. Es soll aus der definierten Strecke (hier
50 cm) und der gemessenen Zeit zwischen den Unterbrechungen die Geschwindigkeit berechnet
werden.

Link: Geschwindigkeit

Ich habe keinen Laserpointer,sondern ein Lasermodul benutz, dass an 5V hängt.
Dieses ist auf eine Photodiode vom Typ BPW34 gerichtet. Der eine Pol hängt über 100 kOhm an +5V,
der andere geht auf den Arduino Pin 8.
Mit dem Messgerät sehe ich, dass die Spannung abfällt, sobald der Laser unterbrochen wird (von 450
auf 250 mV).
Trotzdem funktioniert es nicht, ich bekomme keine Messung.
Habe ich die falsche Photodiode? Denn im Artikel spricht Herr Sinning davon, dass

Die Kathode der BPW34 ist an +5V angeschlossen und geht über 100 k an Masse, die Mitte geht an den Input Capture Pin PB0, pin8 vom Arduino.

Ich habe aber nur 2 Kontakte. Ich habe schon alle möglichen Kombinationen und Polungen ausprobiert,
aber es geht einfach nicht...
Auch auf dem seriellen Monitor kommt nichts.

Ich hoffe jemand findet meinen Fehler und kann mir helfen.

Ich füge noch meinen Code ein, der eigentlich größtenteils dem Original-Code entspricht, ich
habe nur mein Display eingebaut.

Vielen Dank schonmal im Voraus

Emmeff

/*
 Quelle: http://www.elektronik-labor.de/Arduino/Speed.html
 von Gerd Sinning
 
 Arduino Speedy
 measure time and calculate speed
 uses a laserpointer, 2 mirrors and a photodiode for light barrier
 
 photodiode signal goes to Input Capture Pin on PB0, Arduino pin8
 measures time from falling edge to next falling edge = total time
 first measures time from falling edge to next rising edge = time1 (low time)
 useful to abt 50 us, minimum low time is 4 us
 
 serial output and LCD defined/not used

 GS 3-2014
 
  This is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
*/


//include the library code:
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
/**********************************************************/
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
/* Connect Display-Pin SDA to A4 and SCL to A5 */

#ifndef F_CPU
#define F_CPU 16000000L
#endif

#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif

int pinLed=13;         // on board Led
int pinStart=9;        // HIGH to measure, LOW to adjust
int pinTrig=8;         // ICP pin input 

volatile unsigned char p_mlt = 0;       // Timer1 Overflows total
volatile unsigned char p_mlt1 = 0;      // Timer1 Overflows low time
volatile unsigned char p_ready;         // Flag
volatile unsigned int  StartTime = 0;   // ICP pin 1st edge falling
volatile unsigned int  EndTime1 = 0;    // ICP pin next edge rising
volatile unsigned int  EndTime2 = 0;    // ICP pin last edge falling

ISR( TIMER1_CAPT_vect )
{
  static unsigned char edge = 0;

   if( p_ready ) return;     // wait until display done                
 
   if( edge == 0 )                // 1st edge falling 
  {
    StartTime = ICR1;
    TIMSK1 = 0;                   // stop Interrupts , Capture & Overflow
    p_mlt = 0;
    p_mlt1 = 0;
    TCCR1B |= (1<<ICES1);               // then change to rising 
    ++edge;       // 
    TIMSK1 = (1<<ICIE1) | (1<<TOIE1);   // enable Interrupts , Capture & Overflow
  }

  else if( edge == 1 )          // 2nd edge rising
  {
    EndTime1 = ICR1;      // time high
    TIMSK1 = 0;                   // stop Interrupts , Capture & Overflow
    p_mlt1 = p_mlt;
    TCCR1B &= ~(1<<ICES1);              // then change ICES1 to falling
    ++edge;       // 
    TIMSK1 = (1<<ICIE1) | (1<<TOIE1);   // enable Interrupts , Capture & Overflow
  }

  else if( edge == 2 )           // 3rd edge falling
  {
    EndTime2 = ICR1;      // total time
    p_ready = TRUE;                 // p_ready to display
    edge = 0;        
  }
}

ISR( TIMER1_OVF_vect )                  // count overflow
{
  p_mlt++;
}

void setup() {
  pinMode(pinLed, OUTPUT);    // on board led
  pinMode(pinStart,  INPUT_PULLUP); // start Input Capture, pin9
  pinMode(pinTrig,  INPUT);         // Input Capture Pin on PB0, pin8

/* Initialize LCD */
  lcd.init();  //initialize the lcd
  lcd.backlight();  //open the backlight;
  
  lcd.setCursor(0, 0); // set the cursor to column 3, line 0
  lcd.print("KC Hoch die Tas-");  // Print a message to the LCD
  
  lcd.setCursor(0, 1); // set the cursor to column 2, line 1
  lcd.print("sen - Speedy");  // Print a message to the LCD
  
  Serial.begin(9600);     // prepare for serial out
  Serial.println("Pulsewidth to Speed");


  TCCR1A = 0;                           // 
  TIMSK1 = (1<<ICIE1) | (1<<TOIE1);   // 2 Interrupts: Capture & Overflow
  TCCR1B &= ~(1<<ICES1);                // ICES1 trigger on falling
  TIMSK2 &= ~(1<<OCIE2A);       // disable Timer2 Interrupt, millis
  sei();
}

void loop()
{
  char FString[12];
  double myTime = 0.0;
  double pwpercent = 0.0;
  unsigned long  pwidth;
  unsigned long  pwidth1;

  if (digitalRead(pinStart) == HIGH)          // start ISR else adjust
   {

    if( p_ready )
    {
      TCCR1B = 0;                        // stop Input Capture 

      pwidth1 = (p_mlt1 * 65536) + EndTime1 - StartTime;
      Serial.print("PW low= ");    
      Serial.print(pwidth1);                 //PW1 in counts
     
      pwidth = (p_mlt * 65536) + EndTime2 - StartTime;
      Serial.print("  PWtotal= ");
      Serial.print(pwidth);                  //PW total in counts
      Serial.print("  PW % = ");
      pwpercent = pwidth1*100.0/pwidth; 
      dtostrf( pwpercent, 5, 2, FString );   // 2 digits
      Serial.println(FString);               //PW in counts

      myTime = pwidth/16.0 ;                 // in usec
      dtostrf( myTime, 8, 2, FString );      // 2 digits
      
      Serial.print("Time= ");
      Serial.print(FString);
      Serial.print(" usec  "); 
      lcd.print(FString);
     
      myTime = (p_mlt * 65536) + EndTime2 - StartTime;
      myTime = (F_CPU *25.0)/ myTime;           // 25cm  / t
      dtostrf( myTime, 8, 3, FString );   // 3 digits
      
      Serial.print("Speed= ");
      Serial.print(FString);
      Serial.println(" cm/sec"); 
      lcd.print(FString);
      //
      p_ready = FALSE;
      digitalWrite(pinLed,!digitalRead(pinLed));  // blink Led 13 on board
      TCCR1B = (1<<ICES1)  | (1<<CS10);     // enable Input Capture Edge, PreScale 1
      TCCR1B &= ~(1<<ICES1);                      // ICES1 trigger on falling
      
    } //if( p_ready )
    }
    else                                          // stop to adjust 
    {
        TCCR1B = 0;
        digitalWrite(pinLed,digitalRead(pinTrig));  // Led 13 on board shows status       
    }

//  delay(50);
  
}

Bitte setze Deinen Sketch in Codetags (oben links </> im Foreneditor oder [code] davor und [/code] dahinter - ohne die *).
Das kannst Du auch noch nachträglich durch Editieren tun. Bitte mach das, der Sketch ist besser zu lesen, besonders auf mobilen Geräten.

Dein Hardwareaufbau entspricht nicht dem in Deiner Quelle angegebenen.

Deine Version:

Dieses ist auf eine Photodiode vom Typ BPW34 gerichtet. Der eine Pol hängt über 100 kOhm an +5V, der andere geht auf den Arduino Pin 8.

Die von Dir zitierte Version:

Die Kathode der BPW34 ist an +5V angeschlossen und geht über 100 k an Masse, die Mitte geht an den Input Capture Pin PB0, pin8 vom Arduino.

Gruß Tommy

Danke für den Tip, die Option hatte ich gesucht, aber nicht gefunden.

Dann verstehe ich die Anweisung aus der Quelle nicht.

Ich habe an der Diode 2 Pole, wie soll ich einen an Masse, einen an +5V und einen an Pin8?

Wo ist mein Denkfehler?

Grüße
Emmeff

Die Schaltung an sich ist schon ganz ok, aber die Anode gehört Richtung Plus, die Kathode Richtung Minus. Ich schreibe "Richtung", weil die Diode mal gegen GND oder auch an Plus geschaltet sein kann.

Statt einer Fotodiode setze ich immer einen Fototransistor ein. Größerer Spannungshub = besseres Erkennen. Geht je nach Lichteinfall auch als digitales Signal durch, man spart sich den analogRead.

Hallo Klaus,

umgedreht hatte ich das Ding auch schon, funktioniert auch nicht.
Dann werde ich mir mal einen Fototransistor besorgen und es damit versuchen...

Danke für den Tip.

Grüße
Emmeff

Emmeff:
Danke für den Tip, die Option hatte ich gesucht, aber nicht gefunden.

Dann verstehe ich die Anweisung aus der Quelle nicht.

Ich habe an der Diode 2 Pole, wie soll ich einen an Masse, einen an +5V und einen an Pin8?

Wo ist mein Denkfehler?

Grüße
Emmeff

+5V ---(K) Diode (A) -----Pin ---- 110 kOhm --- GND

@Klaus_ww: Photodioden werden in Sperrichtung betrieben!

Gruß Tommy

Tommy,
Du bist mein Held!!! Es funktioniert!!
Anode am Pin 8 und über 100kOhm an Ground und dann funktionierts...

Jetzt muss ich noch herausfinden, wie ich das Programm dazu bringe,
die Anzeige ein bischen schön auf dem Diplay darzustellen.

Vielen, vielen Dank für die Hilfe.

Wenn alles fertig ist, werde ich hier mal posten, wie es aussieht.

Grüße und einen schönen Abend.

Emmeff

Photodioden werden in Sperrichtung betrieben!

Au weia, hast natürlich recht. War gedanklich schon bei meinem Transistor :smiling_imp:

Aber wenn's jetzt läuft dann ist's ja prima.

Prima, dass es funktioniert und danke für die Rückmeldung.

Gruß Tommy

Für Photodioden gibt es 2 Betriebsmodi: als Fotoelement in Sperrichtung, oder als veränderlicher Widerstand in Durchlassrichtung. Was ich nur nicht ganz begreife und was wahrscheinlich dein ursprüngliches Problem war, das du die Photodiode an einen Digitalpin anschließt. An einem Analogpin (wenn man ihn denn auch analog ausliest) hättest du den Spannungshub von 250 auf 450 mV sicher detektieren können

Damit kommen wir aber zu meinem zweiten Problem, da ich keine Ahnung vom Programmieren habe,
verstehe ich nur in Ansätzen, was das Programm eigentlich macht. Insofern wäre die Änderung
auf einen Analog-Port jenseits meiner Fähigkeiten gewesen.
Aber es funktioniert jetzt und ich habe es auch geschafft, die Anzeige "aufzuhübschen" und in
km/h umzuwandeln.

Jetzt muss ich es nur noch endgültig zusammenbauen und dann kommen Fotos und eine genaue
Beschreibung.

Grüße
Emmeff

Wenn du fertig bist kannst du dein Projekt gerne hier posten:

https://forum.arduino.cc/index.php?topic=372623.0

Hallo zusammen,

hier:
http://forum.arduino.cc/index.php?topic=372623.msg3156980#msg3156980

ist das fertige Projekt.

Danke nochmal an alle, die sich Gedanken gemacht haben, insbesondere an Tommy.

Grüße

Emmeff