Random Sine Wave speed manipulation

Hello,

I am new to Arduino and at the moment I am playing around with some LED's. I'm trying to use the Sine wave function to get some funky effects but for some reason I can't get the Sine wave to be generated at random speeds.

This is the code I am using for a simple Sine wave...

int bluePin = 3;

void setup()
{
  pinMode(bluePin, OUTPUT);
}

void loop()
{
  float x = millis()/5000.0;
  int value = 128.0 + 128 * sin( x * 2.0 * PI  );
  analogWrite(bluePin,value);
}

This works fine and if I change the line "float x = millis()/5000.0;" to something like "float x = millis()/1000.0;" I get a faster flashing LED.

What I would like to do is change the end number to a randomly generated figure but whatever I try just doesn't work.

For example:

void loop()
{
int SPEED = random(1000.0, 5000.0);
  float x = millis()/SPEED;
  int value = 128.0 + 128 * sin( x * 2.0 * PI  );
  analogWrite(bluePin,value);
}

Any help is greatly appreciated. Thanks

Hi, that code will change the speed hundreds of times per second, giving random flashing. You must change the speed less often.

whatever I try just doesn't work

That's not a helpful thing to say in any situation. Say what it does do, why that is wrong and what you want it to do.

Paul

Basically that is a bad way of generating a sin wave because it uses the absolute value from millis, this number will get very big quite quickly.

Use a count that you can reset when the cycle goes round over 360 degrees. Each overflow increment another counter. When this one reaches a certain value reset it an recalculate your random speed value. Use this random speed value in a delay call to control the overall speed of you sin fade.

Apart from being unnecessarily compute intensive, there will be no visual benefit in fading a LED with a sine wave. Changes in brightness will be negligible above half brightness which is where it will spend most of the time, while they will be very noticeable at the minimum levels.

This effect may be overcome by using exponential ramping and there is no need to use complex maths to do this. Your working value can be an "int" - 16 bits which at each step you multiply (or divide) by a fixed factor, such as 1.125. This does not require a multiply operation, merely a shift and add, and division is performed the same easy way.

So now we have a nice triangle wave, but you wanted a simulation of a "smooth" sine wave. Easy! Just flatten the peak and trough of the wave by holding the peak value for a certain delay - perhaps one sixth of the cycle time. Since the "trough" will always be visibly jerky, just set a minimum brightness value to add to the "waveform".

This will be much more visually effective and much more efficient to code.

Hi Guys, thanks for the replies. PaulRB - I tried not to show my frustration in my post but clearly I failed...

"whatever I try just doesn't work" should read "whatever I try will just turn the LED on solid with no change"

Paul__B and Mike, thanks for the feedback, I'll look into changing the code and try again.

If you want to make an LED fade in visual equal increments look to using Gamma Correction. https://en.wikipedia.org/wiki/Gamma_correction

This is what I am using, have 6 LEDs that I want a flicker effect for: Each of my “Stages” is 1/4 of the range of the LED. The Flicker is looking good.

void setup() {

pinMode (led1, OUTPUT);
pinMode (led2, OUTPUT);
pinMode (led3, OUTPUT);
pinMode (led4, OUTPUT);
pinMode (led5, OUTPUT);
pinMode (led6, OUTPUT);
pinMode (BUTTON, INPUT);
pinMode (tran, OUTPUT);

Serial.begin(9600);

}

void stage1() {
digitalWrite(tran, HIGH);
for (int i=0; i<64; i++)
{
analogWrite(led1, i);
analogWrite(led2, i);
analogWrite(led3, i);
analogWrite(led4, i);
analogWrite(led5, i);
analogWrite(led6, i);

int x = random(1,6);
delay(100);
switch(x)
{
case 1:
analogWrite(led1, i0.5);
case 2:
analogWrite(led2, i
0.5);
case 3:
analogWrite(led3, i0.5);
case 4:
analogWrite(led4, i
0.5);
case 5:
analogWrite(led5, i0.5);
case 6:
analogWrite(led6, i
0.5);
}
delay(100);

switch(x)
{
case 1:
analogWrite(led1, i);
case 2:
analogWrite(led2, i);
case 3:
analogWrite(led3, i);
case 4:
analogWrite(led4, i);
case 5:
analogWrite(led5, i);
case 6:
analogWrite(led6, i);
}
Serial.print("section 1: ");
Serial.println(i);
}
delay(100);
}

