fotobox_SPRT/Arduino_Code.ino

189 lines
5.6 KiB
Arduino
Raw Permalink Normal View History

2024-10-07 19:55:43 +02:00
//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);
}