You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
60 lines
1.5 KiB
60 lines
1.5 KiB
/**
|
|
* RC2Serial: Simple PPM -> serial converter on Arduino.
|
|
*
|
|
* Wiring:
|
|
* Pin 3: PPM input
|
|
* Output send via USB
|
|
*
|
|
* Serial output on USB: 115200, 8 data bits, 1 stop bit, no parity
|
|
* Frame contains 2 byte header ("RC") and 16 channels values multiplied by 10 (e.g. 15000 for 1500 us), in uint16_t (big endian):
|
|
* [uint8_t header0] [uint8_t header0] [uint16_t channel0] [uint16_t channel1] ... [uint16_t channel15]
|
|
*/
|
|
|
|
#define PPM_Pin 3 // this must be 2 or 3
|
|
#define MULTIPLIER (F_CPU / 1000000 / 8) // TIMER1 prescaler: 8
|
|
#define PPM_CHANNELS_MAX 16
|
|
|
|
#pragma push(pack, 1)
|
|
struct {
|
|
uint8_t header0;
|
|
uint8_t header1;
|
|
uint16_t values[PPM_CHANNELS_MAX];
|
|
} data;
|
|
#pragma pop(pack)
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
|
|
pinMode(PPM_Pin, INPUT);
|
|
attachInterrupt(PPM_Pin - 2, read_ppm, FALLING);
|
|
|
|
TCCR1A = 0; // reset TIMER1
|
|
TCCR1B = 0;
|
|
TCCR1B |= (1 << CS11); // set TIMER1 prescaler: 8
|
|
}
|
|
|
|
void loop() {
|
|
delay(1000);
|
|
}
|
|
|
|
void read_ppm() {
|
|
static byte channel = 0;
|
|
|
|
unsigned long counter = TCNT1;
|
|
TCNT1 = 0;
|
|
|
|
if (counter > 2500 * MULTIPLIER) {
|
|
data.header0 = 'R';
|
|
data.header1 = 'C';
|
|
for (int i = channel; i < PPM_CHANNELS_MAX; i++) {
|
|
data.values[i] = 0;
|
|
}
|
|
channel = 0;
|
|
Serial.write((byte*)&data, sizeof(data));
|
|
} else {
|
|
if (channel < PPM_CHANNELS_MAX) {
|
|
uint16_t v = counter * 10 / MULTIPLIER;
|
|
data.values[channel++] = (v >> 8 | v << 8); // Swap bytes to big endian
|
|
}
|
|
}
|
|
}
|
|
|