Functioning with wifi and internet drops

Im very familiar with arduino, but not spark. Can you explain the basics of how the com port works?
Mine com ports only go when blue light flashing (and the spark code doesnt work), and then com ports stop when its cyan throbbing.

Blinking blue is in the Listening Mode and we turn on the COM port for users to send serial commands.

COM port is not turned on by default since firmware is flashed OTA. However, you can turn it on in code like how you did in Arduino

@kiwibird1, when you connect the Spark to the core it will not, by default, appear as a COM port. It WILL appear as a COM port when:

  1. You hit the mode button long enough to put the core into wifi learning mode (flashing blue). That allows you to setup wifi over from your PC over the USB connection using a terminal program (eg Putty).

  2. Including Serial.begin() in setup() will start the serial-to-PC interface. This is often used for debugging by printing debug messages to the serial port like what Arduino does.

1 Like

@kiwibird1 a small trick I picked up somewhere… Lets you get your serial connection going before the code executes. Like I was saying earlier you can see your com port in device manager and also see what com port number is being used as well. Putty is great for opening a connection to the com port, just make sure your baud rate matches your initialization of the com port.

void setup() {
    // set D7 to output so we can flash it as a sign we are still alive
    pinMode(D7, OUTPUT);
    // make sure its off
    digitalWrite(D7, LOW);
    
    // init com port to 9600 baud
    Serial.begin(9600);

    // take control of the rgb led    
    RGB.control(true);
    // loop till you hit return in putty
    while (!Serial.available()) {
        RGB.color(0, 255, 0);
        delay(500);
        RGB.color(0, 0, 255);
        delay(500);
    };
    //Turn it off
    RGB.color(0, 0, 0);
    //restore control to spark core of the rgb status led
    RGB.control(false);
}

Great for debugging, I plan on implementing syslog for the spark core later to help debug multiple cores and won’t require me to be connected to a device to debug it.

best of luck!

3 Likes

Its now going but I dont know what I did wrong. Perhaps go to system tools, disable the com port, and re-enable.
Always had to do this with arduino if you remove power from the arduino.

I have my arduino ip now, but it wont ping. I can live with that but its handy to monitor the arduino, as my wifi was dropping

here is updated code

// this code flashes blue gree till you hot enter on putty (serial coms program)
// then prints network details, and has a counter that increments
int cnt1=0;
void setup() {
    // set D7 to output so we can flash it as a sign we are still alive
    pinMode(D7, OUTPUT);// led is on this pin
    // make sure its off
    digitalWrite(D7, LOW);

    // init com port to 9600 baud
    Serial.begin(9600);
       Serial.println("Booting up");


    // take control of the rgb led    
    RGB.control(true);
    // loop till you hit return in putty
    while (!Serial.available()) { // flash blue gree
        RGB.color(0, 255, 0);
        delay(500);
        RGB.color(0, 0, 255);
        delay(500);
    };
    //Turn it off
    RGB.color(0, 0, 0);
    //restore control to spark core of the rgb status led
    RGB.control(false);
}

void loop()
{
    
        // Prints out the network parameters over Serial
    Serial.println(Network.SSID());
    Serial.println(Network.gatewayIP());
    Serial.println(Network.subnetMask());
    Serial.println(Network.localIP());
    Serial.println(Network.RSSI());
        delay(1000);
        digitalWrite(D7,HIGH);
        delay(100);
        digitalWrite(D7,LOW);
    Serial.print("Counter=");
    Serial.println(cnt1++); //print counter=cnt. cnt increaments each time
    
}

ps how do i get the code bracket properly. was i `` or “” or ‘’ on each end?

@kiwibird1, I edited your post to fixt the code area. Use the </> item in the editing menu or hit Ctrl-K after selecting your text to make it a code section. :smile:

Glad you got it going! In most cases you should be able to ping your device from within your local LAN. When your core is running what do you get for your RSSI value? I would make sure your firmware on your router is up to date as well. I have seen on some routers that there is a setting to isolate devices on the WiFi meaning they can only interact with the router and make requests going out. Also I have seen where WiFi devices can’t interact with cabled devices. Some routers provide a diagnostic page where you can issue a ping.

You can also check one step further down the chain if your are connected to the cloud from anywhere you have access to the net. The device id and access token can be retrieved from the web ide.

https://api.spark.io/v1/devices/[deviceId]/?access_token=[accessToken]

Mine looks like this:

https://api.spark.io/v1/devices/48ff6c065067555038591287/?access_token=xxxxxxx

responds with json:

