Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Flip-Disc controller code:
- #include <Wire.h>
- #include <wwFlipdot02.h>
- #include <DS3231.h>
- DS3231 clock;
- RTCDateTime dt;
- // states of the process variable
- enum processStates {
- STATE_WAITING, // i2c waiting for input
- STATE_READ_HEADER, // first part of data read
- STATE_READ_DATA, // parameters read (ex. image bits)
- STATE_PROCESSED // data processed, waiting for alarm to reset display
- };
- // types of data to display
- const char TYPE_IMAGE = 'i';
- const char TYPE_TEXT = 't'; // currently not used
- const char TYPE_CHANGE_TIME = 'c';
- const char TYPE_RESET = 'r';
- const char TYPE_DEBUG = 'd';
- // characters for flip-disc display
- boolean numbers[10][5][3] = {
- {{1, 1, 1}, {1, 0, 1}, {1, 0, 1}, {1, 0, 1}, {1, 1, 1}}, //0
- {{0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}}, //1
- {{1, 1, 1}, {0, 0, 1}, {1, 1, 1}, {1, 0, 0}, {1, 1, 1}}, //2
- {{1, 1, 1}, {0, 0, 1}, {1, 1, 1}, {0, 0, 1}, {1, 1, 1}}, //3
- {{1, 0, 1}, {1, 0, 1}, {1, 1, 1}, {0, 0, 1}, {0, 0, 1}}, //4
- {{1, 1, 1}, {1, 0, 0}, {1, 1, 1}, {0, 0, 1}, {1, 1, 1}}, //5
- {{1, 1, 1}, {1, 0, 0}, {1, 1, 1}, {1, 0, 1}, {1, 1, 1}}, //6
- {{1, 1, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}}, //7
- {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}, {1, 0, 1}, {1, 1, 1}}, //8
- {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}, {0, 0, 1}, {1, 1, 1}}, //9
- };
- boolean colon[5][3] = {
- {0, 0, 0},
- {0, 1, 0},
- {0, 0, 0},
- {0, 1, 0},
- {0, 0, 0}
- };
- boolean dot[5][3] = {
- {0, 0, 0},
- {0, 0, 0},
- {0, 0, 0},
- {0, 0, 0},
- {0, 1, 0}
- };
- // character positions for clock
- byte positions[][2] = {
- {2, 2},
- {6, 2},
- {9, 2},
- {12, 2},
- {16, 2},
- {2, 9},
- {6, 9},
- {9, 9},
- {12, 9},
- {16, 9}
- };
- byte positions1[][2] = {
- {7, 9},
- {11, 9}
- };
- byte oldDay;
- boolean configChange = false;
- // variables affected by i2c data
- volatile char command = '\0';
- volatile char text[65] = "";
- volatile byte process = STATE_WAITING;
- volatile long len = 0;
- volatile long unix = 0;
- volatile short count = -1;
- void setup() {
- Serial.begin(9600);
- clock.begin();
- dt = clock.getDateTime();
- oldDay = dt.day;
- clock.armAlarm1(false);
- clock.armAlarm2(false);
- clock.clearAlarm1();
- clock.clearAlarm2();
- //clock.setAlarm1(0, 0, 0, 0, DS3231_EVERY_SECOND, true);
- clock.setAlarm2(0, 0, 0, DS3231_EVERY_MINUTE, true); // updates the clock
- // flip-disc setup (it starts at {1, 1}, not {0, 0}!)
- dotSetup(8, 21, 1, 16, 0);
- dotPowerOn();
- delay(50);
- resetAll(0);
- delay(100);
- // i2c setup
- Wire.begin(105);
- Wire.onReceive(receiveEvent);
- Serial.println("Setup done.");
- configChange = true; // refresh clock when entering main loop
- }
- void loop() {
- if(clock.isAlarm1() && process == STATE_PROCESSED) { // reset display and variables when time (len) has elapsed
- clock.armAlarm1(false);
- clock.clearAlarm1();
- process = 0;
- command = '\0';
- len = 0;
- unix = 0;
- for(byte i = 0; i < 65; i++) {
- text[i] = '\0';
- }
- count = -1;
- Serial.println("Resetting flipdot (alarm triggered)...");
- resetAll(0);
- delay(50);
- configChange = true; // update display (show clock or other data)
- }
- else if(process == STATE_PROCESSED || process == STATE_READ_HEADER) { // stop loop execution if something is (going to be) displayed
- return;
- }
- else if(process == STATE_READ_DATA) { // process received data
- Serial.println("Processing data...");
- if(command == TYPE_IMAGE) {
- Serial.println("Displaying image...");
- for(byte i = 0; i < 42; i++) { // reconstruct image from 42 bytes and show it
- byte x = floor((float) i / (float) 2) + 1;
- byte y = 9;
- if(i % 2 == 0) {
- y = 1;
- }
- for(byte j = 0; j < 8; j++) {
- if(((text[i] >> j) & 1) == 1) {
- setDot(x, y + j);
- }
- else {
- resetDot(x, y + j);
- }
- delay(1);
- }
- }
- Serial.println("Displayed image!");
- }
- else if(command == TYPE_CHANGE_TIME) { // change clock time
- unix += len; // add given offset to given time
- Serial.print("Set time to ");
- Serial.print(unix);
- Serial.println(".");
- clock.setDateTime(unix);
- }
- else if(command == 'r') { // reset display (done when alarm fires, configChange = true);
- Serial.println("Reset flipdot!");
- }
- else if(command == 'd') { // debug display (if some of the dots aren´t working properly anymore)
- Serial.println("Debugging flipdot...");
- debug();
- Serial.println("Debugged flipdot!");
- }
- delay(20);
- // set alarm for display reset
- dt = clock.getDateTime();
- byte minu = dt.minute;
- byte sec = dt.second + len;
- byte hou = dt.hour;
- if(command == TYPE_RESET || command == TYPE_CHANGE_TIME || command == TYPE_DEBUG) { // no changeable length for these types
- sec = dt.second + 2;
- }
- while(sec > 59) {
- minu++;
- sec -= 60;
- }
- while(minu > 59) {
- hou++;
- minu -= 60;
- }
- oldDay = dt.day; // prevent midnight debug if day was changed (see clock displaying)
- clock.setAlarm1(dt.day, hou, minu, sec, DS3231_MATCH_DT_H_M_S);
- process = STATE_PROCESSED;
- return;
- }
- // show clock if nothing else is currently being displayed
- if((clock.isAlarm2() || configChange) && (process != 1 && process != 2 && process != 3)) {
- // convert time into displayable text and add zeros
- dt = clock.getDateTime();
- char hour[3] = "";
- itoa(dt.hour, hour, 10);
- char minute[3] = "";
- itoa(dt.minute, minute, 10);
- char month[3] = "";
- itoa(dt.month, month, 10);
- char day[3] = "";
- itoa(dt.day, day, 10);
- if(dt.day != oldDay) { // run debug at midnight
- debug();
- oldDay = dt.day;
- }
- if(strlen(hour) == 1) {
- char num = hour[0];
- hour[0] = '0';
- hour[1] = num;
- }
- if(strlen(minute) == 1) {
- char num = minute[0];
- minute[0] = '0';
- minute[1] = num;
- }
- if(strlen(month) == 1) {
- char num = month[0];
- month[0] = '0';
- month[1] = num;
- }
- if(strlen(day) == 1) {
- char num = day[0];
- day[0] = '0';
- day[1] = num;
- }
- // array containing data to display (conversion of chars to number from array)
- boolean (*data[])[3] = {
- numbers[((byte) hour[0]) - 48],
- numbers[((byte) hour[1]) - 48],
- colon,
- numbers[((byte) minute[0]) - 48],
- numbers[((byte) minute[1]) - 48],
- numbers[((byte) day[0]) - 48],
- numbers[((byte) day[1]) - 48],
- dot,
- numbers[((byte) month[0]) - 48],
- numbers[((byte) month[1]) - 48]
- };
- // display the numbers at given positions from position array
- for(byte i = 0; i < 10; i++) {
- for(byte j = 0; j < 5; j++) {
- for(byte k = 0; k < 3; k++) {
- if(data[i][j][k]) {
- setDot(positions[i][0] + k + 1, positions[i][1] + j + 1);
- }
- else {
- resetDot(positions[i][0] + k + 1, positions[i][1] + j + 1);
- }
- delay(5);
- }
- }
- }
- configChange = false; // reset update mode (don´t update another time)
- }
- }
- //i2c receive
- void receiveEvent(int howMany) {
- if(process == STATE_READ_DATA || process == STATE_PROCESSED) { // only one block of data can be displayed at the same time, no queue
- return;
- }
- char arg[5] = ""; // simple arguments
- while(Wire.available() > 0) {
- char c = Wire.read();
- count++; // represents the position in array for arguments
- if(process == STATE_WAITING) { // first step
- if(count == 0) {
- command = c;
- }
- else if(count > 0 && count < 5) { // set length/offset argument
- arg[count - 1] = c;
- }
- else if(count > 4) {
- // reconstruct long from 4 bytes (arg array)
- len = 0b00000000000000000000000000000000;
- byte multiplier = 0;
- for(byte i = 0; i < 32; i++) {
- if(i % 8 == 0 && i != 0) {
- multiplier++;
- }
- if(((arg[multiplier] >> (i - multiplier * 8)) & 1) == 1) {
- bitSet(len, i);
- }
- }
- // update for next step
- process = STATE_READ_HEADER;
- count = -1;
- }
- }
- else if(process == STATE_READ_HEADER) { // second step
- if(command == TYPE_IMAGE) {
- if(count == 42) {
- // update for processing
- count = -1;
- process = STATE_READ_DATA;
- }
- else {
- if(count < 42 && count > -1) {
- text[count] = c; // write bytes to text array
- }
- }
- }
- else if(command == TYPE_CHANGE_TIME) {
- if(c == '\0') {
- // reconstruct time (long) from 4 bytes (arg array)
- unix = 0b00000000000000000000000000000000;
- byte multiplier = 0;
- for(byte i = 0; i < 32; i++) {
- if(i % 8 == 0 && i != 0) {
- multiplier++;
- }
- if(((arg[multiplier] >> (i - multiplier * 8)) & 1) == 1) {
- bitSet(unix, i);
- }
- }
- // update for processing
- count = -1;
- process = STATE_READ_DATA;
- }
- else {
- if(count < 4 && count > -1) {
- arg[count] = c; // write new time to arg array
- }
- }
- }
- else if(command == TYPE_RESET || command == TYPE_DEBUG) {
- // update for processing
- count = -1;
- process = STATE_READ_DATA;
- }
- }
- }
- }
- // debug display
- void debug() {
- for(byte i = 18; i >= 3; i -= 3) {
- setAll(i - 3);
- delay(100);
- resetAll(i - 3);
- delay(100);
- }
- }
- Ethernet arduino code:
- #include <SPI.h>
- #include <Ethernet.h>
- #include <Wire.h>
- #define RESET 2
- byte mac[] = {
- 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
- };
- EthernetServer server(80);
- void setup() {
- // init reset pin (resets display when low)
- pinMode(RESET, OUTPUT);
- digitalWrite(RESET, HIGH);
- Serial.begin(9600);
- Wire.begin();
- Ethernet.begin(mac);
- server.begin();
- Serial.print("Flipdot Server is at ");
- Serial.println(Ethernet.localIP());
- }
- void loop() {
- EthernetClient client = server.available();
- if (client) {
- Serial.println();
- char arg[350] = "";
- boolean currentLineIsBlank = true;
- byte commandPos = 0;
- while (client.connected()) {
- if (client.available()) {
- char c = client.read();
- // write data to array
- if(c == '/' && commandPos == 0) {
- commandPos = 1;
- }
- else if(c == ' ' && commandPos == 1) {
- commandPos = 2;
- }
- else if(commandPos == 1) {
- char str[2] = {c, '\0'};
- strcat(arg, str);
- }
- if (c == '\n' && currentLineIsBlank) {
- client.println("HTTP/1.1 200 OK");
- client.println("Content-Type: text/html");
- client.println("Access-Control-Allow-Origin: *");
- client.println("Connection: close");
- client.println();
- client.println("<!DOCTYPE HTML>");
- client.println("<html>");
- client.println("Request answered");
- client.println("</html>");
- break;
- }
- if (c == '\n') {
- currentLineIsBlank = true;
- } else if (c != '\r') {
- currentLineIsBlank = false;
- }
- }
- }
- delay(1);
- client.stop();
- if(arg[0] == 'x') { // hard-reset display
- digitalWrite(RESET, LOW);
- delay(10);
- digitalWrite(RESET, HIGH);
- return;
- }
- Serial.println("Sending received data to flipdot...");
- Wire.beginTransmission(105);
- Wire.write(arg[0]); // write command
- // convert length string to 4 bytes of data
- char len[11] = "";
- for(byte i = 2; i < 12; i++) {
- len[i - 2] = arg[i];
- }
- len[10] = '\0';
- long lenL = atol(len);
- {
- byte multiplier = 0;
- byte buf = 0b00000000;
- for(byte i = 0; i < 32; i++) {
- if(i % 8 == 0 && i != 0) {
- multiplier++;
- Wire.write(buf);
- buf = 0b00000000;
- }
- if(((lenL >> i) & 1) == 1) {
- buf |= 1 << (i - multiplier * 8);
- }
- }
- Wire.write(buf);
- Wire.write('\0');
- }
- Serial.println("Sending header data...");
- byte state = Wire.endTransmission();
- Wire.beginTransmission(105);
- if(arg[0] == 'i') { // if data is image
- // convert 336 char string to 42 bytes of data
- byte multiplier = 0;
- byte buf = 0b00000000;
- for(int i = 0; i < strlen(arg) - 12; i++) {
- if(i % 8 == 0 && i != 0) {
- multiplier++;
- Wire.write(buf);
- buf = 0b00000000;
- if(multiplier % 32 == 0 && multiplier != 0) {
- byte s = Wire.endTransmission();
- if(s != 0) {
- state = 1;
- }
- Wire.beginTransmission(105);
- }
- if(multiplier == 42) {
- break;
- }
- }
- if(arg[i + 13] == '1') {
- buf |= 1 << (i - multiplier * 8);
- }
- }
- Wire.write('\0');
- Serial.println("Sending 42 bytes of image data...");
- }
- else if(arg[0] == 'c') { // if type is change time
- // convert time string to 4 bytes of data
- char unix[11] = "";
- for(byte i = 13; i < 23; i++) {
- unix[i - 13] = arg[i];
- }
- unix[10] = '\0';
- long unixL = atol(unix);
- byte multiplier = 0;
- byte buf = 0b00000000;
- for(byte i = 0; i < 32; i++) {
- if(i % 8 == 0 && i != 0) {
- multiplier++;
- Wire.write(buf);
- buf = 0b00000000;
- }
- if(((unixL >> i) & 1) == 1) {
- buf |= 1 << (i - multiplier * 8);
- }
- }
- Wire.write(buf);
- Wire.write('\0');
- }
- else if(arg[0] == 'r' || arg[0] == 'd') { // if type is reset or debug
- Wire.write('\0');
- }
- // send data and check for errors
- if(Wire.endTransmission() == 0 && state == 0) {
- Serial.println("All data successfully sent!");
- }
- else {
- Serial.println("An error occurred while sending the data!");
- }
- }
- }
Add Comment
Please, Sign In to add comment