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
Boots33B

Boots33

@Boots33
Hero Member
About
Posts
435
Topics
13
Shares
0
Groups
1
Followers
4
Following
0

Posts

Recent Best Controversial

  • i2c Lightning Sensor +
    Boots33B Boots33

    AS3935 Lightning detector based on the playingwithfusion breakout board and includes a light control and also acts as a repeater node.

    This design extends slightly on the original Lightning Detector node found here. As this will be my first outside node in range of my mysensors network I needed it to be a repeater as well. It will be mounted near a garden lamp post that I have converted to 12v and now uses LED's so I also wanted to use the node to control the light as well, this will also be a convenient place to get the 12v needed for the supply.

    The basic circuit is shown below, in the final I intend to use a high powered NRF24L01+PA+LNA 
    module to maximise my range and hopefully extend my network across the yard area. If you use the high powered transceiver you will need to add an external 3.3v regulator as the nano on-board 3v regulator cannot supply enough current.
    0_1466907658702_Lightning sensor noreg i2c.jpg

    To guard against reverse polarity hookup I have used a 1n4001 diode on the input line to the nano. I have used a 150 ohm resistor as a current limiter to ptotect the Arduino and a 10k resistor to ensure the mosfet always switches completely off. The lightning board has built in 10k pullup resistors so none are needed on the A4 and A5 pins.

    The transistor is an IRL540 Mosfet, which is designed to operate from logic level outputs like the nano. By using a device made to operate at logic levels means I should have no problem getting the mosfet to reach full saturation when being switched. Basically that means I should be able to switch a heavier load and generate less heat.

    Here is the breadboard layout

    0_1466907807813_layout.jpg

    The sketch

    // This sketch is to integrate the Playing With Fusion AXS3935 Lightning Sensor Breakout Board
    // with the MySensors environment and is based on a sketch provided by Playing With Fusion
    // http://playingwithfusion.com/productview.php?pdid=22&catid=1001 and from the MySensors
    // forum post at  https://forum.mysensors.org/topic/880/sketch-for-lightning-sensor
    //As well as providing lightning detection this sketch now also alows node to act as
    // a repeater and control an outdoor light that the node is mounted in.
    
    #include "MySensor.h"  
    // the lightning sensor can communicate via SPI or I2C. This sketch uses the I2C interface
    #include "I2C.h"
    // include Playing With Fusion AXS3935 libraries
    #include "PWFusion_AS3935_I2C.h"
    #include "SPI.h"
    // defines for hardware config
    #define SI_PIN               8         // this pin will be switched high for i2c
    #define IRQ_PIN              3        // digital pins 2 and 3 are available for interrupt capability
    #define AS3935_ADD           0x03     // x03 - standard PWF SEN-39001-R01 config
    #define AS3935_CAPACITANCE   48       // <-- SET THIS VALUE TO THE NUMBER LISTED ON YOUR BOARD                     
    volatile int8_t AS3935_ISR_Trig = 0;
    
    // #defines for general chip settings
    #define AS3935_INDOORS       0
    #define AS3935_OUTDOORS      1
    #define AS3935_DIST_DIS      0
    #define AS3935_DIST_EN       1
    
    #define LIGHT_PIN  6  // Arduino Digital I/O pin number for Light
    #define LIGHT_ON 1  // GPIO value to write to turn on attached relay
    #define LIGHT_OFF 0 // GPIO value to write to turn off attached relay
    
    
    // prototypes
    void AS3935_ISR();
    
    PWF_AS3935_I2C  lightning0((uint8_t)IRQ_PIN, (uint8_t)SI_PIN, (uint8_t)AS3935_ADD);
    
    #define CHILD_ID_DISTANCE 1
    #define CHILD_ID_INTENSITY 2
    #define CHILD_ID_LIGHT 3
    
    MySensor gw;
    MyMessage msgDist(CHILD_ID_DISTANCE, V_DISTANCE);
    MyMessage msgInt(CHILD_ID_INTENSITY, V_VAR1);
    MyMessage msg(CHILD_ID_LIGHT,V_LIGHT);
    void setup()  
    { 
     // gw.begin();
      
      gw.begin(incomingMessage, AUTO, true);                      //  enable repeater mode.
      
      gw.sendSketchInfo("Lightning Sensor Plus", "1.0");   // Send the sketch version information to the gateway and Controller
    
      /*----Register all sensors to gw (they will be created as child devices----*/
      gw.present(CHILD_ID_DISTANCE, S_DISTANCE);
      gw.present(CHILD_ID_INTENSITY, S_CUSTOM);
      gw.present(CHILD_ID_LIGHT, S_LIGHT);
      pinMode(LIGHT_PIN, OUTPUT);            //set light pin as output
      digitalWrite(LIGHT_PIN, LIGHT_OFF);    //   make sure light is off at startup
     // Serial.begin(115200);
      Serial.println("Playing With Fusion: AS3935 Lightning Sensor, SEN-39001-R01");
      Serial.println("beginning boot procedure....");
      
     // setup for the the I2C library: (enable pullups, set speed to 400kHz)
      I2c.begin();
      I2c.pullup(true);
      I2c.setSpeed(1); 
      delay(2);
      
      lightning0.AS3935_DefInit();            // set registers to default  
      // now update sensor cal for your application and power up chip
      lightning0.AS3935_ManualCal(AS3935_CAPACITANCE, AS3935_OUTDOORS, AS3935_DIST_EN);
                      // AS3935_ManualCal Parameters:
                      //   --> capacitance, in pF (marked on package)
                      //   --> indoors/outdoors (AS3935_INDOORS:0 / AS3935_OUTDOORS:1)
                      //   --> disturbers (AS3935_DIST_EN:1 / AS3935_DIST_DIS:2)
                      // function also powers up the chip
                      
      // enable interrupt (hook IRQ pin to Arduino Pro Mini, Nano, Uno/Mega interrupt input: 1 -> pin 3 )
      attachInterrupt(1, AS3935_ISR, RISING);
      // dump the registry data to the serial port for troubleshooting purposes
      lightning0.AS3935_PrintAllRegs();
      AS3935_ISR_Trig = 0;           // clear trigger
      // delay execution to allow chip to stabilize.
      delay(1000);
    
    }
    
    void loop()      
    {     
      
      gw.process();          // By calling process() you route messages in the background
      // This program only handles an AS3935 lightning sensor. It does nothing until 
      // an interrupt is detected on the IRQ pin.
      //while(0 == AS3935_ISR_Trig){}
     if (AS3935_ISR_Trig == 1){
      lightningDetected();
     }
      
    }
    
    // this is irq handler for AS3935 interrupts, has to return void and take no arguments
    // always make code in interrupt handlers fast and short
    void AS3935_ISR()
    {
      AS3935_ISR_Trig = 1;
    }
    
    /*--------------Lightning function----------------*/
    void lightningDetected(){
      // reset interrupt flag
      AS3935_ISR_Trig = 0;
      
      // now get interrupt source
      uint8_t int_src = lightning0.AS3935_GetInterruptSrc();
      if(0 == int_src)
      {
        Serial.println("Unknown interrupt source");
      }
      else if(1 == int_src)
      {
        uint8_t lightning_dist_km = lightning0.AS3935_GetLightningDistKm();
        uint32_t lightning_intensity = lightning0.AS3935_GetStrikeEnergyRaw();
    
        Serial.print("Lightning detected! Distance to strike: ");
        Serial.print(lightning_dist_km);
        Serial.println(" kilometers");
        Serial.print("Lightning detected! Lightning Intensity: ");
        Serial.println(lightning_intensity);
        gw.send(msgDist.set(lightning_dist_km));
        gw.send(msgInt.set(lightning_intensity));
      }
      else if(2 == int_src)
      {
        Serial.println("Disturber detected");
      }
      else if(3 == int_src)
      {
        Serial.println("Noise level too high");
      }
    }
    
    
    void incomingMessage(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.type==V_LIGHT) {
         // Change relay state
         digitalWrite(LIGHT_PIN, message.getBool()?LIGHT_ON:LIGHT_OFF);
        
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
    }
    

    I have found it hard to get good inexpensive outdoor cases that will endure the conditions for a long time. As I hope to deploy several outdoor nodes I wanted a case that would be as set and forget as possible without costing too much. I have decided to try and make my own so will see how this first one goes.

    From the local hardware store I have purchased a length of 50mm pvc tubing and end caps to suit. I have cut the tube to suit the PCB of the lightning detector . I will then fit a waterproof cable gland to an end-cap and glue the end-cap to the bottom of the 50mm tube. I will leave the top as just push on with no glue and mount an aerial socket on there as well. The whole thing will be secured to a timber post with a 50mm clamp
    Early days on this one, I will post more as it progresses.

    0_1466908418282_pipe.jpg

    My Project

  • 12v Solar battery monitor
    Boots33B Boots33

    Hi
    I have installed a node to monitor our 12v auxiliary supply for our home. The power system consists of a 200w panel on the roof and a 105AH battery located in our server cabinet. When we built our home I ran a 12v Backbone as well so we can access the low voltage power all over . To date it has been used to run a system of night lights and reading lamps but now that I have found Mysensors I hope it will soon be powering a lot more :) .

    Ok this node has been running for a few weeks now so thought i would share it with others. it monitors battery voltage, Charge current, Dis-charge current, Ambient temp and battery Temp. I have included the temperature monitors after a friend had his battery develop an internal short and melt in his caravan, not a pretty sight.

    My notes are based on my breadboard version which was built around an Arduino nano, In the final I used a Pro Mini.

    Parts List:

    1 x Arduino I have used a Nano but other types or OK too
    1 x ACS712 Current sensing Module. These are available in 5A, 20A and 30A. Choose whichever current fills your needs. Only one line of code needs to be modified to suit your selected device.
    2 x DS18b20 Temperature sensors
    1 x Voltage sensing module or 2 x resistors to be used as a voltage divider. I have used a module that has a maximum reading of 25v. That means when the module sees 25v on its input the output of the module will be 5v.
    1 x nRF24L01+ 2.4ghz Transceiver
    1 x LM2596 regulator module or some other regulator able to supply 5v
    1x 330 ohm resistor
    1x 4.7 k ohm resistor
    1x LED
    1x push button

    When using the analog inputs of the Arduino it is very important that you have a very stable 5v supply voltage. The 20A ACS712 shows a change of only 100mv for every 1A so you can see even small fluctuations can cause sizable errors in your readings. During construction I found powering the circuit from the usb port to give unreliable results and opted for a dedicated 5v supply instead.

    Construction:
    Wire the devices as shown below.

    0_1462608111680_Batmon hookup.jpg

    The Sketch:

     /*Sketch for a MySensor node to monitor a 12v battery with a solar panel for charging
     * The node monitors battery voltage,current into and out of the battery, ambient temperature and battery temperature.
     * 2 x DS18b20 dallas temperature ic's their data pins connected to arduino digital pin 3
     * 1 x ACS712 current sensor module connected to  arduino analog pin A4
     * 1 x 25v voltage sensor module connected to arduino analog pin A0
     * 1 x nRF24L01+  2.4ghz tranceiver connected as per the MySensors web site.
     * 1 x LED connected via a 330 ohm resistor to pin 6
     * 1 x push button connected to pin 5
     */
     
    #include <MySensor.h>  
    #include <SPI.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>
     
    
    #define ONE_WIRE_BUS 3                       // Ds18b20 data wire is connected to digital pin 3 on the Arduino
    #define ID_S_TEMPA 0                         // First temp device
    #define ID_S_TEMPB 1                         // second temp device
    #define ID_S_MULTIMETERV 3                   // Multimeter device for voltage measurement
    #define ID_S_MULTIMETERC 4                   // Multimeter device for positive current measurement 
    #define ID_S_MULTIMETERC1 5                  // Multimeter device for negative current measurement
    #define NUM_SAMPLES 10                       // number of analog voltage samples to take per reading
    
    
    int ledPin = 6;                               // the pin for the LED
    int buttonPin = 5;                            // the input pin for offset pushbutton
    int buttonState = 0;                          // variable for reading the pin status
    unsigned long SLEEP_TIME = 30000;            // Sleep time between reads (in milliseconds)
    int lastmilli = 25000;                       // set to an arbitary number outside of expected current sensor range to ensure a change when first run 
    float sensitivity = 100 ;                    //change this to 185 for ACS712-5 or to 100 for ACS712-20A or to 66 for ACS712-30A
    int VQ = 0;                                  //Placeholder for quiescent voltage calculations
    int ACSPin = A4;                             // Analog pin number the ACS712 data pin connects to
    float lastTemperature[2];                    //Array to hold the last temp readings sent to gateway, only send new data if different
    int sum = 0;                                 // sum of voltage samples taken
    unsigned char sample_count = 0;              // current sample number
    int lastVoltage = 30000;                     // set to an arbitary number outside of expected voltage sensor range to ensure a change when first run
    int voltagePin = A0;                         // analog pin voltage sensor or voltage divider is connected to
    int voltSenseMax = 25000;                    // set to the maximum input voltage in millivolts of your voltage divider input    
    OneWire oneWire(ONE_WIRE_BUS);               // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
    DallasTemperature sensors(&oneWire);         // Pass our oneWire reference to Dallas Temperature.
    
    MySensor gw;
    
    // ------ Initialize  messages -------
    MyMessage msg(0,V_TEMP);                     
    MyMessage msg_S_MULTIMETERv(ID_S_MULTIMETERV,V_VOLTAGE);
    MyMessage msg_S_MULTIMETERc(ID_S_MULTIMETERC,V_CURRENT);
    MyMessage msg_S_MULTIMETERc1(ID_S_MULTIMETERC1,V_CURRENT); 
    
    void setup()
    {
     
    sensors.begin();                                    // Start up the onewire library
    gw.begin();                                         // Startup and initialize MySensors library. Set callback for incoming messages. 
    gw.sendSketchInfo("Battery Status Sensor", "1");    // Send the sketch version information to the gateway and Controller
    
    // ------ Present all sensors to controller ------
    gw.present(ID_S_TEMPA, S_TEMP);
    gw.present(ID_S_TEMPB, S_TEMP);
    gw.present(ID_S_MULTIMETERV,V_VOLTAGE);
    gw.present(ID_S_MULTIMETERC,V_CURRENT);
    gw.present(ID_S_MULTIMETERC1,V_CURRENT);
    
    
    pinMode(buttonPin, INPUT_PULLUP);                     // Set buttonPin as input and turn on internal pull up resistor
    pinMode(ledPin, OUTPUT);                              // Set ledPin as output
    digitalWrite(ledPin, LOW);                            // Make sure ledPin is off
    
    // ------ load offset for current sensor
    int validCheck = gw.loadState(0);
    if (validCheck == 120){                          // check to see if valid data exists
      VQ = gw.loadState(1);                               // Load count offset into VQ
    //  Serial.print(" positive VQ offset loaded..."); Serial.println(VQ);
     }
     else if (validCheck == 125) {
      VQ = -abs(gw.loadState(1));
    //  Serial.print(" negative VQ offset loaded..."); Serial.println(VQ);
     }
    else {
    // Serial.println("VQ offset not set");
    }
    
    delay(500);  
    }
     
    void loop()
    {
    
    buttonState = digitalRead(buttonPin);
    //Serial.print("buttonstate..."); Serial.println(buttonState);
     if (buttonState == LOW) {
        VQ = determineVQ(ACSPin);                           //Returns the offset count needed to show zero with no load
    
        
      if (VQ >= 0 && VQ < 255) {                              //check for valid data. VQ is positive number
        gw.saveState(0, 120);                               // Store 120 value  in eeprom position 0. use this to check for valid data at boot
        gw.saveState(1, VQ);                                // Store offset count in eeprom. in case of re-boot  
      }
      else if (VQ < 0 && VQ > -255) {                              // VQ is a negative number. negatives cannot be stored in eeprom
        gw.saveState(0, 125);                               // Store 125 value  in eeprom position 0. use this to check for valid data at boot
        gw.saveState(1, abs(VQ));                                // convert VQ to positive and  Store offset count in eeprom. in case of re-boot   
      }
    
      }
    
    // ------------------ Start voltage readings --------------------
     
    
     sample_count = 0;
     sum = 0;
     while (sample_count < NUM_SAMPLES) {                                   // take a number of voltage samples  
      sum += analogRead(voltagePin);
      sample_count++;
      delay(10);
     }
    //Serial.print("sum count..."); Serial.println((sum / NUM_SAMPLES));      // print the count result. will be between 0 and 1023
    int voltageI = map(sum/NUM_SAMPLES,0,1023,0,voltSenseMax);              // map the reading and get our result in millivolts
    //Serial.print("mapped volts..."); Serial.println(voltageI / 1000.0, 1);  // convert millivolts back to volts and print. the 1 at the end determines how many decimal places to show
    
    
    if ( voltageI != lastVoltage) {                                         // check if we have a new value. only send data if it is different
     gw.send(msg_S_MULTIMETERv.set(voltageI / 1000.0, 1));                  // voltagel is in millivolts so we divide by 1000 to convert back to volts and
                                                                            // send voltage message to gateway with 1 decimal place
     lastVoltage = voltageI;                                                // copy the current voltage reading for testing on the next loop 
    }
    
    //--------------------Start Current readings---------------------------------
    
    int milli = readCurrent(ACSPin);                                       // take a reading from the ACS712 and send to the readcurrent function
    
    //Serial.print("Milliamps..."); Serial.println(milli);                   // print the value (in milliamps) returned
    
    if ( milli != lastmilli)                                               // check if value has changed
    {
     if ( milli > 0)                                                       // Battery is charging
     {
      gw.send(msg_S_MULTIMETERc.set(milli/1000.0, 1));                     // Send new data to charging amp device
      gw.send(msg_S_MULTIMETERc1.set(0));                                  // set the dis-charging amp device to zero
      lastmilli =  milli;
     }
     else if (milli < 0)                                                  // Battery is discharging
     {
      gw.send(msg_S_MULTIMETERc.set(0));                                  // set the charging amp device to zero
      gw.send(msg_S_MULTIMETERc1.set(abs(milli)/1000.0, 1));             //  use abs(milli) to Send a positive number  to dis-charging amp device
      lastmilli =  milli; 
     }
    else                                                                // No current flowing, set both to zero
    {
     gw.send(msg_S_MULTIMETERc.set(0));
     gw.send(msg_S_MULTIMETERc1.set(0));
     lastmilli =  milli;
    }
    }
     
    //----------------------Teperature readings start------------------------
      
      Serial.println(" Requesting temperatures...");
     
     // Fetch temperatures from Dallas sensors
      sensors.requestTemperatures();                  // call sensors.requestTemperatures() to issue a global temperature request to all devices on the bus
    
      // ------- query conversion time and sleep until conversion completed ------
      int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
      gw.sleep(conversionTime);
    
     for (int i=0; i<2; i++) {
    //  Serial.print("Temperature for Device: ");Serial.print(i);Serial.print(" is: ");
     // Serial.println(sensors.getTempCByIndex(i)); // Why "byIndex"? 
        // You can have more than one IC on the same bus. 
        // 0 refers to the first IC on the wire
    
     float temperature = static_cast<float>(static_cast<int>((sensors.getTempCByIndex(i)) * 10.)) / 10.;  // Fetch and round temperature to one decimal in celcius
    
    if (lastTemperature[i] != temperature)               // check for a changed temperature reading
      {
       gw.send(msg.setSensor(i).set(temperature,1));     // Send in the new temperature
       lastTemperature[i]=temperature;                   // Save new temperatures for next compare
      }     
    }
    gw.sleep(SLEEP_TIME);
    }
    
    
    
    /*-------------- Function to get the offset required for ACS712 to show zero with no current flowing -----------------*/
    int determineVQ(int PIN)                  
     {
      digitalWrite(ledPin, HIGH);                                      // Turn on LED to indicate offset being calculated
      delay(500);                                                      // Delay to hold LED on
      digitalWrite(ledPin, LOW);                                       // Turn off LED
      delay(150);                                                      // Delay to let readings stabilise
    //  Serial.print("estimating avg. quiscent voltage:");
      long acsCount = 0;
      for (int i=0; i<5000; i++)                                       //read 5000 samples to stabilise value
       {
        acsCount += analogRead(PIN);                                   // read the count value between 0 and 1023 and add it to acsCount
        delay(1);                                           
       }
      acsCount /= 5000;                                                      // acsCount now eaquals the average of the 5000 readings taken
    //  Serial.print(map(acsCount, 0, 1023, 0, 5000));Serial.println(" mV");   //Print the avg in millivolts
    //  Serial.print("acsCount:");Serial.println(acsCount);                               //Print the actual count value
      
      return int(acsCount - 512);                                            // return the count difference. 512 is the count for 2.5v which is what the reading should be with no current flow                           
      
    }
    
    
     /*--------------- Function to read current flowing ------------------*/
     
    int readCurrent(int PIN) 
    {
     int count = 0;
     for (int i=0; i<5; i++)                                        //read 5 analog count samples to stabilise value
      {
       count += analogRead(PIN) - VQ;                               //subtract the offset count VQ to improve accuracy
       delay(1);
     //  Serial.print("raw count..."); Serial.println(count);
      }
     /* Notes on the conversion below
      *  .00488 is the volt value per count of the arduino adc. The analog pin measures from 0 to 5 volt and then assigns the result to 
      *  a count from 0 to 1023, thats 1024 counts including zero. If we devide 5v by 1024 we get .oo488 volts for each count.  
      *  
      *  The (count/5) just gets us the average of our 5 count samples.
      *  
      *  So after the first part of the equation  (.00488 * (count/5) is complete we have converted our count reading into volts. 
      *  
      *  The ACS712 can measure current flow in both directions so it outputs a voltage of  2.5v as it's center point (when no current is flowing).
      *  To allow for this offset we must subtract the 2.5v to center our voltage reading.
      *  
      * Thats what the next part does (.00488 * (count/5)) - 2.5) After this is complete we are left with either a negative or  positive voltage
      * reading or a reading of zero for no current flow.
      * 
      * NOTE: While the ACS712 is a 5v device it does not use the full 0 to 5v for it's output. The datasheet shows the 20A version has a sensitivity of
      *  100mv per amp, so if we multiply 100mv by 20 we get 2v.  That means the 20A ACS712 has an output range from .5v to 4.5v.  
      * 
      * So to convert our reading in volts to a reading in amps we need to add the last part ((.00488 * (count/5)) - 2.5)/(sensitivity/1000).
      * The variable sensitivity is defined at the begining of the sketch and holds the ACS712 sensitvity amount, it is stored in millivolts. 
      * That is 66mv for the 30amp,  100mv for the 20amp and 185mv for the 5amp. As sensitivity is in millivolts we need to devide it by 1000 
      * to convert it back to volts so we can use it in the equation. 
      * 
      * Now we have our Amps value stored in the float amps. Integers are much easier to work with when checking for zero so we multiply by 1000 
      * to convert it to milliamps and return it as an integer.
    */
    
    //Serial.print("VQ = ..."); Serial.println(VQ);
    //Serial.print("current count..."); Serial.println(count/5);
    //Serial.print("map  milliamps..."); Serial.println(map((count/5), 102, 922, -20000, 20000));
     float amps = ((.00488 * (count/5)) - 2.5) / (sensitivity/1000);
    // Serial.print("float amps..."); Serial.println(amps, 1);
      return int (amps * 1000);                                         // convert to milliamps and return as an integer
    
    }
    

    Voltage Sensor:
    If you are not using a voltage sensor module you will need to construct a voltage divider circuit to measure the battery voltage. The reason for this is the Arduino Nano can only tolerate a maximum of 5v on its analog inputs so if we were to connect the 12v battery directly to the input we would most likely destroy the Arduino. A google search will turn up plenty of online voltage divider calculators to help you decide on the correct resistor values.
    Make sure you choose an input voltage level for your divider that is well over the maximum of the voltage you intend to measure.
    Our 12v system is likely to see voltages as high as 14.5v to 15v when charging and perhaps even higher if something has gone wrong so a divider with an input voltage of 25 to 30 volts would be a good choice. So for example if we were to use a combination of a 30k for R1 and 7.5k for R2 an input of 25v would result in an output of 5v.
    You will need to change the value in the sketch code int voltSenseMax = 25000; to represent the input voltage in millivolts of your divider
    I am using millivolts as I use the map function for the conversion later in the sketch, so integers are required. A typical voltage divider circuit is shown below.

    0_1462662603329_Voltage-divider-circuit.png

    If you are using the voltage sensor module that I have used you will notice it has three terminals on the output side, the one marked with a + symbol is not used, I am not sure why it is even there.

    0_1462662681538_25v module.png

    DS18b20 Temperature Sensors:
    These devices can be used with just two wires but I have used three as it seems this works best in noisy environments. The big advantage of these “one wire” devices is you can have more than one connected to the same input pin on the Arduino. The only requirement is one 4.7k pull-up resistor connected between VDD and DQ. The code I have used is based on the MySensors Dallas Temperature example.

    ACS712 Current Sensing Module:

    First be aware that the pin out can vary on these modules so check before you connect up. You can see in the picture below that the VCC and GND pins are reversed on these two.

    0_1462662998444_acs.jpg

    The ACS712 current sensing module is a 5v device that measures current flow and returns a voltage that can be used to determine the amount of current flowing. It is available in three versions 5A, 20A and 30A .
    Importantly for this application they read current flow in both directions. To do this they output 2.5v when no current is flowing and increase or decrease the voltage depending on which direction the current is flowing.
    None of them use the full 0 to 5v range for their output, the 20A version I have used has a sensitivity value of 100mv per 1A of current flow. As this is a 20A device we can multiply the 100mv by 20 and we get 2000mv or a 2v change for 20amps. We know the ACS712 shows an output of 2.5v when no current is flowing so using the 2v we now have the output range from .5v to 4.5v.
    To use this device then we need a way to convert its voltage output to a measurement in amps.

    Here is the basic equation needed

    amps = ((voltsPerCount * count) – offsetVolts) / sensitivityVolts

    Where

    VoltsPerCount is the volt value per count of the Arduino ADC. The ADC measures the voltage present at the analog pin (0 to 5 volt) and then assigns the result as a count from 0 to 1023, that's 1024 counts including zero. If we divide 5v by 1024 we get .00488 volts for each count. So VoltsPerCount = .00488 Volts

    count is the value our Arduino ADC returns after processing the output from the ACS712.

    So after the first part of the equation (.00488 * (count) is complete we have converted our count reading from the arduino into volts.

    The ACS712 can measure current flow in both directions so it outputs a voltage of 2.5v as it's center point (when no current is flowing). To allow for this offset we must subtract the 2.5v to center a 2.5 voltage reading at zero. So offsetVolts = 2.5 Volts

    That's what the next part does ((.00488 * (count)) - 2.5) After this is complete we are left with a negative or positive voltage for current flowing in either direction or a value of zero for no current flow.

    The sensitivity values for the ACS712 are shown on the datasheet as

    185mv per Amp for the 5A
    100mv per Amp for the 20A
    66mv per Amp for the 30A

    So to convert our value in volts to a value in amps we need to add the last part
    ((.00488 * (count)) – 2.5)/sensitivityVolts

    Where sensitivityVolts equals the sensitivity value in volts for the device you are using. In my case the 20A version 100mv = .1 volts

      amps = ((.00488 * (count)) – 2.5) / .1
    

    Another way to do this would be to use the Arduino map function
    we worked out earlier that the 20A version would output in the range from .5 to 4.5 volts, to convert that to count values we need to divide by .00488 .
    Which gives us .5 / .00488 = 102 and 4.5 / .00488 = 922. map can only work with integers so it is best to use milliamps instead of amps for the output result.

    The Arduino code for the 20A ACS712 would be:

         milliamps =  map(count, 102, 922, -20000, 20000);
    

    Both of the above methods give very close results so you could use either. I have used the first method as it is easier to select the version of ACS712 you are using by changing the sensitivity.

    The ACS712 is a hall effect device so it can be affected by stray magnetic fields that are nearby. It is best to locate it as far away as possible from any magnetic source to ensure you are getting a true reading. In use I found this was sometimes hard to achieve so I have added code to zero the reading if required. To do this I have used a push button and LED. If you are getting a constant current reading when no current is flowing simply push and hold the button until the led flashes. The sketch will then work out the offset required and apply that to zero the reading. This offset amount will then be saved to the Arduino EEPROM and will be reloaded and used even if the arduino is reset.

    I am using Domoticz as my controller, here is what the end result looks like.

    0_1462664203469_dom.jpg

    My Project

  • MY_TRANSPORT_DONT_CARE_MODE
    Boots33B Boots33

    @okos said:

    I would like to ask whether it is normal that the switch does not work if the server domoticz off? I want to use the switch only crash server :flushed: now i cant"

    Yes that is correct. The "relay with button actuator" sketch relies on an ack back from the controller to do the actual switching. so if the Gateway or Controller go down the local switch will also no longer work

    And i got a reply from @hek it will be in the new library.(post 90)
    Now i see 2.1.0 , and i have question now it is work?

    MY_TRANSPORT_DONT_CARE_MODE has been deprecated and did not make it into MySensors 2.1. As @Fabien has said you now need to use MY_TRANSPORT_WAIT_READY_MS instead.

    What I need to change in the code or configurations (MyConfig.h) to work the physical switch when the failure of the gateway.

    You have two choices, you can modify your MyConfig.h file or Define the change at the top of your sketch.
    If You have a look at the MyConfig.h file you will see that at around line 179 is the area you need to be looking at. The default value is 0 which means no timeout so the sketch will not proceed to the loop part if a connection is not established.
    However I think the best solution will be to Define the change in your sketch rather than change your config file.

    I have not used MY_TRANSPORT_WAIT_READY_MS before but it most likely will need to be added to the top of your sketch before the #include <MySensors.h> line.

    Like this

    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    
    // Enabled repeater feature for this node
    #define MY_REPEATER_FEATURE
    
    //set how long to wait for transport ready. in milliseconds
    #define MY_TRANSPORT_WAIT_READY_MS 3000
    
    #include <SPI.h>
    #include <MySensors.h>
    #include <Bounce2.h>
    

    As this is only run once when the node first boots up you should allow plenty of time to start up normally if a connection is available. In the example above I have used 3 seconds but you may need to play with that to give your sketch the best chance of getting a connection without waiting too long.

    As noted earlier in my post even once you get your sketch to run the loop the switch still will not work without a connection to the controller. So you will need to make some other changes to the sketch as well.

    @hek Has given you a good start with the code modifications needed with the post above. There will be other issues to consider such as keeping the controller in sync with the node but best to get the basics right first then add the extras later.

    Troubleshooting

  • Round water tank level sensor
    Boots33B Boots33

    This describes a water tank level sensor for use in a MySensors network. It uses a DYP-ME007Y waterproof ultrasonic sensor to determine the height of water in a round tank. Based on the water height it then works out the amount of water available in litres and also the percentage of water available. Then the results are transmitted via the MySensors network back to the controller.

    At this time I have not permanently mounted this node to the tank but in testing it does seem to work ok. I will post back when the whole thing is finished but wanted to share the project so far.

    The DYP-ME007Y is a bit fussy about the correct voltage. It needs a good solid 5v supply if you want to get a stable reading. It has a stated range from 30cm to 350cm.
    The 30cm minimum may prove a problem in some tanks if you do not have the space above the full water line but it worked out ok for my situation. In testing I could get stable readings down to 25cm but under that it became unreliable.

    Initially I also had problems with unstable readings once I got over 120cm but this turned out to be caused by a a lack of power while using the USB connection. Once the unit was powered from an external source delivering a good 5v supply the DYP-ME007Y performed within spec.
    This is a repeater node so I am using a Di-pole antenna on the nrf to increase range. I have found this mod to give good results so is worth the effort if you have room for the leads.

    The node will be mounted in a round 50mm pvc case. I have several outside nodes using these now, they are very easy to construct, totally rain proof and allow easy access to the arduino for updates etc.

    The sketch is running on MySensors V2.1.1
    I am using the NewPing library to interact with the DYP-ME007Y
    I use sonar.ping_median(5) to take 5 readings and return the median of the results. This will hopefully reduce the amount of incorrect readings.
    I also constrain the return from the DYP-ME007Y so the readings stay within the known limits of the tank.
    I am using the map function to work out the percentage of water available

    There are a few variables you will need to change to suit your particular tank. Refer to the picture below. All measurements are in cm.

    sensHeight: is the distance from the transducer to the height of the water when the tank is full. The full level will usually be the bottom edge of your overflow outlet. Remember with the DYP-ME007Y this has to be at least 25cm.

    fullHeight: Is the distance from the bottom of the tank to the level of water when the tank is full.

    outletHeight: is the distance from the bottom of the tank to the level you want to be shown as empty. As it is not good for a pump to suck air you would usually make this a comfortable distance above the water outlet.

    tankRad: Radius of tank

    0_1487490226951_TankNoReserve.jpg

    Sketch:

    /* 
    Sketch to read level of water in a round tank and  then send data back to controller
    uses MySensors V2 .
    
    Libraries used
    MySensors          https://www.mysensors.org/
    NewPing            https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home
    SPI                 installed with arduino IDE
    
    */
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    // Enabled repeater feature for this node
    #define MY_REPEATER_FEATURE
    // #define MY_NODE_ID 9    // comment out this line if you use dynamic id's
    // #define MY_RF24_CHANNEL 84    // channel of nrf network
    
    #include <MySensors.h>
    #include <SPI.h>
    #include <NewPing.h>
    
    
    #define CHILD_ID_WATER 1
    #define CHILD_ID_PERCENT 2
    
    
    // newping settings
    #define TRIGGER_PIN  6                  // Arduino pin 6 connected to trigger pin on the ultrasonic sensor.
    #define ECHO_PIN     7                  // Arduino pin 7 connected to echo pin on the ultrasonic sensor.
    #define MAX_DISTANCE 240                // Maximum distance we want to ping for (in centimeters). you should set this to be 
                                            // a bit more than fullHeight + sensHeight.
    
    /*------change these to suit your tank setup-----*/
    const int tankRad = 170;                // Radius of tank in cm
    const int fullHeight = 198;             // Height of water when tank full in cm
    const int sensHeight = 30;              // height of sensor above full water mark in cm
    const int outletHeight = 7;             // height of water when tank reading will show empty in cm
    /*----------------------------------------------*/
    unsigned long heartbeatDelay = 120;     // how often the heartbeat will be sent, in minutes
    unsigned long lastHeartbeat = millis(); // holder for last time heartbeat was sent
    unsigned long waitTime = 6000;          // delay in milliseconds to set time between data readings 
    unsigned long pingHeight;               // holds total height from ultrasonic sender to current water height
    unsigned int waterAvail;                // holds current water available in litres
    byte oldWaterPercent; 
    byte waterPercent = 0 ;                 // used to hold the tank water level percentage
    
    // NewPing setup of pins and maximum distance.
    NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); 
    
    MyMessage msgVolume(CHILD_ID_WATER, V_LEVEL);              //water availble in liters
    MyMessage msgPercent(CHILD_ID_PERCENT, V_LEVEL);           // water percentsge available
    
    void setup() {
    
    }
    
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Tank Level", "1.0");
    
      // Register all sensors to gateway (they will be created as child devices)
      present(CHILD_ID_WATER, S_DUST,"Water Available");
      present(CHILD_ID_PERCENT, S_DUST,"Water Percentage Available");
    }
     
    
     void loop()
     { 
     
     
       data_calc();      // perform calculations to get water remaining etc.
     
     
      if(oldWaterPercent != waterPercent) {         //check to see if new water data is available  
      send(msgVolume.set(waterAvail));
      send(msgPercent.set(waterPercent));
      oldWaterPercent = waterPercent;
      }   
     
      heartbeatCheck();                                    // call heartbeat function
     
      wait(waitTime);  //Wait then back to loop
      
    }
    
    /*-------------------------start of functions-------------------*/
    
    void heartbeatCheck(){
    unsigned long millisNow = millis();           // get the current time
    if ((millisNow - lastHeartbeat) > (heartbeatDelay*60000)) {  
      sendHeartbeat();
      wait(5);
     // sendBatteryLevel(100);
      lastHeartbeat = millis();
      #ifdef MY_DEBUG
        Serial.println("Heartbeat Sent" );
      #endif
    }
    }
    
     void data_calc() {
     pingHeight = sonar.ping_median(5);             //- Do multiple (5) pings and return median
     pingHeight = sonar.convert_cm(pingHeight);     // then convert to cm
     #ifdef MY_DEBUG
      Serial.print("Ping Height raw in cm: ");
      Serial.println(pingHeight);
     #endif
     pingHeight  = constrain(pingHeight, sensHeight, (fullHeight-outletHeight)+sensHeight);     // keep pingHeight within the expected values
     waterPercent = map(pingHeight,sensHeight,(fullHeight-outletHeight)+sensHeight,100,0);           // calculate the percentage of water available
     waterAvail = PI* pow(tankRad,2)*(((fullHeight-outletHeight)+sensHeight)-pingHeight)/1000;    // calculate water available in litres
    
    // Write some debug info
      #ifdef MY_DEBUG
        Serial.print("Ping Height constrained in cm: ");
        Serial.println(pingHeight);
        Serial.print("Percentage Available: ");
        Serial.println(waterPercent);
        Serial.print("Litres Available: ");
        Serial.println(waterAvail);
      #endif
     }
     
    

    It might look a bit strange that i have used the dust sensor for the MySensors data but (in Domoticz at least) they allow for the best visualisation I think.

    0_1487490552307_Screenshot (46).jpg

    Wiring:

    0_1487490843740_wiring.jpg

    All the parts are mounted on a small prototype board. I cut away the board behind the antenna to allow for better reception. I also had to re-position the socket for the transducer to allow it all to fit in the tube.

    0_1487490750824_IMG_20170219_112051.jpg

    The board is then slid inside the tube

    0_1487490929849_IMG_20170219_164616.jpg

    0_1487490946006_IMG_20170219_164539.jpg

    The bottom cap is glued on to prevent moisture from entering but the top is just pressed on to allow easy access when needed. The arduino is positioned at the top so I can quickly connect a serial lead with the cap off. A water proof gland is used at the bottom for the power and transducer cables.

    0_1487491162803_IMG_20170219_164653.jpg

    My Project

  • Outdoors Touch Switch light controller
    Boots33B Boots33

    I have a few lights around the yard under MySensors control now so I am building a touch controller to turn them on and off. This will be located at the beginning of the main path that leads to our garden areas.

    The unit will be constructed using 100mm pvc pipe and connectors. There will be 4 touch studs, these will be stainless M8 cup head bolts.

    Here are the main parts to the housing. The end cap will be glued on the pipe and then partly buried. Once in the ground i will fill it with 20mm gravel to keep it stable. The touch studs and node electronics will all be located in the top joiner and cap.

    0_1490444849562_parts.jpg

    The joiner has a lip around the inside, i have used that to hold the arduino etc.

    0_1490445210961_joiner.jpg

    The mounting plate is made from an old plastic cutting board

    0_1490445345413_mounting plate.jpg

    It just slips into place and uses gravity to hold it there.

    0_1490445411976_in joiner.jpg

    The cap with the studs uses solid wire held in place with hot glue to run out to the touch switch wires . Single dupont connectors push directly on to these. It is important to keep the wires separate from each other to reduce the chance of cross triggering.

    0_1490445682964_cap wire.jpg

    I have also added a small piezo buzzer to give an audible beep when a stud is touched.

    0_1490445947355_buzzer.jpg

    The circuit diagram. This shows it with a nano but I have used a pro mini in the actual unit.

    0_1490446124503_touchPiezo.jpg

    The Sketch for the touch controller is below. It is working ok on the bench. As you can see three of the the buttons all switch the same node at the moment. I will change these to the correct id's once it is installed outside.

    /*  
     * This is a  MySensors node used to control
     * other Binary Switch nodes on the network.
     * It uses node to node messaging to control three nodes directly and a
     * binary switch sensor to be used as a group control in Domoticz
     * 4 way touch switch module for input.
    */
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    //#define MY_PARENT_NODE_ID 1
    //#define MY_PARENT_NODE_IS_STATIC
    #define MY_NODE_ID 100
    #define GROUP_SW_ID 4
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    #define MY_RF24_CHANNEL 84
    #define MY_TRANSPORT_WAIT_READY_MS 3000
    //#include <SPI.h>
    #include <MySensors.h>
    
    uint8_t sensorId = 3;               // Id number of the sensor to send to
    uint8_t nodeId = 201;                 //Id number of the node to send to
    uint8_t sendingSensorId = 1;        // Id number of the sensor sending the message
    
    int buzzerPin = 7;          // arduino pin buzzer is connected to 
    int touchState[5] ;
    int oldTouchState[5] ;
    bool groupState = false;
    
    MyMessage msg(GROUP_SW_ID, V_STATUS);
    
    void setup()
    { 
     for(int i = 3; i < 7; i++){    //set Arduino digital pins 3 to 6 as inputs
       pinMode(i, INPUT);
     }
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Touch controller", "1.0");
      // Register all sensors to gateway (they will be created as child devices)
      present(GROUP_SW_ID, S_BINARY, "Group controller switch");
      
    }
    
    void loop()
    {
    for ( int pinNo = 3, touchNo = 1; pinNo < 7; pinNo++, touchNo++){
        touchState[touchNo] = digitalRead(pinNo);                                                             // Get the current touch switch state
        if (touchState[touchNo] != oldTouchState[touchNo] && touchState[touchNo] == 1) {                      // check for new touch button push
          switch(touchNo){
           case 1:
             /*   Node to Node message format. Note: message is still routed through the gateway or repeater node,         *
              *                                      not diectly to destination Node.                                      *
              *                                                                                                            *
              *            : Id of sending  : message  :   Destination     :     Destination      : Payload                *
              *            :    sensor      :  Type    :    sensor Id      :       Node Id        :                        */ 
             send(MyMessage(sendingSensorId, V_STATUS).setSensor(sensorId).setDestination(nodeId).set(true));  //send message to desitination node from touch 1
             wait(5);
             tone(buzzerPin, 1200, 60);                                                                        //Play short beep to acknowledge touch.  PIN, TONE FREQUENCY, DURATION  
             break;
           case 2:
             send(MyMessage(sendingSensorId, V_STATUS).setSensor(sensorId).setDestination(nodeId).set(true));  //send message to desitination node from touch 2
             tone(buzzerPin, 1200, 60);                                                                        //Play short beep to acknowledge touch
             break;
             case 3:
             send(MyMessage(sendingSensorId, V_STATUS).setSensor(sensorId).setDestination(nodeId).set(true));  //send message to desitination node from touch 3
             tone(buzzerPin, 1200, 60);                                                                        //Play short beep to acknowledge touch
             break;
           case 4:
             groupState = !groupState ;                                                                          //Toggle the state
             send(msg.set(groupState), false);                                                                   // send new state to controller, no ack requested
             tone(buzzerPin, 1200, 60);                                                                          //Play short beep to acknowledge touch
             break;    
        }  
      }    
     }
     
     for (int i = 1; i < 5; i++){
      oldTouchState[i] = touchState[i];
     } 
    }
    
    void receive(const MyMessage &message) {
      if (message.type == V_STATUS && message.sensor == GROUP_SW_ID) {
        groupState = message.getBool();
      }
    }
    

    Here is the double binary switch node sketch I have been using as the test receiver.

    /* This sketch is to control two outdoor lights and also
     *  allow control from a remote switch 
    */
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    #define MY_RF24_CHANNEL 84
    //#define MY_PARENT_NODE_ID 1
    //#define MY_PARENT_NODE_IS_STATIC
    #define MY_NODE_ID 201
    
    
    //#include "SPI.h"
    #include <MySensors.h>
    
    #define LIGHT_PIN_A  6             // Arduino Digital I/O pin connected to mosfet 1
    #define LIGHT_PIN_B  7             // Arduino Digital I/O pin connected to mosfet 2
    #define LIGHT_ON 1                 // Output value to write to turn on attached mosfet
    #define LIGHT_OFF 0                // Output value to write to turn off attached mosfet
    #define CHILD_ID_LIGHT_A 3
    #define CHILD_ID_LIGHT_B 4
    
    unsigned long heartbeatDelay = 120;     // how often the heartbeat will be sent, in minutes
    unsigned long lastHeartbeat = millis(); // holder for last time heartbeat was sent
    bool stateA = 0;                        // State holder for light A
    bool stateB = 0;                        // State holder for light B
    
    MyMessage msgA(CHILD_ID_LIGHT_A, V_STATUS);
    MyMessage msgB(CHILD_ID_LIGHT_B, V_STATUS);
    
    void setup() {
      pinMode(LIGHT_PIN_A, OUTPUT);            //set light pin as output
      pinMode(LIGHT_PIN_B, OUTPUT);            //set light pin as output
      digitalWrite(LIGHT_PIN_A, LIGHT_OFF);    //   make sure light is off at startup
      digitalWrite(LIGHT_PIN_B, LIGHT_OFF);    //   make sure light is off at startup  
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Light controller", "1.0");
      // Register all sensors to gateway (they will be created as child devices)
      present(CHILD_ID_LIGHT_A, S_BINARY, "Lamp Post Light");
      present(CHILD_ID_LIGHT_B, S_BINARY, "Garden Lights");
    }
    
    void loop()
    { 
     heartbeatCheck();                  // call heartbeat function
    }
    
    
    /*-------------------------start of functions-------------------*/
    
    void heartbeatCheck(){ 
     if ((millis() - lastHeartbeat) > (heartbeatDelay*60000)) {  
      sendHeartbeat();
      lastHeartbeat = millis();
      #ifdef MY_DEBUG
        Serial.println("Heartbeat Sent" );
      #endif
     }
    }
    
    void receive(const MyMessage &message) {
    
    if (message.type == V_STATUS) {                                  // check that message is for binary switch
      if (message.sender == 0) {                                     // check if message is from gateway (node 0)   
        switch (message.sensor) {
         case 3:                                                     //incoming message is for light A  (sensor 3)
           stateA = message.getBool();
           digitalWrite(LIGHT_PIN_A, stateA ? LIGHT_ON : LIGHT_OFF); // Set Light A to the new state
           break;
         case 4:                                                     //incoming message is for light B  (sensor 4)
           stateB = message.getBool();
           digitalWrite(LIGHT_PIN_B, stateB ? LIGHT_ON : LIGHT_OFF); // Set Light B to the new state
           break;       
       }   
      } 
      else  {                                                         // message is not from gateway so must be from a remote
        switch (message.sensor) {
          case 3:                                                     //incoming message is for light A (sensor 3) 
            stateA = !stateA;                                         // toggle light state
            digitalWrite(LIGHT_PIN_A, stateA ? LIGHT_ON : LIGHT_OFF); // Set Light A to the new state
            send(msgA.set(stateA), false);                            //Message the gateway so controller will be aware of the change. No ack
            break;
          case 4:                                                     //incoming message is for light B  (sensor 4)
            stateB = !stateB;                                         // toggle light state 
            digitalWrite(LIGHT_PIN_B, stateB ? LIGHT_ON : LIGHT_OFF); // Set Light B to the new state
            send(msgB.set(stateB ? true : false));                    //Message the gateway so controller will be aware of the change. No ack
            break;     
        }
       }
      } 
        /*-------Write some debug info-----*/
    #ifdef MY_DEBUG
        Serial.print("Incoming change for sensor:");
        Serial.print(message.sensor);
        Serial.print(" from node: ");
        Serial.println(message.sender);
    #endif  
    }
    
    
    
    My Project

  • Fire pit RGB striplight controller
    Boots33B Boots33

    I built a fire pit in our back yard using an old crusher mantle.

    0_1474105410511_pit2.jpg

    I wanted the area to look nice so added some led strip lighting to the underside of the railings

    0_1474105518826_DSCN0590.jpg

    There are some clear led garden lights as well. Together the make a very inviting place to entertain friends.

    0_1474105718510_combo.jpg

    and a very comfy place to relax on the cooler nights

    0_1474105787319_pit.jpg

    So now it is time to bring the lighting under Mysensors control. This is a work in progress and I will post wiring etc as I go but thought i would throw the sketch up for a start.

    This node will control the RGB strip as well as separate switch for the white garden lights. In Domoticz the RGB controller looks like this. It can be used to set the brightness and colour of the strip. I will be using mosfet's to control all of the lights.

    0_1474106133732_Screenshot (140).jpg

    The current sketch is working well on a breadboard prototype using a single RGB led . I will probably add some form of colour cycling as well as I progress.

    /*
    RGB LED Node for 12v common anode rgb strip,
    Also has a standard on/off switch to control an extra set of garden lights 
    PWM pins (3, 5, 6, 9, 10, or 11).
    */
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    #define MY_NODE_ID 200  // I use 200 for my test nodes I will remove this line when it is installed
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
     
    #include <SPI.h>
    #include <MySensors.h>
    #define RGB_CHILD_ID 1  // the rbg device includes a dimmer and on/off switch as well
    #define CHILD_ID_LIGHT_B 2
    
     const int controlPinA = 7;  //used to turn of rgb Power pin
     const int controlPinB = 8;  //used to switch off other garden lights
     const int redPin = 3;     //pin used to switch the red mosfet
     const int greenPin = 5;  //pin used to switch the green mosfet
     const int bluePin = 6;  //pin used to switch the blue mosfet
     long RGB_values[3] = {0,0,0};  //array used to hold the three rgb colours
     int dimSet = 0;                 // holder for the current dimmer setting
    // int dimHolder = 0;             
    
     
    void setup()
    {
      pinMode(controlPinA, OUTPUT);    //|
      pinMode(controlPinB, OUTPUT);    //|
      pinMode(redPin, OUTPUT);         //| setup pins as outputs
      pinMode(greenPin, OUTPUT);       //| 
      pinMode(bluePin, OUTPUT);        //|
      setColor(0,0,0);                 // make sure lights are off when first booted
    }
    
    void presentation()  {
      // Present sketch (name, version)
      sendSketchInfo("RGB Node", "1.0");        
           
      // Register sensors (id, type, description, ack back) 
       present(RGB_CHILD_ID, S_RGB_LIGHT,"Firepit RGB Control");
       present(CHILD_ID_LIGHT_B, S_LIGHT,"Firepit Lights");
    }
     
    void loop()
    {
      //nothing needed in here
    }
    
    /*-----------------Start of functions---------------------*/
    
    
    /*----------- function to display LED colour as well as set brightness------------*/
    void setColor(int red, int green, int blue){  
    if (dimSet != 0){
     analogWrite(redPin, round(red*dimSet/100));          //|
     analogWrite(greenPin, round(green*dimSet/100));      //| change the three rgb colours and adjust brightness
     analogWrite(bluePin, round(blue*dimSet/100));        //|
    }
    else{                                                // if dimmer setting is 0 then set all colours to 0
      analogWrite(redPin, dimSet);
      analogWrite(greenPin, dimSet);
      analogWrite(bluePin, dimSet);
    }  
    #ifdef MY_DEBUG            //Print debug info if enabled
      Serial.print("RED = ");
      Serial.println(red);
      Serial.print("BLUE = ");
      Serial.println(blue);
      Serial.print("GREEN = ");
      Serial.println(green);
     #endif
    }
    
    
    
    void receive(const MyMessage &message) {
      
     if (message.type==V_RGB) {             //check for RGB message type
          /*   process the RGB hex code    */
        String rgbHexString = message.getString();                      //Load the hex color code into a string
        long number = (long) strtol( &rgbHexString[0], NULL, 16);
        RGB_values[0] = number >> 16;
        RGB_values[1] = number >> 8 & 0xFF;
        RGB_values[2] = number & 0xFF;
        setColor(RGB_values[0],RGB_values[1],RGB_values[2]);            // call the setColor function to update the LED's
      #ifdef MY_DEBUG                                                   //Print debug info if enabled
         Serial.print("HEX RGB " );
         Serial.println(rgbHexString);
         Serial.print("long number " );
         Serial.println(number);
      #endif
     }
         
     if (message.type==V_DIMMER) {                                        //check for dimmer message type
        dimSet = message.getInt();                                        // Load the dimmer setting into dimSet
        setColor(RGB_values[0],RGB_values[1],RGB_values[2]);              // call the setColor function to update the LED's. new dimmer setting
        #ifdef MY_DEBUG                                                   //Print debug info if enabled
         Serial.print("dimmer setting " );
         Serial.println(dimSet);
        #endif
     }
          
     if (message.type==V_LIGHT) {                                     //check for incoming  light switch message type
        switch (message.sensor) {
          case 1:                                                     //message is for sensor 1 (RGB switch)
            digitalWrite(controlPinA, message.getBool() ? 1 : 0);
            break;
          case 2:                                                     //message is for sensor 2 (garden lights)
            digitalWrite(controlPinB, message.getBool() ? 1 : 0);
            break;
         }
        #ifdef MY_DEBUG
          Serial.print("Incoming change for sensor:");
          Serial.println(message.sensor);
          Serial.print("Light switch setting " );
          Serial.println(message.getBool());
        #endif
        }
     }
    
    
    
    
    
    My Project

  • i2c Lightning Sensor +
    Boots33B Boots33

    I have progressed a little further with this project an am nearly ready to install this one outside. I have changed the sketch to be MySensors V2 compliant and also added an extra mosfet to control a second set of garden lights as well. I remembered the garden lights run on 12v AC so had to include a rectifier in the circuit as well. Seems to run on the bench ok, but of course no storms to check the lightning . Will upload the new sketch and wiring soon.

    Antennae Mounted on lid. I am using a shielded nrf24l01+pa+lna module to increase the range. tests I have done with this one seem to be promising.

    0_1469316491114_IMG_20160724_085734.jpg

    The main board with two mosfets

    0_1469316594276_IMG_20160724_085325.jpg

    A good fit in the tube.

    0_1469316687256_IMG_20160717_154625.jpg

    My Project

  • Car Aux Battery Monitor
    Boots33B Boots33

    We enjoy getting away and camping in remote areas whenever we get the chance. We rely on a second battery fitted in the 4wd to power our fridge and provide lighting. This second battery sadly gets little attention paid to it in between trips, though it is connected to the car charging circuit to keep it topped up.

    So I thought it time to give it the attention it deserves by fitting a MySensors node to monitor the battery voltage. This will allow my Domoticz controller to keep any eye on how it is going and let me know if it strays too far from the norm.

    This node has just one job to do, that is simply to monitor and report the voltage present at the second battery. A simple voltage divider is used to sample the battery voltage.

    As the node will be fitted to a vehicle that will spend some part of the day away from home the sketch first checks for the gateway's presence before sending the information. The node sleeps most of the time only waking for a few seconds every hour to check and send data.

    Domoticz Output

    0_1506244965460_output.jpg

    The sketch

     /*Sketch for a MySensor node to monitor a 12v aux battery in a 4wd ute 
     * The node monitors battery voltage and reports back to the controller.
     * 
     * 
     */
     
    
    #define MY_DEBUG                             // Enable debug prints to serial monitor
    #define MY_RADIO_NRF24 // Enable and select radio type attached
    #define MY_TRANSPORT_WAIT_READY_MS 3000  //set how long to wait for connection to establish before moving on. in milliseconds
    //#define MY_NODE_ID 15
    //#define MY_RF24_CHANNEL 84                   // set channel used
    //#define MY_PARENT_NODE_ID 1                 // set the parent node
    //#define MY_PARENT_NODE_IS_STATIC             // force connection to parent node only.
    #include "MySensors.h" 
    
    #define ID_S_MULTIMETERV 1                   // Multimeter device for voltage measurement
    
    unsigned long sleepTime = 60000*60;          // Sleep time between reads (in milliseconds) (Set to 1 hour at present)
    int voltagePin = A0;                         // analog pin voltage sensor or voltage divider is connected to
    int voltSenseMax = 23460;                    // set to the maximum voltage in millivolts of your voltage divider input    
                   
    MyMessage msg_S_MULTIMETERv(ID_S_MULTIMETERV,V_VOLTAGE);
    
    void setup()
    {
     
    }
    
    void presentation()  {  
     sendSketchInfo("Vehicle Battery Sensor", "1.1");    // Send the sketch version information to the gateway and Controller
     present(ID_S_MULTIMETERV, S_MULTIMETER);                // Register Sensor to gateway 
    }
     
    void loop()
    {
    uplinkCheck();                                       // call function to send data
    Serial.println("sleeping now");
    sleep(sleepTime);                                    // sleep until next scheduled check
    Serial.println("awake now");
    wait (50);                                           // small wait to allow to stabalise after sleep.
    
    }
    
    /*-------------------start of functions--------------------------*/
    
    void uplinkCheck() {
      if (request( ID_S_MULTIMETERV, V_VOLTAGE)) {          // request the current voltage data from the controller and check that the request was succsessful
      Serial.println("uplink established");
      int voltRead =  analogRead(voltagePin);
      int voltMilli = map(voltRead,0,1023,0,voltSenseMax);  // map the reading and get the result in millivolts
      send(msg_S_MULTIMETERv.set(voltMilli / 1000.0, 2));   // Divide by 1000 to convert back to volts to two decimal places, send data to controller.                                                                                                                                            // send voltage message to gateway with 1 decimal place
      }
      else{
        Serial.println(" No uplink ");      
      }
    
    }
    
    
    

    The circuit

    0_1506759444574_collie bat mon.jpg

    The board

    0_1506244879140_board front.jpg

    0_1506244900273_IMG_20170924_173746.jpg

    Testing at the moment hope to fit it next weekend.

    My Project

  • Poolside Music Player
    Boots33B Boots33

    I built a pool thermometer to keep track of the water temperature but the node could not reliably connect to the closest repeater.
    The repeater node was not that far away so I think maybe the closeness of the water and perhaps the pool fence were causing some problems. The easiest solution was to just deploy another repeater node to bridge the gap.

    I didn't wan't to have a node just for repeating the temp data so decided to make use of it as a music player for the pool area as well.

    To keep it simple I settled on a cheap Bluetooth enabled amplifier module and a couple of marine speakers, The node just turns power on and off to the amp and I can control the volume and stream music from my phone via the bluetooth connection.

    For convenience I have set up a button on my Touch switch so I can turn the amp on/off when walking down to the pool area.

    The circuit is just a simple single switch type node to control power to the amp.

    0_1514807588204_pool player.jpg

    The sketch is a standard relay control with a timer to shut down the amp after 3hrs. We are seldom in the pool for longer than that and wanted a way to ensure the amp is not left switched on by accident.

    /**
     *Node to control pool music player 
     *
     *Auto turns off after preset time
     *
     */
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    #define MY_RF24_CHANNEL 84
    #define MY_REPEATER_FEATURE
    
    #include <MySensors.h>
    
    #define PLAYER_PIN  6                          // Arduino  pin number for Player power control
    #define PLAYER_ID  1                          // Id of the player control child
    
    unsigned long millisNow = 0;                  // holder for the current time
    unsigned long startMillisA = 0;
    unsigned long activeTimeA = 180;             // how long the player will stay on, in minutes
    const int switchOn = 1; 
    const int switchOff = 0;
    int timerMarkerA = 0;                       // Used to tell if timer A is active
    bool stateA = false;                        // State holder for player
    
    MyMessage msgA(PLAYER_ID, V_STATUS);
    
    void setup()
    {
     pinMode(PLAYER_PIN, OUTPUT);               // set player pin in output mode 
     digitalWrite(PLAYER_PIN, switchOff);       // Make sure player is off when starting up
    }
    
    void presentation()
    {
    	// Send the sketch version information to the gateway and Controller
    	sendSketchInfo("Pool Player", "1.3");
    	present(PLAYER_ID, S_BINARY,"Pool Player");
    	}
    
    
    void loop()
    {
    poolTimer();
    }
    
    void receive(const MyMessage &message){	
    	if (message.type==V_STATUS) {                                     // check that message is for binary switch
    		if (message.sender == 0) {                                      // check if message is from gateway (node 0)
          stateA = message.getBool();
          digitalWrite(PLAYER_PIN,  stateA ? switchOn : switchOff);
    		}
        else  {                                                         // message is not from gateway so must be from a remote
          stateA = !stateA;                                             // toggle player state
          digitalWrite(PLAYER_PIN,  stateA ? switchOn : switchOff);
          wait (10);
          send( msgA.set(stateA),false) ;                               // Notify controller of change  
       }   
      }
    }
    
    void poolTimer() {
      millisNow = millis();           // get the current time  
      if (digitalRead(PLAYER_PIN) == switchOn && timerMarkerA == 0 ) {        //Check relayPinA status and start timer event if relay is on.
        timerMarkerA = 1;                                                   
        startMillisA = millisNow;
      }
      if (timerMarkerA == 1 && (millisNow - startMillisA) > (activeTimeA*60000)) {   // check to see if timeout has been reached
        digitalWrite(PLAYER_PIN, switchOff);                                         // turn off player
        send(msgA.set(false),false );                                                // send message to controller so it knows the player is now off
        timerMarkerA = 0;                                                            //reset marker
        stateA = false;
      }
        if (digitalRead(PLAYER_PIN) == switchOff && timerMarkerA == 1 ) {            //if  player has been turned off by user, cancel timer event
        timerMarkerA = 0;
        Serial.println("timer A cancelled" );
      }
    
    }
    
    

    The node was constructed on a small prototype board with the nrf mounted well clear at the top.

    0_1514808205998_board.jpg

    Here it is shown with the amp and speakers during testing.
    0_1514808353051_testing.jpg

    The node was housed in a section of 90mm water pipe.

    0_1514808572491_controller.jpg

    The speakers were fitted to an existing seat/storage area. Just a bit of tidying up of the wiring etc to do.

    0_1514808657929_setup.jpg

    My Project

  • 💬 Easy/Newbie PCB for MySensors
    Boots33B Boots33

    Thanks @sundberg84 for this little board. I have just completed a sensor to monitor the state of our 12v house solar power supply.

    It uses an ACS712 Hall Effect Current Sensor Module to keep track of amps in and out of the battery. A voltage sensor to check battery levels and two DS18b20 temp sensors to monitor battery temp and ambient area temp. It reports back to our Domoticz server.

    0_1462273371700_board.jpg

    0_1462273409712_dom.jpg

    OpenHardware.io mysensors battery easy newbie pcb mysx

  • Can you help spot my sketch mistake? Why's it ignoring the delay?
    Boots33B Boots33

    That code looks ok to me. You should get a 5 second delay with that.
    Perhaps add

       Serial.println("start delay");
      // Wait between sensor readings, seems to help reliability of second reading
      delay(5000);
       Serial.println("finish delay");
    

    and see if you get your delay in the serial monitor```
    Insert Code Here

    Troubleshooting

  • Parking Sensor Node
    Boots33B Boots33

    Working on the bench will install soon

    Build a MySensors node to indicate when a vehicle is clear of the roller door when parking. As well as providing a visual aid for parking node will send door open/close data to the gateway. This can be used for security checks etc. by your controller. The LED strip will show three different colours

    Red for when the car is in the danger area under the door
    Green for when the car has cleared the door
    White for a courtesy light to allow you to exit the vehicle

    Sensor will be powered by 12v from the house auxiliary supply.

    An infrared beam will be used across the door to determine when vehicle has cleared the door area. I am using a pre built IR door minder, as these can be bought for less than $8 and are in nice cases as well. Just not worth the hassle of building them from scratch

    A 5v WS2811 RGB LED strip will be used to indicate vehicle position. I have used this type as they are simple to wire in, no need for driver transistors etc. I have used the fastled library to control the strip.

    A N/O reed switch will be used for the garage door switch. I will mount a magnet on the door which will activate the reed switch when the door is closed

    sketch

    /**
     *******************************
     *
     * DESCRIPTION
     * A node to indicate correct parking position to allow closing of garage door.
     * uses a pre built IR beam "door minder" to detect car position
     *
     * Connect N/O contacts of Infrared device between 
     *  pin 3  and GND.
     * 
     * Connect a N/O reed switch between GND and pin 2
     * 
     * Connect RGB Led strip data terminal to pin 4
     * 
     */
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    #define FASTLED_FORCE_SOFTWARE_SPI
    #include "FastLED.h"
    
    #define NUM_LEDS 18                                        // How many leds are in the strip? change this to the number of LEDs in your strip
    #define DATA_PIN 4                                         // Data pin that led data will be written out over
    #define CHILD_ID 0                                         // door switch MySensors id number
    #define IR_PIN  3                                          // Arduino Digital I/O pin for infrared device 
    #define DOOR_PIN 2                                         // pin garage door switch is connected to
    #define COLOR_ORDER  GRB                                   // if your not getting the right colours change the oder of GRB
    #define CHIPSET  WS2811                                    // select the led type
    
    int marker = 0;                           // used to decide if LEDs are allowed to turn white
    int irValue ;                             // holder for ir state
    int doorValue ;                           // holder for garage door state
    int oldDoorValue=-1;                      //set to -1 to ensure current door switch status is sent at startup
    unsigned long startMillis = 0;            // holder for the time when garage door first opens
    unsigned long millisNow = 0;              // holder for the current time
    const long activeTime = 120000;           // Time the sensor will stay active after garage door is opened in milliseconds. change this to suit your situation  
    
     CRGB leds[NUM_LEDS];                              // This is an array of leds.  One item for each led in your strip.
     MySensor gw;
     Bounce debouncerA = Bounce();                    // Instantiate  Bounce object 1.... iR switch
     Bounce debouncerB = Bounce();                    // Instantiate  Bounce object 2.... Garage Door switch
     MyMessage msg(CHILD_ID,V_TRIPPED);
    
    
    
    void setup() {
     
      gw.begin();
      gw.sendSketchInfo("Park Sensor", "1");    // Send the sketch version information to the gateway and Controller
      
      FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);       //Setup fastleds
     
        /* ----Setup the buttons as inputs and activate their internal pull-up resistor----  */
      pinMode(IR_PIN,INPUT_PULLUP);               //set pin as input and activate internal pull-up resistor
      pinMode(DOOR_PIN,INPUT_PULLUP);             //set pin as input and activate internal pull-up resistor
    
        /* ---After setting up the buttons, setup debouncers---- */
      debouncerA.attach(IR_PIN);
      debouncerA.interval(5);
      debouncerB.attach(DOOR_PIN);
      debouncerB.interval(5);
      gw.present(CHILD_ID, S_DOOR);            // Register binary input sensor to gw
      ledChange (0,0,0) ;                      //  Make sure LEDs are off at statup, set to black  
     
    }
    
    void loop() {
     
     updateSwitches();               // call function to check switches status
     millisNow = millis();           // get the current time  
     
     if (millisNow - startMillis < activeTime){    // check to see if timeout has been reached
      if (doorValue == HIGH ) {                    // garage door is open
       if (irValue == LOW ) {                      // car is in ir beam 
        ledChange(255,0,0);                        // turn LEDs red
       }
       else{
        ledChange(0,128,0);                       // car is out of ir beam, turn LEDs green
       }
      }
      else{
       if (marker == 1){
        ledChange(255,255,255);                  // door down but timer not finished. turn leds white for entry mode
       }
      }
     }
     else {                                     // Timeout has been reached. Turn off LEDs
      if (marker == 1){                          // check marker to only turn off if needed
       ledChange (0,0,0) ;                     //    turn off leds (black)
       marker = 0; 
      }
     }
    }
    
    
    /* --------------start of functions-------------- */
    
    /* --Update the switches status, send door state change if required -- */
     void updateSwitches (){
      debouncerA.update();                          // IR switch
      debouncerB.update();                          // Door switch
      irValue = debouncerA.read();                  // get the state of the IR switch
      doorValue = debouncerB.read();                // get the state of the Door switch
      if (doorValue != oldDoorValue) {             // Check if digital input has changed and send in new value if it has
       gw.send(msg.set(doorValue==HIGH ? 1 : 0));  // Send in the new value
        if (doorValue == HIGH){                    // door is open       
         startMillis = millis();                   // store start time of door opening  for timeout check
         marker = 1;                               
        }
       oldDoorValue = doorValue;
      }
     }
     
    /* ----------function to change LED color------------*/
     void ledChange (int r, int g, int b) {
      for(int ledStrip =0; ledStrip < NUM_LEDS; ledStrip++) {
       leds[ledStrip] = CRGB( r, g, b);
      }
      FastLED.show();
     }
    
    

    Wiring

    0_1463902428600_parking hookup.jpg

    My Project

  • Adding a relay switch
    Boots33B Boots33

    @drradkin
    First you need to add your serial gateway as a hardware device. You can see below my LAN Gateway on the hardware page. You will need to select the Mysensors gateway USB from the drop down list and probably enter the serial port it is connected to.

    0_1476511195973_Screenshot (146).jpg

    Once the gateway is running start up your node and then click the setup button for the mysensors gateway. You should now see the node listed. if you click on the node you will see its children listed as well. In the picture below you can see my lightning detector node which also has two light (relay) switches shown as S_LIGHTS_BINARY with child id's of 3 and 4

    0_1476511541427_Screenshot (147).jpg

    Now you go to the Devices page and you should see the switches listed there. You can see my two switches with a unit id of 3 and 4 in the middle of the list. Now to use these you will need to click on the green arrow for the switch over on the right side of the page (mine are blue as they are already added) to add them to your used devices. you will get a requester to give it a name.

    0_1476512146085_Screenshot (148).jpg

    Then you will be able to see them on your switches page. Again you can see my two switches called Flood Lights and Pool Lamps. you can turn them on and off by clicking the light globe icon.

    0_1476512427804_Screenshot (149).jpg

    Domoticz

  • How to tell if mysensors library starts up successfully?
    Boots33B Boots33

    @arraWX The line of code to force the node to move on if no gateway is found is

    //set how long to wait for transport ready in milliseconds
    #define MY_TRANSPORT_WAIT_READY_MS 3000
    

    some posts that may be of interest

    Synchronising Light switch

    Booting sensors without Gateway connection?

    use of ACK

    Development

  • Can't get started
    Boots33B Boots33

    Hi @LarsMachiels

    As @mfalkvidd has said you are starting out with MySensors right in the changeover to V2 so there is understandably a lot of data still to be updated on the site.

    luckily for you the w5100 gateway is even easier to do on V2, no more changing settings in the config files etc.

    So the first thing you must do is remove the MySensors library you have installed as it does not appear to be in the right place and may conflict with the new install.

    Make sure your IDE is the one from arduino.cc and not from arduino.org

    You can then install the MySensors v2 library using the library manager with just a couple of mouse clicks. This will put everything in the right place. See instructions in this post.

    When the MySensors library is installed it also includes many of the example sketches as well. The w5100 gateway is also included. So you just need to open it from the IDE example menu .

    0_1473634058811_Screenshot (5).jpg

    The sketch should work with your shield without much change needed. You will have to change the line that sets the ip address to the address you want.

    #define MY_IP_ADDRESS 192,168,178,66   // If this is disabled, DHCP is used to retrieve address
    

    The wiring for the radio etc will be the same as in the V1.5 w5100 guide
    Remember you no longer need to change any MySensors config files either.

    Troubleshooting

  • i2c Lightning Sensor +
    Boots33B Boots33

    Well it is now installed outside so i just have to wait for a storm to see if it performs as expected. I have made a slight change to the V2 sketch and am using V_TEXT for intensity for now, at least i can see that in Domoticz.

    The installation went well except for when I connected it up to the 12v AC the lightning sensor started producing a constant stream of disturber hits, worked fine when on battery so I guess there was too much noise from the AC. The solution was to up-cycle part of an old PC power supply, to my surprise this worked really well and the sensor is now very stable.

    All ready to go into the tube

    0_1470535773811_IMG_20160730_132537.jpg

    I used an old cork to keep the boards apart. When the boards are in the tube I can still get to the top of the pro-mini for easy updating of sketches.

    0_1470535843161_IMG_20160730_133542.jpg

    The final product ready to be mounted in the garden. I ended up with a junction box below the main sensor as there were several wires to connect up it would have been too hard to do in the sensor. Plus this will allow me to physically change what lights the sensor controls without dis-assembling the sensor.

    0_1470536012718_IMG_20160730_135527.jpg

    The sensor has already been through some heavy rain without an problems so I think this will be a good (and reasonably cheap) design for the garden.

    0_1470536305084_IMG_20160730_141651.jpg

    Here is the light it now controls

    0_1470536506814_IMG_20160730_141659.jpg

    Here is the old PC power supply that I used. The filter section was at the end of the board so I just sliced it off with my Dremel and attached some wires. A word of warning, the capacitors in these things will hold a mains charge for a long time so you must be careful to make sure they are discharged before you touch anything inside.

    0_1470536621735_IMG_20160806_153425.jpg

    My Project

  • Getting values from outside my nodes
    Boots33B Boots33

    @crankycoder said in Getting values from outside my nodes:

    that part I was able to figure out. Was hoping someone had some working examples on how to get the controller to monitor for those requests and answer back.

    I think it is as @gohan has said, if the controller supports request it will be handled automatically and returned to the asking node.

    You have to have code in your void receive(const MyMessage &message) to do something with the returning request. In Domoticz I have found it can take several hundred milliseconds for the request to return so you may have to wait before you get a result.

    Nodes can also request data directly from other nodes but you need to handle the request and return manually in that case as the controller will not be involved.

    You may find the info in this post of some use.
    I have also used request in this project where you can see the delay needed before reading the return.

    Development

  • Display node: how to set up
    Boots33B Boots33

    @Petjepet I have not done a lot with the request feature but here is how I understand it works.

    A node can make a request to the controller for information about its own child sensors by using request in its sketch. Typically this would be in the loop section of the sketch. The request is issued with the following line.

    request( sensorId, messageType)

    So if you had a binary switch sensor with a child id of 1 and you wanted to check on its status you would write it like this.

     request( 1,   V_STATUS);
    

    The request is then processed by your controller and the result is returned to the node that sent the request. You then need to have code on that node to do something with this information.

    As you have already noted this is where the void receive function is used.

    So for our example of a binary switch we could use something as simple as this

    void receive(const MyMessage &message) {
      
      if (message.type == V_STATUS) {
    
        //put code here to be executed when the return from the request arrives   
       }
     }
    

    If you have more than one child sensor that you are expecting returns from you could extend the code using message.sensor to test for which sensor the return is for.

     void receive(const MyMessage &message) {
    
      if (message.type == V_STATUS) { 
        switch (message.sensor) {
         case 1:                          //incoming message is for  sensor 1
             // put code here to be executed when the message is for sensor 1
           break;
         case 2:                       //incoming message is for sensor  2
             // put code here to be executed when the message is for sensor 2
           break;       
       }   
     }
    }
    
    

    If you wanted to separate returns from a request from normal messages from your controller. You can use message.getCommand()
    If you look in the send and receive serial data for your node you will see the command type for a request shown as c=2 , so you just need to test for type 2 commands.

     void receive(const MyMessage &message) {
    
         if (message.type == V_STATUS) { 
           if (message.getCommand() == 2){
             // put code here to be executed when the message is from a request
           }
           else {                                                             //process the message as per normal
              switch (message.sensor) {
                 case 1:                                                     //incoming message is for  sensor 1
                   // put code here to be executed when the message is for sensor 1
                   break;
                 case 2:                                                     //incoming message is for sensor  2
                   // put code here to be executed when the message is for sensor 2
                   break;       
              }   
           }
         }
     }
    
    

    Making a direct request to another node is also possible. To do that you can use the optional third parameter in the request statement which is for the node id that you are requesting information from.

    The default is set to 0 which is the gateway but you can use the node id to select another destination.

    So if we wanted information from a binary switch sensor with an id of 1 which is on a node with an id of 20 we would do this

     request( 1, V_STATUS,  20);
    

    The gateway will rout this request to the desired node but it will be up to you to have code on that node to both read the request and then send a reply back to the node that asked for the information. Of course you will also need code on the sending node to process the request when it is returned

    General Discussion

  • i2c Lightning Sensor +
    Boots33B Boots33

    I have made the changes I mentioned above. The node now resets the lightning data to 0 every hour. This I hope will give a more meaningful log over time and also provide a heartbeat to indicate the node is functioning. If lightning is detected the data reset timer begins its count from the beginning, this is to stop the data from being reset too soon.

    /* This sketch is to integrate the Playing With Fusion AXS3935 Lightning Sensor Breakout Board
    * with the MySensors V2 environment and is based on a sketch provided by Playing With Fusion
    * http://playingwithfusion.com/productview.php?pdid=22&catid=1001 and from the MySensors
    * forum post at  https://forum.mysensors.org/topic/880/sketch-for-lightning-sensor
    * 
    * Circuit:
    *    Arduino Uno     -->  SEN-39001: AS3935 Breakout
    *    SDA:    SDA     -->  MOSI/SDA   (SDA is labeled on the bottom of the Arduino)
    *    SCLK:   SCL     -->  SCK/SCL    (SCL is labeled on the bottom of the Arduino)
    *    SI:     pin  8  -->  SI (select interface; GND=SPI, VDD=I2C
    *    IRQ:    pin  3  -->  IRQ
    *    GND:    GND     -->  CS (pull CS to ground even though it's not used)
    *    GND:    GND     -->  GND
    *    5V:     5V      -->  Arduino I/O is at 5V, so power board from 5V. Can use 3.3V with Due, etc
    */
    
    
    
    
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    
    // Enabled repeater feature for this node
    #define MY_REPEATER_FEATURE
    #define MY_NODE_ID 11
    #define MY_RF24_CHANNEL 84
    #define MY_TRANSPORT_WAIT_READY_MS 3000     //set how long to wait for transport ready.
    
    #include "I2C.h"                           // the lightning sensor can communicate via SPI or I2C. This sketch uses the I2C interface
    #include "PWFusion_AS3935_I2C.h"           // include Playing With Fusion AXS3935 libraries
    #include "SPI.h"
    #include <MySensors.h>
    
    /*------- defines for hardware config---------*/
    #define SI_PIN               8              // this pin will be switched high for i2c
    #define IRQ_PIN              3              // digital pins 2 and 3 are available for interrupt capability
    #define AS3935_ADD           0x03           // x03 - standard PWF SEN-39001-R01 config
    #define AS3935_CAPACITANCE   48             // <-- SET THIS VALUE TO THE NUMBER LISTED ON YOUR BOARD                     
    volatile int8_t AS3935_ISR_Trig = 0;
    
    /*---- #defines for general chip settings----*/
    #define AS3935_INDOORS       0                       //use this setting if the sensor is indoors... more sensitive 
    #define AS3935_OUTDOORS      1                       //use this for sensor outdoors... less sensitive
    #define AS3935_DIST_DIS      0                       // dissable disturber reporting
    #define AS3935_DIST_EN       1                        // enable disturber reporting.... handy when setting up
    
    // prototypes
    void AS3935_ISR();
    
    PWF_AS3935_I2C  lightning0((uint8_t)IRQ_PIN, (uint8_t)SI_PIN, (uint8_t)AS3935_ADD);
    #define CHILD_ID_DISTANCE 1
    #define CHILD_ID_INTENSITY 2
    
    unsigned long lastReset = millis();    // holder for last time reset was triggered
    unsigned long resetTime = 60;          //  time between data resets in minutes
    bool firstBoot = true;
    
    MyMessage msgDist(CHILD_ID_DISTANCE, V_LEVEL);
    MyMessage msgInt(CHILD_ID_INTENSITY, V_LEVEL);
    
    void setup()
    {
      Serial.println("Playing With Fusion: AS3935 Lightning Sensor, SEN-39001-R01");
      Serial.println("beginning boot procedure....");
    
      /* setup for the the I2C library: (enable pullups, set speed to 400kHz) */
      I2c.begin();
      I2c.pullup(true);
      I2c.setSpeed(1);
      wait(2); 
      lightning0.AS3935_DefInit();            // set registers to default
      // now update sensor cal for your application and power up chip
      lightning0.AS3935_ManualCal(AS3935_CAPACITANCE, AS3935_INDOORS, AS3935_DIST_EN);  // capacitance , inside or outside , disturbers enabled or disabled
      // AS3935_ManualCal Parameters:
      //   --> capacitance, in pF (marked on package)
      //   --> indoors/outdoors (AS3935_INDOORS:0 / AS3935_OUTDOORS:1)
      //   --> disturbers (AS3935_DIST_EN:1 / AS3935_DIST_DIS:0)
      // function also powers up the chip
    
      // enable interrupt (hook IRQ pin to Arduino Pro Mini, Nano, Uno/Mega interrupt input: 0 -> pin 2, 1 -> pin 3 )
      attachInterrupt(1, AS3935_ISR, RISING);
      // dump the registry data to the serial port for troubleshooting purposes
      lightning0.AS3935_PrintAllRegs();
      AS3935_ISR_Trig = 0;           // clear trigger
      
      wait(1000);                    // delay execution to allow chip to stabilize.
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Lightning Sensor", "1.1");
    
      // Register all sensors to gateway (they will be created as child devices)
      present(CHILD_ID_DISTANCE, S_DUST, "Lightning Distance");
      present(CHILD_ID_INTENSITY, S_DUST, "Lightning Intensity");
    }
    
    
    
    void loop()
    {
    
    if (firstBoot){     //When node first boots clear the lightning data
     send(msgDist.set(0)); 
      wait (10);
      send(msgInt.set(0));
      firstBoot = false; 
    }
      
      // This program only handles an AS3935 lightning sensor. It does nothing until
      // an interrupt is detected on the IRQ pin.
      //while(0 == AS3935_ISR_Trig){}
     // wait(5);
     if ( AS3935_ISR_Trig == 1){
        wait(5);
        lightningDetected();             // call the lighning function
     }
       // wait(5);
       resetCheck();                      // call data reset function
    
    }
    
    /*-------------------------start of functions-------------------*/
    
    void resetCheck(){
    unsigned long millisNow = millis();           // get the current time
    if ((millisNow - lastReset) > (resetTime*60000)) {  
      lastReset = millis();
      send(msgDist.set(0));       // send lightning distance
      wait (10);
      send(msgInt.set(0));        // send lightning intensity
    }
    }
    
    // this is irq handler for AS3935 interrupts, has to return void and take no arguments
    // always make code in interrupt handlers fast and short
    void AS3935_ISR()
    {
      AS3935_ISR_Trig = 1;
    }
    
    /*--------------Lightning function----------------*/
    void lightningDetected() {
      
      AS3935_ISR_Trig = 0;                     // reset interrupt flag
    
      
      uint8_t int_src = lightning0.AS3935_GetInterruptSrc();     // now get interrupt source
    
      
    /*---0 = Unknown, 1 = Lightning detected, 2 = Disturber detected, 3 = Noise level too high ---*/
       switch (int_src) {
           case 0: {
              #ifdef MY_DEBUG                                                 
              Serial.println("Unknown interrupt source");
              #endif
              }
              break;
            case 1: {                                                      
              uint8_t lightning_dist_km = lightning0.AS3935_GetLightningDistKm();
              uint32_t lightning_intensity = lightning0.AS3935_GetStrikeEnergyRaw();
              #ifdef MY_DEBUG
              Serial.print("Lightning detected! Distance to strike: ");
              Serial.print(lightning_dist_km);
              Serial.println(" kilometers");
              Serial.print("Lightning detected! Lightning Intensity: ");
              Serial.println(lightning_intensity);
              #endif
              send(msgDist.set(lightning_dist_km)); 
              wait (10);
              send(msgInt.set(lightning_intensity));
              lastReset = millis();
              }
              break;
            case 2: {
              #ifdef MY_DEBUG                                                    
              Serial.println("Disturber detected");
              #endif
              }
              break;
            case 3: {
              #ifdef MY_DEBUG                                                   
              Serial.println("Noise level too high");
              #endif
              }
              break;
         }        
     }
    
    
    
    
    
    My Project

  • "connected()" function
    Boots33B Boots33

    @zzz-teo Have a look at these posts for a couple of ideas

    use of ACK

    MYS Library Startup Control ? After()? OnRegistration()?

    General Discussion
  • Login

  • Don't have an account? Register

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