AaronLiddiment / LEDText

FastLED Flexible Text Message Class requires LEDMatrix Class
89 stars 32 forks source link

Change text using buttons #33

Open AlexCachan opened 2 years ago

AlexCachan commented 2 years ago

Hi, I would like to do something quite simlple but i can't make it work ! I'm using switch/case code for making a menu and I would like each item to be a text scroll and each time i press a button i go further in the switch case and the text scroll from start no matter the position of the previous item in the scroll. Idk if its very clear ! I this code I need to wait the first scroll to finish before being able to see actual item of the menu...

Thanks for your help !

#include <FastLED.h>

#include <LEDMatrix.h>
#include <LEDText.h>
#include <FontMatrise.h>

int range=0;
// Change the next 6 defines to match your matrix type and size

#define LED_PIN        12
#define COLOR_ORDER    GRB
#define CHIPSET        WS2812B

#define MATRIX_WIDTH   11
#define MATRIX_HEIGHT  -10
#define MATRIX_TYPE    HORIZONTAL_MATRIX

cLEDMatrix<MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_TYPE> leds;

cLEDText ScrollingMsg;

const unsigned char TxtHorl[] = { EFFECT_SCROLL_LEFT "  ITEM 1 " };
const unsigned char TxtHorlHeures[] = { EFFECT_SCROLL_LEFT "  ITEM 2 " };
const unsigned char TxtHorlMin[] = { EFFECT_SCROLL_LEFT "  ITEM 3 " };

void setup()
{
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds[0], leds.Size());
  FastLED.setBrightness(6);
  FastLED.clear(true);
     Serial.begin(9600);
  pinMode(2, INPUT_PULLUP);

  ScrollingMsg.SetFont(MatriseFontData);
  ScrollingMsg.Init(&leds, leds.Width(), ScrollingMsg.FontHeight() + 1, 0, 0);
  ScrollingMsg.SetText((unsigned char *)TxtHorl, sizeof(TxtHorl) - 1);
  ScrollingMsg.SetTextColrOptions(COLR_RGB | COLR_SINGLE, 0xff, 0x00, 0xff);
}

void loop()
{

  switch (range) {
    case 1:    // your hand is on the sensor
       if (ScrollingMsg.UpdateText() == -1)
    ScrollingMsg.SetText((unsigned char *)TxtHorlHeures, sizeof(TxtHorlHeures) - 1);
  else
    FastLED.show();
  delay(100);
      break;
    case 2:    // your hand is close to the sensor
       if (ScrollingMsg.UpdateText() == -1)
    ScrollingMsg.SetText((unsigned char *)TxtHorl, sizeof(TxtHorl) - 1);
  else
    FastLED.show();
  delay(100);
      break;
    case 3:    // your hand is a few inches from the sensor
      if (ScrollingMsg.UpdateText() == -1)
    ScrollingMsg.SetText((unsigned char *)TxtHorlMin, sizeof(TxtHorlMin) - 1);
  else
    FastLED.show();
  delay(100);
      break;
    case 4:    // your hand is nowhere near the sensor

      break;
  }

 if (digitalRead(2)==LOW  )
  {
    range++;
          Serial.println(range);
delay(150);
    }

}
AaronLiddiment commented 2 years ago

