Can't connect Arduino with Exosite


#1

Hi all, I’m trying to send arduino data to my exosite’s portal via wifi shield.
This is my code:

#include <OpenGarden.h>
#include <EEPROM.h>
#include <SPI.h>
#include <WiFi.h>
#include <Exosite.h>
#include <Wire.h>

String cikData = "21f4ec00000000000000000000000000000000000";  // <-- FILL IN YOUR CIK HERE! (https://portals.exosite.com -> Add Device)
char ssid[] =                  "; // <-- Fill in your network SSID (name)
char pass[] = "             "; // <-- Fill in your network password

// User defined variables for Exosite reporting period and averaging samples
#define REPORT_TIMEOUT 30000 //milliseconds period for reporting to Exosite.com
#define SENSOR_READ_TIMEOUT 5000 //milliseconds period for reading sensors in loop

// Number of Errors before we try a reprovision.
const unsigned char reprovisionAfter = 3;

/*==============================================================================
* End of Configuration Variables
*=============================================================================*/
unsigned char errorCount = reprovisionAfter; // Force Provision On First Loop
char macString[18]; // Used to store a formatted version of the MAC Address
byte macData[WL_MAC_ADDR_LENGTH];

int status = WL_IDLE_STATUS;
class WiFiClient client;
// class EthernetClient client;
Exosite exosite(cikData, &client);

//
// The 'setup()' function is the first function that runs on the Arduino.
// It runs completely and when complete jumps to 'loop()' 
//
void setup() {
  Serial.begin(9600);
  OpenGarden.initSensors();    //Initialize sensors power 

//  Ethernet.begin(macData);
  // wait 3 seconds for connection
//delay(3000); 
  // Create MAC Address String in the format FF:FF:FF:FF:FF:FF
  WiFi.macAddress(macData);
  snprintf(macString, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
    macData[5], macData[4], macData[3], macData[2], macData[1], macData[0]);
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while(true);
  }
 // attempt to connect to Wifi network:
 while ( status != WL_CONNECTED) {
   Serial.print("Attempting to connect to SSID: ");
   Serial.println(ssid);
   // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
  status = WiFi.begin(ssid, pass);
 }
 Serial.println("Connected to Access Point");

 // Print Some Useful Info
 Serial.print(F("MAC Address: "));
 Serial.println(macString);
 Serial.print(F("IP Address: "));
 Serial.println(WiFi.localIP());
}

//
// The 'loop()' function is the 'main' function for Arduino 
// and is essentially a constant while loop. 
//
void loop() {
  static unsigned long sendPrevTime = 0;
  static unsigned long sensorPrevTime = 0; 
  static float airTemperature;
  char buffer[7];
  String readParam= "";
  String writeParam = "";
  String returnString = "";  

  Serial.print("."); // print to show running

 // Read sensor every defined timeout period
    OpenGarden.sensorPowerON();  //Turns on the sensor power supply
    delay(1000); // Time for initializing the sensor
  if (millis() - sensorPrevTime > SENSOR_READ_TIMEOUT) {
    Serial.println();
   
    //sensors.requestTemperatures(); // Send the command to get temperatures
    //float tempC = sensors.getTempCByIndex(0);
    float airTemperature = OpenGarden.readAirTemperature();
    float airHumidity = OpenGarden.readAirHumidity();
    int luminosity = OpenGarden.readLuminosity();
    OpenGarden.sensorPowerOFF();  //Turns off the sensor power supply
    Serial.println("Requesting Temperature...");
    Serial.print("Celsius:    ");
    Serial.print(airTemperature);
    Serial.println(" C ..........DONE");
    Serial.println("Requesting Air Humidity...");
    Serial.print("Air Humidity:    ");
    Serial.print(airHumidity);
    Serial.println(" % RH ..........DONE");
    Serial.println("Requesting Luminocity...");
    Serial.print("Luminocity:    ");
    Serial.print(luminosity);
    Serial.println(" % ..........DONE");
    
    sensorPrevTime = millis();
  }

  // Send to Exosite every defined timeout period
 if (millis() - sendPrevTime > REPORT_TIMEOUT) {
    Serial.println(); //start fresh debug line
    Serial.println("Sending data to Exosite...");

    readParam = "";        //nothing to read back at this time e.g. 'control&status' if you wanted to read those data sources
    writeParam = "temp="; //parameters to write e.g. 'temp=65.54' or 'temp=65.54&status=on'

    String tempValue = dtostrf(airTemperature, 1, 2, buffer); // convert float to String, minimum size = 1, decimal places = 2

    writeParam += tempValue;    //add converted temperature String value

    //writeParam += "&message=hello"; //add another piece of data to send

    if ( exosite.writeRead(writeParam, readParam, returnString)) {
      Serial.println("Exosite OK");
      if (returnString != "") {
        Serial.println("Response:");
        Serial.println(returnString);
      }
    }
    else {
      Serial.println("Exosite Error");
    }

    sendPrevTime = millis(); //reset report period timer
    Serial.println("done sending.");
  }
  delay(1000); //slow down loop
}

