Go Down

Topic: RC Empfängersignal PWM auslesen und Funktionen über PWM steuern /Kehrjet-Antrieb (Read 713 times) previous topic - next topic

muedejoe

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.


Code: [Select]
// 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

postmaster-ino

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 :)

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
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

muedejoe

Hi,

Danke erstmal,

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

Quote
Sorry, 2ms
Erfasse erst Mal das ankommende Signal.

Quote
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 :)

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'.

Quote
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!!

themanfrommoon

Moin,

Über sowas bin ich doch gerade erst vor ein paar Tagen gestolpert.
Siehe hier:
http://wkla.no-ip.biz/ArduinoWiki/doku.php?id=arduino:modellbau:projekte:rueckfahrklappensteuerung-eines-jet-antriebes

Lieben Gruß,
Chris


muedejoe

Hallo Chris,

das wäre die Musterlösung  ;)

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:

Quote
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

postmaster-ino

Code: [Select]
debug.h: No such file or directory
Mindestens die debug.h fehlt Dir (also, steht zumindest da) - was immer Die auch machen soll.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

muedejoe

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

Tommy56

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

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

muedejoe

Hallo zusammen,

und alle Newbis bei denen alles schnell gehen soll ;-)

Ü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 ;-)

VG
Joe

grillgemuese

Guten Morgen,

verwende folgenden Code zum Auslesen des PWM-Signals eines RC Empfängers.
Du meinst doch PPM und nicht PWM oder?

Aus meiner Sammelgrube (ungetestet):
Code: [Select]
//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);
}

Code: [Select]
/* 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 :)

Go Up