Permalink
Browse files

working serial communication after refactoring

  • Loading branch information...
olt committed May 29, 2012
1 parent bc45e08 commit 8981eede16b889bfb5c91cbeefae8f9c393b23b3
Showing with 177 additions and 70 deletions.
  1. +4 −4 display.h
  2. +4 −0 font.h
  3. +61 −17 push_image.py
  4. +7 −4 serial.h
  5. +88 −28 ticker.h
  6. +13 −17 ticker.ino
View
@@ -11,19 +11,19 @@ class DisplayBuffer {
return row * 192 + col;
}
- bool getPixel(byte col, byte row) {
+ inline bool getPixel(byte col, byte row) const {
int offset = pixelOffset(col, row);
- return (buf[offset / 8] & (1 << (offset % 8))) > 0;
+ return (buf[offset / 8] & (0b10000000 >> (offset % 8))) > 0;
}
void setPixelOn(byte col, byte row) {
int offset = pixelOffset(col, row);
- buf[offset / 8] |= 1 << (offset % 8);
+ buf[offset / 8] |= (0b10000000 >> (offset % 8));
}
void setPixelOff(byte col, byte row) {
int offset = pixelOffset(col, row);
- buf[offset / 8] &= ~(1 << (offset % 8));
+ buf[offset / 8] &= ~(0b10000000 >> (offset % 8));
}
void setColumn(byte row, unsigned int columnData) {
View
4 font.h
@@ -1,3 +1,5 @@
+namespace font {
+
struct FontInfo {
byte height, width, first, count;
prog_uint8_t* image;
@@ -79,4 +81,6 @@ unsigned int charColumn(byte column) {
bits += fontInfo.width;
}
return result;
+}
+
}
View
@@ -1,29 +1,73 @@
+from __future__ import with_statement, division
import serial
import sys
from time import sleep
-from PIL import Image, ImageDraw
+from PIL import Image, ImageDraw, ImageEnhance
+
magic_bytes = [159, 170, 85, 241]
+display_size = (192, 14)
+
+def pan_image(img):
+ x_diff = max(0, img.size[0] - display_size[0])
+ y_diff = max(0, img.size[1] - display_size[1])
+ max_diff = max(x_diff, y_diff)
+ if max_diff < 1:
+ yield img
+ raise StopIteration
-def push_image(img):
- for c in reversed(img.tostring()[:336]):
+ x_step = x_diff / max_diff
+ y_step = y_diff / max_diff
+ x = y = 0
+ for i in range(max_diff):
+ x += x_step
+ y += y_step
+ yield img.crop(map(int, (x, y, x+display_size[0], y+display_size[1])))
+
+def push_image(ser, img):
+ ser.write(''.join(chr(x) for x in magic_bytes))
+ ser.write(chr(100))
+ # sleep(0.1)
+ assert len(img.convert('1').tostring())
+ for c in img.convert('1').tostring()[:336]:
ser.write(c)
+ # sleep(0.01)
+ sleep(1/(115200/9))
+
+def prepare_output(img):
+ img = img.convert('L')
+ img = Image.eval(img, lambda x: 255 if x > 200 else 0)
+ return img.convert('1')
+
+def wait(ser):
+ for i in range(5):
+ if ser.readline():
+ return
# 115200
if __name__ == '__main__':
- ser = serial.Serial(sys.argv[1], baudrate=115200)
- sleep(5)
- print ser.readline()
- # ser.write(''.join(chr(x) for x in magic_bytes))
- # ser.write(chr(10))
-
- img = Image.new('1', (192, 14), 0)
- draw = ImageDraw.Draw(img)
- for y in range(0, 14, 2):
- draw.line((0, y, 191, y), fill=1)
- for c in img.tostring():
- ser.write(c)
- sleep(2)
- sleep(2)
+ ser = serial.Serial(sys.argv[1], baudrate=115200, timeout=1)
+ wait(ser)
+ img = Image.open(sys.argv[2])
+ img.thumbnail((display_size[0], display_size[0]))
+ for i, img in enumerate(pan_image(img)):
+ push_image(ser, prepare_output(img))
+ prepare_output(img).save('/tmp/frames/frame-%03d.gif' % i)
+ sleep(1/25)
+ # print '.'
+ # sleep(0.1)
+
+ sleep(500)
+ # print ser.readline()
+ # # ser.write(''.join(chr(x) for x in magic_bytes))
+ # # ser.write(chr(10))
+ # img = Image.new('1', (192, 14), 0)
+ # draw = ImageDraw.Draw(img)
+ # for y in range(0, 14, 2):
+ # draw.line((0, y, 191, y), fill=1)
+ # for c in img.tostring():
+ # ser.write(c)
+ # sleep(2)
+ # sleep(2)
View
@@ -5,13 +5,15 @@
static const byte MAGIC_BYTES[4] = {159, 170, 85, 241};
-#define SERIAL_WAIT_AVAILABLE() while (Serial.available() < 0) {}
+#define SERIAL_WAIT_AVAILABLE() while (Serial.available() < 1) {}
byte seekToFrameStart() {
while (1) {
SERIAL_WAIT_AVAILABLE();
// read till first magic byte
- while (Serial.read() != MAGIC_BYTES[0]) {}
+ while (Serial.read() != MAGIC_BYTES[0]) {
+ SERIAL_WAIT_AVAILABLE();
+ }
// start again (continue) if other three bytes do not match
SERIAL_WAIT_AVAILABLE();
if (Serial.read() != MAGIC_BYTES[1]) { continue; }
@@ -27,11 +29,12 @@ byte seekToFrameStart() {
byte updateDisplayFromSerial(DisplayBuffer *display) {
seekToFrameStart();
int bytesRead = 0;
- while (bytesRead < display->size) {
+ while (bytesRead <= display->size) {
SERIAL_WAIT_AVAILABLE();
- display->buf[bytesRead] = (byte)Serial.read();
+ display->buf[bytesRead] = Serial.read();
bytesRead += 1;
}
+ return 0;
}
#endif
View
116 ticker.h
@@ -66,7 +66,7 @@ static void shiftBlank(byte columns=1) {
static void shiftInColumn(unsigned int data) {
for (int row = 0; row < 14; row++) {
addressRow(row);
- if ((data & (1<<(13-row))) > 0) {
+ if ((data & (1 << row)) > 0) {
ledOn();
} else {
ledOff();
@@ -163,13 +163,18 @@ class Ticker {
}
// shift current LED row by ``columns`` to left
- static void shiftCurrentRow(byte columns=1) {
+ static void shiftCurrentRow(byte columns) {
for (byte i = 0; i < columns; i++) {
PORTD &= ~(1 << 7);
PORTD |= 1 << 7;
}
}
+ static inline void shiftCurrentRow() {
+ PORTD &= ~(1 << 7);
+ PORTD |= 1 << 7;
+ }
+
static inline void ledPowerOn() {
PORTD |= 1 << 2;
}
@@ -178,7 +183,24 @@ class Ticker {
PORTD &= ~(1 << 2);
}
- void shiftInDisplayBuffer(DisplayBuffer *displayBuffer) {
+ static void shiftInColumn(unsigned int data) {
+ for (int row = 0; row < 14; row++) {
+ if ((data & (1 << row)) > 0) {
+ pushOnLed(row);
+ } else {
+ pushOffLed(row);
+ }
+ }
+ }
+ static void shiftBlank(byte columns=1) {
+ for (int row = 0; row < 14; row++) {
+ for (int i = 0; i < columns; i++) {
+ pushOffLed(row);
+ }
+ }
+ }
+
+ static void shiftInDisplayBuffer(const DisplayBuffer *displayBuffer) {
for (int row = 0; row < height; ++row) {
addressRow(row);
for (int col = 0; col < width; ++col) {
@@ -192,6 +214,35 @@ class Ticker {
}
}
+ static void shiftInDisplayBufferRaw(DisplayBuffer *displayBuffer) {
+ // shift in display buffer by direct access to the buffer
+ byte currentByte;
+ for (int row = 0; row < height; ++row) {
+ addressRow(row);
+ for (int col = 0; col < width/8; ++col) {
+ currentByte = displayBuffer->buf[row * (192/8) + col];
+
+ // manual loop unrolling
+ (0b10000000 & currentByte) ? ledPowerOn() : ledPowerOff();
+ shiftCurrentRow();
+ (0b01000000 & currentByte) ? ledPowerOn() : ledPowerOff();
+ shiftCurrentRow();
+ (0b00100000 & currentByte) ? ledPowerOn() : ledPowerOff();
+ shiftCurrentRow();
+ (0b00010000 & currentByte) ? ledPowerOn() : ledPowerOff();
+ shiftCurrentRow();
+ (0b00001000 & currentByte) ? ledPowerOn() : ledPowerOff();
+ shiftCurrentRow();
+ (0b00000100 & currentByte) ? ledPowerOn() : ledPowerOff();
+ shiftCurrentRow();
+ (0b00000010 & currentByte) ? ledPowerOn() : ledPowerOff();
+ shiftCurrentRow();
+ (0b00000001 & currentByte) ? ledPowerOn() : ledPowerOff();
+ shiftCurrentRow();
+ }
+ }
+ }
+
void shiftInRandom() {
for (int row = 0; row < height; ++row) {
addressRow(row);
@@ -206,6 +257,40 @@ class Ticker {
}
}
+ void shiftChar(char c, int colDelay=30) {
+ font::setChar(c);
+ for (int i = 0; i < font::charInfo.width; i++) {
+ shiftInColumn(font::charColumn(i));
+ delay(colDelay);
+ }
+ shiftBlank();
+ delay(colDelay);
+ }
+
+ void shiftString(char *string, int colDelay=30) {
+ while (*string != 0) {
+ if (*string == '\t') {
+ for (int i = 0; i < 50; ++i) {
+ shiftBlank();
+ delay(colDelay);
+ }
+ } else if (*string == ' ') {
+ for (int i = 0; i < 5; ++i) {
+ shiftBlank();
+ delay(colDelay);
+ }
+ } else {
+ shiftChar(*string, colDelay);
+ }
+ string++;
+ }
+
+ for (int i = 0; i < 192; ++i) {
+ shiftBlank();
+ delay(colDelay);
+ }
+ }
+
};
@@ -218,29 +303,4 @@ void blink(const Ticker *ticker) {
ticker->display(50);
}
-void shiftChar(char c, int colDelay=30) {
- setChar(c);
- for (int i = 0; i < charInfo.width; i++) {
- shiftInColumn(charColumn(i));
- display(colDelay);
- }
- shiftBlank();
- display(colDelay);
-}
-
-char string[] = "Kreativitaet trifft Technik!";
-
-void shiftString(char *string) {
- int len = strlen(string);
- while (*string != 0) {
- shiftChar(*string, 30);
- string++;
- }
-
- for (int i = 0; i < (192 - len); ++i) {
- shiftBlank();
- display(30);
- }
-}
-
#endif
View
@@ -18,27 +18,23 @@ void blink(int msDelay) {
void setup() {
Serial.begin(115200);
- Serial.println("Hello!");
+ Serial.write('?');
ticker.initPins();
pinMode(13, OUTPUT);
- setFont(font_helvR10);
- blink(1000);
+ font::setFont(font_helvR10);
}
-void fillBufferRandom(DisplayBuffer *buffer) {
- int bytesRead = 0;
- while (bytesRead < buffer->size) {
- if (random(5) == 0) {
- buffer->buf[bytesRead] = 170;
- } else {
- buffer->buf[bytesRead] = 0;
- }
- bytesRead += 1;
- }
-}
+char *msg = {
+ "Sommer im Quartier."
+ "\tKreativitaet trifft Technik!"
+ "\tDer Oldenburger Hackspace stellt sich vor."
+ "\tBasteln, loeten und diskutieren; 3D-Drucker, Styrophorschneider, LED-Cubes,"
+ " Klackerlaken, Arduino, CNC-Fraese, Terminals"
+ "\tDer Space ist offen! Kommt einfach rein und Treppe hoch."
+};
void loop() {
- updateDisplayFromSerial(&buffer);
- ticker.shiftInDisplayBuffer(&buffer);
- // delay(1000);
+ ticker.shiftString(msg, 20);
+ // updateDisplayFromSerial(&buffer);
+ // ticker.shiftInDisplayBufferRaw(&buffer);
}

0 comments on commit 8981eed

Please sign in to comment.