I think that my code is fine.
Then, In my portal I added the arduino device, and created a Data with alias “airTemperature” (Like one of my variables). I created a widget (line graph) with that alias. I just not received data to my exosite, and the arduino serial monitor sent me a message “Can’t connect to Exosite”.

Maybe I’m missing something.

Thanks in advance for your answer guys,
Regards,
Norberto G.


#2

@nguardia, I assume you actually have values in the ssid and pass variables, right?

Based on that error message your device isn’t connecting to the platform at all, so it’s not a config issue there, it’s likely something to do with getting on the network.

Have you been able to run any of the standard Arduino demos for the wifi shield? If not, that would be a good place to start with to make sure you can get connected to the internet.

It may also be helpful if you could post the full serial output of the the board booting and trying to write data 3-4 times.


#3

Dear Patrick, thanks for quick answer.

Yes, actually I have values in the “ssid” and “pass”. In the ide of arduino, the serial monitor show me that the wifi shield is connected correctly to the wifi network.
I think that my problem is in configuring the exosite portal to received values.

I ran the example WifiReadWriteString so followed all the steps. However, I don’t know exactly how to receive and displays the data from my arduino. What should I get? I can not understand well how to prepare exosite portal to receive data and display it on the dashboard.

Thanks again for your answer.
Regards,


#4

Any help?

When I configure the arduino, it appear Off until I text any value in the Data label in any variable. Then it turn to On but doesn´t received any data (temperature), and the serial monitor print “Can’t connect to exosite”

Thanks in advance for the reply


#5

Sorry about missing your last message @nguardia.

The activity indicator in portals (the red/green on/off symbol) isn’t smart enough to know if data is coming from your device or not, so when it says “on” after you manually write a value it’s just because of that value, not anything to do with the device connecting.

The “Can’t connect to Exosite” error message means that it can’t even open a connection to our servers, so it can’t possibly be a configuration issue on the platform. If it were a config issue you’d see a message “Error Communicating with Exosite” (or possibly no error at all).

Can you run this sketch and post the full serial output for me:

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char server[] = "m2.exosite.com";
EthernetClient client;

void setup() {
  Serial.begin(9600);
  while (!Serial);

  if (Ethernet.begin(mac) == 0) {
    Serial.println("eth problem");
    while(1); //stop
  }
  delay(1000);

  do{
    Serial.println("connecting");
  } while (!client.connect(server, 80));
  
  Serial.println("connected");

  client.println("GET /timestamp HTTP/1.1");
  client.println("Host: m2.exosite.com");
  client.println("Connection: close");
  client.println();
}

void loop()
{
  if (client.available()) {
    Serial.print((char)client.read());
  } else if (!client.connected()) {
    Serial.println("\n\ndone");
    client.stop();

    while (1); //stop
  }
}

#6

Thanks for your answer Patrick.
We’re using Wifi shield of Arduino instead Ethernet shield. Did your code works for us?

We tested the code below to obtaint the timestamp from Exosite server, and we get this error:
"get unixtime from m2.exosite.com/timestamp
Connecting to Exosite (Time)…No Existing Connection, Opening One…"

Here is the code:

#include <EEPROM.h>
#include <SPI.h>
#include <WiFi.h>
#include <Exosite.h>

String cikData = "0000000000000000000000000000000000000000";  //  CIK not needed for this API call to get TIME, can leave as is here
char macString[18]; // Used to store a formatted version of the MAC Address
byte macData[WL_MAC_ADDR_LENGTH];
int status = WL_IDLE_STATUS;
char ssid[] = "____"; // <-- Fill in your network SSID (name)
char pass[] = "___"; // <-- Fill in your network password

class WiFiClient client;
Exosite exosite(cikData, &client);

/*==============================================================================
* setup
*
* Arduino setup function.
*=============================================================================*/
void setup(){  
  Serial.begin(9600);
  delay(1000);
  Serial.println("Boot");
  Serial.println("Network Setup - start");
  // Create MAC Address String in the format FF:FF:FF:FF:FF:FF
  WiFi.macAddress(macData);
  snprintf(macString, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
    macData[5], macData[4], macData[3], macData[2], macData[1], macData[0]);
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while(true);
  }
 // attempt to connect to Wifi network:
 while ( status != WL_CONNECTED) {
   Serial.print("Attempting to connect to SSID: ");
   Serial.println(ssid);
   // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
  status = WiFi.begin(ssid, pass);
 }
 Serial.println("Connected to Access Point");
 Serial.println("Network Setup - Done");

 // Print Some Useful Info
 Serial.print(F("MAC Address: "));
 Serial.println(macString);
 Serial.print(F("IP Address: "));
 Serial.println(WiFi.localIP());
}

