Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is no translation for that post!



LED Effects - Ardui...
 
Share:
Notifications
Clear all

[Solved] LED Effects - Arduino and TwitchChat

44 Posts
2 Users
5 Reactions
11.7 K Views
(@Anonymous)
Joined: 1 second ago
Posts: 0
 

here a lil update of my shared sketch:

 

ToDo List:

✔ the fine-tuning for the effects that cause the Wemos to crash (no jumping balls anymore)

✔ Set all effects to a certain duration 20-30 sec. (timer, counter & repeats)

✔ Brightness by command now work... " !dark - !mid - !bright

✔ Is it possible to adjust the Rainbow Glitter (from Neopixel) for this? (i found it ♥)

• Is it possible to additionally set a VU meter as a selectable effect?

• maybe later versions for Websocket? so users can unlock the effects with channel points

• and an adapted version for serial monitor, without WiFi... ... ...


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2741
Topic starter  

Nice! 👍 🍻


   
ReplyQuote
(@Anonymous)
Joined: 1 second ago
Posts: 0
 

Hello folks! Hello @hans!

I haven't been here for a long time, but I haven't been able to complete all my ToDo's yet...

Sound-reactive doesn't seem to work with WeMos D1... Unless someone here has a solution. ;)

 

I have a little update on effect timing for that. but also a question about it... later... ;)

simply addet:

// renamed "void loop" to "ShowEffect"
void ShowEffect(int selectedEffect,int Seconds) {
// timed test 
  unsigned long startTime = millis();
  unsigned long runMillis = 1000 * Seconds;

  while (millis() - startTime < runMillis) {
// timed test ende
  switch(selectedEffect) {
   
    case 0  : { ............
.............
..................................

and to close the timer add one more } after the last case...

 

?? How to set the timing global for all effects wich called via  "ShowEffect(18,30);" 
i think so ShowEffect(number, Xtimed) or else. and set a constant or define ?
i´ve tried something, but not succesfully...


   
ReplyQuote
(@Anonymous)
Joined: 1 second ago
Posts: 0
 

so in between, I don't know if it fits in here...

I tried to merge the only clock on FastLed and not Neopixel with my sketch...

the clock sketch found there: at github /leonvandenbeukel/Round-LED-Clock

no error messages in the IDE, the whole thing starts and connects,

11:41:35.451 -> 
11:41:35.451 -> Connecting
11:41:35.825 -> ......................
11:41:44.558 -> 
11:41:44.558 -> Connected to FRITZ!Box 7560 GU Soundterror
11:41:44.558 -> IP address:	192.168.178.34
11:41:44.558 -> 
11:41:44.558 -> Starting UDP
11:41:44.558 -> Local port:	123
11:41:44.558 -> 
11:41:44.626 -> Time server IP:	95.211.123.72
11:41:44.626 -> 
11:41:44.626 -> Sending NTP request ...
11:41:44.626 -> Attempting to connect to #ronxtcdabass
11:41:44.864 -> connected and ready
11:41:45.475 -> NTP response:	1677840089

only when I call up the clock, nothing works anymore...

it shows a moment the time and then is over.

11:53:05.683 -> <ronxtcdabass> !Clock
11:53:08.472 -> 
11:53:08.472 -> Soft WDT reset
11:53:08.472 -> 
11:53:08.472 -> ctx: cont 
11:53:08.472 -> sp: 3fff0930 end: 3fff0f40 offset: 01b0
11:53:08.472 -> 
11:53:08.472 -> >>>stack>>>
... ... ... ... ... ...
... ... ... ... ... ...
11:53:08.948 -> <<<stack<<<
11:53:08.948 -> 
11:53:08.948 ->  ets Jan  8 2013,rst cause:2, boot mode:(1,6)
11:53:08.948 -> 
11:53:13.670 -> 
11:53:13.670 ->  ets Jan  8 2013,rst cause:4, boot mode:(1,6)
11:53:13.670 -> 
11:53:13.670 -> wdt reset

It was not easy for me to split up the sketch and then also to observe the order of all commands. then I was happy when no more errors were shown in the IDE and yet I must have forgotten something or done something wrong...

But it's very interesting and kinda funny


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2741
Topic starter  

Posted by: @Anonymous
Sound-reactive doesn't seem to work with WeMos D1

I do not have a Wemos, but I do recall playing with sounds with an Arduino.

So the first thing I tried was using a microphone on one of the analog pins, to find out that doesn't work all that well. You would need a small amplifier with that to get reasonable values.

Next thing I tried, maybe something that could work for your setup, was connecting the Arduino analog port to the audio output of my laptop (3.5mm stereo plug as used with headphones). Now that did work very well, however ... plugging it into my stereo or laptop would (of course) mute the regular speakers.

Maybe a starting point would be using RCA output (may need a small amplifier for that as well).

Note: the amplifier that I mentioned twice now is just a simple transistor or small IC amps. Nothing major.

 

Posted by: @Anonymous
I tried to merge the only clock on FastLed and not Neopixel with my sketch...

the clock sketch found there: at github /leonvandenbeukel/Round-LED-Clock 

As you may have seen in one of my LED effect projects: moving between NeoPixel and FastLED should not be difficult. Especially when moving from NeoPixel to FastLED.
FastLED is much more advanced, so moving from FastLED to NeoPixel can be a challenge 😁 

Just trying to say: if you find a NeoPixel sketch, converting to FastLED is usually relatively easy. 😁 


   
ReplyQuote
(@Anonymous)
Joined: 1 second ago
Posts: 0
 

@hans Hello and happy weekend! :)

1. the most Sound-reactive sketches i´ve seen are working with WeMos MINI, with my NANO ad some other ESP32 but i think i tried all i found from github ^^
i wanna use with line-in from my mixing deck through a miny Amp, not microphone. 2 sketches i tried working definitive with my NANO, but errors while compiling for WeMos... i tried various versions of the important libaries and core... but okay. i can live without...

and then comes the 2nd challenge, merge with my big overload sketch :D :D :D what´s the hardest part of the Clock Thing was and still is. the most sketches i tried, alone works fine but some are too big an crazy for me, and some other are not compilable for my WeMos ^^

 

my LED Setup at the Moment are 1 working Grundig Lamp (81 Led´s) modified to switch between original controller <--> and WeMos with WLED
and 2 middle-pieces from broken Grundig´s with 27Led´s, both in parallel at my 2nd WeMos with my big Twitch-controlled Sketch here. My own Sketch within soo many hours of work with typing and welding, lots of help and soo less sleep ;) and not download and ready to use :) :) :)

the WLED Solution is cool, but without more hardware no Sound-reactive functions supportet too.

i hope i wrote good enough without translator-help.

@hans - you know a lil bit my sketch an if you take a look at the clock sketch, maybe you see faster hot to merge, or if you like, i can show you my actually incomplete merged sketch and you find my mistakes. ^^


   
ReplyQuote
(@Anonymous)
Joined: 1 second ago
Posts: 0
 

Hi and Hello!! :)

1. i found a working method for global timing...

// Global timing variables
unsigned int PlayTime = 60;

 and every call

else if(ircMessage.text == RandomSparkleMessage)
{
sendTwitchMessage(ircMessage.nick + " 🪄 -> RandomSparkle");
ShowEffect(10,PlayTime);
colorWipe(0,0,0, 50);
}

2. i found a soundreactive sketch wich is working (standalone)...

i have changed a lil bit, because i don´t use hardware-buttons.

but until now, not working merged with my big sketch...

with his own animations list...

void addGlitter(uint16_t chanceOfGlitter) {        // Changed fract8 to uint16_t.
  if(random8() < chanceOfGlitter) leds[ random16(NUM_LEDS) ] += CRGB::White;
} // addGlitter()


void rainbow() {
//   fill_rainbow( leds, NUM_LEDS, gHue, 7);                  // Original routine.
  fadeToBlackBy(leds, NUM_LEDS,32);
  int tmp = (random8()+micIn) % NUM_LEDS;
  leds[tmp] += CHSV(gHue+tmp*7,255,micIn*4);
} // rainbow()


void rainbowWithGlitter() {
  rainbow();                                                  // Built-in FastLED rainbow, plus some random sparkly glitter.
//  addGlitter(80);                                           // Original chance of glitter.
  addGlitter(micIn*8);                                        // Increase our chance of glitter.
} // rainbowWithGlitter()


void confetti() {                                             // Random colored speckles that blink in and fade smoothly.
  fadeToBlackBy(leds, NUM_LEDS, 64);
//  leds[pos] += CHSV( gHue + random8(64), 200, 255);         // Original routine.
  for (int i=0; i<8; i++) leds[random16(NUM_LEDS)] += CHSV(gHue + random8(64), 200, micIn*6);  // Updated routine with slower fps needs more action.
} // confetti()


