How to enable Long Range for BLE Mesh in Zephyr OS - c++

I’m working on Bluetooth mesh network solution and I have requirement to increase range.
I’m using nrf52840 DK and nrf52840 dongles, nrf5SDKforMeshv310.
In Nordic Devzone
I found solution which, enables BLE long range mode in NRF SDK for mesh.
NOTE! I'm aware solution doesn't comply with Bluetooth Mesh standard.
Following changes were applied to nrf5 SDK for Mesh v310:
In advertise.c, set_default_broadcast_configuration() changed radio_mode to use RADIO_MODE_NRF_62K5BIT instead of RADIO_MODE_BLE_1MBIT.
In scanner.c, scanner_config_reset() changed scanner_config_radio_mode_set() to use RADIO_MODE_NRF_62K5BIT instead of RADIO_MODE_BLE_1MBIT.
In radio_config.c, radio_config_config() added the following code at the end:
if (p_config->radio_mode==RADIO_MODE_NRF_62K5BIT ){
NRF_RADIO->PCNF0 |=(
((RADIO_PCNF0_PLEN_LongRange << RADIO_PCNF0_PLEN_Pos) & RADIO_PCNF0_PLEN_Msk) |
((2 << RADIO_PCNF0_CILEN_Pos) & RADIO_PCNF0_CILEN_Msk) |
((3 << RADIO_PCNF0_TERMLEN_Pos) & RADIO_PCNF0_TERMLEN_Msk) );
}
In broadcast.c, time_required_to_send_us() added:
if (radio_mode == RADIO_MODE_NRF_62K5BIT)
{
packet_length_in_bytes +=RADIO_PREAMBLE_LENGTH_LR_EXTRA_BYTES;
}
Defined RADIO_PREAMBLE_LENGTH_LR_EXTRA_BYTES = 9 in same file
Changed 5th element in radio_mode_to_us_per_byte[] from 128 to 64.
NOTE. that the long-range mode is mislabeled. It is called RADIO_MODE_NRF_62K5BIT in the header file but corresponds to the 125kbps BLE long range mode instead.
Unfortunately for relays I’m pushed to use Zephyr to support friend feature and Zephyr is not relaying messages after applying changes to NRF SDK. I did brief investigation on Zephyr side and found that code bits for BLE long range described above for NRF SDK are in place and can be enabled using following Kconfig settings:
CONFIG_BT_AUTO_PHY_UPDATE=y
CONFIG_BT_PHY_UPDATE=y
CONFIG_BT_HCI_MESH_EXT=y
CONFIG_BT_CTLR_PHY=y
CONFIG_BT_CTLR_ADV_EXT=y
CONFIG_BT_CTLR_ADVANCED_FEATURES=y
CONFIG_BT_CTLR_PHY_2M=y
CONFIG_BT_CTLR_PHY_CODED=y
But still I don’t see that messages are being relayed on Zephyr side (using J-Link RTT Viewer). I also tried to increase log level for Bluetooth and Mesh to DEBUG, but I don’t see any signs that messages are malformed or rejected.
May be someone has ideas in which direction I should dig in on Zephyr side?

Related

STM32-HAL CAN transmits empty error message only

I'm trying to transmit messages through CAN using HAL library. For test I repeated code from the first part of this video I have the same bluepill so I just did the same. Also I've tried his project, but changing Nucleo RE to ZE model. I've looked through other sources and they all do the same thing, and in their videos/articles bus perfoms as it is supposed to.
But on all of my devices HAL_CAN_AddTxMessage produces empty (or maybe error) message
Theese different lines are TX on one board and RX from other transcievers.
Debugging showed me nothing wrong: function returns HAL_OK. I went step by stem through it in debug mode and everything seemed as normal. But niether loopback nor normal mode transmitts correct message.
Also I've checked my LA with MCP2515 + TJA1040 and CAN bus worked as it has to
So I'm confused and don't understand what I'm doing wrong.
The problem was in TimeQuanta settings. I had to be more considerate. I'll wrigth a more exact explanation later

ESP8266 Access Point Mode - Intermittent when connecting

