RC Empfängersignal PWM auslesen und Funktionen über PWM steuern /Kehrjet-Antrieb

Hallo zusammen,

möchte zuerst kurz mein Projekt vorstellen, habe ein RCBoot mit Jetantrieb und Autopiloten. Der Autopilot ist leider nur ein 3 Kanal (Antrieb/Richtung/Futterklappen). Damit man einen Kehr-Jet Antrieb betreiben kann, benötigt man schon 2 Kanäle für Antrieb und Schubumkehrklappe. Über den Arduino möchte ich nun aus einem Kanal je nach PWM verschiedene PWM's generieren und somit den einen fehlenden Kanal ersetzen.

verwende folgenden Code zum Auslesen des PWM-Signals eines RC Empfängers.

// Controller 
const int CH_2_PIN = 11;

void setup () {
  Serial.begin(9600);
}

void loop () {
    int ch_2 = pulseIn(CH_2_PIN, HIGH, 25000);
    Serial.println(ch_2);
    delay(5);
}

Das PWM Eingangssignal variiert je nach Position des Senders zwischen

  • 2000ms 100% Gas vorwärts
  • 1500ms neutral
  • 1000ms 100% Gas rückwärts

SCHRITT 1

Zum besseren Verständnis möchte ich im ersten Schritt die PWM-Frequenzen 1 zu 1 wieder auf einen Ausgang des Arduino legen. Der Arduino würde nur am Monitor die PWM anzeigen. PWM-Frequenz bleibt gleich.

SCHRITT 2

Ziel, die Ausgabe PWM soll immer über 1500 ms liegen. Also wenn man Rückwärts wählt soll die PWM nicht auf 1000ms am Ausgang sinken sondern ebenfalls wieder auf 2000ms steigen.

SCHRITT 3

Nun soll zusätzich zwischen 1450ms und 1000ms ein weiterers PWM Signal ausgegeben werden, welches immer 2000ms hat.

Nun ist mir nicht klar wie ich den Code erweitern muss. Meine Versuche scheitern kläglich.
Hoffe Ihr könntet mir weiterhelfen, würde gerne die Thematik besser verstehen und habe dies in 3 Schritte geteilt.

Vielen Dank und Grüße
Joe

Hi

Wohin schickst Du dieses 2.te Signal mit 2000ms (wirklich zweitausend Millisekunden?? Das sind 2 Sekunden).

Erfasse erst Mal das ankommende Signal.
Nun hetzt Du Da einige IFs drauf und entscheidest damit, WAS gemacht werden soll.
Dieses 'WAS' gibst Du im Terminal aus.

Wenn Das Deinen Vorstellungen entspricht, 'baust' Du dieses WAS einfach ein :slight_smile:

Die 2000ms 'riechen' nach einem Servo-Antrieb, wobei das Servo ganz gerne 1ms...2ms hätte (also 2000µs).
In die Richtung geht auch 'RC'.

Das 'weiter reichen des aktuellen Wert' ist 'Baustelle Nummer 2' - DAS muß jetzt noch gar nicht funktionieren!!

MfG

Hi,

Danke erstmal,

Wohin schickst Du dieses 2.te Signal mit 2000ms (wirklich zweitausend Millisekunden?? Das sind 2 Sekunden).

Sorry, 2ms

Erfasse erst Mal das ankommende Signal.

Habe ich erfasst PW 1000 - 2000 also 1ms - 2ms mit 50Hz

Nun hetzt Du Da einige IFs drauf und entscheidest damit, WAS gemacht werden soll.
Dieses 'WAS' gibst Du im Terminal aus.

Wenn Das Deinen Vorstellungen entspricht, 'baust' Du dieses WAS einfach ein :slight_smile:

Die 2000ms 'riechen' nach einem Servo-Antrieb, wobei das Servo ganz gerne 1ms...2ms hätte (also 2000µs).
In die Richtung geht auch 'RC'.

Bin immer in ms in RC Foren unterwegs, Sorry der Arduino gibt ja µs-Werte aus.

Das 'weiter reichen des aktuellen Wert' ist 'Baustelle Nummer 2' - DAS muß jetzt noch gar nicht funktionieren!!

Moin,

Über sowas bin ich doch gerade erst vor ein paar Tagen gestolpert.
Siehe hier:

Lieben Gruß,
Chris

