Initialize hardware before Cloud Connection

It has become clear that we need a way to initialize our hardware before the WiFi connects to the cloud. Having relays or other devices connected which need their pins and or internal registers initialized as soon as possible is a good thing. Having to wait to do this when the device powers up to connect to the cloud is not IMHO a good way to go. For instance if I have user leds to indicate things and the device looses power and regains power those leds will be in a incorrect state all the while we are waiting to connect to the cloud. If the wifi is down when this happens we have a real problem on our hands then.

I would like to see one of 2 things changed Either add a new function like CriticalInit(); and place this outside of while(1) /* Main loop / in main,.cpp. Or move the function setup(); outside of while(1) / Main loop */ in main,.cpp.

This would then allow us to initialize our devices first, then the unit can connect to the cloud.

Sure, we can add this ourselves. However, I would rather not change the stock code as that can get into all kinds of issues later down the road with updates as they come.

1 Like

I’m a fan of this, maybe this is a good workaround while we wait for the non-blocking cc3000 driver. – I’ll add this as a feature request to the firmware.

Thanks!
David

Good idea, and related to this… I have found trying to initialize hardware such as pinMode() digitalWrite() use of delay() in Class constructors in Application.cpp does not work and can sometimes hang up the Core.

The “multi-threaded” version of core-firmware should technically handle your issue (assuming it starts both threads at the same time), but I’m still not sure about mine. However “multi-threaded” has other downsides…

I’m wondering if we couldn’t solve the pinMode thing by having those functions save whatever params are passed in, and then use those when initializing the hardware later in the initialization?

What I’ve done is split up my libraries to just save constructor details in private variables, like pin numbers, modes… and then have a public method that is used for initialization that I call from setup(); This means we’ll have to re-write this functionality in all arduino libraries that are implemented with pinMode() and digitalWrite(), etc… in constructors… I would think this is non-desirable.

Would you please elaborate on where you are suggesting we “save” params and run “initialization”?

Ah sorry, I was thinking adding something to the system firmware like:

####horrible psuedocode follows:

//system code
var pinDefaults = { A0: null, A1: null ... };
var pinsInitialized = false;

...

//user code before init
pinMode(A0, OUTPUT);

...

//system firmware init
SystemCodeInitializingPins();

//fix for pre-initialized pinMode calls
foreach(pin in pinDefaults.keys) {
  var mode = pinDefaults[pin]; 
  pinMode(pin, mode)
}

####end horrible psuedocode

I guess re-initializing them sounds like a fix… but what about logic in the code that is trying to toggle those pins in constructors with delays as well? My specific failure case was a constructor that was initializing a Shift Register via Software SPI. A lot of times pins are just defined (and set high/low)… but other times they are controlled in the time-domain and that would certainly be an issue to just re-init them later in time.

Maybe we just need to make sure all the low level Arduino Wiring stuff is setup before a Constructor is processed… how to do that is the question. Arduino seems to do it somehow.

I’m not familiar with that specifically, but if I had to guess it would be a matter of performing that hardware initialization before loading user code at all. Maybe in their bootloader? This sounds like a good question for @satishgn and @zachary

Fixed in commit: https://github.com/spark/core-firmware/commit/6e1a7d726cfb8c29b9d9a8660c1249c5a1aac5cb

1 Like