element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
    About the element14 Community
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      •  Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Internet of Things
  • Technologies
  • More
Internet of Things
Blog Old meets new, the 1-Wire Weather Station on the SPARK Core. (part 5)
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Internet of Things to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: gpolder
  • Date Created: 7 Jan 2015 9:38 PM Date Created
  • Views 3683 views
  • Likes 7 likes
  • Comments 12 comments
  • weather_station
  • 1-wire
  • 1_wire_bus
  • spark_core
  • internet-of-things
Related
Recommended

Old meets new, the 1-Wire Weather Station on the SPARK Core. (part 5)

gpolder
gpolder
7 Jan 2015

In my previous blog posts I mainly focused on the IoT aspects of the project. In Old meets new, the 1-Wire Weather Station on the SPARK Core. (part 2) I showed a scan of the 1-Wire bus, which showed the devices in the 1-Wire Weather Station. In the last one Old meets new, the 1-Wire Weather Station on the SPARK Core. (part 4) I showed how two extra 1-Wire temperature sensors ar read and published in the cloud. In Old meets new, the 1-Wire Weather Station on the SPARK Core. (part 1) I very briefly introduced you to the Weather Station. It's now time to go into more detail into the hardware and the software to read out the weather data.

The description of the hardware is based on a document written by Dan Awtrey from Dallas Semiconductor.(http://www.midondesign.com/Documents/1wire_weather_stn.PDF)

 

1-Wire Weather Station

A diagram of the basic 1-Wire weather station is shown below:

image

 

Eight compass points are directly measured with eight reed switches actuated by a magnet attached to the weather vane axle. Whenever the magnet is between two adjacent reeds both switches close. This supplies an additional eight directions, for a total of sixteen compass points. Note that the bus master can only read wind direction when the DS2407 addressable switch is closed. Similarly, a magnet attached to the wind cups operates a reed switch connected to the DS2423 counter chip that keeps track of the total number of revolutions the cups make and provides the data to the bus master on demand. Ambient temperature is measured with a DS1820 Digital Thermometer. Below is the detailed schematic.

 

image

 

As you can see in the pictures, all 1-Wire devices are connected in parallel to the 1-Wire bus. By issuing a search command on the bus one can find the unique addresses of all these chips:

 

void findDevices() {
    uint8_t addr[12];
    int found = 0;
    int counter;
    while(one.search(addr)) {
        Serial.print("Found device: ");
        char *owID = new char[24];
        sprintf(owID, "%02x%02x%02x%02x%02x%02x%02x%02x",
            addr[0],  addr[1], addr[2] , addr[3] , addr[4] , addr[5], addr[6], addr[7]
        );
        sensors[found].id = owID;

        for(int i=0;i<8;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);
            sensors[found].value = getTemp('C',12);
            Serial.print(" Temperature: " + String(getTemp('C',12)));
            sensors[found].updated = millis();
        }
        if (addr[0] == 0x10) { //  DS1820 temp sensor
            getTempBytes(sensors[found].rom);
            sensors[found].value = getTemp('C',9);
            Serial.print(" Temperature: " + String(sensors[found].value));
            sensors[found].updated = millis();
        }
        if (addr[0] == 0x1D) { //ds2423 counter
            counter = readCounter(sensors[found].rom,2);
            uint32_t now = millis();
            sensors[found].value = ((counter - oldcounter) *1000/(now - timestamp) / 2.0) ;  // in m/s ????
            Serial.print(" Windspeed: " + String(sensors[found].value));
            sensors[found].updated = now;
            timestamp = now;
            oldcounter = counter;
        }
        if (addr[0] == 0x12) { //  DS2407 switch
            setSwitch(sensors[found].rom,dirswitch);
            sensors[found].value = dirswitch;
            Serial.print(" Wind Direction: " + String(winddir));
            sensors[found].updated = millis();
            dirswitch = !dirswitch;
        }
        Serial.println("");
        found++;
    }
    for (int j = found; j<NUM_SENSORS;j++){
        sensors[j].id = NULL;
    }
}

 

Each found device is put into an array of sensor structs:

 

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

 

The first 8 bit (1 byte or 2 Hex characters) of the unique device address identifies the type of 1-wire device. See the family code list for the types.

Based on the family code different routines are used for measuring the specific feature.

 

Temperature

Ambient temperature is measured with the DS1820. This self contained sensor measures temperature as the difference between two oscillators, one of which is temperature dependent. The sensor functions over a -55 to 125°C range and provides plus and minus 0.5°C uncorrected accuracy over 0 to +70 °C. Normally this sensor would be mounted in a separate properly ventilated housing in order to measure ambient temperature as closely as possible. However, the initial design called for a single housing to simplify installation, so the sensor was mounted on the weather station PCB. Since exposure to the sun can raise the inside of the housing as much as 20 degrees higher than ambient, this arrangement can lead to large errors in the reading for many applications. In order to obtain a more accurate measure of ambient temperature an additional DS1820 can be mounted in a suitable separate enclosure and added to the bus by plugging into the daisy-chain connector provided on the PCB. Two functions are used for reading the temperature, getTemp for reading the temperature in Fahrenheit or Celcius and getTempBytes for reading the raw value from the sensor. Temperature can be read in 0.0625 or 0.25 degrees precision, depending on the sensor type used. Here I'm using the DS1820 on the Weather Station PCB, and a DS1822 close to the Spark Core.

 

