I have gotten pretty much to the end of writing the initial version of the code, i just need to add the storing and retreaving data from an EEPROM
During the initialisation this code runs, as far as I know the Put works - I haven't gotten to testing that bit yet
During testing the serial terminal will print "Stering", "Reading EEPROM" and then stop. The connected LCD does not update and neither the variable resitor or encoder have an effect.
If the EEPROM.get commands are commented out I get the full set of serial print ->
Starting
Reading EEPROM
EEPROM: 150
Done reading EEPROM
This is as expected, the LCD updates and the controls function as they should.
To save some reading, directions and sequences are byte values while DELAYVAL is an int value. Code is writen using arduino 1.8.19 and uploaded via teensy loader 1.56
Complete code:
During the initialisation this code runs, as far as I know the Put works - I haven't gotten to testing that bit yet
During testing the serial terminal will print "Stering", "Reading EEPROM" and then stop. The connected LCD does not update and neither the variable resitor or encoder have an effect.
If the EEPROM.get commands are commented out I get the full set of serial print ->
Starting
Reading EEPROM
EEPROM: 150
Done reading EEPROM
This is as expected, the LCD updates and the controls function as they should.
To save some reading, directions and sequences are byte values while DELAYVAL is an int value. Code is writen using arduino 1.8.19 and uploaded via teensy loader 1.56
Code:
if (temp > 5){
//eeprom unused store defaults
EEPROM.put(store_direct, directions);
EEPROM.put(store_seq, sequences);
EEPROM.put(store_delay1, DELAYVAL);
} else {
Serial.println("Reading EEPROM"); //show reading
EEPROM.get(store_direct, directions);
EEPROM.get(sequences, store_seq);
EEPROM.get(DELAYVAL, store_delay1);
Serial.print("EEPROM: "); //show value read
Serial.println(DELAYVAL);
}
Serial.println("Done reading EEPROM"); //show done reading of EEPROM
Complete code:
Code:
#include <OctoWS2811.h>
#include <LiquidCrystal.h>
#define ENCODER_OPTIMIZE_INTERRUPTS
#include <Encoder.h>
#include <EEPROM.h>
//const int rs = 14, en = 15, d4 = 16, d5 = 17, d6 = 18, d7 = 19;
//const int rs = 12, en = 11, d4 = 10, d5 = 9, d6 = 8, d7 = 7;
const int rs = 10, en = 11, d4 = 18, d5 = 17, d6 = 16, d7 = 15;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
const int ledsPerStrip = 216; //one strip of 216
DMAMEM int displayMemory[ledsPerStrip * 6];
int drawingMemory[ledsPerStrip * 6];
const int config = WS2811_GRB | WS2811_800kHz;
OctoWS2811 pixels(ledsPerStrip, displayMemory, drawingMemory, config);
//upper case R,G,B set the colour
uint16_t R = 255;
uint16_t B = 0;
uint16_t G = 0;
long all_colors = 79867;
//lower case r,g,b is manipulated but the bright function and should not be manually
//these are to allow brightness control
byte r;
byte g;
byte b;
#define bright_var A9
byte Brightness = 65;
int new_bright = 0;
byte old_bright = 0;
int upHyst_bright = 0;
int loHyst_bright = 0;
bool force_bright = false;
int static_val = 0;
uint16_t i = 0;
uint16_t j = 0;
const byte rainbow_1 = 0;
const byte rainbow_2 = 1;
const byte brutal_rainbow = 2;
const byte static_colour = 3;
const byte just_white = 4;
const byte colour_change = 5;
#define clk 0
#define dt 1
#define sw 3
Encoder knob(clk, dt);
byte positionknob = 0;
unsigned long enc_millis;
int counter = 0;
int old_pos = 0;
int new_pos = 0;
int menu_pos = 0;
int sub_pos = 0;
bool encoder_bool = false;
byte encoder_count = 0;
byte menu_pointer = 0;
byte directions = 0;
byte sequences = 0;
int DELAYVAL = 150;
bool menu_bool = false;
bool sub_bool = false;
bool done_bool = false;
bool fixed_bool = false;
unsigned long last_press;
const byte store_direct = 0;
const byte store_seq = 1;
const byte store_delay1 = 3;
const byte store_delay2 = 4;
byte bottom_ring = 0; //this is the only set of LED at are access in sequence
byte lower_riser[] = { 36, 99, 117, 152, 62, 80}; //six lower risers - 3 up, 3 down
byte middle_ring[] = { 45, 63, 108, 135}; //middle ring only has 4 address
byte upper_riser[] = {153, 126, 81, 207, 206, 98}; //six upper risers - 4 up, 2 down
byte top_ring[] = {162, 171, 180, 189}; //top ring only has 4 addresses
byte pattern_val = 0;
byte sub_pointer = 0;
/*
byte pattern_0[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21}; //bottom to top
byte pattern_1[] = {21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; //top to bottom
byte pattern_2[] = {1,21,2,20,3,19,4,18,5,17,6,16,7,15,8,14,9,13,10,12,11}; //bottom/top to middle
byte pattern_3[] = {11,10,12,9,13,8,14,7,15,6,16,5,17,4,18,3,19,2,20,1,21}; //middle to top/bottom
//replaced by 2D array below
*/
//Pattern 2D array
byte patterns [][21] = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21},
{21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
{1, 21, 2, 20, 3, 19, 4, 18, 5, 17, 6, 16, 7, 15, 8, 14, 9, 13, 10, 12, 11},
{11, 10, 12, 9, 13, 8, 14, 7, 15, 6, 16, 5, 17, 4, 18, 3, 19, 2, 20, 1, 21}
};
//values for a brutal rainbow efect - whish i could find a smoother way to do this.
byte rainbow_r[] = {2, 44, 86, 128, 170, 212, 254, 254, 212, 170, 128, 86, 44, 2, 0, 0, 0, 0, 0, 0, 0};
byte rainbow_g[] = {0, 0, 0, 0, 0, 0, 0, 2, 44, 86, 128, 170, 212, 254, 254, 212, 170, 128, 86, 44, 2};
byte rainbow_b[] = {254, 212, 170, 128, 86, 44, 2, 0, 0, 0, 0, 0, 0, 0, 2, 44, 86, 128, 170, 212, 254};
#define speed_curs 10
#define bright_curs 0
void setup() {
pinMode(bright_var, INPUT);
pinMode(rs, OUTPUT);
pinMode(en, OUTPUT);
pinMode(d4, OUTPUT);
pinMode(d5, OUTPUT);
pinMode(d6, OUTPUT);
pinMode(d7, OUTPUT);
attachInterrupt (digitalPinToInterrupt(clk), encoder, CHANGE);
attachInterrupt (digitalPinToInterrupt(sw), switch_press, RISING);
Serial.begin(115200);
delay(1000);
Serial.println("Starting");
pixels.begin();
set_bright(); //use this to allow for brightness control instead of pixels.show()
byte temp = EEPROM.read(store_direct);
if (temp > 5){
//eeprom unused store defaults
EEPROM.put(store_direct, directions);
EEPROM.put(store_seq, sequences);
EEPROM.put(store_delay1, DELAYVAL);
} else {
Serial.println("Reading EEPROM");
EEPROM.get(store_direct, directions);
EEPROM.get(sequences, store_seq);
EEPROM.get(DELAYVAL, store_delay1);
Serial.print("EEPROM: ");
Serial.println(DELAYVAL);
}
Serial.println("Done reading EEPROM");
lcd.begin(16, 2);
titleLCD();
speed_print();
}
void loop() {
switch (sequences){
case rainbow_1: //rainbow 1
for (j = 0; j < 255; j++){
Wheel((i+j) & 255);
for (byte i = 1; i < 22; i++){
set_Leds(i);
change_bright(); //see if brightness has been changed
//set_bright(); //this contain pixels.show
if (sequences != rainbow_1){
break;
}
}
for (int z = 0; z <= DELAYVAL; z++){
delay(1);
if (sequences != rainbow_1){
break;
}
}
delay(500);
if (sequences != rainbow_1){
break;
}
}
break;
case rainbow_2: //rainbow 2
//use this for smooth colour circle
for (j = 0; j < 255; j++){
for (byte i = 1; i < 22; i++){
Wheel((i+j) & 255);
set_Leds(patterns[pattern_val][i-1]);
change_bright(); //see if brightness has been changed
//set_bright(); //this contain pixels.show
for (int z = 0; z <= DELAYVAL; z++){
delay(1);
if (sequences != rainbow_2){
break;
}
}
if (sequences != rainbow_2){
break;
}
}
if (sequences != rainbow_2){
break;
}
}
break;
case brutal_rainbow: //brutal rainbow
for (j = 1; j < 22; j++){
for (i = 1; i < 22; i++){
//i+j then wrap round after 21
byte q = i+j;
if (q >= 22){
q -= 21;
}
R = rainbow_r[q-1];
G = rainbow_g[q-1];
B = rainbow_b[q-1];
set_Leds(patterns[pattern_val][i-1]);
change_bright();
//set_bright();
for (int z = 0; z <= DELAYVAL; z++){
delay(1);
if (sequences != brutal_rainbow){
break;
}
}
if (sequences != brutal_rainbow){
break;
}
}
if (sequences != brutal_rainbow){
break;
}
}
break;
case static_colour: //static
for (i = 1; i < 22; i++){
Wheel(static_val);
set_Leds(i);
change_bright();
}
break;
case just_white: //just white
R = 255;
G = 255;
B = 255;
for (i = 1; i < 22; i++){
set_Leds(i);
change_bright();
}
break;
case colour_change: //colour change
if (R == 255 && G == 255 && B == 255){
R = 255;
G = 0;
B = 0;
}
for (i = 1; i < 22; i++) {
byte q = patterns[pattern_val][i - 1];
//delay(DELAYVAL);
for (int z = 0; z <= DELAYVAL; z++){
set_Leds(q);
change_bright();
//set_bright();
delay(1);
if (sequences != colour_change){
break;
}
}
if (sequences != colour_change){
break;
}
}
if (R == 255) {
R = 0;
B = 255;
} else if (B == 255) {
B = 0;
G = 255;
} else {
G = 0;
R = 255;
}
break;
}
}
//*****************************************
//**********LED Control Functions**********
//*****************************************
void change_bright() {
new_bright = analogRead(bright_var);
if (new_bright < loHyst_bright || new_bright > upHyst_bright || force_bright == true) {
force_bright = false;
Brightness = map(new_bright, 0, 1023, 10, 255);
loHyst_bright = new_bright - 10; //give the ADC hysterasis
upHyst_bright = new_bright + 10;
if (menu_bool == false) { //if not in a menu, updatye the display
lcd.setCursor(0, 1);
lcd.print(" "); //clear small section of display
lcd.setCursor(bright_curs, 1);
long temp = map(new_bright, 0, 1023, 0, 100);
lcd.print(temp); //map to a percetnage - not quite how it work but whatever
}
}
set_bright(); //this conatins pixels.show(); so no need to to call it again
}
void set_Leds(byte No) {
byte mode = 0;
if (No == 1) mode = 1;
if ((No >= 2) && (No <= 10)) mode = 2;
if (No == 11) mode = 3;
if ((No >= 12) && (No <= 20)) mode = 4;
if (No == 21) mode = 5;
switch (mode) {
case 1 :
for (byte n = 0; n < 36; n++) {
pixels.setPixel(n, r, g, b);
}
break;
case 2:
for (byte n = 0; n < 3; n++) {
pixels.setPixel(lower_riser[n] - 2 + No, r, g, b);
}
for (byte n = 3; n < 6; n++) {
pixels.setPixel(lower_riser[n] + 2 - No, r, g, b);
}
break;
case 3:
for (byte n = 0; n < 9; n++) {
pixels.setPixel(middle_ring[0] + n, r, g, b);
pixels.setPixel(middle_ring[1] + n, r, g, b);
pixels.setPixel(middle_ring[2] + n, r, g, b);
pixels.setPixel(middle_ring[3] + n, r, g, b);
}
break;
case 4:
for (byte n = 0; n < 4; n++) {
pixels.setPixel(upper_riser[n] - 12 + No, r, g, b);
}
for (byte n = 4; n < 6; n++) {
pixels.setPixel(upper_riser[n] + 12 - No, r, g, b);
}
break;
case 5:
for (int n = 0; n < 9; n++) {
pixels.setPixel(top_ring[0] + n, r, g, b);
pixels.setPixel(top_ring[1] + n, r, g, b);
pixels.setPixel(top_ring[2] + n, r, g, b);
pixels.setPixel(top_ring[3] + n, r, g, b);
}
break;
default:
break;
}
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
R = 255 - WheelPos * 3;
G = 0;
B = WheelPos * 3;
//set_bright();
return;
}
if (WheelPos < 170) {
WheelPos -= 85;
R = 0;
G = WheelPos * 3;
B = 255 - WheelPos * 3;
//set_bright();
return;
}
WheelPos -= 170;
R = WheelPos * 3;
G = 255 - WheelPos * 3;
B = 0;
//set_bright();
return;
}
void set_bright() {
r = (R * Brightness) >> 8;
g = (G * Brightness) >> 8;
b = (B * Brightness) >> 8;
pixels.show();
}
//*****************************************
//********End LED Control Functions********
//*****************************************
//************************
//**********ISRs**********
//************************
void encoder() {
detachInterrupt (digitalPinToInterrupt(clk));
//Serial.print("menu_bool: ");
//Serial.println(menu_bool);
new_pos = knob.read();
if (encoder_count >= 2) {
if (new_pos > old_pos) {
if (menu_bool == false) {
DELAYVAL++;
if (DELAYVAL > 1000) {
DELAYVAL = 1000;
}
speed_print();
} else {
menu_pos++;
if (menu_bool == true && sub_bool == false) {
main_titles();
} else {
sub_menus();
}
}
} else if (new_pos < old_pos) {
if (menu_bool == false) {
DELAYVAL--;
if (DELAYVAL <= 1) {
DELAYVAL = 1;
}
speed_print();
} else {
menu_pos--;
if (menu_bool == true && sub_bool == false) {
main_titles();
} else {
sub_menus();
}
}
}
old_pos = new_pos;
encoder_count = 0;
} else {
encoder_count ++;
}
//Serial.print("menu_pos: ");
//Serial.print(menu_pos);
//Serial.print(" : ");
//Serial.println(new_pos);
//Serial.print("Delayval: ");
//Serial.println(DELAYVAL);
attachInterrupt (digitalPinToInterrupt(clk), encoder, CHANGE);
}
void switch_press() {
//need to either enter the menu or select the menu
Serial.print("menu_bool: ");
Serial.println(menu_bool);
if (millis() - last_press > 500) {
if (menu_bool == true && sub_bool == true && done_bool == false) {
//if the button is pressed, set the sub bool to false
Serial.println("Exit sub");
sub_bool = false;
lcd_main_menu();
} else if (menu_bool == true && sub_bool == false && done_bool == false) {
sub_bool = true;
lcd.clear();
lcd.setCursor(0, 0);
//sequence
if (sub_pointer == 0) {
lcd.print("Sequences");
}
//direction
if (sub_pointer == 1) {
lcd.print("Direction");
}
//fixed colour
if (sub_pointer == 2) {
lcd.print("Fixed Colour");
}
//you in the main menu, the button has been pressed
//menu 2 (fixed colour needs bool checked before calling sub menu)
} else if ( menu_bool == true && done_bool == true && sub_bool == false) {
menu_bool = false; //reset the menu notifier
done_bool = false;
knob.write(DELAYVAL);
Serial.println("Print title screen");
titleLCD();
speed_print();
force_bright = true;
} else {
menu_bool = true; //if all of the above is not true, then just entered here
lcd_main_menu();
menu_pos = 0;
knob.write(0);
main_titles();
}
last_press = millis();
}
Serial.println("Leaving switch_press");
}
//************************
//********End ISRs********
//************************
void titleLCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Running");
}
void speed_print() {
//this does not work while in a menu so no need to check for menu access
lcd.setCursor(speed_curs, 1);
lcd.print(" "); //should only ever be 4 numbers
lcd.setCursor(speed_curs, 1);
lcd.print(DELAYVAL); //the time dleay in ms - this may change in the future
}
void lcd_main_menu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Menu");
}
void main_titles() {
done_bool = false; //switch this off, it will auto switch on everytime this is entered if the option is selected
if (menu_pos > 4) { //negate rollover and roll under
menu_pos = 4;
knob.write(menu_pos);
} else if (menu_pos < 0) {
menu_pos = 0;
knob.write(0);
}
if (menu_pos == 0) {
clear_bottom();
lcd.print("Sequences");
sub_pointer = 0;
}
if (menu_pos == 1) {
clear_bottom();
lcd.print("Direction");
sub_pointer = 1;
}
if (menu_pos == 2 && fixed_bool == true) {
clear_bottom();
lcd.print("Fixed colour");
sub_pointer = 2;
}
if (menu_pos == 3) {
clear_bottom();
lcd.print("Store");
sub_pointer = 4;
}
if (menu_pos == 4) {
clear_bottom();
lcd.print("Done");
done_bool = true;
}
Serial.print("Sub_pointer: ");
Serial.println(sub_pointer);
}
void clear_bottom() {
lcd.setCursor(0, 1);
for (byte x = 0; x < 17; x++) {
lcd.print(" ");
}
lcd.setCursor(0, 1);
}
void sub_menus() {
//sub menu pointer to select the sub menu and the encoder value finds the menu requested
clear_bottom();
Serial.println("Sub menus called");
if (sub_pointer == 0) {
//sequences
//0-4
//rainbow all at once, rainbow in direction, end to end rainbow, static colour, just white
if (menu_pos > 5){
menu_pos = 5;
knob.write(menu_pos);
}
if (menu_pos < 0){
menu_pos = 0;
knob.write(menu_pos);
}
sequences = menu_pos;
//now display what has been selected
if (menu_pos == 0){
lcd.print("Rainbow 1");
}else if (menu_pos == 1){
lcd.print("Rainbow 2");
}else if (menu_pos == 2){
lcd.print("Brutal Rainbow");
}else if (menu_pos == 3){
lcd.print("static Color");
}else if (menu_pos == 4){
lcd.print("Just White");
}else{
lcd.print("Color Change");
}
if (menu_pos == 3){
fixed_bool = true;
}else{
fixed_bool = false;
}
Serial.print("sequence: ");
Serial.println(menu_pos);
}
if (sub_pointer == 1) {
//direction
//4 different directions 0-3
if (menu_pos > 3){
menu_pos = 3;
knob.write(menu_pos);
}
if (menu_pos < 0){
menu_pos = 0;
knob.write(menu_pos);
}
pattern_val = menu_pos;
if (menu_pos == 0){
lcd.print("Up");
}else if(menu_pos == 1){
lcd.print("Down");
}else if (menu_pos == 2){
lcd.print("Inward");
}else{
lcd.print("Outward");
}
}
if (sub_pointer == 2) {
//fixed colour
//cycle through the colour wheel
if (menu_pos < 0){
menu_pos = 255;
knob.write(menu_pos);
}
if (menu_pos > 255){
menu_pos = 0;
knob.write(menu_pos);
}
static_val = menu_pos;
lcd.print(menu_pos);
//set static bool
Wheel(menu_pos);
lcd.setCursor(5,1);
lcd.print(R);
lcd.setCursor(9,1);
lcd.print(G);
lcd.setCursor(13,1);
lcd.print(B);
}
if (sub_pointer == 4){
//store stuff to the eeprom
Serial.println("Writing EEPROM");
EEPROM.put(store_direct, directions);
EEPROM.put(store_seq, sequences);
EEPROM.put(store_delay1, DELAYVAL);
//EEPROM.write(store_delay1, DELAYVAL >> 8);
//EEPROM.write(store_delay1 + 1, DELAYVAL & 0xFF);
Serial.print("Stored");
lcd.print("Stored");
}
}