Tuesday, January 16, 2018

Wireless node configuration.

Wireless nodes are part of OHS ecosystem. They serve as source of data from sensors, and as receivers for inputs. Inputs represents relays or other devices waiting for incoming commands. If you want to connect wireless node to gateway you need to set it up first. Start with download of example sketch from GitHub. Here is code for hardware version 1.4 https://github.com/vysocan/remote_1_4_RFM69. If you have on hand version with on-board temperature sensor and USB charging circuit then you can use the code almost without change. Basically you need to modify just the setting for radio module. Here is the part for radio

// Radio
#define NODEID      14
#define NETWORKID   100
#define GATEWAYID   1
#define FREQUENCY   RF69_868MHZ //Match this with the version of your gateway 
#define KEY         "ABCDABCDABCDABCD" //has to be same 16 characters/bytes on all nodes, not more not less!
#define ENABLE_ATC  //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI -75 

From this you need to only change following:


NODEID      2     // is number from 2 .. 250, do not number the nodes with same NODEID!
FREQUENCY   RF69_868MHZ // depends on your country, leave it as is or put RF69_915MHZ
KEY         "ABCDABCDABCDABCD" // needs to match the KEY of gateway.
ENABLE_ATC        // leave as is for battery powered nodes
ATC_RSSI -75      // threshold for AUTO TRANSMISSION CONTROL, you can safely leave as it is.

To start with minimal changes only, change just NODEID to be unique and KEY to match the one from gateway.

Wireless nodes are programmable, as gateway, with 3V3 FTDI 6pin USB to Serial programmer. They can be also powered from the programmer, that means you do not need a battery or charger plugged in while experimenting. To upload your sketch into board you have choose the right board target:
Select Tools > Board menu > Arduino Pro or Pro Mini, then choose Tools > Processors > ATmega328P (5V / 16Mhz)

All nodes run on 3V3 but on 16Mhz, as there is no such option choose  always (5V / 16Mhz), it will not do any harm. But FTDI programmer should be always set to 3V3 or the radio module will be damaged!

If all is set, you should see four new sensors in Node tab of gateway web interface. Wireless node then report temperature, battery voltage if battery is connected, charging status and own radio power level. Power level is useful to see how good the signal is when Auto Transmission Control is enabled, lower is better.

If you want to add new hardware to any node you need to create a default configuration for it in software. Assume that you want to add another temperature sensor to above mentioned four. First locate and change the total number of elements on this node, highlighted as bold:

// Configuration struct
struct config_t {
  uint16_t version;
  char     reg[REG_LEN * 5]; // Number of elements on this node
} conf; 

Then locate function setDefault(), you can see it is starting with following:

conf.version = VERSION;   // Change VERSION to force EEPROM load
conf.reg[0]  = 'S';       // Sensor
conf.reg[1]  = 'T';       // Temperature
conf.reg[2]  = 0;         // Local address
conf.reg[3]  = B00000000; // Default setting
conf.reg[4]  = B00011110; // Default setting, group=16, disabled
for (uint8_t ii=0; ii < 17; ii++){ conf.reg[5+ii] = 0;}

conf.version is place holder for node EEPROM setting and is to be left as is. But conf.reg[0..20] is place for default element configuration. Every element size is 21 bytes and their meaning is as follows:
  • 0  means the major element type. First letter of Sensor, Input, Key or Zone.
  • 1 is minor type of element. First letter of iButton, Temperature, Humidity, Pressure, Voltage, Battery, Digital, Analog, Float, TX_Power or Gas. If others are needed they should be added to GW software, or they will be reported as Unknown.
  • 2 Is local address in range from 0..255. In case you need to have more then one device of same type.
  • 3..4 are default configuration place holder, it is always as is. In real it holds various status flags of current element, but it is configured through web interface of gateway after it connects.
  • 5..20 are storing element name. Here set to null, as real name is received from web interface of gateway.
To go back to adding a new element you need to add bellow 21 bytes to the end of  setDefault() function and increase the number in [] accordingly:


conf.reg[84] = 'S';       // Sensor
conf.reg[85] = 'T';       // Temperature
conf.reg[86] = 1;         // Local address
conf.reg[87] = B00000000; // Default setting
conf.reg[88] = B00011110; // Default setting, group=16, disabled
for (uint8_t ii=0; ii < 17; ii++){ conf.reg[89+ii] = 0;}

Notice the local address is increased by one. Last thing after adding new element is to force the node to reset its EEPROM configuration and load the data from setDefault(). This is done by increasing the VERSION in top of sketch:
 