Only had a quick look but think this might do what you want (Can't seem to get the formatting right!!!):

int oldrange=0;

void loop() { switch (range) { case 1: // your hand is on the sensor if ((ScrollingMsg.UpdateText() == -1) || (oldrange != range)) { ScrollingMsg.SetText((unsigned char )TxtHorlHeures, sizeof(TxtHorlHeures) - 1); ScrollingMsg.UpdateText(); oldrange = range; } FastLED.show(); delay(100); break; case 2: // your hand is close to the sensor if ((ScrollingMsg.UpdateText() == -1) || (oldrange != range)) { ScrollingMsg.SetText((unsigned char )TxtHorl, sizeof(TxtHorl) - 1); ScrollingMsg.UpdateText(); oldrange = range; } FastLED.show(); delay(100); break; case 3: // your hand is a few inches from the sensor if ((ScrollingMsg.UpdateText() == -1) || (oldrange != range)) { ScrollingMsg.SetText((unsigned char *)TxtHorlMin, sizeof(TxtHorlMin) - 1); ScrollingMsg.UpdateText(); oldrange = range; } FastLED.show(); delay(100); break; case 4: // your hand is nowhere near the sensor

  break;

}

if (digitalRead(2)==LOW ) { range++; Serial.println(range); delay(150); } }

AlexCachan commented 2 years ago

It works well !!! Thanks for this trick (and the library !)

AlexCachan commented 2 years ago

Another small issue that I got, I'm using it 9 times on my switch(case) menu, and when i want to add a 10th item of scrolled text, it compiles but the sketch wont run ? I'm using a nano. Is there some hardware limitation or does it come from the software ? Thanks

AaronLiddiment commented 2 years ago

The Nano doesn't have much ram so you have to watch how many LED's you can use as each uses 6 bytes. Then you have the stack overhead as well as the amount of variable space you use. And of course code space is limited to <30K after the boot loader. Anyway I have reworked the code above a little reduce it's size, you should be able to expand this for more range.

const unsigned char TxtHorl[] = { EFFECT_SCROLL_LEFT " ITEM 1 " }; const unsigned char TxtHorlHeures[] = { EFFECT_SCROLL_LEFT " ITEM 2 " }; const unsigned char TxtHorlMin[] = { EFFECT_SCROLL_LEFT " ITEM 3 " };

static const unsigned char *TxtAry[] = { TxtHorl, TxtHorlHeures, TxtHorlMin }; int oldrange=0;

void loop() { if ((range >= 1) && (range <= 3)) { if ((ScrollingMsg.UpdateText() == -1) || (oldrange != range)) { ScrollingMsg.SetText((unsigned char *)TxtAry[range - 1], sizeof(TxtAry[range - 1]) - 1); ScrollingMsg.UpdateText(); oldrange = range; } FastLED.show(); delay(100); }

if (digitalRead(2)==LOW ) { range++; Serial.println(range); delay(150); } }

AlexCachan commented 2 years ago

Hello again ! Thanks for your help, i'm back onto my project and now I'm trying to make it lighter by removing unused character from FontMatrise.h I just want to use cap letters, numbers, and " " "<" ">" It led me to a strange result of random character ! I bet it must come from theses values
32, // Font First Character 127,// Font Last Character But how should I do now ?!! Thanks :)

AaronLiddiment commented 2 years ago

Yes. 32 is the ASCII code for a SPACE character. You can easily skip characters but it would make it much harder to write your messages as the character codes would not match the ASCII table any more. Your best approach to keep programming messages easier is to still keep your base character as 32 (SPACE) and make your last character 90, making sure you have data for all the characters in this range.

AlexCachan commented 2 years ago

Hello hello ! I'm still playing with your library trying to display a navigation menu, and I got a new strange issue. I'm using a scrolltext and I would like to turn on one of the LED in the matrix.

ScrollingMsg.SetText(msg, sizeof(3));ScrollingMsg.UpdateText(); ledsMTX[0][111] = CHSV( color, 255, 255); FastLED.show();

The LED isnt used by the scroll area, the display works but it crashes everything else ! (buttons, timings...)

Do you have any idea how it could conflict with the library ?

Thanks

AaronLiddiment commented 2 years ago

I would need to see more of your code. Specifically how you are initialising the ScrollingMsg and how you are setting up your LED array, I presume your are using my Matrix class. Is your Msg array really only 2 displayable characters and why is your LED array multi dimensional?

AlexCachan commented 2 years ago

Thanks for your answer, I will try to answer all your questions !

void displaytemp(){

String str = "";
if(tempC<10){str += "0";}
str += String(tempC);
str += " ";
static unsigned char msg[3];
str.toCharArray((char *)msg, 3);
ScrollingMsg.SetText(msg, sizeof(3));ScrollingMsg.UpdateText();
ledsMTX[0][111] = CHSV( color, 255, 255);
FastLED.show();

}

I'm using multidimentional array because I got a strip of 114 leds and only 110 are used in matrix type, the led I want to turn on is located outside of the matrix.

I'm hoping it will help you ! Thanks !

AaronLiddiment commented 2 years ago

Your LED array reference is the issue and will be corrupting memory as the Matrix class will only be allocating 110 leds. You should use ledsMTX(111) but you will also need to add an extra Horizontal line to the Matrix definition but still leave the ScrollingText area as is.

Ignore this! I was out and replied on my phone but this is not quite right! Here is a proper answer

The problem you are having is the way you are accessing the Led array I think, by treating it as a 2 dimensional CRGB array that doesn't take into account my overloading of the [] operators. I would imagine it is corrupting memory randomly based on the values in the CRGB structure. Try '*(ledsMTX[111]) = CHSV( color, 255, 255)' instead of 'ledsMTX[0][111] = CHSV( color, 255, 255)'

Editing this again! I really should engage my brain before answering! My original comments are still valid, you need to increase the size of the cMatrix definition or you will be accessing data beyond the end of the array. So actually checking my answer properly means my original suggestion was correct, increase you height to -11. The ScrollingMsg init can still be 0-10 and will stop it from messing with your extra leds. You can then use my overload on the '()' to just do ledsMTX(111).

AlexCachan commented 2 years ago

ahahahahah ! I had a lot of fun reading your comment ! So I went to your final (oh wait... can it really be the final final correction? lol) patch (change the matrix size) and it worked perfectly ! I just had to change the origin of the text scroller ! Thanks for your answers !!! Alex