0

I want to make a program that writes on the EEPROM some structs, the final device will take structs of RGB LED data:

typedef struct{
    unsigned char r;
    unsigned char g;
    unsigned char b;
} led_color;

I will have 16 LEDS and I need to keep the RGB data of each LED despite of powering off the Arduino, I have developed this functions:

void getColorValuesFromEEPROM(led_color *colorStructArray) { // Here I need to read all the data and store it in an array of structs with 16 positions
  int eedirection = 0;
  int i = 0;
  while (eedirection <= 16 * sizeof(led_color)) {
    EEPROM.get(eedirection, color[i]);
    i++;
    eedirection *= i * sizeof(led_color);
  }
}

void getSingleColorValueFromEEPROM(led_color *sing_color) { //Here I want to read only one struct that is stored in an arbitrary position(3700) the position could be anyone that doesn't interferes with the array data
  EEPROM.get(3700, sing_color);
}

void writeColorValuesToEEPROM(unsigned char led_number, led_color *color) { //Here I need to write the struct data of the led_number given(from 1 to 16);
  int eedirection;
  eedirection = led_number * sizeof(led_color);
  EEPROM.update(eedirection, color);
}

void writeSingleColorValueToEEPROM(led_color *single) { //Here I want to write only one struct of data in the arbitary direction(3700)
  EEPROM.update(3700, single);
}

The problem is that my Arduino freezes when I try to read/write data with the functions above, here I paste the full code, it freezes in the setup():

ddj.c

#include "ddj.h"
#include <EEPROM.h>
#include <RotaryEncoder.h>
#include <MIDI.h>
#include <Adafruit_NeoPixel.h>

#define DATA_PIN 6  //DATA PIN OF THE RGB LEDS

#define runEvery(t) for (static uint16_t _lasttime;\
                         (uint16_t)((uint16_t)millis() - _lasttime) >= (t);\
                         _lasttime += (t))

RotaryEncoder encoder(18, 19); //Encoders are connected to pins 18-19 and 2-3 (A and B of each encoder)
RotaryEncoder encoder1(20, 21);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, DATA_PIN, NEO_GRB + NEO_KHZ800);

MIDI_CREATE_DEFAULT_INSTANCE();

led_color color[16];
led_color single_color;
unsigned char ledMode = 0;
bool ledState = LOW;
unsigned int interval = 500; //Interval in milliseconds of the Led Blinking mode
int potenciometro[6] = {A0, A1, A2, A3, A4, A5};  //The potentiometers are connected to A0, A1, A2 and A3
int valpot[6] = {0, 0, 0, 0, 0, 0};
int lastval[6] = {0, 0, 0, 0, 0, 0};
bool state[44] = {0};
bool laststate[44] = {0};

void getColorValuesFromEEPROM(led_color *colorStructArray) {
  int eedirection = 0;
  int i = 0;
  while (eedirection <= 16 * sizeof(led_color)) {
    EEPROM.get(eedirection, color[i]);
    i++;
    eedirection *= i * sizeof(led_color);
  }
}

void getSingleColorValueFromEEPROM(led_color *sing_color) {
  EEPROM.get(3700, sing_color);
}

void writeColorValuesToEEPROM(unsigned char led_number, led_color *color) {
  int eedirection;
  eedirection = led_number * sizeof(led_color);
  EEPROM.update(eedirection, color);
}

void writeSingleColorValueToEEPROM(led_color *single) {
  EEPROM.update(3700, single);
}

void setLedMode(unsigned char n) { // 0 - All On; 1 - All Off; 2 - Blink With Delay; 3 - On When Pressed
  ledMode = n;
}

void setSingleLed(unsigned char led_number, led_color colorStructArray) {
  strip.setPixelColor(led_number, colorStructArray.r, colorStructArray.g, colorStructArray.b);
  strip.show();
}

void setAllLeds(unsigned char mode) { // 0 - All On; 1 - All Off;
  if (mode = 0) {
    for (int i = 0; i < 16; i++) {
      strip.setPixelColor(i, single_color.r, single_color.g, single_color.b);
      strip.show();
    }
  } else if (mode = 1) {
    for (int i = 0; i < 16; i++) {
      strip.setPixelColor(i, 0, 0, 0);
      strip.show();
    }
  }
}

void pushbuttonsRead() {
  for (int i = 2; i < 14; i++) {
    state[i + 30] = digitalRead(i); //This statement read the state of the digital pin
    if (state[i + 30] != laststate[i + 30]) { //This two if conditionals make the interrupt and "debounce" the button so it only will send data when the state changes, and that state is LOW
      if (state[i + 30] == 0) {
        MIDI.sendNoteOn(i + 30, 127, 1); //This send the MIDI data---  NOTE 56, VELOCITY 127, CHANNEL 1
      }
    }
    laststate[i + 30] = state[i + 30];
  }
  for (int i = 22; i < 54; i++) { //32 BUTTONS
    state[i - 22] = digitalRead(i); //This statement read the state of the digital pin
    if (state[i - 22] != laststate[i - 22]) { //This two if conditionals make the interrupt and "debounce" the button so it only will send data when the state changes, and that state is LOW
      if (state[i - 22] == 0) {
        MIDI.sendNoteOn(i - 21, 127, 1); //This send the MIDI data---  NOTE 56, VELOCITY 127, CHANNEL 1
        if ((ledMode == 3) && (i >= 22 && i <= 38)) {
          setSingleLed(i - 22, color[i - 22]);
        }
      }
    }
    laststate[i - 22] = state[i - 22];
  }
}

void potentiometersRead() {
  for (int i = 0; i < 6; i++) {   //Here you read the potentiometers data, convert them from 10 bit(Arduino's ADC read resolution) to 7 bit (MIDI protocol resolution) and send them
    valpot[i] = analogRead(potenciometro[i]) >> 3;
    if (valpot[i] != lastval[i]) {
      MIDI.sendControlChange(i + 1, valpot[i], 1);
    }
    lastval[i] = valpot[i];
  }
}

void setup()
{
  //MIDI.begin(MIDI_CHANNEL_OMNI);  //Here the MIDI communication starts
  strip.begin();
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  for (int i = 30; i < 46; i++) {
    pinMode(i, INPUT_PULLUP);  //Set the pushbuttons pins as input with a PULLUP resistor
  }
  getSingleColorValueFromEEPROM(&single_color);
  //getColorValuesFromEEPROM(color);
}

void loop()
{
  if (ledMode == 0 || ledMode == 1) { //ALL ON AND ALL OFF MODES
    setAllLeds(ledMode);
  } else if (ledMode == 2) { //BLINK WITH DELAY MODE
    runEvery(interval) {
      if (ledState == LOW) {
        ledState = HIGH;
      }
      else {
        ledState = LOW;
      }
      setAllLeds(ledState);
    }
  }

  pushbuttonsRead();

  potentiometersRead();

  static int pos = 60;
  encoder.tick();

  int newPos = encoder.getPosition(); //Here you read the encoder position and if it has changed from the last time, you send it
  if (pos != newPos) {
    if (pos < newPos) {
      MIDI.sendControlChange(15, 1, 2);
    } else if (pos > newPos) {
      MIDI.sendControlChange(15, 127, 2);
    }
    pos = newPos;
  }
  static int pos1 = 60;
  encoder1.tick();

  int newPos1 = encoder1.getPosition();
  if (pos1 != newPos1) {
    if (pos1 < newPos1) {
      MIDI.sendControlChange(16, 1, 2);
    } else if (pos1 > newPos1) {
      MIDI.sendControlChange(16, 127, 2);
    }
    pos1 = newPos1;
  }
}

ddj.h

typedef struct{
    unsigned char r;
    unsigned char g;
    unsigned char b;
} led_color;

void getColorValuesFromEEPROM(led_color colorStructArray[]);

void getSingleColorValueFromEEPROM(led_color *sing_color);

void writeColorValuesToEEPROM(unsigned char led_number, unsigned char red, unsigned char green, unsigned char blue);

void writeSingleColorValueToEEPROM(unsigned char red, unsigned char green, unsigned char blue);

void setLedMode(unsigned char n);

void setSingleLed(unsigned char led_number, led_color colorStructArray[]);

void setAllLeds(unsigned char mode);

void pushbuttonsRead();
  • you can do EEPROM.put(0, color); and EEPROM.get(0, color); where color is your array of structs – Juraj Jun 9 '19 at 12:40
  • I can not find code that freezes. I can not find stack overflow or array out of bounds. There is something going on with EEPROM.get. You may not use a pointer there, only a full variable/struct/anything because it uses the size of that full variable/struct/anything. The color[i] might work but not the led_color *. Something else is perhaps a voltage drop when the led strip is initialized. What is the voltage of the 5v pin? – Jot Jun 9 '19 at 18:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.