void sinelon() {                                              // A colored dot sweeping back and forth, with fading trails.
  fadeToBlackBy(leds, NUM_LEDS, 20);
//  int pos = beatsin16(17,0,NUM_LEDS-1);                     // Original routine.
//  leds[pos] += CHSV( gHue, 255, 192);                       // Original routine.
  for (int i=0; i<7; i++) {
    int pos = beatsin16((i+1)*4,0,NUM_LEDS-1);
    leds[pos] += CHSV(gHue, 255, micIn*6);
  }
} // sinelon()


void juggle() {                                               // Eight colored dots, weaving in and out of sync with each other.
  fadeToBlackBy(leds, NUM_LEDS, 20);
//  byte dothue = 0;                                          // Original routine.
  byte dothue = micIn;
  for(int i = 0; i < 8; i++) {
//    leds[beatsin16(i+7,0,NUM_LEDS-1)] |= CHSV(dothue, 200, 255);  // Original routine.
    leds[beatsin16(i+7,0,NUM_LEDS-1)] |= CHSV(dothue, 200, micIn*4);
    dothue += 32;
  }
} // juggle()


void bpm() {                                                  // Colored stripes pulsing at a defined Beats-Per-Minute.
  fadeToBlackBy(leds, NUM_LEDS, 20);
  uint8_t beat = beatsin8(17, 64, 255);
  for(int i = 0; i < NUM_LEDS; i++) leds[i] = ColorFromPalette(palette,gHue+(i*3), beat-gHue+(i*10) );
  if (micIn > 0) leds[random16() % NUM_LEDS] = CRGB::White;
} // bpm()

   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2741
Topic starter  

Awesome! Thank you for sharing! 

I see the code is using a microphone with a small amplifier. Nice!

