RSSI injection on RC channel

This forum is dedicated to software development related to MultiWii.
It is not the right place to submit a setup problem.
Software download
Post Reply
rubadub
Posts: 154
Joined: Mon Apr 28, 2014 2:36 am

RSSI injection on RC channel

Post by rubadub »

MWC doesn't appear to currently support handling RSSI as a PWM value from an RC input on a PPM channel...
Is anyone working on this or has anyone tried doing it? It doesn't seem like a hard change to make, since the code just needs to be adjusted to take one of the channel values, scale it in the 0-1023 range (to keep it compatible with analog RSSI readings?), and save it to analog.rssi, correct?

thinking something like the following
config.h

Code: Select all

/********************************************************************/
/****                             RSSI                           ****/
/********************************************************************/
#define RX_RSSI
//#define RX_RSSI_PIN A3
#define RX_RSSI_CHAN 8 //RSSI injection on selected channel (for PPM, SBUS, etc.)



multiwii.cpp

Code: Select all

  #if defined(RX_RSSI)
  case 2:
  {
    static uint8_t ind = 0;
    static uint16_t rvec[RSSI_SMOOTH], rsum;

#ifdef(RX_RSSI_CHAN)
    uint16_t r = (uint16_t) rcData[RX_RSSI_CHAN]; //range [1000:2000]
    r=(r-1000)*1023/1000; //scale to 0-1023 range
#else
    uint16_t r = analogRead(RX_RSSI_PIN);
#endif   

#if RSSI_SMOOTH == 1
      analog.rssi = r;
    #else
      rsum += r;
      rsum -= rvec[ind];
      rvec[ind++] = r;
      ind %= RSSI_SMOOTH;
      r = rsum / RSSI_SMOOTH;
      analog.rssi = r;
    #endif
    break;
  }
  #endif


any thoughts?

User avatar
haydent
Posts: 583
Joined: Sun Jun 17, 2012 1:35 am
Location: NSW, AU

Re: RSSI injection on RC channel

Post by haydent »

sure, kv/mw osd do this currently (have a look at their code), so its totally possible. though the pwm signal will be different between rc channel and rssi channel and likely different between receivers.

Another option is a low pass filter (cap and resistor)

rubadub
Posts: 154
Joined: Mon Apr 28, 2014 2:36 am

Re: RSSI injection on RC channel

Post by rubadub »

haydent wrote:sure, kv/mw osd do this currently (have a look at their code), so its totally possible. though the pwm signal will be different between rc channel and rssi channel and likely different between receivers.

Another option is a low pass filter (cap and resistor)


I'm using OrangeRX UHF receiver with OpenLRSng firmware which allows injecting RSSI into PPM stream. An LC filter won't work with a CPPM stream where the RSSI is embedded in a single channel.

I believe that the KV OSD code only supports either reading RSSI from MWC or from analog source, either PWM or standard analog voltage. Again, it won't help if the RSSI is embedded in the PPM stream.

User avatar
haydent
Posts: 583
Joined: Sun Jun 17, 2012 1:35 am
Location: NSW, AU

Re: RSSI injection on RC channel

Post by haydent »

sorry i missunderstood you, so the rssi is mixed in with an actual channel, like roll, or on its on channel like >4

rubadub
Posts: 154
Joined: Mon Apr 28, 2014 2:36 am

Re: RSSI injection on RC channel

Post by rubadub »

haydent wrote:sorry i missunderstood you, so the rssi is mixed in with an actual channel, like roll, or on its on channel like >4

that's correct, you can assign the RSSI to a specific channel (any channel >4 and available through rcData[] array). I'm not sure, but I was under the impression that EZUHF also offered this option? Anyway, the OpenLRSng code supports it, which actually makes reading the RSSI values pretty simple and fool-proof.

User avatar
haydent
Posts: 583
Joined: Sun Jun 17, 2012 1:35 am
Location: NSW, AU

