Jump to content

Banner.jpg.b89429c566825f6ab32bcafbada449c9.jpg

Arduino Based Weather Station


Gina

Recommended Posts

Here is a screenshot from SketchUp showing a cross-section view of the centre main support structure for 3D printing.  This is the exact model of the printed part except that I have applied the cross-section tool.  It fits on the 1" OD aluminium tube top section of the main mast.

56b9cdc33fd97_WineVaneBearingSupportCros

Link to comment
Share on other sites

Worked out the spacing of the optical sensors with them soldered to stripboard and the appropriate sized Gray encoder disc.  Here is a screenshot of the SketchUp model.

56ba224b27eab_WinVaneEncoderDisc02.thumb

Link to comment
Share on other sites

Yes, indeed :)  I don't know where my original drawings went but I'll try to explain without.  I might redraw them.

Basically the 4th sensor is on the outer track but at 90 degrees to the other sensors.  I'll explain this from the basic Gray code :-

  1. 0000
  2. 0001
  3. 0011
  4. 0010
  5. 0110
  6. 0111
  7. 0101
  8. 0100
  9. 1100
  10. 1101
  11. 1111
  12. 1110
  13. 1010
  14. 1011
  15. 1001
  16. 1000
  17. 0000  repeat of no.1

Careful examination shows that the MSB and next bit are both 8 segments (half a revolution) but displaced by 90°.  This means that the same track can be used for both bits but with the sensors at 90°.  Doing this saves space.

Here's a 4 track Gray encoder disc.  As may be seen, the red track is the same as the black track but rotated 90°.  So three sensors in line read bits 134 and another at 90° also uses the black track but is placed at 90° to the other sensors and corresponds to bit 2.

56ba55fd82879_GrayEncoderDisc4Track.thum

 

Edited by Gina
  • Like 1
Link to comment
Share on other sites

The optical sensors are type TCRT5000 which appear to need more supply current but also provide greater phototransistor current.  Just as well I'm now hard wiring the power supply instead of relying on parasitic power from the 1-wire bus though I guess I could try reducing the IR LED current as I don't need a lot of PT current since it will feed a CMOS device whether DS2450 quad A/D or DS2408 8 bit PIO.

Here is an example of one connected directly to an Arduino.

56b238ae500e2_TRCT5000OpticalSensor01.JP

Link to comment
Share on other sites

Here is a diagram showing the layout of the optical sensors and the top flange which will be fastened to the lid and anemometer base and to the centre main support.  There's more electronics to be mounted so the small pieces of stripboard shown will probably be bigger and might even link up depending on how the component layout works out.

56bb8add03174_SensorLayout01.thumb.JPG.3

Edited by Gina
  • Like 1
Link to comment
Share on other sites

Production is under way again.  Firstly the centre support part.  Fits on top of the mast, supports ball bearing for wind vane and top flange part that takes the saucepan lid and anemometer.  The top flange will be coming next.

56bcb37a86d0e_WineVaneBearingSupport01.J

Edited by Gina
Link to comment
Share on other sites

Having printed a couple of parts for the wind vane hub and direction sensor casing, I find the space is too deep so I'm redesigning the parts.  Here is a new cross-section diagram.

56bd1fa7962e0_WineVaneBearing02.thumb.JP

Link to comment
Share on other sites

I shall soon be ready to test the wind vane encoder and anemometer so I'm checking up on the 1-wire sketches for accessing the present 1-wire devices and seeing if these obsolete devices are still accessible, because if they are and I can get things working it will save me devising something new.

The two chips used are the DS2423 dual counter and the DS2450 quad A/D converter.  These are already mounted onto stripboard and modification for the new sensors is just a matter of changing resistors and wiring up to the new sensors instead of the IR LED and phototransistor separate components.

Here is an example sketch for the DS2423 - reading the counters is so simple :)

/*
 *   DS2423Counter
 *
 *   This example demonstrates the use of the DS2423 library and the Arduino
 *   OneWire library to read a counter value from a Dallas Semiconductor DS2423.
 *
 *   by Joe Bechter
 *
 *   (C) 2012, bechter.com
 *
 *   All files, software, schematics and designs are provided as-is with no warranty.
 *   All files, software, schematics and designs are for experimental/hobby use.
 *   Under no circumstances should any part be used for critical systems where safety,
 *   life or property depends upon it. You are responsible for all use.
 *   You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided
 *       1. No part of this software or design may be used to cause injury or death to humans or animals.
 *       2. Use is non-commercial.
 *       3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source.
 *
 */

#include <Arduino.h>
#include <OneWire.h>
#include <DS2423.h>

// define the Arduino digital I/O pin to be used for the 1-Wire network here
const uint8_t ONE_WIRE_PIN = 2;

// define the 1-Wire address of the DS2423 counter here
uint8_t DS2423_address[] = { 0x1D, 0x76, 0x31, 0x09, 0x00, 0x00, 0x00, 0x33 };