(INMP401, MAX4466, MAX9814  - the MAX4466 is even dirt cheap on AliExpress, not even a Euro haha - I'll go order one myself!)


   
ReplyQuote
(@Anonymous)
Joined: 1 second ago
Posts: 0
 

@hans i´m using the Lineout from my mixing deck and its working fine.

if u like, here the complete code: including the button file:

RENAME from jsbutton.ino to button.h !!!

i must rename for upload here...

 and the main sketch

the animations.h is shown in my last post...

 

but how to merge with my twitch-sketch please?


   
Hans reacted
ReplyQuote
(@Anonymous)
Joined: 1 second ago
Posts: 0
 

i think @hans and maybe other peoples would like this:

the maker of this soundreactive sketch

there are many nice sketches, effect patterns and more.


   
Hans reacted
ReplyQuote
(@Anonymous)
Joined: 1 second ago
Posts: 0
 

i experimentet with an effect more to add into the animations.h and SimplePatternList^^

i call it "jumpySaw and jumpySaw WithGlitter"

void jumpySaw() {

  int bpm = 60;
  int ms_per_beat = 60000/bpm;          // 500ms per beat, where 60,000 = 60 seconds * 1000 ms 
  int ms_per_led = 60000/bpm/NUM_LEDS;

  int cur_led = ((millis() % ms_per_beat) / ms_per_led)%(NUM_LEDS);     // Using millis to count up the strand, with %NUM_LEDS at the end as a safety factor.

  if (micIn > 0) cur_led = 0;

  if (cur_led == 0)
   fill_solid(leds, NUM_LEDS, CRGB::Black);
  else
    leds[cur_led] = ColorFromPalette(palette,gHue+(cur_led*3), micIn*bpm-gHue+(cur_led*10) );    // I prefer to use palettes instead of CHSV or CRGB assignments.

} // sawtooth()

void jumpySawWithGlitter() {
  jumpySaw();                         // Built-in FastLED rainbow, plus some random sparkly glitter.
//  addGlitter(80);                  // Original chance of glitter.
  addGlitter(micIn*8);            // Increase our chance of glitter.
} // jumpySawWithGlitter()

   
ReplyQuote
(@Anonymous)
Joined: 1 second ago
Posts: 0
 

Hello again!

i have an idea... all my tries to merging the soundreactive and the twitch sketch not work...

is it possible, to switch with an hardware button between the two sketches?

so i can run the soundactive when nothing in my chat, or switch to the other sketch when i´m live, and enough action in chat.

okay, loading two sketches same time is not possible, but if i put the soundactive in a ***.h file? would this work?


   
ReplyQuote
(@Anonymous)
Joined: 1 second ago
Posts: 0
 

I think I found a mistake 🙂

in my attempt switching ONLY the soundreactive and as testobject because it's so simple, only the RGB fade from the FastLED sketch.....

added to each "soundreactive pattern / effect" before the closing bracket:

showStrip(); delay(3);

now I can switch between the sound reactive patterns 😄 BUT!!!!!

the WeMos now reconnects far too often... (i think it has ADHS ^^ it reconnects almost if nothing to do)

and the soundreactive part doesn´t fade the colors anymore :(

//* Sound Variables to change! *
analog_sample();
EVERY_N_MILLIS(1000/FRAMES_PER_SECOND) { // You can optionally set the display frame rate to a fixed frame rate without
// resorting to the blocking method of FastLED.delay(1000/FRAMES_PER_SECOND).
gHue++;
FastLED.show();
}
//* Sound Variables *

here my little experiment-sketch:

@hans ??? maybe can you help me again? please!


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2741
Topic starter  

Hi ronxtcdabass!

Apologies for the radio silence - it's been a crazy few days, and it always takes quite some time to read code and see what is going on 😁 

I'm really not familiar with the IRCClient, so I do not know if the library maybe conflicts with other libraries.

First of all, you should probably consider cleaning up your code a little bit - just so it becomes more readable for others or when trying to debug something. Don't feel bad though, my code at times becomes a mess as well and then I just have to sit down and clean up.

Here an example of your loop() function after cleaning up ...
Use proper indentation and add spacing and such to make things more readable.

void loop() {
  // Sound 
  analog_sample(); 

  EVERY_N_MILLIS(1000/FRAMES_PER_SECOND) {   // Optionally set the display frame rate to a fixed frame rate without
                                               // resorting to the blocking method of FastLED.delay(1000/FRAMES_PER_SECOND).
    gHue++;
    FastLED.show();
  }

  // Try to connect to chat. If it loses connection try again
  if (!client.connected()) {
    Serial.println("Attempting to connect to " + ircChannel );
    
    // Attempt to connect, Second param is not needed by Twitch
    if (client.connect(TWITCH_BOT_NAME, "", TWITCH_OAUTH_TOKEN)) 
    {
      client.sendRaw("JOIN " + ircChannel);
      Serial.println("connected and ready");
      
      // Show if connected
      fill_solid(leds, NUM_LEDS, CRGB::Green);
      FastLED.delay(300);
      fill_solid(leds, NUM_LEDS, CRGB::Black);
      FastLED.delay(300);
    
      sendTwitchMessage("ready to 💡 start with !fx");
    } else {
      Serial.println("failed... try again in 5 seconds");

      for (int i = 0; i < 5; i++) {
        digitalWrite(LED_BUILTIN, HIGH);
        delay(500);
        digitalWrite(LED_BUILTIN, LOW);
        delay(500);
      }
       
      // Wait 5 (10) seconds before retrying
      delay(5000);
    }
    return;
  }

  client.loop();
}

 

You can also simplify the code a little bit by removing some parts that were originally added so my code could be used with FastLED and NeoPixel - but you're using FastLED so we can remove this. 

// Apply LED color changes
void showStrip() {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.show();
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   FastLED.show();
 #endif
}

Once removed, replace all occurances of "showStrip();" with "FastLED.show();"

Same goes for the "setPixel" function which can be removed by removing this part of the code

// ***************************************
// ** FastLed/NeoPixel Common Functions **
// ***************************************

// Set a LED color (not yet visible)
void setPixel(int Pixel, byte red, byte green, byte blue) {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.setPixelColor(Pixel, strip.Color(red, green, blue));
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
 #endif
}

and replace every (where Pixel, Red, Green and Blue are parameters that can be different)

setPixel(Pixel, Red, Green, Blue);

with

leds[Pixel].setRGB( Red, Green, Blue);

 

The "SetAll()" function can be removed as well and each call to SetAll(Red,Green,Blue) can be replaced with a "fill_solid(leds, NUM_LEDS, CRGB(Red,Green,Blue));" function call (you've used them before);

// Set all LEDs to a given color and apply it (visible)
void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}

 

After that clean up; Now a few things to keep in mind:

1) An Arduino, or similar microcontroller, are not designed to do multitasking.
So changing the hue of your LEDs and checking Twitch IRC at the same time may conflict (timing wise). So there may be some trickery needed there. This is where I can see changing the Hue every second may be a challenge.

Tip: some (maybe even all?) ESP32 models have dual core processors, and do allow some of this to be done at the same time a little better. But it will take time and effort to learn and see how this works.

2) Libraries additionally can conflict, especially when timing becomes critical (which could be the case in your situation).

Especially for #2 I'd always test certain pieces of code in separate sketched - just to make sure they work. I assume you've already done this.

 

Having said all that, lets look at one problem at a time ... do I understand this right;
You're saying the "client.connected()" keeps failing and it therefor keeps trying to connect like a crazy person?
Or is this function called too often?

 


   
ReplyQuote
Page 3 / 3
Share: