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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren