2

I'm working on arduino based RGB LED strip controller.
This simple schematic was used to control 12V channels via 5V PWM signal from arduino:
https://learn.adafruit.com/system/assets/assets/000/002/692/medium800/led_strips_ledstripfet.gif?1396785823
I have also connected an HC-05 bluetooth module to be able to control it using android phone.
Android application, created for this project, is sending 4 bytes to set mode, red, green and blue colors. It looks like {0,255,0,0} to set static red color, {1,0,0,0} to start fade mode and {2,0,0,0} to start blink mode.

Here is my first demo video of this project: click here.

The problem is that my code works perfectly on Arduino Mega 1280, but when I use Arduino Nano it works only with manual mode and blink mode. If I send {1,0,0,0} to turn on fade mode, LED strip starts to increase random color brightness and stops, before it gets to max value. In a moment LED strip turns off and doesn't react to bluetooth commands. Reset button helps in this situation.

I'm not sure, but I think there is not enough SRAM (only 2KB) on Arduino Nano to process fade mode data.

Source code:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(12, 13);

#define REDPIN 6
#define GREENPIN 3
#define BLUEPIN 9

#define FADESPEED 10
#define PANICSPEED 425

//0 - red
//1 - green
//2 - blue
int fadeColor = 0;
int panicColor = 0;

//values (brightness) for red, green and blue colors [0; 255]
int colors[] = {0, 0, 0};

long previousTime = 0;

//0 - manual, 1 - fade, 2 - blink
int ledMode = 0;

int fadeAmount = 1;

//if color is selected, it'll change brightness;
//when we got 0 or 255 brightness we'll change
//this flag and select next color in loop()
boolean fadeColorSelected = false;

void setup() {
  pinMode(REDPIN, OUTPUT);
  pinMode(GREENPIN, OUTPUT);
  pinMode(BLUEPIN, OUTPUT);
  mySerial.begin(9600);

  randomSeed(0);
}

void loop() {
  long currentTime = millis();

  //data format - 4 bytes {mode, red, green, blue}
  if (mySerial.available() > 3) {
    ledMode = mySerial.read();
    int red = mySerial.read();
    int green = mySerial.read();
    int blue = mySerial.read();
    colors[0] = constrain(red, 0, 255);
    colors[1] = constrain(green, 0, 255);
    colors[2] = constrain(blue, 0, 255);
  }

  switch (ledMode) {
    //manual mode - just set received color on the led strip
    case 0:
      setColor();
      break;
    //fade mode - if color is selected, we'll 
    //increase/decrease it's brightness by fadeAmount
    case 1:
      if (currentTime - previousTime > FADESPEED) {
        //change color (we can't choose the same color as previous 
        //and we can't choose the color, if it's the last one,
        //because at least 1 color should be always ON
        if (!fadeColorSelected) {
          int randomColor = fadeColor;
          while (randomColor == fadeColor || isColorAlone(randomColor)) {
            randomColor = random(3);
          }
          fadeColor = randomColor;
          fadeColorSelected = true;
        }
        //depending on current brightness of selected color
        //we'll either increase, or decrease it's brightness
        if (colors[fadeColor] == 0) {
          fadeAmount = abs(fadeAmount);
        } else if (colors[fadeColor] == 255) {
          fadeAmount = -abs(fadeAmount);
        }
        colors[fadeColor] += fadeAmount;
        setColor();
        //when we got to max/min brightness, we should change current fadeColor
        if (colors[fadeColor] == 0 || colors[fadeColor] == 255) {
          fadeColorSelected = false;
        }
        previousTime = currentTime;
      }
      break;
    case 2:
      if (currentTime - previousTime > PANICSPEED) {
        int randomColor = panicColor;
        while (randomColor == panicColor || isColorAlone(randomColor)) {
          randomColor = random(3);
        }
        panicColor = randomColor;
        if (colors[panicColor] == 0) {
          colors[panicColor] = 255;
        } else {
          colors[panicColor] = 0;
        }
        setColor();
        previousTime = currentTime;
      }
      break;
  }
}

void setColor(int r, int g, int b) {
  analogWrite(REDPIN, r);
  analogWrite(GREENPIN, g);
  analogWrite(BLUEPIN, b);
}

void setColor() {
  analogWrite(REDPIN, colors[0]);
  analogWrite(GREENPIN, colors[1]);
  analogWrite(BLUEPIN, colors[2]);
}

boolean isColorAlone(int colorNumber) {
  if (colors[colorNumber] == 0)
    return false;
  for (int i = 0; i < 3; i++) {
    if (i != colorNumber && colors[i] > 0) {
      return false;
    }
  }
  return true;
}

Do you have any ideas why it happens?

If there is not enough SRAM, how can I optimize this code to solve the problem?

  • avr-size on the ELF says? – Ignacio Vazquez-Abrams Dec 7 '14 at 17:34
  • text 4770, data 22, bss 122, dec 4914, hex 1332 – Firago Dec 7 '14 at 17:55
  • (data + bss) is less than 2KB, but it does not include dynamic memory allocated from the heap at run time... – Firago Dec 7 '14 at 18:04
  • You don't have any heap allocation. And I certainly don't see more than about 40 bytes in locals from the stack at any time. – Ignacio Vazquez-Abrams Dec 7 '14 at 18:11
  • I agree with you, but I have no idea, what can be wrong with it – Firago Dec 7 '14 at 18:16

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.