Hallo Chris,

das wäre die Musterlösung :wink:

Leider bekomme ich beim Kompillieren eine Fehlermeldung. Ich nutze einen Arduino/Genuino Uno.

Bei dem Sketch wurde folgende Board verwendet: Arduino Duemilanove, ATTiny85

Bekomme folgende Fehlermeldung:

Arduino: 1.8.5 (Windows 10), Board: "Arduino/Genuino Uno"

C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Admin\Documents\Arduino\libraries -fqbn=arduino:avr:uno -vid-pid=0X2341_0X0043 -ide-version=10805 -build-path C:\Users\Admin\AppData\Local\Temp\arduino_build_530273 -warnings=none -build-cache C:\Users\Admin\AppData\Local\Temp\arduino_cache_695801 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -verbose C:\Users\Admin\Documents\Arduino\Jet\Jet.ino
C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Admin\Documents\Arduino\libraries -fqbn=arduino:avr:uno -vid-pid=0X2341_0X0043 -ide-version=10805 -build-path C:\Users\Admin\AppData\Local\Temp\arduino_build_530273 -warnings=none -build-cache C:\Users\Admin\AppData\Local\Temp\arduino_cache_695801 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -verbose C:\Users\Admin\Documents\Arduino\Jet\Jet.ino
Using board 'uno' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
Using core 'arduino' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
Detecting libraries used...
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "C:\Users\Admin\AppData\Local\Temp\arduino_build_530273\sketch\Jet.ino.cpp" -o "nul"
"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "C:\Users\Admin\AppData\Local\Temp\arduino_build_530273\sketch\Jet.ino.cpp" -o "C:\Users\Admin\AppData\Local\Temp\arduino_build_530273\preproc\ctags_target_for_gcc_minus_e.cpp"
C:\Users\Admin\Documents\Arduino\Jet\Jet.ino:2:19: fatal error: debug.h: No such file or directory

#include <debug.h>

^

compilation terminated.

exit status 1
Fehler beim Kompilieren für das Board Arduino/Genuino Uno.

Liegt das an meinem Board?

MFG
Joe

debug.h: No such file or directory

Mindestens die debug.h fehlt Dir (also, steht zumindest da) - was immer Die auch machen soll.

MfG

Hi,

also ich hätte Sie gefunden inkl. aller anderen die der Ersteller hinterlegt hat unter:

Library's

Nun hätte ich die Library z.B. debug.h unter einem neuen TAB in dem JET Sketch eingefügt. Leider wird diese wieder nicht gefunden.

Muss ich diese anderweitig hinzufügen?

MFG
Joe

Lies Dir mal das hier durch.
Die falsch installierten Libs wieder löschen.

Gruß Tommy

Hallo zusammen,

und alle Newbis bei denen alles schnell gehen soll :wink:

Über github.com findet man meist alle Libs, wenn Sie vom Programmierer hinterlegt wurden. Ich hatte Glück alle waren da und alles funktioniert.

Leider finde ich den Sketch in der Anwendung etwas verwirrend. Zum einen ist die Anleitung falsch, da die Pins falsch beschrieben sind. Dies ist aber schnell ermittelt. Viel mehr bekomme ich viele Störsignale auf den Ausgang, was bei 0/1 Servos nicht tauglich ist.

Gut gedachter Sketch nur ein bisschen "to much", das Interpolieren am Anfang müsste nicht sein. Leider bin ich noch nicht so tief drinnen, dass ich schon groß Änderungen vornehmen kann.

Vielen Dank nochmal für eure Unterstützung, aber ich muss erst mal laufen lernen :wink:

VG
Joe

Guten Morgen,

muedejoe:
verwende folgenden Code zum Auslesen des PWM-Signals eines RC Empfängers.

Du meinst doch PPM und nicht PWM oder?

Aus meiner Sammelgrube (ungetestet):

//Zum einlesen eines PPM Kanals
const uint8_t pin_PPM = 2; //PIND(2) = Pin 2 Arduino UNO
const uint16_t high_PPM = 1750;
volatile uint32_t PPM_start, PPM_end;

