Navigation

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

    Posts made by thumper

    • Automated Raised Garden

      This is my first MySensors project so figured I would post it in the forum and get some feedback and perhaps some optimization on my code.

      *** Disclaimer ***
      I am new to coding and new to MySensors.

      When I came across MySensors I decided I would build a monitor for a raised garden bed that I wanted. It would be able to monitor various variables and act upon the certain variables of the garden bed. I run Vera as my home automation controller and figured I could use the PLEG addon to control other sensors. Additionally, I wanted to store the variables of the garden bed and allow them to be exported for analysis.

      Some of the things I wanted to monitor:
      • Soil Moisture and Temperature
      • Water Flow
      • Amount of Light
      • Environmental Humidity and Temperature

      Some of the things I wanted to control:
      • Water Valve
      • That's it for now I guess... maybe something more later on??

      So far I have gotten everything working with the exception of the soil temperature as I have not added those sensors yet.

      My other problem is I am unable to get a reading for the flow rate sensor, I get a variable of zero (0) and nothing more even when water is flowing past the sensor. Below is the code I used I am running a Arduino Mega as I have a few laying around from other projects.

      // Enable debug prints to serial monitor
      #define MY_DEBUG
      
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      //#define MY_RADIO_RFM69
      
      // Lets get that radio working with the Mega
      #define MY_RF24_CE_PIN 49
      #define MY_RF24_CS_PIN 53
      
      // Enable repeater functionality for this node
      #define MY_REPEATER_FEATURE
      
      // Pull in those external libraries
      #include <SPI.h>
      #include <MySensors.h>
      #include <DHT.h>
      
      // Pin Numbers that the sensors are on and Define some items.
      #define DIGITAL_INPUT_SENSOR 2 // The digital input you attached your sensor.  (Only 2 and 3 generates interrupt!)
      #define RELAY_1  4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
      // #define Relay uses Digital I/O pins 4-7
      #define DHT1_DATA_PIN 8 // Temperature and Humidity sensor.
      #define DHT2_DATA_PIN 9 // Temperature and Humidity sensor.
      int mositure_sensor_pin1 = A0;
      int mositure_sensor_pin2 = A1;
      
      // Relay Information
      #define NUMBER_OF_RELAYS 4 // Total number of attached relays
      #define RELAY_ON 1  // GPIO value to write to turn on attached relay
      #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
      
      // Set this offset if the sensor has a permanent small offset to the real temperatures
      #define SENSOR_TEMP_OFFSET 0
      
      // Sleep time between sensor updates (in milliseconds)
      // Must be >1000ms for DHT22 and >2000ms for DHT11
      static const uint64_t UPDATE_INTERVAL = 60000;
      
      // Force sending an update of the temperature after n sensor reads, so a controller showing the
      // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
      // the value didn't change since;
      // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
      static const uint8_t FORCE_UPDATE_N_READS = 10;
      
      // child ID for the sensors
      #define CHILD_ID_HUM1 5 // ID of the DHT humidity sensor child
      // #define CHILD_ID_RELAY 1 // ID of the relay (It is expressed in another area of the code)
      #define CHILD_ID_TEMP1 6 // ID of the DHT temperature sensor child
      #define CHILD_ID_HUM2 7 // ID of the DHT humidity sensor child
      #define CHILD_ID_TEMP2 8 // ID of the DHT temperature sensor child
      #define CHILD_ID_SOIL1 9 // ID of the first soil monitor
      #define CHILD_ID_SOIL2 10 // ID of the second soil monitor
      #define CHILD_ID_FLOW 11 // ID of the water flow sensor
      
      float lastTemp1;
      float lastHum1;
      float lastTemp2;
      float lastHum2;
      uint8_t nNoUpdatesTemp1;
      uint8_t nNoUpdatesHum1;
      uint8_t nNoUpdatesTemp2;
      uint8_t nNoUpdatesHum2;
      bool metric = true;
      
      // Water flow sensor information
      //#define PULSE_FACTOR 12500                    // Nummber of blinks per m3 of your meter (One rotation/liter)
      #define PULSE_FACTOR 288000
      #define SLEEP_MODE false                        // flowvalue can only be reported when sleep mode is false.
      #define MAX_FLOW 25                             // Max flow (l/min) value to report. This filetrs outliers.
      #define INTERRUPT DIGITAL_INPUT_SENSOR-2        // Usually the interrupt = pin -2 (on uno/nano anyway)
      unsigned long SEND_FREQUENCY = 10000;           // Minimum time between send (in miliseconds). We don't want to spam the gateway.
      
      double ppl = ((double)PULSE_FACTOR)/1000;       // Pulses per liter
      
      volatile unsigned long pulseCount = 0;
      volatile unsigned long lastBlink = 0;
      volatile double flow = 0;
      bool pcReceived = false;
      unsigned long oldPulseCount = 0;
      unsigned long newBlink = 0;
      double oldflow = 0;
      double volume;
      double oldvolume;
      unsigned long lastSend;
      unsigned long lastPulse;
      unsigned long currentTime;
      // End water flow information
      
      // Here we are setting up some water thresholds that we will
      // use later. Note that you will need to change these to match
      // your soil type and environment. It doesn't do much for me because I'm using domoticz
      int thresholdUp = 400;
      int thresholdDown = 075;
      
       // Message from the Sensors
      MyMessage msgHum1(CHILD_ID_HUM1, V_HUM);
      MyMessage msgTemp1(CHILD_ID_TEMP1, V_TEMP);
      MyMessage msgHum2(CHILD_ID_HUM2, V_HUM);
      MyMessage msgTemp2(CHILD_ID_TEMP2, V_TEMP);
      MyMessage msgSoil1(CHILD_ID_SOIL1, V_LEVEL);
      MyMessage msgSoil2(CHILD_ID_SOIL2, V_LEVEL);
      DHT dht1;
      DHT dht2;
      MyMessage flowMsg(CHILD_ID_FLOW, V_FLOW);
      MyMessage volumeMsg(CHILD_ID_FLOW, V_VOLUME);
      MyMessage pcMsg(CHILD_ID_FLOW, V_VAR1);
      
      void before()
              //
              //  Start of the Relay before all other sections
              //
      {
          for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
              // Then set relay pins in output mode
              pinMode(pin, OUTPUT);
              // Set relay to last known state (using eeprom storage)
              digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
          }
      }
              //
              // End of the Relay before all other sections
              //
      
      void setup()
      {
        //
        // Start of the DHT setup
        //
        dht1.setup(DHT1_DATA_PIN); // set data pin of DHT sensor
        if (UPDATE_INTERVAL <= dht1.getMinimumSamplingPeriod()) {
          Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
        }
        // Sleep for the time of the minimum sampling period to give the sensor time to power up
        // (otherwise, timeout errors might occure for the first reading)
        sleep(dht1.getMinimumSamplingPeriod());
        //
        // End of the DHT Setup
        //
      
        //
        // Start of the DHT setup
        //
        dht2.setup(DHT2_DATA_PIN); // set data pin of DHT sensor
        if (UPDATE_INTERVAL <= dht2.getMinimumSamplingPeriod()) {
          Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
        }
        // Sleep for the time of the minimum sampling period to give the sensor time to power up
        // (otherwise, timeout errors might occure for the first reading)
        sleep(dht2.getMinimumSamplingPeriod());
        //
        // End of the DHT Setup
        //
      
        //
        // Begin Water Flow Setup
        //
        //begin(incomingMessage, AUTO, true);
        //begin(incomingMessage, AUTO, false, AUTO, RF24_PA_LOW);
        //begin(incomingMessage, AUTO, false, AUTO);
        //  send(pcMsg.set(0));
        //  send(volumeMsg.set(0.000, 3));
        //Water meter setup
        //Serial.print("PPL:");
        //Serial.print(ppl);
      
        // Fetch last known pulse count value from gw
        request(CHILD_ID_FLOW, V_VAR1);
        //pulseCount = oldPulseCount = 0;
      
        //Serial.print("Last pulse count from gw:");
        //Serial.println(pulseCount);
        attachInterrupt(INTERRUPT, onPulse, RISING);
        lastSend = millis();
        //
        // End Water Flow Setup
        //
      }
      
      
      void presentation()
       {
          // Send the sketch version information to the gateway and Controller
          sendSketchInfo("Garden Controller", "1.0");
      
          // Relay Presentation/Register all sensors to Gateway
          for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
              // Register all sensors to gw (they will be created as child devices)
              present(sensor, S_BINARY);
          }
          // DHT Presentation/Register all sensors to Gateway (they will be created as child devices)
          present(CHILD_ID_HUM1, S_HUM);
          present(CHILD_ID_TEMP1, S_TEMP);
          present(CHILD_ID_HUM2, S_HUM);
          present(CHILD_ID_TEMP2, S_TEMP);
      
          metric = getControllerConfig().isMetric;
      
         // Soil moisture sensor Presentation/Register this device as Moisture sensor
          present(CHILD_ID_SOIL1, S_MOISTURE);
          present(CHILD_ID_SOIL2, S_MOISTURE);
      
         // Register this device as Waterflow sensor
          present(CHILD_ID_FLOW, S_WATER);
        }
      
      void loop()
       {
        //
        // Start the DHT Sensor loop
        //
        // Force reading sensor, so it works also after sleep()
        dht1.readSensor(true);
      
        // Get temperature from DHT library
        float temperature1 = dht1.getTemperature();
        if (isnan(temperature1)) {
          Serial.println("Failed to read the temperature from DHT");
        } else if (temperature1 != lastTemp1 || nNoUpdatesTemp1 == FORCE_UPDATE_N_READS) {
          // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
          lastTemp1 = temperature1;
          if (!metric) {
            temperature1 = dht1.toFahrenheit(temperature1);
          }
          // Reset no updates counter
          nNoUpdatesTemp1 = 0;
          temperature1 += SENSOR_TEMP_OFFSET;
          send(msgTemp1.set(temperature1, 1));
      
          #ifdef MY_DEBUG
          Serial.print("Temperature: ");
          Serial.println(temperature1);
          #endif
        } else {
          // Increase no update counter if the temperature stayed the same
          nNoUpdatesTemp1++;
        }
      
        // Get humidity from DHT library
        float humidity1 = dht1.getHumidity();
        if (isnan(humidity1)) {
          Serial.println("Failed to read the humidity from DHT");
        } else if (humidity1 != lastHum1 || nNoUpdatesHum1 == FORCE_UPDATE_N_READS) {
          // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
          lastHum1 = humidity1;
          // Reset no updates counter
          nNoUpdatesHum1 = 0;
          send(msgHum1.set(humidity1, 1));
      
          #ifdef MY_DEBUG
          Serial.print("Humidity: ");
          Serial.println(humidity1);
          #endif
        } else {
          // Increase no update counter if the humidity stayed the same
          nNoUpdatesHum1++;
        }
      
       //
       // End the DHT Sensor Loop
       //
      
       //
       // Start the DHT Sensor loop
       //
       // Force reading sensor, so it works also after sleep()
       dht2.readSensor(true);
      
       // Get temperature from DHT library
       float temperature2 = dht2.getTemperature();
       if (isnan(temperature2)) {
         Serial.println("Failed to read the temperature from DHT");
       } else if (temperature2 != lastTemp2 || nNoUpdatesTemp2 == FORCE_UPDATE_N_READS) {
         // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
         lastTemp2 = temperature2;
         if (!metric) {
           temperature2 = dht2.toFahrenheit(temperature2);
         }
         // Reset no updates counter
         nNoUpdatesTemp2 = 0;
         temperature2 += SENSOR_TEMP_OFFSET;
         send(msgTemp2.set(temperature2, 2));
      
         #ifdef MY_DEBUG
         Serial.print("Temperature: ");
         Serial.println(temperature2);
         #endif
       } else {
         // Increase no update counter if the temperature stayed the same
         nNoUpdatesTemp2++;
       }
      
       // Get humidity from DHT library
       float humidity2 = dht2.getHumidity();
       if (isnan(humidity2)) {
         Serial.println("Failed to read the humidity from DHT");
       } else if (humidity2 != lastHum2 || nNoUpdatesHum2 == FORCE_UPDATE_N_READS) {
         // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
         lastHum2 = humidity2;
         // Reset no updates counter
         nNoUpdatesHum2 = 0;
         send(msgHum2.set(humidity2, 2));
      
         #ifdef MY_DEBUG
         Serial.print("Humidity: ");
         Serial.println(humidity2);
         #endif
       } else {
         // Increase no update counter if the humidity stayed the same
         nNoUpdatesHum2++;
       }
         //
         // End the DHT Sensor Loop
         //
      
         //
         // Start Water Flow Loop
         //
         currentTime = millis();
         bool sendTime = currentTime - lastSend > SEND_FREQUENCY;
         if (pcReceived && (SLEEP_MODE || sendTime)) {
           // New flow value has been calculated
           if (!SLEEP_MODE && flow != oldflow) {
             // Check that we dont get unresonable large flow value.
             // could hapen when long wraps or false interrupt triggered
             if (flow<((unsigned long)MAX_FLOW)) {
               send(flowMsg.set(flow, 2));        // Send flow value to gw
             }
      
             //Serial.print("l/min: ");
             //Serial.println(flow);
             oldflow = flow;
           }
      
           // No Pulse count in 2min
           if(currentTime - lastPulse > 20000){
             flow = 0;
           }
      
      
           // Pulse count has changed
           if (pulseCount != oldPulseCount) {
             send(pcMsg.set(pulseCount));                  // Send  volumevalue to gw VAR1
             double volume = ((double)pulseCount/((double)PULSE_FACTOR)*264.172);
             //double volume = ((double)pulseCount/((double)PULSE_FACTOR));
             oldPulseCount = pulseCount;
             Serial.print("Pulse count:");
             Serial.println(pulseCount);
             if (volume != oldvolume) {
               send(volumeMsg.set(volume, 3));               // Send volume value to gw
               //Serial.print("m3: ");
               //Serial.println(volume);
               oldvolume = volume;
             }
           }
           lastSend = currentTime;
         }
         else if (sendTime) {
           // No count received. Try requesting it again
           request(CHILD_ID_FLOW, V_VAR1);
           lastSend=currentTime;
         }
         //
         // End Water Flow Lop
         //
      
        // Sleep for a while to save energy
        sleep(UPDATE_INTERVAL);
      
        //
        // Start Soil Mositure Loop
        //
          int sensorValue1;
      sensorValue1 = analogRead(mositure_sensor_pin1);
          int sensorValue2;
      sensorValue2 = analogRead(mositure_sensor_pin2);
      
        //send back the values
          send(msgSoil1.set(sensorValue1));
          send(msgSoil2.set(sensorValue2));
      
        //
        // End Soil mositure loop
        //
      }
      
      void receive(const MyMessage &message)
       {
          // We only expect one type of message from controller. But we better check anyway.
          if (message.type==V_STATUS) {
              // Change relay state
              digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
              // Store state in eeprom
              saveState(message.sensor, message.getBool());
              // Write some debug info
              Serial.print("Incoming change for sensor:");
              Serial.print(message.sensor);
              Serial.print(", New status: ");
              Serial.println(message.getBool());
          }
       }
      
       void onPulse()
       {
         if (!SLEEP_MODE) {
           unsigned long newBlink = micros();
           unsigned long interval = newBlink-lastBlink;
           lastPulse = millis();
           if (interval < 2080) {       // Sometimes we get interrupt on RISING,  500000 = 0.5sek debounce ( max 120 l/min)  WAS 2080
             return;
           }
      
           flow = ((60000000.0 /interval) / ppl)*.264172;
           //flow = ((60000000.0 /interval) / ppl);
           // Serial.print("interval:");
           // Serial.println(interval);
           lastBlink = newBlink;
            // Serial.println(flow, 4);
         }
         pulseCount++;
      
       }
      
       void incomingMessage(const MyMessage &message) {
         if (message.type==V_VAR1) {
           pulseCount = oldPulseCount = message.getLong();
           Serial.print("Received last pulse count from gw:");
           Serial.println(pulseCount);
           pcReceived = true;
         }
      
       }
      
      

      I am not getting any flow rate data passed into my Vera Dashboard. I want to monitor the flow rate to make sure that the power actuated valve is closed when vera actually states that it is closed (I don't want to over water my plants causing them to stress and die).

      0_1505754010536_Screen Shot 2017-09-18 at 8.28.44 AM.png

      Any help with getting the flow rate to actually display in Vera would be helpful and much appreciated and any way to optimize the code to run quick and/or more efficient is gladly accepted.

      This is my first project and I honestly enjoyed building it. I know some of the components I used were overkill but I didn't care as it was a learning experience and I had fun.

      posted in My Project
      thumper
      thumper
    • RE: Raspberry Pi Gateway and Vera

      I know this topic is old, but I was experiencing the same problem and figured I would respond to it with the fix to the issue. Just in case someone else comes to the forum with the same issue.

      To get the start/include button to work after you upload the files to vera (from the Mysensors Github Repo)

      using putty or terminal SSH into your pi and type

      sudo nano /home/pi/MySensors/examples_linux/mysgw.cpp
      

      when nano opens hit ctrl-w to search for "MY_INCLUSION" and then remove the // marks before #define to enable inclusion mode on your pi gateway.

      #define MY_INCLUSION_MODE_FEATURE
      

      after that reboot and it should start to work. If you need to see what your gateway is doing I suggest enabling debug (Explained from the Pi Gateway installation from this site ... copied and pasted below for quick reference)

      When installed as a service, the output of the gateway will be directed to syslog in /var/log/syslog.
      If you want full debug output from the gateway to be logged to syslog (including serial protocol) you have to edit the following file: /etc/systemd/system/mysgw.service
      Add the -d parameter to the ExecStart line

      [Service]
      ExecStart=/usr/local/bin/mysgw -d
      

      hit control+x to exit and it will ask you if you want to save hit y and then enter.

      Then reload the systemd process and restart the gateway

      sudo systemctl daemon-reload
      sudo systemctl restart mysgw.service
      

      Now the output from the gateway can be monitored by

      tail -f /var/log/syslog
      

      Everything your Pi gateway is doing will be logged in real time in your putty or terminal window from the syslog file. Remove the -d from the /etc/systemd/system/mysgw.service file to remove all the debug info.

      When you enable debug you should be able to see that the gateway is listening for the children nodes. you may have to plug your children into your computer via usb and open arduino IDE and hit command+shift+M to open the serial monitor to see if your child node is working and broadcasting a signal properly.

      posted in Vera
      thumper
      thumper
    • RE: Relay actuator + water meter pulse sensor sketch

      @tbully thank you for the code, can you hardware you are using. What are you using to monitor the flow of your pipes (flow meter or pulse monitor). Thanks in advance and sorry if you already mentioned this elsewhere.

      posted in Development
      thumper
      thumper
    • RE: DIY 1" Blind Tilting Sketch

      @naveen Thanks for the input, I will do a little more research I was thinking of using the Futaba S3305 Standard High-Torque servos (6.0V has 124oz-in torque) figured I go this route to help hide wiring and not run electric into each window.

      posted in My Project
      thumper
      thumper
    • RE: DIY 1" Blind Tilting Sketch

      @lininger Great implementation on controlling your blinds ... I see this this is being powered by the use of a barrel plug, would it be* possible to power using a LiPo battery and a solar panel? The solar panel would be* on the window in the corner and have it trickle charge the LiPo battery (Something like this http://www.adafruit.com/product/390) ... would it be possible to power both the arduino mini and a servo?

      *Edited at 9/20/2014 for grammatical correction.

      posted in My Project
      thumper
      thumper