OneWire ow(ONE_WIRE_PIN);
DS2423 ds2423(&ow, DS2423_address);

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

void loop() {
    ds2423.update();
    if (ds2423.isError()) {
        Serial.println("Error reading counter");
    } else {
        Serial.print("Count = ");
        Serial.println(ds2423.getCount());
    }
    delay(500);
}

Now to the DS2450.  One of the examples in the Arduino Library as published on GitHub is for wind direction, would you believe, so the job is pretty much done for me :)

/*
 *   DS2450Direction
 *
 *   This example demonstrates the use of the DS2450 library and the Arduino
 *   OneWire library to read wind vane direction from a Dallas Semiconductor DS2450
 *   quad a/d in an AAG wind vane.
 *
 *   by Joe Bechter
 *
 *   (C) 2012, bechter.com
 *
 *   Tim Bitson's "Weather Toys" was used as a reference for the voltage table and direction selection algorithm.
 *
 *   All files, software, schematics and designs are provided as-is with no warranty.
 *   All files, software, schematics and designs are for experimental/hobby use.
 *   Under no circumstances should any part be used for critical systems where safety,
 *   life or property depends upon it. You are responsible for all use.
 *   You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided
 *       1. No part of this software or design may be used to cause injury or death to humans or animals.
 *       2. Use is non-commercial.
 *       3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source.
 *
 */

#include <Arduino.h>
#include <OneWire.h>
#include <DS2450.h>

// define the Arduino digital I/O pin to be used for the 1-Wire network here
const uint8_t ONE_WIRE_PIN = 2;

// define the 1-Wire address of the DS2450 quad a/d here (lsb first)
uint8_t DS2450_address[] = { 0x20, 0x1C, 0x86, 0x00, 0x00, 0x00, 0x00, 0x9E };

// define North offset here
const int NORTH_OFFSET = 0;

OneWire ow(ONE_WIRE_PIN);
DS2450 ds2450(&ow, DS2450_address);

const float directionTable[16][4] = {
        { 4.5, 4.5, 2.5, 4.5 }, // N
        { 4.5, 2.5, 2.5, 4.5 }, // NNE
        { 4.5, 2.5, 4.5, 4.5 }, // NE
        { 2.5, 2.5, 4.5, 4.5 }, // ENE
        { 2.5, 4.5, 4.5, 4.5 }, // E
        { 2.5, 4.5, 4.5, 0.0 }, // ESE
        { 4.5, 4.5, 4.5, 0.0 }, // SE
        { 4.5, 4.5, 0.0, 0.0 }, // SSE
        { 4.5, 4.5, 0.0, 4.5 }, // S
        { 4.5, 0.0, 0.0, 4.5 }, // SSW
        { 4.5, 0.0, 4.5, 4.5 }, // SW
        { 0.0, 0.0, 4.5, 4.5 }, // WSW
        { 0.0, 4.5, 4.5, 4.5 }, // W
        { 0.0, 4.5, 4.5, 2.5 }, // WNW
        { 4.5, 4.5, 4.5, 2.5 }, // NW
        { 4.5, 4.5, 2.5, 2.5 }  // NNW
    };

const char directions[17][4] = {
        "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE",
        "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW",
        "Err"
    };


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

void loop() {
    ds2450.update();
    if (ds2450.isError()) {
        Serial.println("Error reading from DS2450 device");
    } else {
        int direction = 16;
        float ch_a = ds2450.getVoltage(0);
        float ch_b = ds2450.getVoltage(1);
        float ch_c = ds2450.getVoltage(2);
        float ch_d = ds2450.getVoltage(3);
        for (int i = 0; i < 16; i++) {
            if (((ch_a < directionTable[i][0] + 1.0) && (ch_a >= directionTable[i][0] - 1.0)) &&
                    ((ch_b < directionTable[i][1] + 1.0) && (ch_b >= directionTable[i][1] - 1.0)) &&
                    ((ch_c < directionTable[i][2] + 1.0) && (ch_c >= directionTable[i][2] - 1.0)) &&
                    ((ch_d < directionTable[i][3] + 1.0) && (ch_d >= directionTable[i][3] - 1.0))) {
                direction = (i + NORTH_OFFSET) % 16;
                break;
            }
        }
        Serial.println(directions[direction]);
    }
    delay(500);
}

 

Link to comment
Share on other sites

I noticed mention of Tim Bitson's "Weather Toys" which is a book I have so I think it's time I re-read it - might help me from "reinventing the wheel" :D

Just minor mods to the above sketches should be all that's required for what I want.  The individual IDs of the 1-wire devices need replacing with the actual values of devices used.  I already have a sketch to read these.

// This sketch looks for 1-wire devices and
// prints their addresses (serial number) to
// the UART, in a format that is useful in Arduino sketches
// Tutorial: 
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

#include <OneWire.h>

OneWire  ds(8);  // Connect your 1-wire device to pin 8

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

void discoverOneWireDevices(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];
  
  Serial.print("Looking for 1-Wire devices...\n\r");
  while(ds.search(addr)) {
    Serial.print("\n\rFound \'1-Wire\' device with address:\n\r");
    for( i = 0; i < 8; i++) {
      Serial.print("0x");
      if (addr[i] < 16) {
        Serial.print('0');
      }
      Serial.print(addr[i], HEX);
      if (i < 7) {
        Serial.print(", ");
      }
    }
    if ( OneWire::crc8( addr, 7) != addr[7]) {
        Serial.print("CRC is not valid!\n");
        return;
    }
  }
  Serial.print("\n\r\n\rThat's it.\r\n");
  ds.reset_search();
  return;
}

void loop(void) {
  // nothing to see here
}

Currently I have the DS2423, DS2450 and a DS18B20 on the 1-wire bus on an Arduino Uno I'm using for testing and this is the display in the Serial Monitor

Link to comment
Share on other sites

Quote

Looking for 1-Wire devices...


Found '1-Wire' device with address:

0x20, 0xAD, 0x30, 0x12, 0x00, 0x00, 0x00, 0x42

Found '1-Wire' device with address:

0x28, 0x55, 0x43, 0xC4, 0x03, 0x00, 0x00, 0xAF

Found '1-Wire' device with address:

0x1D, 0x9B, 0xFB, 0x0F, 0x00, 0x00, 0x00, 0xC6


That's it.

 

0x20 is the DS2450 family, 0x28 the DS18B20 family and 0x1D the DS2423 family.

I have now put the addresses for the DS2423 and DS2450 in the appropriate sketches, updated the libraries and run the sketches and the results look promising.  The counter reads zero as expected and the direction reads N also as expected with no sensors illuminated.  I conclude that the 1-wire devices are being read successfully and I can wire them up to the new sensors and assemble the wind vane direction system :)

Link to comment
Share on other sites

I've done some more testing of the optical sensor and come up with suitable resistor values.  The IR LED needs a substantial current to work at all and the workable minimum seems to be with 180Ω from 5v with the LED dropping 1.2v.  Thus the current is 3.8v in 180Ω = 21mA.  There are 4 IR LEDs which could be wired in series-parallel for running off 5v or all in series for running off 12v.  Now the wind instruments mast will be near the observatory with the CAT5 cable going into it so 12v (or more precisely 13.8v) is readily available from the main observatory supply. 

Powering the IR LEDS wants 20mA and the resistor wants to drop 13.8 - 4x1.2 = 9v.  Resistance required = 9 / 0.02 = 450Ω.

The DS2450 has parasitic power internally but the DS2423 needs 2.8-5.5v supply at a few μA.  This may be obtained either by external parasitic power from the 1-wire bus or from the 13.8v with resistor and zener diode - a regulator chip would be overkill.  The full 13.8v is also fine for the Hall effect sensor used in the anemometer which wants 4.5v to 24v.

Edited by Gina
Link to comment
Share on other sites

Thought I had some 5.1v zener diodes but I can't find any so it'll have to be 4.7v of which I have several.  Next nearest is 5.6v but that exceeds the 5.5v maximum for the chips.  I've done some wiring up with more to do but I think I've finished for tonight.

Wiring for the optical sensors.

56bf9315d4c1e_OpticalSensorWiring01.JPG.

Edited by Gina
Link to comment
Share on other sites

21 hours ago, Gina said:

I noticed mention of Tim Bitson's "Weather Toys" which is a book I have so I think it's time I re-read it - might help me from "reinventing the wheel" :D

Just minor mods to the above sketches should be all that's required for what I want.  The individual IDs of the 1-wire devices need replacing with the actual values of devices used.  I already have a sketch to read these.


// This sketch looks for 1-wire devices and
// prints their addresses (serial number) to
// the UART, in a format that is useful in Arduino sketches
// Tutorial: 
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

#include <OneWire.h>

OneWire  ds(8);  // Connect your 1-wire device to pin 8

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

void discoverOneWireDevices(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];
  
  Serial.print("Looking for 1-Wire devices...\n\r");
  while(ds.search(addr)) {
    Serial.print("\n\rFound \'1-Wire\' device with address:\n\r");
    for( i = 0; i < 8; i++) {
      Serial.print("0x");
      if (addr[i] < 16) {
        Serial.print('0');
      }
      Serial.print(addr[i], HEX);
      if (i < 7) {
        Serial.print(", ");
      }
    }
    if ( OneWire::crc8( addr, 7) != addr[7]) {
        Serial.print("CRC is not valid!\n");
        return;
    }
  }
  Serial.print("\n\r\n\rThat's it.\r\n");
  ds.reset_search();
  return;
}

void loop(void) {
  // nothing to see here
}

Currently I have the DS2423, DS2450 and a DS18B20 on the 1-wire bus on an Arduino Uno I'm using for testing and this is the display in the Serial Monitor

I have Tim's book aswell. From memory his code is all Java using the Maxim libraries. You can certainly re-use the algorithms though.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. By using this site, you agree to our Terms of Use.