Sehr dringend Hilfe für Stoppuhr benötigt

Hallo in die Runde,

bin neu hier und bastele auch erst seit wenigen Tagen mit einem UNO herum. Hintergrund meines Anliegens ist, dass einem kleinen Hundeverein in unserer Stadt die Zeitnahme mittels einer älteren Stoppuhr abgeraucht ist und etwas Neues an die Lichtschranken soll. Da sich das Budget des Vereins sehr in Grenzen hält, kommt eine komplette Neuanschaffung nicht in Frage. Ersatzteile für die alte Uhr gibt es leider nicht mehr.

Nun soll schon am kommenden Sonntag eine Zeitmessung verfügbar sein. Für mich als Anfänger in Sachen Arduino ist das in 3 Tagen nicht zu leisten, auch wenn ich mich jetzt Tag und Nacht hinsetze um zu lernen. Deshalb bitte ich hier um eure Hife.

Nun zur Aufgabe:
Ich habe einen UNO mit LCD Keypad gekauft und einen vorhandenen Sketch in setup() und loop() etwas umgebaut. Die benötigten Stellen zählen nun auf dem Display hoch, wie gewünscht.

Was mir jedoch noch fehlt, ist die Anschaltung der beiden Lichtschranken für START und STOP sowie ein TASTER für RESET und das Halten des Nullzustandes, bis LS schaltet.

Die LS laufen empfängerseitig mit 5V, sollten also ggf. direkt anschaltbar sein.
http://www.produktinfo.conrad.com/datenblaetter/125000-149999/130242-an-01-ml-Zusatzlichtschranke_fuer_130202.pdf (Schaltplan siehe Seite 4).

Hier ist der bisherige Code:

/*
  Simple stopwatch code for the SainSmart LCD & Keypad Shield
  This example code is in the public domain
  
  ---------------------------------------------------------------------
   
  Pins used by LCD & Keypad Shield:
  
    A0: Buttons, analog input from voltage ladder
    D4: LCD bit 4
    D5: LCD bit 5
    D6: LCD bit 6
    D7: LCD bit 7
    D8: LCD RS
    D9: LCD E
    D3: LCD Backlight (high = on, also has pullup high so default is on)
  
  ADC voltages for the 5 buttons on analog input pin A0:
  
    RIGHT:  0.00V :   0 @ 8bit ;   0 @ 10 bit
    UP:     0.71V :  36 @ 8bit ; 145 @ 10 bit
    DOWN:   1.61V :  82 @ 8bit ; 329 @ 10 bit
    LEFT:   2.47V : 126 @ 8bit ; 505 @ 10 bit
    SELECT: 3.62V : 185 @ 8bit ; 741 @ 10 bit
*/
/*--------------------------------------------------------------------------------------
  Includes
--------------------------------------------------------------------------------------*/
#include <Wire.h>
#include <LiquidCrystal.h>   // include LCD library
/*--------------------------------------------------------------------------------------
  Defines
--------------------------------------------------------------------------------------*/
// Pins in use
#define BUTTON_ADC_PIN           A0  // A0 is the button ADC input
#define LCD_BACKLIGHT_PIN         3  // D3 controls LCD backlight
// ADC readings expected for the 5 buttons on the ADC input
#define RIGHT_10BIT_ADC           0  // right
#define UP_10BIT_ADC            145  // up
#define DOWN_10BIT_ADC          329  // down
#define LEFT_10BIT_ADC          505  // left
#define SELECT_10BIT_ADC        741  // right
#define BUTTONHYSTERESIS         10  // hysteresis for valid button sensing window
//return values for ReadButtons()
#define BUTTON_NONE               0  // 
#define BUTTON_RIGHT              1  // 
#define BUTTON_UP                 2  // 
#define BUTTON_DOWN               3  // 
#define BUTTON_LEFT               4  // 
#define BUTTON_SELECT             5  // 
//some example macros with friendly labels for LCD backlight/pin control, tested and can be swapped into the example code as you like
#define LCD_BACKLIGHT_OFF()     digitalWrite( LCD_BACKLIGHT_PIN, LOW )
#define LCD_BACKLIGHT_ON()      digitalWrite( LCD_BACKLIGHT_PIN, HIGH )
#define LCD_BACKLIGHT(state)    { if( state ){digitalWrite( LCD_BACKLIGHT_PIN, HIGH );}else{digitalWrite( LCD_BACKLIGHT_PIN, LOW );} }
/*--------------------------------------------------------------------------------------
  Variables
--------------------------------------------------------------------------------------*/
byte buttonJustPressed  = false;         //this will be true after a ReadButtons() call if triggered
byte buttonJustReleased = false;         //this will be true after a ReadButtons() call if triggered
byte buttonWas          = BUTTON_NONE;   //used by ReadButtons() for detection of button events

