I am making RC simulator toggle that receives PPM from RC transmitter and outputs joystick to RC simulator.
The first and very fast version was this, and it works good, but has 150 ms latency from moving the stick before the controls move on computer screen, so not great.
Here is some latency testing. The LED lights based on PPM value as seen on code.
https://vimeo.com/475858573
https://vimeo.com/475870685
#include <PulsePosition.h>
float PPM[14];
float PPMvalue;
int16_t JSTvalue[14];
PulsePositionInput PPMin(RISING);
// When receiving, any time between rising edges longer than this will be
// treated as the end-of-frame marker.
#define RX_MINIMUM_SPACE 500.0
void setup() {
PPMin.begin(9);
pinMode(13, OUTPUT);
}
void loop() {
if(PPMin.available()==8){
for ( uint8_t n = 1; n < 9; n++) {
PPMvalue = PPMin.read ;
if (PPMvalue > 1) PPM[n] = PPMvalue ;
JSTvalue[n] = round(PPM[n]- 988.0) ;
if ( JSTvalue[n] < 0) JSTvalue[n] = 0 ;
if ( JSTvalue[n] > 1023) JSTvalue[n] = 1023 ;
}
if(JSTvalue[1] < 900) digitalWrite(13,true); else digitalWrite(13,false);
Joystick.X(JSTvalue[1]); // "value" is from 0 to 1023
Joystick.Y(JSTvalue[2]); // 512 is resting position
Joystick.Z(JSTvalue[3]);
Joystick.Zrotate(JSTvalue[4]);
Joystick.sliderLeft(JSTvalue[5]);
Joystick.sliderRight(JSTvalue[6]);
if(JSTvalue[7] > 700) Joystick.button(1, 1); else Joystick.button(1, 0);
if(JSTvalue[7] < 300) Joystick.button(2, 1); else Joystick.button(2, 0);
if(JSTvalue[8] > 700) Joystick.button(3, 1); else Joystick.button(3, 0);
if(JSTvalue[8] < 300) Joystick.button(4, 1); else Joystick.button(4, 0);
}
}
Since that I made it so that Joystick is send only if values have changed and they are all send at the end using
if (JSTupdates > 0) Joystick.send_now();
And the latency seems to be better now (did not measure yet, could be jus me imagine.)
The unclear part for me regarding joystick is what does the Joystick message contain. i.e. if only Joystick.X(JSTvalue[1]); was called before Joystick.send_now(); will that message contain the structures only for Joystick.X or anyway all the values?
Is there some steps I could still take to reduce the latency regarding joystick messages?
Now I am looking into optimising PPM
myInput.available(); it says "Returns the number of channels recieved, or zero when no new data is available. "
But it seems it returns -1 or the total number of channels. In this case 8. So it seems it waits for the complete PPM message to be ready before updating. How ever PPM message is long. 22.5 ms according to this http://www.mftech.de/ppm_en.htm
I would like to access each channel as soon as that channel has been decoded from PPM. Is that possible?
The first and very fast version was this, and it works good, but has 150 ms latency from moving the stick before the controls move on computer screen, so not great.
Here is some latency testing. The LED lights based on PPM value as seen on code.
https://vimeo.com/475858573
https://vimeo.com/475870685
#include <PulsePosition.h>
float PPM[14];
float PPMvalue;
int16_t JSTvalue[14];
PulsePositionInput PPMin(RISING);
// When receiving, any time between rising edges longer than this will be
// treated as the end-of-frame marker.
#define RX_MINIMUM_SPACE 500.0
void setup() {
PPMin.begin(9);
pinMode(13, OUTPUT);
}
void loop() {
if(PPMin.available()==8){
for ( uint8_t n = 1; n < 9; n++) {
PPMvalue = PPMin.read ;
if (PPMvalue > 1) PPM[n] = PPMvalue ;
JSTvalue[n] = round(PPM[n]- 988.0) ;
if ( JSTvalue[n] < 0) JSTvalue[n] = 0 ;
if ( JSTvalue[n] > 1023) JSTvalue[n] = 1023 ;
}
if(JSTvalue[1] < 900) digitalWrite(13,true); else digitalWrite(13,false);
Joystick.X(JSTvalue[1]); // "value" is from 0 to 1023
Joystick.Y(JSTvalue[2]); // 512 is resting position
Joystick.Z(JSTvalue[3]);
Joystick.Zrotate(JSTvalue[4]);
Joystick.sliderLeft(JSTvalue[5]);
Joystick.sliderRight(JSTvalue[6]);
if(JSTvalue[7] > 700) Joystick.button(1, 1); else Joystick.button(1, 0);
if(JSTvalue[7] < 300) Joystick.button(2, 1); else Joystick.button(2, 0);
if(JSTvalue[8] > 700) Joystick.button(3, 1); else Joystick.button(3, 0);
if(JSTvalue[8] < 300) Joystick.button(4, 1); else Joystick.button(4, 0);
}
}
Since that I made it so that Joystick is send only if values have changed and they are all send at the end using
if (JSTupdates > 0) Joystick.send_now();
And the latency seems to be better now (did not measure yet, could be jus me imagine.)
The unclear part for me regarding joystick is what does the Joystick message contain. i.e. if only Joystick.X(JSTvalue[1]); was called before Joystick.send_now(); will that message contain the structures only for Joystick.X or anyway all the values?
Is there some steps I could still take to reduce the latency regarding joystick messages?
Now I am looking into optimising PPM
myInput.available(); it says "Returns the number of channels recieved, or zero when no new data is available. "
But it seems it returns -1 or the total number of channels. In this case 8. So it seems it waits for the complete PPM message to be ready before updating. How ever PPM message is long. 22.5 ms according to this http://www.mftech.de/ppm_en.htm
I would like to access each channel as soon as that channel has been decoded from PPM. Is that possible?
Last edited: