minisatip icon indicating copy to clipboard operation
minisatip copied to clipboard

[Q] Signal SNR in dB ==> Improve percentage conversion

Open lars18th opened this issue 3 years ago • 87 comments

Hi @catalinii ,

In my E2 STB I discovered that the SNR value that gets the minisatip is not consistent with the one reported by the tuner.

For example I use --multiplier 0:1.0-2.0, so the SNR value is duplicated by minisatip. And the behaviour is correct, as the UI of minisatip prints the double of the SNR value readed. However, I feel the value used is incorrect. Ler to explain why I think this. I've executed the dvb-fe-tool -a 0 -g -m command and I discovered why the SNR value is so low. Please see the output:

Lock   (0x1f) Signal= 89,00% C/N= 12,16dB
          Layer A: C/N= 82,00%

When the tool prints this, the UI of the minisatip shows 24% of SNR and 89% of STR. But why? Because SNR is ~12*2. So if you have noted what the driver reports, the value used for SNR it's in dB, and not in percentage.

Then, I suggest a improve the SNR calculation in case the driver reports it in dB.

Regards.

lars18th avatar Dec 28 '21 15:12 lars18th

Hey,

The satip standard requires the values to be relative (in percentages) rather than DB* values.

You can see here how they are converted: https://github.com/catalinii/minisatip/blob/master/src/dvb.c#L1392

If you have a better suggestion than what the current code has, let me know

catalinii avatar Dec 28 '21 18:12 catalinii

Hi @catalinii ,

If you have a better suggestion than what the current code has, let me know.

So, yes I've one! 😉

I do some research and here are my results:

  • When tuning one transponder (in the E2 STB) while executing minisatip with debug enabled for the dvb module and with the dvb-fe-tool running as well, I see these values:
[29/12 08:52:20.984 signal]: get_signal_new adapter 0: status 31, strength 0 % -> 59636, snr 12050 dB -> 7896, BER: 0, err 0

Lock   (0x1f) Signal= 91,00% C/N= 12,05dB
          Layer A: C/N= 82,00%
  • You can see here that minisatip gets the correct values of Strength and SNR, but the problem is with the conversion of the dB scale of the SNR value to a percentage value. Note this: for the Strength minisatip gets 59636, that's the 91%. But for the SNR it gets 12050 dB (in fact 12.050 dB, so I recommend to include a separator in the log) and it calculates then the 7896 value in the scale [0..65535]. So for this reason minisatip prints a SNR of 12% (without corrections using --multiplier). However, the correct value of SNR (in percentage) is 82% (the value printed by the dvb-fe-tool).

So, the real question is how the SNR percentage value requires to be calculated from the dB scale?

Ok, here the answer from my research:

  • You can read some tables from the dvb-fe-tool in this file: https://github.com/gjasny/v4l-utils/blob/6c905930e8e9bdf485f857ea8aadcaffbfd0943d/lib/libdvbv5/dvb-fe.c#L1184-L1270
  • These tables represents the ranges for each DTV modulation between the correct SNR values in the dB scale.
  • My assumption after reading some part of the code is that the first value in the table represents the 100% value, and the second is the maximum value.
  • So in my example the tuned transponder is DVB-S2 with a 2/3 FEC in 8PSK mode. And then the magic calculation is: in the table the 100% value (the first) for this modulation is 14.5, so 12050 * 100 / 14.5 = 83103 that represents the 83%.

As a result, the calculus of the SNR in percentage (in the 65535 scale) from the dB scale could be done using this formula:

SNR = ((((driver_snr * 100) / modulation_scale_of_the_mux) * 65535) / 100000)

or with simplification: SNR = get_snr * 65.535f / mod_scale(mux) ; // mod_scale(DVBS2/8PSK/2_3) == 14.5f

I hope you want to update your code with this new scale conversion. Regards.

lars18th avatar Dec 29 '21 09:12 lars18th

