kitesurfer1404 / WS2812FX

WS2812 FX Library for Arduino and ESP8266
MIT License
1.59k stars 344 forks source link

Set speed inverse #59

Closed M-4A closed 6 years ago

M-4A commented 6 years ago

The minimum and maximum are reversed, 255 = the minimum speed, if set to 1, it really puts 10 but this is the maximum speed.

M-4A commented 6 years ago

in some modes, the speed is not controlled at all, for example - Color Wipe (3)

M-4A commented 6 years ago

I apologize. saw in the code

define SPEED_MIN 10

define SPEED_MAX 65535

The question is closed.

synssins commented 6 years ago

I guess I don't understand the speed stuff... On my ESP8266 I'm running the default example on 600 pixels, and what I end up with in certain modes (theater chase) is just a highspeed flicker of all of the LEDs... It's a chase alright, but it's so fast that it almost looks like a strobe.

I see it in all chase patterns and a couple of others... Speed adjusting via the web interface results in no changes whatsoever to the pattern.

rummyr commented 6 years ago

For things like chases/strobes try a very large speed (aka very slow) ... like 2000 or even more!

synssins commented 6 years ago

That took care of it! The only issue I'm seeing now is that when I hit the + in order to "decrease" the speed from the web interface, it definitely does so, but after a couple of times, it defaults back to the original issue I had and the only fix is to power the whole unit off and back on.

Additionally, is there a way that certain patterns can be set to have a pre-defined speed when the pattern is selected? Theater Chase is great when you can visibly see the lights move in a nice even pattern, but if I cycle back to Hyper Sparkle or the like, I end up with such a slow response, the lights don't even change.

rummyr commented 6 years ago

I'm going to submit a change to this.. IMHO the speed should change proportionally so e.g 4x plus always doubles and doesn't add a constant number on. For example 4x plus when the speed is 1000 should make the speed 500. And another 4x plus takes it to 250.

I've also got some changes to Display the speed/brightness on the web interface And to give it a REST interface so it can be better controlled from another system.

Won't be for a few days tho

On Thu, 7 Dec 2017, 15:28 synssins, notifications@github.com wrote:

That took care of it! The only issue I'm seeing now is that when I hit the

  • in order to "decrease" the speed from the web interface, it definitely does so, but after a couple of times, it defaults back to the original issue I had and the only fix is to power the whole unit off and back on.

Additionally, is there a way that certain patterns can be set to have a pre-defined speed when the pattern is selected? Theater Chase is great when you can visibly see the lights move in a nice even pattern, but if I cycle back to Hyper Sparkle or the like, I end up with such a slow response, the lights don't even change.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kitesurfer1404/WS2812FX/issues/59#issuecomment-350000832, or mute the thread https://github.com/notifications/unsubscribe-auth/ATlQ7XcoVy8Oy1Ic3U9QBaIAoUyu1ct0ks5s-AQIgaJpZM4Qzd_t .

synssins commented 6 years ago

I love you so much right now... I use SmartThings and have been trying to find a way to get a NeoPixel system integrated into it, but sadly have no development skills whatsoever... This unit is the closest I've seen as it does have a "sort of" api in which you can call the url by ipaddress/set?m=## to set the mode... With an HTTP endpoint in SmartThings, I can call any of those URLs to trigger a pattern, but won't get any feedback into ST to let me know which pattern is on.

moose4lord commented 6 years ago

I'm afraid I'm responsible for the change in how the speed parameter works. Until the latest release, the speeds range was 0-255 and a larger number gave you faster animation. Unfortunately, calculating time delays internal to the WS2812FX library was a bit haphazard, and made it difficult to synchronize the animations for multiple segments. So I changed the speed parameter so it had a range of 0-65535 and a larger number gave you a SLOWER animation. Harm incorporated my scheme in his latest release.

In essence the speed parameter now sets the time (in milliseconds) it takes to complete one cycle of an animation. For example, if you set the mode to FX_MODE_BLINK and speed=1000, then the LEDs will be on for 500ms and off for 500ms (one cycle of animation = 1000ms). It gets a little more complicated for modes that "chase" an LED from the beginning of a strip to the end of the strip, since the speed of animation depends on the length of the strip. For example, if the mode is FX_MODE_SCAN and speed=1000, then the "on" LED will move from the beginning of the strip to the end in 1000ms, no matter how long the strip is.

Sorry if this threw some existing users of the library for a loop. It is a disruptive change in how the library worked. But it does provide more control over the animation timing.

synssins commented 6 years ago

The logic makes sense and I see no issues with it. I actually just discovered the library after those changes were implemented, but I don't believe I fully understood how they worked.

What I'm running into now as part of the speed stuff is that when I set the default speed and then upload it, the speed works fine at that default. But the moment I adjust the speed by clicking on the speed up or speed down icons in the web interface, it IMMEDIATELY defaults back to the fastest possible speed for the patterns to run. I am unable to change speeds for any patterns whatsoever away from the defaults. With @rummyr commenting about some changes to the UI and adding a REST API, I'm super pumped about getting this implemented in our theater downstairs with our SmartThings home automation after Christmas is over when the Neopixel strings come down from outside.

moose4lord commented 6 years ago

Ahh, I see what you mean about adjusting the speed from the web interface. You've uncovered a bug in the library. I have a fix. If you go into your Arduino\libraries\WS2812FX folder and edit the WS2812FX.cpp file, you'll see these two functions:

