Permalink
Browse files

Working for Country Club

Merge branch 'master' of https://github.com/hackrockcity/domeFirmware

Conflicts:
	c++_host/host.cpp
  • Loading branch information...
2 parents 8f83a62 + dd88510 commit 75d8c4baa4121b41c9369ca80e68d17f5b718c44 justin committed May 26, 2012
Showing with 268 additions and 144 deletions.
  1. +100 −0 c++_host/LedStrip.cpp
  2. +57 −0 c++_host/LedStrip.h
  3. +53 −0 c++_host/SocketListener.cpp
  4. +30 −0 c++_host/SocketListener.h
  5. +24 −140 c++_host/host.cpp
  6. +1 −1 host/LedStrips.py
  7. +3 −3 host/domelistener.py
View
100 c++_host/LedStrip.cpp
@@ -0,0 +1,100 @@
+#include <iostream>
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+
+#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) {
+ char output_data[m_image_height*m_image_width*3];
+ memcpy(output_data, data, m_image_height*m_image_width*3);
+
+ // Convert the data to the appropriate space
+ for (int index = 1; index < m_image_height*8*3; index+=24) {
+ ConvertColor24(output_data+index);
+ }
+
+ // Write out the appropriate amount of data
+ for (int index = 1; index < m_image_height*8*3; index+=64) {
+ SendBytes64(output_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
53 c++_host/SocketListener.cpp
@@ -0,0 +1,53 @@
+#include <iostream>
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+
+#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
164 c++_host/host.cpp
@@ -1,154 +1,38 @@
-
#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;
+#include <vector>
- int m_fd; // File descriptor
-};
+#include "LedStrip.h"
+#include "SocketListener.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?
- }
-
- 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;
- }
-
-}
-
-void LedStrip::LoadData(char* data) {
-
- char test[64];
- for (int index = 0; index < 64; index++) {
- test[index] = 0xFF;
- }
-
- // Write out the appropriate amount of data
- for (int index = 0; index < m_image_height*8*3; index+=64) {
- SendBytes64(data);
- }
-}
-
-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);
-}
int main( int argc, const char* argv[] ) {
- std::cout << "Connecting!" << std::endl;
- LedStrip test(24,160,0);
+ int display_height = 160;
+ int display_width = 24;
+
+ // Connect to a LED strip
+ std::vector<LedStrip> strips;
+
+ strips.push_back(LedStrip(display_width,display_height,0));
+ strips.push_back(LedStrip(display_width,display_height,8));
+ strips.push_back(LedStrip(display_width,display_height,16));
+ strips[0].Connect("/dev/ttyACM0");
+ strips[1].Connect("/dev/ttyACM1");
+ strips[2].Connect("/dev/ttyACM2");
// test.Connect("/dev/cu.usbmodem12341");
- test.Connect("/dev/ttyACM0");
-
- // Black test frame
- char data_off[24*160*3];
- for (int i = 0; i < 24*160*3; i+=1) {
- data_off[i] = 0x00;
- }
-
- for (int i = 0; i < 24*160*3; i+=8) {
- data_off[i] = 0xFF;
- }
+ SocketListener listener;
+ listener.Connect("0.0.0.0", 58082);
- // White test frame
- char data_on[24*160*3];
-
- for (int i = 0; i < 24*160*3; i+=1) {
- data_on[i] = 0xFF;
- }
-
- int count = 0;
while(1) {
- std::cout << "Loading!" << std::endl;
- if (count < 1) {
- test.LoadData(data_on);
+ char data[display_width*display_height*3+1];
+ listener.GetFrame(data, display_width*display_height*3+1);
+ for(int i = 0; i < strips.size(); i++) {
+ strips[i].Flip();
}
- else {
- test.LoadData(data_off);
+
+ for(int i = 0; i < strips.size(); i++) {
+ strips[i].LoadData(data);
}
- count = (count+1)%2;
-
- std::cout << "Flipping!" << std::endl;
- test.Flip();
}
}
View
2 host/LedStrips.py
@@ -18,7 +18,7 @@ def __init__(self, image_width, offset):
self.offset = offset
def connect(self, port):
- self.ser = serial.Serial(port, 1000002, timeout=0)
+ self.ser = serial.Serial(port, 115200, timeout=0)
def RgbRowToStrips(self, data):
"""
View
6 host/domelistener.py
@@ -15,9 +15,9 @@
# Serial port settings
strip_names = [
- ['/dev/tty.usbmodem12341', 0],
- ['/dev/tty.usbmodem11', 16],
- ['/dev/tty.usbmodem12', 8],
+ ['/dev/ttyACM0', 0],
+ ['/dev/ttyACM1', 16],
+ ['/dev/ttyACM2', 8],
]
class threadedLedStrips(multiprocessing.Process):

0 comments on commit 75d8c4b

Please sign in to comment.