Hi @catalinii ,

Or with more simple words: please change this line https://github.com/catalinii/minisatip/blob/23507ddc69ad86cabeb5996d41bfe1a4691eada3/src/dvb.c#L1413-L1414

with something like this:

float mod_scale = adapter_mod_scale(ad); // new function to be implemented
snrd = init_snr * 65.535f / mod_scale ;  // dB value ==> %  (based on Modulation Table) 

And the Modulation Table could be something like:

struct mod_table dvb_mod_table[] = {
	{ DVB_C__QAM_256__FEC_NONE,  34.0 },
	{ DVB_C__QAM_64___FEC_NONE,  30.0 },

	{ DVB_S__QPSK__FEC_1_2,       7.0 },
	{ DVB_S__QPSK__FEC_2_3,       9.0 },
	{ DVB_S__QPSK__FEC_3_4,      10.0 },
	{ DVB_S__QPSK__FEC_5_6,      11.0 },
	{ DVB_S__QPSK__FEC_7_8,      12.0 },

	{ DVB_S2_QPSK__FEC_1_2,       9.0 },
	{ DVB_S2_QPSK__FEC_2_3,      11.0 },
	{ DVB_S2_QPSK__FEC_3_4,      12.0 },
	{ DVB_S2_QPSK__FEC_5_6,      12.0 },
	{ DVB_S2_QPSK__FEC_8_9,      13.0 },
	{ DVB_S2_QPSK__FEC_9_10,     13.5 },

	{ DVB_S2_PSK_8_FEC_2_3,      14.5 },
	{ DVB_S2_PSK_8_FEC_3_4,      16.0 },
	{ DVB_S2_PSK_8_FEC_5_6,      17.5 },
	{ DVB_S2_PSK_8_FEC_8_9,      19.0 },

	{ DVB_T__QPSK__FEC_1_2,       4.1 },
	{ DVB_T__QPSK__FEC_2_3,       6.1 },
	{ DVB_T__QPSK__FEC_3_4,       7.2 },
	{ DVB_T__QPSK__FEC_5_6,       8.5 },
	{ DVB_T__QPSK__FEC_7_8,       9.2 },

	{ DVB_T__QAM16_FEC_1_2,       9.8 },
	{ DVB_T__QAM16_FEC_2_3,      12.1 },
	{ DVB_T__QAM16_FEC_3_4,      13.4 },
	{ DVB_T__QAM16_FEC_5_6,      14.8 },
	{ DVB_T__QAM16_FEC_7_8,      15.7 },

	{ DVB_T__QAM64_FEC_1_2,      14.0 },
	{ DVB_T__QAM64_FEC_2_3,      19.9 },
	{ DVB_T__QAM64_FEC_3_4,      24.9 },
	{ DVB_T__QAM64_FEC_5_6,      21.3 },
	{ DVB_T__QAM64_FEC_7_8,      22.0 },
}

Regards.

lars18th avatar Dec 29 '21 09:12 lars18th

Happy to accept a PR :)

catalinii avatar Dec 29 '21 19:12 catalinii

Hi @catalinii ,

Happy to accept a PR :)

Done #912 . However, please check it first. I don't have a local tuner in the dev machine, so I tested (indirectly) using the satipc module. My concern is with the AUTO values. I'm not sure if the ad->tp structure has the fully tuned data (the real tuning parameters) before calling to get_db_snr_map() at the end of the dvb_tune() function. If not, then you'll need to fix this getting the tuner data in the first call to the get_signal_new(). I'm sure you can do this by yourself. In the code I've encapsulated all inside the DVB module, but storing the scale value in the adapter as it's more consistent (and easy to port it to other type of tuners if they require this conversion).

In any case, perhaps you will need to search for some incomplete values. I've used all the values described inside the dvb-fe-tool, but perhaps some are missing (specifically for DVB-T2).

Regards.

