In Old meets new, the 1-Wire Weather Station on the SPARK Core. (part 1) I described the motivation of the project. This part will focus on the first steps of programming the SPARK Core and interfacing it to the 1-Wire bus.

I don't repeat the information which can be found on the spark.io website and user forum, just a description of what I did to get the project going and some opinions about the spark.io system.

 

Although the SPARK language is almost similar to Arduino, it can not be programmed with the Arduino software. But the good thing is that there is a complete online IDE available at spark.io. It's a bit comparable to mbed.org which I think was the first online microcontroler IDE. Different from mbed is that you don't need a physical connection like usb to the computer. The SPARK Core is completely programmed from the cloud using its wifi connection. That has a big benefit, as it makes it possible to update the software remotely, even from the other side of the globe if you want. In my case I'm planning to put the weather station on a pole in the backyard, and power it with a solar panel charged battery, so a complete self contained remote system. Since a good connection between the weather station and my wifi network is needed I'm using the Core with a uFL connecter and separate antenna which should give a more stable connection than the version with the chip antenna. The process to initially connect it to the spark cloud using a wifi network is wel described on the spark.io website.


Here is a photo of my initial testing setup. There are two DS1822 1-Wire temperature sensors on the breadboard, and a connection to the weather station.

iPhoto.png

iPhoto.png


Although the SPARK Core is not an Arduino, lots of Arduino libraries are compiled for the Core and works out of the box. This is also the case for the one wire library as can be seen on the following IDE screen shot.

Spark.png

So I hacked some code together, based on available examples. Using the web IDE it can be compiled by pressing the checkmark and uploaded to the Core using the lightning sign. Using the web IDE is very approachable, but uploading the software takes a lot of time, even 80s in my case, where compiling only takes just a few seconds. When pressing the lightning sign, the led on the Core first starts flashing magenta (blue red)  for quite some time, then breezing cyan shortly, then it starts flashing green, and breezing cyan again. During this time sometimes also firmware updates are carried out, which makes the process even more slow.

When running the code, I often see that there are problems on the board, while the led starts flashing SOS in red, followed by some initialization flashing green/cyan etc, but always it starts up again. For a detailed description of the led colors see the spark.io website.

 

Here is a listing of my code:

// This #include statement was automatically added by the Spark IDE.
#include "OneWire/OneWire.h"
#include "OWSensor.h"


#define NUM_SENSORS 2


OneWire one = OneWire(D3);
uint8_t resp[9];
char myIpAddress[24];
char tempfStr[16];
double temperature = 0;
int test = 0;


//unsigned int lastTime = 0;

OWSensor sensors[NUM_SENSORS];
int checkIndex = 0;


void getTempBytes(uint8_t *rom) {
    // Get the temp
    one.reset();
    one.write(0x55);
    one.write_bytes(rom,8);
    one.write(0x44);
    delay(10);

    //ask for the temperature from
    one.reset();
    one.write(0x55);
    one.write_bytes(rom, 8);
    one.write(0xBE);
    one.read_bytes(resp, 9);
}


float getTemp(char unit) {
    byte MSB = resp[1];
    byte LSB = resp[0];

    float tempRead = ((MSB << 8) | LSB); //using two's compliment
    if (unit == 'F') {
        float TemperatureSum = tempRead / 16;

        //Multiply by 9, then divide by 5, then add 32
        float fahrenheit =  ((TemperatureSum * 9) / 5) + 32;

        if (fahrenheit > 7000) {
            fahrenheit = 7404 - fahrenheit;
        }
        return fahrenheit;
    } else {
        float celcius = tempRead * 0.0625;
        return celcius;
    }
}




void findDevices() {
    uint8_t addr[12];
    int found = 0;
    while(one.search(addr)) {

        Serial.print("Found device: ");

        char *owID = new char[24];
        sprintf(owID, "%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            addr[0],  addr[1], addr[2] , addr[3] , addr[4] , addr[5], addr[6], addr[7] , addr[8]
        );
        sensors[found].id = owID;

        for(int i=0;i<9;i++)
        {
            sensors[found].rom[i] = addr[i];
        }

        sensors[found].updated = 0;

        Serial.print(owID);

        if (addr[0] == 0x22) { //ds1822 temp sensor
            getTempBytes(sensors[found].rom);
            temperature = getTemp('C');
            sensors[found].value = temperature;
            Serial.print(" Temperature: " + String(temperature));
            sensors[found].updated = millis();
        }
        Serial.println("");
        found++;
    }
}


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

    findDevices();

    IPAddress myIp = WiFi.localIP();
    sprintf(myIpAddress, "%d.%d.%d.%d", myIp[0], myIp[1], myIp[2], myIp[3]);
}



void loop() {
    Serial.println("waiting 3 seconds...");
    delay(3000);


    findDevices();
}










 

And a separate header file for a struct holding sensor data:

class OWSensor {
    public:
        char *id ;
        uint8_t rom[8];
        float value ;
        int updated ;
};





 

As you can see output of the software is done using a serial connection. For this you need to connect the usb port available in the Core to a pc and use a terminal program to see the output. I used the Arduino software for that. The output looks like:

waiting 3 seconds...
Found device: 10c1613c000000d55f
Found device: 22e83003000000115f Temperature: 21.312500
Found device: 224a3f030000004c5f Temperature: 21.312500
Found device: 122aaa0d000000eb5f
Found device: 1d9b1101000000b45f
waiting 3 seconds...
Found device: 10c1613c000000d563
Found device: 22e830030000001163 Temperature: 21.312500
Found device: 224a3f030000004c63 Temperature: 21.312500
Found device: 122aaa0d000000eb63
Found device: 1d9b1101000000b463
waiting 3 seconds...
Found device: 10c1613c000000d563
Found device: 22e830030000001163 Temperature: 21.312500
Found device: 224a3f030000004c63 Temperature: 21.312500
Found device: 122aaa0d000000eb63
Found device: 1d9b1101000000b463






 

So you see it finds the two temperature sensors on the breadboard (address 22..........) and shows the measured temperature.

On the weather station it finds three devices, according to the device addresses (1-Wire Device Command Code Table) these are:

  1. 10.............. - the 18S20 temperature sensor
  2. 12.............. - the 2406 dual addressable switch
  3. 1d.............. - the 2423 counter

This list confirms the schematic which I showed in my previous blog post.

 

Although we have some output now, it is not an internet of things. Therefore the data needs to be placed somewhere on a website in the cloud, in stead of sent over a serial link to my pc.

 

In my next blog post I will focus on possibilities for publishing the weather data.

Stay tuned!