Porting tips and tricks from Arduino Ethernet to Spark?

Can someone point me to how I can get started with porting an existing program that uses the Ethernet library and associated commands to port to the Spark ?

For example, the porting of this snippet:

 // start the Ethernet connection:
  while (Ethernet.begin(mac) == 0) {
    if (DEBUG1) Serial.println("Failed to configure Ethernet using DHCP");
    // DHCP failed, keep retrying
    Alarm.delay(10000);
}

on the Spark would this translate to:

   while (WiFi.ready() ==false) {

etc?

Thanks for your help.

Cheers,

AJ


I’ve edited your post to properly format the code. Please check out this post, so you know how to do this yourself in the future. Thanks in advance! ~Jordy

Perhaps @peekay123 can shed some light on this, since he’s ported quite a few libraries, if I’m not mistaken.

@aj8uppal, which library (include link if possible) are you trying to port?

Thanks Jordy, I appreciate the much cleaner formating and your link to the blog post that showed me how to do it.

AJ

1 Like

I am using the following libraries: Ethernet.h, Base64.h, Time.h and Timealarms.h. The code also uses spi.h but I suspect it hs there because the Arduino Ethernet uses SPI to go between the ARM chip and the 5100. I dont think I will need that on the Spark. Also I plan to use the HttpClient library from the Spark to make the senddata call a lot cleaner.

Here is the entire code I am trying to port:

#include <SPI.h>
#include <Ethernet.h>
#include <Base64.h>
#include <Time.h>
#include <TimeAlarms.h>


#define DEBUG1 1
#define DEBUG2 1
#define TIMESINTERVAL 10

char authPlain[] = "blah:blah; // <APIkey>:<APIsecret>
String seriesKey="SERIESKEY"; // modify this to give your own series key. 
const unsigned long postingInterval = 30000; // 30 seconds delay between updates to tempo-DB.com
const unsigned long ethernetDead = TIMESINTERVAL*postingInterval; //when to check dead enet
char server[] = "api.tempo-db.com";   // name address for tempo-DB API
int failedattempts = 0;

byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x0D, 0xCE, 0xD3};
  
// initialize the library instance:
EthernetClient client;

// some other placeholders for variables in the code...
unsigned long lastConnectionTime = 0;          // last time you connected to the server, in milliseconds
unsigned long lastSuccessConnectionTime = 0;
unsigned long nowtime = 0;
unsigned long atime = 0;
unsigned long trips = 0;                       // number of loops in the code
unsigned long analogvalue = 0;
unsigned long analogcount = 0;

boolean nowConnected = false;
boolean lastConnected = false;                 // state of the connection last time through the main loop
char authBase64[200]="";                       // will be used to hold the base64 encoded authentication key

void(* resetFunc) (void) = 0;                 //declare reset function @ address 0

// setup runs once during bootup, so use this to set up the environment...
void setup() {
  // base64 encode the authorization key
  base64_encode(authBase64, authPlain, sizeof(authPlain)-1); 
  
  if (DEBUG1) {
    Serial.begin(9600);
      while (!Serial) {
      ; // wait for serial port to connect. Needed for Leonardo only
      }
  }

  if (DEBUG1) Serial.println("running setup...");

 // start the Ethernet connection:
  while (Ethernet.begin(mac) == 0) {
    if (DEBUG1) Serial.println("Failed to configure Ethernet using DHCP");
    // DHCP failed, keep retrying
    //Ethernet.begin(mac, ip);
    Alarm.delay(10000);
  }
  Alarm.timerRepeat(300, CheckEthernet);          // timer for every 5 minutes  
}


void loop() {
 
  analogvalue = analogvalue + analogRead(A0);
  analogcount++;
  
  if (client.available()) {
    char c = client.read();
    if (DEBUG2) {
      Serial.print(c);
    }
  }
  
  atime = millis();
  nowConnected = client.connected();
  if (!nowConnected && lastConnected) {
    if (DEBUG2) Serial.println("disconnecting1");
    client.stop();
    if (DEBUG2) Serial.println("client stopped");
  }

  if (atime - lastConnectionTime > postingInterval) {
    
    if(nowConnected) {
      Serial.println("Now Connected and Stopping Client: ");
      client.stop();
      Alarm.delay(0);
    }
    if (DEBUG2) Serial.print("trips ");
    if (DEBUG2) Serial.println(trips);
 
    analogvalue = analogvalue/analogcount;
    float sensorReading = analogvalue*24.414;
    sendData(sensorReading);
    if(failedattempts > 4) {
      if (Ethernet.begin(mac) == 0) {
        if (DEBUG2) Serial.println("Failed to configure Ethernet using DHCP");
         // DHCP failed, so use a fixed IP address:
         resetFunc();
      }
    }
     trips = 0; 
     analogvalue = 0;
     analogcount = 0;
  }
  // store the state of the connection for next time through
  // the loop:
  lastConnected = client.connected();
  trips++;
  Alarm.delay(0);
}

// this method makes a HTTP connection to the server:
void sendData(float sensorData) {
  // create the JSON formatted DataString using the sensorData value and calculate the length of the resulting
  String dataString = makeDataString(sensorData);
  // you might like to look at this when debugging:
  if (DEBUG2) Serial.println(dataString);
  if (DEBUG2) Serial.println(authBase64);

  // if there's a successful connection:
  if (client.connect(server, 80)) {
    if (DEBUG2) Serial.println("connecting...");
    // send the HTTP PUT request:
    client.print("POST /v1/series/key/");
    client.print(seriesKey);
    client.println("/data/ HTTP/1.1");
    // add the authentication:
    client.print("Authorization: Basic ");
    client.println(authBase64);
    // just for the info on the server: show them you use this code:
    client.println("User-Agent: tempodb-arduino/0.1");
    // just for info of a schizofrene server
    client.println("Host: api.tempo-db.com");
    // string to provide the content-length in the HTTP header.
    client.print("Content-Length: ");
    client.println(dataString.length());
    // last pieces of the HTTP PUT request:
    client.println("Content-Type: application/x-www-form-urlencoded");
    // a blank line is required here before sending the actual data:
    client.println();
    // here's the actual content of the POST request:
    client.println(dataString);
    lastSuccessConnectionTime = millis();
    failedattempts = 0;
  } 
  else {
    // if you couldn't make a connection:
    if (DEBUG2) {
      Serial.println("connection failed");
      Serial.println("disconnecting2");
    }
    failedattempts++;
    client.stop();
  }
   // note the time that the connection was made or attempted:
  lastConnectionTime = millis();
  if (DEBUG2) {
      Serial.println(lastConnectionTime);
    }
}

// make a (short) JSON string to upload the sensor value
String makeDataString(long sensorData) {
  String returnString = String("[{\"v\":");  
  returnString += String(sensorData, DEC); 
  returnString += String("}]");  
return returnString; 
}

void CheckEthernet() {
  Serial.println("Checking Ethernet");
  nowtime = millis();
  if (nowtime - lastSuccessConnectionTime > ethernetDead) {
    Serial.println("Ethernet is dead");
    Serial.print(lastSuccessConnectionTime);
    Serial.print(" ");
    Serial.println(nowtime);
    if (Ethernet.begin(mac) == 0) {
        if (DEBUG2) Serial.println("Failed to configure dead Ethernet using DHCP");
    // DHCP failed, so start again:
    resetFunc();
    }
    else {
      Serial.println("Restarted Ethernet Successfully");
    }
  }
}

Hi @aj8uppal

You won’t need SPI or Time libraries–those are built-in (but there could be some small changes to your code required). Only small changes should needed to change Ethernet to WiFi.

I ported TimeAlarms and it is available on the web IDE or github.

Base64 might just work directly but should not be hard to port in any event.

@aj8uppal, just to support what @bko said, @vk2tds did a port of base64 which may to the trick for you.

There is also an HTTPClient library you can use for the http connection or just adapt what’s there since the Spark code is almost identical. Read up on the Cloud and WiFi firmware functions to find the ethernet replacements. :smile:

1 Like