|
|
|
|
Thread OP
|
Discussion
Arduino Code to read PPM timings
I wrote some code that allows me to capture about 100 PPM frames in a row and outputs the timings for each channel, the sync pulse and the framelength.
Maybe someone wants to try and report some results and if these match to generate a PPM signal. I know most times PPM should be fixed frame length about 22.5 ms.. but in my case it is rather fixed sync pulse.. to track this down I wrote the code.. Should work for at least 4 channels, just change one of the first lines to try with 6 or 8 channels.. Using inverted signal should be possible to.. currently it uses the serial port with 115200 baud, also can be changed to whatever your serial speed is.. Also (/especially) if you have your PPM timings already working, I'd like to know if the timings this code reads match what you have working. I only own a NineEagles transmitter, so please report any working transmitters + results, or any problems. use the reply button or feel free to write an email my result: Code:
FrameNumber: 1 frameLength: 27032 1059 1021 524 1046 20792 FrameNumber: 2 frameLength: 27000 1061 1022 527 1052 20761 FrameNumber: 3 frameLength: 27132 1062 1021 522 1054 20903 FrameNumber: 4 frameLength: 27024 1059 1021 528 1052 20787 FrameNumber: 5 frameLength: 27000 1061 1022 521 1052 20767 FrameNumber: 6 frameLength: 27020 1063 1021 528 1054 20789 FrameNumber: 7 frameLength: 27132 1059 1021 528 1053 20902 FrameNumber: 8 frameLength: 26996 1054 1022 521 1050 20765 FrameNumber: 9 frameLength: 27020 1062 1021 529 1054 20783 FrameNumber: 10 frameLength: 27000 1059 1021 522 1052 20769 FrameNumber: 11 frameLength: 27140 1061 1021 527 1053 20899 FrameNumber: 12 frameLength: 27024 1062 1021 521 1054 20789 FrameNumber: 13 frameLength: 27000 1059 1021 527 1052 20771 FrameNumber: 14 frameLength: 27020 1061 1022 527 1052 20783 FrameNumber: 15 frameLength: 27136 1062 1021 522 1054 20903 FrameNumber: 16 frameLength: 27000 1059 1021 527 1052 20764 FrameNumber: 17 frameLength: 27024 1061 1022 521 1052 20789 FrameNumber: 18 frameLength: 27004 1062 1021 527 1054 20765 FrameNumber: 19 frameLength: 27132 1061 1022 529 1052 20902 FrameNumber: 20 frameLength: 27020 1054 1022 521 1046 20791 FrameNumber: 21 frameLength: 26996 1062 1021 527 1054 20757 FrameNumber: 22 frameLength: 27024 1061 1022 522 1052 20795 FrameNumber: 23 frameLength: 27136 1061 1021 527 1053 20899 FrameNumber: 24 frameLength: 27000 1062 1022 522 1054 20766 FrameNumber: 25 frameLength: 27024 1061 1022 528 1052 20792 FrameNumber: 26 frameLength: 26996 1061 1021 527 1053 20761 FrameNumber: 27 frameLength: 27136 1062 1021 522 1054 20903 FrameNumber: 28 frameLength: 27020 1061 1022 528 1052 20786 FrameNumber: 29 frameLength: 27000 1061 1021 521 1052 20767 FrameNumber: 30 frameLength: 27024 1063 1021 528 1054 20782 FrameNumber: 31 frameLength: 27140 1061 1023 521 1052 20909 FrameNumber: 32 frameLength: 26996 1061 1022 527 1052 20766 FrameNumber: 33 frameLength: 27020 1062 1021 527 1054 20782 FrameNumber: 34 frameLength: 26996 1061 1023 521 1052 20768 FrameNumber: 35 frameLength: 27136 1059 1021 528 1052 20902 FrameNumber: 36 frameLength: 27020 1062 1022 522 1054 20788 FrameNumber: 37 frameLength: 27000 1061 1023 528 1052 20769 FrameNumber: 38 frameLength: 27016 1059 1021 528 1053 20786 FrameNumber: 39 frameLength: 27132 1062 1021 522 1054 20903 FrameNumber: 40 frameLength: 27000 1061 1022 528 1052 20764 FrameNumber: 41 frameLength: 27020 1059 1021 522 1052 20792 FrameNumber: 42 frameLength: 26996 1063 1021 528 1054 20759 FrameNumber: 43 frameLength: 27136 1061 1023 521 1052 20906 FrameNumber: 44 frameLength: 27024 1059 1021 528 1053 20794 FrameNumber: 45 frameLength: 26992 1062 1021 527 1054 20757 FrameNumber: 46 frameLength: 27024 1061 1022 522 1052 20793 FrameNumber: 47 frameLength: 27136 1059 1021 528 1053 20902 FrameNumber: 48 frameLength: 26996 1062 1022 522 1054 20765 FrameNumber: 49 frameLength: 27020 1061 1022 528 1052 20785 FrameNumber: 50 frameLength: 27000 1059 1021 522 1053 20764 FrameNumber: 51 frameLength: 27136 1061 1021 521 1052 20903 FrameNumber: 52 frameLength: 27020 1061 1022 528 1052 20785 FrameNumber: 53 frameLength: 27000 1059 1021 522 1052 20770 FrameNumber: 54 frameLength: 27020 1061 1022 527 1052 20783 FrameNumber: 55 frameLength: 27136 1061 1023 521 1052 20907 FrameNumber: 56 frameLength: 26996 1059 1021 528 1053 20769 FrameNumber: 57 frameLength: 27024 1061 1021 527 1052 20784 FrameNumber: 58 frameLength: 26992 1061 1023 522 1052 20766 FrameNumber: 59 frameLength: 27140 1059 1021 528 1052 20902 FrameNumber: 60 frameLength: 27020 1061 1022 521 1052 20791 FrameNumber: 61 frameLength: 26996 1061 1023 528 1052 20761 FrameNumber: 62 frameLength: 27024 1059 1021 522 1052 20790 FrameNumber: 63 frameLength: 27136 1061 1021 521 1053 20904 FrameNumber: 64 frameLength: 26996 1061 1022 528 1052 20761 FrameNumber: 65 frameLength: 27024 1059 1021 522 1052 20793 FrameNumber: 66 frameLength: 26996 1061 1022 527 1052 20761 FrameNumber: 67 frameLength: 27136 1062 1021 522 1054 20903 FrameNumber: 68 frameLength: 27028 1059 1021 527 1052 20791 FrameNumber: 69 frameLength: 26996 1061 1019 527 1053 20759 FrameNumber: 70 frameLength: 27020 1062 1021 522 1054 20789 FrameNumber: 71 frameLength: 27140 1059 1021 528 1053 20902 FrameNumber: 72 frameLength: 26996 1061 1022 521 1052 20766 FrameNumber: 73 frameLength: 27020 1062 1021 527 1054 20783 FrameNumber: 74 frameLength: 27000 1059 1021 522 1052 20771 FrameNumber: 75 frameLength: 27140 1061 1021 521 1052 20905 FrameNumber: 76 frameLength: 27020 1062 1021 527 1054 20781 FrameNumber: 77 frameLength: 27000 1059 1021 522 1052 20771 FrameNumber: 78 frameLength: 27020 1061 1021 527 1052 20782 FrameNumber: 79 frameLength: 27136 1062 1022 522 1054 20905 FrameNumber: 80 frameLength: 26996 1059 1021 528 1053 20762 FrameNumber: 81 frameLength: 27024 1061 1021 523 1052 20785 FrameNumber: 82 frameLength: 26996 1062 1022 522 1054 20764 FrameNumber: 83 frameLength: 27136 1061 1022 528 1052 20902 FrameNumber: 84 frameLength: 27024 1061 1021 521 1052 20791 FrameNumber: 85 frameLength: 26996 1062 1021 529 1054 20759 FrameNumber: 86 frameLength: 27020 1060 1023 522 1052 20792 FrameNumber: 87 frameLength: 27136 1061 1021 521 1052 20905 FrameNumber: 88 frameLength: 26988 1062 1021 528 1054 20759 FrameNumber: 89 frameLength: 27024 1061 1023 522 1052 20793 FrameNumber: 90 frameLength: 27000 1061 1021 527 1052 20761 FrameNumber: 91 frameLength: 27132 1062 1021 521 1054 20903 FrameNumber: 92 frameLength: 27024 1061 1023 528 1052 20789 FrameNumber: 93 frameLength: 26996 1061 1021 521 1052 20765 FrameNumber: 94 frameLength: 27020 1062 1022 522 1054 20789 FrameNumber: 95 frameLength: 27140 1061 1022 529 1052 20902 FrameNumber: 96 frameLength: 27000 1061 1021 521 1052 20765 FrameNumber: 97 frameLength: 27024 1062 1021 527 1054 20783 FrameNumber: 98 frameLength: 27000 1060 1022 522 1052 20770 FrameNumber: 99 frameLength: 27144 1053 1021 521 1053 20909 FrameNumber: 100 frameLength: 27012 1062 1021 527 1054 20781 Code: Code:
// Arduino Code to get PPM timings - v1.1 //
/////////////////////////////////////////////
// written by Dave B. [2010.09.09] //
/////////////////////////////////////////////
// comments, bugs, ideas to davedave1@gmx.net
// first 6 lines should be adjusted to individual setup
#define channelnumber 4 // Number of channels
#define framecount 100 // How many frames to capture? tested with 100 frames for 4 channels on atmega328
#define minsync 3000 // Minimum syncpulselength values above 3000 should work for normal PPM
int inputpin = 4; // PPM input pin
int inverted = 0; // use "inverted = 1" for inverted signals
long serialspeed = 115200; // tested with 115200 Baud, needs to match driver settings and serial monitor setting
long synclength[framecount]; // syncvalues
int channel[channelnumber*framecount]; // Channel values
long framelength[framecount]; // frame start times
int counter = 0; // counter for measuring timings
int outcounter = 0; // counter for output measured timings
int synced = 0; // used boolean after found sync, start get all frames from pattern
void setup()
{
Serial.begin(serialspeed); // open serial connection
pinMode(inputpin, INPUT); // set input pin for input
synced = 0;
}
void loop()
{
synclength[counter] = 0; //
if (synced == 0){ // if not already in sync
if ( inverted == 0 ){ // if inverted signal selected is false
synclength[counter] = pulseIn(inputpin, HIGH); // wait for next HIGH pulse
}
else{ // else inverted is selected
synclength[counter] = pulseIn(inputpin, LOW); // wait for next LOW pulse
}
}
if ((synclength[counter] > minsync)or(synced == 1)){ // if syncpulse found or already synced
synced = 1; // set synced as "true"
framelength[counter] = micros(); // get start time
synclength[counter] = 0; // reset synclength which was used to find syncpulse ( [0] should work )
if ( inverted == 0 ){ // if inverted signal selected
for (int channelcounter = 0; channelcounter < channelnumber; channelcounter++){ // loop for measuring all channels
channel[(counter * channelnumber) + channelcounter]=pulseIn(inputpin, HIGH);
}
synclength[counter] = pulseIn(inputpin, HIGH); // get syncpulse length
}
else{ // else inverted is selected
for (int channelcounter = 0; channelcounter < channelnumber; channelcounter++){ // loop for measuring all channels
channel[(counter * channelnumber) + channelcounter]=pulseIn(inputpin, LOW);
}
synclength[counter] = pulseIn(inputpin, LOW); // get syncpulse length
}
framelength[counter] = micros() - framelength[counter] ; // keep difference between start- and endtime
if (counter >= (framecount-1)){ // if captured enough frames
synced = 0; // set synced to "false"
outcounter = 0; // start output with second (third) frame, the first (first to) get measured bad
while (outcounter < framecount){ // loop for all captured frames
Serial.print("FrameNumber: "); // output measured timings
Serial.print(outcounter+1);
Serial.print(" ");
Serial.print("frameLength: ");
Serial.print(framelength[outcounter]);
Serial.print(" ");
Serial.print(" ");
for (int channelcounter = 0; channelcounter < channelnumber; channelcounter++){ // output all channels and pulses
Serial.print(channel[(outcounter * channelnumber) + channelcounter]);
Serial.print(" ");
}
Serial.print(synclength[outcounter]); // output syncpulse length
Serial.println(""); // output NewLine()
outcounter++; // increase counter for output frames
}
Serial.println(""); // output NewLine()
counter = 0; // reset counter for measuring the next sequence of frames
}
else{ // else (not enough frames captured)
counter++; // increase counter for measuring the next frame
}
}
}
|
|
|
Last edited by Nase; Sep 09, 2010 at 10:22 PM.
|
|
|
|
|
|
|
Thread OP
|
I added that MIN and MAX values for the channels get captured.. so you just have to move sticks to min/max positions..
Code:
FrameNumber: 1 1045 1007 522 1067 20794 frameLength: 27020 FrameNumber: 2 1046 1003 522 1069 20927 frameLength: 27148 FrameNumber: 3 1046 991 527 1070 20791 frameLength: 27000 FrameNumber: 4 1045 1007 522 1067 20792 frameLength: 27004 FrameNumber: 5 1046 1002 528 1068 20794 frameLength: 27016 FrameNumber: 6 1046 1006 521 1070 20919 frameLength: 27132 FrameNumber: 7 1045 1007 528 1068 20786 frameLength: 27004 FrameNumber: 8 1046 1003 522 1069 20800 frameLength: 27016 FrameNumber: 9 1046 1006 522 1070 20787 frameLength: 27004 FrameNumber: 10 1048 1005 528 1067 20916 frameLength: 27136 FrameNumber: 11 1046 1003 522 1069 20799 frameLength: 27016 FrameNumber: 12 1047 1006 529 1070 20783 frameLength: 27004 FrameNumber: 13 1048 1005 522 1067 20797 frameLength: 27012 FrameNumber: 14 1039 1005 522 1062 20919 frameLength: 27140 FrameNumber: 15 1047 1007 528 1070 20783 frameLength: 27004 FrameNumber: 16 1048 1005 522 1067 20799 frameLength: 27016 FrameNumber: 17 1043 1004 528 1068 20799 frameLength: 27016 FrameNumber: 18 1047 1004 521 1069 20920 frameLength: 27124 FrameNumber: 19 1047 1005 528 1068 20793 frameLength: 27012 FrameNumber: 20 1044 1005 522 1069 20805 frameLength: 27016 FrameNumber: 21 1047 1004 521 1071 20800 frameLength: 27004 FrameNumber: 22 1044 1007 528 1068 20915 frameLength: 27132 FrameNumber: 23 1042 1006 522 1069 20793 frameLength: 27008 FrameNumber: 24 1048 1004 527 1070 20791 frameLength: 27012 FrameNumber: 25 1045 1007 522 1067 20792 frameLength: 27008 FrameNumber: 26 1046 1003 522 1062 20929 frameLength: 27148 FrameNumber: 27 1047 992 521 1069 20797 frameLength: 27000 FrameNumber: 28 1045 1007 522 1067 20792 frameLength: 27004 FrameNumber: 29 1046 1003 528 1069 20795 frameLength: 27016 FrameNumber: 30 1045 1005 521 1068 20921 frameLength: 27140 FrameNumber: 31 1045 1007 528 1067 20784 frameLength: 27000 FrameNumber: 32 1047 1003 522 1068 20801 frameLength: 27016 FrameNumber: 33 1039 1006 521 1062 20801 frameLength: 27016 FrameNumber: 34 1046 1003 527 1070 20914 frameLength: 27124 FrameNumber: 35 1046 1004 522 1069 20801 frameLength: 27016 FrameNumber: 36 1046 1006 527 1069 20784 frameLength: 27004 FrameNumber: 37 1047 1004 522 1069 20796 frameLength: 27012 FrameNumber: 38 1044 1004 528 1068 20919 frameLength: 27140 FrameNumber: 39 1045 1005 521 1068 20803 frameLength: 27016 FrameNumber: 40 1046 992 522 1070 20797 frameLength: 27004 FrameNumber: 41 1043 1004 528 1068 20799 frameLength: 27016 FrameNumber: 42 1046 1004 521 1068 20933 frameLength: 27136 FrameNumber: 43 1046 1003 527 1070 20791 frameLength: 27000 FrameNumber: 44 1042 1006 522 1069 20805 frameLength: 27020 FrameNumber: 45 1046 1004 521 1062 20799 frameLength: 27004 FrameNumber: 46 1047 1005 528 1069 20914 frameLength: 27132 FrameNumber: 47 1043 1005 522 1069 20793 frameLength: 27008 FrameNumber: 48 1047 1004 527 1068 20792 frameLength: 27012 FrameNumber: 49 1047 1006 522 1070 20790 frameLength: 27008 FrameNumber: 50 1047 1005 528 1068 20929 frameLength: 27148 FrameNumber: 51 1046 991 521 1068 20797 frameLength: 27000 FrameNumber: 52 1040 1006 522 1067 20789 frameLength: 27004 FrameNumber: 53 1047 1005 528 1068 20795 frameLength: 27016 FrameNumber: 54 1045 1005 521 1068 20921 frameLength: 27136 FrameNumber: 55 1047 1005 527 1070 20782 frameLength: 27004 FrameNumber: 56 1047 1005 522 1067 20801 frameLength: 27016 FrameNumber: 57 1046 1006 527 1069 20802 frameLength: 27016 FrameNumber: 58 1046 1003 527 1070 20913 frameLength: 27124 FrameNumber: 59 1047 1006 522 1067 20801 frameLength: 27016 FrameNumber: 60 1046 1006 527 1069 20784 frameLength: 27004 FrameNumber: 61 1047 1004 522 1070 20796 frameLength: 27012 FrameNumber: 62 1045 1007 527 1068 20919 frameLength: 27140 FrameNumber: 63 1046 1006 521 1068 20803 frameLength: 27016 FrameNumber: 64 1046 992 522 1064 20797 frameLength: 27000 FrameNumber: 65 1045 1007 528 1068 20786 frameLength: 27008 FrameNumber: 66 1046 1003 522 1069 20934 frameLength: 27148 FrameNumber: 67 1046 1003 527 1070 20792 frameLength: 27000 FrameNumber: 68 1044 1007 522 1068 20791 frameLength: 27004 FrameNumber: 69 1046 1003 528 1068 20797 frameLength: 27020 FrameNumber: 70 1047 1006 528 1070 20914 frameLength: 27132 FrameNumber: 71 1038 1007 522 1068 20791 frameLength: 27004 FrameNumber: 72 1046 1002 528 1068 20794 frameLength: 27016 FrameNumber: 73 1046 1006 522 1069 20790 frameLength: 27004 FrameNumber: 74 1048 1005 528 1068 20915 frameLength: 27140 FrameNumber: 75 1046 1003 522 1069 20798 frameLength: 27012 FrameNumber: 76 1047 1006 528 1070 20790 frameLength: 27004 FrameNumber: 77 1047 1005 528 1068 20793 frameLength: 27016 FrameNumber: 78 1044 1005 521 1068 20925 frameLength: 27136 FrameNumber: 79 1047 1006 527 1070 20781 frameLength: 27004 FrameNumber: 80 1047 1006 522 1067 20799 frameLength: 27012 FrameNumber: 81 1043 1006 528 1069 20799 frameLength: 27016 FrameNumber: 82 1047 1010 527 1070 20913 frameLength: 27124 FrameNumber: 83 1048 1005 522 1061 20799 frameLength: 27012 FrameNumber: 84 1043 1004 528 1068 20787 frameLength: 27008 FrameNumber: 85 1047 1004 521 1070 20797 frameLength: 27012 FrameNumber: 86 1045 1007 528 1068 20916 frameLength: 27136 FrameNumber: 87 1044 1005 521 1069 20807 frameLength: 27020 FrameNumber: 88 1047 992 527 1070 20797 frameLength: 27008 FrameNumber: 89 1044 1007 528 1068 20786 frameLength: 26996 FrameNumber: 90 1047 1003 521 1069 20935 frameLength: 27152 FrameNumber: 91 1047 1004 527 1070 20793 frameLength: 27004 FrameNumber: 92 1045 1007 522 1069 20790 frameLength: 27000 FrameNumber: 93 1047 1002 528 1068 20794 frameLength: 27016 FrameNumber: 94 1045 1006 522 1068 20921 frameLength: 27136 FrameNumber: 95 1045 1007 528 1068 20789 frameLength: 27004 FrameNumber: 96 1047 1003 527 1068 20794 frameLength: 27016 FrameNumber: 97 1046 1006 521 1068 20789 frameLength: 27004 FrameNumber: 98 1048 1004 528 1070 20913 frameLength: 27136 FrameNumber: 99 1047 1003 521 1068 20799 frameLength: 27016 FrameNumber: 100 1046 1006 527 1069 20797 frameLength: 27016 min/max per channel: 518/1531 507/1536 507/1541 508/1534 Code:
// Arduino Code to get PPM timings - v1.2 //
/////////////////////////////////////////////
// written by Dave B. [2010.09.09] //
/////////////////////////////////////////////
// comments, bugs, ideas to davedave1@gmx.net
// first 6 lines should be adjusted to individual setup
#define channelnumber 4 // Number of channels
#define framecount 100 // How many frames to capture? tested with 100 frames for 4 channels on atmega328
#define minsync 3000 // Minimum syncpulselength values above 3000 should work for normal PPM
int inputpin = 4; // PPM input pin
int inverted = 0; // use "inverted = 1" for inverted signals
long serialspeed = 115200; // tested with 115200 Baud, needs to match driver settings and serial monitor setting
long minchannel[channelnumber];
long maxchannel[channelnumber];
long synclength[framecount]; // syncvalues
int channel[channelnumber*framecount]; // Channel values
long framelength[framecount]; // frame start times
int counter = 0; // counter for measuring timings
int outcounter = 0; // counter for output measured timings
int synced = 0; // used boolean after found sync, start get all frames from pattern
void setup()
{
Serial.begin(serialspeed); // open serial connection
pinMode(inputpin, INPUT); // set input pin for input
synced = 0;
for (int channelcounter = 0; channelcounter < channelnumber; channelcounter++){
minchannel[channelcounter] = 50000;
maxchannel[channelcounter] = 0;
}
}
void loop()
{
synclength[counter] = 0; //
if (synced == 0){ // if not already in sync
if ( inverted == 0 ){ // if inverted signal selected is false
synclength[counter] = pulseIn(inputpin, HIGH); // wait for next HIGH pulse
}
else{ // else inverted is selected
synclength[counter] = pulseIn(inputpin, LOW); // wait for next LOW pulse
}
}
if ((synclength[counter] > minsync)or(synced == 1)){ // if syncpulse found or already synced
synced = 1; // set synced as "true"
framelength[counter] = micros(); // get start time
synclength[counter] = 0; // reset synclength which was used to find syncpulse ( [0] should work )
if ( inverted == 0 ){ // if inverted signal selected
for (int channelcounter = 0; channelcounter < channelnumber; channelcounter++){ // loop for measuring all channels
channel[(counter * channelnumber) + channelcounter]=pulseIn(inputpin, HIGH);
}
synclength[counter] = pulseIn(inputpin, HIGH); // get syncpulse length
}
else{ // else inverted is selected
for (int channelcounter = 0; channelcounter < channelnumber; channelcounter++){ // loop for measuring all channels
channel[(counter * channelnumber) + channelcounter]=pulseIn(inputpin, LOW);
}
synclength[counter] = pulseIn(inputpin, LOW); // get syncpulse length
}
framelength[counter] = micros() - framelength[counter] ; // keep difference between start- and endtime
if (counter >= (framecount-1)){ // if captured enough frames
synced = 0; // set synced to "false"
outcounter = 0; // start output with second (third) frame, the first (first to) get measured bad
while (outcounter < framecount){ // loop for all captured frames
Serial.print("FrameNumber: "); // output measured timings
Serial.print(outcounter+1);
Serial.print(" ");
Serial.print(" ");
for (int channelcounter = 0; channelcounter < channelnumber; channelcounter++){ // output all channels and pulses
Serial.print(channel[(outcounter * channelnumber) + channelcounter]);
Serial.print(" ");
if (minchannel[channelcounter] > channel[(outcounter * channelnumber) + channelcounter]){
minchannel[channelcounter] = channel[(outcounter * channelnumber) + channelcounter];
}
if (maxchannel[channelcounter] < channel[(outcounter * channelnumber) + channelcounter]){
maxchannel[channelcounter] = channel[(outcounter * channelnumber) + channelcounter];
}
}
Serial.print(synclength[outcounter]); // output syncpulse length
Serial.print(" ");
Serial.print("frameLength: ");
Serial.print(framelength[outcounter]);
Serial.println(""); // output NewLine()
outcounter++; // increase counter for output frames
}
Serial.print("min/max per channel: ");
for (int channelcounter = 0; channelcounter < channelnumber; channelcounter++){
Serial.print(minchannel[channelcounter]);
Serial.print("/");
Serial.print(maxchannel[channelcounter]);
Serial.print(" ");
}
Serial.println(""); // output NewLine()
Serial.println(""); // output NewLine()
counter = 0; // reset counter for measuring the next sequence of frames
}
else{ // else (not enough frames captured)
counter++; // increase counter for measuring the next frame
}
}
}
|
|
|
Last edited by Nase; Sep 09, 2010 at 10:23 PM.
|
|
|
|
|
|
You should count milis between rising (falling if inverted) edges of the signal coming out of the receiver. Instead you measure the length of the pulse. Timing between pulses should be between 1000 and 2000 ms (and about 1500 ms when the stick is centered). The values that you read for ch 3 are invalid, I believe the other values are wrong too.
Assuming you are using ATMEGA328 you can have pretty accurate results using ICP1 (which is same pin as PB1), but then you will need to use interrupts. |
|
|
|
|
|
||
|
Thread OP
|
Quote:
the fifth value is the length of the sync pulse channel three is throttle stick on my transmitter.. it was at minimum position.. the others are centered.. min/max is about 500 to 1500, I think there is nothing wrong. of course, for every channel and the syncpulse, there is an additional pulse of about 480 us with my transmitter, this should be about 300 us with standard PPM.. I started with a version that was intended to capture everything.. because of the behaviour of pulsein this was not successfull,.. however, I will try to put together a version that uses interrupts.. Maybe I should call the signal that my transmitter uses inverted. from http://www.arduino.cc/en/Reference/PulseIn pulseIn() Description Reads a pulse (either HIGH or LOW) on a pin. For example, if value is HIGH, pulseIn() waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing. Returns the length of the pulse in microseconds. Gives up and returns 0 if no pulse starts within a specified time out. compare: |
|
|
|
Last edited by Nase; Sep 10, 2010 at 11:01 PM.
|
|
|
|
|
|
|
I've edited your scope image and added the things that you really want to measure.
From the Image I see that your radio is four-channel and is using negative pulses (Futaba style). Channels 1,2 and 4 are centered and are indeed about 1.5 ms. Channel 3 (throttle at its low position?) is about 1 ms. The full frame is about 27 ms. |
|
|
|
|
|
|
|
Thread OP
|
thanks, but I still don't get why you would know better than me, what I want to measure..
if I want to generate this signal, I need to know how long the pulses are, how long the times between are, how long the syncpulse is.. how long it takes for ( a channel + it's pulse ) is not of interest in the first place.. I could take this time minus the channel high time, or just measure the low times, too.. Maybe the length of the low pulses is irrelevant, but as I am quite sure that my transmitter uses no standard PPM, I want to know exactly what the code is reading. The framelength is not constant 27ms .. the syncpulse is fixed 20ms.. I think the code I posted reads exactly the timings that I want to know. Just to understand, what should I do with the times that you marked? take them.. minus pulse length and have the same times that my code reads, that I need to generate the correct high and low times for the signal? I posted the code here, hoping someone, who has a PPM signal generator working, would post results of a a known working PPM signal. so I would know how (in)accurate they are.. Please explain why / if you still think I don't know what I want to measure. Just add the fixed length of the pulse to my timings and you have what *you* want to know.. since pulses are commonly not varying I thought I could just leave them out. First code that I tried measured all those times, but arduino measured framelengths of 80ms.. so it only got about every fourth frame.. Thanks! |
|
|
|
|
|
|
|
Thread OP
|
got some code that gives results like this
Code:
492 1040 488 1028 484 532 484 1076 484 21040 492 1044 484 1028 488 528 484 1076 488 20924 488 1048 484 1028 484 528 488 1076 484 20900 488 1044 488 1028 484 528 488 1072 488 20924 488 1044 488 1028 484 528 488 1076 488 21036 488 1048 484 1028 484 528 488 1076 488 20896 488 1044 488 1028 488 524 488 1072 488 20924 488 1044 488 1028 484 528 488 1076 488 20896 492 1044 484 1028 488 528 484 1080 484 21036 488 1044 488 1028 484 528 488 1072 488 20924 492 1044 484 1028 488 528 488 1072 488 20896 492 1044 484 1028 488 528 484 1080 484 20920 492 1044 484 1032 484 528 484 1076 488 21036 496 1040 484 1028 488 528 488 1072 488 20896 492 1044 484 1028 488 528 484 1080 484 20920 492 1044 484 1032 484 528 484 1076 488 20900 492 1040 488 1028 484 528 488 1072 488 21040 488 1048 484 1028 484 528 488 1076 488 20916 492 1044 484 1032 484 528 484 1076 488 20900 492 1040 488 1028 484 528 488 1076 484 20924 492 1044 484 1028 484 532 484 1076 488 21036 488 1044 488 1028 484 528 488 1076 484 20900 492 1040 488 1028 484 528 488 1076 484 20924 492 1044 484 1032 484 528 488 1076 484 20896 488 1044 488 1028 484 532 484 1076 484 21040 492 1040 488 1028 484 528 488 1076 484 20928 488 1044 488 1028 484 528 488 1076 484 20896 492 1044 484 1032 484 528 488 1072 488 20920 492 1044 484 1028 488 528 484 1076 488 21040 then I' post it here.. |
|
|
|
|
|
|
|
Thread OP
|
should work for 4-8 channels and also normal and inverted signals.
use PIN 2, needed for the external Interrupt. capturing should work even if channel number doesn't match, however, just change 2 lines for channelnumber and serial speed.. results look like this Code:
492 1044 484 1020 488 528 484 1076 488 20908 Frame Length: 27012 492 1044 484 1020 488 528 484 1076 488 21044 Frame Length: 27148 492 1044 484 1020 488 528 484 1080 484 20928 Frame Length: 27032 492 1040 488 1020 484 528 488 1076 484 20912 Frame Length: 27012 488 1044 488 1020 484 528 488 1076 488 20928 Frame Length: 27032 488 1048 484 1020 484 528 488 1076 488 21044 Frame Length: 27148 492 1040 488 1020 484 532 484 1076 484 20908 Frame Length: 27008 492 1044 484 1020 488 528 488 1072 488 20932 Frame Length: 27036 488 1048 484 1020 484 532 484 1076 488 20900 Frame Length: 27004 492 1044 484 1024 484 528 488 1072 488 21048 Frame Length: 27152 488 1044 488 1020 484 528 488 1076 488 20928 Frame Length: 27032 492 1044 484 1020 488 528 488 1076 484 20904 Frame Length: 27008 492 1044 484 1024 484 528 488 1072 488 20932 Frame Length: 27036 488 1044 488 1020 484 532 484 1076 488 21044 Frame Length: 27148 488 1048 484 1020 484 532 484 1076 488 20904 Frame Length: 27008 492 1040 488 1020 484 532 484 1076 484 20932 Frame Length: 27032 492 1044 484 1020 488 528 488 1072 488 20908 Frame Length: 27012 492 1044 484 1020 484 532 484 1076 488 21044 Frame Length: 27148 492 1044 484 1024 484 528 484 1076 488 20908 Frame Length: 27012 492 1040 488 1020 484 528 488 1076 484 21048 Frame Length: 27148 492 1044 484 1020 488 528 484 1080 484 20928 Frame Length: 27032 488 1044 488 1020 484 528 488 1076 484 20908 Frame Length: 27008 492 1044 484 1020 488 528 484 1076 488 20932 Frame Length: 27036 488 1048 484 1020 484 528 488 1076 488 21044 Frame Length: 27148 488 1044 488 1020 484 528 488 1076 484 20908 Frame Length: 27008 492 1040 488 1020 484 528 488 1076 484 20936 Frame Length: 27036 488 1048 484 1020 484 528 488 1076 488 20900 Frame Length: 27004 492 1044 484 1024 484 528 484 1076 488 21044 Frame Length: 27148 492 1044 484 1020 488 528 484 1076 488 20932 Frame Length: 27036 492 1044 484 1020 488 528 484 1080 484 20904 Frame Length: 27008 492 1044 484 1024 484 528 488 1072 488 20928 Frame Length: 27032 492 1044 484 1020 488 528 484 1076 488 21048 Frame Length: 27152 488 1048 484 1020 484 528 488 1076 488 20904 Frame Length: 27008 488 1044 488 1020 484 532 484 1076 484 20932 Frame Length: 27032 492 1040 488 1020 484 532 484 1076 484 20912 Frame Length: 27012 488 1044 488 1020 484 532 484 1076 488 21040 Frame Length: 27144 Code:
// Arduino Code to get PPM timings - v1.5 //
////////////////////////////////////////////////
// written by Dave B. [2010.09.09] //
////////////////////////////////////////////////
// comments, bugs, ideas to davedave1@gmx.net //
// * use PIN 2 for PPM signal //
// change the first line if you have more or //
// less channels.. //
// Leave the valueCount as it is, arduino //
// might run out of memory! //
////////////////////////////////////////////////
#define channelCount 4 // set channel count
#define serialSpeed 115200 // set serialSpeed here
// don't change anything below
#define valueCount 200
long counter = 0; // counter
long values[valueCount]; // array for values
int frameFound = 0; // used as boolean
long minSync = 3000; // standard PPM
void pinChanged(){ // Function called by Interrupt
values[counter] = micros(); // store timestamp
counter++; // count value
if (counter >= valueCount-1){ // if got enough values
frameFound = 0; // reset
counter = 0; // reset counter
Serial.println(""); // send NewLine
output(); // start output function
}
}
void output(){ // output function
for (int i=1; i < valueCount; i++){ // loop over all stored values
if (frameFound == 1){ // if next value is full frame
Serial.print(values[i]-values[i-1]); // output value
Serial.print(" ");
if ((values[i] -values[i-1])> minSync){ // if current value is sync
Serial.print("\tFrame Length: "); // output Frame Length
Serial.print(values[i]-values[i-((channelCount+1)*2)]);
Serial.println(""); // output NewLine
if ((i+((channelCount+1)*2)) >= valueCount-1){// if no more full frame possible
break; // stop output
}
}
}
else { // else if still not found sync
if ((values[i] - values[i-1])> minSync){ // if sync found now
frameFound=1; // set frameFound "true"
}
}
}
}
void setup(){
Serial.begin(serialSpeed); // set serial speed
pinMode(2, INPUT); // set PIN 2 as input
attachInterrupt(0, pinChanged, CHANGE); // setup Interrupt
}
void loop(){ // loop() not used
}
|
|
|
Last edited by Nase; Sep 12, 2010 at 01:30 AM.
|
|
|
|
|
|
Sorry, I assumed that the main thing that you wanted was to interpret the PPM signal and use it in some system (eg., to contol a robot). In that case you really don't care about separate timing of the pulse and the gap that follows the pulse.
Now if you are after much more accurate results, you can use the Input Capture register (assuming your arduino uses ATMEGA328P there's only one on PB0, that's PIN8 of the Arduino. The value of the 16 bit hardware timer is copied to ICR1 immadiately when the event that you want to time happens, so the recorded values do not depend on the time it takes to respond to the interrupt. Attaching AVR code (I'm using avr-gcc, not Arduino) that's reading PPM input. I think that can be used with Arduino as well. AFAIK the 1/64 prescaler is the default in Arduino. You can change it to 1/8 and get even more accurate timing, but then you will not be able to use arduino functions that depend on it (like millis()). |
|
|
|
|
|
|
|
Thread OP
|
alright!
hm.. thanks for your code, having exactly the time when the interrupt occurs seems to be better, although I still don't know how (in)accurate my code is.. I'd really like to know this before I go over and over again.. ![]() Anyways, I will try to adapt your code to my needs. True, Arduino code only is the first step, I'm pretty sure it can be improved by direct usage of ATmegas possibilities.. I just don't feel like reading the whole ATmega328 reference at the moment. |
|
|
|
|
|
||
|
|
Quote:
|
|
|
|
||
|
|
||
|
Thread OP
|
Quote:
not sure what exactly you want to do.. just start the program or pass through some signal. receiver should give you a pwm-signal that you could pass to the servo |
|
|
|
||
|
|
|
|
|
Im just trying to connect the servo to the arduino pin (as output) and channel 5 of the receiver to another arduino pin (as input) so when I click the channel button on the transmmiter, the servo will travel to specified positions, with a delay time between the positions and then return to the original position. The purpose of this is to trigger a camera button, with the servo, using prefocus first (much better pictures). Cannot connect to the channel 1-4 because they are in use. I found a program that moves the servo to the desired positions independly. I just need to access the channel from the receiver to give the order to run the program that I already have, when I hit the switch on the transmmiter . I dont know much about programing Arduino. (I am form the BASIC generation)
|
|
|
Last edited by Billimont; Jan 25, 2011 at 08:49 AM.
|
| Similar Threads | |||||
| Category | Thread | Thread Starter | Forum | Replies | Last Post |
| Question | PPM to TX problem with arduino generated PPM | Nase | DIY Electronics | 65 | Jul 22, 2016 06:42 PM |
| Discussion | Arduino code for BMP085 pressure sensor? | 13brv3 | DIY Electronics | 23 | Oct 24, 2011 11:07 AM |
| Discussion | Need help flashing besc with Quax ppm code | rjwims | DIY Electronics | 2 | Aug 30, 2010 09:04 PM |
| Discussion | help me !!!18f4455 ppm c18 code | gta18 | DIY Electronics | 1 | Apr 13, 2008 06:43 PM |
| PIC 'C' code + circuit to decode PPM | JoeB99 | DIY Electronics | 24 | Mar 08, 2005 03:47 AM | |