Hallo zusammen,
ich komme aus dem RC Modellbau und nach langer Zeit möchte ich mal wieder etwas mit dem Arduino machen. Es geht dabei um eine 16 Kanal Schaltkarte. Von der Funke kommen 2 Kanäle mit je 8 PWM Werten. Diese möchte ich auswerten und dann entsprechende Funktionen schalten. Ich habe sowas vor langer Zeit mal zum laufen bekommen, allerdings mit den bösen Delay Befehlen und das möchte ich nun ändern und verbessern. Zunächst für nur einen Kanal, also 8 Funktionen.
Was schon mal gut funktioniert, ist das Auslesen des Signals, und das korrigieren mit einem vorher festgestellten Wert( Min=1000, Mitte=1500, Max=2000). Soll bedeuten, wenn der Mittelwert beim einschalten statt 1500 nur 1450 ist, merkt er sich das und korrigiert die danach eingelesenen Werte automatisch.
Jetzt die generelle Frage zum Programmaufbau. Sollte ich mich mit der IF Funktion durch alle Punkte arbeiten oder die switch case Variante wählen?
Ich habe beide Varianten versucht und im Sketch ist eine davon auskommentiert
#include <MobaTools.h>
MoToServo meinServo1;
MoToServo meinServo2;
int Anker1busy = 0;
int Anker2busy = LOW;
int statAnker1unten = 0;
int statAnker2unten = LOW;
int statAnkersenk1 = LOW;
int statAnkersenk2 = LOW;
int statAnkerheb1 = LOW;
int statAnkerheb2 = LOW;
int IN1 = 2;
int IN2 = 3;
int servoPin1 = 4; //int CH1 = 4; //const int
int servoPin2 = 5; //int CH2 = 5; //const int
int var = 0;
// ************ PWM Variablen ******************
int CH1inputValue; // Speichert die ausgelesene Pulsbreite in us vom Kanal 1
int CH2inputValue; // Speichert die ausgelesene Pulsbreite in us vom Kanal 2
int PWM1;
int PWM2;
int PWM1OK;
int PWM2OK;
int CH1PWMcorrection; // PWM-Korrekturwert für Nullstellung von Kanal 1
int CH2PWMcorrection; // PWM-Korrekturwert für Nullstellung von Kanal 2
const int negativ = -1;
// ************ Timer Variablen ******************
unsigned long Ankertimer1 = 0; // Anker fallen lassen previousMillis
unsigned long Ankertimer2 = 0; // Anker fallen lassen previousMillis
const long Ankerinterval11 = 10000;
const long Ankerinterval12 = 3000;
void setup() {
// put your setup code here, to run once:
pinMode (IN1, INPUT);
pinMode (IN2, INPUT);
pinMode(servoPin1, OUTPUT);
pinMode(servoPin2, OUTPUT);
Serial.begin(9600);
meinServo1.attach(servoPin1); //Servo an Pin 4
meinServo1.setSpeed( 0 ); // Verfahrgeschwindigkeit einstellen
meinServo1.write(90);
meinServo2.attach(servoPin2); //Servo an Pin 5
meinServo2.setSpeed( 0 ); // Verfahrgeschwindigkeit einstellen
meinServo2.write(90);
PWMcorrection();
Serial.println("SETUP PWM CH1: ");
Serial.println(PWM1OK);
Serial.println(CH1PWMcorrection);
Serial.println(PWM1OK + CH1PWMcorrection);
}
void loop() {
readRCinput();
Serial.println("PWM CH1: ");
Serial.println(PWM1);
Serial.println("Anker busy");
Serial.println(Anker1busy);
Serial.println("Anker unten");
Serial.println(statAnker1unten);
/*
if (Anker1busy == LOW)
{
Serial.println("LOW");
}
if (Anker1busy == HIGH)
{
Serial.println("HIGH");
}
Serial.println("Anker unten");
if (statAnker1unten == LOW)
{
Serial.println("LOW");
}
if (statAnker1unten == HIGH)
{
Serial.println("HIGH");
}
*/
// *****************Variante ohne Delay mit case **************
if (PWM1 > 950 && PWM1 < 1050 )
{
var = 1;
}
if (PWM1 > 1950 && PWM1 < 2050 )
{
var = 2;
}
switch (var) {
case 1:
meinServo1.write(20);
Anker1busy = 1;
unsigned long currentMillis1 = millis();
if (currentMillis1 - Ankertimer1 >= Ankerinterval11)
{
Ankertimer1 = currentMillis1;
meinServo1.write(90);
}
var = 0;
Anker1busy = 0;
statAnker1unten = 1;
break;
case 2:
meinServo1.write(160);
Anker1busy = 0;
statAnker1unten = 0;
break;
}
}
/*
case 2:
meinServo2.write(150);
// statAnkerheb1 = HIGH;
unsigned long currentMillis2 = millis();
if (currentMillis2 - Ankertimer2 >= Ankerinterval12) { // Falls mehr als 1000 ms vergangen sind
Ankertimer2 = currentMillis2;
meinServo2.write(90);
// statAnkerheb1 = LOW;
var = 0;
}
break;
default:
break;
}
*/
/*
// *****************Variante ohne Delay ohne case **************
if (PWM1 > 950 && PWM1 < 1050 && (Anker1busy == 0) && (statAnker1unten == 0))
{
meinServo1.write(20);
Anker1busy = 1;
}
unsigned long currentMillis1 = millis();
if (currentMillis1 - Ankertimer1 >= Ankerinterval11)
{
Ankertimer1 = currentMillis1;
meinServo1.write(90);
Anker1busy = 0;
statAnker1unten = 1;
}
if (PWM1 > 1950 && PWM1 < 2050 && (Anker1busy == 0) && (statAnker1unten == 1))
{
meinServo1.write(160);
Anker1busy = 1;
}
unsigned long currentMillis2 = millis();
if (currentMillis2 - Ankertimer2 >= Ankerinterval12) { // Falls mehr als 1000 ms vergangen sind
Ankertimer2 = currentMillis2;
meinServo1.write(90);
Anker1busy = 0;
statAnker1unten = 0;
}
*/
// ========== PWM Korrekturwerte für CH1 und CH2 ermitteln ==========
void PWMcorrection() {
CH1PWMcorrection = 0; // PWM-Korrekturwert für Nullstellung von Kanal 1 auf 0 setzen
CH2PWMcorrection = 0; // PWM-Korrekturwert für Nullstellung von Kanal 2 auf 0 setzen
int PWM1IN = pulseIn(IN1, HIGH);
if (PWM1IN > 900 && PWM1IN < 2100)
PWM1OK = PWM1IN;
int PWM2IN = pulseIn(IN2, HIGH);
if (PWM2IN > 900 && PWM2IN < 2100)
PWM2OK = PWM2IN;
if (PWM1OK > 1500)
CH1PWMcorrection = (PWM1OK - 1500);
CH1PWMcorrection = (CH1PWMcorrection * negativ);
if (PWM1OK < 1500)
CH1PWMcorrection = (1500 - PWM1OK);
if (PWM2OK > 1500)
CH2PWMcorrection = (PWM2OK - 1500);
CH2PWMcorrection = (CH2PWMcorrection * negativ);
if (PWM2OK < 1500)
CH2PWMcorrection = (1500 - PWM2OK);
}
// ========== PWM Werte einlesen und plausibel ? ==========
void readRCinput() {
int PWM1IN = pulseIn(IN1, HIGH); //Read PWM Pulse
if (PWM1IN > 900 && PWM1IN < 2100)
PWM1OK = PWM1IN;
PWM1 = (PWM1OK + CH1PWMcorrection);
int PWM2IN = pulseIn(IN2, HIGH); //Read PWM Pulse
if (PWM2IN > 900 && PWM2IN < 2100)
PWM2OK = PWM2IN;
PWM2 = (PWM2OK + CH2PWMcorrection);
}
Welche Methode würdet ihr wählen und warum? Zu erwähnen ist noch das die Funktionen später noch Merker bekommen sollen um zu entscheiden ob ein Ausgang ein oder ausgeschaltet werden soll. Im aktuellen Fall wird ein Servo für den Ankerfall angesteuert. bei pwm1000 soll das Servo von 90 auf 0 Grad gehen und eine Zeit stehen bleiben. (Anker mit Kette im Freifall) , danach zurück auf 90 Grad. Durch pwm2000 dreht der Servo auf 180 Grad und ein Motor wird über einen Endschalter eingeschaltet, der den Anker wieder hochzieht. Nach einer Zeit X soll das Servo wieder auf 90 Grad gehen.
Sehr viel Text und irgendwie nicht einfach zu erklären, dazu die ganzen neuen Begrifflichkeiten, aber ich hoffe man kann zumindest Ansatzweise verstehen was ich beabsichtige.
Vielen Dank und Gruß Thomas