Author Topic: Projekt RC-Receiver(Modell Fernsteuerungsempfänger mit 2,4GHz),Arduino & Servos  (Read 24711 times)

House

  • freakyfriday
  • Jr. Member
  • *
  • Posts: 95
  • Karma: +1/-0
    • Hausammann-Dekor
Hallo zusammen,

ich möchte über eine RC-Fernsteueranlage 2,4GHz(Funke) und einen Arduino (kann ein gewöhnlicher Arduino, ein Nano oder sonst ein gängiger Clon sein), mehrere Servos steuern. Die Kanäle werden einzeln vom Receiver abgegriffen und per femal jumper wire an den MC angeschlossen. Ich habe es geschafft, mir 5 RC-Kanäle per SerialOut anzeigen zu lassen, wobei ich die gemessenen Werte auf 0 bis 180 gemapt habe um auf die gänggigen Servo-Werte zu kommen. Danach habe ich mit der Servo-Library ein paar Servos in den Sketch einbezogen. Mit dem Resultat, das ich jeweils nur 3 Kanäle resp. nur 3 Servos zu laufen gebracht habe. Ich habe verschiedenes aus dem Netz in der Richtung probiert und nach gelesen, jedoch funktioniert immer irgendwas nicht( Lade fehler und Jitter usw., auch mit ArduPilot1-Sketch >:(). Deshalb habe ich an meinem Ansatz weiter gearbeitet. Ich habe bei meinem Skript die SerialPrints raus genommen, was zur Folge hat, dass sich die 3 funktionalen Servos sehr zügig und ohne Jittern über die Funke stellen lassen :). Jedoch bleibt das Problem, dass nur 3 der 5 Kanäle mit Servos laufen(habe alle Out-Pins mit einem Servo durch getestet), was in meinem Fall nicht reicht :(. Ich brauche mindestens 4 Kanäle wie im Sketch unten, und der MC sollte auch nicht zu gross bzw. zu schwer sein. Ich denke es hat was mit den Interrupts zu tun, mit einem ArduinoMega wäre ich schon lange fertig, jedoch ist der deutlich zu gross und schwer(ein Arduino-Nano wäre mir am liebsten). Ich habe an meinem Skript mit den Pins jongliert, jedoch ohne Erfolg. Hat jemand ein ähnliches Problem gehabt und eine Lösung gefunden oder hat jemand von euch ein Ansatz (z.B. wie man dieses Problem mit Interrupts lösen kann :o)? Unten Poste ich noch meinen Versuchscode, der Serial Begin, sowie die SerialPrints könnt Ihr ja selbst entfernen, ich habe sie im Sketch gelassen, damit man die einzelnen Teile mal Anschauen kann.

Danke im voraus für Euer Interesse bzw. Eure Hilfe ;)!

Mit freundlichen Grüssen
Patric Hausammann

Und hier kommt noch der erwähnte Sketch  :):
     
/*
 RC PulseIn Serial Read out, with adjusted Output to Arduinos and compatibles
 By: Nick Poole, BARRAGAN, Patric Hausammann
 SparkFun Electronics
 Date: 07.07.2014
 License: CC-BY SA 3.0 - Creative commons share-alike 3.0
 use this code however you'd like, just keep this license and
 attribute. Let me know if you make hugely, awesome, great changes.
 */
 
int ch1; // Here's where we'll keep our channel values // Hier werden die Werte hinterlegt
int ch2;
int ch3;
int ch4;


#include <Servo.h>  //enable Servo-Library // die Servo-Library anhängen
 
Servo myservo1;  // create servo object to control a servo // erstellen eines Servo-Objekts
                // a maximum of eight servo objects can be created // laut Library können acht Servo-Objekte erstellt werden
Servo myservo2;
Servo myservo3;
Servo myservo4;  //here I've created 4 servo objects which begins with myservo and ends with myservo3 //Hier habe ich 4 Servo-Objekte von myservo bis myservo3 erstellt

 
//int pos = 0;    //Normally this would be the variable to store the servo position from 0 to 180 , which represents the sevo way, but in this case I used the variables ch1 to ch4
 // Normalerweise wäre (int pos=0) die Variable zum hinterlegen der Gradanzahl des Ausschlags des Servos von 0 bis 180, hier wurde diese Variable ausgelassen resp. durch ch1 bis ch4 ersetzt


