@jurs: Supervielen Dank für die Mühe mit dem Beispiel Code, ich werde ihn heute Abend "einbauen" und testen.
Prinzipiell dachte ich, daß das Pollen von Signalen ja dem Benutzen von pulseIn entspricht, aber Du baust hier noch eine Synchronisation mit der Schleife ein.
Ich bin mir nicht sicher, ob nicht die Sache mit den Zeitfenstern mit 50 mal 8 ms für den späteren restlichen Code zu knapp wird. Ich will ja eigentlich noch per I2C Daten vom 10OF Sensor abrufen, und via PID Regler verarbeiten. Ich habe hier noch nicht die Geschwindigkeit gemessen.
Da ich aber zusätzlich noch entweder ein LCD-Display nutze (zum Einstellen der Parameter im Testbetrieb), oder auf eine SD-Karte mitlogge, (beides gleichzeitig geht wg. Speicherplatz nicht), dürften für den späteren Vollausbau die 8ms Zeitschlitze wohl zu kurz sein.
Aber ich probiere es aus.
Ich habe jetzt auf Hinweis von Willi168 aber vorher nochmal versucht meinem Beispielscode des einfachen Durchreichens der Signale via "RC receiver" leicht umzubauen, und auf den Pins 12 und 13 jeweils ein Signal im detektiertem Fehlerfall auszugeben. Beim nächsten korrekten Auslesen wird das Signal wieder auf Null gesetzt.
Code:
#include <Servo.h>
#include "makros.h"
#include "debug.h"
#include "RCReceive.h"
//---------- SERVO----------------------
Servo myservo1; // create servo object to control a servo
Servo myservo2; // create servo object to control a servo
#define ServoSignalAusgang1 9 // Das Signal für den Ausgangsservo 1
#define ServoSignalAusgang2 10 // Das Signal für den Ausgangsservo 2
int ServoWert1 = 0; // variable to store the value coming from the sensor
int ServoWert2 = 0; // variable to store the value coming from the sensor
// ********************** Code für das Auslesen des RC-Signals *****************************
// Code aus http://www.rcarduino.tk/
RCReceive rcReceiver1; // Der Empfänger: QR-Signal
RCReceive rcReceiver2; // Der Empfänger: Schaltkanal
boolean KeinRCSignal1 = true;
boolean KeinRCSignal2 = true;
byte Servovalue1;
byte Servovalue2;
boolean QR_Stabi_AN = false;
#define RC_QR 2 //arduino pins attached to the receiver Die Interrupts gehen nur für Pin 2 und 3
#define RC_SCHALT 3
void setup() // #################### SETUP ##################################################
{
myservo1.attach(ServoSignalAusgang1); // attaches the servo on pin 9 to the servo object 1
myservo2.attach(ServoSignalAusgang2); // attaches the servo on pin 10 to the servo object 2
pinMode(RC_QR, INPUT); //Querruder-Signal
pinMode(RC_SCHALT, INPUT); // Das Schaltsignal, daß mal die PID-Regelung ausschalten soll
// ********************** Code für das Auslesen des RC-Signals *****************************
// Für die Signalanalyse via Interrupts, geht nur an Pin 2 und 3
rcReceiver1.attachInt(RC_QR);
rcReceiver2.attachInt(RC_SCHALT);
pinMode(12, OUTPUT); // für Fehlersignale von Kanal 1
pinMode(13, OUTPUT); // für Fehlersignale von Kanal 2
digitalWrite(12, LOW);
digitalWrite(13, LOW);
}
void loop() // #################### LOOP ##################################################
{
// ********************** Auslesen des RC-Signals für das QR über Interrupts *****************************
if (rcReceiver1.hasNP() && !rcReceiver1.hasError())
{
Servovalue1 = rcReceiver1.getValue(); //Es werden Werte von 0 bis 255 ausgegeben
KeinRCSignal1 = false;
digitalWrite(12, LOW);
}
else if (rcReceiver1.hasError()) {
KeinRCSignal1 = true;// Fehlerbehandlung failsafe oder sowas...
Servovalue1 = 0; // Failsafe: Neutralstellung
digitalWrite(12, HIGH);
}
// ******************** Umrechnen des RC-Signal für das QR an Servo 1
if (KeinRCSignal1 == false) //nur dann ist es ein gültiger Wert
{
ServoWert1 = constrain(map(Servovalue1, 0, 255, -1023, +1023), -1023, +1023);
// Wertebereich zwischen -1023 und +1023, Mittenwert ist 0, das wäre dann Setpoint Null
}
// ************************* Auslesen des RC-Signals für den Schaltkanal über Interrupts *****************************
if (rcReceiver2.hasNP() && !rcReceiver2.hasError())
{
Servovalue2 = rcReceiver2.getValue(); //Es werden Werte von 0 bis 255 ausgegeben
KeinRCSignal2 = false;
digitalWrite(13, LOW);
}
else if (rcReceiver2.hasError()) {
KeinRCSignal2 = true;// Fehlerbehandlung failsafe oder sowas...
Servovalue2 = 0; // Failsafe: Neutralstellung
digitalWrite(13, HIGH);
}
// ******************** Umrechnen des RC-Signal für den Schaltkanal an Servo 2
if (KeinRCSignal2 == false) //nur dann ist es ein gültiger Wert
{
ServoWert2 = constrain(map(Servovalue2, 0, 255, -1023, 1023), -1023, 1023);
}
// ---------------------- Ausgabe der Servosignale ------------------------------------
// Remapping der Signale auf die Winkel
myservo1.write(map(ServoWert1, -1023, +1023, 160, 20)); // Durchreichen der erfassten Servosignale vom Empfänger
myservo2.write(map(ServoWert2, -1023, +1023, 160, 20)); // Durchreichen der erfassten Servosignale vom Empfänger
}
Ergebnis: Das Oszi zeigt recht regelmäßig alle ca. 400 ms gleichzeitig(!) auf beiden Kanälen ein 20 oder 40 ms andauerndes Fehlersignal.
Also alle 20 bis 22 RC-Signale werden regelmäßig ein oder 2 Signale falsch gelesen.
Das gilt, wenn beide Kanäle in Ruheposition sind. Screenshot siehe angehängte GIF Datei.
Um Hardwareprobleme auszuschließen, habe ich nochmal:
- den RC-Empfänger ausgetauscht (Spektrum statt Multiplex-System)
- einen anderen Arduino Uno (Chinaklon) eingesetzt, an dem sonst nichts anderes mehr angeschlossen war
Keine Änderung, am RC-Signal wird es damit nicht liegen: Weiterhin die regelmäßigen Fehlermeldungen.
Beim Versuch zusammen mit den 10DOF I2C Sensoren und sowie PID Regler wird die ganze Sache wieder recht träge. Mit dem nun neu eingeführten Abschalten der Ausgabe auf LCD auf Tastendruck (ich brauche das ja nur am Boden, nicht in der Luft) reagiert das Gesamtsystem zwar schneller, aber trotzdem noch zu träge für ein sauberes Steuern.
Wenn es sonst keine Ideen mehr gibt, versuche ich als nächste Aktion den Code von Jurs zu beleben, und sonst nochmal auf eine Suche nach einer anderen Servo-Bib zu gehen.
Tütenflieger
