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);
}