Conflict between Neopixel BluetoothLE Libraries

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
fxmech
 
Posts: 90
Joined: Fri Mar 09, 2012 12:19 pm

Conflict between Neopixel BluetoothLE Libraries

Post by fxmech »

I am simply trying to merge to pieces of code together.
One is Bluefruit connection based on your great Guggenhat example
and the other is just a pattern program running on the adafruit neopixel library.
I tried switching my Bluetooth RDY pin from 2 to 3 on my nano and also tried changing the data pin for the neopixels but the neopixels fail to begin as soon as I include the line:

Adafruit_BLE_UART BTLEserial = Adafruit_BLE_UART(
ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);

Are these libraries incompatible with each other?

Heres the unfinished code.... The neopixel part works fine as long as I comment out the Bluetooth code:

Code: Select all

/*--------------------------------------------------------------------------
 GUGGENHAT: a Bluefruit LE-enabled wearable NeoPixel marquee.
 
 Requires:
 - Arduino-compatible microcontroller board.  Most mainstream ATmega-based
 boards (Uno, Micro, etc.) should work; cutting-edge boards (Teensy 3,
 Arduino Due, Netduino) are untested and likely not compatible.
 - Adafruit Bluefruit LE nRF8001 breakout: www.adafruit.com/products/1697
 - 4 Meters 60 NeoPixel LED strip: www.adafruit.com/product/1461
 - 3xAA alkaline cells, 4xAA NiMH or a beefy (e.g. 1200 mAh) LiPo battery.
 - Late-model Android or iOS phone or tablet running nRF UART or
 Bluefruit LE Connect app.
 - BLE_UART, NeoPixel, NeoMatrix and GFX libraries for Arduino.
 
 Written by Phil Burgess / Paint Your Dragon for Adafruit Industries.
 MIT license.  All text above must be included in any redistribution.
 --------------------------------------------------------------------------*/


#include <SPI.h>
#include <Adafruit_NeoPixel.h>
#include <Adafruit_BLE_UART.h>
#include "moving_pattern.h"
moving_pattern mp1;
moving_pattern mp2;
moving_pattern mp3;
moving_pattern mp4;
moving_pattern mp5;
moving_pattern mp6;
moving_pattern mp7;
int R=0;
int G=100;
int B=255;
int S=10;
uint32_t stripValues[144];//create array to store all led position values
#define num_LEDS 144
#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(num_LEDS, PIN, NEO_GRB + NEO_KHZ800);


// NEOPIXEL STUFF ----------------------------------------------------------

String          msgSum;
String          msgSumSafety;
int printFlag;
char peekVal;
uint8_t       msgSumLen        = 0;              // Empty message
char          msg[20]       = {  
  0};            // BLE 20 char limit + NUL
uint8_t       msgLen        = 0;              // Empty message

// Scrolling speed
unsigned long q;
// BLUEFRUIT LE STUFF-------------------------------------------------------

// CLK, MISO, MOSI connect to hardware SPI.  Other pins are configrable:
#define ADAFRUITBLE_REQ 10
#define ADAFRUITBLE_RST  9
#define ADAFRUITBLE_RDY  2 // Must be an interrupt pin

Adafruit_BLE_UART BTLEserial = Adafruit_BLE_UART(
ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);
aci_evt_opcode_t  prevState  = ACI_EVT_DISCONNECTED;

// UTILITY FUNCTIONS -------------------------------------------------------

// Given hexadecimal character [0-9,a-f], return decimal value (0 if invalid)
uint8_t unhex(char c) {
  return ((c >= '0') && (c <= '9')) ?      c - '0' :
  ((c >= 'a') && (c <= 'f')) ? 10 + c - 'a' :
  ((c >= 'A') && (c <= 'F')) ? 10 + c - 'A' : 0;
}
/*
// Read from BTLE into buffer, up to maxlen chars (remainder discarded).
 // Does NOT append trailing NUL.  Returns number of bytes stored.
 uint8_t readStr(char dest[], uint8_t maxlen) {
 int     c;
 uint8_t len = 0;
 while((c = BTLEserial.read()) >= 0) {
 if(len < maxlen) dest[len++] = c;
 }
 return len;
 }
 */
// MEAT, POTATOES ----------------------------------------------------------

void setup() {
  //Serial.begin(9600);
  strip.begin();
  // BTLEserial.begin();

  for (int i=0; i<strip.numPixels(); i++){//set all leds to off and load array of off values
    stripValues[i]=255;
    strip.setPixelColor(i, stripValues[i]); 
  }
  strip.show(); // Initialize all pixels to 'off'
  mp1.flag=1;
  mp2.flag=1;
  mp3.flag=1;
  mp4.flag=1;
  mp5.flag=1;
  mp6.flag=1;
  mp7.flag=1;


}

void loop() {

  unsigned long t = millis(); // Current elapsed time, milliseconds.
  // millis() comparisons are used rather than delay() so that animation
  // speed is consistent regardless of message length & other factors.

  BTLEserial.pollACI(); // Handle BTLE operations
  aci_evt_opcode_t state = BTLEserial.getState();

  // If connected, check for input from BTLE...
  if((state == ACI_EVT_CONNECTED) && BTLEserial.available()) {
    peekVal=BTLEserial.peek();
    if(peekVal == 'C') { // Color commands start with '/'
      char color[7];
      if(readStr(color, sizeof(color))==4) {
        // #RGB    4/4/4 RGB
        R=unhex(color[1]) * 31; // Expand to 8/8/8
        G=unhex(color[2]) * 31;
        B=unhex(color[3]) * 31;
        ;
      }

    }
    else
      if(peekVal == 'S') { // Color commands start with '/'
        char animSpeed[7];
        if(readStr(animSpeed, sizeof(animSpeed))==2) {
          // #RGB    4/4/4 RGB
          S=unhex(animSpeed[1]) * 31; // Expand to 8/8/8

        }
      }
  }


  // PROCEED TO ANIMATIONS
  loopAround(strip.Color(R, G, B),S,0,19,8, &mp1);
  loopAround(strip.Color(R, G, B),S,20,39,8, &mp2);
  loopAround(strip.Color(R, G, B),S,40,59,8, &mp3);
  loopAround(strip.Color(R, G, B),S,60,79,8, &mp4);
  loopAround(strip.Color(R, G, B),S,80,99,8, &mp5);
  loopAround(strip.Color(R, G, B),S,100,119,8, &mp6);
  loopAround(strip.Color(R, G, B),S,120,143,8, &mp7);
  showLEDS();//display the loaded array on LED strip

}


void showLEDS(){//display the loaded array on LED strip
  for (int i=0; i<strip.numPixels(); i++){
    strip.setPixelColor(i, stripValues[i]); 
  }
  strip.show();
}

//Loop lights around

void loopAround(uint32_t c, int wait, int firstLED, int lastLED,int numLEDS, moving_pattern* cp) { //color, speed(millis),firstLED,LastLED,number of LEDs in chase
  if (millis()-cp->pattern_start_time > wait){//do something only if delay parameter is met
    if (cp->flag==1) {// if at start of sequence determine first led position
      cp->current_LED=firstLED;
      cp->flag=2;
    }

    if (cp->flag==2){//slide leds down strip
      if (cp->current_LED>firstLED && cp->current_LED>0) {
        stripValues[cp->current_LED-1]= 0;
      }
      for (int i=cp->current_LED; i <= cp->current_LED+numLEDS; i++) {
        if (cp->current_LED<=lastLED-numLEDS )stripValues[i]= c;   
      }
      strip.show(); 
      cp->current_LED+=1;
      if (cp->current_LED>lastLED+numLEDS || cp->current_LED>=strip.numPixels()){// if at end of strip or working space then move to next section
        cp->flag=1;

      }
    }

    cp->pattern_start_time=millis();
  }
}




moving_pattern.h:

Code: Select all

//Loop lights around

void loopAround(uint32_t c, int wait, int firstLED, int lastLED,int numLEDS, moving_pattern* cp) { //color, speed(millis),firstLED,LastLED,number of LEDs in chase
  if (millis()-cp->pattern_start_time > wait){//do something only if delay parameter is met
    if (cp->flag==1) {// if at start of sequence determine first led position
      cp->current_LED=firstLED;
      cp->flag=2;
    }

    if (cp->flag==2){//slide leds down strip
      if (cp->current_LED>firstLED && cp->current_LED>0) {
        stripValues[cp->current_LED-1]= 0;
      }
      for (int i=cp->current_LED; i <= cp->current_LED+numLEDS; i++) {
        if (cp->current_LED<=lastLED-numLEDS )stripValues[i]= c;   
      }
      strip.show(); 
      cp->current_LED+=1;
      if (cp->current_LED>lastLED+numLEDS || cp->current_LED>=strip.numPixels()){// if at end of strip or working space then move to next section
        cp->flag=1;

      }
    }

    cp->pattern_start_time=millis();
  }
}

User avatar
pburgess
 
Posts: 4161
Joined: Sun Oct 26, 2008 2:29 am

Re: Conflict between Neopixel BluetoothLE Libraries

Post by pburgess »

The BTLE library requires a ton of RAM (as do NeoPixels, of course). In fact the Guggenhat (w/240 pixels) totally depends on the extra 512 bytes RAM present on the Arduino Leonardo & Micro.

Though your strip is shorter, I think the trouble might be here:

Code: Select all

uint32_t stripValues[144];//create array to store all led position values
Skimming the code, this appears to be a duplicate of the color data that's already maintained within the NeoPixel library. Unless you need to pull some shenanigans, you could just use the getPixelColor() function to query previously-stored pixel color values, or the getPixels() function to get the base address of the pixel buffer directly (use with caution, since you're just bopping around in RAM with this...anyway, it returns a (uint8_t *) and pixels are packed as 3-byte values).

User avatar
fxmech
 
Posts: 90
Joined: Fri Mar 09, 2012 12:19 pm

Re: Conflict between Neopixel BluetoothLE Libraries

Post by fxmech »

Thats it!!!
I havent modified the code but I did do a debugging test where I left all code active but instead of trying to display
what is in my stripValues[144]; array, i replaced it with a generic FOR TO loop to simply fill all leds one color...
The code worked worked just fine that way..... The array seems to corrupt things so I'm guessing I am going out of bounds on the memory usage....

Locked
Please be positive and constructive with your questions and comments.

Return to “Glowy things (LCD, LED, TFT, EL) purchased at Adafruit”