void get_PPM() //ISR
{
  if (bitRead(PIND, 2)) PPM_start = micros();
  else                  PPM_end = micros();
}
void setup()
{
  Serial.begin(19200); while (!Serial) {}
  pinMode(LED_BUILTIN, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(pin_PPM), get_PPM, CHANGE);
}
void loop()
{
  uint32_t dauer_PPM = 0;
  if (PPM_start < PPM_end) dauer_PPM = PPM_end - PPM_start;
  if (dauer_PPM >= high_PPM) digitalWrite(LED_BUILTIN, HIGH);
  else digitalWrite(LED_BUILTIN, LOW);
  if (dauer_PPM > 0) Serial.println(dauer_PPM);
}
/* 06.2018 PPM Signalgenerator by grillgemuese
   PPM Pulsdauer  1000-2000us
   PPM Zyklus     20000us
   PPM Kanaele    2-8
   fuer digitalRead() -> 0=LOW 1023=HIGH
*/
//Makros fuer PPM Pin 4 (Arduino UNO)
#define PD4_PPM B00010000           //oder (1 << PD4)
#define PD4_ON PORTD |= PD4_PPM     //aktiviert   Pin 4
#define PD4_OFF PORTD &= ~PD4_PPM   //deaktiviert Pin 4

#define ppm_ch 4                    //Kanalanzahl (2-8)
#if ppm_ch > 8
#error ppm_ch zu gross! (maximal 8)
#elif ppm_ch < 2
#error ppm_ch zu klein! (minimal 2)
#endif
//globale Variablen
//const uint8_t ai_pin[ppm_ch] = {A2, A3, A4, A5};
const uint32_t ai_read_takt = 5; //ms

//Prototypen
void ppm_ausgabe(const uint32_t *ch_raw);

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); //nerft auf dem Tisch
  DDRD |= PD4_PPM; //Pin 4 als Ausgang
}//void setup() ENDE

void loop()
{
  static uint16_t testwerte[ppm_ch]; //dient dem Test!
  static uint32_t ai_read_ms;
  static uint32_t ai_raw[ppm_ch];
  uint32_t akt_ms = millis(); //pro loop aktuelle ms
  //Werte einlesen
  if (akt_ms - ai_read_ms >= ai_read_takt)
  {
    ai_read_ms = akt_ms;
    for (uint8_t ch = 0; ch < ppm_ch; ch++)
    {
      if (testwerte[ch] < 1023) testwerte[ch] += 1;
      else testwerte[ch] = 0;
      ai_raw[ch] = testwerte[ch]; //dient dem Test!
      //ai_raw[ch] = analogRead(ai_pin[ch]);
    }
  }
  ppm_ausgabe(ai_raw); //jeden loop-Zyklus aufrufen!
}//void loop() ENDE

void ppm_ausgabe(const uint32_t *ch_raw)
{
  enum {START, STOP, KANAL};
  const uint32_t ppm_total = 20000; //20ms
  const uint32_t ppm_puls_min = 700;
  const uint32_t ppm_puls_max = 1700;
  const uint32_t ppm_stop = 300;

  static uint8_t akt_mode = STOP;
  static uint8_t akt_ch = ppm_ch;
  static uint32_t ppm_last_us, ppm_start_us, ppm_ch_us;
  static uint32_t ppm_pause = 10000; //wird dynamisch an ppm_total angepasst

  uint32_t akt_us = micros();
  switch (akt_mode)
  {
    case START:
      if (akt_us - ppm_start_us >= ppm_pause)
      {
        ppm_last_us = akt_us;
        akt_mode = STOP;
        PD4_OFF;
      }
      break;
    case STOP:
      if (akt_us - ppm_last_us >= ppm_stop)
      {
        ppm_last_us = akt_us;
        if (akt_ch < ppm_ch)
        {
          ppm_ch_us = map(ch_raw[akt_ch], 0, 1023, ppm_puls_min, ppm_puls_max);
          akt_mode = KANAL;
          akt_ch++;
          PD4_ON;
        }
        else
        {
          ppm_start_us = akt_us;
          ppm_pause = ppm_total - (akt_us - ppm_start_us);
          akt_mode = START;
          akt_ch = 0;
          PD4_ON;
        }
      }
      break;
    case KANAL:
      if (akt_us - ppm_last_us >= ppm_ch_us)
      {
        ppm_last_us = akt_us;
        akt_mode = STOP;
        PD4_OFF;
      }
      break;
  }
}//void ppm_ausgabe() ENDE

Gruß
grillgemuese :slight_smile: