A couple of days ago I published a blog discussing how I used NRF24L01 radios to implement a point-to-point network between two Raspberry Pi computers. I implemented this as a virtual network device and sent packets between the radios.
Since then, I have made numerous improvements to the software and more than tripled the throughput from ~90kbps to nearly 300kbps. These improvements were through a variety of changes that I will cover in this blog post.
![]() |
Streaming video from one headless Raspberry Pi to another |
Thanks to the higher throughput, I was able to implement streaming video using the h264 HEVC video codec and monaural audio using the Opus codec at 32kbps. The result is great, especially when considering the link.
Continue reading to learn more!
Implementation
If you want to know more about the implementation, I recommend that you ready my previous blog post. I will go over the improvements that were made and how I was able to stream video.
The previous implementation was able to transmit network traffic at 90kbps (that's kilobits). Since that blog post, I have improved performance to nearly 300kbps which is high enough to support streaming h.265 video!
Protocol Improvements
// A TxRx request for the network tunnel. message NetworkTunnelTxRx { // The bytes to send to the secondary radio. optional bytes payload = 1; // The number of remaining bytes for this packet. Once zero, write out // to the tunnel interface. optional uint32 remaining_bytes = 2; // The ID of this payload. optional uint32 id = 3; // The ID that this payload is acking from the secondary radio. optional uint32 ack_id = 4; }
Radio Tuning
while (!radio_.txStandBy()) { LOGI("Waiting for transmit standby"); }
CHECK(channel < 128, "Channel must be between 0 and 127"); CHECK(radio_.begin(), "Failed to start NRF24L01"); radio_.setChannel(channel); radio_.setPALevel(RF24_PA_MAX); radio_.setDataRate(RF24_2MBPS); radio_.setAddressWidth(3); radio_.setAutoAck(1); radio_.setRetries(0, 15); radio_.setCRCLength(RF24_CRC_8); CHECK(radio_.isChipConnected(), "NRF24L01 is unavailable");
Frame Format
bool RadioInterface::EncodeTunnelTxRxPacket( const TunnelTxRxPacket& tunnel, std::vector<uint8_t>& request) { request.resize(kMaxPacketSize, 0x00); if (tunnel.id.has_value()) { request[0] = tunnel.id.value(); } if (tunnel.ack_id.has_value()) { request[0] |= (tunnel.ack_id.value() << 4); } if (tunnel.payload.size() > kMaxPayloadSize) { LOGE("TxRx packet payload is too large"); return false; } request[1] = tunnel.bytes_left; for (size_t i = 0; i < tunnel.payload.size(); i++) { request[2 + i] = tunnel.payload[i]; } return true; }
The first byte of this packet encodes the transaction ID as a pair of nibbles. These transaction IDs are never, which allows the value 0 in this byte to be used to negotiate a connection reset.
The second byte contains the number of remaining bytes in a network frame, capped to 255. If this value ever drops to 30 or fewer bytes, the frame is complete and written to the network tunnel.
Video Streaming
ffmpeg -i bbb_sunflower_1080p_60fps_normal.mp4 \ -acodec libopus -b:a 32k -ac 1 \ -vcodec libx265 -b:v 50k -filter:v fps=fps=15,scale=720:480 \ bbb_sunflower_1080p_60fps_lowbitrate.mkv
The next step was to setup an RTP stream using VLC.
cvlc -vvv --no-sout-video \ --sout '#rtp{dst=localhost,port=9000,sdp=rtsp://:8080/test.sdp}' \ --sout-rtp-caching=5000 \ bbb_sunflower_1080p_60fps_lowbitrate.mkv
This was received by mplayer and displayed on the framebuffer.
sudo mplayer -ao alsa:device=hw=2.0 \ -vo fbdev2 -vf scale=720:480 -cache 64000 \ rtsp://192.168.10.2:8080/test.sdp
Automatic Connection Recovery
[Unit] Description=The nerfnet listener. After=multi-user.target [Service] Type=idle ExecStart=/home/andrew/Projects/nerfnet/build/nerfnet/net/nerfnet --secondary Restart=always RestartSec=10 [Install] WantedBy=multi-user.target
Range
![]() |
Radio on a lamp standard, roughly 60 meters away |
Indian Web Designers fast-growing website designing company in Delhi intend to create a website on your request according to your specifications.
ReplyDeleteWeb Designing Company in Delhi
SEO company in india
Energy Saving Sensors Made by Highly Components Pvt. Ltd. - Which is the leading company in the field of Security related products in India. The company has achieved an unrivalled position in the market by introducing PIR Motion Sensors for automatic control of lights apart from other Security Sensors. Energy Saving Sensors in New Delhi
ReplyDeleteSmoke Alarm Sensor
Thanks for sharing such a great blog......!!!
ReplyDeletefull form
full form of nrc
nrc full form
mbbs full form
full form of rip
Thanks for all the information. This is very helpful.
ReplyDeleteTV, WebTV, and green screen studio in Salt Lake City. Apart from the studio, SLC Studio also offers sleek and fully equipped meeting rooms event live streaming services uk
ReplyDelete