0

Custom Neopixel Matrix CHAR Length Issues
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Custom Neopixel Matrix CHAR Length Issues

by JordanCaddyMan on Fri Jun 04, 2021 11:00 pm

I am so so close to having this project where I want it to be but I've hit a hiccup that I can't work out for the life of me. I am building a daft punk Thomas helmet that is Bluetooth enabled through a Adafruit Bluefruit LE UART Friend. I have it setup to either display a preset string from flash(that can be as long as I want it to be), or if it doesn't match a hot key then it'll just display what was entered. My issue is that I literally can not have any more than cbuffer[15] . If I increase the buffer size the code will still compile and run but the matrix commands no longer work(even in the setup code). Is there a limitation in the GFX library I am missing, or is there something glaringly obvious wrong with my code I haven't caught

Code: Select all | TOGGLE FULL SIZE
#include <Arduino.h>
#include <SPI.h>
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"
#include "BluefruitConfig.h"
#include "string.h"

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#include <Fonts/Picopixel.h>

#define PIN 6

#if SOFTWARE_SERIAL_AVAILABLE
  #include <SoftwareSerial.h>
#endif

/*=========================================================================
    APPLICATION SETTINGS

    FACTORYRESET_ENABLE       Perform a factory reset when running this sketch
   
                              Enabling this will put your Bluefruit LE module
                              in a 'known good' state and clear any config
                              data set in previous sketches or projects, so
                              running this at least once is a good idea.
   
                              When deploying your project, however, you will
                              want to disable factory reset by setting this
                              value to 0.  If you are making changes to your
                              Bluefruit LE device via AT commands, and those
                              changes aren't persisting across resets, this
                              is the reason why.  Factory reset will erase
                              the non-volatile memory where config data is
                              stored, setting it back to factory default
                              values.
       
                              Some sketches that require you to bond to a
                              central device (HID mouse, keyboard, etc.)
                              won't work at all with this feature enabled
                              since the factory reset will clear all of the
                              bonding data stored on the chip, meaning the
                              central device won't be able to reconnect.
    MINIMUM_FIRMWARE_VERSION  Minimum firmware version to have some new features
    MODE_LED_BEHAVIOUR        LED activity, valid options are
                              "DISABLE" or "MODE" or "BLEUART" or
                              "HWUART"  or "SPI"  or "MANUAL"
    -----------------------------------------------------------------------*/
    #define FACTORYRESET_ENABLE         0
    #define MINIMUM_FIRMWARE_VERSION    "0.6.6"
    #define MODE_LED_BEHAVIOUR          "MODE"
/*=========================================================================*/

// Create the bluefruit object, either software serial...uncomment these lines

SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN);

Adafruit_BluefruitLE_UART ble(bluefruitSS, BLUEFRUIT_UART_MODE_PIN,
                      BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN);

// A small helper
void error(const __FlashStringHelper*err) {
  Serial.println(err);
  while (1);
}

Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(47, 8, PIN,
  NEO_MATRIX_BOTTOM    + NEO_MATRIX_LEFT +
  NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG,
  NEO_GRB            + NEO_KHZ800);

const uint16_t colors[] = {
  matrix.Color(255, 0, 0), matrix.Color(204, 204, 0), matrix.Color(0, 255, 255),
  matrix.Color(255, 10, 127), matrix.Color(127, 0, 255), matrix.Color(0, 255, 0),
  matrix.Color(255, 99, 255)};

void setup() {
  matrix.begin();
  matrix.setTextWrap(false);
  matrix.setBrightness(50);
  matrix.setFont(&Picopixel);
  matrix.setTextColor(colors[0]);
  matrix.fillScreen(0);
  matrix.setCursor(0,7);
  matrix.show();
  delay(33);
  //while (!Serial);  // required for Flora & Micro
  // delay(500);

  Serial.begin(115200);
  Serial.println(F("Adafruit Bluefruit Command <-> Data Mode Example"));
  Serial.println(F("------------------------------------------------"));

  /* Initialise the module */
  Serial.print(F("Initialising the Bluefruit LE module: "));

  if ( !ble.begin(VERBOSE_MODE) )
  {
    error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
  }
  Serial.println( F("OK!") );

  if ( FACTORYRESET_ENABLE )
  {
    /* Perform a factory reset to make sure everything is in a known state */
    Serial.println(F("Performing a factory reset: "));
    if ( ! ble.factoryReset() ){
      error(F("Couldn't factory reset"));
    }
  }

  /* Disable command echo from Bluefruit */
  ble.echo(false);

  Serial.println("Requesting Bluefruit info:");
  /* Print Bluefruit information */
  ble.info();

  Serial.println(F("Please use Adafruit Bluefruit LE app to connect in UART mode"));
  Serial.println(F("Then Enter characters to send to Bluefruit"));
  Serial.println();

  ble.verbose(false);  // debug info is a little annoying after this point!

  /* Wait for connection */
  while (! ble.isConnected()) {
      delay(500);
  }

  Serial.println(F("******************************"));


  // Set module to DATA mode
  Serial.println( F("Switching to DATA mode!") );
  ble.setMode(BLUEFRUIT_MODE_DATA);

}


char c;
char cbuffer[15];
int b = matrix.width();

void loop() {   

  int y=0;
  bool FSC=true;
  while ( ble.available() )
  {
   //Check if it's the "First Scan" of the while loop. If so clear the buffer and set the first scan boolean to false
   if(FSC==true)
   {
    cbuffer[0] = '\0';
    Serial.println(FSC);
    FSC=false;
    }
   c = ble.read();
   cbuffer[y] = c;
   delay (10);
  y++;
  }
   
   int msgsize = strlen(cbuffer);
   char myword[msgsize];
   if (FSC==false){
    myword[0] = '\0';
    Serial.println(msgsize);
    for (int i=0;i<strlen(cbuffer);i++)
    {
      myword[i]=cbuffer[i];
    }
    myword[msgsize+1]= '\0';
   }
  //Test print to verify transfer from buffer
  //if (FSC==false) {Serial.println(myword); Serial.println(myword[0]); Serial.println(myword[1]); Serial.println(myword[2]);}

  //if the input matches a preset then run the function, else display what was input from the uart menu
  if((cbuffer[0]=='A' && cbuffer[1]=='T' && cbuffer[2]=='W') || (cbuffer[0]=='a' && cbuffer[1]=='t' && cbuffer[2]=='w') )
  {
   atw();
   }
  else if((cbuffer[0]=='U' && cbuffer[1]=='A' && cbuffer[2]=='N') || (cbuffer[0]=='u' && cbuffer[1]=='a' && cbuffer[2]=='n'))
  {
   uan();
   }
  else
  {
    //Serial.println( F("AC") );
    matrix.fillScreen(0);
    matrix.setCursor(b,7);
    matrix.print(cbuffer);
    if( --b < -110 ) {
      b = matrix.width();
      }
    matrix.show();
    delay(33);
    }
}

int x = matrix.width();
void atw(){
    Serial.println( F("ATW") );
    matrix.fillScreen(0);
    matrix.setCursor(x,7);
    matrix.print(F("AROUND THE WORLD"));
   if( --x < -110 ) {
      x = matrix.width();
     }
    matrix.show();
    delay(33);
  }

int a = matrix.width();
void uan(){
    Serial.println( F("UAN") );
    matrix.fillScreen(0);
    matrix.setCursor(a,7);
    matrix.print(F("UP ALL NIGHT TO GET LUCKY"));
   if( --a < -110 ) {
      a = matrix.width();
      }
    matrix.show();
    delay(33);
  }

JordanCaddyMan
 
Posts: 4
Joined: Fri Jun 04, 2021 9:34 pm

Re: Custom Neopixel Matrix CHAR Length Issues

by dastels on Sat Jun 05, 2021 11:38 am

Please explain exactly what you mean by "no longer work".

Your problem may have to do with the way you deal with (or not in some cases) the null string terminator character. Have a look at https://www.tutorialspoint.com/cprogramming/c_strings.htm for info.

Dave

dastels
 
Posts: 6777
Joined: Tue Oct 20, 2015 3:22 pm

Re: Custom Neopixel Matrix CHAR Length Issues

by JordanCaddyMan on Sat Jun 05, 2021 3:47 pm

dastels wrote:Please explain exactly what you mean by "no longer work".

Dave


By no longer work I mean that with an array of 15 the code acts as expected. The pixel matrix resets and blanks out which is a what I tell it to do in the setup instruction. When I connect my phone it moves to loop and I can either enter the hot keys, or a small string for it to display and loop through. Now here’s the interesting part. If I increase that array to 16 and upload then the matrix no longer blanks out like it’s supposed to in setup. The odd part is that all of the serial prints still work, as well the reads to drop in to the loop. Just the matrix function is broken as a whole from start to finish.
Attached is the matrix after uploading with chat array of higher than 15
F12C21F1-3429-4414-8878-BB99195218AB.jpeg
F12C21F1-3429-4414-8878-BB99195218AB.jpeg (114.01 KiB) Viewed 148 times

JordanCaddyMan
 
Posts: 4
Joined: Fri Jun 04, 2021 9:34 pm

Re: Custom Neopixel Matrix CHAR Length Issues

by dastels on Sat Jun 05, 2021 5:47 pm

But cbuffer isn't used in setup. My feeling is that the length of cbuffer is a ref herring and that the problem stems from how you use it.

Dave

dastels
 
Posts: 6777
Joined: Tue Oct 20, 2015 3:22 pm

Re: Custom Neopixel Matrix CHAR Length Issues

by JordanCaddyMan on Sat Jun 05, 2021 7:27 pm

dastels wrote:But cbuffer isn't used in setup. My feeling is that the length of cbuffer is a ref herring and that the problem stems from how you use it.

Dave


I agree, and that’s what makes it so odd. If I remove all references in the loop to cbuffer it will work too. I guess my question boils down to, how can something used in the loop function break something in setup? If an arduino executes top to bottom starting with setup and moving to loop. Also, it strikes me as odd that the only time it breaks is when I increase the buffer almost like a compilation issue of some sorts. I’m sorry if I sound like I’m being stubborn, I do programming for a living (albeit not in c++) and I’m trying to think of it logically lol.

Edit: I was vague in some spots. By work too, I mean I can still use a hard coded string in the matrix command instead of entering something over Bluetooth.

JordanCaddyMan
 
Posts: 4
Joined: Fri Jun 04, 2021 9:34 pm

Re: Custom Neopixel Matrix CHAR Length Issues

by JordanCaddyMan on Sun Jun 06, 2021 12:32 pm

I have modified some of the code to better show the issue at hand.

Code: Select all | TOGGLE FULL SIZE
char c;
char cbuffer[]={'0','1','2','3','4','5','6','7','0','1','2','3','4','5','6','7','0','1','2','3','4','5','6','7','\0'};
int b = matrix.width();

void loop() {   
/*
  int y=0;
  bool FSC=true;
  while ( ble.available() )
  {
   //Check if it's the "First Scan" of the while loop. If so clear the buffer and set the first scan boolean to false
   if(FSC==true)
   {
    cbuffer[0] = '\0';
    Serial.println(FSC);
    FSC=false;
    }
   c = ble.read();
   cbuffer[y] = c;
   delay (10);
  y++;
  }
   
   int msgsize = strlen(cbuffer);
   char myword[msgsize];
   if (FSC==false){
    myword[0] = '\0';
    Serial.println(msgsize);
    for (int i=0;i<strlen(cbuffer);i++)
    {
      myword[i]=cbuffer[i];
    }
    myword[msgsize+1]= '\0';
   }*/
  //Test print to verify transfer from buffer
  //if (FSC==false) {Serial.println(myword); Serial.println(myword[0]); Serial.println(myword[1]); Serial.println(myword[2]);}

  //if the input matches a preset then run the function, else display what was input from the uart menu
  if((cbuffer[0]=='A' && cbuffer[1]=='T' && cbuffer[2]=='W') || (cbuffer[0]=='a' && cbuffer[1]=='t' && cbuffer[2]=='w') )
  {
   atw();
   }
  else if((cbuffer[0]=='U' && cbuffer[1]=='A' && cbuffer[2]=='N') || (cbuffer[0]=='u' && cbuffer[1]=='a' && cbuffer[2]=='n'))
  {
   uan();
   }
  else
  {
    Serial.println( F("AC") );
    matrix.fillScreen(0);
    matrix.setCursor(b,7);
    matrix.print(cbuffer);
    if( --b < -110 ) {
      b = matrix.width();
      }
    matrix.show();
    delay(33);
    }
}


The Bluetooth portion has been taken completely out and the cbuffer has been increased past 15 and filled in with numeral characters with a terminating '\0' at the end. With this done the code drops into the else statement and begins printing AC over serial. However, nothing is being display on the LED matrix.

JordanCaddyMan
 
Posts: 4
Joined: Fri Jun 04, 2021 9:34 pm

Please be positive and constructive with your questions and comments.