int hsekunden = 0;
int sekunden  = 0;
int minuten   = 0;
	 
/*--------------------------------------------------------------------------------------
  Init the LCD library with the LCD pins to be used
--------------------------------------------------------------------------------------*/
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );   //Pins for the freetronics 16x2 LCD shield. LCD: ( RS, E, LCD-D4, LCD-D5, LCD-D6, LCD-D7 )
/*--------------------------------------------------------------------------------------
  setup()
  Called by the Arduino framework once, before the main loop begins
--------------------------------------------------------------------------------------*/
void setup()
{
   //button adc input
   pinMode( BUTTON_ADC_PIN, INPUT );         //ensure A0 is an input
   digitalWrite( BUTTON_ADC_PIN, LOW );      //ensure pullup is off on A0
   //lcd backlight control
   digitalWrite( LCD_BACKLIGHT_PIN, HIGH );  //backlight control pin D3 is high (on)
   pinMode( LCD_BACKLIGHT_PIN, OUTPUT );     //D3 is an output
   //set up the LCD number of columns and rows: 
   lcd.begin( 16, 2 );
   //Print some initial text to the LCD.
   lcd.setCursor( 0, 0 );   //top left
   //          1234567890123456
   lcd.print( "Hunderennen 2014" );
   //
   lcd.setCursor( 0, 1 );   //bottom left
   //          1234567890123456
   lcd.print( "Zeit:" );

}
/*--------------------------------------------------------------------------------------
  loop()
  Arduino main loop
--------------------------------------------------------------------------------------*/
void loop()
{  
   
	hsekunden = ( (millis() / 1) % 60 );
	// setzt doppelpunkte vor hsekunden
	lcd.setCursor( 13, 1 );
		lcd.print( ":" );		   
	// schreibt den wert der hundertstel mit 2 stellen
	lcd.setCursor( 14, 2 );
	if( hsekunden <= 9 )
		lcd.print( "0" );
	lcd.print( hsekunden, DEC );
   
	sekunden = ( (millis() / 1000) % 60 );
	// setzt doppelpunkte vor sekunden
	lcd.setCursor( 10, 1 );
		lcd.print( ":" );		   
	// schreibt den wert der sekunden mit 2 stellen
	lcd.setCursor( 11, 1 );
	if( sekunden <= 9 )
		lcd.print( "0" );
	lcd.print( sekunden, DEC );
		   
	minuten = ( (millis() / 100000) % 60 );	   
	// schreibt den wert der minuten mit 2 stellen
	lcd.setCursor( 8, 1 );
	if( minuten <= 9 )
		lcd.print( "0" );
	lcd.print( minuten, DEC );
        
}

Gibt es keine Stoppuhren mehr, die man in der Hand halten kann mit Start und Stop? Somit sehe ich nicht das Problem der Dringlichkeit.

Es sollte auch für einen Anfänger kein Problem sein, den Sketch selber in der Zeit auf die Beine zu stellen. Dafür bedarf es keine Tage und Nächte.

Lichtschranken können ähnlich wie Taster genutzt werden.

Der Programmablauf kann wie folgt aussehen.

1) Abfragen, ob deine LS frei sind.
2) Wenn LS1 (Start) zum ersten Mal kommt, einen Timer starten, der solange immer eine Sekunde dazuaddiert
3) Wenn LS zum ersten Mal kommt, keine Sekunde mehr dazuaddieren.
4) Timer neustarten, wenn Reset gedrückt wurde.