void setup() {

  pinMode(5, INPUT); // Set our input pins as such   //hier werden die Output-Pins als solche definiert
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  pinMode(8, INPUT);

 myservo1.attach(3);  // attaches the servo on pin 3 to the servo object // Anhängen des Servo-Objets am Pin 3
 myservo2.attach(9); //Pin 9
 myservo3.attach(17);//Analog-Pins 1
 myservo.4attach(18);//Analog-Pins 2


  Serial.begin(9600); // Pour a bowl of Serial

}

void loop() {

  ch1 = pulseIn(5, HIGH, 25000); // Read the pulse width of //Liest die Pulsweite
  ch2 = pulseIn(6, HIGH, 25000); // each channel // jedes Kanals
  ch3 = pulseIn(7, HIGH, 25000);
  ch4 = pulseIn(8, HIGH, 25000);
 
  ch1 = map(ch1,1030, 2003, 0, 180); //adjust the first receiver channel to the value of Servo-Library  //Anpassen der Pulsweitensignale auf die gebräuchlichen Servo-Library-Werte von 0 bis 180
   myservo1.write(ch1); //write adjusted value from above to first servo  //Gibt den korrigierten Wert an den Servo aus
  ch2 = map(ch2,1030, 2003, 0, 180);//adjust the second receiver channel ... //Wieder das selbe wie oben, anpassen und an den Servo ausgeben, usw.
   myservo2.write(ch2); //write adjusted value from above(ch2) to second servo
  ch3 = map(ch3,1030, 2003, 0, 180);// adjust No.3
    myservo3.write(ch3); //same as the two examples before
  ch4 = map(ch4,1030, 2003, 0, 180);//adjust No.4
    myservo4.write(ch4); //write adjusted value from above to first servo
 
  Serial.print("Channel 1:"); // Print the value of  //Gibt die Werte aller Kanäle nach einander im Serial Monitor wieder
  Serial.println(ch1);        // each channel

  Serial.print("Channel 2:");
  Serial.println(ch2);

  Serial.print("Channel 3:");
  Serial.println(ch3);

  Serial.print("Channel 4:");
  Serial.println(ch4);


  delay(100); // I put this here just to make the terminal // Damit es im Terminal nicht all zu sehr ruckelt
              // window happier
}
« Last Edit: July 08, 2014, 09:10:42 AM by House »

mikeZ337

  • Newbie
  • *
  • Posts: 28
  • Karma: +3/-1
Quote
Code: [Select]
myservo.attach(3);  // attaches the servo on pin 3 to the servo object // Anhängen des Servo-Objets am Pin 3
 myservo.attach(16); //Analog-Pins 0
 myservo.attach(17);//Analog-Pins 1
 myservo.attach(18);//Analog-Pins 2
 myservo.attach(19);//Analog-Pins 3
Hier weist Du dem selben myservo Objekt 5 mal hintereinander einen anderen Pin zu.

Du willst eher sowas:
Code: [Select]
myservo.attach(3);  // attaches the servo on pin 3 to the servo object // Anhängen des Servo-Objets am Pin 3
 myservo1.attach(16); //Analog-Pins 0
 myservo2.attach(17);//Analog-Pins 1
 myservo3.attach(18);//Analog-Pins 2