lars18th avatar Dec 30 '21 11:12 lars18th

Happy to see this, I would love a better precentage. Currently I am using multipliers, but some sattelites and transponders show SNR like 9% or 20% and still work just fine. E2 box would show 50-60% SNR for those transponders.

Better conversion would also make it easier adjusting the sattelite signal. which I usually do with my phone and minisatip web interface. I use 1 second refresh rate.

But still there is a little problem - when the sattelite signal is temporarily lost (blocked lnb or misaligned dish) for more than 1-2 seconds, the SNR and STR both goes down to 0, but doesn't recover. The stream works just fine, but the SNR/STR values are stuck at 0. Should I open a new issue ticket? If this problem can be fixed and SNR/STR values showed more precise, I was thinking about implementing some beeping feature (for SNR) within the web interface.

kellerman avatar Jan 07 '22 22:01 kellerman

Hi @kellerman ,

I'm glad if you want to contribute with an enhanced interface for SNR adjusting. I suggest, if you want, to adapt the HTML page to print something similar to Enigma2 boxes when calling to /web/signal. Then with a smartphone it will be easy to align the antenna using only the stock web browser.

And regarding the 0 % SNR value, I observed something similar with an updated minisatip from the last commit using the "satipc" module. So I feel the problem is not related to the mapping conversion. In fact, the calculated signal values are in pair with the values reported by the "dvb-fe-tool". So I can assume that the code is nice, but some code in the report is erroneous. I'll investigate it.

Regards.

lars18th avatar Jan 10 '22 17:01 lars18th

Hi @catalinii ,

But still there is a little problem - when the sattelite signal is temporarily lost (blocked lnb or misaligned dish) for more than 1-2 seconds, the SNR and STR both goes down to 0, but doesn't recover. The stream works just fine, but the SNR/STR values are stuck at 0. Should I open a new issue ticket?

Inb order to fix this I need to ask you about this:

  • Why this code in the HTML page ? https://github.com/catalinii/minisatip/blob/408764dbd38c56b464e57adcb4939f30e800284a/html/status.html#L239 I don't see any reason to reduce the snr in 10 units less.
  • And what is the range of the adapter.snr ? [0..15] or [0..255] ?

Regards.

lars18th avatar Jan 10 '22 17:01 lars18th

Hi @kellerman ,

I don't see any cause for your problem of 0 % SNR value. And I can't reproduce it. Then I can't help you. Sorry.

lars18th avatar Jan 10 '22 19:01 lars18th

Hello @lars18th The web interface code is fully open and editable for the end user, so implementing some audible feedback with a graphical meter in a dedicated page, similar to your mentioned /web/signal would be no problem at all, a simple task. As long as SNR/STR values are correct. A nice addition would be to grab and show signal signal level in dB, dont know whether it is possible with minisatip.

I forgot to mention that the problem of 0% SNR/STR happens to me using a DVB-S/2 interface, using DVB-T interface the signal levels do recover after lost signal. So I just checked with dvb-fe-tool and the signal levels doesn't recover there as well, so not a problem with minisatip, but, probably, with reciever drivers or firmware. I probably have to try different firmware, don't know of any other fixes. I'm running latest arm-compiled minisatip on zgemma h9s with pure2 firmware.

kellerman avatar Jan 10 '22 19:01 kellerman

Hi @kellerman ,

First of all: The new signal level calculation works right with drivers that provide a dB scale. You can check the code and the values with the dvb-fe-tool. From my point of view they're right calculated. However, it could be that some specific modulation isn't targeted at time. In this case the LOG prints a warning. If you (or any other user) see this message, then please report it to update the code.

Second: I suggest you to provide the implementation that you want to enhance the web UI. The only question to discuss it's if we need to include a thrid value in the IU. At time the SIGNAL and SNR in a percentage scale are shown. Perhaps we can include the dB value too, as the dvb-fe-tool does. What you think about this @catalinii ?

