LED-BOARD/LED-Board.ino

250 lines
4.8 KiB
C++

#include <Ethernet.h>
#include "image.h"
#define LOAD 7
#define DATA 8
#define CLOCK 9
struct _source_t {
// width and height of current frame
unsigned int width;
unsigned int height;
// delay until next frame is shown
unsigned int delay;
// position of current pixel
int x;
int y;
};
typedef struct _source_t source_t;
byte mac[] = { 0xBE, 0xB7, 0x5C, 0x30, 0xC3, 0x04 };
IPAddress ip(10, 23, 42, 24);
IPAddress router(10, 23, 42, 1);
IPAddress subnet(255, 255, 254, 0);
EthernetServer server(9000);
image_t image;
source_t source;
void setup() {
// setup network
Ethernet.init(10);
Ethernet.begin(mac, ip, router, router, subnet);
server.begin();
Serial.begin(115200);
pinMode(DATA, OUTPUT);
pinMode(CLOCK, OUTPUT);
pinMode(LOAD, OUTPUT);
Serial.println("setup done");
}
void send_block(image_t* p, int x, int y) {
int order[32][2] = {
{ 1, 1 }, // 1
{ 1, 0 }, // 2
{ 0, 1 }, // 3
{ 1, 2 }, // 4
{ 0, 2 }, // 5
{ 1, 3 }, // 6
{ 0, 0 }, // 7
{ 0, 3 }, // 8
{ 0, 4 }, // 9
{ 1, 4 }, // 10
{ 0, 5 }, // 11
{ 1, 7 }, // 12
{ 1, 5 }, // 13
{ 0, 6 }, // 14
{ 1, 6 }, // 15
{ 0, 7 }, // 16
{ 3, 7 }, // 17
{ 2, 6 }, // 18
{ 2, 7 }, // 19
{ 3, 6 }, // 20
{ 2, 5 }, // 21
{ 3, 5 }, // 22
{ 3, 4 }, // 23
{ 2, 4 }, // 24
{ 3, 3 }, // 25
{ 2, 0 }, // 26
{ 3, 0 }, // 27
{ 2, 3 }, // 28
{ 3, 2 }, // 29
{ 2, 1 }, // 30
{ 3, 1 }, // 31
{ 2, 2 }, // 32
};
for (int n = 0; n < 32; n++) {
int x_offset = order[n][0];
int y_offset = order[n][1];
byte pixel = get_pixel(p, x + x_offset, y + y_offset);
digitalWrite(DATA, pixel);
clock();
}
// 33 bit - kein pixel - senden
clock();
}
void send_image(image_t* img) {
for (int y = 0; y < MAX_HEIGHT; y += 8) {
for (int x = 0; x < MAX_WIDTH; x += 4) {
send_block(img, x, y);
}
}
load();
}
void clock() {
digitalWrite(CLOCK, HIGH);
digitalWrite(CLOCK, LOW);
}
void load() {
digitalWrite(LOAD, HIGH);
digitalWrite(LOAD, LOW);
}
// 0x00 0x00 0x00 0x00 0x00 0x00 0x00...
// Width Height Delay Pixel
void default_image(image_t* p) {
static int offset = 0;
// reset image to maximum size
set_size(p, 32767, 32767);
// toggle all pixels in tilted bars
int dim = max(p->width, p->height);
for (int n = 0; n < dim; n++) {
int x = (n + offset) % p->width;
int y = n % p->height;
byte pixel = get_pixel(p, x, y);
set_pixel(p, x, y, !pixel);
}
offset++;
}
bool read_header(EthernetClient cli, source_t* src) {
// number of bytes already read from header
static int offset = 0;
// flag set, if header is complete
bool complete = false;
while (offset < 6) {
int value = cli.read();
if (value == -1) {
break;
}
switch (offset) {
case 0:
src->width = (value << 8);
break;
case 1:
src->width |= value;
break;
case 2:
src->height = (value << 8);
break;
case 3:
src->height |= value;
break;
case 4:
src->delay = (value << 8);
break;
case 5:
src->delay |= value;
break;
}
offset++;
}
if (offset > 5) {
src->x = 0;
src->y = 0;
offset = 0;
complete = true;
}
return complete;
}
bool read_pixels(EthernetClient cli, source_t* src, image_t* img) {
// copy dimension from header
set_size(img, src->width, src->height);
while (true) {
int value = cli.read();
if (value == -1) {
return false;
}
set_pixel(img, src->x, src->y, value);
src->x++;
if (src->x >= src->width) {
src->x = 0;
src->y++;
if (src->y >= src->height) {
src->y = 0;
return true;
}
}
}
}
void loop() {
static unsigned long last_activity = 0;
static bool in_header = true;
// if an incoming client connects, there will be bytes available to read:
EthernetClient client = server.available();
if (client) {
if (in_header == true) {
if (read_header(client, &source) == true) {
Serial.print("width=");
Serial.print(source.width);
Serial.print(" height=");
Serial.print(source.height);
Serial.print(" delay=");
Serial.println(source.delay);
if ((source.width == 0) || (source.height == 0)) {
Serial.println("invalid dimension");
client.stop();
} else {
in_header = false;
}
}
} else {
if (read_pixels(client, &source, &image) == true) {
Serial.println("pixels complete");
in_header = true;
send_image(&image);
}
}
last_activity = millis();
} else {
if ((millis() - last_activity) > 60000) {
default_image(&image);
send_image(&image);
}
}
}