I'm using an ESP8266 in access point mode to send it some data (wifi credentials) from a mobile app via HTTP. The access point init code is very simple:
IPAddress apIP(10, 10, 10, 1);
IPAddress subnet(255,255,255,0);
WiFi.softAPConfig(apIP, apIP, subnet);
WiFi.softAP(ACCESS_POINT_NAME); // No password requird
What I find is that sometimes the mobile phone connects to the ESP's network seamlessly, and other times seriously struggles (rejects the connection, or takes > 3 mins to connect).
Questions are:
Are there issues with this code that could make a connection to the ESP by a client temperamental (sometimes fine, other times not)? Like should I change the WiFi channel from 1? Are the static IP/Subnet mask creating issues?
Is the issue likely hardware related - i.e. sometimes the client gets a good wifi signal from the ESP, sometimes not?
If anyone else faces this, I found a large performance improvement from doing the following:
Removing DNS
Reseting the WiFi config
Explicitly setting the module to AP mode - this is referenced by this Github issue comment. This seems to be the primary driver of improvement.
So the code is now:
// Set up WiFi mode [Improve AP stability - no dual STA mode]
ESP.eraseConfig();
WiFi.mode(WIFI_AP);
IPAddress apIP(10, 10, 10, 1);
IPAddress subnet(255,255,255,0);
WiFi.softAPConfig(apIP, apIP, subnet);
WiFi.softAP(ACCESS_POINT_NAME); // No password
WiFi.printDiag(Serial);
The reasoning is that while in STA mode, the ESP may channel hop (depending on the environment), and the AP gets pulled with it. So any client connected before the channel hop will have to reconnect.

Playing flv files from Cloudfront/S3 with Strobe Media Playback

I'm using the OSMF's Strobe Media Playback player to try and play files from AWS Cloudfront/S3
The bucket is called ct.recorder. The cloudfront distribution is called 1dm7svtk8jb00c.cloudfront.net, and it's origin is ct.recorder.
The video within the bucket is called vid_test001
I've tried initializing the player with rtmp://s34osaecrafusl.cloudfront.net/cfx/st/vid_test001
But that doesn't work.
I get Connection attempt rejected by FMS server. Connection failed.
I've also tried it with .flv at the end, but that doesn't work either.
Am I not linking to the file properly, or is it my player?
Well, I had an entire answer written up, speculating that it was related to bucket permissions, and now I'm scratching that answer and posting this, instead. :)
$ rtmpdump -r rtmp://s34osaecrafusl.cloudfront.net/cfx/st/vid_test001.flv -o testfile.flv
RTMPDump v2.4
(c) 2010 Andrej Stepanchuk, Howard Chu, The Flvstreamer Team; license: GPL
Connecting ...
WARNING: HandShake: client signature does not match!
INFO: Connected...
Starting download at: 0.000 kB
INFO: Metadata:
INFO: duration 13.82
INFO: videocodecid 2.00
INFO: audiocodecid 6.00
INFO: canSeekToEnd FALSE
INFO: createdby AMS 5
INFO: creationdate Tue Dec 03 13:41:46 2013
1190.238 kB / 13.82 sec (100.0%)
Download complete
This actually works for me... both with, and without, the .flv on the end, and the resulting file is a 7 second video of a guy looking at a webcam.
Using "smplayer" for Windows, I can connect to cloudfront with the rtmp:// url and stream the video, but it only works without the .flv on the end, using:
MPlayer Redxii-SVN-r36243-4.6.3 (C) 2000-2013 MPlayer Team
Custom build by Redxii, http://smplayer.sourceforge.net
Compiled against FFmpeg version N-52798-gf5846dc
Build date: Sun May 5 23:51:25 EDT 2013
This doesn't quite answer your question of why it isn't working, except to say that your player seems to be lying to you as far as "Connection attempt rejected by FMS server" because, at least from here, it's good, except for this part, and I don't know what it means.
WARNING: HandShake: client signature does not match!
However, that could just be a distraction.
It looks as if it's going to be your player... so trying other players would be worthwhile.
It is, of course, possible, that there's a regional issue involving the particular edge location inside cloudfront that you access from your location, which could be significantly different than the one I'm hitting, since it's geographically... but if another player works where you are, then you may have the answer you're looking for. Firing up wireshark and analyzing the protocol exchange could be an interesting exercise also.
Afterthought: the extra slash in your path could also be blowing something's mind, since an RTMP url apparently consists of two distinct components, "application"/"stream_name" and the point of delineation may be ambiguous at some level to some component in the chain. If cloudfront thinks the "application" is "cfx" and the stream is "st/vid_test001" but the client assumes the "application" is "cfx/st" with stream name "vid_test001" it seems like there could be some potential for interoperability trouble there. This is wild speculation, but perhaps worth experimentation, too.
The embed parameter urlIncludesFMSApplicationInstance needs to be set to true.

Standalone AGC (auto gain control) in WebRtc application

I'm trying to create a standalone AGC using WebRtc library. (Input - wav file, output - wav file with adjusted gain). But at this time I have some problems with this issue.
I'm trying to use functions which are declared in gain_control.h file. When I'm using WebRtcAgc_Process(....) I obtain constant gain, which applies to whole signal, but not nonlinear gain which depends from input signal magnitude.
May be I should use another functions for my purpose? How can I implement AGC via WebRTC library?
The AGC's main purpose is to provide a recommended system mic volume which the user is expected to set through the OS. If you would like to apply a purely digital gain, you can configure it in one of two modes (from modules/audio_processing/include/audio_processing.h, but gain_control.h has analogous modes):
// Adaptive mode intended for situations in which an analog volume control
// is unavailable. It operates in a similar fashion to the adaptive analog
// mode, but with scaling instead applied in the digital domain. As with
// the analog mode, it additionally uses a digital compression stage.
kAdaptiveDigital,
// Fixed mode which enables only the digital compression stage also used by
// the two adaptive modes.
//
// It is distinguished from the adaptive modes by considering only a
// short time-window of the input signal. It applies a fixed gain through
// most of the input level range, and compresses (gradually reduces gain
// with increasing level) the input signal at higher levels. This mode is
// preferred on embedded devices where the capture signal level is
// predictable, so that a known gain can be applied.
kFixedDigital
You can set these through WebRtcAgc_Init(), though unless you need to avoid the overhead, I'd recommend just using the AudioProcessing class.
refer to http://osxr.org/android/source/external/webrtc/src/modules/audio_processing/agc/interface/gain_control.h#0133
The gain adjustments are done only during 0135 * active periods of
speech. The input speech length can be either 10ms or 0136 * 20ms and
the output is of the same length.
quick overview of webrtcage_process
int WebRtcAgc_Process(void* agcInst,
const WebRtc_Word16* inNear,
const WebRtc_Word16* inNear_H,
WebRtc_Word16 samples,
WebRtc_Word16* out,
WebRtc_Word16* out_H,
WebRtc_Word32 inMicLevel,
WebRtc_Word32* outMicLevel,
WebRtc_Word16 echo,
WebRtc_UWord8* saturationWarning);

RS-232 confusion under C++

What's the problem in given code? Why it is not showing the output for rs232 when we connect it by the d-9 connector with the short of pin number 2 & 3 in that?
#include <bios.h>
#include <conio.h>
#define COM1 0
#define DATA_READY 0x100
#define SETTINGS ( 0x80 | 0x02 | 0x00 | 0x00)
int main(void)
{
int in, out, status;
bioscom(0, SETTINGS, COM1); /*initialize the port*/
cprintf("Data sent to you: ");
while (1)
{
status = bioscom(3, 0, COM1); /*wait until get a data*/
if (status & DATA_READY)
if ((out = bioscom(2, 0, COM1) & 0x7F) != 0) /*input a data*/
putch(out);
if (kbhit())
{
if ((in = getch()) == 27) /* ASCII of Esc*/
break;
bioscom(1, in, COM1); /*output a data*/
}
}
return 0;
}
Well, the code looks alright. Have you really connected the remaining pins correctly in the plug, see serial and pin connections.
Nothing obvious stands out from your code as the cause. Check all your bases as you are dealing with hardware/software. The following Microsoft article has a different implementation using _bios_serialcom (from bios.h) which might be a good reference point for you.
http://support.microsoft.com/kb/39501
Suggestions for where to go from here:
I would also suggest replacing the literals (eg 0x08) using the constants predefined for Baud rate, Parity (eg _COM_NOPARITY) to make the code more readable in your question.
Check that the Com port is actually open, as its a assumption which is unchecked in your code example above.
Also check up on the pin connections for the DB9. To connect two computers/devices you will need to null modem it, eg pin 2 to pin 3 at the other end, plus the Signal Ground. Make sure you are disabling/not looking for DTR.
If the other computer/device is setup then I would suggest first running HyperTerminal (Programs->Accessories->Communication) and connect to your COM 1 and check you can see characters from the other device. If not its most likely related to your cable.
Hope that helps.
Before checking with your code always check your serial communication with a terminal program. I don't have much experience with Windows environment but in Linux you have programs like cutecom or gtkterm where you can send/receive data from serial port. We extensively used these programs for serial communication in Linux, they are great for debugging potential problems with serial port interface (both h/w & s/w as well). So, before suspecting your code check with a terminal emulator program.
Hey, I am not an expert on Win32, but it seems to be easier to use another article as a source (the one mentioned here before looks outdated):
http://msdn.microsoft.com/en-us/library/ms810467
This is old too, dated around 1995, but it looks still effective. The NT architecture is very restrictive when it comes to grant access to hardware, for example, to send bytes to a PC paralell port one needs to rely on workarounds dll written by open source developers.
I'm assuming from your comment about "pin 2 & 3" that you've connected a loopback cable, so you're expecting to see anything you type come up on the screen (and stop doing so when you disconnect the cable).
I think there's a bug in the code: the if (kbhit()) is inside the if (status & DATA_READY).
That means you only check the keyboard if there is some input ready to receive from the serial port - which there won't be, because you haven't sent it anything yet! Try moving the test and see if it improves matters.
(Here is some similar serial port code that puts the if (kbhit()) test outside the DATA_READY check. It doesn't claim to work, but provides some evidence that this might be the source of the problem...)