Re: RSSI injection on RC channel

Post by haydent »

well than that would be easy, yeah just grab the aux channel value convert it to rssi reading and fead it into the rssi variable. sounds great. then try get a devs attention to commit it to the project.

User avatar
haydent
Posts: 583
Joined: Sun Jun 17, 2012 1:35 am
Location: NSW, AU

Re: RSSI injection on RC channel

Post by haydent »

dude, as it happens for unrelated reasons i just ordered a orangerx pair ! and looking at the rssi options the injection one sounds great, so ill be into that...

User avatar
shikra
Posts: 783
Joined: Wed Mar 30, 2011 7:58 pm

Re: RSSI injection on RC channel

Post by shikra »

I like this idea... sounds very easy to implement in MultIWii. I hope someone picks up !

Just as fyi some guys use RSSI from Openlrsng direct to MWOSD today. They have to set the PWM frequency to 50hz.
It may work with default Openlrsng PWM frequency if use #FASTPWMRSSI in config.h

ReadError
Posts: 70
Joined: Sun Sep 09, 2012 11:08 pm

Re: RSSI injection on RC channel

Post by ReadError »

For what its worth, Baseflight has this feature..
https://github.com/multiwii/baseflight/ ... #L493-L499

User avatar
haydent
Posts: 583
Joined: Sun Jun 17, 2012 1:35 am
Location: NSW, AU

Re: RSSI injection on RC channel

Post by haydent »

Shik, yes, i had seen that option and thought that it would no doubt work, but the prospect of 1 less wire is always a good one :)

i also want to make mw be able to interact with frsky sport sensors direct, rather than rely on rx to interface with them.

that code readerror, will be helpful

rubadub
Posts: 154
Joined: Mon Apr 28, 2014 2:36 am

Re: RSSI injection on RC channel

Post by rubadub »

ReadError wrote:For what its worth, Baseflight has this feature..
https://github.com/multiwii/baseflight/ ... #L493-L499


cool, lol, almost the exact same thing that I came up with... 8-)

User avatar
haydent
Posts: 583
Joined: Sun Jun 17, 2012 1:35 am
Location: NSW, AU

Re: RSSI injection on RC channel

Post by haydent »

rubadub wrote:
ReadError wrote:For what its worth, Baseflight has this feature..
https://github.com/multiwii/baseflight/ ... #L493-L499


cool, lol, almost the exact same thing that I came up with... 8-)


**edit, still trying to get this to work...

i tried a mix of both, but it complains about RX_RSSI_PIN being not defined though it could not be used... so i just uncommented it in config though it is not used.

edit: i had to change ifdef to if defined to get it ok

Code: Select all

