Skip to content
Browse files

Single port version of a c++ UDP listener.

  • Loading branch information...
1 parent 5b4dcb4 commit dd88510720ba8b13f736660f1235a28fedf361a0 @cibomahto cibomahto committed May 24, 2012
Showing with 257 additions and 118 deletions.
  1. +93 −0 c++_host/LedStrip.cpp
  2. +57 −0 c++_host/LedStrip.h
  3. +50 −0 c++_host/SocketListener.cpp
  4. +30 −0 c++_host/SocketListener.h
  5. +27 −118 c++_host/host.cpp
View
93 c++_host/LedStrip.cpp
@@ -0,0 +1,93 @@
+#include <iostream>
+#include <fcntl.h> /* File control definitions */
+#include <errno.h> /* Error number definitions */
+#include <termios.h> /* POSIX terminal control definitions */
+
+#include "LedStrip.h"
+
+void LedStrip::Connect(std::string portname)
+{
+ m_fd = open(portname.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
+ if (m_fd == -1)
+ {
+ perror("open_port: Unable to open port:");
+ perror(portname.c_str());
+ exit(1); // TODO: Should we actually exit here?
+ }
+
+// Don't need to set a baud rate, the teensy ignores it
+// struct termios options;
+// tcgetattr(m_fd, &options);
+// cfsetispeed(&options, B115200);
+// cfsetospeed(&options, B115200);
+// tcsetattr(m_fd, TCSANOW, &options);
+}
+
+void LedStrip::SendBytes64(char* data) {
+ int return_code;
+ int count = 0;
+
+ do {
+ return_code = write(m_fd, data, 64);
+ // If a write error occurs, it is probably because the buffer is full.
+ // Force it to drain, then try again.
+ if (return_code < 0) {
+ tcdrain(m_fd);
+ count++;
+ }
+ }
+ while (return_code < 0);
+
+ if (count > 0) {
+ std::cerr << "count=" << count << std::endl;
+ }
+}
+
+void LedStrip::ConvertColor24(char* data) {
+ char newData[24];
+
+ memset(newData,0,24);
+
+ newData[0] = 0xFF;
+ newData[8] = 0xFF;
+ newData[16] = 0xFF;
+
+
+ for (int bit_index = 7; bit_index > 0; bit_index--) {
+ for (int pixel_index = 0; pixel_index < 8; pixel_index++) {
+ newData[1 +7-bit_index] |= ((data[1 + 3*pixel_index] >> bit_index) & 1) << pixel_index;
+ newData[9 +7-bit_index] |= ((data[ 3*pixel_index] >> bit_index) & 1) << pixel_index;
+ newData[17+7-bit_index] |= ((data[2 + 3*pixel_index] >> bit_index) & 1) << pixel_index;
+ }
+ }
+
+// for (int i = 0; i < 7; i++) {
+// newData[i+1] = 0x00;
+// newData[i+9] = 0x00;
+// newData[i+17] = 0x00;
+// }
+
+ memcpy(data, newData, 24);
+}
+
+void LedStrip::LoadData(char* data) {
+ // Convert the data to the appropriate space
+ for (int index = 1; index < m_image_height*8*3; index+=24) {
+ ConvertColor24(data+index);
+ }
+
+ // Write out the appropriate amount of data
+ for (int index = 1; index < m_image_height*8*3; index+=64) {
+ SendBytes64(data+index);
+ }
+}
+
+void LedStrip::Flip() {
+ char test[64];
+ for (int index = 0; index < 64; index++) {
+ test[index] = 0x00;
+ }
+
+ // Write out the appropriate amount of data
+ SendBytes64(test);
+}
View
57 c++_host/LedStrip.h
@@ -0,0 +1,57 @@
+#ifndef LEDSTRIP_H
+#define LEDSTRIP_H
+
+#include <string>
+
+class LedStrip {
+ public:
+ /**
+ * Create a new LedStrip
+ * @param image_width Width of the source impage
+ * @param image_height Height of the source image
+ * @param offst Row offset to write to this strip
+ */
+ LedStrip(int image_width, int image_height, int offset) :
+ m_image_width(image_width),
+ m_image_height(image_height),
+ m_offset(offset) {
+ }
+
+ /**
+ * Open a serial device for writing
+ * @param portname Name of the serial port to open (example: /dev/ttyACM0)
+ */
+ void Connect(std::string portname);
+
+ /**
+ * Write a buffer of data out to the serial port
+ * @param data Frame of color data to load, image_height*image_width*3 bytes
+ */
+ void LoadData(char* data);
+
+ /**
+ * Cause the strips to update their displays by clocking out 0's
+ */
+ void Flip();
+
+ private:
+ /**
+ * Send 64 bytes of data to the machine. Automatically handles flushing the
+ * data, and retrying if necessicary.
+ * @param data 64 bytes of data to send.
+ **/
+ void SendBytes64(char* data);
+
+ /**
+ * Convert a block of colors from split RGB format to parallal format
+ */
+ void ConvertColor24(char* data);
+
+ int m_image_width;
+ int m_image_height;
+ int m_offset;
+
+ int m_fd; // File descriptor
+};
+
+#endif
View
50 c++_host/SocketListener.cpp
@@ -0,0 +1,50 @@
+#include <iostream>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "SocketListener.h"
+
+void SocketListener::Connect(std::string ip_address, unsigned int port) {
+ struct sockaddr_in address;
+
+ m_fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (m_fd < 0)
+ {
+ perror("open_socket: Unable to open socket");
+ exit(1); // TODO: Should we actually exit here?
+ }
+
+
+ address.sin_family = AF_INET;
+ address.sin_port = htons(port);
+ inet_aton(ip_address.c_str(), &address.sin_addr);
+
+ int return_code;
+ return_code = bind(m_fd, (struct sockaddr*) &address, sizeof(struct sockaddr_in));
+ if (return_code < 0)
+ {
+ perror("open_socket: Unable to bind to port");
+ exit(1); // TODO: Should we actually exit here?
+ }
+}
+
+int SocketListener::GetFrame(char* frame, int length) {
+ int received_length = read(m_fd, frame, length);
+
+ // TODO: How to return erros here?
+ if (length != received_length) {
+ std::cerr << "Bad data frame, expected_length=" << length
+ << " received_length=" << received_length << std::endl;
+ return -1;
+ }
+
+ if (frame[0] != 0x01) {
+ std::cerr << "Bad header, expected=1"
+ << " got=" << static_cast<int>(frame[0]) << std::endl;
+ return -2;
+ }
+
+ return 0;
+}
View
30 c++_host/SocketListener.h
@@ -0,0 +1,30 @@
+#ifndef SOCKETLISTENER_H
+#define SOCKETLISTENER_H
+
+#include <string>
+
+class SocketListener {
+ public:
+ /**
+ * Start a UDP server at the given address
+ * @param ip_address IP address to listen on (0.0.0.0 binds to all)
+ * @param port Port to listen on (58082 is popular)
+ */
+ void Connect(std::string ip_address, unsigned int port);
+
+ /**
+ * Get a frame of data from the socket and check that it is valid.
+ * @param frame Buffer to store the frame in.
+ * @param length Expected length of the frame.
+ * @return 0 if successful, < 0 if a failure occurred.
+ */
+ int GetFrame(char* frame, int length);
+
+ private:
+ std::string m_address;
+ unsigned int m_port;
+
+ int m_fd;
+};
+
+#endif
View
145 c++_host/host.cpp
@@ -1,145 +1,54 @@
-
#include <iostream>
#include <string>
-#include <cstdio>
-#include <cstdlib>
-
-// First, try to send data to the usb port
-#include <fcntl.h> /* File control definitions */
-#include <errno.h> /* Error number definitions */
-#include <termios.h> /* POSIX terminal control definitions */
-
-
-class LedStrip {
- public:
- /**
- * Create a new LedStrip
- * @param image_width Width of the source impage
- * @param image_height Height of the source image
- * @param offst Row offset to write to this strip
- */
- LedStrip(int image_width, int image_height, int offset) :
- m_image_width(image_width),
- m_image_height(image_height),
- m_offset(offset) {
- }
-
- /**
- * Open a serial device for writing
- * @param portname Name of the serial port to open (example: /dev/ttyACM0)
- */
- void Connect(std::string portname);
-
- /**
- * Write a buffer of data out to the serial port
- * @param data Frame of color data to load, image_height*image_width*3 bytes
- */
- void LoadData(char* data);
-
- void Flip();
-
- private:
- /**
- * Send 64 bytes of data to the machine
- **/
- void SendBytes64(char* data);
-
- int m_image_width;
- int m_image_height;
- int m_offset;
-
- int m_fd; // File descriptor
-};
-
-void LedStrip::Connect(std::string portname)
-{
- m_fd = open(portname.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
- if (m_fd == -1)
- {
- perror("open_port: Unable to open port:");
- perror(portname.c_str());
- exit(1); // TODO: Should we actually exit here?
- }
-
- struct termios options;
- tcgetattr(m_fd, &options);
- cfsetispeed(&options, B115200);
- cfsetospeed(&options, B115200);
- tcsetattr(m_fd, TCSANOW, &options);
-}
-
-void LedStrip::SendBytes64(char* data) {
- int return_code;
- int count = 0;
-
- do {
- return_code = write(m_fd, data, 64);
- if (return_code < 0) {
- tcdrain(m_fd);
- count++;
-// std::cerr << "LedStrip::LoadData: Failure to write to serial port"
-// << " error=" << strerror(errno)
-// << " index=" << index
-// << std::endl;
- }
- }
- while (return_code < 0);
- if (count > 0) {
- std::cout << "count=" << count << std::endl;
- }
-}
+#include "LedStrip.h"
+#include "SocketListener.h"
-void LedStrip::LoadData(char* data) {
- char test[64];
- for (int index = 0; index < 64; index++) {
- test[index] = 0xFF;
- }
+int main( int argc, const char* argv[] ) {
+ int display_height = 160;
+ int display_width = 24;
- // Write out the appropriate amount of data
- for (int index = 0; index < m_image_height*8*3; index+=64) {
- SendBytes64(data);
- }
-}
+ // Connect to a LED strip
+ LedStrip test(display_width,display_height,0);
+ test.Connect("/dev/cu.usbmodem12341");
+// test.Connect("/dev/ttyACM0");
-void LedStrip::Flip() {
- char test[64];
- for (int index = 0; index < 64; index++) {
- test[index] = 0x00;
- }
+ SocketListener listener;
+ listener.Connect("0.0.0.0", 58082);
+ //
- // Write out the appropriate amount of data
- SendBytes64(test);
-}
-int main( int argc, const char* argv[] ) {
- std::cout << "Connecting!" << std::endl;
- LedStrip test(24,160,0);
- test.Connect("/dev/cu.usbmodem12341");
-// test.Connect("/dev/ttyACM0");
// Black test frame
- char data_off[24*160*3];
+ char data_off[display_width*display_height*3];
- for (int i = 0; i < 24*160*3; i+=1) {
+ for (int i = 0; i < display_width*display_height*3; i+=1) {
data_off[i] = 0x00;
}
- for (int i = 0; i < 24*160*3; i+=8) {
+ for (int i = 0; i < display_width*display_height*3; i+=8) {
data_off[i] = 0xFF;
}
// White test frame
- char data_on[24*160*3];
+ char data_on[display_width*display_height*3];
- for (int i = 0; i < 24*160*3; i+=1) {
+ for (int i = 0; i < display_width*display_height*3; i+=1) {
data_on[i] = 0xFF;
}
+ while(1) {
+ char data[display_width*display_height*3+1];
+ listener.GetFrame(data, display_width*display_height*3+1);
+
+ test.LoadData(data);
+ test.Flip();
+ }
+/*
+ // Just flash.
int count = 0;
while(1) {
- std::cout << "Loading!" << std::endl;
if (count < 1) {
test.LoadData(data_on);
}
@@ -148,7 +57,7 @@ int main( int argc, const char* argv[] ) {
}
count = (count+1)%2;
- std::cout << "Flipping!" << std::endl;
test.Flip();
}
+*/
}

0 comments on commit dd88510

Please sign in to comment.
Something went wrong with that request. Please try again.