Skip to content

Instantly share code, notes, and snippets.

@jaygarcia
Created April 18, 2019 19:53
Show Gist options
  • Save jaygarcia/5d77e6687e742dcfb19f58728c997b76 to your computer and use it in GitHub Desktop.
Save jaygarcia/5d77e6687e742dcfb19f58728c997b76 to your computer and use it in GitHub Desktop.
rpi-rgb-led-matrix example using TCP/IP to fill a display (SENDER)
/*
This is a non-threaded & blocking TCP/IP sender program to your RPI running hzeller's RGB Matrix
thread.
It will loop and create a random color, sending `totalBytes` to the receving pi.
Original thread: https://github.com/hzeller/rpi-rgb-led-matrix/issues/796
Client example: https://gist.github.com/jaygarcia/c8b0ce341b36c453c869fc2fe8c4f29c
*/
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>
#include <stdlib.h>
using boost::asio::ip::tcp;
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 256
#define max_length (SCREEN_WIDTH * SCREEN_HEIGHT)
// Make sure these match the receving pi's dimensions!
const uint16_t matrixHeight = 64;
const uint16_t matrixWidth = 64;
const uint16_t numPixelsPerMatrix = (matrixHeight * matrixWidth);
const uint16_t numMatricesWide = 3;
const uint16_t numMatricesTall = 2;
const uint16_t totalPixels = numPixelsPerMatrix * numMatricesWide * numMatricesTall;
const size_t totalBytes = totalPixels * sizeof(uint16_t);
uint16_t *screenBuffer;
// Make sure IP and ports match for the RPi connected to the matrices
const char *destIP = "172.20.2.161";
const char *destPort = "9898";
// Blocking function
void sendData(int n) {
try {
boost::asio::io_service io_service;
tcp::socket s(io_service);
tcp::resolver resolver(io_service);
printf("Connecting..\n");
boost::asio::connect(s, resolver.resolve({destIP, destPort}));
uint16_t data[totalPixels];
size_t numBytesPerRow = matrixWidth;
uint16_t *dataPtr = data;
//Could be changed to use memcpy to make faster
for (int i = 0; i < totalPixels; i++) {
data[i] = screenBuffer[i];
}
std::string str = std::to_string(n);
char *request = new char [str.length() + 1];
std::strcpy(request, str.c_str());
size_t request_length = std::strlen(request);
printf("sending %lu bytes\n", totalBytes);
boost::asio::write(s, boost::asio::buffer(data, totalBytes * sizeof(uint16_t)));
char reply[10];
size_t reply_length = boost::asio::read(s,boost::asio::buffer(reply, 10));
// Change to manage your own exception flow
if (reply_length == 1) {
printf("----- GOOD!\n\n");
}
else {
printf("****** BAD *****\n\n");
}
}
catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << "\n";
}
}
int main(int argc, char* argv[]) {
// This is the screen buffer you write to. It gets copied in the sendData function above.
screenBuffer = (uint16_t *)std::malloc(sizeof(uint16_t) * totalPixels);
int n = 0;
while(n < 10000000) {
uint16_t color = (uint16_t)(random() & INT16_MAX);
// You could write a better function to write to the screen buffer. It could actually be another
// drawing program that draws images and/or primitives to the screenBuffer
for (int i = 0; i < totalPixels; i++) {
screenBuffer[i] = color;
}
sendData(n); // call my blocking function. Could be changed to threaded or async.
usleep(30 * 100);// sleep for however long.
n++;
}
delete screenBuffer;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment