Arduino: Servo PWM Signale zu PPM

OP #2865355
Lesenswert?
• ▲
▼
Hey,
ich habe einen RC Simulator, der seine Signale von einer Fernsteuerung 
durch ein PPM Signal erhält. Da das benötigte Kabel etwas nervt, möchte 
ich gerne den RC Empfänger an das Simulatorkabel anschließen können. Das 
ganze soll mit einem Arduino Uno passieren.

Bis jetzt habe ich alle Servo Ausgänge (PWM) mit PinChange interrupts 
eingelesen bzw. die Zeit zwischen den Flanken gemessen.
Wie kann ich jetzt das benötigte PPM Signal (die Kombination aller 
Servosignale) erzeugen? Ich denke da an Timer interrupts. Meine Frage 
ist, wie man diese interrupts am besten kombinieren kann, ohne die 
zeitkritische Verarbeitung bzw. Erzeugung der Signale zu stören?

Falls es wichtig ist, hier noch der Code zum Lesen der Servosignale vom 
Empfänger:
1
#include <avr/interrupt.h>
2
#include <avr/io.h> 
3

4
typedef struct {
5
  byte edge;
6
  unsigned long riseTime;
7
  unsigned long fallTime;
8
  unsigned int  lastGoodWidth;
9
} tPinTimingData;
10
volatile static tPinTimingData pinData[6];
11
volatile static uint8_t PCintLast;
12

13
void setup() {
14
  Serial.begin(9600);
15
  DDRC = 0;
16
  PCICR |= (1 << PCIE1);  
17
  PCMSK1 |= 0x3F;
18
}
19

20
void loop() {
21
  Serial.println();
22
  for (byte i = 0; i < 6; i++) {
23
    Serial.print("C");
24
    Serial.print((int)i + 1);
25
    Serial.print(": ");
26
    Serial.print(pinData[i].lastGoodWidth);
27
    Serial.print(", ");
28
  }
29
  
30
  delay(100);
31
}
32

33
ISR(PCINT1_vect){
34
  uint8_t bit;
35
  uint8_t curr;
36
  uint8_t mask;
37
  uint32_t currentTime;
38
  uint32_t time;
39
  
40
  curr = PINC & 0x3F;
41
  mask = curr ^ PCintLast;
42
  PCintLast = curr;
43
  
44
  currentTime = micros();
45
  
46
  for (uint8_t i=0; i < 6; i++) {
47
    bit = 0x01 << i;
48
    if (bit & mask) {
49
      if (bit & PCintLast) {
50
        time = currentTime - pinData[i].fallTime;
51
        pinData[i].riseTime = currentTime;
52
        if ((time >= 10000) && (time <= 26000))
53
          pinData[i].edge = 1;
54
        else
55
          pinData[i].edge = 0; 
56
      }
57
      else {
58
        time = currentTime - pinData[i].riseTime;
59
        pinData[i].fallTime = currentTime;
60
        if ((time >= 800) && (time <= 2200) && (pinData[i].edge == 1)) {
61
          pinData[i].lastGoodWidth = time;
62
          pinData[i].edge = 0;
63
        }
64
      }
65
    }
66
  }
67
}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.