Die Objekte myservo bis myservo3 hast du weiter oben in deinem Code schon definiert. Die letzte Linie mit Analog 3 habe ich gelöscht, weil du sonst im ganzen Code nur 4 Servos verwendest.


 
Quote
Code: [Select]
ch1 = map(ch1,1030, 2003, 0, 180); //adjust the first receiver channel to the value of Servo-Library  //Anpassen der Pulsweitensignale auf die gebräuchlichen Servo-Library-Werte von 0 bis 180
   myservo.write(ch1); //write adjusted value from above to first servo  //Gibt den korrigierten Wert an den Servo aus
  ch2 = map(ch2,1030, 2003, 0, 180);//adjust the second receiver channel ... //Wieder das selbe wie oben, anpassen und an den Servo ausgeben, usw.
   myservo.write(ch2); //write adjusted value from above(ch2) to second servo
  ch3 = map(ch3,1030, 2003, 0, 180);// adjust No.3
    myservo.write(ch3); //same as the two examples before
  ch4 = map(ch4,1030, 2003, 0, 180);//adjust No.4
    myservo.write(ch4); //write adjusted value from above to first servo
Hier ist nochmals das selbe, du "sendest" den Wert des Kanals immer an den selben Servo.

Das sind bis jetzt 4 Kanäle, einen fünften kannst Du einfach hinzufügen. Was ich etwas unglücklich finde ist, wenn du für den selben Servo einmal myservo1 verwendest und dann den dazugehörigen Wert des Kanals in ch2 speicherst, übersichtlicher ist, wenn du immer den gleichen Index brauchst.


Der Code mit 5 Kanälen, den Pin für den 5ten Kanal musst du eventuell noch anpassen. Im Moment ist es D9.
Code: [Select]
/*
 RC PulseIn Serial Read out, with adjusted Output to Servos for Arduinos and compatibles
 By: Nick Poole, BARRAGAN, Patric Hausammann
 SparkFun Electronics
 Date: 07.07.2014
 License: CC-BY SA 3.0 - Creative commons share-alike 3.0
 use this code however you'd like, just keep this license and
 attribute. Let me know if you make hugely, awesome, great changes.
 */
 
int ch1; // Here's where we'll keep our channel values // Hier werden die Werte hinterlegt
int ch2;
int ch3;
int ch4;
int ch5;


#include <Servo.h>  //enable Servo-Library // die Servo-Library anhängen
 
Servo myservo1;  // create servo object to control a servo // erstellen eines Servo-Objekts
                // a maximum of eight servo objects can be created // laut Library können acht Servo-Objekte erstellt werden
Servo myservo2;
Servo myservo3;
Servo myservo4; 
Servo myservo5;  //here I've created 5 servo objects which begins with myservo1 and ends with myservo4 //Hier habe ich 5 Servo-Objekte von myservo bis myservo3 erstellt
 
//int pos = 0;    //Normally this would be the variable to store the servo position from 0 to 180 , which represents the sevo way, but in this case I used the variables ch1 to ch4
 // Normalerweise wäre (int pos=0) die Variable zum hinterlegen der Gradanzahl des Ausschlags des Servos von 0 bis 180, hier wurde diese Variable ausgelassen resp. durch ch1 bis ch4 ersetzt


void setup() {

  pinMode(5, INPUT); // Set our input pins as such   //hier werden die Output-Pins als solche definiert
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  pinMode(8, INPUT);
  pinMode(9, INPUT);// fünfter Kanal, den richtigen Pin musst Du noch festlegen <---------------------------------------------------------

 myservo1.attach(3);  // attaches the servo on pin 3 to the servo object // Anhängen des Servo-Objets am Pin 3
 myservo2.attach(16); //Analog-Pins 0
 myservo3.attach(17);//Analog-Pins 1
 myservo4.attach(18);//Analog-Pins 2
 myservo5.attach(19);//Analog-Pins 3

  Serial.begin(9600); // Pour a bowl of Serial

}

