RC_Simulator.....By Jafar Qutteineh with mods to connect my Futaba 9C to \'RC Helicopter\' by http://www.alphamacsoftware.com/
main.cpp
00001 #include "mbed.h" 00002 #include "usbhid.h" 00003 00004 00005 /* RC_Simulator.....By Jafar Qutteineh*/ 00006 /* This program takes the PPM Singal(Pulse Position Modulation) from your RC transmitter 00007 and emulate it as a USB HID Joystick. 00008 Currently, program configured to accept Throttle, Rudder, Elevator, Ailerons and 00009 2 buttons. It can be adjusted easily to read other channels as well. 00010 The current state of code is just a proof of concept. It's rough and not clean, 00011 once you understand how it work, customize to your like*/ 00012 00013 /*Credit goes to Phil Wright for USB HID code and to Shinichiro Oba Joystiq work*/ 00014 00015 /*Setup: Just connect the GND and PPM singal of your transmitter to the GND and P5 respectivly.*/ 00016 00017 /*How it works: 00018 -P5 is configured as InturreptIn pin. whenever the PPM signal goes down Inturrept SignalFall() is fired. 00019 -SignalFall keep track of timing: 00020 a) If Pulse width is <300 uS it's most probably a glitch. 00021 b) If pulse width is >300 uS but less than < 2000 uS this is a correct channel. Read it and wait for next channel 00022 c) If Pulse width is >8000 uS this is a new frame, start again. 00023 d) Timing will be different from transmitter to another, you may want to play a little bit here 00024 -Once a complete frame is read the values are feedback to our USB HID Joysick class. 00025 */ 00026 00027 00028 00029 InterruptIn PPMsignal(p5); // connect PPM signal to this, you can change to anyother pin 00030 Serial PC(USBTX,USBRX); // I used this for debuging 00031 USBJoystick joystick; /* This is basicly Shinichiro joystiq, I've only adjusted the Report descriptor to my needs. 00032 for more help on this check: 00033 -http://frank.circleofcurrent.com/cache/hid_tutorial_1.htm 00034 -http://helmpcb.com/electronics/usb-joystick */ 00035 00036 00037 int TimeElapsed =0; //Keeps track of time between inturrepts 00038 Timer timer; 00039 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 00040 // yours could be different 00041 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. 00042 unsigned short Times[11]={0,0,0,0,0,0,0,0,0,0,0}; //This where channels value is stored until frame is complete. 00043 bool CanUpdate=false; // Once PPM frame is complete this will be true 00044 00045 //Raise_Error is just a function that helped me in development process. You can ignore it all togather. 00046 void Raise_Error (unsigned char Err_Code, int info) { 00047 switch (Err_Code) { 00048 case 0: 00049 PC.printf ("%i\n",info); 00050 break; 00051 case 1: 00052 PC.printf ("Broke@ %i\n",info); 00053 break; 00054 case 2: 00055 PC.printf ("Set ok\n"); 00056 break; 00057 case 3: 00058 PC.printf ("%i\n",info); 00059 break; 00060 case 255: 00061 PC.printf("Initalized sucessfully \n"); 00062 break; 00063 default: 00064 PC.printf("I shouldn't be here \n"); 00065 } 00066 00067 } 00068 00069 //Here were all the work takeplace 00070 void SignalFall() { 00071 TimeElapsed = timer.read_us(); 00072 if (TimeElapsed <300) { 00073 //Raise_Error(0,TimeElapsed); 00074 return; //ignore, it's a glitch. Dont move to the next channel 00075 } 00076 __disable_irq(); 00077 timer.reset(); 00078 //Raise_Error(0,TimeElapsed); 00079 if ((TimeElapsed > 8000 ) && (CurChannel != 0)) { //somehow before reaching the end of PPM frame you read "New" frame signal??? 00080 //Ok, it happens. Just ignore this frame and start a new one 00081 //Raise_Error (1,CurChannel); //incomplete channels set 00082 CurChannel=0; 00083 } 00084 if ((TimeElapsed < 8000 ) && (CurChannel == 0)) { 00085 //Raise_Error (1,CurChannel); //incomplete channels set 00086 __enable_irq(); // This is good. You've received "New" frame signal as expected 00087 return; 00088 } 00089 00090 // Process current channel. This is a correct channel in a correct frame so far 00091 //if (CurChannel==4) Raise_Error(3,TimeElapsed); 00092 Channels[CurChannel]= (TimeElapsed-1000)*255/1000; // Normalize reading (Min: 900us Max: 1900 us). This is my readings, yours can be different 00093 Times[CurChannel] = TimeElapsed; 00094 CurChannel++; 00095 00096 if (CurChannel==9 ) { // great!, you've a complete correct frame. Update Joystick and star a new frame 00097 CurChannel=0; 00098 //Raise_Error(3,0); 00099 CanUpdate= true; 00100 } 00101 __enable_irq(); 00102 } 00103 00104 void Initalize () { 00105 __disable_irq(); 00106 PC.baud(115200); // set baude rate 00107 PPMsignal.mode (PullUp); 00108 PPMsignal.fall(&SignalFall); //Attach SignalFall routine to handle PPMsignal fall 00109 timer.start(); 00110 Raise_Error(255,0); // return successful 00111 timer.reset(); 00112 __enable_irq(); 00113 00114 } 00115 00116 int main() { 00117 //unsigned short *pOut = Times; 00118 unsigned char *pOut = Channels; 00119 00120 Initalize(); 00121 //wait(5); 00122 00123 00124 while (1) { 00125 if (CanUpdate) { // update joystick here 00126 CanUpdate=false; 00127 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) 00128 PC.printf("% 4d,% 4d,% 4d,% 4d\r",pOut[1],pOut[2],pOut[3],pOut[4]); // Raise_Error(3,Channels[1]); 00129 //Channel 5 : PIT 00130 //Channel 6: PLT 00131 } 00132 } 00133 00134 } 00135
Generated on Tue Jul 12 2022 20:25:32 by
1.7.2