Danke für dein Feedback.

Handstoppung provoziert nur unnötige Diskussionen mit Teilnehmern, wenn die Zeiten nur Hundertstel auseinander liegen, war kürzlich so als das probiert wurde. :frowning:

Leider habe ich noch einen Job und kann mich zurzeit wirklich nicht ausführlich mit der Sache beschäftigen.

Wenn dieses Forum nur dazu da ist, Anfängern zu sagen, dass sie im Grunde nicht fragen sollen, habe ich wohl etwas falsch verstanden. Ist dann so wie "Huch ein Kunden, husch husch, weg!" :wink:

Es geht nicht darum, dass man nicht fragen darf. Nur kommt von dir keine Initiative.
Das Forum ist nicht dafür da, wenn ich etwas nicht machen möchte, in der Hoffnung, ein anderer macht das für mich "mal eben" so für lau.

Du bist des weiteren auch kein Kunde von uns. Das Forum hegt keinerlei kommerzielle Absichten. Es ist freiwilliger Support zu einer Entwicklungsumgebung, die frei zur Verfügung steht. Lediglich die Boards werden verkauft. Das ist schon klar, dass man diese nicht verschenken kann.

Handelt es sich bei deinem UNO um einen Originalen (Preis ~25€)? Wenn nein, kannst du auch für den Vertrieb kein Kunde sein. Das Geld floß dann in die Taschen von anderen Leuten, die keine Zeit in die IDE gesteckt haben. Nur mal so am Rande. Ob Clone oder Orginal-Diskussion möchte ich hier nicht anfangen.

Einen Job haben andere auch, ist nicht so das nichts anderes zu tun wäre. Es mag auch Leute geben, die mit sowas (Programmierung) ihre täglichen Brötchen verdienen müssen.

Für den Anstoß hier mal folgender Sketch von mir. Die Funktionen sind einfach gehalten. Auf Tasterentprellen wurde verzichtet, da es hier keinesfalls erforderlich ist. Die LEDs sind nicht notwendig.

Da ich kein LCD-Display mehr besitzte, welches die Tasten über die Analogen Eingänge ausliest, kann ich das mit deinem Sketch nicht verbinden. Des weiteren habe ich auch keine Lichtschranken rumliegen.
Die Anpassung muss deinerseits erfolgen oder von jemand anderem.

Der Sketch ist so aufgebaut,
dass sich die Variable die vorlaufende Zeit von millis() beim ersten Durchlaufen der Lichtschranke merkt. Diese wird dann fortlaufend auf dem Display in 00:00:0000 ausgegeben.

Sobald der Hund die 2. Lichtschranke durchläuft, wird diese Zeit nicht weitergezählt. Sollte die letzte Lichtschranke zuerst passiert worden sein, zB. von einem unachtsamen Hundebesitzer ]:D, so wird das Programm wieder zurückgesetzt.

Ist die Stoppuhr angehalten, bleibt der Wert solange stehen, bis der Reset Taster gedrückt wird, stehen. Danach beginnt dieser wieder bei 0.

Desweiteren ist dieser nur schnell geschrieben worden. Fehler können sich eingeschlichen haben, sollte aber nicht der Fall sein. Getestet/Debuggt wurde er nicht und somit auch keinerlei Gewährleistung auf Funktion.

#define LED_DEBUG

#define LS_START 2
#define LS_STOP  10
#define LS_RESET  12

#define LED_START 3
#define LED_STOP 11


void setup() 
{
  pinMode(LS_START, INPUT);
  pinMode(LS_STOP, INPUT);
  pinMode(LS_RESET, INPUT);

  pinMode(LED_START, OUTPUT);
  pinMode(LED_STOP, OUTPUT);
}

void loop()
{
  static uint8_t counter_begin;
  static uint8_t counter_end;
  static uint32_t counter_raw_value;
  static uint32_t counter_value;

  if(digitalRead(LS_START) && !counter_begin)
  {
    /* Wenn LS_START zum ersten Mal erkannt wird,
     signalisiert LED_START, dass der Zähler gestartet ist */
    counter_begin = 1;
    digitalWrite(LED_START, 1);
    digitalWrite(LED_STOP, 0);
    counter_raw_value = millis();
  }
  if(digitalRead(LS_STOP) && !counter_end)
  {
    /* Wenn LS_STOP zum ersten Mal erkannt wird,
     signalisiert LED_STOP, dass der Zähler gestoppt ist */
    counter_end = 1;
    digitalWrite(LED_STOP, 1); 
    digitalWrite(LED_START, 0);
  }

  if(counter_begin && !counter_end) 
  {
    /* Aktualisiert den Wert solange LS_STOP nocht nicht gekommen ist */
    counter_value = millis() - counter_raw_value;
  }

  if(digitalRead(LS_RESET) || !counter_begin && counter_end)
  {
    /* Setzt den Zähler zurück, wenn der LS_RESET (Taster) kommt.
     Des weiteren wird der Zähler auch zurückgesetzt, wenn
     der Zähler die Anforderung bekommt "STOP", ohne dass diese 
     vor gestartet ist */
    counter_begin = 0;
    counter_end = 0;
    digitalWrite(LED_STOP, 0);
    digitalWrite(LED_START, 0); 
    counter_value = 0;
  }

  static uint32_t last_millis;
  if(millis() - last_millis >= 1000)
  {
    /* Jede Sekunde das Display updaten */
    last_millis = millis();

    uint8_t counter_minutes = counter_value / 60000;
    uint8_t counter_seconds = counter_value % 60000;
    uint16_t counter_millis = counter_value % 1000;

    lcd.setCursor(0, 0);
    leading_zero(counter_minutes, 2);
    lcd.print(":");
    leading_zero(counter_seconds, 2);
    lcd.print(":");
    leading_zero(counter_millis, 3);
  }
}

void leading_zero(uint16_t value, uint8_t digits)
{
  /* Fuellt leere Stellen mit "0" aus */
  if(digits == 2)
  {
    if(value < 10) lcd.print("0");
    lcd.print(value);
  }
  else if(digits == 3)
  {
    if(value < 100) 
    {
      lcd.print("0");
      if(value < 10) lcd.print("0");
    }
  }
  else return;  
}

tilloriemer:
Was mir jedoch noch fehlt, ist die Anschaltung der beiden Lichtschranken für START und STOP sowie ein TASTER für RESET und das Halten des Nullzustandes, bis LS schaltet.

Als "Reset" Taster kannst Du problemlos den "Reset" des Controller-Boards nehmen, auf dem LCD-Keypad-Shield mit "RST" beschriftet.

Bei einer sauberen Programmlogik brauchst Du allerdings kein Reset, sondern dass Programm kann sich nach Abschluss einer Messung problemlos wieder selbst "Startbereit" schalten.

Hast Du eine Lichtschranke gemeinsam für Start und Stopp?
Oder gibt es zwei getrennte Lichtschranken, eine für Start und eine andere für Stopp?

Ich gehe mal davon aus, es wird eine Runde gestoppt, also dieselbe Lichtschranke für Start UND Stopp. Das ist der schwierigere Fall.

Als erstes mal müßtest Du herausbekommen, was für ein Signal Deine Lichtschranken abgeben. Für mich (bin schaltungstechnisch nicht so fit) sieht das nach einem Open-Collector-Ausgang aus. Das würde bedeuten: An den Eingang des Mikrocontrollers muß ein PullUp-Widerstand gehängt werden.

Ich habe Dir mal einen Testcode gemacht, der den internen PullUp am Start-/Stop-Pin aktiviert.

Vielleicht möchtest Du damit mal testen:

#define LICHTSCHRANKE 8  // Pin für Lichtschranke
#define STARTBEREITLED 13 // Pin für Signalisierung "startbereit"

boolean lichtschrankeUnterbrochen()
{
  static byte lastState=false;
  static unsigned long lastRuntime=0;
  boolean result=false;
  if (millis()-lastRuntime<5) return result; // Signal entprellen 
  byte state=!digitalRead(LICHTSCHRANKE);
  if (state && !lastState) result=true;
  lastState=state;
  return result;
}

void setup() {
  Serial.begin(9600);
  pinMode(LICHTSCHRANKE,INPUT_PULLUP);
  pinMode(STARTBEREITLED,OUTPUT);
}


unsigned long letzteStartzeit;
boolean startbereit=false;
boolean gestartet=false;


void loop() {
  long now=millis();
  long endzeit;
  if (lichtschrankeUnterbrochen() && now-letzteStartzeit>3000) // Mindest-Messdauer
  {
    if (gestartet) 
    {
      gestartet=false;
      Serial.print("Gestoppt :");
      Serial.println(now/1000.0);
      endzeit=now-letzteStartzeit;
      Serial.print("Gemessene Dauer: ");
      Serial.println(endzeit/1000.0);
      letzteStartzeit=now; 
    }
    else
    {
      letzteStartzeit=now;
      gestartet=true; 
      startbereit=false;
      digitalWrite(STARTBEREITLED,LOW);
      Serial.print("Gestartet :");
      Serial.println(letzteStartzeit/1000.0);
    }
  }
  if (!gestartet && !startbereit && (now-letzteStartzeit>3000))
  {
    startbereit=true;
    Serial.println("Startbereit");
    digitalWrite(STARTBEREITLED,HIGH);
  }
}

Dabei sind verschiedene Dinge berücksichtigt, und zwar vor allem, dass eine Lichtschranke bei einem einzelnen Startvorgang mehrmals unterbrochen werden kann, genau so wie sie am Ende beim Stoppen mehrmals unterbrochen werden kann.

Daher habe ich als "Mindestmesszeit" mal 3000 Millisekunden (3s) angesetzt. Also wenn beim Start zum ersten mal die Lichtschranke unterbrochen wird, fängt ab da die Zeitmessung an, aber wenn die Lichtschranke innerhalb von 3 Sekunden unterbrochen wird, wird die Messung innerhalb der ersten 3 Sekunden nicht beendet. Erst wenn die Lichtschranke nach Ablauf der Mindestzeit von 3s unterbrochen wird, wird beim nächsten Unterbrechen der Lichtschranke die Zeit gestoppt.

Und nochmal drei Sekunden weiter schaltet sich das System automatisch wieder "scharf" auf "Startbereit".

Debugausgabe auf Serial.
Funktioniert das so als Lichtschrankentest mit Deiner Lichtschranke?

@jurs:

Ich gehe davon aus, dass 2 LS (das steht soweit oben auch) verbaut sind. Somit handelt es sich scheinbar nicht um einen Rundenbasierten Lauf. Sondern nur von Punkt A nach B.

Die Überlegung mit den Zeiten habe ich mir erspart. Theoretisch kann bei mir der Taster RESET auch NEUER LAUF heißen. Es sollte, so wie ich mir die Strecke vorstelle, keinerlei Probleme geben, da ich nicht davon ausgehe, dass die Hunde die Strecke in unter 20ms schaffen XD

@Mike:
+1

Etwas OT und bitte nur als Witz verstehen: Jurs, du kannst ja auch mal schnell eine Libary auf die Beine stellen, die ganzen Funktionen übernimmt. So dass er nur noch 2 Zeilen im Code einfügen muss.

#include<asd.h>

...

void loop() { asd_loop(); }

In der Libary wird dann dauerhaft Code erzeugt: "Geschrieben von Xy und keinem anderen". Dieser wird so verschachtelt und versteckt geschrieben, dass man ihn nicht problemlos auskommentieren kann :smiley:

sschultewolter:
@jurs:

Ich gehe davon aus, dass 2 LS (das steht soweit oben auch) verbaut sind. Somit handelt es sich scheinbar nicht um einen Rundenbasierten Lauf. Sondern nur von Punkt A nach B.

Das würde die Programmlogik natürlich vereinfachen, wenn es für Start und Stop getrennte Lichtschranken gibt.

Da habe ich wohl aus dem stark begrenzten Budget fälschlicherweise herausgelesen, dass nur eine einzige Lichtschranke vorhanden ist.

