Navigation

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

    BulldogLowell

    @BulldogLowell

    Contest Winner

    83
    Reputation
    813
    Posts
    5099
    Profile views
    9
    Followers
    1
    Following
    Joined Last Online

    BulldogLowell Follow
    Contest Winner

    Best posts made by BulldogLowell

    • Irrigation Controller (up to 16 valves with Shift Registers)

      I put together an extension of the multi-Relay controller for use as a controller for your irrigation project if you have more zones than available pins on your Arduino.

      This sketch features the following:

      • Allows you to cycle through All zones or individual zone control.
      • Use the (n+1)th device to activate each zone in numeric sequence (zero to n) using
        Variable1 as the "ON" time in minutes in each of the vera devices created.
      • Use the individual zone controller to activate a single zone. This feature uses
        Variable2 as the "ON" time for each individual device/zone.
      • Connect according to pinout in the sketch and uses an 74HC595 (or equiv) Shift Register as to
        allow the MySensors standard radio configuration and still leave available digital pins
      • Compiles to ~12,000 Bytes, so will run on any Arduino
      • Turning on any zone will stop the current process and begin that particular process.
      • Turning off any zone will stop the current process and turn off all zones.
      • Sketch must collect your desired intervals so it takes several minutes to startup.
      • If you change your desired time intervals for your zones, simply restart your arduino
        and it will self update to reflect those changes.

      Example, I am using with 8 relays:

      This will create 9 devices. Zero through 7 are the individual relays. Eight is the Sequencer, so to speak (refer to attachment).

      Once you create this and add it using the gateway, go to each of zero through 7 and edit Variable1 and Variable2 for what time you want to use for the Sequencer or Zone respectively. Then save the settings. Then, restart your arduino; your arduino will extract these settings and save them to an array.

      When you turn on device 8 (aka the Sequencer) the relays will actuate in order from zero to seven, each one staying on for the period entered in the Variable1 field. There is a 5 second delay at the start of a new zone to allow for the valves to hydraulically reset.

      When you turn on any of devices zero through 7, it will run that zone only for the period of time entered in Variable2.

      Selecting any new zone (0-8) will stop the current process and start as per above.

      Hope you have a use for it. If you see any opportunity to improve, or find a bug, let me know.

      Jim
      modified. Attached wrong file, whoops!

      Sprinkler.ino

      posted in My Project
      BulldogLowell
      BulldogLowell
    • DailyTimer library for Arduino

      I recently updated my DailyTimer library for Arduino which provides tools to set daily timers for control of devices such as lamps, appliances, etc. I hope someone else will find this useful. There is also a Particle version.

      I developed this primarily for automatically (device level) firing time-based events on certain days of the week (configurable).

      Any contribution is welcome.

      Something about the library:

      A library that will allow you to control daily events.

      Provides tools to set daily timers for control of devices such as lamps, appliances, etc. Developed primarilary for houshold presence simulation.

      Allows for setting ON and OFF times, days of the week (i.e. weekends, weekdays, Fridays) and the use of random on/off times.

      Timers may bridge midnight, simply enter times accordingly.

      Can automatically set correct timer state on powerup or schedule changes.

      Random start and/or end times.

      Randomly set days of week.

      Select custom days of the week.

      Set a timed event with just the start time as a trigger.

      you can return the active days (e.g. in the case of setting random days).

      Dynamically set your start or end time (i.e. using some type of celestial function or web or server call to determine Sunrise or Sunset times)

      posted in Development
      BulldogLowell
      BulldogLowell
    • Vera Helper with Arduino

      I've been interested in augmenting my network with Ethernet and WiFi devices for some time. So, just messing around with an Uno and an Ethernet Shield, I built a device that can (without the RF integration)

      • Control any Vera device through HTTP Commands

      • Can be controlled by VERA luup or any wget style command

      • be a sensor on my network

      • be an independant/agnostic layer with equal footing with My Sensors

      • be dependable

      I'm not all the way there yet, but i built a sensor that can talk to my Vera, controlling vera devices and can be controlled by vera.

      This is the web page it creates:

      Screen Shot 2014-12-06 at 3.46.02 PM.png

      this sketch allow you to turn on/off a relay via a webpage or Vera, and control a vera device.

      take a look:

      ArduinoEthernetNode – 01:29
      — Jim B

      #include <Wire.h>
      #include <EEPROM.h>
      #include <SPI.h>         
      #include <Ethernet.h>
      #include <EthernetUdp.h>
      #include <utility/w5100.h>
      #include <Time.h>
      #include <Timezone.h>
      #include <LiquidCrystal_I2C.h>
      #include "DHT.h"
      
      //#define DEBUG_ON
      #define LED_PIN 8
      #define DHT_SENSOR_PIN 7
      
      #ifdef DEBUG_ON
      #define DEBUG_PRINT(x)   Serial.print(x)
      #define DEBUG_PRINTLN(x) Serial.println(x)
      #define SERIAL_START(x)  Serial.begin(x)
      #else
      #define DEBUG_PRINT(x)
      #define DEBUG_PRINTLN(x)
      #define SERIAL_START(x)
      #endif
      //
      boolean lightOn;
      DHT dht;
      //
      LiquidCrystal_I2C lcd(0x27, 16, 2);
      uint8_t clock[8] = {0x0,0xe,0x15,0x17,0x11,0xe,0x0}; // I'm-fetching-time-indicator for LCD display
      //
      EthernetUDP Udp;
      EthernetServer server(80);
      uint8_t mac[] = { 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE };
      unsigned int localPort = 8888;
      IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov NTP server  // IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov NTP server  // IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov NTP server
      const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
      byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 
      byte socketStat[MAX_SOCK_NUM];
      //
      char myString[100];
      byte locator = 0;
      EthernetClient client;
      const byte myserver[] = { 192,168,1,59 };
      //
      const char *dayOfWeek[] = {"Null","Sunday ","Monday ", "Tuesday ", "Wednesday ", "Thursday ", "Friday ", "Saturday "};
      const char *monthString[] = {"NULL", "January", "February", "March", "April", "May", "June", "July", "August","September", "October", "November", "December"};
      // 
      TimeChangeRule usEDT = {"EDT", Second, Sun, Mar, 2, -240};  //Eastern Daylight Time = UTC - 4 hours
      TimeChangeRule usEST = {"EST", First, Sun, Nov, 2, -300};   //Eastern Standard Time = UTC - 5 hours
      Timezone usET(usEDT, usEST);
      TimeChangeRule *tcr;
      boolean forceClockUpdate = true;
      //
      void setup() 
      {
        SERIAL_START(9600);
        lightOn = EEPROM.read(0);
        pinMode(LED_PIN, OUTPUT);
        dht.setup(DHT_SENSOR_PIN);
        digitalWrite(LED_PIN, lightOn);
        //
        DEBUG_PRINTLN(F("configuring ethernet"));
        if (Ethernet.begin(mac) == 0) // start Ethernet and UDP
        {
          DEBUG_PRINTLN(F("Failed to configure Ethernet using DHCP")); 
          while(true){}
        }
        server.begin();
        Udp.begin(localPort);
        //
        lcd.init();
        lcd.clear();
        lightOn? lcd.backlight() : lcd.noBacklight();
        lcd.createChar(0, clock);
      }
      //
      void loop()
      {
        updateLCD();
        getNTPtime();
        webControl();
      }
      //
      void updateLCD()
      {
        static int lastSecond; 
        time_t rightNow = now();
        if (second(rightNow) != lastSecond)
        {
          lcd.setCursor(0,0);
          lcd.print(F("Time:"));
          DEBUG_PRINT(F("Time:"));
          lcd.print(hourFormat12(rightNow) < 10 ? F(" ") : F(""));
          DEBUG_PRINT(hourFormat12(rightNow) < 10 ? F(" ") : F(""));
          lcd.print(hourFormat12(rightNow));
          DEBUG_PRINT(hourFormat12(rightNow));
          lcd.print(minute(rightNow) < 10 ? F(":0") : F(":"));
          DEBUG_PRINT(minute(rightNow) < 10 ? F(":0") : F(":"));
          lcd.print(minute(rightNow));
          DEBUG_PRINT(minute(rightNow));
          lcd.print(second(rightNow) < 10 ? F(":0") : F(":"));
          DEBUG_PRINT(second(rightNow) < 10 ? F(":0") : F(":"));
          lcd.print(second(rightNow));
          DEBUG_PRINT(second(rightNow));
          lcd.print(isAM() ? "am" : "pm");
          DEBUG_PRINT(isAM() ? " am " : " pm ");
          lcd.setCursor(0,1);
          lcd.print(dayOfWeek[weekday(rightNow)]);
          DEBUG_PRINTLN(dayOfWeek[weekday(rightNow)]);
          lcd.print(F("      "));
          lcd.setCursor(11,1);
          lcd.print(month(rightNow) < 10 ? F(" ") : F(""));
          lcd.print(month(rightNow));
          lcd.print(day(rightNow) < 10 ? F("/0") : F("/"));
          lcd.print(day(rightNow));
        }
        lastSecond = second(rightNow);
      }
      //unsigned long
      void sendNTPpacket(IPAddress& address) // Send an NTP request to the time server at the given address 
      {
        memset(packetBuffer, 0, NTP_PACKET_SIZE); 
        packetBuffer[0] = 0b11100011;   // LI, Version, Mode
        packetBuffer[1] = 0;            // Stratum, or type of clock
        packetBuffer[2] = 6;            // Polling Interval
        packetBuffer[3] = 0xEC;         // Peer Clock Precision
        packetBuffer[12]  = 49; 
        packetBuffer[13]  = 0x4E;
        packetBuffer[14]  = 49;
        packetBuffer[15]  = 52;           
        Udp.beginPacket(address, 123); //NTP requests are to port 123
        Udp.write(packetBuffer,NTP_PACKET_SIZE);
        Udp.endPacket(); 
      }
      //
      void receiveTime(unsigned long newTime)
      {
        DEBUG_PRINT(F("Time value received: "));
        int lastSecond = second();
        int lastMinute = minute();
        int lastHour = hour();
        setTime(newTime);
        if ((second() != lastSecond) || (minute() != lastMinute) || (hour() != lastHour))
        {
          DEBUG_PRINTLN(F("Clock updated...."));
          DEBUG_PRINT(F("Sensor's time currently set to:"));
          DEBUG_PRINT(hourFormat12() < 10? F(" 0") : F(" "));
          DEBUG_PRINT(hourFormat12());
          DEBUG_PRINT(minute() < 10? F(":0") : F(":"));
          DEBUG_PRINT(minute());
          DEBUG_PRINTLN(isAM()? F("am") : F("pm"));
          DEBUG_PRINT(month());
          DEBUG_PRINT(F("/"));
          DEBUG_PRINT(day());
          DEBUG_PRINT(F("/"));
          DEBUG_PRINTLN(year());
          DEBUG_PRINTLN(dayOfWeek[weekday()]);
        }
        lcd.setCursor(15,0);
        lcd.print(F(" "));
      }
      //
      void getNTPtime()
      {
        static unsigned long lastUpdateTime;
        const unsigned long interval = 60000UL;
        if ((millis() - lastUpdateTime >= interval) || forceClockUpdate)
        {
          lcd.setCursor(15,0);
          lcd.write(0);
          sendNTPpacket(timeServer); // send an NTP packet to a time server
          delay(1000);  
          if (Udp.parsePacket()) 
          {  
            Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
            unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
            unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
            unsigned long secsSince1900 = highWord << 16 | lowWord;  
            DEBUG_PRINT(F("Seconds since Jan 1 1900 = "));
            DEBUG_PRINTLN(secsSince1900);               
            DEBUG_PRINT(F("Unix time = "));
            time_t utcEpoch = secsSince1900 - 2208988800UL;//seventyYears = 2208988800UL
            DEBUG_PRINTLN(utcEpoch);                               
            receiveTime(usET.toLocal(utcEpoch, &tcr) + 2);  //about 2 seconds to call for time
          }
          if (!forceClockUpdate)
          {
            lastUpdateTime += interval;
          }
          forceClockUpdate = false;
        }
      }
      //
      void webControl()
      {
        EthernetClient client = server.available();
        if (client) 
        {
          while (client.connected()) 
          {
            if (client.available()) 
            {
              char c = client.read();
              if (locator < 100)
              {
                myString[locator] = c;
                locator++;
                myString[locator] = '\0'; 
              }
              if (c == '\n') //if HTTP request has ended
              {
                DEBUG_PRINTLN(F("MyString ="));
                DEBUG_PRINTLN(myString);
                client.println(F("HTTP/1.1 200 OK")); //new page
                client.println(F("Content-Type: text/html"));
                client.println();
                client.println(F("<HTML>"));
                client.println(F("<HEAD>"));
                client.println(F("<meta name='apple-mobile-web-app-capable' content='yes' />"));
                client.println(F("<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />"));
                client.println(F("<link rel='stylesheet' type='text/css' href='http://homeautocss.net84.net/a.css' />"));
                client.println(F("<TITLE>Jim's Home Automation</TITLE>"));
                client.println(F("</HEAD>"));
                client.println(F("<BODY>"));
                client.println(F("<H1>NTP Clock/Light</H1>"));
                client.println(F("<hr />"));
                client.println(F("<br />"));
                client.println(F("<a href=\"/?ledOn\"\">Light On</a>"));
                client.println(F("<a href=\"/?ledOff\"\">Light Off</a><br />"));  
                client.println(F("<br />"));
                client.println(F("<br />"));
                client.println(F("<a href=\"/?phoneyOn\"\">PhoneyTV On</a>"));
                client.println(F("<a href=\"/?phoneyOff\"\">PhoneyTV Off</a><br />"));  
                client.println(F("<br />"));
                client.println(F("<br />"));
                client.println(F("<a href=\"/?syncClock\"\">Force Synchronize Clock</a>"));
                client.println(F("<br />"));
                client.println(F("<br />"));
                client.println(F("<hr />"));
                client.println(F("<H2>Current Conditions</H2>"));
                client.println(F("<H3>"));
                client.println(dayOfWeek[weekday()]);
                client.println(F(","));
                client.println(monthString[month()]);
                client.println(F(" "));
                client.println(day());
                client.println(F(","));
                client.println(year());
                client.println(F("<br />"));
                client.println(F("<br />"));
                client.println(F("<font color=\"blue\">Temperature</font>"));
                client.println(F("<font color=\"red\">"));
                client.println((int)floor(dht.toFahrenheit(dht.getTemperature()) + 0.5), 1);
                client.println(F("</font>"));
                client.println(F("<font color=\"blue\">F</font>"));
                client.println(F("<br />"));
                client.println(F("<H3><font color=\"blue\">Humidity</font>"));
                client.println(F("<font color=\"red\">"));
                client.println((int)floor(dht.getHumidity() + 0.5), 1);
                client.println(F("</font>"));
                client.println(F("<font color=\"blue\">%</font>"));
                client.println(F("<br />"));
                client.println(F("<div style=\"background-color:grey;"));
                client.print(F(" color:black; margin:20px; padding:20px;\">"));
                client.println(F("<h3>Jim Brower</h3>"));
                client.println(F("<p>"));
                client.println("&#169");
                client.println(F(" 2014"));
                client.println(F("</p>"));
                client.println(F("</div>"));
                client.println(F("</BODY>"));
                client.println(F("</HTML>"));
                delay(1);
                client.stop();
                if(strstr(myString, "?ledOn")) // control arduino pin and LCD backlight //checks for 'on'
                {
                  lightOn = true;
                  EEPROM.write(0,0xFF);
                  digitalWrite(LED_PIN, HIGH);
                  lcd.backlight();
                  DEBUG_PRINTLN(F("Led On"));
                }
                if(strstr(myString, "?ledOff")) // compliment to above
                {
                  lightOn = false;
                  EEPROM.write(0,0x00);
                  digitalWrite(LED_PIN, LOW);
                  lcd.noBacklight();
                  DEBUG_PRINTLN(F("Led Off"));
                }
                else if (strstr(myString, "?syncClock"))
                {
                  forceClockUpdate = true;
                  DEBUG_PRINTLN(F("Sync Set"));
                }
                else if (strstr(myString, "?phoneyOn"))
                {
                  phoneyTV(true);
                  DEBUG_PRINTLN(F("PhoneyTV On"));
                }
                else if (strstr(myString, "?phoneyOff"))
                {
                  phoneyTV(false);
                  DEBUG_PRINTLN(F("PhoneyTV Off"));
                }
                myString[0] = '\0'; //clearing string for next read
                locator = 0;
              }
            }
          }
        }
      }
      //
      void phoneyTV(boolean status)
      {
        ShowSockStatus();
        if (client.connect(myserver, 3480)) //starts client connection, checks for connection
        {  
          DEBUG_PRINTLN(F("connected"));
          client.print(F("GET /data_request?"));
          client.print(F("id=action&output_format=xml"));
          client.print(F("&DeviceNum=88"));
          client.print(F("&serviceId=urn:upnp-org:"));
          client.print(F("serviceId:SwitchPower1"));
          client.print(F("&action=SetTarget"));
          client.print(F("&newTargetValue="));
          client.print(status ? F("1") : F("0"));
          client.println(F(" HTTP/1.1"));
          client.println(F("Connection: close"));  //close 1.1 persistent connection  
          client.println(); //end of get request
          delay(1);
          client.stop();
        }
      }
      
      void ShowSockStatus()
      {
        for (int i = 0; i < MAX_SOCK_NUM; i++) {
          DEBUG_PRINT(F("Socket#"));
          DEBUG_PRINT(i);
          uint8_t s = W5100.readSnSR(i);
          socketStat[i] = s;
          DEBUG_PRINT(F(":0x"));
          #ifdef DEBUG_ON
          Serial.print(s,16);
          #endif
          DEBUG_PRINT(F(" "));
          DEBUG_PRINT(W5100.readSnPORT(i));
          DEBUG_PRINT(F(" D:"));
          uint8_t dip[4];
          W5100.readSnDIPR(i, dip);
          for (int j=0; j<4; j++) {
            Serial.print(dip[j],10);
            if (j<3) Serial.print(".");
          }
          DEBUG_PRINT(F("("));
          DEBUG_PRINT(W5100.readSnDPORT(i));
          DEBUG_PRINT(F(")"));
        }
      }
      posted in My Project
      BulldogLowell
      BulldogLowell
    • RE: Best dimmable countertop lights?

      @mfalkvidd

      I used these on Amazon. By and large the reviews are spot on... but I installed inside a molding strip that I routed out like this and mounted underneath, to make it have a finished look. You can see the molding in the photo below, just inboard of the doors. I used a clear adhesive to augment the not-great adhesive backing that the strips come with, something like a bead of hot glue down each side of the milled out molding.

      0_1458770884571_FullSizeRender.jpg
      and the finished product like this... though the color is horribly off on my iPhone photo. It looks much warmer to the eye in real life.
      0_1458771159855_FullSizeRender-1.jpg
      Most importantly, they allow for a lot of light and a happy wife!

      Photo from the other side shows the LED's above as well, though not completed for the left hand island:
      0_1458772094442_FullSizeRender-2.jpg
      Again, the Colors are all wrong!!

      posted in Hardware
      BulldogLowell
      BulldogLowell
    • Web App for Simple Control of my Home Automation kludge

      Like a lot of forum members, I have a lot of automation in my house. It sometimes creates issues for guests who don't have a familiarity with home automation and my wife!

      I don't want to give total control of the house to guests, but I wanted them to have a tool that will allow them to control my hybrid system (Vera and a bunch of Particle Photon controlled devices and other gadgets) without having to download an app, which would allow them total control of my house and I have to enter my security keys.

      So, I wrote a web app which is hosted on my mac mini server and it is accessible to anyone I let onto my private LAN, only while they are on the LAN.

      It took me a while to do this, having never done anything in HTML/CSS/JavaScript/PHP, but it turns out that it is all pretty easy to do. The most difficult part was getting the status data from Vera, because of its particular preferences of handling cross-domain Ajax calls. I eventually created a PHP proxy and well, it all came together after that.

      when the website loads, it makess an Ajax call to my Vera and updates the state of every device. Plus, it also gets the state of each of the Particle Photon devices I can control/monitor. I also go get all of the local weather conditions, as you can see below.

      If anyone is interested in working on something similar or building off of this project, I'm happy to share my code. I'm certain that it would offer a lot of utility to the MySensors crowd, especially where they are using Vera's ugly UI.

      Here are a few screen shots off my web browser and iOS device:

      different devices including control of my thermostats (they can only control within a range) and dimmer in the outdoor kitchen:

      0_1472135355783_Screen Shot 2016-08-25 at 10.15.27.png

      Another shot including the drop down "Zoom to Room" menu:

      0_1472135410798_Screen Shot 2016-08-25 at 10.16.27.png

      Local Conditions:

      0_1472135865680_Screen Shot 2016-08-25 at 10.36.59.png

      posted in My Project
      BulldogLowell
      BulldogLowell
    • RE: What did you build today (Pictures) ?

      @dbemowsk said in What did you build today (Pictures) ?:

      Seeing the falling stars at the end of the Adafruit test code made me think of rain or snow falling. Something like that might go outside the limits of the pro minis memory, but hey, never hurts to try.

      Hey Nice Work!

      I see you are using I2C, vs SPI... that may be why your display is so much slower than the demo in the Adafruit video.

      Can't wait to see the final board!

      posted in General Discussion
      BulldogLowell
      BulldogLowell
    • RE: Waterproof Temp Sensor with dht humidty/temp sensor

      @cleight

      try this...

      start here:

      boolean metric = true; 
      

      with

      boolean metric = false;
      

      and comment out this line:

      metric = gw.getConfig().isMetric;
      posted in My Project
      BulldogLowell
      BulldogLowell
    • RE: Web App for Simple Control of my Home Automation kludge

      @TheoL

      So, my little app connects to Particle devices using their RESTful API, Ajax looks like this, which control my PhoneyTV (Particle version here) and a LED dimmer:

      example of a getter:

      function getParticleData(){
      	var requestURL = "https://api.spark.io/v1/devices/" + deviceID + "/" + getFunc + "/?access_token=" + accessToken;
      	$.getJSON(requestURL, function(json) {
      		document.getElementById("range").innerHTML = json.result + "%";
      		document.getElementById("myRange").value = json.result;
      	});
      	var myURL = "https://api.spark.io/v1/devices/" + phoneyID + "/" + phoneyVariable + "/?access_token=" + accessToken;
      	$.getJSON(myURL, function(data) {
      	var state = parseInt(data.result);
      	console.log("phoneyTV state =" + state);
      	document.getElementById("phoneyTV").checked = ((state == 1)? true : false);
      	});
      }
      

      and a setter:

      function sendDimmerValue() {
          var newValue = document.getElementById("range").innerHTML;
          var request = new XMLHttpRequest();
          var data = 'params=' + newValue + '&access_token=' + accessToken;
          var url = 'https://api.particle.io/v1/devices/' + dev_id + '/setDimLevel/';
          request.open('POST', url, true);
          request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
          request.send(data);
      }
      

      no extra url encoding needed here but for Vera you must, for example:

      function sendThermostatValue(tStat) {
      	console.log("pressed");
          var newValue = document.getElementById(tStat.reading).innerHTML;
          var request = new XMLHttpRequest();
          var url = 'http://10.0.1.15/proxy.php?url=http%3A%2F%2F10.0.1.25%3A3480%2Fdata_request%3Fid%3Daction%26output_format%3Dxml%26DeviceNum%3D' + tStat.deviceNum + '%26serviceId%3Durn%3Aupnp-org%3AserviceId%3ATemperatureSetpoint1_Cool%26action%3DSetCurrentSetpoint%26NewCurrentSetpoint%3D' + newValue;
      	console.log(url);
          request.open('GET', url);
          request.send();
      }
      

      My code doesn't dynamically create devices (yet) rather, it is static HTML. My next improvement would be to build device classes, poll Vera for relevant device types and build the UI dynamically.

      @sundberg84,

      I started with a simple web page with a single value... once I learned how to make an AJAX call to Vera, it was easy to call any variable I wanted, especially because of Vera's native JSON output.

      If Domoticz API supports JSON, well it will be a breeze for you.

      Since there are a few people interested I can post something. If we get a Vera person interested, the Javascript I wrote will give them a big step in the right direction.

      posted in My Project
      BulldogLowell
      BulldogLowell
    • RE: IR Switch for Luminara Candle Automation (repost with video, photos and final sketch)

      Wow this is an old topic!

      But... I was working on a project and thought that anyone who was looking for a NeoPixel candle example that isn't blocking, well this would be the place. It flickers and flutters like a real candle. The only thing is that the flame isn't illuminated like these nice Luminaras, but I'm too cheap to buy them!

      Keep in mind that my example here uses GRB LEDs, but you merely need to reorder the variables in order to get this working for RGB. Plus the Time Library is not Arduino, so you will have to play with that too for a good randomSeed().

      It looks pretty realistic with even a single neoPixel in a sheet of A4 paper rolled into a cylinder. I'll post a video when I can.

      Have fun with it:

      #include "neopixel.h"
      
      enum CandleStates{
        BURN_CANDLE,
        FLICKER_CANDLE,
        FLUTTER_CANDLE,
        MODES_MAX_CANDLE
      };
      
      enum PixelSelect{
        EVERY_PIXEL,
        SINGLE_PIXEL,
      };
      
      class Candle : public Adafruit_NeoPixel
      {
        public:
          Candle(uint16_t count, uint8_t pin, uint8_t type);
          Candle(uint16_t count, uint8_t pin, uint8_t type, PixelSelect pixel, uint32_t pixNum = 0);
          ~Candle(){};
          void update();
      
        private:
          bool fire(uint8_t greenDropValue, uint32_t cycleTime);
      
          PixelSelect _pixelMode = EVERY_PIXEL;
          uint32_t _pixNum = 0;
          CandleStates _mode;
          uint32_t _lastModeChange;
          uint32_t _modeDuration;
      
          uint8_t _redPx = 255;
          uint8_t _bluePx = 10; //10 for 5v, 15 for 3.3v
          uint8_t _grnHigh = 100; //110-120 for 5v, 135 for 3.3v
          uint8_t _grnPx = 100;
      
          uint32_t _lastBurnUpdate = 0;
          int _direction = 1;
      };
      
      Candle::Candle(uint16_t count, uint8_t pin, uint8_t type) : Adafruit_NeoPixel(count, pin, type)
      {
        randomSeed(Time.now() + micros());
        _mode = BURN_CANDLE;
      }
      
      Candle::Candle(uint16_t count, uint8_t pin, uint8_t type, PixelSelect pixel, uint32_t pixNum) : Adafruit_NeoPixel(count, pin, type)
      {
        _pixelMode = pixel;
        _pixNum = pixNum;
      }
      
      void Candle::update()
      {
        if(millis() - _lastModeChange > _modeDuration)
        {
          _mode = static_cast<CandleStates>(random(MODES_MAX_CANDLE));
          _modeDuration = random(1000, 8000);
          _lastModeChange = millis();
          //Serial.printlnf("New state: %d\tTime: %d", static_cast<int>(_mode), _modeDuration);
        }
        switch(_mode)
        {
          case BURN_CANDLE:
            this->fire(10, 120);
            break;
          case FLICKER_CANDLE:
            this->fire(15, 120);
            break;
          case FLUTTER_CANDLE:
            this->fire(30, 120);
            break;
        };
      }
      
      bool Candle::fire(uint8_t greenDropValue, uint32_t cycleTime)
      {
        int currentMillis = millis();
        if(currentMillis - _lastBurnUpdate > (cycleTime / greenDropValue / 2))
        {
          _grnPx = constrain(_grnPx += _direction, _grnHigh - greenDropValue, _grnHigh);
          if(_grnPx == _grnHigh - greenDropValue or _grnPx == _grnHigh)
          {
            _direction *= -1;
          }
          switch (_pixelMode)
          {
            case EVERY_PIXEL:
              for(int i = 0; i < this->numPixels(); i++)
              {
                this->setPixelColor(i, _grnPx, _redPx, _bluePx);
              }
              break;
            case SINGLE_PIXEL:
              this->setPixelColor(_pixNum, _grnPx, _redPx, _bluePx);
              break;
          }
          this->show();
          _lastBurnUpdate = currentMillis;
        }
      }
      
      #define PIXEL_COUNT 2
      #define PIXEL_PIN D2
      #define PIXEL_TYPE WS2812B    // I'M USING GRB WS2821B's here
      
      Candle candle = Candle(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE, SINGLE_PIXEL);
      
      void setup(void)
      {
        Serial.begin(115200);
        pinMode(13, OUTPUT);
        candle.begin();
        candle.show();
        Serial.println("Started program");
      }
      
      void loop(void)
      {
        candle.update();
        static uint32_t lastFlashMillis = 0;
        if(millis() - lastFlashMillis > 250)
        {
          digitalWrite(13, !digitalRead(13));
          lastFlashMillis = millis();
        }
      }
      
      posted in My Project
      BulldogLowell
      BulldogLowell
    • RE: Getting numbers from Vera to a sensor

      @axillent

      Again, thanks for the help.

      I attached some photos of the display if anyone is interested. The sketch has not been simplified test, but it works so if you are at all interested, you have a good place to start:

      // Humidity and Temperature Sensor with LCD Display
      // Retrieves Temperature, Humidity and today's Hi/Low from Vera and displays it on an LCD alongside with Room Temperature and Humidity.
      //Updates Vera with Temp and Humidity just like any other sensor
      #include <Sleep_n0m1.h>
      #include <SPI.h>
      #include <EEPROM.h>  
      #include <RF24.h>
      #include <Sensor.h>  
      #include <DHT.h> 
      #include <Wire.h> 
      #include <LiquidCrystal_I2C.h>
      //
      LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x20 for a 16 chars and 2 line display
      //
      #define CHILD_ID_HUM 0
      #define CHILD_ID_TEMP 1
      #define HUMIDITY_SENSOR_DIGITAL_PIN 4
      unsigned long SLEEP_TIME = 5; // Sleep time between reads (in seconds)
      //
      Sensor gw;
      DHT dht;
      Sleep sleep;
      float lastTemp;
      float lastHum;
      float temperature;
      float humidity;
      float temp;
      boolean metric = false;
      int OutdoorHumidity;
      int OutdoorTemp;
      int TodayLow;
      int TodayHigh;
      int counter = 60;
      //
      void setup()  
      { 
        Serial.begin(9600);
        gw.begin();
        dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 
        gw.sendSketchInfo("Humidity", "1.0");
        gw.sendSensorPresentation(CHILD_ID_HUM, S_HUM); 
        gw.sendSensorPresentation(CHILD_ID_TEMP, S_TEMP);
        gw.getStatus(CHILD_ID_HUM, V_VAR1);
        gw.getStatus(CHILD_ID_TEMP,V_VAR1);//current exterior temperature
        gw.getStatus(CHILD_ID_TEMP,V_VAR2);//today's high temperature
        gw.getStatus(CHILD_ID_TEMP,V_VAR3);//today's low temperature
        //
        lcd.init(); // initialize the lcd 
        // Print a message to the LCD.
        lcd.backlight();
        lcd.setCursor(0,0);
        lcd.print("    Welcome!");
        lcd.setCursor(0,1);
        lcd.print("      Home");
        delay(2000);
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("    Wireless");
        lcd.setCursor(0,1);
        lcd.print("  WeatherWatch");
        delay(2000);
      }
      //
      void loop()      
      {  
        delay(dht.getMinimumSamplingPeriod());
        if (counter == 60){
          gw.getStatus(CHILD_ID_HUM, V_VAR1);
          HumStatus(gw.getMessage());
          gw.getStatus(CHILD_ID_TEMP, V_VAR1);
          TempStatus(gw.getMessage());
          gw.getStatus(CHILD_ID_TEMP, V_VAR2);
          LowStatus(gw.getMessage());
          gw.getStatus(CHILD_ID_TEMP, V_VAR3);
          HighStatus(gw.getMessage());
          counter = 0;
        }
        temperature = dht.getTemperature();
        temp = dht.toFahrenheit(temperature);
        if (isnan(temperature)) {
            Serial.println("Failed reading temperature from DHT");
        } else if (temperature != lastTemp) {
          lastTemp = temperature;
           if (!metric) {
            temperature = dht.toFahrenheit(temperature);
          }
          gw.sendVariable(CHILD_ID_TEMP, V_TEMP, temperature, 1);
            Serial.print("T: ");
            Serial.println(temperature);
        }
        humidity = dht.getHumidity();
        if (isnan(humidity)) {
            Serial.println("Failed reading humidity from DHT");
        } else if (humidity != lastHum) {
             lastHum = humidity;
            gw.sendVariable(CHILD_ID_HUM, V_HUM, humidity, 1);
            Serial.print("H: ");
            Serial.println(humidity);
        }
        // Power down the radio.  Note that the radio will get powered back up
        // on the next write() call.
        delay(1000); //delay to allow serial to fully print before sleep
        gw.powerDown();
        sleep.pwrDownMode(); //set sleep mode
        sleep.sleepDelay(SLEEP_TIME * 1000); //sleep for: sleepTime
        updateOutsideTemp();
        updateOutsideHumid();
        delay(3000);
        updateLow();
        updateHigh();
        delay(3000);
        updateTemp();
        updateHumid();
        counter = (counter + 1);
      }
      void updateTemp(){
        lcd.setCursor(0,0);
        lcd.print("Temperature: ");
        lcd.print(round(temp));
        lcd.print("F ");
      }
      void updateLow(){
        lcd.setCursor(0,0);
        lcd.print("Today's Low: ");
        lcd.print(round(TodayLow));
        lcd.print("F ");
      }
      void updateHigh(){
        lcd.setCursor(0,1);
        lcd.print("       High: ");
        lcd.print(round(TodayHigh));
        lcd.print("F ");
      }
      void updateHumid(){
        lcd.setCursor(0,1);
        lcd.print("Humidity:    ");
        lcd.print(round(humidity));
        lcd.print("% ");
      }
      void updateOutsideTemp(){
        lcd.setCursor(0,0);
        lcd.print("Outside Temp:");
        lcd.print(OutdoorTemp);
        lcd.print("F ");
      }
      void updateOutsideHumid(){
        //getStatus(CHILD_ID_HUM, V_VAR1);
        lcd.setCursor(0,1);
        lcd.print("Humidity:    ");
        lcd.print(OutdoorHumidity);
        lcd.print("% ");
      }
      void HumStatus(message_s message){
        if (message.header.type==V_VAR1) {
           OutdoorHumidity = atoi(message.data);
         }
      }
      void TempStatus(message_s message){
        if (message.header.type==V_VAR1) {
           OutdoorTemp = atoi(message.data);
         }
      }
      void LowStatus(message_s message){
        if (message.header.type==V_VAR2) {
           TodayLow = atoi(message.data);
         }
      }
      void HighStatus(message_s message){
        if (message.header.type==V_VAR3) {
           TodayHigh = atoi(message.data);
         }
      }
      

      Have fun with it and let me know if you have any ideas to improve or take it further!

      photo.JPG
      photo2.JPG
      photo3.JPG

      posted in Hardware
      BulldogLowell
      BulldogLowell

    Latest posts made by BulldogLowell

    • RE: Battery percentage on door contact sensor erratic (sent on interrupt)

      As the analog pins share a single A2D, rapid use of it can cause the previous read to impact the next. A common workaround in this situation is to read twice on each input, ignoring the first.

      try that:

      // read analog pin
        (void) analogRead(BATTERY_SENSE_PIN);
        int sensorValue = analogRead(BATTERY_SENSE_PIN);
        // calculate battery voltage
        float vBat  = static_cast<float>(sensorValue * (V_MAX/1023));
      
      posted in Development
      BulldogLowell
      BulldogLowell
    • RE: What did you build today (Pictures) ?

      @dbemowsk said in What did you build today (Pictures) ?:

      Seeing the falling stars at the end of the Adafruit test code made me think of rain or snow falling. Something like that might go outside the limits of the pro minis memory, but hey, never hurts to try.

      Hey Nice Work!

      I see you are using I2C, vs SPI... that may be why your display is so much slower than the demo in the Adafruit video.

      Can't wait to see the final board!

      posted in General Discussion
      BulldogLowell
      BulldogLowell
    • RE: Using object from another file

      @mfalkvidd said in Using object from another file:

      @BulldogLowell I was hoping to avoid including ArduinoLog in all .h files, but there seems to be no way around that.

      what's the problem with adding the #include directive? It is a dependency by definition....

      posted in Development
      BulldogLowell
      BulldogLowell
    • RE: Using object from another file

      Where is Log declared?

      it is a global and defined in the CPP file for the Logging class:

      Logging Log = Logging();
      

      so, if it is Global... why the heck can't it be accessed in the Configuration class? Well each set of files is a different translation unit...

      Have you tried adding

      #include <ArduinoLog.h>
      

      in your

      "Configuration.h"
      

      class?

      posted in Development
      BulldogLowell
      BulldogLowell
    • RE: No luck with ethernet Gateway

      @gohan said in No luck with ethernet Gateway:

      Try latest mysensors development library, then if problem persists try a different UNO or downgrade boards definitions to 1.6.11 or 1.6.13 and see if it still has problems. Did you try to remove code for each of the sensors at a time in order to figure out if it's a specific sensor?

      take heed to this advice... did you modify the boards definition in your Arduino IDE?

      posted in Troubleshooting
      BulldogLowell
      BulldogLowell
    • RE: Why text-based communication???

      @4Project said in Why text-based communication???:

      Does that mean all the communication is always destined/sourced to/from the controller?

      I think that is explained in the network topology.

      If you want to send a message node-to-node, you could try to manage it through your gateway or a repeater.

      posted in Development
      BulldogLowell
      BulldogLowell
    • 3G Serial Bridge for Vera

      I wanted to share a project that I did for my Vera using the Particle Electron and a Nano... I think that the MySensors skill set transfers to Particle, so I'm hopeful some of you brave souls may try to pull this off!

      It is all documented here on my Git Repo. Ideas, suggestions and contributions welcome!

      0_1505768172165_VeraMainPanel.png

      0_1505768093992_VeraControlPanel.png

      0_1505768135162_ThreeGeeRocks.png

      I have a vacation home that I use Vera to control events. I, like a lot of other folks, have been a victim of:

      1. Power is out and I don't know.... I only find out when I try to log on 😠
      2. Vera is stalled, likewise, I only find out when I try to log on
      3. I've lost my connection the the internet. Again, how do I know that this happened? 😕

      I've recently developed a device (hardware & . Software) that allows me to detect all of these very difficult-to-detect events, for example:

      My Device lost Internet connectivity
      In this case, the device will detect the loss of internet and send a message via 3G network, circumventing the "How do I send a message if my Internet is down" paradox.

      My device (or home) has lost power
      In this case, the device will repeatedly remind me at a fixed interval until power is restored. The device has a LiPo battery which can send messages for days, even if there is no power.

      My Vera 3G gateway is not communicating with Vera
      If this happens you can create a notification which Vera can send

      My Vera is inactive, stalled or otherwise not properly functioning.
      When this happens, the 3G gateway can automatically power-cycle my Vera after some user-defined period of inactivity. (coming soon)

      The device can send SMS messages (during events as above or ad hoc by creating your own events using scenes or PLEG) or similarly use a service like Pushover to send a notification to any mobile (or desktop). I'm using Pushover direct to my Mobile device.

      I've developed a plugin that enables a new device to be set up in minutes.

      With such a configuration, I am using a 3G SIM/plan that costs $3.00 per month... about the cost of a cup of coffee. But you can use any SIM/plan you like.

      While I built mine on my own, because of the low operating cost, I realized that others may have an interest in building such a device. I was considering developing a PCB and providing a list of all the components necessary to build a device. I may even design a 3D printable case if there is enough interest.

      So, I'm looking to see if there is any interest and based on that, provide (sell) a kit that anyone can use. So, if you have an interest please let me know by responding to this post. If you are great at PCB dev, then even better, I can use your help!

      It is cool... and just what many of forum participants have been asking for.

      posted in My Project
      BulldogLowell
      BulldogLowell
    • RE: SoCal help completing a MySensor system

      @ensbusiness said in SoCal help completing a MySensor system:

      Then I try adding a wireless sensor using the libraries from MySensor for the Atmega328P Pro-mini's and nRF2401's I already decided to use even before I found MySensors. The problem is that I can't seem to get the Pro-mini/nRF2401 combinations to send any usable data at all, either between two test units, let alone back to a Pi

      I think you are missing the point... you won't be sending messages peer-to-peer with my sensors. Rather, each sensor communicates through the gateway.

      @ensbusiness said in SoCal help completing a MySensor system:

      Adding a sensor to the Pi is what I already have up and running. I don't need or use a Controller for that.

      Again, focus on the radio bits first and forget about your Pi connected sensor for now.

      Read the docs... and wire up the gateway and a sensor exactly like the docs explain for the Pi gateway. Then, post some photos of your rig and the exact code you are using.

      posted in General Discussion
      BulldogLowell
      BulldogLowell
    • RE: SoCal help completing a MySensor system

      @ensbusiness

      I'm not sure you understand.

      Build the Raspberry Pi gateway, and then a single sensor. Get that working, the very clear instructions are in the MySensors docs...

      The rest (adding additional wireless nodes or connecting a sensor to your Pi) is trivial.

      posted in General Discussion
      BulldogLowell
      BulldogLowell
    • RE: SoCal help completing a MySensor system

      @ensbusiness

      Have you started with the Raspberry Pi Gateway?

      that should be relatively easy... get your gateway working with one sensor first, and forget about the attached sensors for the time being.

      posted in General Discussion
      BulldogLowell
      BulldogLowell