//custom letter and symbol libary
#include "symbols.h"
//ASCII ARRAY user input that has been converted to ASCII
int ASCIIArray[20];
//Declare pins
int cols[8] = {22,24,26,28,30,32,34,36};
int rows[8] = {23,25,27,29,31,33,35,37};
//EEPROM lib
#include <EEPROM.h>
String inputString = "Edmund"; //inpuiitstring used in serial event, placeholder for led
bool sendit = true; //determines if user pressed enter during serial event
//interrrupt button
#include "OneButton.h"
#define PIN_INPUT 3
OneButton button(PIN_INPUT, true);
// save the millis when a press has started.
unsigned long pressStartTime;
int presslength; //time that is button pressed
int direction = 0; //0 is right to left, 1 is left to right
void setup() {
Serial.begin(115200);
Serial.println("Enter New text via serial. (Max 20, Leters only)");
//defines the pin modes for the led array
for (int i = 0; i < 8; i++) {
pinMode(cols[i], OUTPUT);
pinMode(rows[i], OUTPUT);
}
ledreset();
attachInterrupt(digitalPinToInterrupt(PIN_INPUT), checkTicks, CHANGE);
button.attachClick(singleClick);
button.attachDoubleClick(doubleClick);
button.setPressTicks(800); // time until longpress
button.attachLongPressStart(pressStart);
button.attachLongPressStop(pressStop);
}
void loop() {
getInput(); //emprom inside
read4eeprom(); //updates ascii with eeprom
if (direction == 0) {
RightToLeft(50);
} else {
LeftToRight(50);
}
}
//write to eeprom
void write2eeprom() {
for (int i = 0; i < 20; i++) {
EEPROM.write(i, 255); //resets eeprom - moveed outside of if as eeprom would remember non-over written vars
if (ASCIIArray[i]) { //eg first msg "edmund" second msg "cake", result "cakend"
EEPROM.write(i, ASCIIArray[i]); //write eeprom address
}
}
}
//read from eeprom
void read4eeprom() {
for (int i = 0; i < 20; i++) {
if (EEPROM.read(i) != 255) { //skips assignment of value if read value is 255 (empty)
ASCIIArray[i] = EEPROM.read(i); //without the skip the display wont cycle back
}
}
}
//scrolling text function Right 2 left
void RightToLeft(int speed) {
int loopcycle; //loop cycle is used in speed setting
int cycle = 14; //starting point for the first letter
int letter1 = ASCIIArray[0] - 65; //ascii array contains ascii, we - 65 to get bitmap equivatlent 0 = a, 1 = b
int letter2 = ASCIIArray[1] - 65;
int add1 = 1; //counter cycle for each passed letter
while (1) {
button.tick();
// % speed determines the times that the cycle is true. This sets speed, lower = faster
if (loopcycle % speed == 0) {
//changes position of the display by 2
cycle = cycle - 2;
}
//when we have counted the number of letters in input + 1 we reset the text and add1 var
if (add1 == getASCIIcount() + 1) {
add1 = 1;
letter1 = ASCIIArray[0] - 65;
letter2 = ASCIIArray[1] - 65;
}
//when text is off screen 2nd display becomes 3rd. 1st display becomes 2nd
if (cycle == -14) {
//end of cycle
add1 = add1 + 1;
letter1 = letter2;
letter2 = ASCIIArray[add1] - 65;
//Serial.println(add1);
cycle = 0;
if (add1 == getASCIIcount() + 1) { //instead of cycle position 0 we goto 14 when reseting text, prevents letter in middle
break; //break added so the while loop ends after a single message
}
loopcycle++;
}
printletter(letter1, cycle);
printletter(letter2, cycle + 14);
loopcycle++;
}
}
//Scrolling text function left 2 right
void LeftToRight(int speed) {
int loopcycle; //loop cycle is used in speed setting
int cycle = 0; //starting point for the first letter
int letter1 = ASCIIArray[getASCIIcount()] - 65; //ascii array contains ascii, we - 65 to get bitmap equivatlent 0 = a, 1 = b
int letter2 = ASCIIArray[getASCIIcount()-1] - 65;
int add1 = getASCIIcount()-1; //counter cycle for each passed letter
while (1) {
button.tick();
//Serial.println(cycle);
// % speed determines the times that the cycle is true. This sets speed, lower = faster
if (loopcycle % speed == 0) {
//changes position of the display by 2
cycle = cycle + 2;
}
//when we have counted the number of letters in input + 1 we reset the text and add1 var
if (add1 == -getASCIIcount()) {
add1 = getASCIIcount()-1;
letter1 = ASCIIArray[getASCIIcount()] - 65;
letter2 = ASCIIArray[getASCIIcount()-1] - 65;
}
//when text is off screen 2nd display becomes 3rd. 1st display becomes 2nd
if (cycle == 14) {
//end of cycle
add1 = add1 - 1;
letter1 = letter2;
letter2 = ASCIIArray[add1] - 65;
cycle = 0;
//Serial.println(add1);
if (add1 == -2) { //instead of cycle position 0 we goto 14 when reseting text, prevents letter in middle
break; //break added so the while loop ends after a single message
}
loopcycle++;
}
printletter(letter1, cycle);
printletter(letter2, cycle - 14);
loopcycle++;
}
}
// display function, letter is the number corresponding to the 3d bitmap array and offset is the position of display
void printletter(int letter, int offset) {
for (int i = 0; i < 8; i++) { //Loops cycle through for each letter
for (int j = 0; j < 8; j++){
//int readbyte = a[i][j];
int readbyte = symbols[letter][i][j];
digitalWrite(rows[i],HIGH);
digitalWrite(cols[j] + offset,!readbyte);
}
ledreset();
}
}
//function to find the length of actual text to display
int getASCIIcount() {
int count = 0;
for (int cc = 0; cc < 20; cc++) {
if (ASCIIArray[cc] != 0) {
count++;
}
}
return count;
}
//reset leds
void ledreset() {
for (int i = 0; i < 8; i++) {
digitalWrite(cols[i], HIGH);
digitalWrite(rows[i], LOW);
}
}
void getInput() {
String input;
char INarray[20];
if (sendit == true) {
sendit = false;
input = inputString;
input.toUpperCase();
inputString = "";
for (int j = 0; j < 20; j++) {
ASCIIArray[j] = 0;
INarray[j] = 0;
}
//convert string to char array, +1 to the length at it starts from 0
input.toCharArray(INarray, input.length() + 1);
//char to ascii conversion, +48 is used to bump it up to the expected values
for (int i = 0; i < 20; i++) {
if (isAlpha(INarray[i])) { //isAlpha check required as unknown vars are appended to ascii array
ASCIIArray[i] = (INarray[i] - '0') + 48;
//Serial.println(i);
} else {
ASCIIArray[i] = 0;
}
}
write2eeprom(); //writes new msg to eeprom
}
}
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char key = (char)Serial.read();
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (key == '\n') {
sendit = true;
Serial.println(inputString);
}
if (isAlpha(key)) {
if (inputString.length() < 20) { //prevents not alpha and too long inputs
inputString += key;
}
}
}
}
//debug - tests all leds
void dotcycle() {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++){
ledreset();
digitalWrite(rows[i],HIGH);
digitalWrite(cols[j],LOW);
delay(50);
}
}
}
void checkTicks() {
button.tick();
}
void singleClick() {
} // singleClick
void doubleClick() {
}
void pressStart() {
pressStartTime = millis() - 800; // as set in setPressTicks()
}
// function called after long press
void pressStop() {
presslength = millis() - pressStartTime;
Serial.print("Button Pressed for:"); Serial.println(presslength);
if (presslength >= 800 && presslength <= 1200) {
//right 2 left
direction = 0;
} else if (presslength >= 1800 && presslength <= 2200) {
//left 2 right
direction = 1;
} else {
direction = direction;
//stay
}
}