Just a simple PPM out library

Files at this revision

API Documentation at this revision

Comitter:
goodgod
Date:
Sun Jan 08 20:17:29 2017 +0000
Commit message:
Initial ppm commit;

Changed in this revision

PPMOut.cpp Show annotated file Show diff for this revision Revisions of this file
PPMOut.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r ab42e541f04d PPMOut.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PPMOut.cpp	Sun Jan 08 20:17:29 2017 +0000
@@ -0,0 +1,64 @@
+#include "mbed.h"
+#include "PPMOut.h"
+
+PpmOut::PpmOut(PinName pin, uint8_t channel_number): ppm(pin) {
+    if(channel_number > MAX_CHANNELS){
+        this->channel_number = MAX_CHANNELS;
+    }
+    this->channel_number = channel_number;
+    resetChannels();
+    pulse_out = 1;
+    ppm = pulse_out;
+    current_dot = 0;
+    timeout.attach_us(this, &PpmOut::attimeout, FRAME_LEN);
+}
+
+void PpmOut::setChannel(int channel_no, uint16_t value) {
+    //__disable_irq();     // Disable Interrupts
+    if(channel_no > channel_number-1){
+        return;
+    }
+    if(value > MAX_CHANNEL_VALUE){
+        value = MAX_CHANNEL_VALUE;
+    }
+    dots[channel_no*2] = CHANNEL_SYNC;
+    dots[channel_no*2+1] = CHANNEL_PAD_SYNC + value;
+
+    setFrameSync();
+    //__enable_irq();     // Enable Interrupts
+}
+
+void PpmOut::setFrameSync(){
+    uint16_t sum_channels = 0;
+    for(uint8_t channel = 0; channel < channel_number; channel++) {
+        sum_channels += dots[channel*2+1];
+    }
+    sum_channels += channel_number*CHANNEL_SYNC;
+    dots[channel_number*2] = CHANNEL_SYNC;
+    dots[channel_number*2+1] = FRAME_LEN - CHANNEL_SYNC - sum_channels;
+}
+
+void PpmOut::attimeout() {
+    pulse_out = !pulse_out;
+    ppm = pulse_out;
+    
+    timeout.attach_us(this, &PpmOut::attimeout, dots[current_dot]);
+    current_dot++;
+
+    if(current_dot == channel_number*2+2) { // 2 for FRAME_SYNC
+        current_dot = 0;
+    }
+}
+
+void PpmOut::resetChannels() {
+    int8_t channel;
+    uint16_t sum_channels = 0;
+
+    current_dot = 0;
+    memset(dots, 0x00, DOTS);
+    for(channel = 0; channel < channel_number; channel++) {
+        dots[channel*2] = CHANNEL_SYNC;
+        dots[channel*2+1] = CHANNEL_PAD_SYNC;
+    }
+    setFrameSync();
+}
\ No newline at end of file
diff -r 000000000000 -r ab42e541f04d PPMOut.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PPMOut.h	Sun Jan 08 20:17:29 2017 +0000
@@ -0,0 +1,36 @@
+#ifndef CH_PPM_OUT
+#define CH_PPM_OUT
+
+class PpmOut{
+    public:
+        static const uint8_t MAX_CHANNELS = 8;
+        static const uint16_t CHANNEL_SYNC = 300; // us
+        static const uint16_t CHANNEL_PAD_SYNC = 1000 - CHANNEL_SYNC; // us
+        static const uint16_t FRAME_SYNC = 5000; // us
+        static const uint16_t FRAME_LEN = 22300; // us
+        static const uint16_t MAX_CHANNEL_VALUE = 1000; // us
+        static const uint16_t MIN_CHANNEL_VALUE = 0; 
+        static const uint16_t DOTS = MAX_CHANNELS*2+2; // two dots per channel + FRAME_SYNC
+
+        /* Will start the PPM output */
+        PpmOut(PinName pin, uint8_t channel_number);
+        /* Values go from MIN_CHANNEL_VALUE to MAX_CHANNEL_VALUE */
+        void setChannel(int channel_no, uint16_t value);
+
+    private:
+        /* These are the time dots where the signal changes the value 
+           from 0 to 1 and in reverse */
+        uint16_t dots[DOTS];
+        Timeout timeout;
+        DigitalOut ppm;
+        uint8_t current_dot;
+        uint8_t channel_number;
+        uint16_t frame_length;
+        uint16_t pulse_out;
+
+        void attimeout();
+        inline void resetChannels();
+        inline void setFrameSync();
+};
+
+#endif // CH_PPM_OUT
\ No newline at end of file