void loop() {

  ch1 = pulseIn(5, HIGH, 25000); // Read the pulse width of //Liest die Pulsweite
  ch2 = pulseIn(6, HIGH, 25000); // each channel // jedes Kanals
  ch3 = pulseIn(7, HIGH, 25000);
  ch4 = pulseIn(8, HIGH, 25000);
  ch5 = pulseIn(9, HIGH, 25000); // fünfter Kanal, den richtigen Pin musst Du noch festlegen  <---------------------------------------------------------
 
  ch1 = map(ch1,1030, 2003, 0, 180); //adjust the first receiver channel to the value of Servo-Library  //Anpassen der Pulsweitensignale auf die gebräuchlichen Servo-Library-Werte von 0 bis 180
   myservo1.write(ch1); //write adjusted value from above to first servo  //Gibt den korrigierten Wert an den Servo aus
  ch2 = map(ch2,1030, 2003, 0, 180);//adjust the second receiver channel ... //Wieder das selbe wie oben, anpassen und an den Servo ausgeben, usw.
   myservo2.write(ch2); //write adjusted value from above(ch2) to second servo
  ch3 = map(ch3,1030, 2003, 0, 180);// adjust No.3
    myservo3.write(ch3); //same as the two examples before
  ch4 = map(ch4,1030, 2003, 0, 180);//adjust No.4
    myservo4.write(ch4); //write adjusted value from above to first servo
  ch5 = map(ch5,1030, 2003, 0, 180);//adjust No.5
    myservo5.write(ch5); //write adjusted value from above to first servo
 
  Serial.print("Channel 1:"); // Print the value of  //Gibt die Werte aller Kanäle nach einander im Serial Monitor wieder
  Serial.println(ch1);        // each channel

  Serial.print("Channel 2:");
  Serial.println(ch2);

  Serial.print("Channel 3:");
  Serial.println(ch3);

  Serial.print("Channel 4:");
  Serial.println(ch4);
 
  Serial.print("Channel 5:");
  Serial.println(ch5);


  delay(100); // I put this here just to make the terminal // Damit es im Terminal nicht all zu sehr ruckelt
              // window happier
}

Ich habe keinen Servo zur Hand. Kompilieren tut der Code, ob er nun auch so funktioniert wie gewünscht - keine Ahnung.
« Last Edit: July 07, 2014, 09:07:31 PM by mikeZ337 »

House

  • freakyfriday
  • Jr. Member
  • *
  • Posts: 95
  • Karma: +1/-0
    • Hausammann-Dekor
Lieber mikeZ337,

Danke, für Deine Hinweise ;). Habe den Sketch auf 4 Kanäle reduziert, den Index angepasst und diverses Anderes korrigiert. Hoffe das passt so.  Sorry musste den Sketch gestern aufs neue zusammenstellen, weshalb ich ein paar Anpassungen vergessen habe. Da die einzelnen Elemente des Sketches für sich alleine funktionieren, jedoch die Servos beim ganzen Sketch nicht alle korrekt reagieren, denke ich, dass sich die interrupts von PulseIn und servo.write nicht vertragen. Hatte schon jemand ähnliche Probleme oder gar eine Lösung zu den Interrupts? Ich denke das ganze hängt mit dem 16-Bit Timer zusammen, da der möglicherweise der einzig verwendbare Timer für diese Aufgabe ist. Bin mir zwar sicher das der ArduinoUNO und Clon konsorten drei Timer besitzen, jedoch verfügt nur ein Timer über 16-Bit und ob 8-Bit von der Auflösung her reichen ist eine andere Frage, ich vermute eher nicht.
Ein ganz anderer Ansatz, den ich mir noch vorstellen könnte wäre, zwei ArduinoNANO zu verwenden (gefällt mir nicht ganz so gut). Dem einen gebe ich die Aufgabe die Kanäle der Funke einzulesen und sie per digital.Write od. seriel gemapt resp. korrigiert an den zweiten NANO zu senden. Der empfängt wiederum und verrechnet das ganze auf Wunsch mit Gyro, Accelerometer, 3-Achs-Kompass, GPS und ggf. mit Barometer und gibt auch die Impulse an die Servos aus. Ein NANO alleine wäre mit so vielen Sensoren und Servos resp. ESC's (Brushless Motorregler) womöglich sowieso überfordert. Wäre nicht noch das Problem mit dem Gewicht bzw. der Grösse, würde ich das ganze in doppelter Ausführung(4xNANO) integrieren um die Redundanz, wie auch den FailSave zu 99,99 Prozent zu garantieren oder im aller schlimmsten Fall ein Rettungssystem auszulösen(Fallschirm, CO2-Kapsel-Airbag ;D). Wäre ein Multiplexer ein einfacherer Lösungsansatz? Bin jedoch bei der Umsetzung recht unentschlossen, und bin um jeden sinnvollen Rat bzw. Tip dankbar.

MfG
P. Hausammann
« Last Edit: July 08, 2014, 12:07:35 PM by House »

pylon

  • freakyfriday
  • Full Member
  • *
  • Posts: 158
  • Karma: +16/-0
Quote
denke ich, dass sich die interrupts von PulseIn und servo.write nicht vertragen.

pulseIn() verwendet keine Interrupts. Hingegen wird für die serielle Ausgabe ein Interrupt verwendet. Lass mal die serielle Ausgabe weg bzw. kürze sie auf das Allernotwendigste, dann dürftest Du weniger Probleme haben. Allenfalls müsstest Du das pulseIn() ersetzen, hängt aber davon ab, welche Probleme Du genau hast.

Kannst Du näher umschreiben, was Du unter "nicht korrekt reagieren" verstehst? Sind die gelesenen Werte korrekt und nur die Servo-Ausgabe nicht oder wird der Empfänger schon falsch gelesen?

Quote
Ein ganz anderer Ansatz, den ich mir noch vorstellen könnte wäre, zwei ArduinoNANO zu verwenden

Das dürfte Deine Timing-Probleme tendenziell vergrössern, denn die Kommunikation zwischen den beiden dürfte Dir an vielen Orten Verzögerungen einstreuen.

Wäre ein Teensy 3.x eine Alternative? Die Software-Unterstützung ist natürlich bei weitem nicht so weit wie beim Arduino, aber die Hardware ist doch bedeutend potenter.

House

  • freakyfriday
  • Jr. Member
  • *
  • Posts: 95
  • Karma: +1/-0
    • Hausammann-Dekor
Lieber pylon,

Danke für deine Antwort ;). Betreffend interrupts und PulseIn gabs bei mir noch Unklarheiten :o, dacht mir die beiden kommen sich ins Gehege. Da ich die serielle Ausgabe schon ganz deaktiviert (raus genommen) habe und ich immer noch nicht mehr als 3 Receiverkanäle auf 3 Servos legen kann, bin ich ein wenig ratlos. An der Stromversorgung kann's meiner Meinung nach nicht liegen, da ich die Kanäle mit einem einzelnen Servo durch gecheckt habe. Betreffend nicht korrekt reagieren meine ich, dass sich die 2 nicht funktionierenden Servos willkürlich Stellen und nicht auf die Fernsteuerbefehle reagieren, manchmal gibt es unerklärbare Ausschläge oder gar unkontrolliertes Zittern(Jitter), die anderen drei Kanäle funktionieren tadellos.

Wie meinst du das mit dem Ersetzen von pulseIn()? Durch was, bzw.wie kann man den Befehl ersetzen? Ich hab hier ein Skript im Netzgefunden, was möglicherweise in richtung deines Ansatzes geht. Ich hänge ganz unten mal den Code an. Auch hier laufen die 3 Kanäle problemlos, hatte jedoch noch keine Zeit das Skript auf 5 Kanäle zu erweitern. Zudem frage ich mich weshalb der AUX_Flag Wert auf 4 gesetzt wurde und nicht auf 3?