{
“id”: “48ff6c065067555038591287”,
“name”: “raptor_gerbil”,
“connected”: false,
“variables”: null,
“functions”: null
}

Here is a small sketch to pull info like you have and increments a little counter. This counter is exposed via the Spark.variable method, so you can access it via the cloud like so:

https://api.spark.io/v1/devices/48ff6c065067555038591287/counter?access_token=xxxxxxx

Output Looks like this on the com port:

Press Enter to continue
Press Enter to continue
Press Enter to continue

    Device Id: 48ff6c065067555038591287
    CC3000 FW: 1.24
         SSID: GLaDOS
         RSSI: -44
  MAC Address: 8:0:28:FF:FF:1
     Local IP: 10.0.0.13
  Subnet Mask: 255.255.255.0
   Gateway IP: 10.0.0.1
 Gateway Ping: Good
  Google Ping: Good

    User loop starting.

171

Code here:

int counter = 0;

void setup() {
    Spark.variable("counter", &counter, INT);
    
    unsigned char wver[2];
    unsigned char wmac[6];

    pinMode(D7, OUTPUT); // set D7 to output so we can flash it as a sign we are still running
    digitalWrite(D7, LOW); // make sure its off

    Serial.begin(9600); // init com port to 9600 baud

    // This section is here so you have time to setup your com port communications
    // take control of the rgb led    
    RGB.control(true);
    // flashy loop till you hit return in putty
    // I seem to have trouble flashing while in this loop.  hit enter then flash if it doesn't work
    while (!Serial.available()) {
        RGB.color(0, 255, 0);
        delay(500);
        RGB.color(0, 0, 255);
        delay(500);
        Serial.println("Press Enter to continue");
    };
    
    RGB.color(0, 0, 0); //Turn it off
    RGB.control(false); //restore control to spark core of the rgb status led
    
    Serial.println("\n");
    
    Serial.print("    Device Id: ");
    Serial.println(Spark.deviceID());

    Serial.print("    CC3000 FW: ");
    nvmem_read_sp_version(wver); 
    Serial.print(wver[0]); Serial.print("."); Serial.println(wver[1]);
    
    Serial.print("         SSID: ");
    Serial.println(Network.SSID());
    
    Serial.print("         RSSI: ");
    Serial.println(Network.RSSI());
    
    Serial.print("  MAC Address: ");
    Network.macAddress(wmac);  // makes me sad no leading 0
    Serial.print(wmac[5], HEX); Serial.print(":");
    Serial.print(wmac[4], HEX); Serial.print(":");
    Serial.print(wmac[3], HEX); Serial.print(":");
    Serial.print(wmac[2], HEX); Serial.print(":");
    Serial.print(wmac[1], HEX); Serial.print(":");
    Serial.println(wmac[0], HEX);

    Serial.print("     Local IP: ");
    Serial.println(Network.localIP());

    Serial.print("  Subnet Mask: ");
    Serial.println(Network.subnetMask());

    Serial.print("   Gateway IP: ");
    Serial.println(Network.gatewayIP());
 
    Serial.print(" Gateway Ping: ");
    Serial.println((Network.ping(Network.gatewayIP()) > 0 ? "Good" : "Bad"));
 
    Serial.print("  Google Ping: ");
    Serial.println((Network.ping(IPAddress(74,125,228,8)) > 0 ? "Good" : "Bad"));

    Serial.println("\nUser loop starting.\n");
    
}


void loop() {
    static unsigned long lastMillis = millis();
    
    
    if (millisElapsed(lastMillis) >= 1000) {
        lastMillis = millis();
        
        Serial.print("\r");
        Serial.print((++counter), DEC);
    }
}


unsigned long millisElapsed(unsigned long startMillis) {
    unsigned long curMillis = millis();
    
    return curMillis >= startMillis ? curMillis - startMillis : (4294967295ul - startMillis) + curMillis;
}
1 Like

I updated my code, then the spark crashed. com port comes and goes very few seconds, serial not go, couldn’t flash…
spark & I not having a good day. Did factory reset.

/blink_an_led1.cpp:2:32: fatal error: SparkIntervalTimer.h: No such file or directory

  compilation terminated.

my code now wont compile, and I suspect code causes spark to crash.
Can someone please check it.
If the lan goes down, it should beep the number of times lan has gone down.
rssi value was -70. I still couldnt ping it.

// This #include statement was automatically added by the Spark IDE.
#include "SparkIntervalTimer.h"
#include "spark_disable_wlan.h"
#include "spark_disable_cloud.h"

// Read temperature
// -----------------