Third: Regarding your specific trouble with the 0 signal, if the dvb-fe-tool reports the same values, then the problem is inside the driver. We can't do anything to fix this bug.

Regards.

lars18th avatar Jan 11 '22 09:01 lars18th

@lars18th dvb-fe-tool provides a dB value for me as well, so it should probably work. Including dB value, of course, is optional, I just came out with a suggestion. It could be switchable dB/% in the meter. About the graphical signal meter, I will definately try to create one using some javascript/jquery, just have to fix the issue with my box first.

kellerman avatar Jan 11 '22 13:01 kellerman

Hi @kellerman ,

It could be switchable dB/% in the meter.

I prefer to print both values at the same time. With this approach (that does the dvb-fe-tool) you can see the real dB and it's more easy to fix erroneous mappings. Perhaps you can try to print something like this:

               [█████(16dB)█    ] 70%

In reference to the dB value, try to print a fixed value (like '99') hardcoded in the HTML page inside a local variable. Then we can try to get the value from the tuner.

Regards.

lars18th avatar Jan 11 '22 18:01 lars18th

@lars18th Yes, this looks like a good approach. Where would you like to put the signal meter? I was thinking about a analog+digital+audible meter which could be accessible from other page than status.html for a specific adapter. For example http://minisatip:8080/signal/0 for adapter 0. status.html probably includes all the info there needs to be already. Got it about the variable!

kellerman avatar Jan 11 '22 19:01 kellerman

Hi @kellerman ,

If you want to start to implement the UI part, then I suggest this:

  • Use the var "snr_db" in the code.
  • First try to implement in the "status.html" page the idea of printing the value of the "snr_db" var if it is not 0 (without overwriting the percentage value).
  • For the specific page printing only the signal value, I recomment to mimic the E2-Openwif interface. Then it will more easy to use with other external tools (and with the plain web browser).

Regarding the E2 signal interface, here a simple description:

  • /mobile/satfinder: The web page to show to the user the values of the current in use tuner. Regular HTML page.
  • /web/signal: XML page with the values of the current in use tuner.
  • /api/signal: JSON page with the values of the current in use tuner.

However, if you want to make it simple, then you can only implement the /mobile/satfinder page. For the minisatip I recommend then to list all tuners; including if they're off-line (to distinguish from 0 signal). Then you don't need to implement different pages for different adapters. And you can reuse some code from your E2 STB (try to see the source of the page from your browser). Regarding the minisatip, note that the page /state.json has all the data. Then we'll include the new ad_db parameter like the current ad_snr and ad_ber for your use.

In any case perhaps @catalinii will have a suggestion about a different approach.

Regards.

lars18th avatar Jan 12 '22 08:01 lars18th

Hi @lars18th

About implementing /mobile/satfinder - in E2 this is a normal HTML page with some CSS styling and Javscript. Easy to get json data and refresh it in necessary places. In E2 this gets json data from /api/signal. Here I think about some better graphics and audible response. Don't know about switching tuners tho. Dropdown selection maybe? Or a variable passed to the /mobile/satfinder url?

About mimicking E2 - other tools and apps you mention will probably read the signal data from /web/signal or /api/signal, not from /mobile/satfinder which is probably intended to only be viewed as a HTML page in a web browser. But I can't implement both functions, because then I would have to dig deeper in minisatip code and figure out how state.json is produced. I think both /web/signal and /api/signal should then be generated similar to state.json. Also I don't know how multiple tuners are handled here with E2.

/api/signal: ` {   | "agc": "",   | "tunernumber": "",   | "snr": "",   | "ber": "",   | "snr_db": "",   | "tunertype": ""   | }

`

/web/signal is a very similar output Maybe with multiple tuners this simply adds more entries into the xml/json files. I don't know.

About your idea [█████(16dB)█ ] 70% I dropped the pBar plugin and came up with a simple pure HTML/CSS solution. Just have to add some colorization, red for low, green for good signal. https://imgur.com/a/iBJLlt8

kellerman avatar Jan 12 '22 15:01 kellerman

Hi @kellerman ,

I feel I've miss commented my suggestion: In order to maintain it simple I suggest to now only implement the "/mobile/satfinder" page. Only on the future we can try to support "/web/signal" and/or "/api/signal" if it has sense.

The idea to use the URL "/mobile/satfinder" is because it's the same as with E2/Openwif. Then for the user will be more easy to remember. You only need to change the port (from :80 to :8080) and you will see from the minisatip.

Futhermore, as it's a regular HTML page, you can put inside it all tuners at the same time. And if you want to add audible beeps, then you can add some buttons to select it. And in reference about how to obtain the data from the process, you can use identical script code that the current one inside the "status.html" page:

var snr = parseInt(state['ad_db'][i]);

The new value "ad_db" will be implemented after. This value will be a table/list with the index of the adapter. You only need to iterate over all of them. And if the adapter is disabled/offline then don't print it. For the development I suggest to use a hardcoded INT value (i.e. "99").

Note: The range of the "ad_db" parameter will be [0..999], and represents the dB * 10 scale. Then a value of 105 will be "10.5 dB". You agree with that?

Regards.

lars18th avatar Jan 12 '22 17:01 lars18th

About your idea [█████(16dB)█ ] 70% I dropped the pBar plugin and came up with a simple pure HTML/CSS solution. Just have to add some colorization, red for low, green for good signal. https://imgur.com/a/iBJLlt8

👍 👍 👍

Remember in any case, when you create the page "/mobile/satfinder" to include a link to it inside the "status.html" page. In this case the user will not requires to know the URL.

I hope you can provide a PR soon. Good job! 😉

lars18th avatar Jan 12 '22 17:01 lars18th

No problems about the ad_db scaling. You can easily calculate human readable values using javascript. I have now also added red, yellow, and green coloring to the new signal bars depending of the signal value. Works fine with Chrome/Firefox. The jquery.pBar.min.js could be removed from webroot and some additional CSS styling will have to be added, and some slight javascript additions made to status.html. I think that the /mobile/satfinder page shouldn't include any fancy dials, just the standard bars for SNR, STR, BER, CC for all available tuners.

kellerman avatar Jan 12 '22 20:01 kellerman

Hi @kellerman ,

Great! I suggest then to improve the development these aspects:

  • First, please focus on the enhancement of the current "status.html" page. Assuming that the "ad_db" variable from the "/state.json" exists, then you can finish your work. After, if you provide a new PR, I'll provide the internal implementation to get the value in the dB*10 scale using a INT value. You agree with that?
  • Second, you can start to implement the new "/mobile/satfinder" page. Don't worry about the pathname, I know how to implement it. At time you can name it "satfinder.html" and put it inside the "/html" directory (you can browse it then using the path "http://minisatip:8080/satfinder.html"). Perhaps the best and simple solution is to print all the values of all available tuners as you've mentioned. However, remember to print the status of the tuner (could be: disabled, off-line and on-line).

Regards.

lars18th avatar Jan 13 '22 07:01 lars18th

@lars18th I already made a simple satfinder.html page which displays info about one tuner and has some beeping. Now have to figure out how to display all of them or maybe just the active ones. And add some responsive style to it. Okay, I agree, so I should display ad_db/10. And show one digit after comma. Like 12,5dB, for example. And OK, I will focus on to finishing status.html now. status.html is pretty done, just need to clean up some code and test if everything shows up okay with different browsers.

kellerman avatar Jan 13 '22 11:01 kellerman

PR is up. Only the progress bar update. I triple checked the code and everything seems to be good so far.

kellerman avatar Jan 13 '22 17:01 kellerman

PR is up. Only the progress bar update. I triple checked the code and everything seems to be good so far.

OK. Thank you @kellerman . I'll check it and I'll implement the "ad_db" capture.

Regards.

lars18th avatar Jan 13 '22 18:01 lars18th

No problems @lars18th Feel free to say if anything should be changed. I think, I forgot dividing the snr_db value by 10.

I made up a testing statfinder.html page. I would find it easier to list all available tuners (+status, type and signal) at side, for example, and then switch between them, so the whole table changes. Listing all available tuners at once would make the page long and scrollable, which wouldn't be as nice for mobile users to scroll trough. This way it also would be very easy for me to implement. Listing all tuners at once would take quite a time to code. What do you think? https://i.imgur.com/QYWl1L0.png This also beeps and json-reloads every second, using SNR as base value for beeping. For higher value the frequency of tone increases noticeably. I already feel like testing this when adjusting one lnb on my dish tomorrow.

kellerman avatar Jan 13 '22 18:01 kellerman

Hi @kellerman ,

Don't worry about the snr_db implementation. I'll finish the implementation (in fact, I'll need to "copy&paste" your PR inside it).

Regarding the "satfinder.html" page, your example seems good. 👍 However, some ideas to improve it:

  • Instead of reuse the current minisatip "status.html" page, I suggest to make a clean and mobile oriented interface. More or less like is doing the E2/Openwif. So please, remove all unused data and if you're confortable mimic the E2 interface.
  • Even it's not a problem to list all tuners (in fact all data for all tuners is comming from the "state.json" file), I agree with the idea to list only one. This enables to use sounds (beeps) that can help to pointing the antenna.
  • To change from one tuner to another, I suggest a simple solution: at the top insert one button for each tuner. When you select the button the data table changes to this tuner. You can use the browser size to organize the buttons in a grid if multiple tuners are listed.
  • And in the tuner data, remember to include the state: disabled, off-line and active. Futhermore, please remove the BER value, as at time, we don't have implemented to catch it (it could be included in the future).

Regards.

lars18th avatar Jan 14 '22 08:01 lars18th

Hi @lars18th Okay, I see that the current status.html is more like a desktop-like interface, which is OK. satfinder.html should be then made both mobile and desktop friendly, for the purpose of aligning the antenna with any device. I started making the html page based on E2 satfinder page. The interface will be similar, but I will keep the minisatip status.html "theme", but in a responsive version, so the page doesn't stand out. Well anyways I will come up with something and then post here for discussion.

Agreed with the tuner buttons at the top, seems good to me. Will then remove BER and include the tuner state.

kellerman avatar Jan 14 '22 09:01 kellerman

Hi @lars18th I made an update. This needs bug testing and improving, but seems to be working. I kept it as simple as I could and kept the minisatip look. For signal adjusting, nothing more is needed, in my opinion. I had an idea about a toggle-able SNR graph with history, but not needed, probably. The page is so simple that it should look perfectly fine in a mobile browser and not exceed the display of a modern smartphone. https://i.imgur.com/8TiZm1x.png I uploaded the html file on my Nextcloud, if you want to check it out. https://ki.id.lv/s/aXXJoBo34iYBmEs

kellerman avatar Jan 14 '22 22:01 kellerman

Trying to make the GUI more mobile oriented in general. https://i.imgur.com/kv6gbYy.png

kellerman avatar Jan 17 '22 19:01 kellerman

Hi @kellerman ,

Please check PR #918. I can't test it, as all my SAT>IP servers with minisatip and real DVB cards are E2 boxes.

lars18th avatar Jan 20 '22 18:01 lars18th

Hi @lars18th . I will check your PR tomorrow while at work. Do you mean that E2 box won't be able to show the dB value? All my minisatip servers are E2 boxes as well... What about the case when a tuner is unable to provide the dB value? Maybe we should hide the dB box/value if the dB=0? For example add display:none to the dB box element.

kellerman avatar Jan 20 '22 22:01 kellerman