/*==============================================================================
* loop 
*
* Arduino loop function.
*=============================================================================*/
void loop(){
  //Write to "uptime" and read from "uptime" and "command" datasources.
  Serial.println("get unixtime from m2.exosite.com/timestamp");
  exosite.time();
  delay(10000); //delay for 10 seconds for loop
}

#7

Ah, right, my mistake. Here is a version that should work with a WiFi shield (I don’t actually have a WiFi shield to test it with):

#include <SPI.h>
#include <WiFi.h>

char ssid[] = "";    // <-- Fill in your network SSID (name)
char pass[] = "";    // <-- Fill in your network password

char server[] = "m2.exosite.com";

int status = WL_IDLE_STATUS;
class WiFiClient client;

void setup() {
  Serial.begin(9600);
  while (!Serial);


  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    while(true);
  }

  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass);
  }

  Serial.println("Connected to Access Point");

  delay(1000);

  do{
    Serial.println("connecting");
  } while (!client.connect(server, 80));
  
  Serial.println("connected");

  client.println("GET /timestamp HTTP/1.1");
  client.println("Host: m2.exosite.com");
  client.println("Connection: close");
  client.println();
}

void loop()
{
  if (client.available()) {
    Serial.print((char)client.read());
  } else if (!client.connected()) {
    Serial.println("\n\ndone");
    client.stop();

    while (1); //stop
  }
}

Please post the entire serial output of running that code.

Also, Connecting to Exosite (Time)...No Existing Connection, Opening One... isn’t an error message, it’s more for debugging purposes. Our Arduino library tries to be efficient and reuse TCP connections to help with speed, that message just means that there isn’t already a connection open to our platform and it’s telling you it is going to open one.

Whether that succeeds or fails is what the text right after that will tell you, either “Connected” or “Error: Can’t Open Connection to Exosite.”


#8

Hi Patrick,
I just executed the code. This is serial monitor from arduino ide.


#9

It looks like you’re successfully connecting to the network, but the network doesn’t seem to have an actual internet connection. If your network does have some sort of internet connection there may be some issue with a proxy (which AFAIK, no Arduino supports connecting through). Other than that I’m not sure where the problem is and the client libraries don’t provide any debugging information other than “it didn’t work”.

If your network does have an internet connection behind it, I’d suggest heading over to the Arduino Forums as they’ll be much more likely to be able to help you debug the issue.


#10

Dear Patrick,
Finally we fix the problem with the wifi shield. The shield needed upgrade the firmware.

Now I run your last code and this is the response:

Firmware version: 1.1.0
Attempting to connect to SSID: ****
Connected to Access Point
connecting
connected
HTTP/1.1 200 OK
Date: Mon, 19 Oct 2015 14:33:56 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 10
Connection: close
Server: nginx

1445265236

done

It’s look that everything is going good.
Then, I run my code:

#include <OpenGarden.h>
#include <EEPROM.h>
#include <SPI.h>
#include <WiFi.h>
#include <Exosite.h>
#include <Wire.h>

String cikData = "*********";  // <-- FILL IN YOUR CIK HERE
char ssid[] = "********"; // <-- Fill in your network SSID (name)
char pass[] = "********"; // <-- Fill in your network password

// User defined variables for Exosite reporting period and averaging samples
#define REPORT_TIMEOUT 5000 //milliseconds period for reporting to Exosite.com
#define SENSOR_READ_TIMEOUT 5000 //milliseconds period for reading sensors in loop

// Number of Errors before we try a reprovision.
const unsigned char reprovisionAfter = 3;
unsigned char errorCount = reprovisionAfter; // Force Provision On First Loop
char macString[18]; // Used to store a formatted version of the MAC Address
byte macData[WL_MAC_ADDR_LENGTH];
boolean incomingData = false;
int status = WL_IDLE_STATUS;
class WiFiClient client;
Exosite exosite(cikData, &client);    // class EthernetClient client;

void setup() 
{
      Serial.begin(9600);
      Serial.println("Boot");
      OpenGarden.initSensors();    //Initialize sensors power
      WiFi.macAddress(macData);
      snprintf(macString, 18, "90:A2:DA:0F:B1:8C", macData[5], macData[4], macData[3], macData[2], macData[1], macData[0]);
      
      // check for the presence of the shield:
      if (WiFi.status() == WL_NO_SHIELD) 
      {
        Serial.println("WiFi shield not present");
        while(true);    // don't continue:
      }
      
 // attempt to connect to Wifi network:
 while ( status != WL_CONNECTED) 
     {
       Serial.print("Attempting to connect to SSID: ");
       Serial.println(ssid);
       status = WiFi.begin(ssid, pass);
     }
 Serial.println("Connected to Access Point");
}

void loop() 
{
  static unsigned long sendPrevTime = 0;
  static unsigned long sensorPrevTime = 0; 
  static float airTemperature;
  char buffer[7];
  String readParam= "";
  String writeParam = "";
  String returnString = "";  

  Serial.print("."); // print to show running

 // Read sensor every defined timeout period
    OpenGarden.sensorPowerON();  //Turns on the sensor power supply
    delay(1000); // Time for initializing the sensor
  if (millis() - sensorPrevTime > SENSOR_READ_TIMEOUT) 
    {
      Serial.println();
      float airTemperature = OpenGarden.readAirTemperature();
      float airHumidity = OpenGarden.readAirHumidity();
      int luminosity = OpenGarden.readLuminosity();
      OpenGarden.sensorPowerOFF();  //Turns off the sensor power supply
      Serial.print("Celsius:    ");
      Serial.print(airTemperature);
      Serial.println(" C ..........DONE");
      Serial.print("Air Humidity:    ");
      Serial.print(airHumidity);
      Serial.println(" % RH ..........DONE");
      Serial.print("Luminocity:    ");
      Serial.print(luminosity);
      Serial.println(" % ..........DONE");
      sensorPrevTime = millis();
    }

  // Send to Exosite every defined timeout period
 if (millis() - sendPrevTime > REPORT_TIMEOUT) 
    {
      Serial.println(); //start fresh debug line
      Serial.println("Sending data to Exosite...");
      readParam = "";        //nothing to read back at this time e.g. 'control&status' if you wanted to read those data sources
      writeParam = "temp="; //parameters to write e.g. 'temp=65.54' or 'temp=65.54&status=on'
      String tempValue = dtostrf(airTemperature, 1, 2, buffer); // convert float to String, minimum size = 1, decimal places = 2
      writeParam += tempValue;    //add converted temperature String value

    if (exosite.writeRead(writeParam, readParam, returnString)) 
    {
        Serial.println("Exosite OK");
          if (returnString != "") 
          {
            Serial.println("Response:");
            Serial.println(returnString);
          }
    }
    else 
    {
      Serial.println("Exosite Error");
    }

      sendPrevTime = millis(); //reset report period timer
      Serial.println("done sending.");
    }  
  delay(1000); //slow down loop
}

But send me error

Thanks in advance for your answer Patrick.
Regards,
NG


#11

Yep, everything looks good in the first bit.

That is a very odd that you’re seeing that response after seeing the first one work. Are you on an especially high latency internet connection (eg satellite or similar)? When you run the first code how long would you estimate it is between seeing the connected line printed and the HTTP/1.1 200 OK line printed? Is it about 3 seconds (or more)? Right now the library hard codes the timeout time to be 3 seconds. You could try bumping this number up: https://github.com/exosite-garage/arduino_exosite_library/blob/451ebe5688be2645496a5ad3fbed3a541e22dab0/Exosite.cpp#L72 Try setting it ridiculously high, something like 100 seconds (timeout = 100000).

If that doesn’t work, you can try enabling some more of the debugging output by uncommenting one of these: https://github.com/exosite-garage/arduino_exosite_library/blob/451ebe5688be2645496a5ad3fbed3a541e22dab0/Exosite.h#L36-L38 Setting it to 3 is probably going to be the most useful.


#12

Dear Patrick,
I’m using a regular internet connection (home router). The line printed is less than 3 seconds.

I bumped up the timeout to 100000 ms and the “http timeout” error dissapear, but not the “Error communicating to exosite”.
This status will affect the communication if it’s “not activated”?

To be clear. If you look the code, what’s suppose the variables that I need to fill in this fields?

Thanks again for the support.
I think that we’re close to the solution.

Regards,
NG


#13

Okay, not sure if the HTTP timeout is a red herring or not, but I’m pretty sure I understand the current problem.

With the example code that you are using, you should be creating a generic device, not one based on a client model. Devices based on a client model need to be activated using a call to http://m2.exosite.com/provision/activate (doc). You can either call this manually, or use the provisioning call in the arduino library like https://github.com/exosite-garage/arduino_exosite_library/blob/master/examples/WifiProvision/WifiProvision.ino#L108 (you would also then not pass in a CIK to the initialization function as part of activating is getting the CIK directly from the platform.

As for the fields in the Data Setup image, if your code has something like exosite.writeRead("uptime=0&temp=23.3", "led", returnString), you’d want to have three dataports with the aliases “uptime”, “temp”, and “led”. The names are completely up to you and aren’t used by the arduino, only for displaying the info in portals.


#14

Dear Patrick,
No we can receive data from our arduino sensors!

Thanks for your support!

Regards,
NG


#15

Wonderful! Glad to hear it!


#16

A post was split to a new topic: Getting 400 Bad Request Using Arduino Library