Navigation

    • Register
    • Login
    • Search
    • OpenHardware.io
    • Categories
    • Recent
    • Tags
    • Popular
    1. Home
    2. Boots33
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Best
    • Groups

    Boots33

    @Boots33

    Hero Member

    246
    Reputation
    435
    Posts
    1877
    Profile views
    4
    Followers
    0
    Following
    Joined Last Online

    Boots33 Follow
    Hero Member

    Best posts made by Boots33

    • i2c Lightning Sensor +

      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

      posted in My Project
      Boots33
      Boots33
    • 12v Solar battery monitor

      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

      posted in My Project
      Boots33
      Boots33
    • RE: MY_TRANSPORT_DONT_CARE_MODE

      @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 ๐Ÿ˜ณ 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.

      posted in Troubleshooting
      Boots33
      Boots33
    • Round water tank level sensor

      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

      posted in My Project
      Boots33
      Boots33
    • Outdoors Touch Switch light controller

      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  
      }
      
      
      
      posted in My Project
      Boots33
      Boots33
    • Fire pit RGB striplight controller

      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
          }
       }
      
      
      
      
      
      posted in My Project
      Boots33
      Boots33
    • RE: i2c Lightning Sensor +

      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

      posted in My Project
      Boots33
      Boots33
    • Car Aux Battery Monitor

      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.

      posted in My Project
      Boots33
      Boots33
    • Poolside Music Player

      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

      posted in My Project
      Boots33
      Boots33
    • RE: ๐Ÿ’ฌ Easy/Newbie PCB for MySensors

      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

      posted in OpenHardware.io
      Boots33
      Boots33

    Latest posts made by Boots33

    • RE: 12v Solar battery monitor

      @nurul-amira Yes that should all work fine. That circuit has been running 24/7 for around 4 years now without any issues.

      posted in My Project
      Boots33
      Boots33
    • RE: How to properly handle variable requests

      @tante-ju
      Sorry for the late reply, I have been away for a few days with work.

      While I am sure there will be more than one way to achieve your goal I have given a brief outline of the way i did it below.

      If all you want to do is request data from another node it should not need any more steps than @Sasquatch has listed above.
      Lets say we have node A with an id of 1
      we also have node B with an id of 2 and it has a binary sensor with a child id of 3

      Node A wants to know the the status of the binary sensor on node B
      So in your code on node A you will issue the request to query child id 3 on node 2

       request( 3, V_STATUS,  2);
      

      The gateway will rout this directly to node B where you will need to have code to deal with the request in the receive(); function. In it's simplest form you could have something like this below.

      void receive(const MyMessage &message) {
      
           if (message.type == V_STATUS) { 
             if (message.getCommand() == C_REQ){   // message is request
      
               // put code here to be executed when the message is from a request
               // most likely you will call a function that will get the requested 
               // data and return it to node A. If you are expecting requests for more than 1
               // sensor you can use  message.sensor to test which sensor the request is for 
             
      }
             else {                                                             // message is from gateway,process the message as per normal
                 
                  // put code here to be executed when the message is from gateway   
                  }
           }
       }
      

      in the scenario above node B only expects requests from node A or commands from the gateway so it is easy to check what has arrived. If the message is a request we can execute code to get the required data and send it back. if it is a command (C_SET) from the gateway then it will fall through to the else part of the statement and be available as per normal.

      To send back the Data you will need to use a node to node message.
      this can be done on the fly, the format is shown below

       /*   Node to Node message format.                                                                                     *
                *                                                                                                            *
                *                                                                                                            *
                *            : 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 
      

      So using our example you would have. (As we are not trying to actually switch any sensors on node A we can leave out the setSensor() part of the message)

      send(MyMessage(3, V_STATUS).setDestination(1).set(true));
      

      Being a binary sensor the payload would be set to either true or false.

      Now we have sent the data all that is left to do is catch it in the recieve part of node A. One way to do this is simply to test for where the message has come from, if it is from the gateway (node 0) or in our case node 2.

      void receive(const MyMessage &message) {
      
       if (message.type == V_STATUS) {
         if (message.sender == 0) {                                        // check if message is from gateway (node 0)
          
          // put code here for normal gateway messages
          
      }
        else {                                                           // message is not from gateway so check to see if it is from node B 
          
          if (message.sender == 2 ){
      
               Put code here to deal with returning request
          }
      
      } 
      }
      }
      
      posted in Development
      Boots33
      Boots33
    • RE: How to properly handle variable requests

      sorry @tante-ju I am not quite getting what you are trying to achieve. Are you trying to request data directly from one node to the other of from a node to the controller.

      posted in Development
      Boots33
      Boots33
    • RE: How to properly handle variable requests

      @tante-ju

      If you are making a request to the controller it will return the required data for you to use, you will then need to have code on the requesting node to handle this return.

      If you are making a node to node request you will need to manually handle both the incoming request on the target node and then use node to node communication to the return of the required data to the node that requested the data. Then on the node that sent the request you will need to have code to separate this return from normal controller commands.

      In MySensors you can use message.sender to determine where the message came from and message.getCommand to see if the message is a request or command etc.

      Have a look at these three posts to see what these look like in use and also how to format a node to node message.

      https://forum.mysensors.org/topic/6422/display-node-how-to-set-up/20

      https://forum.mysensors.org/topic/6948/synchronising-light-switch

      https://forum.mysensors.org/topic/6542/outdoors-touch-switch-light-controller?_=1596330659286

      posted in Development
      Boots33
      Boots33
    • RE: House renovation, how to a good electrical system oriented to MySensors?

      @alowhum There will be a wealth of information out there on the net and probably also at your local library. look for resources about remote cabin power systems and also even the larger 5th wheeler type caravan systems will be helpful reading. You will also need to check your local building codes to see if there are any rules to be adhered to.

      When we built our house (about 15 years ago, long before i discovered MySensors ๐Ÿ™‚ we ran a low voltage backbone cable throughout the house. From this backbone we ran smaller cable drops to every room in the house. Many of these are still not in use but as others have said the cost of running wires is relatively cheap when you are building. Of course we still have mains power as well and use the low voltage system to compliment this.

      In those initial years the 12v system was used primarily for lighting systems such as night lights etc. As time progressed we installed 12v outlets in the bedrooms and these now are used to power bed/reading lamps. The small 12v downlights have also proved to be very easy to convert over as well. These were initially halogen bulbs but now there is a good range 12v LED replacements for just about any type of socket. Once I discovered MySensors and home automation then the 12v system became even more useful now powering several nodes and even the gateway.

      Right from the start we ran our system from a battery with solar charging and in 15 years it has never let us down. Voltage drop will always be a thing to watch, but with LED's low power draw and as you have surmised the ability of arduinos to run well below 12v it will usually be of little practical concern. Unless of course you are thinking of running more than lights and nodes.

      posted in Hardware
      Boots33
      Boots33
    • RE: Two MySensor gateways to the same Home Assistant

      @jocke4u yes that is correct, both gateways will also need to be using different channels as well.

      posted in Home Assistant
      Boots33
      Boots33
    • RE: Ds18b20/ nodemcu fluctuations in temp

      @mjdula
      The 85 reading is actually an error message used by the ds18b20 to indicate it has not had time to complete the processing of the reading. Most commonly this is only seen when the node first boots up and can be ignored or fixed by adding a small delay. You will find a lot of information on this if you do a google search. I have never experienced it myself but from other posts on the net it seems power supply problems and long cable runs to the sensor can also cause the error. Some have also had success by using a different resistor value. Note you only need one resistor fitted near your nodemcu not a resistor at each ds18b20.
      If the 85 reading is well outside your expected reading you could just filter out any readings over 84 as well.

      posted in Hardware
      Boots33
      Boots33
    • RE: Newbie question about how the mysensors gateway connects to controller

      yes you are correct, the serial gateway will connect to your controllers (Hassio) serial port and the Ethernet gateway will connect over your wired network connection. Both will work well, i guess the Ethernet approach gives you the flexibility of having the gateway away from the controller if needed.

      In my setup I have two gateways, both are built on NodeMCU boards and connect via wifi. they have proven very reliable as well.

      posted in General Discussion
      Boots33
      Boots33
    • RE: (Solved) S_Multimeter in HomeAssistant

      @Joost great news! always a good feeling when you find a solution to a pesky problem ๐Ÿ™‚

      posted in Home Assistant
      Boots33
      Boots33
    • RE: getting data from sensor to sensor

      @Robert-Krรณl Yes that is certainly possible, Have a look at requesting data on the api page. You can request data from any node on your Mysensors network.

      posted in Domoticz
      Boots33
      Boots33