Other articles


  1. Weather Station Code

    Current code (needs some clean up but working) for the weather station that post to both Xively and ThingSpeak.
    

    ThingSpeak Weather Channel Xively Weather Station

    [pre lang="C" wrapline="false"]
    // Includes
    #include <Dhcp.h>
    #include <Dns.h>
    #include <Ethernet.h>
    #include <EthernetClient.h>
    #include <EthernetServer.h>
    #include <EthernetUdp.h>
    #include <ThingSpeak.h>
    #include <Xively.h>
    #include <Wire.h>
    #include <Adafruit_Sensor.h>
    #include <Adafruit_TSL2561_U.h>
    #include <Adafruit_BMP085_U.h>

    // Setup TSL2561 and BMP085 Sensors

    Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 12345);
    Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085);

    // MAC address for your Ethernet shield
    byte mac[] = { 0xDE, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };

    //Uploading Data to two different services for comparisons

    // Your Xively key to let you upload data
    char xivelyKey[] = "YOURKEYHERE";

    // ThingSpeak
    unsigned long myChannelNumber = 000000;
    const char * myWriteAPIKey = "YOURKEYHERE";

    // Define the strings for our datastream IDs for Xively
    char tempID[] = "Temp";
    char lightID[] = "Light";
    char bpID[] = "Barometric_Pressure";
    char wsID[] = "Wind_Speed";

    //Setting up Windspeed
    //Thanks Allison Lassiter - hackerscapes.com for help with anemometer code
    int sensorPin = A0;
    int sensorValue = 0;
    float voltageConversionConstant = .0048828125;
    float windSpeed = 0;
    float sensorVoltage = 0;

    float voltageMin = .4; // Mininum output voltage from anemometer in V.
    float windSpeedMin = 0; // Wind speed in meters/sec corresponding to minimum voltage

    float voltageMax = 2.0; // Maximum output voltage from anemometer in V.
    float windSpeedMax = 32; // Wind speed in meters/sec corresponding to maximum voltage

    //Data structure for Xively data upload
    //Basically one for each sensor
    XivelyDatastream datastreams[] = {
    XivelyDatastream(tempID, strlen(tempID), DATASTREAM_FLOAT),
    XivelyDatastream(lightID, strlen(lightID), DATASTREAM_FLOAT),
    XivelyDatastream(bpID, strlen(bpID), DATASTREAM_FLOAT),
    XivelyDatastream(wsID, strlen(wsID), DATASTREAM_FLOAT)
    };
    // Finally, wrap the datastreams into a feed
    XivelyFeed feed(00000000, datastreams, 4 /* number of datastreams */);

    //Setup Ethernet Client
    EthernetClient client;

    //Setup Xively client
    XivelyClient xivelyclient(client);

    /**************************************************************************/
    /*
    Displays some basic information on this sensor from the unified
    sensor API sensor_t type (see Adafruit_Sensor for more information)
    */
    /**************************************************************************/
    void displaySensorDetails(void)
    {
    sensor_t sensor;
    tsl.getSensor(&sensor);
    Serial.println("------------------------------------");
    Serial.print ("Sensor: "); Serial.println(sensor.name);
    Serial.print ("Driver Ver: "); Serial.println(sensor.version);
    Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
    Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" lux");
    Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" lux");
    Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" lux");
    Serial.println("------------------------------------");
    Serial.println("");
    delay(500);

    }

    void displayBMPSensorDetails(void)
    {
    sensor_t sensor;
    bmp.getSensor(&sensor);
    Serial.println("------------------------------------");
    Serial.print ("Sensor: "); Serial.println(sensor.name);
    Serial.print ("Driver Ver: "); Serial.println(sensor.version);
    Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
    Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" hPa");
    Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" hPa");
    Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" hPa");
    Serial.println("------------------------------------");
    Serial.println("");
    delay(500);
    }

    /**************************************************************************/
    /*
    Configures the gain and integration time for the TSL2561
    */
    /**************************************************************************/
    void configureSensor(void)
    {
    /* You can also manually set the gain or enable auto-gain support */
    // tsl.setGain(TSL2561_GAIN_1X); /* No gain ... use in bright light to avoid sensor saturation */
    // tsl.setGain(TSL2561_GAIN_16X); /* 16x gain ... use in low light to boost sensitivity */
    tsl.enableAutoRange(true); /* Auto-gain ... switches automatically between 1x and 16x */

    /* Changing the integration time gives you better sensor resolution (402ms = 16-bit data) */
    tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS); /* fast but low resolution */
    // tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_101MS); /* medium resolution and speed */
    // tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_402MS); /* 16-bit data but slowest conversions */

    /* Update these values depending on what you've set above! */
    Serial.println("------------------------------------");
    Serial.print ("Gain: "); Serial.println("Auto");
    Serial.print ("Timing: "); Serial.println("13 ms");
    Serial.println("------------------------------------");
    }

    /**************************************************************************/
    /*
    Arduino setup function (automatically called at startup)
    */
    /**************************************************************************/
    void setup(void)
    {
    Serial.begin(9600);
    Serial.println("Light Sensor Test"); Serial.println("");
    // Setup Ethernet

    while (Ethernet.begin(mac) != 1)
    {
    Serial.println("Error getting IP address via DHCP, trying again...");
    delay(5000);
    }
    // print your local IP address:
    Serial.print("My IP address: ");

    for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print(".");
    }

    /* Initialise the BMP sensor */
    if(!bmp.begin())
    {
    /* There was a problem detecting the BMP085 ... check your connections */
    Serial.print("Ooops, no BMP085 detected ... Check your wiring or I2C ADDR!");
    while(1);
    }

    /* Display some basic information on this sensor */
    Serial.println("Found BMP");
    displayBMPSensorDetails();

    /* Initialise the TSL sensor */
    if(!tsl.begin())
    {
    /* There was a problem detecting the ADXL345 ... check your connections */
    Serial.print("Ooops, no TSL2561 detected ... Check your wiring or I2C ADDR!");
    while(1);
    }

    /* Display some basic information on this sensor */

    displaySensorDetails();

    /* Setup the sensor gain and integration time */
    //configureSensor();

    //Setup Thingspeak client
    ThingSpeak.begin(client);

    /* We're ready to go! */
    Serial.println("");
    }

    /**************************************************************************/
    /*
    Arduino loop function, called once 'setup' is complete (your own code
    should go here)
    */
    /**************************************************************************/
    void loop(void)
    {
    /* Get a new sensor event */
    sensors_event_t event;
    sensors_event_t tslevent;
    tsl.getEvent(&tslevent);

    bmp.getEvent(&event);

    /* Display the results (light is measured in lux) */
    if (tslevent.light)
    {
    Serial.print(tslevent.light); Serial.println(" lux");
    //Add Light reading to Xively datastream and ThingSpeak
    datastreams[1].setFloat(tslevent.light);
    ThingSpeak.setField(3,tslevent.light);
    }
    else
    {
    /* If event.light = 0 lux the sensor is probably saturated
    and no reliable data could be generated! */
    Serial.println("Sensor overload");
    }

    /* Display the results (barometric pressure is measure in hPa) */

    if (event.pressure)
    {
    /* Display atmospheric pressue in hPa */
    Serial.print("Pressure: ");
    Serial.print(event.pressure);
    Serial.println(" hPa");

    /Add Event Pressure to Xively datastream and ThingSpeak

    datastreams[2].setFloat(event.pressure);
    ThingSpeak.setField(1,event.pressure);
    /* Calculating altitude with reasonable accuracy requires pressure *
    * sea level pressure for your position at the moment the data is *
    * converted, as well as the ambient temperature in degress *
    * celcius. If you don't have these values, a 'generic' value of *
    * 1013.25 hPa can be used (defined as SENSORS_PRESSURE_SEALEVELHPA *
    * in sensors.h), but this isn't ideal and will give variable *
    * results from one day to the next. *
    * *
    * You can usually find the current SLP value by looking at weather *
    * websites or from environmental information centers near any major *
    * airport. *
    * *
    * For example, for Paris, France you can check the current mean *
    * pressure and sea level at: http://bit.ly/16Au8ol */

    /* First we get the current temperature from the BMP085 */
    float temperature;
    bmp.getTemperature(&temperature);

    datastreams[0].setFloat(temperature);
    ThingSpeak.setField(2,temperature);

    Serial.print("Temperature: ");
    Serial.print(temperature);
    Serial.println(" C");

    /* Then convert the atmospheric pressure, SLP and temp to altitude */
    /* Update this next line with the current SLP for better results */
    float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;
    Serial.print("Altitude: ");
    Serial.print(bmp.pressureToAltitude(seaLevelPressure,
    event.pressure,
    temperature));
    Serial.println(" m");
    Serial.println("");
    }
    else
    {
    Serial.println("Sensor error");
    }

    //Read anemometer
    sensorValue = analogRead(sensorPin);
    sensorVoltage = sensorValue * voltageConversionConstant; //Convert sensor value to actual voltage
    Serial.print("Sensor Value: ");
    Serial.println(sensorValue);

    //Convert voltage value to wind speed using range of max and min voltages and wind speed for the anemometer
    if (sensorVoltage <= voltageMin){
    windSpeed = 0; //Check if voltage is below minimum value. If so, set wind speed to zero.
    //Write to Xively and ThingSpeak
    datastreams[3].setFloat(windSpeed);
    ThingSpeak.setField(4,windSpeed);
    }else {
    //Write to Xively and ThingSpeak
    windSpeed = (sensorVoltage - voltageMin)*windSpeedMax/(voltageMax - voltageMin); //For voltages above minimum value, use the linear relationship to calculate wind speed.
    datastreams[3].setFloat(windSpeed);
    ThingSpeak.setField(4,windSpeed);
    }

    //Add all streams to Xively
    Serial.println("Uploading it to Xively");

    Serial.println(xivelyKey);
    Serial.println(feed);
    int ret = xivelyclient.put(feed, xivelyKey);

    Serial.print("xivelyclient.put returned ");
    Serial.println(ret);

    // Update Thingspeak
    // Write the fields that you've set all at once.
    ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);

    //Print voltage and windspeed to serial
    Serial.print("Voltage: ");
    Serial.print(sensorVoltage);
    Serial.print("\t");
    Serial.print("Wind speed: ");
    Serial.println(windSpeed);
    delay(3000);
    }

    [/pre]

    read more
  2. Weather Station with Anemometer

    I have been chipping away at building an Arduino based Weather Station.  Upgraded to a Arduino Mega as I was running out of memory on the Uno with all the libraries and sensors I was using.

    Have code reading the Anemometer/BMP180/TSL2561 at this point. (more code sharing in upcoming post).

    Using basic Ethernet Shield at the moment for proof of concept.  Will eventually go wireless.

    Also have code writing to an Xively feed at: Weather Station

    Will more than likely play with other sites like Thingspeak and or more Plot.ly.

    read more
  3. Moved proto type off the breadboard

    Used the Adafruit Data Logger prototype area.  A little sloppy but working.  Need to move the BMP180 next time as I realized the pins interfer with the Uno ATmega chip.

    Next steps: figure out power and a simple enclosure.

    Updated the Fritzing diagram to mostly match the project.  There does not appear to be an Adafruit Data Logging part for Fritzing yet and the Barometric sensor has not been updated to the BMP180 (but 85 close enough).

    read more
  4. Arduino Barometer, Light and Temperature Data Logger

    New soldering station "Sparkfun 937b"..a cheap RadioShack board to practice my old soldering skills..an Adafruit datalogger and BMP pressure sensor...tah dah.

    Adafruit:


    Local MicroCenter had the Spackfun 937B so I grabbed it from there. Works really well, agree with most reviews on the holder (it sucks) but had not problem soldering the headers for the Data Logging shield and the BMP180.

    Next steps...use plotly to show results from the logger.

    read more
  5. Dumpster Aluminum Breadboard Base

    Made the aluminum base mate to the one I did for the Uno for the breadboard.  Makes for a much more stable breadboard.


    Finished base after using fly cutter to do the final finish passes and a few quick runs on the disk sander.


    This side as way off as I messed up the cut in the hacksaw. Ran a roughing mill to get it close and now ready for the fly cutter.


    Roughing mill pass.


    Initial cut on hacksaw got away from me - fixed later with roughing mill.


    Fly cutter - pre cut. Actually our of sequence but used this tool later to finish of the block.


    Power Hack Saw! Love this machine.


    Aluminum block from the scrap pile. Came off a big discarded injection mold.

    read more
  6. ThingSpeak - pretty cool

    After messing around with node.js implementation I found some other services that help collect sensor data from devices. They make it pretty easy to embed charts as well:

    This is a simple light meeter in my living room - connected to ThingSpeak channel. Still getting used to the Charts on ThingSpeak but pretty cool so far. Also will look into there are apps soon enough.

    https://thingspeak.com/channels/10735#

    ThingSpeak makes it easy: create and account on ThingSpeak and a simple sketch later you have a collector!

    Sketch:

    [code language="cpp"]
    /*

    Arduino --> ThingSpeak Channel via Ethernet

    The ThingSpeak Client sketch is designed for the Arduino and Ethernet.
    This sketch updates a channel feed with an analog input reading via the
    ThingSpeak API (http://community.thingspeak.com/documentation/)
    using HTTP POST. The Arduino uses DHCP and DNS for a simpler network setup.
    The sketch also includes a Watchdog / Reset function to make sure the
    Arduino stays connected and/or regains connectivity after a network outage.
    Use the Serial Monitor on the Arduino IDE to see verbose network feedback
    and ThingSpeak connectivity status.

    Getting Started with ThingSpeak:

    * Sign Up for New User Account - https://www.thingspeak.com/users/new
    * Register your Arduino by selecting Devices, Add New Device
    * Once the Arduino is registered, click Generate Unique MAC Address
    * Enter the new MAC Address in this sketch under "Local Network Settings"
    * Create a new Channel by selecting Channels and then Create New Channel
    * Enter the Write API Key in this sketch under "ThingSpeak Settings"

    Arduino Requirements:

    * Arduino with Ethernet Shield or Arduino Ethernet
    * Arduino 1.0 IDE

    Network Requirements:

    * Ethernet port on Router
    * DHCP enabled on Router
    * Unique MAC Address for Arduino

    Created: October 17, 2011 by Hans Scharler (http://www.iamshadowlord.com)

    Additional Credits:
    Example sketches from Arduino team, Ethernet by Adrian McEwen

    */

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

    // Local Network Settings
    byte mac[] = { 0xD4, 0x28, 0xB2, 0xFF, 0xA0, 0xA1 }; // Must be unique on local network

    // ThingSpeak Settings
    char thingSpeakAddress[] = "api.thingspeak.com";
    String writeAPIKey = "YOURWRITEAPIKEYHERE"; // YOUR writeAPIKey here
    const int updateThingSpeakInterval = 16 * 1000; // Time interval in milliseconds to update ThingSpeak (number of seconds * 1000 = interval)

    // Variable Setup
    long lastConnectionTime = 0;
    boolean lastConnected = false;
    int failedCounter = 0;

    // Initialize Arduino Ethernet Client
    EthernetClient client;

    void setup()
    {
    // Start Serial for debugging on the Serial Monitor
    Serial.begin(9600);

    // Start Ethernet on Arduino
    startEthernet();
    }

    void loop()
    {
    // Read value from Analog Input Pin 0
    String analogPin0 = String(analogRead(A4), DEC);

    // Print Update Response to Serial Monitor
    if (client.available())
    {
    char c = client.read();
    Serial.print(c);
    }

    // Disconnect from ThingSpeak
    if (!client.connected() && lastConnected)
    {
    Serial.println("...disconnected");
    Serial.println();

    client.stop();
    }

    // Update ThingSpeak
    if(!client.connected() && (millis() - lastConnectionTime > updateThingSpeakInterval))
    {
    updateThingSpeak("field1="+analogPin0);
    }

    // Check if Arduino Ethernet needs to be restarted
    if (failedCounter > 3 ) {startEthernet();}

    lastConnected = client.connected();
    }

    void updateThingSpeak(String tsData)
    {
    if (client.connect(thingSpeakAddress, 80))
    {
    client.print("POST /update HTTP/1.1\n");
    client.print("Host: api.thingspeak.com\n");
    client.print("Connection: close\n");
    client.print("X-THINGSPEAKAPIKEY: "+writeAPIKey+"\n");
    client.print("Content-Type: application/x-www-form-urlencoded\n");
    client.print("Content-Length: ");
    client.print(tsData.length());
    client.print("\n\n");

    client.print(tsData);

    lastConnectionTime = millis();

    if (client.connected())
    {
    Serial.println("Connecting to ThingSpeak...");
    Serial.println();

    failedCounter = 0;
    }
    else
    {
    failedCounter++;

    Serial.println("Connection to ThingSpeak failed ("+String(failedCounter, DEC)+")");
    Serial.println();
    }

    }
    else
    {
    failedCounter++;

    Serial.println("Connection to ThingSpeak Failed ("+String(failedCounter, DEC)+")");
    Serial.println();

    lastConnectionTime = millis();
    }
    }

    void startEthernet()
    {

    client.stop();

    Serial.println("Connecting Arduino to network...");
    Serial.println();

    delay(1000);

    // Connect to network amd obtain an IP address using DHCP
    if (Ethernet.begin(mac) == 0)
    {
    Serial.println("DHCP Failed, reset Arduino to try again");
    Serial.println();
    }
    else
    {
    Serial.println("Arduino connected to network using DHCP");
    Serial.println();
    }

    delay(1000);
    }
    [/code]

    read more

links

social