5

I can't get the min,max range to function properly. Monitoring the serial, only gives out ~50 difference from the min. I then added truerandom.ino to try to fix, but no help.

const int ledPin = 13; // the number of the LED pin
// Variables will change:
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
//long interval = random(800, 8000); // interval at which to blink (milliseconds)
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
long interval = random(800,8000);
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
Serial.println(interval);
}
}

Added truerandom.ino still ~50 range:

// TrueRandomSeed.ino
//   This example sketch shows how to provide a truly random seed value to the built in 
//   library pseudo random number generator.  This ensures that your sketch will be
//   using a different sequence of random numbers every time it runs.  Unlike the 
//   usually suggested randomSeed(analogRead(0)) this method will provide a much more 
//   uniform and varied seed value.  For more information about the basic technique used
//   here to produce a random number or if you need more than one such number you can 
//   find a library, Entropy from the following web site along with documentation of how
//   the library has been tested to provide TRUE random numbers on a variety of AVR 
//   chips and arduino environments. 
//
//   https://sites.google.com/site/astudyofentropy/project-definition/
//           timer-jitter-entropy-sources/entropy-library
//
//   Copyright 2014 by Walter Anderson, wandrson01 at gmail dot com
//

#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/atomic.h>
// The following addresses a problem in version 1.0.5 and earlier of the Arduino IDE 
// that prevents randomSeed from working properly.
//        https://github.com/arduino/Arduino/issues/575
#define randomSeed(s) srandom(s)

volatile uint32_t seed;  // These two variables can be reused in your program after the
volatile int8_t nrot;    // function CreateTrulyRandomSeed()executes in the setup() 
                         // function.
const int ledPin = 13; // the number of the LED pin
// Variables will change:
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated

void CreateTrulyRandomSeed()
{
  seed = 0;
  nrot = 32; // Must be at least 4, but more increased the uniformity of the produced 
             // seeds entropy.

  // The following five lines of code turn on the watch dog timer interrupt to create
  // the seed value
  cli();                                             
  MCUSR = 0;                                         
  _WD_CONTROL_REG |= (1<<_WD_CHANGE_BIT) | (1<<WDE); 
  _WD_CONTROL_REG = (1<<WDIE);                       
  sei();                                             

  while (nrot > 0);  // wait here until seed is created

  // The following five lines turn off the watch dog timer interrupt
  cli();                                             
  MCUSR = 0;                                         
  _WD_CONTROL_REG |= (1<<_WD_CHANGE_BIT) | (0<<WDE); 
  _WD_CONTROL_REG = (0<< WDIE);                      
  sei();                                             
}

ISR(WDT_vect)
{
  nrot--;
  seed = seed << 8;
  seed = seed ^ TCNT1L;
}

void setup()
{
  CreateTrulyRandomSeed();
  randomSeed(seed);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600); 
  // The preceeding two function calls will take approximately 0.5 second to execute if 
  // nrot is set to 32 ... the rest of your setup code should FOLLOW from here.
}

void loop()
{
  long interval = random(800,8000);
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
Serial.println(interval);
}
}
  • 1
    can you give some example outputs of random sent through serial? – BrettAM Jan 23 '15 at 21:31
  • 818 847 800 842 802 801 818 817 813 849 817 810 808 805 808 810 828 814 818 810 813 817 803 830 803 802 824 829 836 844 804 806 813 849 831 848 806 803 802 833 842 – Eagle1 Jan 23 '15 at 21:47
2

I suspect it actually is generating other values and it's your program logic that's at fault.

Here's what I think you meant your program to do:

  1. Generate a random interval.
  2. Wait until that interval has elapsed.
  3. Start again with a new interval.

Here's what's actually happening:

  1. Generate a random interval.
  2. Check if that interval has elapsed.
  3. Whether or not it has elapsed, generate a new random interval anyway.

Note that you're generating a new random interval every time round loop(). This means your condition just keeps trying new random intervals until one happens (by chance) to be less than the amount of time that's elapsed since the last interval. You're only outputting the interval when that occurs, and evidently it happens on average at least every 50ms.

You can test this theory by outputting interval to serial as soon as you've generated it (i.e. before the if statement). I think you'll find it will flood the serial monitor with a huge range of values.

Fixing the problem should be pretty easy. Just generate your first interval value during setup(). After that, only generate a new random interval value when the old interval has elapsed (i.e. inside the if block). Don't do it every time round the main loop.

1

I had the same problem (random, milliseconds), and in my case what I needed to make was a toy, able to Blink its eye (LED) in a more human way, with variable intervals, so I used the basic "blink without delay" and tweaked until I got a result I wanted. This is my first post here so I hope I'm doing it correctly. Here is the code that worked for me:

const int ledPin =  13;      // the number of the LED pin
unsigned long previousMillis = 0;        // will store last time LED was     updated

 long interval = 4000;           // starting interval at which to blink   (milliseconds)

void setup() {
Serial.begin(9600); 
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}

void loop()
{
digitalWrite(ledPin, HIGH);   

unsigned long currentMillis = millis();


if(currentMillis - previousMillis >= interval) 

{
  // save the last time you blinked the LED 
  previousMillis  = currentMillis;
  interval = random((3, 14) * 1000); 

Serial.println("Blink");
Serial.println(interval);  // Just so I can confirm if the effect seems natural
digitalWrite(ledPin, LOW);
delay(250);
digitalWrite(ledPin, HIGH);
 }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.