Ich dachte mir auch schon, dass zwei Nanos zuviel Verzögerung erzeugen, also fällt dieser Lösungsansatz schon mal weg :(.

Betreffend Teensy 3.x bin ich mir noch unsicher, da ich mich mit diesem MC noch überhaupt nicht auskenne. Im Hinterkopf habe ich noch den Ansatz meinen rum liegenden ArduPilotMEGA2 zu verwenden,jedoch hab ich auch hier meine Probleme da ich mit dem FTDI scheinbar keine Uploads aufs Board mehr hin bekomme. Vielleicht kann mir ja jemand an einem Freaky Friday weiterhelfen. Der PilotMEGA sollte das Projekt auch hinbekommen und ich würde es gerne mit Ihm probieren, bevor ich auf was "neues" wie das Teensy 3 umsteige.

MfG
Patric Hausammann

P.S.: Hier der oben erwähnte Code von  rcarduino.blogspot.com

 // MultiChannels
//
// rcarduino.blogspot.com
//
// A simple approach for reading three RC Channels using pin change interrupts
//
// See related posts -
// http://rcarduino.blogspot.co.uk/2012/01/how-to-read-rc-receiver-with.html
// http://rcarduino.blogspot.co.uk/2012/03/need-more-interrupts-to-read-more.html
// http://rcarduino.blogspot.co.uk/2012/01/can-i-control-more-than-x-servos-with.html
//
// rcarduino.blogspot.com
//

// include the pinchangeint library - see the links in the related topics section above for details
#include <PinChangeInt.h>

#include <Servo.h>

// Assign your channel in pins
#define THROTTLE_IN_PIN 8
#define STEERING_IN_PIN 9
#define AUX_IN_PIN 10

// Assign your channel out pins
#define THROTTLE_OUT_PIN 5
#define STEERING_OUT_PIN 6
#define AUX_OUT_PIN 7

// Servo objects generate the signals expected by Electronic Speed Controllers and Servos
// We will use the objects to output the signals we read in
// this example code provides a straight pass through of the signal with no custom processing
Servo servoThrottle;
Servo servoSteering;
Servo servoAux;

// These bit flags are set in bUpdateFlagsShared to indicate which
// channels have new signals
#define THROTTLE_FLAG 1
#define STEERING_FLAG 2
#define AUX_FLAG 4

// holds the update flags defined above
volatile uint8_t bUpdateFlagsShared;

// shared variables are updated by the ISR and read by loop.
// In loop we immediatley take local copies so that the ISR can keep ownership of the
// shared ones. To access these in loop
// we first turn interrupts off with noInterrupts
// we take a copy to use in loop and the turn interrupts back on
// as quickly as possible, this ensures that we are always able to receive new signals
volatile uint16_t unThrottleInShared;
volatile uint16_t unSteeringInShared;
volatile uint16_t unAuxInShared;

// These are used to record the rising edge of a pulse in the calcInput functions
// They do not need to be volatile as they are only used in the ISR. If we wanted
// to refer to these in loop and the ISR then they would need to be declared volatile
uint32_t ulThrottleStart;
uint32_t ulSteeringStart;
uint32_t ulAuxStart;

void setup()
{
  Serial.begin(9600);
 
  Serial.println("multiChannels");

  // attach servo objects, these will generate the correct
  // pulses for driving Electronic speed controllers, servos or other devices
  // designed to interface directly with RC Receivers
  servoThrottle.attach(THROTTLE_OUT_PIN);
  servoSteering.attach(STEERING_OUT_PIN);
  servoAux.attach(AUX_OUT_PIN);

  // using the PinChangeInt library, attach the interrupts
  // used to read the channels
  PCintPort::attachInterrupt(THROTTLE_IN_PIN, calcThrottle,CHANGE);
  PCintPort::attachInterrupt(STEERING_IN_PIN, calcSteering,CHANGE);
  PCintPort::attachInterrupt(AUX_IN_PIN, calcAux,CHANGE);
}

void loop()
{
  // create local variables to hold a local copies of the channel inputs
  // these are declared static so that thier values will be retained
  // between calls to loop.
  static uint16_t unThrottleIn;
  static uint16_t unSteeringIn;
  static uint16_t unAuxIn;
  // local copy of update flags
  static uint8_t bUpdateFlags;

  // check shared update flags to see if any channels have a new signal
  if(bUpdateFlagsShared)
  {
    noInterrupts(); // turn interrupts off quickly while we take local copies of the shared variables

    // take a local copy of which channels were updated in case we need to use this in the rest of loop
    bUpdateFlags = bUpdateFlagsShared;
   
    // in the current code, the shared values are always populated
    // so we could copy them without testing the flags
    // however in the future this could change, so lets
    // only copy when the flags tell us we can.
   
    if(bUpdateFlags & THROTTLE_FLAG)
    {
      unThrottleIn = unThrottleInShared;
    }
   
    if(bUpdateFlags & STEERING_FLAG)
    {
      unSteeringIn = unSteeringInShared;
    }
   
    if(bUpdateFlags & AUX_FLAG)
    {
      unAuxIn = unAuxInShared;
    }
   
    // clear shared copy of updated flags as we have already taken the updates
    // we still have a local copy if we need to use it in bUpdateFlags
    bUpdateFlagsShared = 0;
   
    interrupts(); // we have local copies of the inputs, so now we can turn interrupts back on
    // as soon as interrupts are back on, we can no longer use the shared copies, the interrupt
    // service routines own these and could update them at any time. During the update, the
    // shared copies may contain junk. Luckily we have our local copies to work with :-)
  }
 
  // do any processing from here onwards
  // only use the local values unAuxIn, unThrottleIn and unSteeringIn, the shared
  // variables unAuxInShared, unThrottleInShared, unSteeringInShared are always owned by
  // the interrupt routines and should not be used in loop
 
  // the following code provides simple pass through
  // this is a good initial test, the Arduino will pass through
  // receiver input as if the Arduino is not there.
  // This should be used to confirm the circuit and power
  // before attempting any custom processing in a project.
 
  // we are checking to see if the channel value has changed, this is indicated
  // by the flags. For the simple pass through we don't really need this check,
  // but for a more complex project where a new signal requires significant processing
  // this allows us to only calculate new values when we have new inputs, rather than
  // on every cycle.
  if(bUpdateFlags & THROTTLE_FLAG)
  {
    if(servoThrottle.readMicroseconds() != unThrottleIn)
    {
      servoThrottle.writeMicroseconds(unThrottleIn);
    }
  }
 
  if(bUpdateFlags & STEERING_FLAG)
  {
    if(servoSteering.readMicroseconds() != unSteeringIn)
    {
      servoSteering.writeMicroseconds(unSteeringIn);
    }
  }
 
  if(bUpdateFlags & AUX_FLAG)
  {
    if(servoAux.readMicroseconds() != unAuxIn)
    {
      servoAux.writeMicroseconds(unAuxIn);
    }
  }
 
  bUpdateFlags = 0;
}


// simple interrupt service routine
void calcThrottle()
{
  // if the pin is high, its a rising edge of the signal pulse, so lets record its value
  if(digitalRead(THROTTLE_IN_PIN) == HIGH)
  {
    ulThrottleStart = micros();
  }
  else
  {
    // else it must be a falling edge, so lets get the time and subtract the time of the rising edge
    // this gives use the time between the rising and falling edges i.e. the pulse duration.
    unThrottleInShared = (uint16_t)(micros() - ulThrottleStart);
    // use set the throttle flag to indicate that a new throttle signal has been received
    bUpdateFlagsShared |= THROTTLE_FLAG;
  }
}

void calcSteering()
{
  if(digitalRead(STEERING_IN_PIN) == HIGH)
  {
    ulSteeringStart = micros();
  }
  else
  {
    unSteeringInShared = (uint16_t)(micros() - ulSteeringStart);
    bUpdateFlagsShared |= STEERING_FLAG;
  }
}

void calcAux()
{
  if(digitalRead(AUX_IN_PIN) == HIGH)
  {
    ulAuxStart = micros();
  }
  else
  {
    unAuxInShared = (uint16_t)(micros() - ulAuxStart);
    bUpdateFlagsShared |= AUX_FLAG;
  }
}
« Last Edit: July 09, 2014, 11:45:10 AM by House »

pylon

  • freakyfriday
  • Full Member
  • *
  • Posts: 158
  • Karma: +16/-0
Quote
An der Stromversorgung kann's meiner Meinung nach nicht liegen, da ich die Kanäle mit einem einzelnen Servo durch gecheckt habe.

Damit kannst Du die Stromversorgung aber nicht checken. Wenn 5 Servos gleichzeitig laufen, belastet das die Stromversorgung deutlich mehr als nur einer allein.

Quote
Betreffend nicht korrekt reagieren meine ich, dass sich die 2 nicht funktionierenden Servos willkürlich Stellen und nicht auf die Fernsteuerbefehle reagieren, manchmal gibt es unerklärbare Ausschläge oder gar unkontrolliertes Zittern(Jitter), die anderen drei Kanäle funktionieren tadellos.

Damit dürfte die pulseIn()-Funktion fein raus sein, denn die sollte bei 5 immer noch gleich funktionieren, wie bei nur 3, Du misst ja nacheinander, somit kommen sich die nicht in's Gehege.

Funktionieren die ersten 3 auch gut, wenn alle 5 aktiviert sind? Falls ja, dann dürfte das Problem in der Servo-Bibliothek zu suchen sein. Die Servo-Ansteuerung wird dort hintereinander ausgeführt, somit könnte das bei mehr Servos durchaus eine Fehlerquelle sein. Welchen Servo-Typ setzt Du denn ein? Sind alle vom selben Typ?

Quote
Zudem frage ich mich weshalb der AUX_Flag Wert auf 4 gesetzt wurde und nicht auf 3?

Weil der Wert des Bits abgefragt wird und nicht die Bitnummer. Bit 0 hat den Wert 1, Bit 1 den Wert 2 und Bit 3 hat den Wert 4.


House

  • freakyfriday
  • Jr. Member
  • *
  • Posts: 95
  • Karma: +1/-0
    • Hausammann-Dekor
- Sorry, denke mir bezüglich Stromversorgung haben wir uns falsch verstanden bzw. ich habe mich vielleich zu unklar ausgedrückt. Ich habe  zum Testen, mit nur einem Servo, alle Kanäle nacheinader überprüft um nicht an die Lastgrenze des MC's zu stossen. Später wird ein Projekt resp. die Servos davon mit einer separaten 5 Volt 2 Ampere betrieben. Beim anderen Projekt, einem Tri-Copter spielt die Stromversorgung nicht so ne grosse Rolle, da drei Esc's und nur ein Servo am System hängen. Die Esc's müssen jeweils nur mit GND und Outputsignal verbunden sein, um sie zu Steuern. Dann ziehe ich von einem der Esc's 5Volt für die Stromversorgung des MC's, die Spannungsversorgung der übrigen zwei Esc's dürfen nicht angeschlossen werden.
Beim Sketch mit den 5 Servos funktionieren nur jeweils 3, ich kann zwar die Kanäle vom Receiver tauschen, jedoch liegt es nicht am Receiver, da die Servos, wenn sie direkt am Receiver betrieben gut funktionieren und auch beim Umstecken der Input-Kanäle bleiben immer nur die selben drei Output-Kanäle schaltbar.

- Bezüglich Testservos, setze ich bei allen auf die kleinen blauen 9g mini Servos, welche bei Boxtec erhältlich sind. Dachte mir, dass dieser Typ ideal für solche Testzwecke ist.

- Danke für die Erklärung betreffend Wert des Bits, nun verstehe ichs :D!

House

  • freakyfriday
  • Jr. Member
  • *
  • Posts: 95
  • Karma: +1/-0
    • Hausammann-Dekor
Fortschritt mit Teensy
« Reply #7 on: August 04, 2014, 03:52:29 PM »
Hi pylon,

habe mir ein Teensy 3.1 gekauft, worauf mein Sketch mit fünf Kanälen vom Receiver und den dazugehörigen Testservos perfekt läuft. Danke Dir für den super Tip! Das Teensy ist sehr gut für mein Projekt geeignet, da "fast" alle Pins 5 Volt tolerant sind. Jedoch sollte beachtet werden, das die Pins Analog von A10 bis A14, AREF, Program und Reset  nur 3.3V aushalten. Also bei diesen Pins auf keinen Fall höher als 3.3 Volt. Auch betreffend der Grösse und des Gewichts ist das Teensy genial(klein). Nun muss ich "nur" noch mein MPU-6050 - Projekt mit dem RC-Receiver/Servo-Projekt "verknüpfen" bzw. beide Sketches zusammen führen :D, dann kommt der Testflug :o.

MfG House