forked from schinken/PPMEncoder
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPPMEncoder.cpp
More file actions
72 lines (53 loc) · 1.47 KB
/
Copy pathPPMEncoder.cpp
File metadata and controls
72 lines (53 loc) · 1.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include "PPMEncoder.h"
PPMEncoder ppmEncoder;
void PPMEncoder::begin(uint8_t pin) {
begin(pin, PPM_DEFAULT_CHANNELS);
}
void PPMEncoder::begin(uint8_t pin, uint8_t ch) {
cli();
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
state = true;
elapsedUs = 0;
currentChannel = 0;
numChannels = ch;
outputPin = pin;
for (uint8_t ch = 0; ch < numChannels; ch++) {
setChannelPercent(ch, 0);
}
TCCR1A = 0;
OCR1A = 100;
TCCR1B = (1 << WGM12) | (1 << CS11);
TIMSK1 = (1 << OCIE1A); // enable timer compare interrupt
sei();
}
void PPMEncoder::setChannel(uint8_t channel, uint16_t value) {
channels[channel] = constrain(value, PPMEncoder::MIN, PPMEncoder::MAX);
}
void PPMEncoder::setChannelPercent(uint8_t channel, uint8_t percent) {
percent = constrain(percent, 0, 100);
setChannel(channel, map(percent, 0, 100, PPMEncoder::MIN, PPMEncoder::MAX));
}
void PPMEncoder::interrupt() {
TCNT1 = 0;
if (state) {
digitalWrite(outputPin, HIGH);
OCR1A = PPM_PULSE_LENGTH_uS * 2;
} else {
digitalWrite(outputPin, LOW);
if (currentChannel >= numChannels) {
currentChannel = 0;
elapsedUs = elapsedUs + PPM_PULSE_LENGTH_uS;
OCR1A = (PPM_FRAME_LENGTH_uS - elapsedUs) * 2;
elapsedUs = 0;
} else {
OCR1A = (channels[currentChannel] - PPM_PULSE_LENGTH_uS) * 2;
elapsedUs = elapsedUs + channels[currentChannel];
currentChannel++;
}
}
state = !state;
}
ISR(TIMER1_COMPA_vect) {
ppmEncoder.interrupt();
}