void stage2() {
for (int i=64; i<128; i++)
{
analogWrite(led1, i);
analogWrite(led2, i);
analogWrite(led3, i);
analogWrite(led4, i);
analogWrite(led5, i);
analogWrite(led6, i);

delay(100);
int x = random(1,6);

switch(x)
{
case 1:
analogWrite(led1, i0.63);
case 2:
analogWrite(led2, i
0.63);
case 3:
analogWrite(led3, i0.63);
case 4:
analogWrite(led4, i
0.63);
case 5:
analogWrite(led5, i0.63);
case 6:
analogWrite(led6, i
0.63);
}
delay(100);
switch(x)
{
case 1:
analogWrite(led1, i);
case 2:
analogWrite(led2, i);
case 3:
analogWrite(led3, i);
case 4:
analogWrite(led4, i);
case 5:
analogWrite(led5, i);
case 6:
analogWrite(led6, i);
}
Serial.print("section 2: ");
Serial.println(i);
}
delay(100);
}

void stage3() {
for (int i=128; i<192; i++)
{
analogWrite(led1, i);
analogWrite(led2, i);
analogWrite(led3, i);
analogWrite(led4, i);
analogWrite(led5, i);
analogWrite(led6, i);

delay(100);
int x = random(1,6);

switch(x)
{
case 1:
analogWrite(led1, i0.76);
case 2:
analogWrite(led2, i
0.76);
case 3:
analogWrite(led3, i0.76);
case 4:
analogWrite(led4, i
0.76);
case 5:
analogWrite(led5, i0.76);
case 6:
analogWrite(led6, i
0.76);
}
delay(100);
switch(x)
{
case 1:
analogWrite(led1, i);
case 2:
analogWrite(led2, i);
case 3:
analogWrite(led3, i);
case 4:
analogWrite(led4, i);
case 5:
analogWrite(led5, i);
case 6:
analogWrite(led6, i);
}
Serial.print("section 3: ");
Serial.println(i);
}
delay(100);
}

void stage4() {

for (int i=192; i<256; i++)
{
analogWrite(led1, i);
analogWrite(led2, i);
analogWrite(led3, i);
analogWrite(led4, i);
analogWrite(led5, i);
analogWrite(led6, i);
int x = random(1,6);

switch(x)
{
case 1:
analogWrite(led1, i0.89);
case 2:
analogWrite(led2, i
0.89);
case 3:
analogWrite(led3, i0.89);
case 4:
analogWrite(led4, i
0.89);
case 5:
analogWrite(led5, i0.89);
case 6:
analogWrite(led6, i
0.89);
}
delay(100);
switch(x)
{
case 1:
analogWrite(led1, i);
case 2:
analogWrite(led2, i);
case 3:
analogWrite(led3, i);
case 4:
analogWrite(led4, i);
case 5:
analogWrite(led5, i);
case 6:
analogWrite(led6, i);
}
Serial.print("section 4: ");
Serial.println(i);
}
delay(100);
}

void loop() {
// put your main code here, to run repeatedly:
Serial.println(“Main”);
stage1();
stage2();
stage3();
stage4();

Thanks for the code bvandyke, that code produces a pretty cool effect. :)

Paul__B, thanks for the min and max value tip, that certainly does help with the visual effect.

The effect might be cool but the code is appalling. The whole thing could be many many times shorter.

I blame copy and paste for such poor code.

And it is not in code tags. You can edit your post you know, don't post that code again.