void getTempBytes(uint8_t *rom) {
    one.reset();
    one.select(rom);
    one.write(0x44);
    delay(500);
    one.reset();
    one.select(rom);
    one.write(0xBE);
    one.read_bytes(resp, 9);
}

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


    float tempRead = ((MSB << 8) | LSB); //using two's compliment
    switch (precision) {
        case 12:
            celcius = tempRead * 0.0625;
            break;
        case 9:
            celcius = tempRead * 0.25;
            break;
    }


    if (unit == 'F') {
        return (celcius * 1.8) + 32;
    } else {
        return celcius;
    }
}

 

Wind direction

The wind direction sensor consists of eight magnetically actuated reed switches mounted radially on a PCB at 22.5 degree intervals. Each reed switch is connected between the data line and a DS2401 Silicon Serial number, which provides an identification number for each switch. A rectangular activating magnet polarized with a single pole facing the reed switch, is mounted in a rotor attached to the weather vane axle. The rotor is designed so that one layout can be used for both the wind speed and direction sensors. When used for wind direction, a single magnet is mounted in either one of the two holes located near the center. As the wind rotates the vane and attached rotor, the magnet closes the switch as it passes over the reed. When a reed is closed, it’s companion DS2401 is connected to the bus (if the DS2407 Addressable Switch is on) and the master can read its serial number. This unique serial number identifies the reed switch, and the compass point it represents. Notice that the bus master can only read wind direction information when the DS2407 addressable switch is closed. This is for isolation reasons, otherwise, communication would be disrupted each time a reed switch closed and the DS2401 associated with it signaled its presence on the line. Communication with the wind direction sensor therefore begins when the bus master turns on the DS2407 output, connecting one side of all the DS2401s to the 1-Wire bus ground line. The weather vane with its rotor and magnet will be activating (closing) at least one of the reed switches connecting the other side of that DS2401 to the data line so the bus master can read its serial number. In the code is defined which compass point each DS2401 identifies, it knows which direction the vane is pointing when a particular DS2401 is on the bus. The eight reed switches directly indicate eight compass points. However, the length of the magnet is such that whenever it is approximately half way between two adjacent reed switches both are closed. The bus master understands that this means the weather vane is midway between two compass points, so eight additional directions are inferred, for a total of sixteen compass points. Unfortunately this is currently not implemented in the software.

The DS2407 is switched on and of in an alternating way by the find devices routine. When it is on the DS2401 which are found (maximal 2) are added to the sensor array, as can be seen in the code above.

 

void setSwitch(uint8_t *rom, bool on)
{
  one.reset();
  one.select(rom);


  one.write(0x55);
  one.write(0x07);
  one.write(0x00);
  if (on) {
    one.write(0x1F); // 1F direction on, 5F direction off
  } else {
    one.write(0x5F); // 1F direction on, 5F direction off
  }
  one.write(0xFF);
  one.write(0xFF);


  one.read_bytes(resp, 6);
  one.reset();
}

 

Wind Speed

Similarly, two magnets mounted on a second rotor attached to the wind cups axle operate a reed switch connected to the DS2423 counter chip which provides a unique identification for this sensor with its 1-Wire serial number. One magnet is mounted in each of the two outermost holes of the rotor. This provides two counts per revolution which improves response at low wind speeds. It also provides rotational balance to the rotor, which becomes important with increasing wind speed, as the rotor can reach 2400 rpm in 160 km/h winds. The DS2423 keeps track of the total number of revolutions the wind cups make and provides the data to the bus master on demand. The chip contains two 232 bit counters and can be powered for ten years with a small Lithium battery, however, here power for the counter chip comes from CR1 and C1 (Figure 1 again) which form a half wave rectifier that “steals” power from the data line. The DS2423 can only be reset to zero when this “parasite power” is lost. Wind speed is calculated by the bus master taking the difference between two counts of the counter used. One count generated before and the other after a clocked interval. The output is currently given in rpm. This later needs to be converted to m/s or km/h.

 

uint32_t readCounter(uint8_t *rom, uint8_t counter)
{
  uint8_t myTA1;

  one.reset();
  one.select(rom);
  one.write(0xA5);

  if (counter == 1) {
    myTA1 = 0xC0;
  }
  else if (counter == 2) {
    myTA1 = 0xE0;
  }

  one.write(myTA1);
  one.write(0x01);
  one.read_bytes(resp, 38);
  one.reset();

  uint32_t count = (uint32_t)resp[35];
  for (int j = 34; j >= 32; j--) {
        count = (count << 8) + (uint32_t)resp[j];
  }
  return count;
}

 

