Forum: Mikrocontroller und Digitale Elektronik Arduino: Servo PWM Signale zu PPM


von Dominik H. (yeahiii)


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
}

von Hubert G. (hubertg)


Lesenswert?

Den Abstand der Pulse erzeugst du am einfachsten mit einem Timer im 
CTC-Mode.
In der ISR den neuen Wert eingeben.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.