//Code für den Arduino, später nur den Pin 11 entfernen, da der für das selbstständige Triggern ohne Messrad benutzt wird #include volatile unsigned int counter = 0; unsigned long lastSignalMillis1 = 0; unsigned long lastSignalMillis2 = 0; unsigned long time200 = 0; bool signalActive1 = false; bool signalActive2 = false; int trigger = 10; int vortrigger = 8; int belichtung = 3; bool pwmAktiv = false; bool light_reset = false; volatile float pwmFrequency = 15000; // PWM-Frequenz in Hz volatile float dutyCycle = 70; // Duty Cycle in Prozent long tast = (16000000L / pwmFrequency) * (dutyCycle / 100); void setup() { Serial.begin(9600); // Falls vorhanden, werden die letzten gespeicherten Werte aus dem EEPROM gelesen EEPROM.get(0, trigger); EEPROM.get(4, vortrigger); EEPROM.get(8, belichtung); EEPROM.get(12, pwmFrequency); EEPROM.get(16, dutyCycle); //EEPROM.get(20, pwmAktiv); //Falls nicht vorhanden, werden vordefinierte Werte verwendet und in den EEPROM geschrieben if ((trigger == 0 || trigger == -1) || (vortrigger == 0 || vortrigger == -1) || (belichtung == 0 || belichtung == -1) || (pwmFrequency == 0 || pwmFrequency == -1) || (dutyCycle == 0 || dutyCycle == -1)) { trigger = 10; vortrigger = 8; belichtung = 3; pwmFrequency = 15000; dutyCycle = 10; pwmAktiv = false; EEPROM.put(0, trigger); EEPROM.put(4, vortrigger); EEPROM.put(8, belichtung); EEPROM.put(12, pwmFrequency); EEPROM.put(16, dutyCycle); //EEPROM.put(20, pwmAktiv); } updateTast(); //Tastverhältnis für die PWM Einstellung aktuallisieren pinMode(2, INPUT); // Eingangspin pinMode(13, OUTPUT); // Hauptausgang zum Triggern der Kameras pinMode(12, OUTPUT); //Zweiter Hauptausgang zum Triggern der Kameras (Aufgrund von reduzierter Belastbarkeit des Stromteilers benötigt) pinMode(9, OUTPUT); // PWM-Ausgang für Beleuchtung pinMode(11, OUTPUT); // PWM-Ausgang für das selbstständige Triggern // Timer 1 Konfiguration fast PWM an Pin 9 TCCR1A = 0; TCCR1B = 0; TCCR1A |= (1 << COM1A1) | (1 << WGM11); TCCR1B |= (1 << WGM13) | (1 << WGM12) | (1 << CS10); ICR1 = (16000000L / pwmFrequency) - 1; //Pin 2 (Eingang Messrad) erzeugt einen Interrupt um Impulse sicher zu erfassen attachInterrupt(digitalPinToInterrupt(2), countSignal, RISING); } void loop() { int cycleTime = 4000; // Mikrosekunden 3703 = 27 Hz (nur für selbstständiges Triggern benötigt) int onTime = cycleTime * 0.5; // 50% Duty Cycle int offTime = cycleTime - onTime; digitalWrite(11, HIGH); delayMicroseconds(onTime); digitalWrite(11, LOW); delayMicroseconds(offTime); if (counter >= vortrigger) { //Beleuchtung X Impulse vor dem Kameratrigger einschalten if (!signalActive2) { signalActive2 = true; OCR1A = tast; } lastSignalMillis2 = millis(); } if (counter >= trigger) { //Kameras triggern time200 = millis(); if (!signalActive1) { signalActive1 = true; digitalWrite(13, HIGH); digitalWrite(12, HIGH); } lastSignalMillis1 = millis(); counter -= trigger; } if (signalActive2 && (millis() - time200 >= belichtung) && counter < vortrigger && pwmAktiv==false) { //Beleuchtung ausschalten, wenn Belichtungszeit (beginnend ab Trigger) vorbei ist und der Counter wieder zurückgesetzt wurde signalActive2 = false; OCR1A = 0; } if (signalActive1 && (millis() - lastSignalMillis1 >= 1)) { signalActive1 = false; digitalWrite(13, LOW); digitalWrite(12, LOW); } if (pwmAktiv == true) //Beleuchtung dauerhaft an wenn das über GUI angefordert wurde. (Noch to do: Diese Abfrage aus dem loop herausziehen und den Aufruf in recieveData packen) { OCR1A = tast; } if (light_reset == true) { OCR1A = 0; light_reset = false; } if (Serial.available() > 0) { receiveData(); } } void countSignal() { counter++; } void updateTast() { tast = (16000000L / pwmFrequency) * (dutyCycle / 100); ICR1 = (16000000L / pwmFrequency) - 1; } //Funktion zum Erhalten von Daten über den RPi void receiveData() { String data = Serial.readStringUntil('\n'); if (data.startsWith("SET")) { String command = data.substring(4); if (command.startsWith("trigger")) { trigger = command.substring(8).toInt(); EEPROM.put(0, trigger); } else if (command.startsWith("vortrigger")) { int tempVortrigger = command.substring(11).toInt(); vortrigger = trigger - tempVortrigger; EEPROM.put(4, vortrigger); } else if (command.startsWith("belichtung")) { belichtung = command.substring(11).toInt(); EEPROM.put(8, belichtung); } else if (command.startsWith("pwmFrequency")) { pwmFrequency = command.substring(13).toInt(); EEPROM.put(12, pwmFrequency); updateTast(); } else if (command.startsWith("dutyCycle")) { int dutyCycleInt = command.substring(10).toInt(); dutyCycle = dutyCycleInt / 1.0; EEPROM.put(16, dutyCycle); updateTast(); } else if (command.startsWith("pwm_aktiv")) { pwmAktiv = command.substring(10).toInt(); EEPROM.put(20, pwmAktiv); if (pwmAktiv == 0) { light_reset = 1; } } } else if (data.startsWith("GET")) { sendData(); } } //Funktion zum Senden von Daten an den RPi void sendData() { String data = "trigger:" + String(trigger) + ";"; data += "vortrigger:" + String(trigger-vortrigger) + ";"; data += "belichtung:" + String(belichtung) + ";"; data += "pwmFrequency:" + String(pwmFrequency) + ";"; data += "dutyCycle:" + String(int(dutyCycle)) + ";"; data += "pwm_aktiv:" + String(pwmAktiv) + ";"; Serial.println(data); }