Random_seed_from_cloud - Not Working?

I’m attempting to use random_seed_from_cloud() as described in the Photon documentation. However my random_seed_from_cloud() function goes not ever seem to be called.

The code is as simple as this, which stores the seed in a global variables. The global never changes from 42

unsigned int g_seed = 42;
void random_seed_from_cloud(unsigned int seed);
void random_seed_from_cloud(unsigned int seed)
{
  g_seed = seed;
}

The rest of the sketch is just code to print g_seed to the serial port.

I’ve tried this with with and without SYSTEM_THREAD( ENABLED ).

Does random_seed_from_cloud work? It’s fairly cleanly documented. I don’t see anyone discussing its use.

I noticed the other method for seeding random numbers (publishing to spark/device/random) but I’d prefer to avoid the additional round-trip time.

@Forged, I believe you are misinterpreting the way the firmware does the seeding. The documentation says:

Fortunately, when the device connects to the cloud, it receives a very randomized seed value, which is used as the random seed. So you can be sure the random numbers produced will be different each time your program is run.

When the device receives a new random seed from the cloud, it's passed to this function:
void random_seed_from_cloud(unsigned int seed);

So on the initial connection to the cloud the firmware will fetch a new random seed unless you disable this functionality. You can set your own seed by calling randomSeed(seed value). I have seen code, for example, that uses an analog input as a seed value with randomSeed(analogRead(A0));. The call you are attempting is itself called when the seed is obtained from the cloud so it doesn't do what you expect. I don't believe there is a user function to do an ad-hoc random seed fetch from the cloud. :smile:

I believe my understanding is the same as yours. I am not calling random_seed_from_cloud myself. Rather, I expect the system to call it once connected. I guess I was unclear in my post or sketch.

I’ve simplified the sketch to demonstrate what I’m talking about. I’ve included the entirety of it below.

I would expect this sketch to print ‘1’ repeatedly to the serial port. Instead, it prints ‘0’, even after connected. What do others expect the behavior of this sketch to be?

Thanks for any help!

SYSTEM_THREAD( ENABLED );

int g_value = 0;

void random_seed_from_cloud( unsigned int seed );

void random_seed_from_cloud( unsigned int seed )
{
  g_value = 1;
  srand( seed );
}

void setup()
{
  Serial.begin( 9600 );
}

void loop()
{
  Serial.println( g_value );
}

Perhaps I should also mention why I care.

I noticed that the stream of numbers produced by rand() in my sketches is the same every run. So I began to suspect that srand() is not getting a random seed on connection.

Ping @mdma

Hi @Forged

Have you tried using the publish/subscribe method shown in the doc’s:

    Particle.subscribe("spark/", handler);
    Particle.publish("spark/device/random");

I saw the “spark/device/random” method, but I have not tried it. I was thinking I wouldn’t need to wait for the additional round-trip if I used the seed from random_seed_from_cloud().

In any case I’ve moved forward seeding with Time.now(). (In my case it’s not important that my seed be truly random.)

But I wanted to report the issue in case I had stumbled across a real issue.

What is supposed to happen is–when the session key message from the Particle cloud is received by the device:

  • If you want to use the random seed from the cloud, you write no code–it just happens.

  • If you want to override the random seed from the cloud, you write the random_seed_from_cloud function and then you can ignore the passed in seed or modify it etc.

I don’t see how the linkage to random_seed_from_cloud is supposed to happen right now and I did not find a test for this feature in the code. Maybe @mdma can clear up the mystery.

OK. Thanks.

In this compare I see code that weakly links random_seed_from_cloud(). But that does not seem to be in the head revision. I have not investigated further.

As a further test of the seeding process, I wrote this sketch. Instead of producing a random number every flash, it always prints the same number, 1481765933.

The ten second delay is probably unnecessary, but I added it to make doubly sure the Photon was connected. It was always breathing cyan well before the serial output began.

int g_value = 0;

void setup()
{
  Serial.begin( 9600 );
  delay( 10 * 1000 );
}

void loop()
{
  if ( g_value == 0 && Particle.connected() )
  {
    g_value = rand();
  }
  Serial.println( g_value );
}

I’m having the same issue. Any chance this is fixed in the upcoming 0.4.9 firmware @mdma?

I’m not sure at present why this isn’t working for you - I’ll add this to our backlog and add some tests for this.

On the Photon/Electron the STM32F2 has a RNG. You can use it by calling
HAL_RNG_GetRandomNumber()

e.g.

void setup()
{
    uint32_t seed = HAL_RNG_GetRandomNumber();
    srand(seed);
}
1 Like

I’ve identified the issue - the default case (when random_seed_from_cloud() was not defined) wasn’t correctly handled. This will be resolved in 0.5.0. In the meantime you can add this to your firmware:

void random_seed_from_cloud(unsigned seed) {
   srand(seed);
}
2 Likes

I had the same problems with my Electron. The work-arounds didn’t help. There might be larger issues here like the seed from cloud effectively overriding my srand(seed). I gave up and am happily using the HAL_RNG_GetRandomNumber() to get different random numbers every time my sketch runs.

Hi @Erhughes1944

Yes, the current behavior is confusing since you have to build locally to override non-random random number in 0.4.8.

In 0.5.0 this is all fixed.

This issue seems to be back in 0.6.1-rc1. Adding the below code fixes it.

void random_seed_from_cloud(unsigned seed) {
  srand(seed);
}

I’m also having this issue in 0.6.1 (and @mdma’s workaround fixed the issue).

Much to my surprise, the code I wrote to generate version 4 UUID was generating the exact same sequence of UUID after each reset. Using HAL_RNG_GetRandomNumber() fixed the issue as mentioned above.