Anyway, in dem Fall vielleicht erstmal einen noch einfacheren Sketch zum Testen verwenden, ob die Lichtschranke mit dem Arduino und aktiviertem PullUp ausgewertet werden kann und ob das Signal auch in der Phasenlage korrekt erkannt wird:

#define LICHTSCHRANKE 8  // Pin für Lichtschrankenanschluss

void setup() {
  Serial.begin(9600);
  pinMode(LICHTSCHRANKE,INPUT_PULLUP);
}

boolean letzterStatus;
void loop() {
  boolean dieserStatus=!digitalRead(LICHTSCHRANKE);
  if (dieserStatus && !letzterStatus) Serial.println("Dunkelunterbrechung");
  else if (!dieserStatus && letzterStatus) Serial.println("Hellsignal");
  letzterStatus=dieserStatus;
  delay(5);
}

Vorab mal vielen Dank für die Unterstützung.

Anmerkung: Ich weiß sehr wohl, was ich kann. Aber auch, was ich nicht kann, deshalb meine Frage nach Mithilfe, weil die Zeit sehr drängt.

Zur Stoppuhr:
Es handelt sich um eine A - B Strecke mit 2 vorhandenen Lichtschranken. Im Anfangspost hatte ich schon geschrieben:

Die LS laufen empfängerseitig mit 5V, sollten also ggf. direkt anschaltbar sein.
http://www.produktinfo.conrad.com/datenblaetter/125000-149999/130242-an-01-ml-Zusatzlichtschranke_fuer_130202.pdf (Schaltplan siehe Seite 4).

Die Sender können momentan noch unberücksichtigt bleiben, denn die sind (vorerst noch) stand alone mit eigener 9V-Stromversorgung.

Der Ablauf soll so sein:

  1. Stoppuhr wird aktiviert.
  2. LS 1 startet die Uhr.
  3. Lichtschranke 2 stoppt die Uhr.
  4. Die Anzeige wird vom Personal abgelesen und die Zeit notiert.
  5. Die Stoppuhr wird resettet und für die nächste Messung aktiviert.

GRD und +5V sind mir klar.
Was mir nicht klar ist:
Kann ich die Ausgänge der LS direkt auf PINS am LCD legen oder muss da noch was vorgeschaltet werden?

tilloriemer:
Kann ich die Ausgänge der LS direkt auf PINS am LCD legen oder muss da noch was vorgeschaltet werden?

Ach so, Du wolltest ja ein sogenanntes "LCD-Keypad-Shield" aufstecken?

In dem Fall sind die Pins tabu, die bereits von diesem Shield verwendet werden, die darfst Du NICHT für eigene Zwecke verwenden, als da sind:

  • die Pins, mit denen die Ausgabe auf dem Display gesteuert wird:
    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
  • der Pin für die Ansteuerung der Hintergrundbeleuchtung des Dislays (10)
  • und der Pin, über den die Buttons analog abgefragt werden (A0).

Die Pins 0 und 1 solltest Du ebenfalls nicht verwenden, da diese mit der seriellen Schnittstelle verbunden sind, über die Du wertvolle Debug-Ausgaben über Serial machen kannst.

D.h. Du kannst Deine Lichtschranken noch an diese freien Pins anschließen, wenn das LCD-Keypad-Shield verwendet wird:

  • 2, 3, A1, A2, A3, A4, A5

Die Anschlüsse sind über die Steckverbinder zwischen Shield und Board verbunden, so dass Du den (Löt-)Anschluss oben am Shield vornehmen kannst.

@jurs:
Ich erhalte beim Kompilieren diese Meldungen:

