USB2PPM Interface for accessing transmitter trainer ports using arduino

This project is done by Jaeyoung Lim

Overview

usb2ppm_logo

In this project I have built a usb2ppm interface, which is a programmable board that can generate ppm signals. Commands can be programmed to come from potentiometers or command from a PC connected via a USB cable.
There are some literature that explains how to control the control inputs by generating ppm signals using an Arduino or other MCUs. This is done using timer interrupts in the MCU. However, to be able to do time consuming tasks as serial communications, it can be challenging to use timer interrupts as the serial communication can be interrupted while not finished. This article is about my work of how I have solved the problem and build a working model.
제목 없음1

PPM Signals

PPM(Pulse Position Modulation) is a signal that consists of a series of pules, which each channel values corresponds to the poistion of the pulse.

ppp-schema2
As from the picture above, a complete PPM frame has a length of 22.5ms. For Accessing Turnigy 9X, 22mms is the right value. After a overlong start pulse, 8 channel information is transmitted. The length of channel impulse ranges from 0.7ms to 1.7ms, which corresponds to the stick position linearly.

Reference : http://www.mftech.de/ppm_en.htm

Wiring

schematic
To interface with the turnigy 9X trainer port, a 3.5mm stereo jack. The tip of the jack is used for signal and the ring is used as ground. The signal is wired to pin 10. This is because pin 10 is directly hard wired to the Atmega 328 timer. Connecting the signal wires other than pin 10 will not work.

2015-05-29 20.38.26
Above is a basic prototype used for testing. For demo, the video below shows Turnigy 9X displaying the channel inputs received from the usb2ppm.

Software (Firmware)

Timer interrupts were used to generate ppm signals. For timer interrupts, we use the 16 bit timer in Atmega 328. In the code, timer1 is used to match the timing of the start and end pulse.

ISR(TIMER1_COMPA_vect)
{
if (timer_ptr == number_of_outputs) {
timer_ptr = 0; //reset the pointer to 0
OCR1A = timer_framelength - (timer_accumulator * timer_correction_factor); //calculate the padding
timer_accumulator = 0; //set the accumulator to 0
}
else {
OCR1A = (pulses[timer_ptr] + timer_pause) * timer_correction_factor; //set the pulse length
timer_accumulator += pulses[timer_ptr] + timer_pause; //add the pulse length to the accumulator
timer_ptr++; //increment the pointer
}
}

Other approaches use simple delay functions to generate serials of pulses. This can work as a simple and dirty way but is problematic as the end pulse will not be properly synced, which will result in unstable signal generation.
All codes are shared by the OpenUSB2PPM repository. (https://github.com/gokoreas/OpenUSB2PPM)

Software (PC)

Basic Serial communication with c++ with the arduino is used from the reference: http://playground.arduino.cc/Interfacing/CPPWindows
The usb2ppm code encodes each channel values of integer into a string using serial_encode ppm(). For reference I have written the code below.
usb2ppm.h

#include
#include
#include
using namespace std;

extern char* rtrn;

char* encode_PPM(int cmd_ch1, int cmd_ch2, int cmd_ch3, int cmd_ch4);

usb2ppm.cpp

#include "usb2PPM.h"

char* encode_PPM(int cmd_ch1, int cmd_ch2, int cmd_ch3, int cmd_ch4){

int cmd_ch[4] = { 0, 0, 0, 0}; //Default values for each channels
char output_string[26]="";
char* output_string_p = output_string;
rtrn = (char*)malloc(26);

char const_ch[4] = { 'x','y', 'z', 'k' };

cmd_ch[0] = cmd_ch1;
cmd_ch[1] = cmd_ch2;
cmd_ch[2] = cmd_ch3;
cmd_ch[3] = cmd_ch4;

int j = 0;

//for loop for each channel value processing
for (int i = 0; i 1023){
cmd_ch[i] = 1023;
}
else if (cmd_ch[i] < 1){
cmd_ch[i] = 0;
}
char cmd_ch_s[5]="";
char* cmd_ch_sp = cmd_ch_s;

_itoa_s(cmd_ch[i], cmd_ch_s, 10);

//convert to single string for communication with Arduino

*(output_string_p + j) = const_ch[i];
j++;
while (*(output_string_p + j) = *(cmd_ch_sp++))
{
j++;
}

}
//printf("string :%sn", output_string);
strcpy_s(rtrn,25, output_string);
return rtrn;
}

Open USB2PPM Project

All codes are shared by the OpenUSB2PPM repository. (https://github.com/gokoreas/OpenUSB2PPM).

Advertisements

One thought on “USB2PPM Interface for accessing transmitter trainer ports using arduino

  1. Pingback: USB2PPM Interface | 404warehouse

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s