Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
- Committer:
- j3sq
- Date:
- 2011-07-02
- Revision:
- 0:3dbb22992c94
File content as of revision 0:3dbb22992c94:
#include "mbed.h"
#include "usbhid.h"
/* RC_Simulator.....By Jafar Qutteineh*/
/* This program takes the PPM Singal(Pulse Position Modulation) from your RC transmitter
and emulate it as a USB HID Joystick.
Currently, program configured to accept Throttle, Rudder, Elevator, Ailerons and
2 buttons. It can be adjusted easily to read other channels as well.
The current state of code is just a proof of concept. It's rough and not clean,
once you understand how it work, customize to your like*/
/*Credit goes to Phil Wright for USB HID code and to Shinichiro Oba Joystiq work*/
/*Setup: Just connect the GND and PPM singal of your transmitter to the GND and P5 respectivly.*/
/*How it works:
-P5 is configured as InturreptIn pin. whenever the PPM signal goes down Inturrept SignalFall() is fired.
-SignalFall keep track of timing:
a) If Pulse width is <300 uS it's most probably a glitch.
b) If pulse width is >300 uS but less than < 2000 uS this is a correct channel. Read it and wait for next channel
c) If Pulse width is >8000 uS this is a new frame, start again.
d) Timing will be different from transmitter to another, you may want to play a little bit here
-Once a complete frame is read the values are feedback to our USB HID Joysick class.
*/
InterruptIn PPMsignal(p5); // connect PPM signal to this, you can change to anyother pin
Serial PC(USBTX,USBRX); // I used this for debuging
USBJoystick joystick; /* This is basicly Shinichiro joystiq, I've only adjusted the Report descriptor to my needs.
for more help on this check:
-http://frank.circleofcurrent.com/cache/hid_tutorial_1.htm
-http://helmpcb.com/electronics/usb-joystick */
int TimeElapsed =0; //Keeps track of time between inturrepts
Timer timer;
unsigned char CurChannel=0; //This will point to the current channel in PPM frame. My PPM signal looks like 10 channels and 1 start frame
// yours could be different
unsigned char Channels[11]={0,0,0,0,0,0,0,0,0,0,0}; //This where channels value is stored until frame is complete.
bool CanUpdate=false; // Once PPM frame is complete this will be true
//Raise_Error is just a function that helped me in development process. You can ignore it all togather.
void Raise_Error (unsigned char Err_Code, int info) {
switch (Err_Code) {
case 0:
PC.printf ("%i\n",info);
break;
case 1:
PC.printf ("Broke@ %i\n",info);
break;
case 2:
PC.printf ("Set ok\n");
break;
case 3:
PC.printf ("%i\n",info);
break;
case 255:
PC.printf("Initalized sucessfully \n");
break;
default:
PC.printf("I shouldn't be here \n");
}
}
//Here were all the work takeplace
void SignalFall() {
TimeElapsed = timer.read_us();
if (TimeElapsed <300) {
//Raise_Error(0,TimeElapsed);
return; //ignore, it's a glitch. Dont move to the next channel
}
__disable_irq();
timer.reset();
//Raise_Error(0,TimeElapsed);
if ((TimeElapsed > 8000 ) && (CurChannel != 0)) { //somehow before reaching the end of PPM frame you read "New" frame signal???
//Ok, it happens. Just ignore this frame and start a new one
// Raise_Error (1,CurChannel); //incomplete channels set
CurChannel=0;
}
if ((TimeElapsed < 8000 ) && (CurChannel == 0)) {
// Raise_Error (1,CurChannel); //incomplete channels set
__enable_irq(); // This is good. You've received "New" frame signal as expected
return;
}
// Process current channel. This is a correct channel in a correct frame so far
//if (CurChannel==4) Raise_Error(3,TimeElapsed);
Channels[CurChannel]= (TimeElapsed-900)*255/1100; // Normalize reading (Min: 900us Max: 1900 us). This is my readings, yours can be different
CurChannel+=1;
if (CurChannel==11 ) { // great!, you've a complete correct frame. Update Joystick and star a new frame
CurChannel=0;
// Raise_Error(3,0);
CanUpdate= true;
}
__enable_irq();
}
void Initalize () {
__disable_irq();
PC.baud(115200); // set baude rate
PPMsignal.mode (PullUp);
PPMsignal.fall(&SignalFall); //Attach SignalFall routine to handle PPMsignal fall
timer.start();
Raise_Error(255,0); // return successful
timer.reset();
__enable_irq();
}
int main() {
Initalize();
wait(5);
while (1) {
if (CanUpdate) { // update joystick here
CanUpdate=false;
joystick.joystick(Channels[1],Channels[4],Channels[3],Channels[2],Channels[7],Channels[8]); //update joystick state (Throttle, Rudder, X,Y, Button 1, Button 2)
// Raise_Error(3,Channels[1]);
//Channel 5 : PIT
//Channel 6: PLT
}
}
}