core.a(main.cpp.o): In function main': I:\Anwendungen\Arduino\hardware\arduino\cores\arduino/main.cpp:11: undefined reference to setup'
I:\Anwendungen\Arduino\hardware\arduino\cores\arduino/main.cpp:14: undefined reference to `loop'

An D10 hab ich nicht gedacht! Aber die Leds kannst du für den Einsatz sowieso rausnehmen.
Dein gewünschter Ablauf dürfte sich mit meinem Sketch decken.

Anmerkung: Ich weiß sehr wohl, was ich kann. Aber auch, was ich nicht kann, deshalb meine Frage nach Mithilfe

Davon war im Anfangspost leider nichts zu erkennen.

Fehlermeldung ohne den Sktech zu sehen ist schwer zu zu ordnen. Da musst du selber noch was verändert haben, kann den Teil von jurs ohne Probleme kompilieren.

tilloriemer:
@jurs:
Ich erhalte beim Kompilieren diese Meldungen:

core.a(main.cpp.o): In function main': I:\Anwendungen\Arduino\hardware\arduino\cores\arduino/main.cpp:11: undefined reference to setup'
I:\Anwendungen\Arduino\hardware\arduino\cores\arduino/main.cpp:14: undefined reference to `loop'

Welche Arduino-Softwareversion hast Du (Betriebssystem, Versionsnummer)?
Welches Arduino-Board hast Du?
Und welches Board hast Du als Board unter "Tools - Board" eingestellt?

Wenn Du ein UNO-Board hast, müßte auch Arduino UNO als Board eingestellt sein.

Nachtrag: Und kontrolliere mal, ob Du den gesamten Test-Sketch in Deine IDE kopiert hast, inklusive der Funktionen setup() und loop(). Ich hatte vorhin zwei Test-Sketche gepostet, davon wird einer hier im Forum mit Scroll-Bereich dargestellt. Bei dem müßtest Du natürlich auch den Code aus dem gesamten Scroll-Bereich heraus- und in die Arduino-Software hinein kopieren.

Board UNO
Software 1.0.5-r2
Eingestellt ist UNO

Ich probiere ja schon zwei Tage herum und es läuft damit soweit richtig.

Habe jetzt mal die Pins A1 und A2 mit den beiden LS belegt.

tilloriemer:
Habe jetzt mal die Pins A1 und A2 mit den beiden LS belegt.

So, hier dann ein ganz einfach gemachter Sketch für zwei getrennte Lichtschranken mit Ausgabe auf LCD-Keypad-Shield zum Testen.

Pegel habe ich jetzt mal geraten dass LOW Pegel für eine Unterbrechung der Lichtschranke steht.
Kann im Sketch aber leicht geändert werden.

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // Für Sainsmart LCD Keypad Shield

#define STARTLICHTSCHRANKE A1  // Lichtschranke zum Starten der Zeit
#define STOPPLICHTSCHRANKE A2  // Lichtschranke zum Stoppen der Zeit
#define UNTERBRECHUNGSPEGEL LOW // welcher Pegel signalisiert eine Unterbrechung der Lichtschranke?

boolean startLichtschrankeUnterbrochen()
{
  static byte lastState=false;
  boolean result=false;
  byte state=digitalRead(STARTLICHTSCHRANKE);
  if (state != lastState && state==UNTERBRECHUNGSPEGEL) result=true;
  lastState=state;
  return result;
}

boolean stoppLichtschrankeUnterbrochen()
{
  static byte lastState=false;
  boolean result=false;
  byte state=digitalRead(STOPPLICHTSCHRANKE);
  if (state != lastState && state==UNTERBRECHUNGSPEGEL) result=true;
  lastState=state;
  return result;
}


void setup() {
  Serial.begin(9600);
  lcd.begin(16,2);
  Serial.println("Messbereitschaft");
  lcd.print("Messbereitschaft");
  pinMode(STARTLICHTSCHRANKE,INPUT_PULLUP);
  pinMode(STOPPLICHTSCHRANKE,INPUT_PULLUP);
  startLichtschrankeUnterbrochen(); // nur zur Initialisierung, keine Auswertung
  stoppLichtschrankeUnterbrochen(); // nur zur Initialisierung, keine Auswertung
}

void loop() {
  while (!startLichtschrankeUnterbrochen()) ; // warten auf Unterbrechung der Start-Lichtschranke
  unsigned long zeit=millis(); // Jetzt wurde gestartet
  Serial.println("gestartet");
  lcd.clear();
  lcd.print("gestartet");
  while (!stoppLichtschrankeUnterbrochen()) ; // warten auf Unterbrechung der Stopp-Lichtschranke
  zeit=millis()-zeit; // Jetzt wurde gestoppt
  Serial.print("Zeit: ");
  Serial.println(zeit/1000.0,3);
  lcd.clear();
  lcd.print("Zeit: ");
  lcd.print(zeit/1000.0,3);
  while(1); // Endlosschleife - Warten auf Reset
}

Beim Herauskopieren des Sketches aufpassen, dass Du den ganzen Sketch bekommst, inklusive dem Scrollbereich und den Funktionen setup() und loop().

Rücksetzen auf "Messbereitschaft" jetzt nur durch den "Reset" Button möglich, d.h. nachdem eine Endzeit fixiert ist, wird kein neuer Messvorgang ausgelöst, bevor man nicht einen Controller-Reset gemacht und damit die Messbereitschaft neu hergestellt hat.

Habe das 2. Sketch mal geändert:
LS von 8 auf A1
LED überall rausgenommen

Liess sich kompilieren und übertragen, aber auf dem Display passiert nichts.

tilloriemer:
Habe das 2. Sketch mal geändert:
LS von 8 auf A1
LED überall rausgenommen

Liess sich kompilieren und übertragen, aber auf dem Display passiert nichts.

Na bravo!

Die Test-Sketche steuern das LCD NICHT an, sondern machen nur Debug-Ausgaben auf dem Seriellen Monitor.

Nur der fertige Sketch in Reply #14 steuert das LCD an!

Wenn du Änderungen machst, bitte auch immer den aktuellen Sketch mitposten, dafür sind Code da. Über zu häufig geposeten Code mecker keiner, nur wenn er zu selten aktualisiert wird oder zwischen den Beiträgen liegt.

Habe selbst schon gemerkt, dass das LCD nicht initialisiert war.

Mit dem letzten Sketch läuft es nun, aber die LS zeigt keine Wirkung. Dafür schaltet die Uhr ein und aus, wenn ich das Kabel zur jeweiligen LS an irgend ein Potential halte.

tilloriemer:
Habe selbst schon gemerkt, dass das LCD nicht initialisiert war.

Mit dem letzten Sketch läuft es nun, aber die LS zeigt keine Wirkung. Dafür schaltet die Uhr ein und aus, wenn ich das Kabel zur jeweiligen LS an irgend ein Potential halte.

Hast Du auch GND der Lichtschranke(n) mit GND vom Arduino verbunden?

Wie lang sind die Kabel zwischen Arduino-Board und Lichtschranke?

Kannst Du mit einem Multimeter im Voltbereich mal nachmessen, was sich am Ausgang der Lichtschranke tut, wenn sie schaltet? Einmal messen mit Lichtschranke angeschlossen am laufenden Sketch und einmal messen ohne die Lichtschranke anzuschließen.

  1. Angeschlossen am Arduino, mit laufendem Sketch
    a) bei nicht unterbrochener Lichtschranke = ? Volt
    b) bei unterbrochener Lichtschranke = ? Volt

  2. Enden der Lichtschranke nicht angeschlossen, nur am Multimeter
    a) bei nicht unterbrochener Lichtschranke = ? Volt
    b) bei unterbrochener Lichtschranke = ? Volt

Die Spannung an der LS kommt vom Arduino, GND ist also gleich.

A1 = 4,9 V
A2 = 4,9 V

  1. Angeschlossen am Arduino, mit laufendem Sketch
    a) bei nicht unterbrochener Lichtschranke = 4,9 Volt
    b) bei unterbrochener Lichtschranke = zuckt nur mal kurz auf 4,8 Volt (nicht wirklich messbar, jeder Kontak mit dem Messpunkt schaltet Sketch um)

  2. Enden der Lichtschranke nicht angeschlossen, nur am Multimeter
    a) bei nicht unterbrochener Lichtschranke = 0.03 Volt
    b) bei unterbrochener Lichtschranke = 1.x Volt (nicht richtig messbar, fällt sofort wieder zurück)