// Create a variable that will store the temperature value
int temperatureraw = 0;
double voltage=0;
double temperature=0;

// -----------------------------------
// Controlling LEDs over the Internet
// -----------------------------------

// name the pins
int led1 = D0;
int led2 = D1;
int led8 = D7;
int wififailurecounter = 0;
int BeepCounter = 0;

int ledControl(String command);
IntervalTimer myTimer;

// Pre-define ISR callback functions
void turnOnWifi(void);
volatile unsigned long turnOnWifiCount = 0; // use volatile for shared variables
volatile int myTimerOn = 0; // use volatile for shared variables

void setup()
{
    WiFi.off();
  // Register a Spark variable here
// Spark.variable("temperature", &temperature, double);
  Spark.variable("temperature", &temperature, DOUBLE);
  
  Serial.begin(9600);
  Serial.println("Booting up");
  //register the Spark function
  Spark.function("brew", brewCoffee);

  // Connect the temperature sensor to A7 and configure it
  // to be an input
  pinMode(A7, INPUT);
  
      //Register our Spark function here
    Spark.function("led", ledControl);

    // Configure the pins to be outputs
    pinMode(led1, OUTPUT);
    pinMode(led2, OUTPUT);
    pinMode(led8, OUTPUT);

    // Initialize both the LEDs to be OFF
    digitalWrite(led1,LOW);
    digitalWrite(led2,LOW);
    digitalWrite(led8,LOW);
}

void loop()
{
    if (WiFi.status() == WIFI_OFF && myTimerOn == 0)
    {
      myTimer.begin(turnOnWifi, 1000, hmSec);  // turnOnWifi to run every 500ms (1000 * .5ms period) //wifi failed for the first time here.
        myTimerOn = 1;
        //turnOnWifiCount = 0; //peter removed this line
        Serial.println("wifi failed");
        Serial.println(turnOnWifiCount);
        turnOnWifiCount++; //peter changed this line
    }
    
    if (myTimerOn == 1 && WiFi.status() == WIFI_ON)
    { //if wifi now ok, go here.
    Serial.println("wifi ok now");
        myTimer.end();
        myTimerOn = 0;
        turnOnWifiCount = 0;
    }
    
    
    unsigned long blinkCopy;
    noInterrupts();
    blinkCopy = turnOnWifiCount;
    interrupts();
    
    if (blinkCopy > 10)
    { //there have now been 10 failurs. turn wifi off, then on to reset it.
        myTimer.end();
       wififailurecounter++;
        myTimerOn = 0;
        turnOnWifiCount = 0;
        Spark.sleep(1000);
        delay(1000);
        
    }
    
  // Keep reading the temperature so when we make an API
  // call to read its value, we have the latest one
  temperatureraw = analogRead(A7);
  voltage = ( (double)temperatureraw * 3.3)/4095;
 
  temperature  =(voltage-0.5)*100;
 
  
      //digitalWrite(led1,LOW);
      
       
   // delay(1000);

    // Prints out the network parameters over Serial
    Serial.println(Network.SSID());
    Serial.println("test");
    Serial.println("test:");
    Serial.println("wififailurecounter:");
    Serial.println(wififailurecounter);
    Serial.println(Network.gatewayIP());
    Serial.println(Network.subnetMask());
    Serial.println(Network.localIP());
    Serial.println(Network.RSSI()); // strength -127 = no signal.
    Serial.println("wififailurecounter:");
    Serial.println(wififailurecounter);
    
    
      
      delay(1000);
      
          digitalWrite(led8,HIGH);
          digitalWrite(led1,HIGH);
      delay(500);
      
      BeepCounter=wififailurecounter;
      while (BeepCounter >0) //IF IT FAILES, BEEP ONCE FOR EACH FAILURE
      
      {
          BeepCounter--;
             digitalWrite(led1,HIGH);
      delay(500);
         digitalWrite(led1,LOW);
      delay(500);
    
      }
      
      
       digitalWrite(led8,LOW);
     digitalWrite(led1,LOW);
          
          //delay(1000);
           brewCoffee("coffee");
}

// This function gets called whenever there is a matching API request
// the command string format is l<led number>,<state>
// for example: l1,HIGH or l1,LOW
//              l2,HIGH or l2,LOW


//this function automagically gets called upon a matching POST request
int brewCoffee(String command)
{
//look for the matching argument "coffee" <-- max of 64 characters long
if(command == "coffee")
{
  //  digitalWrite(led8,HIGH);
//do something here
//activateWaterHeater();
//activateWaterPump();
return 1;
}
else return -1;
}


