Navigation

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

    Posts made by simbo

    • RE: What did you build today (Pictures) ?

      Air particulate sensor.

      BTW, solder fumes seem to be bad for you........

      2_1568765899621_Photo 18-9-19, 9 57 10 am-1.jpg 1_1568765899621_Photo 18-9-19, 9 50 34 am-1.jpg 0_1568765899620_Photo 18-9-19, 9 44 38 am-1.jpg

      posted in General Discussion
      simbo
      simbo
    • Air particulate / dust sensor node

      I'm sharing my latest project which is a air particulate sensor based on the PMS7003 module.

      I designed a custom PCB to break out all the connectors as well as a 3D printed enclosure.

      The node uses a 5v pro mini as well as the common 1602 LCD. A LE33 is used to regulate down to 3v3 for the NRF24.

      My latest board that hasn't been built up yet also includes an I2C breakout for temp / humidity / barometric pressure.

      The PMS7003 module is physically a bit of a pain as the intake / exhaust ports are on the same side as the connector. The case had to be designed with channels to manage the air and out whilst keeping clearances for the wire connectors.

      I've mounted mine next to my 3D printer to see what the 3D printed does to the air quality inside the house.

      Happy to share the PCB, code and the 3D model if there's any interest.

      5_1568765563644_Photo 18-9-19, 9 57 10 am-1.jpg 4_1568765563643_Photo 18-9-19, 9 50 34 am-1.jpg 3_1568765563643_Photo 18-9-19, 9 48 42 am-1.jpg 2_1568765563643_Photo 18-9-19, 9 44 49 am-1.jpg 1_1568765563643_Photo 18-9-19, 9 44 44 am-1.jpg 0_1568765563643_Photo 18-9-19, 9 44 38 am-1.jpg

      posted in My Project
      simbo
      simbo
    • RE: Everything nRF52840

      Someone may get some reuse out of this. I've made a 3d printed prototyping rig for the NRF52840 DK board as part of my MySensors adventures....

      https://www.thingiverse.com/thing:3836487

      1_1567139386009_Photo 30-8-19, 2 10 17 pm.jpg 0_1567139386008_Photo 30-8-19, 2 10 43 pm.jpg

      posted in Hardware
      simbo
      simbo
    • Lamp

      I made a thing 🙂

      I used @sunberg84 's LED dimmer and Newbie boards (https://www.openhardware.io/view/552/Dimmable-Led-Strip-board-MysX) (https://www.openhardware.io/view/389/EasyNewbie-PCB-RFM69-HWW-edition-for-MySensors) to make some desk lamps using warm white 5050 LED strips from the ebays.

      All up, it probably cost about $12 AUD to make excluding the 12v power adapter. Luckly I had some old ones laying around. Otherwise the power adapter alone would be more expensive than the lamp!

      I 3D printed the parts to make the lamp in PLA plastic.

      I've been monitoring the temps and the MOFSET seems to make the most heat. If you don't use a heat-sink, it gets to approx 45 deg C with the ambient of approx 20 deg C. With a heat-sink, it's about 30 deg C! I strongly recommend using heat-sinks. Note that the white lamp shade warped during printing, not from use of the lamp!

      It's designed to be a convection pipe which does seem to keep the air moving well. I'm happy with the temps and the PLA plastic especially with the heat sinks on the MOFSET and voltage regulator.

      The lamp draws about 12W when it's 100% on @ approx 1.1A. I'm using a 2A power supplies to be on the safe side.

      If there is any interest, I'll post the designs and BOM on Thingiverse.

      BTW, I've found MySensors to be much more reliable and responsive than the Ikea Tradfri lights I have in my house 🙂

      0_1563245032476_Photo 16-7-19, 12 28 37 pm (1)_edited.jpg

      0_1563245231153_Photo 16-7-19, 12 26 48 pm_edited.jpg

      0_1563245285201_Photo 16-7-19, 12 27 56 pm_edited.jpg

      0_1563245349975_Photo 16-7-19, 12 27 23 pm_edited.jpg

      0_1563246235499_2019-07-16 13_03_07-Autodesk Fusion 360 (Education License).png

      posted in My Project
      simbo
      simbo
    • RE: How to repeat presentation when using home-assistant with persistance false

      A related thread: https://forum.mysensors.org/topic/6843/re-request-presentation

      How can we send a I_PRESENT or I_REBOOT command using the HA / MySensors API? If there's a way, then an automation be be hard-coded to request each node to reboot.

      posted in Home Assistant
      simbo
      simbo
    • Entity renaming

      Howdy,

      Is it possible to rename MySensor nodes in Home Assistant? I've noticed that I can't use the normal method to rename by clicking on the cog in the Developer States window.

      Cheers,
      Simon.

      posted in Home Assistant
      simbo
      simbo
    • Newbie motion and dimmer case

      Hi All,

      Just knocked up a case for @sundberg84 's Newbie PCB with Dimmer module. Thanks to @sundberg84 for the great PCB's.

      This is the first version, and the clearances are rather generous which makes the case bigger than it needs to be. Further revisions will try and get this down to make the overall size smaller.

      As you can see in the photos, the print around the aperture is a little scabby, but I think that has more to do with my poor placement of supports rather than the model itself.

      The case is a press fit with snap clasps.

      Files over on thingiverse here: https://www.thingiverse.com/thing:3135667

      Enjoy!

      4_1538629899784_IMG_0865.JPG 3_1538629899784_IMG_0866.JPG 2_1538629899784_IMG_0867.JPG 1_1538629899784_IMG_0868.JPG 0_1538629899784_IMG_0869.JPG!

      posted in Enclosures / 3D Printing
      simbo
      simbo
    • RE: 💬 Dimmable Led Strip board (MysX)

      In your next rev, perhaps you increase the spacing between the voltage regulator and the MOFSET to accommodate heat sinks? The minimum would be 2.54mm.

      posted in OpenHardware.io
      simbo
      simbo
    • Power / pulse meter

      Howdy,

      I'm loving the NodeManager for my temperature, humidity and repeater nodes. I've just built a battery power meter node and noticed some weird behavior. I'm using the latest version 1.7.

      The pulse sensor can interrupt < 1 second. That is to say, the pulse frequency can be less than 1 second at certain periods of the day. I find that I can't get the sensor to report because the node interrupts and then sleeps and then interrupts again before the sleep expires and wakes to send the report. So in the debug, all you see is the interrupt processing and never a send.

      Just for debug, I've set both the sleep and report interval to 1 second and I've seen this behavior. What I would like to do is to set the sleep and report interval to 5 minutes, but I don't think that it would ever report.

      Any thoughts?

      posted in NodeManager
      simbo
      simbo
    • RE: 💬 Easy/Newbie PCB for MySensors

      Hi All,

      Thanks Sundberg84 for creating a board where I can knock out sensors in the matter of minutes instead of hours. 🙂

      That being said, I actually spent many hours on the weekend trying to get my first board to work so I thought that I'd share so it could benefit others.

      I was setting up a 3v3 board with 2 x AA batteries with the battery pad jumpered and using the 3v3 booster. I triple checked the board for continuity.

      I was suffering from !TSM:FPAR:FAIL messages when firing up the node using the FTDI adaptor. I found that the board didn't work when both the battery and FTDI were supplying power.

      Here are my lessons:

      • You need to have a battery connected. This is required to power the radio, as it radio isn't powered by the FTDI adapter
      • You need to remove power from the FTDI adapter. I couldn't disable power on my FTDI adapter so I had to use jumper wires for CTS, DTR, RXD, TXD, and GND between the adapter and the ProMini.

      Thanks again, and I look forward to knocking out some nodes super quick.

      Cheers,
      Simon.

      posted in OpenHardware.io
      simbo
      simbo
    • RE: How can I have a test environment separate from production

      Awesome...thanks.

      posted in General Discussion
      simbo
      simbo
    • RE: How can I have a test environment separate from production

      @Nca78

      Ok....That sounds reasonable. I am assuming that is set with the #define MY_RF24_CHANNEL?

      posted in General Discussion
      simbo
      simbo
    • How can I have a test environment separate from production

      Howdy,

      Title says it all. I'd like to have the ability to build and debug sensors with a test gateway and have a way to present to the production gateway when they've been tested.

      I am mostly using SenseBenders in my production setup, with a few Nano's as repeaters.

      Any ideas on how to be able to run up a sensor without it presenting to the production gateway?

      Why do I want to do this? I've had issues when using HomeAssistant keeping the state of test child sensors that change while I'm still working and debugging the sketch. I'd like to run a test HomeAssistant with the test gateway.

      Thanks,
      Simon.

      posted in General Discussion
      simbo
      simbo
    • RE: Not all of a node's children sensors are visible in HA

      I'm an idiot.......

      I just noticed a binary_sensor.nodemanager_113_3 was created in the dev-state page.

      posted in Home Assistant
      simbo
      simbo
    • Not all of a node's children sensors are visible in HA

      Howdy,

      I have added a new SenseBender NodeManger which is visible in the dev-states screen. However one of the children sensors is not showing in the dev-states screen in HA . Specifically the door sensor which is child sensor #3. Below is a copy and paste from the dev-states screen.

      sensor.nodemanager_113_1	24.99	battery_level: 100
      child_id: 1
      description: 
      device: /dev/ttyACM1
      node_id: 113
      V_TEMP: 24.99
      unit_of_measurement: °C
      friendly_name: NodeManager 113 1
      sensor.nodemanager_113_2	69.01	battery_level: 100
      child_id: 2
      description: 
      device: /dev/ttyACM1
      node_id: 113
      V_HUM: 69.01
      unit_of_measurement: %
      friendly_name: NodeManager 113 2
      sensor.nodemanager_113_200	SLEEPING	battery_level: 100
      child_id: 200
      description: 
      device: /dev/ttyACM1
      node_id: 113
      V_CUSTOM: SLEEPING
      friendly_name: NodeManager 113 200
      sensor.nodemanager_113_201	3.34	battery_level: 100
      child_id: 201
      description: 
      device: /dev/ttyACM1
      node_id: 113
      V_VOLTAGE: 3.34
      unit_of_measurement: V
      friendly_name: NodeManager 113 201
      

      I'm successfully running a number of other NodeManager SenseBender nodes on HA with just temp and humidity.

      The mysensors.json file appears to be showing the correct number of children sensors, including sensor #3 which is the door sensor:

      "113": {
          "sensor_id": 113,
          "children": {
            "1": {
              "id": 1,
              "type": 6,
              "description": "",
              "values": {
                "0": "24.99"
              }
            },
            "2": {
              "id": 2,
              "type": 7,
              "description": "",
              "values": {
                "1": "69.01"
              }
            },
            "3": {
              "id": 3,
              "type": 23,
              "description": "",
              "values": {
                "16": "1"
              }
            },
            "200": {
              "id": 200,
              "type": 23,
              "description": "",
              "values": {
                "48": "SLEEPING"
              }
            },
            "201": {
              "id": 201,
              "type": 30,
              "description": "",
              "values": {
                "38": "3.34"
              }
            }
          },
      

      I know that the door sensor is working as child sensor #200 shows the change to the wake / sleeping state when the NodeManager wakes up from the door sensor interrupt. Also, I can see that the NodeManager is sending the message in the serial console on change to the door sensor,

      Any thoughts as to why child sensor #3 is not showing in HA?

      Thanks,
      Simon

      posted in Home Assistant
      simbo
      simbo
    • RE: Sensebender programmer is not responding

      @simbo said:

      I was never able to sort out the programming issue using the stock Linux Arduino IDE package.

      I spent some time installing the PlatformIO package on Arch Linux which allowed me to reliably upload to the sense bender. It was a bit of mucking about to get it installed, but it seems to work for me. Plus give me the command line any day over an IDE! 🙂

      posted in Troubleshooting
      simbo
      simbo
    • Sensebender programmer is not responding

      Hi,

      I have an intermittent problem where I can not always upload my sketch to my Sensebender.

      The Sensebender is running a modified version of the Sensebender sketch and shows the expected debug on the serial monitor, indicating that it has completed the setup, and then moved into the main loop and reading the sensors with reasonable values. I just don't seem to be able to upload a new version of the sketch reliably.

      What has worked previously has been to upload the ClearEPROM sketch, and when that is sucessful, upload my modified Sensebender sketch. This is not working now.

      In my ignorance, it feels like there is some timing factor going that would allow me to upload the ClearEPROM sketch.

      Since I can see the serial debug, I assume the problem isn't with my FTDI USB adaptor.

      I've checked the soldering on the header for the FTDI and that seems good, and I assume it must be because I can see the the sketch debug in the serial monitor?

      I am using the Arduino 1.6.9 IDE on Arch Linux with the Mysensors 2.0.0 library. I've not modified the bootloader.

      I'm using the FTDI adaptor linked from the MySensors store.

      What follows is the the verbose messages from the IDE when uploading failed:

      Sketch uses 21,244 bytes (69%) of program storage space. Maximum is 30,720 bytes.
      Global variables use 861 bytes (42%) of dynamic memory, leaving 1,187 bytes for local variables. Maximum is 2,048 bytes.
      /home/singlis/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino2/bin/avrdude -C/home/singlis/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino2/etc/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/ttyUSB0 -b19200 -Uflash:w:/tmp/build16801fad7f0386b38002733e635aa592.tmp/SenseBender.ino.hex:i 
      
      avrdude: Version 6.3, compiled on Jun 14 2016 at 17:17:01
               Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
               Copyright (c) 2007-2014 Joerg Wunsch
      
               System wide configuration file is "/home/singlis/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino2/etc/avrdude.conf"
               User configuration file is "/home/singlis/.avrduderc"
               User configuration file does not exist or is not a regular file, skipping
      
               Using Port                    : /dev/ttyUSB0
               Using Programmer              : stk500v1
               Overriding Baud Rate          : 19200
      avrdude: stk500_recv(): programmer is not responding
      avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
      avrdude: stk500_recv(): programmer is not responding
      avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
      avrdude: stk500_recv(): programmer is not responding
      avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
      avrdude: stk500_recv(): programmer is not responding
      avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
      avrdude: stk500_recv(): programmer is not responding
      avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
      avrdude: stk500_recv(): programmer is not responding
      avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
      avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xe8
      avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xda
      avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x1a
      avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xc8
      
      avrdude done.  Thank you.
      
      Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.
      

      I've also run the programmer from the command line with increased debug verbosity:

      [singlis@localhost SenseBender]$ /home/singlis/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino2/bin/avrdude -v -v -v -v -C/home/singlis/.ardu
      ino15/packages/arduino/tools/avrdude/6.3.0-arduino2/etc/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/ttyUSB0 -b19200 -Uflash:w:/tmp/buildd81c5a6658
      2a8d9d1e847e29ff4d6e6b.tmp/ClearEepromConfig.ino.hex:i 
      
      avrdude: Version 6.3, compiled on Jun 14 2016 at 17:17:01
               Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
               Copyright (c) 2007-2014 Joerg Wunsch
      
               System wide configuration file is "/home/singlis/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino2/etc/avrdude.conf"
               User configuration file is "/home/singlis/.avrduderc"
               User configuration file does not exist or is not a regular file, skipping
      
               Using Port                    : /dev/ttyUSB0
               Using Programmer              : stk500v1
               Overriding Baud Rate          : 19200
      avrdude: Send: 0 [30]   [20] 
      avrdude: Send: 0 [30]   [20] 
      avrdude: Send: 0 [30]   [20] 
      avrdude: ser_recv(): programmer is not responding
      avrdude: stk500_recv(): programmer is not responding
      avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
      avrdude: Send: 0 [30]   [20] 
      avrdude: ser_recv(): programmer is not responding
      avrdude: stk500_recv(): programmer is not responding
      avrdude: Send: 0 [30]   [20] 
      avrdude: Recv: . [e8] 
      avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0xe8
      avrdude: Send: 0 [30]   [20] 
      avrdude: Recv: . [9a] 
      avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x9a
      avrdude: Send: 0 [30]   [20] 
      avrdude: Recv: . [1a] 
      avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x1a
      avrdude: Send: 0 [30]   [20] 
      avrdude: Recv: . [c8] 
      avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0xc8
      avrdude: Send: 0 [30]   [20] 
      avrdude: Recv: . [f2] 
      avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xf2
      avrdude: Send: 0 [30]   [20] 
      avrdude: Recv: . [c0] 
      avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xc0
      avrdude: Send: 0 [30]   [20] 
      avrdude: Recv: . [aa] 
      avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0xaa
      avrdude: Send: 0 [30]   [20] 
      avrdude: Recv: . [f2] 
      avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xf2
      
      avrdude done.  Thank you.
      

      Here's the log from the IDE when an upload succeeeds:

      Sketch uses 21,244 bytes (69%) of program storage space. Maximum is 30,720 bytes.
      Global variables use 861 bytes (42%) of dynamic memory, leaving 1,187 bytes for local variables. Maximum is 2,048 bytes.
      /home/singlis/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino2/bin/avrdude -C/home/singlis/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino2/etc/avrdude.conf -v -patmega328p -carduino -P/dev/ttyUSB0 -b57600 -D -Uflash:w:/tmp/build16801fad7f0386b38002733e635aa592.tmp/SenseBender.ino.hex:i 
      
      avrdude: Version 6.3, compiled on Jun 14 2016 at 17:17:01
               Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
               Copyright (c) 2007-2014 Joerg Wunsch
      
               System wide configuration file is "/home/singlis/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino2/etc/avrdude.conf"
               User configuration file is "/home/singlis/.avrduderc"
               User configuration file does not exist or is not a regular file, skipping
      
               Using Port                    : /dev/ttyUSB0
               Using Programmer              : arduino
               Overriding Baud Rate          : 57600
               AVR Part                      : ATmega328P
               Chip Erase delay              : 9000 us
               PAGEL                         : PD7
               BS2                           : PC2
               RESET disposition             : dedicated
               RETRY pulse                   : SCK
               serial program mode           : yes
               parallel program mode         : yes
               Timeout                       : 200
               StabDelay                     : 100
               CmdexeDelay                   : 25
               SyncLoops                     : 32
               ByteDelay                     : 0
               PollIndex                     : 3
               PollValue                     : 0x53
               Memory Detail                 :
      
                                        Block Poll               Page                       Polled
                 Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
                 ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
                 eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
                 flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
                 lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
                 hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
                 efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
                 lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
                 calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
                 signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
      
               Programmer Type : Arduino
               Description     : Arduino
               Hardware Version: 3
               Firmware Version: 5.0
               Vtarget         : 0.3 V
               Varef           : 0.3 V
               Oscillator      : 28.800 kHz
               SCK period      : 3.3 us
      
      avrdude: AVR device initialized and ready to accept instructions
      
      Reading | ################################################## | 100% 0.00s
      
      avrdude: Device signature = 0x1e950f (probably m328p)
      avrdude: reading input file "/tmp/build16801fad7f0386b38002733e635aa592.tmp/SenseBender.ino.hex"
      avrdude: writing flash (21244 bytes):
      
      Writing | ################################################## | 100% 4.98s
      
      avrdude: 21244 bytes of flash written
      avrdude: verifying flash memory against /tmp/build16801fad7f0386b38002733e635aa592.tmp/SenseBender.ino.hex:
      avrdude: load data flash data from input file /tmp/build16801fad7f0386b38002733e635aa592.tmp/SenseBender.ino.hex:
      avrdude: input file /tmp/build16801fad7f0386b38002733e635aa592.tmp/SenseBender.ino.hex contains 21244 bytes
      avrdude: reading on-chip flash data:
      
      Reading | ################################################## | 100% 4.17s
      
      avrdude: verifying ...
      avrdude: 21244 bytes of flash verified
      
      avrdude done.  Thank you.
      

      I've checked that the IDE board is 'Sensebender Micro' and the programmer is 'Arduino as ISP'

      I have tried powering just using the FTDI adaptor and by a 3.3v battery source.

      I have a 47uf cap on the radio. There seems to be conflicting information on the forums on if this should be 4.7uf or 47uf. I've used 47uf on the basis of what is written on the Connecting the Radio instructions.

      I've tried unplugging and re-plugging in the USB adaptor multiple times, and in the process flip flopping from /dev/ttyUSB0 to /dev/ttyUSB1.

      I've used minicom successfully in addition to the IDE as a serial monitor.

      Here's my modified Sensebender sketch for what it's worth!

      /**
       * The MySensors Arduino library handles the wireless radio link and protocol
       * between your home built sensors/actuators and HA controller of choice.
       * The sensors forms a self healing radio network with optional repeaters. Each
       * repeater and gateway builds a routing tables in EEPROM which keeps track of the
       * network topology allowing messages to be routed to nodes.
       *
       * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       * Copyright (C) 2013-2015 Sensnology AB
       * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
       *
       * Documentation: http://www.mysensors.org
       * Support Forum: http://forum.mysensors.org
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License
       * version 2 as published by the Free Software Foundation.
       *
       *******************************
       *
       * REVISION HISTORY
       * Version 1.0 - Thomas Bowman Mørch
       * 
       * DESCRIPTION
       * Default sensor sketch for Sensebender Micro module
       * Act as a temperature / humidity sensor by default.
       *
       * If A0 is held low while powering on, it will enter testmode, which verifies all on-board peripherals
       *  
       * Battery voltage is as battery percentage (Internal message), and optionally as a sensor value (See defines below)
       *
       * Version 1.3 - Thomas Bowman Mørch
       * Improved transmission logic, eliminating spurious transmissions (when temperatuere / humidity fluctuates 1 up and down between measurements) 
       * Added OTA boot mode, need to hold A1 low while applying power. (uses slightly more power as it's waiting for bootloader messages)
       * 
       * Version 1.4 - Thomas Bowman Mørch
       * 
       * Corrected division in the code deciding whether to transmit or not, that resulted in generating an integer. Now it's generating floats as expected.
       * Simplified detection for OTA bootloader, now detecting if MY_OTA_FIRMWARE_FEATURE is defined. If this is defined sensebender automaticly waits 300mS after each transmission
       * Moved Battery status messages, so they are transmitted together with normal sensor updates (but only every 60th minute)
       * 
       */
      
      // Enable debug prints to serial monitor
      //#define MY_DEBUG 
      
      // Define a static node address, remove if you want auto address assignment
      //#deine MY_NODE_ID 3
      
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      //#define MY_RADIO_RFM69
      
      // Enable to support OTA for this node (needs DualOptiBoot boot-loader to fully work)
      #define MY_OTA_FIRMWARE_FEATURE
      
      #include <SPI.h>
      #include <MySensors.h>
      #include <Wire.h>
      #include <SI7021.h>
      #include <BH1750.h>
      #ifndef MY_OTA_FIRMWARE_FEATURE
      #include "drivers/SPIFlash/SPIFlash.cpp"
      #endif
      #include <EEPROM.h>  
      #include <sha204_lib_return_codes.h>
      #include <sha204_library.h>
      #include <RunningAverage.h>
      #include <avr/power.h>
      
      // Uncomment the line below, to transmit battery voltage as a normal sensor value
      #define BATT_SENSOR    199
      
      #define RELEASE "1.4"
      
      #define AVERAGES 2
      
      // Child sensor ID's
      #define CHILD_ID_TEMP  1
      #define CHILD_ID_HUM   2
      #define CHILD_ID_MOT   3
      #define CHILD_ID_LIGHT 4
      
      // How many milli seconds between each measurement
      #define MEASURE_INTERVAL 60000
      
      // How many milli seconds should we wait for OTA?
      #define OTA_WAIT_PERIOD 300
      
      // FORCE_TRANSMIT_INTERVAL, this number of times of wakeup, the sensor is forced to report all values to the controller
      #define FORCE_TRANSMIT_INTERVAL 30 
      
      // When MEASURE_INTERVAL is 60000 and FORCE_TRANSMIT_INTERVAL is 30, we force a transmission every 30 minutes.
      // Between the forced transmissions a tranmission will only occur if the measured value differs from the previous measurement
      
      // HUMI_TRANSMIT_THRESHOLD tells how much the humidity should have changed since last time it was transmitted. Likewise with
      // TEMP_TRANSMIT_THRESHOLD for temperature threshold.
      #define HUMI_TRANSMIT_THRESHOLD 0.5
      #define TEMP_TRANSMIT_THRESHOLD 0.5
      #define LUX_TRANSMIT_THRESHOLD 10
      
      // Pin definitions
      #define TEST_PIN       A0
      #define LED_PIN        A2
      #define ATSHA204_PIN   17 // A3
      #define MOT_PIN        3  // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
      #define LIGHT_PIN      4  // LED lights
      
      const int sha204Pin = ATSHA204_PIN;
      atsha204Class sha204(sha204Pin);
      
      SI7021 humiditySensor;
      SPIFlash flash(8, 0x1F65);
      
      BH1750 lightSensor;
      
      // Sensor messages
      MyMessage msgHum(CHILD_ID_HUM, V_HUM);
      MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
      MyMessage msgMot(CHILD_ID_MOT, V_TRIPPED);
      MyMessage msgLight(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
      
      
      #ifdef BATT_SENSOR
      MyMessage msgBatt(BATT_SENSOR, V_VOLTAGE);
      #endif
      
      // Global settings
      int measureCount = 0;
      int sendBattery = 0;
      boolean isMetric = true;
      boolean highfreq = true;
      boolean transmission_occured = false;
      
      // Storage of old measurements
      float lastTemperature = -100;
      int lastHumidity = -100;
      long lastBattery = -100;
      boolean lastMot = false;
      uint16_t lastLux = -100;
      
      RunningAverage raHum(AVERAGES);
      
      /****************************************************
       *
       * Setup code 
       *
       ****************************************************/
      void setup() {
        
        pinMode(LED_PIN, OUTPUT);
        digitalWrite(LED_PIN, LOW);
      
        Serial.begin(115200);
        Serial.print(F("Sensebender Micro FW "));
        Serial.print(RELEASE);
        Serial.flush();
      
        // First check if we should boot into test mode
      
        pinMode(TEST_PIN,INPUT);
        digitalWrite(TEST_PIN, HIGH); // Enable pullup
        if (!digitalRead(TEST_PIN)) testMode();
      
        // Make sure that ATSHA204 is not floating
        pinMode(ATSHA204_PIN, INPUT);
        digitalWrite(ATSHA204_PIN, HIGH);
        
        digitalWrite(TEST_PIN,LOW);
        
        digitalWrite(LED_PIN, HIGH); 
      
        humiditySensor.begin();
      
        lightSensor.begin();
      
        digitalWrite(LED_PIN, LOW);
      
        Serial.flush();
        Serial.println(F(" - Online!"));
        
        isMetric = getConfig().isMetric;
        Serial.print(F("isMetric: ")); Serial.println(isMetric);
        raHum.clear();
        sendTempHumidityMeasurements(false);
        sendBattLevel(false);
        
      #ifdef MY_OTA_FIRMWARE_FEATURE  
        Serial.println("OTA FW update enabled");
      #endif
      }
      
      void presentation()  {
        sendSketchInfo("Sensebender Micro", RELEASE);
      
        present(CHILD_ID_TEMP,S_TEMP);
        present(CHILD_ID_HUM,S_HUM);
        present(CHILD_ID_MOT, S_MOTION);
        present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
      
          
      #ifdef BATT_SENSOR
        present(BATT_SENSOR, S_POWER);
      #endif
      }
      
      
      /***********************************************
       *
       *  Main loop function
       *
       ***********************************************/
      void loop() {
        
        measureCount ++;
        sendBattery ++;
        bool forceTransmit = false;
        transmission_occured = false;
      #ifndef MY_OTA_FIRMWARE_FEATURE
        if ((measureCount == 5) && highfreq) 
        {
          clock_prescale_set(clock_div_8); // Switch to 1Mhz for the reminder of the sketch, save power.
          highfreq = false;
        } 
      #endif
        
        if (measureCount > FORCE_TRANSMIT_INTERVAL) { // force a transmission
          forceTransmit = true; 
          measureCount = 0;
        }
          
        sendTempHumidityMeasurements(forceTransmit);
        sendMotionMeasurements(forceTransmit);
        sendLightLevel(forceTransmit);
        if (sendBattery > 60) 
        {
           sendBattLevel(forceTransmit); // Not needed to send battery info that often
           sendBattery = 0;
        }
      #ifdef MY_OTA_FIRMWARE_FEATURE
        if (transmission_occured) {
            wait(OTA_WAIT_PERIOD);
        }
      #endif
      
        // Sleep until interrupt comes in on motion sensor. 
        sleep(digitalPinToInterrupt(MOT_PIN), CHANGE, MEASURE_INTERVAL);
      }
      
      
      /*********************************************
       *
       * Sends temperature and humidity from Si7021 sensor
       *
       * Parameters
       * - force : Forces transmission of a value (even if it's the same as previous measurement)
       *
       *********************************************/
      void sendTempHumidityMeasurements(bool force)
      {
        bool tx = force;
      
        si7021_env data = humiditySensor.getHumidityAndTemperature();
        
        raHum.addValue(data.humidityPercent);
        
        float diffTemp = abs(lastTemperature - (isMetric ? data.celsiusHundredths : data.fahrenheitHundredths)/100.0);
        float diffHum = abs(lastHumidity - raHum.getAverage());
      
        Serial.print(F("TempDiff :"));Serial.println(diffTemp);
        Serial.print(F("HumDiff  :"));Serial.println(diffHum); 
      
        if (isnan(diffHum)) tx = true; 
        if (diffTemp > TEMP_TRANSMIT_THRESHOLD) tx = true;
        if (diffHum > HUMI_TRANSMIT_THRESHOLD) tx = true;
      
        if (tx) {
          measureCount = 0;
          float temperature = (isMetric ? data.celsiusHundredths : data.fahrenheitHundredths) / 100.0;
           
          int humidity = data.humidityPercent;
          Serial.print("T: ");Serial.println(temperature);
          Serial.print("H: ");Serial.println(humidity);
          
          send(msgTemp.set(temperature,1));
          send(msgHum.set(humidity));
          lastTemperature = temperature;
          lastHumidity = humidity;
          transmission_occured = true;
          if (sendBattery > 60) {
           sendBattLevel(true); // Not needed to send battery info that often
           sendBattery = 0;
          }
        }
      }
      
      /********************************************
       *
       * Sends battery information (battery percentage)
       *
       * Parameters
       * - force : Forces transmission of a value
       *
       *******************************************/
      void sendBattLevel(bool force)
      {
        if (force) lastBattery = -1;
        long vcc = readVcc();
        if (vcc != lastBattery) {
          lastBattery = vcc;
      
      #ifdef BATT_SENSOR
          float send_voltage = float(vcc)/1000.0f;
          send(msgBatt.set(send_voltage,3));
      #endif
      
          // Calculate percentage
      
          vcc = vcc - 1900; // subtract 1.9V from vcc, as this is the lowest voltage we will operate at
          
          long percent = vcc / 14.0;
          sendBatteryLevel(percent);
          transmission_occured = true;
        }
      }
      
      void sendMotionMeasurements(bool force)
      {
        bool tx = force;
      
        // Read digital motion value
        bool tripped = digitalRead(MOT_PIN) == HIGH;
      
        Serial.print("Motion: ");
        Serial.println(tripped);
      
        if (tripped != lastMot) tx = true;
      
        if (tx) {
            send(msgMot.set(tripped?"1":"0"));  // Send tripped value to gw
            lastMot = tripped;
            transmission_occured = true;
        }
      }
      
      void sendLightLevel(bool force)
      {
        bool tx = force;
      
        // Read light level
        uint16_t lux = lightSensor.readLightLevel();
        uint16_t diffLux = abs(lastLux - lux);
      
        if (diffLux > LUX_TRANSMIT_THRESHOLD) tx = true;
        Serial.print(F("TempLux :"));
        Serial.println(diffLux);
      
        if (tx) {
            Serial.print("Lux: ");
            Serial.println(lux);
            send(msgMot.set(lux));  // Send tripped value to gw
            lastLux = lux;
            transmission_occured = true;
        }
      }
      
      
      /*******************************************
       *
       * Internal battery ADC measuring 
       *
       *******************************************/
      long readVcc() {
        // Read 1.1V reference against AVcc
        // set the reference to Vcc and the measurement to the internal 1.1V reference
        #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
          ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
        #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
          ADMUX = _BV(MUX5) | _BV(MUX0);
        #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
          ADcdMUX = _BV(MUX3) | _BV(MUX2);
        #else
          ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
        #endif  
       
        delay(2); // Wait for Vref to settle
        ADCSRA |= _BV(ADSC); // Start conversion
        while (bit_is_set(ADCSRA,ADSC)); // measuring
       
        uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH  
        uint8_t high = ADCH; // unlocks both
       
        long result = (high<<8) | low;
       
        result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
        return result; // Vcc in millivolts
       
      }
      
      /****************************************************
       *
       * Verify all peripherals, and signal via the LED if any problems.
       *
       ****************************************************/
      void testMode()
      {
        uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
        uint8_t ret_code;
        byte tests = 0;
        
        digitalWrite(LED_PIN, HIGH); // Turn on LED.
        Serial.println(F(" - TestMode"));
        Serial.println(F("Testing peripherals!"));
        Serial.flush();
        Serial.print(F("-> SI7021 : ")); 
        Serial.flush();
        
        if (humiditySensor.begin()) 
        {
          Serial.println(F("ok!"));
          tests ++;
        }
        else
        {
          Serial.println(F("failed!"));
        }
        Serial.flush();
      
        Serial.print(F("-> Flash : "));
        Serial.flush();
        if (flash.initialize())
        {
          Serial.println(F("ok!"));
          tests ++;
        }
        else
        {
          Serial.println(F("failed!"));
        }
        Serial.flush();
      
        
        Serial.print(F("-> SHA204 : "));
        ret_code = sha204.sha204c_wakeup(rx_buffer);
        Serial.flush();
        if (ret_code != SHA204_SUCCESS)
        {
          Serial.print(F("Failed to wake device. Response: ")); Serial.println(ret_code, HEX);
        }
        Serial.flush();
        if (ret_code == SHA204_SUCCESS)
        {
          ret_code = sha204.getSerialNumber(rx_buffer);
          if (ret_code != SHA204_SUCCESS)
          {
            Serial.print(F("Failed to obtain device serial number. Response: ")); Serial.println(ret_code, HEX);
          }
          else
          {
            Serial.print(F("Ok (serial : "));
            for (int i=0; i<9; i++)
            {
              if (rx_buffer[i] < 0x10)
              {
                Serial.print('0'); // Because Serial.print does not 0-pad HEX
              }
              Serial.print(rx_buffer[i], HEX);
            }
            Serial.println(")");
            tests ++;
          }
      
        }
        Serial.flush();
      
        Serial.println(F("Test finished"));
        
        if (tests == 3) 
        {
          Serial.println(F("Selftest ok!"));
          while (1) // Blink OK pattern!
          {
            digitalWrite(LED_PIN, HIGH);
            delay(200);
            digitalWrite(LED_PIN, LOW);
            delay(200);
          }
        }
        else 
        {
          Serial.println(F("----> Selftest failed!"));
          while (1) // Blink FAILED pattern! Rappidly blinking..
          {
          }
        }  
      }
      

      Thanks,
      Simon.

      posted in Troubleshooting
      simbo
      simbo