UV Sensor ML8511



  • Well i have been searching for the code to work with my UV Sensor ML8511 over domoticz using mysensors off corse but i had no luck.
    Tried to use the code over the build section for the UV Sensor but it does not work correctly whit the sensor i have.
    Sow i have tried to make a working code, But i'm not a good programmer...

    At he time i'm posting this i don't now if it's working correctly because it's night at my place...

    #include <SPI.h>
    #include <MySensor.h>  
    #include <MySensor.h>  
    #include <SPI.h>
    
    #define UV_SENSOR_ANALOG_PIN 0
    
    #define CHILD_ID_UV 0
    
    unsigned long SLEEP_TIME = 30*1000; // Sleep time between reads (in milliseconds)
    
    MySensor gw;
    MyMessage uvMsg(CHILD_ID_UV, V_UV);
    
    float lastUV = -1;
    unsigned long lastSend =0; 
    
    void setup()  
    { 
      gw.begin(NULL, 9, true);
    
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("UV Sensor", "3.0");
    
      // Register all sensors to gateway (they will be created as child devices)
      gw.present(CHILD_ID_UV, S_UV, "ML8511_UV");
    }
    
    void loop()      
    {
      gw.process();
      
      int uvLevel = averageAnalogRead(UV_SENSOR_ANALOG_PIN);
      unsigned long currentTime = millis();
     
      float outputVoltage = 5.0 * uvLevel/1024;
      float uvIntensity = mapfloat(outputVoltage, 0.99, 2.9, 0.0, 15.0);
    
      if ((uvIntensity != lastUV)||(currentTime-lastSend >= 5*60*1000)) 
      {
          lastSend=currentTime;
          gw.send(uvMsg.set(uvIntensity,2));
          lastUV = uvIntensity;
      }
      //delay(100);
    }
     
    //Takes an average of readings on a given pin
    //Returns the average
    int averageAnalogRead(int pinToRead)
    {
      byte numberOfReadings = 8;
      unsigned int runningValue = 0; 
     
      for(int x = 0 ; x < numberOfReadings ; x++)
        runningValue += analogRead(pinToRead);
      runningValue /= numberOfReadings;
     
      return(runningValue);  
     
    }
     
    //The Arduino Map function but for floats
    //From: http://forum.arduino.cc/index.php?topic=3922.0
    float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
    {
      return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    }
    
    

    Has you can seen i had adapted the code from the build area and other code i had found on the web.
    Well if any one see erros in the code that i do believe it has, i do appreciate the help on fixing it and making this a perfect working code.


  • Hero Member

    @mrc-core said:

    ML8511

    Have you checked the wiring (from https://github.com/sparkfun/ML8511_Breakout/blob/master/firmware/MP8511_Read_Example/MP8511_Read_Example.ino😞

    Connect the following MP8511 breakout board to Arduino:
    3.3V = 3.3V
    OUT = A0
    GND = GND
    EN = 3.3V
    3.3V = A1



  • Looking over the pin connection that you have post i do see one mistake i have done.
    I did not connect de 3.3V to A1 pin.

    I'm gona trie it when i'm at home.

    The sensor is connected to domoticz but the readings are very low... 0.2 UVI



  • I have done some changings to the code and corrected de 3.3V = A1 Pin that i did not had in the first code.
    Onde day has passed with the changes and the result off this days is what you can see on the image below:

    0_1463007856557_UV_Sensor _Chart.png

    I dont now if this results are correct. I'm going to let the sensor outiside until the end of the week and see the results.
    Does anyone in the forum have a UV sensor working? Is this chart correct ??


  • Hero Member

    @mrc-core looks like you are using Domoticz.. Look for the Weather Underground virtual hardware.

    You can have WU report most of the weather related data from a station nearby. This includes UV measurement in a similar graph you have.

    Or my opinion : It looks like a correct graph to me but will depend on your local sun intensity.


  • Hero Member

    a quick question as I try to revive a node with UV sensor (a UVM-30A) : is there a simple way to simulate the UV after sundown which is the time I can test it ?


  • Hero Member

    @epierre UV led? :bowtie:



  • Ok i have now configured the Weather Underground virtual hardware let's see what will happen during the day off tomorrow.
    For what i can seen the UV sensor is detecting the UV normally between 11h and 17h....
    I'm going to make one new change on the code to introduce the reading s of the MP8511 voltage.

    And i'm going to change the location off the prototype in my house.

    To test the UV sensor at night you can use a UV light.


  • Hero Member

    @mrc-core said:

    To test the UV sensor at night you can use a UV light.

    does a halogen lamp does this ?


  • Hero Member

    @epierre The spectrum of UV is between 10 en 400 nanometer. so in relation to the spectrum of UV:
    0_1463141831569_upload-7c6d41cc-0a2d-4066-8102-63f44f3af6ea

    and an excerpt from medical study:

    "Halogen lamps emit significant levels of ultraviolet radiation and should be doped or covered with glass prior to use"

    0_1463141787908_upload-de6f625b-62b8-4a8e-b3c7-fe996aa277a7

    But in summary: not much



  • This is my new code for this sensor and reajusted to library 2.1.1

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - epierre
     * Contribution: bulldoglowell, gizmocuz
     *
     * DESCRIPTION
     * Connect sensor ML8511 / Arduino:
     *
     *  3.3V = 3.3V
     *  OUT = A0
     *  GND = GND
     *  EN = 3.3V
     *  Arduino 3.3V = Arduino A1
     *
     * License: Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached 
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //#define MY_RS485
    
    #include <SPI.h>
    #include <MySensors.h>  
    #include <SPI.h>
    
    //Hardware pin definitions
    int REF_3V3 = A1;
    int UVOUT = A0;
    
    #define CHILD_ID_UV 0
    
    unsigned long SLEEP_TIME = 30*1000; // Sleep time between reads (in milliseconds)
    
    MyMessage uvMsg(CHILD_ID_UV, V_UV);
    
    float lastUV = -1;
    unsigned long lastSend =0; 
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("UV Sensor", "3.0");
    
      // Register all sensors to gateway (they will be created as child devices)
      present(CHILD_ID_UV, S_UV, "ML8511_UV");
    }
    
    void setup()  
    { 
      //gw.begin(NULL, 9, true);
      pinMode(UVOUT, INPUT);
      pinMode(REF_3V3, INPUT);
    }
    
    void loop()      
    {
      int uvLevel = averageAnalogRead(UVOUT);
      int refLevel = averageAnalogRead(REF_3V3);
      unsigned long currentTime = millis();
    
      //Use the 3.3V power pin as a reference to get a very accurate output value from sensor
      float outputVoltage = 3.3 / refLevel * uvLevel;
     
      //float outputVoltage = 5.0 * uvLevel/1024;
      float uvIntensity = mapfloat(outputVoltage, 0.99, 2.8, 0.0, 15.0);          //Convert the voltage to a UV intensity level
    
      Serial.print("output: ");
      Serial.print(refLevel);
    
      Serial.print("ML8511 output: ");
      Serial.print(uvLevel);
    
      Serial.print(" / ML8511 voltage: ");
      Serial.print(outputVoltage);
    
      Serial.print(" / UV Intensity (mW/cm^2): ");
      Serial.print(uvIntensity);
    
      Serial.println();
    
      if ((uvIntensity != lastUV)||(currentTime-lastSend >= 5*60*1000)) 
      {
          lastSend=currentTime;
          send(uvMsg.set(uvIntensity,2));
          lastUV = uvIntensity;
      }
      delay(100);
    }
     
    //Takes an average of readings on a given pin
    //Returns the average
    int averageAnalogRead(int pinToRead)
    {
      byte numberOfReadings = 8;
      unsigned int runningValue = 0; 
    
      for(int x = 0 ; x < numberOfReadings ; x++)
        runningValue += analogRead(pinToRead);
      runningValue /= numberOfReadings;
    
      return(runningValue);  
    }
    
    //The Arduino Map function but for floats
    //From: http://forum.arduino.cc/index.php?topic=3922.0
    float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
    {
      return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    }```


  • @mrc-core Thanks for the code. The code works fine but I am seing the node reporting direct measurements to the gateway every single second, spamming the gateway.

    Is there anything I can do to stop this behavior and transmit averages; in example - every minute or every 5 minutes?

    Thanks in advance!



  • @benik change

     delay(100);
    

    to

    delay(300000); //5 mins reporting
    

Log in to reply
 

Suggested Topics

  • 8
  • 1
  • 7
  • 1
  • 5
  • 1

57
Online

11.4k
Users

11.1k
Topics

112.6k
Posts