void turnOnWifi(void)
{
    WiFi.on();
    turnOnWifiCount = turnOnWifiCount + 1;
    
}


int ledControl(String command)
{
   int state = 0;
   //find out the pin number and convert the ascii to integer
   int pinNumber = (command.charAt(1) - '0') - 1;
   //if (command=="8") pinNumber=7;
   //if (command=="2") pinNumber=1;
   //if (command=="1") pinNumber=0;
   //Sanity check to see if the pin numbers are within limits
   if (pinNumber < 0 || pinNumber > 7) return -1;

   // find out the state of the led
   if(command.substring(3,7) == "HIGH") state = 1;
   else if(command.substring(3,6) == "LOW") state = 0;
   else return -1;

   // write to the appropriate pin
   digitalWrite(pinNumber, state);
  // digitalWrite(7, state);
   
   return 1;
}

Hi somefixitdude
this might be why i cant ping my spark
Press Enter to continue
Press Enter to continue
Press Enter to continue
Press Enter to continue

Device Id: 53ff720xxxxx75535144151387
    CC3000 FW: 1.29
         SSID: virus2
         RSSI: -72
  MAC Address: 8:0:28:59:F0:24
     Local IP: 192.168.2.11
  Subnet Mask: 255.255.255.0
   Gateway IP: 192.168.2.1
 Gateway Ping: Bad
  Google Ping: Bad

User loop starting.

165

late note. I now good pings good but still cant ping spark from my pc

This error indicates that you don't have SparkIntervalTimer.h and SparkIntervalTimer.cpp loaded in web IDE as extra tabs. You can get these files here - they have been updated recently. :smile:

how do i make extra tabs?

@kiwibird1, at the top right hand side of the window you will see a little white circle with a bar

Click on that and two new tabs will appear. Type in the name SparkIntervalTimer and it rename both tabs - one with .cpp extension and the other with .h

You can then cut and paste the code for the two files from the link I gave you. :smile:

I cant compile. see png

HI @kiwibird1

You have a typo in the file name in the tab. You have SparkIntervalTimerh.h and .cpp with an extra “h” at the end and they should be SparkIntervalTimer.h and .cpp

Because the .cpp does a #include of the .h file, the names need to match exactly.

1 Like

complied, but it kills my spark.
usb cycles off and on, code doesnt run. Whats wrong with it
cant update code. led is white. on solid, then off for 1/10 of a second

Hi @kiwibird1

There is a lot going in your code that I don’t understand. It looks like a bunch of sample programs merged together and I am not sure what it is trying to do.

Maybe you could simplify your code to something that is easier to debug?

I don’t know if you can declare a Spark.function and Spark.variable with (1) WiFi off and (2) with the cloud off. These are cloud connected functions and variables and I do not know what will happen.

1 Like

@kiwibird1, I am going to build your code on my own Core to try and understand what you are trying to do. However, it sounds like your code is in a race condition. To recover your Core, you will have to do a factory reset.

First thing I noticed is the way you use IntervalTimer will cause turnOnWifi() to be called EVERY 500ms, continuously, not just once. It takes longer than 500ms for wifi to actually come on and connect but the timer will keep calling it. This may cause the Core to crash. I don’t believe this is what you wanted.

If you can describe what you are trying to achieve, I may be able to help you better.

the big picture is if wifi failes, turn wifi off, then on & increment fail count.

for each fail, do one beep exry x seconds.
ie 3 fails will give 3 beeps

@kiwibird1, if I understand correctly, you want to start with wifi/cloud off. Then you want to attempt to turn on wifi and if it does not connect after some (pre-determined) time, then count the failure and make a beep. Correct? Why would the wifi not connect - are you moving around? How often do you want to “probe” the wifi connection?

I noticed in your code that if the connection fails 10 times, you call Spark.sleep(1000). This will put the wifi module in standby mode the 1000 seconds!!!

You do not need nor should you use IntervalTimer. You can use another library called elapsedMillis to do your timing and create a simple FSM (Finite State Machine) to step through the different “states” of the test.

1 Like

Is putting wifi to sleep likely to fix my problem?
If one gets milli sec and seconds mixed up in life, you are in trouble :frowning:
That explains the crash.
The big picture is the spark looses wifi once per day roughly, and wont recover.
The goal was to get around this , by checking if wifi is down, then turn it off, then on …
notifying me by beep count when this happens

Is putting wifi to sleep likely to fix my problem?

Also, this code crashes straight away, not just when wifi goes down. It means there more wrong in it.