#define VERSION     140 // <- increase by 1

If you upload above changes to node gateway should recognize the new sensor and you will see it in Nodes tab. You can then configure it as any other element. Gateway will send the configuration back node and it will store it in its own EEPROM. This configuration persist even if you power off the node.

Next thing would be to actually add the code to handle your new sensor data. I skip the part of how you get the temperature value, as it will depend on which temperature sensor you are actually using. And I go directly to sending. Gateway receives various packets, but similar to registration structure mentioned above, sensor data need to follow data structure:
  • 0 identifies type of payload. First letter of  Sensor, Input or Zone.
  • 1 is minor type of element as defined in setDefault() function.
  • 2 Is local address as defined in setDefault() function.
  • 3..6 are the actual data.
For example following code:

// Temperature 
u.fval = (((float)analogRead(A6) * 0.003223)-0.5)*100; 
msg[0] = 'S'; // Sensor
msg[1] = 'T'; // Temperature
msg[2] = 0;   // local address
msg[3] = u.b[0]; msg[4] = u.b[1]; msg[5] = u.b[2]; msg[6] = u.b[3];
// Send to GW 
radio.sendWithRetry(GATEWAYID, msg, 7); 

It will read the analog value from A6 pin, then do some necessary calculation depending on this exact temperature sensor, and store it in special float variable u.fval. All data for sensors and inputs are type float, that is they are 4 bytes long. First part of msg[0..2] create the header describing the source of data and msg[3..6] reads the data converted from float u.fval to 4x u.b[0..3] byte values. Calling radio.sendWithRetry then sends the data stored in msg array to gateway. Length of data is set to 7 as it contains bytes stored in array msg[0..6].
In one packet you can send more then one payload of same major type, here as 'S' in msg[0]. As shown here:

// Temperature 
u.fval = (((float)analogRead(A6) * 0.003223)-0.5)*100; 
msg[0] = 'S'; // Sensor
msg[1] = 'T'; // Temperature
msg[2] = 0;   // local address
msg[3] = u.b[0]; msg[4] = u.b[1]; msg[5] = u.b[2]; msg[6] = u.b[3];
// BATT Voltage 
u.fval = 0.0064453125 * (float)analogRead(A7); // Voltage divider 2:1
msg[7] = 'V'; // Voltage
msg[8] = 0;   // local address
msg[9] = u.b[0]; msg[10] = u.b[1]; msg[11] = u.b[2]; msg[12] = u.b[3];
// Send to GW 
radio.sendWithRetry(GATEWAYID, msg, 13); 

All that is needed, is to prepare the data in msg buffer and increase the length of message. Radio message length cannot exceed 62 bytes, or the actual size of bytes allocated in sketch for array msg[].

And that should be all :).

Saturday, October 21, 2017

New major version 1.7.6.0

Since summer time I was adding some features to gateway that led into new major version 1.7.6.0. Changes include:
  • Remote zones added.
  • Added group arm and disarm chain. That is when arming/disarming group by key, Gateway is able to automatically arm/disarm another group or groups.
  • Added group state MQTT publish. Gateway now, if enabled, will publish state of group via MQTT. Such information can captured by Home Assistant or other automation program.
  • MQTT sensor publish structure modified, added group name to path.
  • Updated MQTT library and MQTT protocol to 3.1.1.
  • Added new sensor type "Battery", to easily identify battery powered nodes voltage. 
  • Added new sensor type "Gas", to easily identify any air quality environmental sensor.
  • Added SMS command gateway. Authorized numbers from contact list are able to get Group state or set it On, Off, Arm and Disarm by sending SMS in predefine format to gateway GSM number. This functionality need some testing.
  • Updated NilRTOS to latest version available. In future port is needed to ChNil, which is newer replacement of NilRTOS, but unfortunately not one to one compatible with NilRTOS.
  • Various small enhancements in code and web interface.
New version is now at GItHub.

Monday, September 18, 2017

Remote zones

Recently I have started to play with feature that was on my list for long time. That is remote zone. To introduce it a little, on beginning I had in mind 2 general types of zones. Local zones are directly connected to gateway hardware. These can be build in 8 analog plus 4 digital zones, or zones connected by I2C expansion connector. Then remote zones connected either by RS485(wire) or wireless zones. Connection type does not matter to gateway, but such zones can be divided to two groups by reporting state. One group would report fully its state, that is it will report every change of state out of OK, PIR or Tamper. The other, battery powered remote zones, will only report alarm states such as PIR or Tamper. Gateway will then automatically change the zone state to OK if there is no event received for 2 seconds.

Remote zones brings new possibilities, you can build yourself a wireless PIR and add it to your gateway. Or you can build remote expander, either wired or wireless that will extend you zone count. Imagine you have barn near by, and you have only 4 wires connected to barn, that is only enough wires for authentication node. Now you decide you need two analog plus one digital zones there. Simply enough you connect such zones, with some little protection circuity, directly to authentication node. Add code to authentication node to include zone registration plus zone state handling, and you have 3 new zones connected.

I have here on my desk for test a battery powered remote zone, as shown on
picture. It is running for some days, and seems to do its job properly. I use Chinese all-in-one PIR sensor AS312 attached to PIR shell by hot glue. For this purpose I have modified standard battery node code and added zone state handling, based on interrupt signal coming form PIR sensor. The node does also temperature and humidity monitoring out of external SHT11. Battery life seems to be reasonable, with some modification it could last few months with 700mAh Li-Po. This is tempting, it would be nice to create rechargeable wireless PIR sensor that could be placed into standard commercial PIR shell :). I will publish the code to GitHub as example code.

Registering is same as for sensors. As soon as the node is powered up it will send registration packet and gateway will add a zone in zone tab. Then you can set attributes as for any other zone. Zone setting are sent back to nodes as master copy, and on next power cycle the zone is registered with newly stored  attributes. There are enforced rules for remote zones during registration, such as analog digital flag on bit 15 and it is based on registration  type ('A' or 'D'). Or remote zone flag on bit 12 is set On, and present bit flag on bit 14 is set On. Zone number cannot override any local zone, that is it cannot be lower then 13, or cannot override existing I2C zone. Zone last OK and PIR timestamps are set to registration time. Sleeping battery powered remote zones share the same message queue as sensors, that is gateway keeps registration packet for at least one hour to not loose such packets during node sleep.



Tuesday, August 29, 2017

Realy nodes

After some testing I have finished new relay node. As all nodes it is Arduino compatible board with ATmega 328P clocked at 16MHz@3.3V.
  • Size 6.1 x 5.6 cm.
  • On-board AC/DC power supply. Input 100-240VAC, 50-60Hz. Output 5V/3W. Fused with TVS on input with slow blow 0.5A fuse.
  • 2x Japanese(Panasonic) power relays with COM, NC and NO inputs. With TVS on both.
  • It has more powerful RFM69HW soldered on back with IPX connector.
  • Temperature sensor to indicate overheating based on MCP7900A on ADC6. It is mounted under AC/DC power supply.
  • IO header, rest of pins are taken out. As well as +5V and +3V3 to add another relays or sensors.
  • Programmable via standard FTDI 6 pin 3V3 programmer.
It is available in my online store.  Schematic is in my shared folder, and example sketch is placed on GitHub.


Saturday, July 22, 2017

Node code for PCB 1.4.

I have just created new repositories for nodes version 1.4. Although you can, similarly as I did, covert the code from version 1.3. But all new changes will be as always targeted to the latest version.

https://github.com/vysocan/remote_1_4_Key_Temp.git

https://github.com/vysocan/remote_1_4_RFM69.git

There are some changes mostly needed for new hardware features present, like charging indicator and other small corrections.

Tuesday, June 27, 2017

Auto arm moved from zone to group

After improving auto arm, I have realized that auto arm flag should be moved into group instead of zone. That is, it make no sense to have just one zone flagged as auto arm in a group. The algorithm then would not work, if user will not flag all zones in auto arm group, it will not consider all zones.  And most probably gateway will auto arm group that still has some movement detected. To prevent this possible human error, I have moved the auto arm flag to Group setting.

Changes are pushed into GitHub.

The use of auto arm feature can be greatly extended. For example, it can be easily used to lock an electromagnetic locks when authentication node will receive arm packet. As easy as wiring a pair of cable to node, but of course you have to have the electromagnetic locks installed first :).

Monday, June 26, 2017

Improved auto arm

I have just committed to github new improved part for auto arm feature. Previous code mapped the auto arm to zone with oldest alarm, and that was impractical when there was more then one zone in a group. Now the gateway selects it by taking newest alarm from any zone that is in the group. That is, if there is someone moving in at least one zone in a group, the group will not get auto armed.

I will not yet release it as new version, as I have in mind some other improvements.