void WS2812FX::increaseSpeed(uint8_t s) {
  s = constrain(SEGMENT.speed + s, SPEED_MIN, SPEED_MAX);
  setSpeed(s);
}

void WS2812FX::decreaseSpeed(uint8_t s) {
  s = constrain(SEGMENT.speed - s, SPEED_MIN, SPEED_MAX);
  setSpeed(s);
}

Changing them to this will fix the speed adjustment bug:

void WS2812FX::increaseSpeed(uint8_t s) {
  uint16_t newSpeed = constrain(SEGMENT.speed + s, SPEED_MIN, SPEED_MAX);
  setSpeed(newSpeed);
}

void WS2812FX::decreaseSpeed(uint8_t s) {
  uint16_t newSpeed = constrain(SEGMENT.speed - s, SPEED_MIN, SPEED_MAX);
  setSpeed(newSpeed);
}

Also, you'll want to change this line in the esp8266_webinterface.ino sketch: #define SPEED_STEP 10 to this: #define SPEED_STEP 100

Otherwise, the steps for increasing/decrease the speed will be too small and you'll be clicking the web page buttons way too much to see a change in the speed.

I'll fork a copy of the code and apply the bug fix, and get Harm to incorporate it into the library.

synssins commented 6 years ago

@moose4lord Phenomenal... That fixed the speed adjustments, though I'm finding I need to spam the + or - buttons a couple hundred times to notice any substantial speed changes... It is definitely adjusting now...

I assume the increment of 100 is out of a scale of 0 to 65535? So, theoretically I could set that number to have an increment change of 1000 and have 65 discreet speed settings?

moose4lord commented 6 years ago

Well, what you're saying is technically true, but the useful range of speed values depends on the mode you're running. Some modes run well with speed between 50-500 and some modes work well in the range 1000-10000. Also, a good speed setting sometimes needs to take into account the length of the LED strip you're trying to control. A speed value of 1000 might work well for a strip of 30 LEDs, but not work well with a strip of 300 LEDs. A speed value above 10000 generally isn't very useful unless you have a very long strip of LEDs. So setting the speed is a little more nuanced then it used to be.

You can probably bump the speed increment up to 200, but any higher then that and you'll have a hard time dialing in a good speed for some of the modes that work better in the 50-500 range. It would be better if the increment value was nonlinear, being smaller for small speed values and larger for large speed values. I'll have to give that some thought.

synssins commented 6 years ago

Ok. I think I understand what you're saying with regards to some modes working in certain ranges better than other modes requiring vastly different ranges...

Is there a way to configure default speeds for certain modes? When switching from a mode that works in the 50-500 range to a chase pattern that would benefit from being considerably slower, such as 8000 or 10000, I now have to spam click the speed adjustment to get the pattern to look right. If certain modes were able to default to a specific speed value and then be adjusted to taste from there (or be configured in the sketch ahead of time to the preferred value) it would vastly increase the "user friendliness" of the library... Of course, I'm saying this from a position of no knowledge with regards to the development skills and time needed to implement something like this, if possible.

moose4lord commented 6 years ago

Adding defaults for each mode is doable, but I think I have an easier solution. In esp8266_webinterface.ino look for these lines near the bottom:

   if(server.argName(i) == "s") {
      if(server.arg(i)[0] == '-') {
        ws2812fx.decreaseSpeed(SPEED_STEP);
      } else {
        ws2812fx.increaseSpeed(SPEED_STEP);
      }
    }

That's the code that gets executed when you click the speed increase/decrease buttons on the web interface. If you change it to this:

    if(server.argName(i) == "s") {
      if(server.arg(i)[0] == '-') {
          ws2812fx.setSpeed(ws2812fx.getSpeed() * 0.9);
      } else {
          ws2812fx.setSpeed(ws2812fx.getSpeed() * 1.1);
      }
    }

It'll increase/decrease the speed by 10% each time you click the buttons (rather then increasing/decreasing the speed by a fixed amount). It gives granular control when the speed is a small value and lets you make big changes when the speed is a large value.

Give it a try.

PS you might also want to change the DEFAULT_SPEED near the top of the file. It's currently set to 200, which is a bit low for most modes. Setting it to 1000 seems like a nice, middle-of-the-road value that's a good starting point for most modes. #define DEFAULT_SPEED 1000

fietstasss commented 6 years ago

When i'm using the serial_control.ino I've noticed that any speed entered by s <n> will be brought back to a value between 10 and 255, which makes it impossible to set speeds > 255.

Are you aware of this, and how is it fixable?

moose4lord commented 6 years ago

The serial_control sketch was never updated to accommodate the higher speed values. If you look about half way down the sketch you'll see this:

  if(cmd.startsWith("s ")) {
    uint8_t s = (uint8_t) cmd.substring(2, cmd.length()).toInt();
    ws2812fx.setSpeed(s);

Change it to this:

  if(cmd.startsWith("s ")) {
    uint16_t s = (uint16_t) cmd.substring(2, cmd.length()).toInt();
    ws2812fx.setSpeed(s);

That'll use a 16-bit speed value instead of an 8-bit speed value and you should be good to go.

Mulfarion commented 6 years ago

How do I get back the old speed selection method?

moose4lord commented 6 years ago

You can download older versions of the library right from GitHub. If you click the "commits" link on the WS2812FX project, you can scroll through all previous versions of the code. It looks like the last code commit with the old speed selection method was Nov. 7 2017, which you can download here.