189 lines
5.6 KiB
C++
189 lines
5.6 KiB
C++
//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 <EEPROM.h>
|
|
|
|
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);
|
|
} |