#if defined(RX_RSSI)
  case 2:
    {
      static uint8_t ind = 0;
      static uint16_t rvec[RSSI_SMOOTH], rsum;
#if defined(RX_RSSI_CHAN)
    uint16_t r = (uint16_t) rcData[RX_RSSI_CHAN]; //range [1000:2000]
    r = (uint16_t)((constrain(r - 1000, 0, 1000) / 1000) * 1023); //scale to 0-1023 range
#else
    uint16_t r = analogRead(RX_RSSI_PIN);
#endif   
#if RSSI_SMOOTH == 1
      analog.rssi = r;
#else
      rsum += r;
      rsum -= rvec[ind];
      rvec[ind++] = r;
      ind %= RSSI_SMOOTH;
      r = rsum / RSSI_SMOOTH;
      analog.rssi = r;
#endif

rubadub
Posts: 154
Joined: Mon Apr 28, 2014 2:36 am

Re: RSSI injection on RC channel

Post by rubadub »

I ended up doing the following:

Code: Select all

#if defined(RX_RSSI_CHAN) && RX_RSSI_CHAN>0
    uint16_t r = (uint16_t) rcData[RX_RSSI_CHAN]; //range [1000:2000]
    r=(r-1000)*1023/1000; //scale to 0-1023 range
#else
    uint16_t r = analogRead(RX_RSSI_PIN);
#endif 

same basic concept, just added a little sanity check to make sure that RX_RSSI_CHAN is valid. you could probably clean it up further with more checks to make sure the compiler doesn't bark if RX_RSSI_PIN isn't defined. But, I'm lazy, and this works for me, so I'm good to go with the above solution...

User avatar
haydent
Posts: 583
Joined: Sun Jun 17, 2012 1:35 am
Location: NSW, AU

Re: RSSI injection on RC channel

Post by haydent »

i just tried your code and it does not calculate right for what ever reason. with a channel value of 1815 i get a rssi reading of 47 when it should be 833...

User avatar
haydent
Posts: 583
Joined: Sun Jun 17, 2012 1:35 am
Location: NSW, AU

Re: RSSI injection on RC channel

Post by haydent »

i just did it like this:

added note that RX_RSSI_CHAN starts at 0

Code: Select all

#if defined(RX_RSSI_CHAN)
    uint16_t r = map((uint16_t)rcData[RX_RSSI_CHAN], 1000, 2000, 0, 1023);
#else
    uint16_t r = analogRead(RX_RSSI_PIN);
#endif   


Code: Select all

    #define RX_RSSI_CHAN 6 //RSSI injection on selected channel (for PPM, SBUS, etc.) (Starts at 0)

rubadub
Posts: 154
Joined: Mon Apr 28, 2014 2:36 am

Re: RSSI injection on RC channel

Post by rubadub »

haydent wrote:i just did it like this:

added note that RX_RSSI_CHAN starts at 0

Code: Select all

#if defined(RX_RSSI_CHAN)
    uint16_t r = map((uint16_t)rcData[RX_RSSI_CHAN], 1000, 2000, 0, 1023);
#else
    uint16_t r = analogRead(RX_RSSI_PIN);
#endif   


Code: Select all

    #define RX_RSSI_CHAN 6 //RSSI injection on selected channel (for PPM, SBUS, etc.) (Starts at 0)

hey, cool! that works, and much cleaner too.
don't really like the idea of depending on the Arduino lib's for the map function, but oh well, as long as it works...
It also takes care of an overflow issue with the original code that I posted... The "(r-100)*1023/1000" was too much for the uint16 to handle, and it was overflowing and rolling back over, thus giving inaccurate values.

Anyway, I can confirm that this is working with the OpenLRSng RSSI injection.
we should find a way to promote this to the dev's. Do you have authority to do this?

User avatar
haydent
Posts: 583
Joined: Sun Jun 17, 2012 1:35 am
Location: NSW, AU

Re: RSSI injection on RC channel

Post by haydent »

not myself but there are members i will ask, also fyi i checked and map is used elsewhere

PatrikE
Posts: 1976
Joined: Tue Apr 12, 2011 6:35 pm
Location: Sweden
Contact:

Re: RSSI injection on RC channel

Post by PatrikE »

haydent wrote:i just did it like this:

added note that RX_RSSI_CHAN starts at 0

Code: Select all

#if defined(RX_RSSI_CHAN)
    uint16_t r = map((uint16_t)rcData[RX_RSSI_CHAN], 1000, 2000, 0, 1023);
#else
    uint16_t r = analogRead(RX_RSSI_PIN);
#endif   

Code: Select all

    #define RX_RSSI_CHAN 6 //RSSI injection on selected channel (for PPM, SBUS, etc.) (Starts at 0)


I would recommend to add constrain of the input otherwise map() function can overflow the output.

Code: Select all

#if defined(RX_RSSI_CHAN)
    uint16_t rssi_Input = constrain(rcData[RX_RSSI_CHAN],1000,2000);
    uint16_t r = map((uint16_t)rssi_Input , 1000, 2000, 0, 1023);
#else
    uint16_t r = analogRead(RX_RSSI_PIN);
#endif   

User avatar
haydent
Posts: 583
Joined: Sun Jun 17, 2012 1:35 am
Location: NSW, AU

Re: RSSI injection on RC channel

Post by haydent »

great, that is excellent ! thanks. can you commit it ?

PatrikE
Posts: 1976
Joined: Tue Apr 12, 2011 6:35 pm
Location: Sweden
Contact:

Re: RSSI injection on RC channel

Post by PatrikE »

Works fine in my benchTests.
Committed to r1698.

User avatar
haydent
Posts: 583
Joined: Sun Jun 17, 2012 1:35 am
Location: NSW, AU

Re: RSSI injection on RC channel

Post by haydent »

thanks. did not get time for any mw tnight...

rubadub
Posts: 154
Joined: Mon Apr 28, 2014 2:36 am

Re: RSSI injection on RC channel

Post by rubadub »

FYI, one thing I did personally was avoid using the rcData value because it is an averaged value.

Code: Select all

#if defined(RX_RSSI_CHAN)
    extern volatile uint16_t rcValue[];
    uint16_t r = map((uint16_t)constrain(rcValue[RX_RSSI_CHAN],1000,2000), 1000, 2000, 0, 1023);
#else
    uint16_t r = analogRead(RX_RSSI_PIN);
#endif

that way, it uses the raw, unfiltered value from the PPM stream, instead of using the filtered/averaged value from rcData... I figured that, for RSSI, you'd want the instantaneous, unfiltered value.

PatrikE
Posts: 1976
Joined: Tue Apr 12, 2011 6:35 pm
Location: Sweden
Contact:

Re: RSSI injection on RC channel

Post by PatrikE »

rubadub wrote:FYI, one thing I did personally was avoid using the rcData value because it is an averaged value.
Instead of using the filtered/averaged value from rcData... I figured that, for RSSI, you'd want the instantaneous, unfiltered value.


You're right.
But since Analog Rssi is already heavy filtered.
#define RSSI_SMOOTH 16
And rcData[] adds extra Avg of 4.
It shouldn't make a big difference.

I can change it to next commit.

/Patrik

User avatar
shikra
Posts: 783
Joined: Wed Mar 30, 2011 7:58 pm

Re: RSSI injection on RC channel

Post by shikra »

Thanks for comitting - this is nice feature

Rubadub
For me jumpy display of RSSI on an OSD is annoying - I get asked more to average readings than display actual...
I have also noticed that for the digital RSSI, you can get 100% RSSI then 0% because the one rx packet didn't get processed by the rx. So some RX seem to provide a filtered average and others do not. I think maybe as there is no standard its difficult to cover all scenarios.

rubadub
Posts: 154
Joined: Mon Apr 28, 2014 2:36 am

Re: RSSI injection on RC channel

Post by rubadub »

shikra wrote:Thanks for comitting - this is nice feature

Rubadub
For me jumpy display of RSSI on an OSD is annoying - I get asked more to average readings than display actual...
I have also noticed that for the digital RSSI, you can get 100% RSSI then 0% because the one rx packet didn't get processed by the rx. So some RX seem to provide a filtered average and others do not. I think maybe as there is no standard its difficult to cover all scenarios.


I understand your point, but I've had bad experiences in the past with averaged RSSI. The values don't react fast enough when filtered/averaged, so you might get big, quick drops in RSSI, yet the RSSI value will lag behind and not show a true minimum. If you're trying to diagnose a control link problem, it helps to see exactly when&where your link dropped out.

Anyway, like I said, this was just a personal fix that I made, in case anyone else was interested.

User avatar
haydent
Posts: 583
Joined: Sun Jun 17, 2012 1:35 am
Location: NSW, AU

Re: RSSI injection on RC channel

Post by haydent »

well seems there is already the option to smooth which i believe is accessible from config too, then maybe better to use unfiltered for this method, then you have option to have filtered or not.

Post Reply