Now all sensor data is placed in the sensor array, we can put them into spark variables for distribution in the cloud this is done in getValues:

void getValues() {
    for(int i=0;i<NUM_SENSORS;i++) {
        if (sensors[i].id != NULL) {
            String strid(sensors[i].id);
            if (strid == "10c1613c000000d5") {
                temperature = sensors[i].value;
            }
            if (strid == "22e8300300000011") {
                temperature1 = sensors[i].value;
            }
            if (strid == "224a3f030000004c") {
                temperature2 = sensors[i].value;
            }
            if (strid == "1d9b1101000000b4") {
                windspeed = sensors[i].value;
            }
            if (strid == "017d384a04000030") {
                winddir = 0;
            }
            if (strid == "018c384a04000075") {
                winddir = 1;
            }
            if (strid == "0174384a040000a6") {
                winddir = 2;
            }
            if (strid == "0177384a040000ff") {
                winddir = 3;
            }
            if (strid == "017a384a040000b5") {
                winddir = 4;
            }
            if (strid == "016b384a040000d9") {
                winddir = 5;
            }
            if (strid == "0183384a04000051") {
                winddir = 6;
            }
            if (strid == "0180384a04000008") {
                winddir = 7;
            }
        }
    }
}

 

Note that the unique addresses are hard coded in this function. This is done for better understanding of the software. In a practical application its better to put these in defines in the upper part of the code, or in a separate header file.

findDevices and getValues are called from the main loop. For testing we now have a delay of 10 seconds, but for the real application this can be much longer, as the minimal probing time from the cloud service (Atomiot) is 5 minutes, but half an hour is much more appropriate. Eventualy a average over this time span can be calculated, but since we want to run the Core on solar power it's better to put it into sleep for a long period.

 

void loop() {
  Serial.println("Spark One-wire weatherstation");
  Serial.println("waiting 10 seconds...");
    delay(10000);


    findDevices();
    getValues();
}

 

After some cleaning of the code I will put the full program listing on github, so please stay tuned.

Next time I will have a look at the hardware of the solar power and battery charger.

Don't hesitate when you have some questions.

  • Sign in to reply

Top Comments

  • DAB
    DAB over 11 years ago +1
    I like the simple design. I remember I got a similar weather kit about 45 years ago that also used mechanical switches to determine the same parameters. It will be interesting to see if you get any switch…
  • gpolder
    gpolder over 11 years ago in reply to DAB +1
    @DAB thanks. I don't see any bounce problems, either with the direction sensors or the counter. I expect this is handled by the 1-wire devices. Gerrit.
  • Former Member
    Former Member over 10 years ago +1
    Hi Gerrit, The article made me look to my 1-Wire weather station again, it was on a shelf for many years. I'm currently trying to get the code running, upto part4 everything works, the final integration…
  • gpolder
    gpolder over 10 years ago in reply to Former Member

    Rudy,

     

    I quickly had a look, it appeared that due to the transition from Spark to Particle, my code also doesn't compile anymore.

    So it needs to be upgraded to the new naming scheme. See https://docs.particle.io/guide/getting-started/intro/core/ for details.

    Please let me know about your progress.

    Best, Gerrit.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Former Member
    Former Member over 10 years ago in reply to gpolder

    HI Gerrit, thanks for the feedback.

    when i put everything together from step 5 it doesn't compile, i added the changes to step 3 or 4. So of you have a piece of code that compiles for you you would do me a big favour.

    The version I have is from 1998, so I asume it is the initial.

    looking forward,

    all the best for the New Year

    rudy

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • gpolder
    gpolder over 10 years ago in reply to Former Member

    Hi Rudy,

     

    great to hear that you put your 1-Wire weather station in service again. To my opinion it is a very neat piece of equipment, strong due to its simplicity.

    What exactly is your problem in step 5? Did you realize that the wind direction sensors addresses are hard coded, and needs to be adapted to your specific hardware?

    I realize just now that I never put my code on github, I will look into that soon, but the code in the post above should get you going.

    Another thing to check is whether you have exactly the same hardware, if I remember well, there was a newer version with a slightly different circuit design.

    Best, Gerrit.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Former Member
    Former Member over 10 years ago

    Hi Gerrit,

    The article made me look to my 1-Wire weather station again, it was on a shelf for many years. I'm currently trying to get the code running, upto part4 everything works, the final integration of the weatherstation in part5 is not working for me. Do you have a link to the code somewhere for me ? I really would be happy in getting this going again.

    I considered the TINI 15 years ago and never got to it, these days I have lot's of fun with the Sparks and Photon.

    So if you could help me out it would really be appreciated.

    KR,Rudy

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • gadget.iom
    gadget.iom over 11 years ago

    Looks very good!

    Interested to see how it develops. image

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
<>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2026 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube