Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. My Project
  3. Rebuild of my broken 433mhz Cresta/hideki UV-Sensor

Rebuild of my broken 433mhz Cresta/hideki UV-Sensor

Scheduled Pinned Locked Moved My Project
24 Posts 7 Posters 20.4k Views 8 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • sundberg84S Offline
    sundberg84S Offline
    sundberg84
    Hardware Contributor
    wrote on last edited by sundberg84
    #21

    I just wanted to update this post with my code and rebuild to this UV sensor thanks to @core_c!
    I also updated the box ;)

    0_1494874383421_1.jpg
    The Dallas temp sensor was never used in this project so please ignore...

    The node is build with a Slim Node. I could save some power by using a booster with VIn attached to D4. I keep the D4 low between sleeps. In sleep mode it consumes less than 10uA.

    The code:

    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24                  //The radio we use!
    #define MY_NODE_ID 19                      //Fixed node ID
    #define MY_BAUD_RATE 9600           //Needs to be defined because standard for MySensors is 115200. This bootloader uses 9600!
    
    #include <SPI.h>
    #include <MySensors.h>
    #include <Vcc.h>
    
    //SketchInfo MySensors
    #define SKETCH_NAME "UV #19"                // Change to a fancy name you like
    #define SKETCH_VERSION "1.4"                // Your version  
    
    //Light
    #define CHILD_ID_LIGHT 1
    #define LIGHT_SENSOR_ANALOG_PIN A0
    #define SENSORS_POWER_PIN 4
    MyMessage light_Msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    
    //===================================================
    // UVM30A ultraviolet detector.
    //
    // Thanks to core_c @ mysensors.org for code and info!
    // The sensor's VCC is connected to +5V
    //
    // At first glance, the datasheet is not entirely making sense:
    //  "输出电压" translates to "Output voltage", with a value of: DC 0—1V.
    //  So the sensor will never output/measure the 2 highest values listed in the graph & table of the datasheet (1079 and 1170+).
    //  The datasheet explains it: "(对应 UV 指数 0-10)" translates to "(corresponding to UV index 0-10)".  Fair enough.
    //
    //  "测试精度" translates to: "Test accuracy", with a value of: ±1 UV INDEX
    //  That is not very accurate on a range 0-10. Example: if the real UV-index is 4, you could measure 3, or 5.
    //  For that reason we take an average of multiple samples, to get a better measurement.
    
    #define UV_PIN A1
    #define CHILD_ID_UV 0
    MyMessage uv_Msg(CHILD_ID_UV, V_UV);
    const int UV_threshold[12] = {50, 227, 318, 408, 503, 606, 696, 795, 881, 976, 1079, 1170}; // // The list of UV index thresholds in units of mV
    
    // The read value is a 10-bit value, ranging from 0 to 2^10-1 (0 to 1023).
    // The reference voltage on the input pin is set to 1.1V.
    // That voltage is spread out over the 1024 possible values of a sample.
    // So our achieved resolution equals (1.1 Volts / 1024) = 0.00107421875 Volt.
    // The UVM30A sensor datasheet lists all UV-index values according to measured milli-Volts.
    const float SAMPLE_TO_MV = (1.1 * 1000) / 1024; // mV per sample-resolution
    
    uint16_t UV_value;
    uint16_t UV_index;        // the UV index
    uint16_t UV_index_f;      // the fractional part of the UV index
    
    // Compiler directives for averiging the UV-sensor readings
    // (Change the values of UV_AVERAGE_T & UV_AVERAGE_N according to your own taste).
    #define UV_AVERAGE_T 4000 // Sample interval duration in milliseconds..  (1 <= T <= 60000)
    #define UV_AVERAGE_N 10   // ..During that interval, N samples are taken, and averaged.    (1 <= N <= 100, must be <>0)
    
    #if UV_AVERAGE_T < 1      // Sanity check. It must be dummy proof
    #define UV_AVERAGE_T 1
    #endif
    #if UV_AVERAGE_N < 1      // Sanity check. It must be dummy proof
    #define UV_AVERAGE_N 1    // This value must be <>0 at all times, because we divide by it
    #endif
    
    // calculate once, use many times in the loop()
    const float UV_AVERAGE_N_RP = 1.0 / UV_AVERAGE_N;
    const uint32_t UV_AVERAGE_D = UV_AVERAGE_T * UV_AVERAGE_N_RP;
    //===================================================
    
    //SleepTime
    unsigned long SLEEP_TIME = 600000; // Sleep time between reads (in milliseconds)
    
    //Battery
    const float VccMin   = 1.9;           // Minimum expected Vcc level, in Volts.
    const float VccMax   = 3.0;           // Maximum expected Vcc level, in Volts.
    const float VccCorrection = 1.0 / 1.0; // Measured Vcc by multimeter divided by reported Vcc
    
    Vcc vcc(VccCorrection);
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
    
      // Register all sensors to gateway (they will be created as child devices)
      present(CHILD_ID_UV, S_UV);
      present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
      
    }
    
    void setup()  {
    
      analogReference(INTERNAL);
    
      pinMode(SENSORS_POWER_PIN, OUTPUT);
      pinMode(UV_PIN, INPUT);
      pinMode(LIGHT_SENSOR_ANALOG_PIN, INPUT);
    
    }
    
    void loop()
    {
    
      digitalWrite(SENSORS_POWER_PIN, HIGH);  //Set power on digital pin for lightsensor.
      wait(500); //Wait 500ms to make sure lightsensor is powered and stable.
    
      processUV();   //Read UV
    
      readLightLevel();   //Read Light
    
      digitalWrite(SENSORS_POWER_PIN, LOW); // Set power for lightsensor off to save power.
    
      BatteryCalculation();
    
      //Sleep!
      sleep(SLEEP_TIME);
    }
    
    void readLightLevel()      {
      int lightLevel = (1023 - analogRead(LIGHT_SENSOR_ANALOG_PIN)) / 10.23; //To get a value ranging from 0 (dark) to 100 (bright).
    
    #ifdef MY_DEBUG
      Serial.print("Light: "); Serial.println(lightLevel);
    #endif
      send(light_Msg.set(lightLevel));
    
    }
    
    //===================================================
    // Process a UV measurement:
    // read an average value from the UV detector.
    // The average consists of N samples taken during a T milliseconds interval.
    //===================================================
    void processUV() {
      // Set the reference voltage for sampling
      // For our ATmega328 Nano: INTERNAL = 1.1V, DEFAULT = 5V
      // After using analogReference(), the first few samples may not be accurate (according to the Arduino language reference),
      // and that is why we read a few dummy samples before starting the actual measurement.
      // NOTE: If you change the next statement, beware to adjust the value of SAMPLE_TO_MV too.
    
      for (int i = 0; i < 10; i++) UV_value = analogRead(UV_PIN); // ignore the possibly inaccurate samplevalues.
    
    #ifdef MY_DEBUG
      Serial.print("UV raw values: [");
    #endif
      uint32_t average = 0;
      for (int i = 0; i < UV_AVERAGE_N; i++) {
    #ifdef MY_DEBUG
        UV_value = analogRead(UV_PIN);
        Serial.print(UV_value);  Serial.print(" ");
        average += UV_value;
    #else
        average += analogRead(UV_PIN);
    #endif
        delay(UV_AVERAGE_D);
      }
      UV_value = average * UV_AVERAGE_N_RP;
    #ifdef MY_DEBUG
      Serial.print("]    avg: ");  Serial.print(UV_value);
    #endif
    
      // We must convert sample-values into mV-values before we look up the UV-index.
      UV_value *= SAMPLE_TO_MV;
    
    #ifdef MY_DEBUG
      Serial.print("     mV: ");  Serial.print(UV_value);
    #endif
    
      // determine the UV index
      if (UV_value < UV_threshold[0]) {
        // too low value  or  invalid value (in case the sensor is wrongly connected it always returns 0)
        UV_index = 0;
        UV_index_f = 0;
      } else {
        for (UV_index = 11; UV_index > 0; UV_index--) {
          if (UV_value >= UV_threshold[UV_index]) break;
        }
        // calculate fractional part of the UV-index
        if (UV_index == 11) {
          // already at the maximum level; Displaying a fraction is meaningless
          UV_index_f = 0;
        } else {
          UV_index_f = map(UV_value, UV_threshold[UV_index], UV_threshold[UV_index + 1], 0, 9); // one decimal, so a number ranging 0 to 9
        }
      }
      float UV_index_float = UV_index + (UV_index_f * 0.1); // that is the same as /10
    
    #ifdef MY_DEBUG
      Serial.print("     UV index: ");  Serial.println(UV_index_float);
    #endif
    
      send(uv_Msg.set(UV_index_float, 1));
    
    }
    
      
    void BatteryCalculation()
    {
      float v = vcc.Read_Volts();
    
    #ifdef MY_DEBUG
      Serial.print("VCC = ");
      Serial.print(v);
      Serial.println(" Volts");
    #endif
      float p = vcc.Read_Perc(VccMin, VccMax);
    
    #ifdef MY_DEBUG
      Serial.print("VCC = ");
      Serial.print(p);
      Serial.println(" %");
    #endif
    
      sendBatteryLevel(p);
    
    }
    

    0_1494927947601_Schematics.jpg
    And offcourse the sensors analog output was connected to analog input of the atmega - forgot that in the schematics. UV=A0 and Light =A1

    Controller: Proxmox VM - Home Assistant
    MySensors GW: Arduino Uno - W5100 Ethernet, Gw Shield Nrf24l01+ 2,4Ghz
    MySensors GW: Arduino Uno - Gw Shield RFM69, 433mhz
    RFLink GW - Arduino Mega + RFLink Shield, 433mhz

    1 Reply Last reply
    2
    • core_cC Offline
      core_cC Offline
      core_c
      wrote on last edited by
      #22

      cool!..
      I like that slim node. compact.
      It's even more fun that it's all functioning. (y)

      1 Reply Last reply
      0
      • korttomaK Offline
        korttomaK Offline
        korttoma
        Hero Member
        wrote on last edited by korttoma
        #23

        So is the UVM-30a still the prefered sensor for this implementation or are there any better options?

        The ML8511 was mentioned but it was not yet confirmed to be working.

        Does connecting a booster to an output pin that is turned of work as expected? Does not the booster try to boost even if the output pin is low?

        • Tomas
        sundberg84S 1 Reply Last reply
        0
        • korttomaK korttoma

          So is the UVM-30a still the prefered sensor for this implementation or are there any better options?

          The ML8511 was mentioned but it was not yet confirmed to be working.

          Does connecting a booster to an output pin that is turned of work as expected? Does not the booster try to boost even if the output pin is low?

          sundberg84S Offline
          sundberg84S Offline
          sundberg84
          Hardware Contributor
          wrote on last edited by sundberg84
          #24

          @korttoma

          UVM-30a still the prefered sensor

          Cant say. I have been using this for the last year (wrong apparently) but worked as expected.

          Does connecting a booster to an output pin that is turned of work as expected? Does not the booster try to boost even if the output pin is low?

          I dont know what will happen over time so I have to come back to that but I had a reading of 5uA in sleep mode which to me indicates a success. I did so because one of the sensors has a minimum of 3.3v and that would stop working pretty soon. Since the rest of the system should be able to go lower I wanted to test... the node is really stable and working great so far!

          Controller: Proxmox VM - Home Assistant
          MySensors GW: Arduino Uno - W5100 Ethernet, Gw Shield Nrf24l01+ 2,4Ghz
          MySensors GW: Arduino Uno - Gw Shield RFM69, 433mhz
          RFLink GW - Arduino Mega + RFLink Shield, 433mhz

          1 Reply Last reply
          1
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          16

          Online

          11.7k

          Users

          11.2k

          Topics

          113.0k

          Posts


          Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • MySensors
          • OpenHardware.io
          • Categories
          • Recent
          • Tags
          • Popular