EEPROM.get causing hangs Teensy 3.2

orac

Member
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


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");
  }
}
 
Code:
 } else {
    Serial.println("Reading EEPROM");        //show reading
    EEPROM.get(store_direct, directions);
[B]    EEPROM.get(sequences, store_seq);                [COLOR="#FF0000"]Address and data reversed here[/COLOR]
    EEPROM.get(DELAYVAL, store_delay1);[/B]
    Serial.print("EEPROM: ");               //show value read
    Serial.println(DELAYVAL);
  }
 
Thank you, knew it must have been something simple that I was overlooking - working perfectly now, thanks.
 
Back
Top