The release is [here](https://github.com/grodansparadis/can4vscp_kelvin_ntc10k/releases/tag/v1.2.7)
Category: CAN4VSCP Kelvin NTC10KA
This (upper cabinet of refrigerator)
and this (lower cabinet of refrigerator)
is live data from the refrigerator project described here, here and here.
First of all, this is quite a complex way to do this, it could have been solved in an easier way. But I wanted to test the modules Grodans Paradis AB made and put them to work.
Two CAN4VSCP based modules has been use for this project. The Kelvin NTC10K module is used to sense temperatures and the Beijing I/O module is used to turn /on/off the compressor.
Configuration
Kelvin NTC10K
The module is fully describe here.
The Kelvin NTC10K (on nickname = 5) have one thermistor connected to input one which is located in the upper cabinet of the refrigerator and the one thermistor connected to input two which is connected to a sensor that is located in the lower cabinet. Both has been set to send out temperature every ten seconds
As noted also the on-board sensor send out temperature data, It sends out the data with a longer interval (0x3C = 60) which is once a minute. This value can be used to sense the room temperature but is always a bit high as the sensor is placed on the pcb. One can adjust this in the sensor calibration registers
Most thermistor needs a calibration and here it can be set with a two complement number that can calibrate a temperature with an accuracy of two decimals.
If you want temperatures sent to some sort of central server this is actually all you need to configure. The values will be sent with the set interval. The default unit is degrees Celsius but this can be changed. In our case we also need some other features enabled. This configuration we do in the control registers for each sensor
Temperature Sensor 0 and temperature sensor 2 just send out the temperature with the set interval. They are set to 1 which means they send the temperature in degrees Celsius.
For temperature sensor 1 more features has been enabled. It is configured with 0xB9 which is 10111001 in binary.
As Bit 0/Bit 1 forms 1 the temperature will be presented in degrees Celsius as for the other sensors.
Bit 3 is set so low alarm is enables.
Bit 4 is set so high alarm is enabled.
Bit 5 is set which means that CLASS1.CONTROL, TurnOff events and CLASS1.CONTROL, TurnOn events will be sent instead off CLASS1.ALARM, Alarm occurred. So an OFF event will be sent when the temperature goes below the low alarm level and an ON event will be sent then the temperature goes above the high alarm level.
Bit 7 is set which means alarm events will be sent continuously, not just when a limit is passed.
For this to work we need to set the low alarm level
which is set to four degrees Celsius. And also the high alarm value
which is set to six degrees.
The hysteresis value is set to two as default and we leave it at that.
So what will happen here?
If the temperature is below four degrees Celsius CLASS1.CONTROL, TurnOff events will be sent out every second. This will continue until the temperature is above the low alarm temperature + the hysteresis, that means at 6 degrees. When the temperature go over 6 degrees Celsius CLASS1.CONTROL, TurnOn events will be sent out every second until the temperature goes below the set high alarm point minus hysteresis, that means 4 degrees Celsius.
In addition to the TurnOn/TurnOff events the temperatures will also be sent out for us to diagram or collect in a database or do other things with.
Before we setup the Beijing module to handle the TurnOn/TurnOff events we need to mark out TurnOn/TurnOff events so they can be identified to the refrigerator. We can do this with the nickname id (node id) which in this case is set to 5. But this value could be changed if a module is replaced but it can also be good not to use this id for other purposes as well. So instead we use the zone/subzone. For the Kelvin NTC10K we can set a zone/subzone for each sensor. And we set
the zone to hex 23 (35 decimal) and the subzone for each temperature sensor to it’s index. So temperature sensor 0 get subzone= 0, sensor 1 get subzone=1 and so on.
There is no magic here. One can set up any number schema one likes.
This is how a temperature event looks like for sensor 1
And this is how a CLASS1.CONTROL, TurnOn event looks like
Beijing I/O module
The module is fully described here.
The Beijing module can do many things. But as we have a relay that control the compressor of the refrigerator connected to I/O channel we are only interested in configuration of this channel.
The I/O channels of the Beijing module is set as outputs by defaults
We have set bit 1 as an input here for a task we want to go through in this write-up (refrigerator door sensor).
Note also that the nickname (node id) is set to 4.
We also need to match the zone with the one we set for the Kelvin NTC10K (0x23) and also the subzone (0x01) for I/O channel 0 .
That is all we need to configure.
To complete the task we also need to program the decision matrix of the Beijing module. In this matrix we program what the Beijing should do when certain events is received by the module.
In our case there is the two events from the Kelvin NTC 10K module we are interested in.
If CLASS1.CONTROL, TurnOn is received we want I/O to be turned on or stay on, that is the compressor of the refrigerator should be turned on.
If CLASS1.CONTROL, TurnOff is received we want I/O zero to be turned off or stay off, that is the compressor of the refrigerator should be turned off.
The decision matrix have actions it can perform when an event matches a selection criteria. For us the SET and CLR actions is what we need.
The rest of the actions are described here.
We program the decision matrix like this. One row for each action we want to be carried out
In the first row, which looks like this
we enable the row, don’t check the originating address as we discussed above, and the originating address is not hardcoded, the zone of the received event should match the zone of the our module (0x23) and the subzone should match that for the channel set in the action parameter (I/O 0 = 0) or the module subzone depending on chosen action.
the class mask tells which bits of the class filter that is of interest. Here all is of interest (0x1FF) and the class filter is set to 0x1E which is 30 and is the code for CLASS1.CONTROL
The type mask tells which bits of the type filter is of interest. Here all is of interest (0xFF) and the type is set to 0x05 which is the code for CLASS1.CONTROL, TurnOn
So if a CLASS1.CONTROL, TurnOn event is received with zone=0x23 and subzone=0x01 the Beijing module will carry out the chosen action. We want I/O 0 to be turned on so the compressor is turned on and the action set output of I/O channel high will do that for us. This action expects the I/O channel as action parameter so we set it to x00.
So now out CLASS1.CONTROL, TurnON events will turn on the compressor. The Beijing will confirm the I/O change with a CLASS1.INFORMATION, On event.
The DM row for the CLASS1.CONTROL, TurnOff is then setup in the same way.
Thats it. We have now made a self contained unit consisting of two modules that can work autonomously.
The cloud
The fridge project explains how to share the generated data to the cloud. I will do another write-up about this later. But it’s not more to it then to program the decision matrix of the VSCP daemon to send data to the cloud. You have live data for this setup here as a sample. This data is on a CAN4VSCP bus in this house and is collected by a Raspberry Pi and is sent up to ThingsSpeak.
VSCP have other means of displaying data and more will come in the next version.
The refrigerator again. It takes more time then expected of course. It always do. This time because I have a lot of other things to attend to at the moment. I understand if you ask some questions about this project. So I answer them here (before you actually ask them)
Why this project?
Our refrigerator broke down two weeks ago. And we need one also in my family. Of course we do, open source programmers may not afford much buying stuff but we also want our milk to be cold. Luckily it is winter here now and we have some other storage that is at about four/five degrees so it is no immediate panic, but as weather is getting better (the spring is coming) this is not a good long-term solution.
When our fridge broke down some years ago I decided to try to rescue it and if it was possible I would take standard VSCP modules to do so. The compressor was OK and if it is this is a simple project mostly. This project has worked perfectly well since then and became a nice VSCP demo project.
Yes, Yes, YES it’s an overkill using VSCP standard modules for this. An Arduino or some other simple board would have done the job. But I wanted to use the modules to see if they did their job also over time. The best way to actually see if things are working the way you thought is to put them in some critical system in your house (the heating in our house is already controlled this way). If there is some bugs or design problems things will be solved by necessity. To have them in a demo system on a workbench is just not the same thing.
So for the refrigerator the first question was to check if the compressor still worked. If it was dead it is just a pieces of junk and not a refrigerator. But just as with the fridge it was the control logic that had broken also this time. Make me wonder how many perfectly fine refrigerators/fridges are thrown away out there that could have new control added for a few bucks and do the job they were designed for for many years more.
How?
As with the fridge I decided to go for standard VSCP modules for the refrigerator project to make it a demo project. It is easier this time as I have the CAN4VSCP bus connected to the fridge that stands next to the refrigerator. I just need to connect the two together.
So I put in a Kelvin NTC10K module and a Bejing I/O module in the refrigerator and hook it up to the CAN4VSCP bus so I am able to monitor temperatures and change temperature settings and get possible alarms from the unit. As with all VSCP modules they form a self-contained unit. There is actually no need for a server after they have been configured. The second video here show the configuration process and the first show how the modules are connected together.
The Kelvin NTC 10K module is a module that one can connect a couple of temperature sensors to. It can be programmed to alarm at low and high temperatures and as in this case turn on and off things when certain temperature thresholds are reached.
In the fridge project a Paris module is used together with the Kelvin NTC module. The Paris module is constructed to control relays and have all the electronics on board to do that. It also include protection timers and a lot more.
In the refrigerator project I decided to use the Beijing module instead of the Paris module. Mostly because it did not matter to have standard I/O channels as I use a solid state relay to switch on and off the compressor, but my main reason was that I got a chance to use it in a real life demo system.
So the Kelvin NTC10K module sense the temperature in the refrigerator and the Beijing module is used to switch the compressor on or off and to sense if the refrigerator door is open or not and if it is light the lamp inside the box.
It is possible to sound s siren if the door to the refrigerator is opened between midnight and six in the morning. But some things just hit you right in the face so I will not implement that functionality. At least not now.
Next?
Connect cables and putting it in the refrigerator where the old control logic was located. No programming is needed just configuration. The second video above show a bit of this configuration but I will go through it in a more precise way in a future post. Hopefully things will work as thy should tomorrow. The VCSP modules are very flexible and can be used in most control situations to form self-contained systems that can be connected together and be connected to the world in a safe and secure way.
A new version, 1.2.6 of the firmware for Kelvin NTC10K has been released.
2016-03-30 AKHE – Made code work for PIC18F26K80
2016-03-29 AKHE – Raw A/D register values was displayed in wrong order. Fixed.
In the manual the sensor calibration part has been corrected and extended. It previously described the indexed calibration value version which was present in the first version of the module.
- The Paris module module firmware has been updated to version 1.1.5.
- The Kelvin NTC10K temperature module firmware has been updated to version 1.2.5.
- The Beijing I/O module firmware has been updated to version 1.1.5.
- The Accra counter module firmware has been updated to version 1.0.2.
- The Odessa expansion module firmware has been updated to version 1.0.2
- The Vilnius A/D module firmware has been updated to version 1.0.3.
Please update your module.
Instructions on how to update the firmware is available in the modules manual.
Some days I actually get some time to code. But not today. At least not a lot. Building Beijing, Vilnius and Kelvin NTC10K today. Beijing is our most selling product at the moment. Almost all go to Belgium and Netherlands. VSCP countries down there. Bright people.
By Ake Hedman
One day the fridge in our house died. Probably due to a recent thunderstorm. Panic of course and when I noticed that it was totally dead I bought a new one and saved the situation. The fridge was left in its location and later I realized that the control logic inside it was dead. I checked the obvious things but without a drawing it was not much I could do and buying a new board was in excess of EUR 250 so I decided to build my own control logic.
Well, I as most people, have a lot to do, so two years later I actually started the project. As my company build VSCP based modules I decided to use two of them for the project and by that way make it a reference project. I could have done this much easier probably with an Arduino or similar, after all it’s not a very complicated project, as a fridge is an easy thing to control. It is just basically turn on compressor when it’s to hot inside it and turn it off when the wanted temperature has been reached.
But as I said above my company makes control modules and I am the maintainer of the VSCP project so this could be a reference project for VSCP and our modules. That and to again to get a working fridge in the kitchen therefore became the goal of the project.
So that was the staring point. Join the journey.
Hardware assembly
Old control card
This picture shows the controller card after I removed it. A beeper, a transformer, a potentometer for the set temp, a boost button and some LEDs is all that it is.
As I am rather feed up with changing batteries in units all the time i prefer cables when ever possible. Therefore I decided to draw wires from my office up to the kitchen. I wanted an RJ-45 connector there anyway for Ethernet so I draw CAT-5 cables for that one, and another CAT-5 for the CAN4VSCP bus. Yes I could have used Ethernet for the fridge also of course. But I decided to use CAN4VSCP for demo/test purposes and because it have the advantage of having power included.
Office at the bottom floor and apartment at the top floor. in this old school house.
I live in an old school house (well this picture is old to) so putting in new cables is not a big deal. Just to make more holes in the walls and add more cables. It still is some work of course drilling in 30 cm solid wood walls but as I see it worth the effort it in the end and being an embedded programmer I need the exercise anyway.
Two modules from my company was the perfect choice for this job. The Paris relay controller that can control seven relays and the Kelvin NTC10K that can read six temperatures. Well it’s just one relay to control in this case and the relay I decided to use is a solid state relay that could have been used without the extra driving capabilities of the Paris module but it is really the functionality of the Paris module I am after. Same is true for the Kelvin NTC module. I don’t need the extra temperature measurements this module can offer but as it had the capabilities I decided to put a temperature sensor on the compressor of the fridge to check it for overheating as well and another sensor in the kitchen itself. It is also easy to connect more sensors if/when the need arise.
Testing the modules before mounting them.The Paris relay module to the left and the Kelvin NTC10K to the right with one NTC sensor connected.
All CAN4VSCP modules can be connected together (and be power) over the RJ-45 connector or over the daisy chain connector on the board. In a cabinet the daisy chaining is perfect and convinient. Here the CAN4VSCP cable is drawn from the office which is downstairs in our house. This cable also supply 24V power to the modules and is UPS protected at the source. The modules then are connected together using the daisy chain connector. For more boards one can use the CAN4VSCP power injector but that was not needed in this case with just two modules.
Paris in place and Kelvin NTC10K waiting to be mounted in the control logic part of the fridge.
Next step is t mount the boards in the control logic enclosure where the old control card where installed. I had to remove some plastic fittings for the old board but after that evrything was easy to mount.
Paris firmly mounted with the wall type mounting accessories for CAN4VSCP modules.
The boards my company sells have two mount options. Screw/wall mount or DIN rail mount. In this case I use the screw mount versions.
LED’s and solid state relay
Then it is time to mount the solid state really and some LED’s for status information. The LED’s show that the fridge is on, compressor status and a warning LED for low temperature. The solid state relay is a standard 230V/10A five volt controllable piece. Pretty standard gear.
LED’s, solid state relay and wall mounts for the two CAN4VSCP modules.
Then it was time to connect things together
Connecting things together
and mounting it all on the fridge
Time to drill a hole for the new fridge temperature sensor and mount it remembering to isolate well. The old sensor was mounted with some plastic stuff and I used it for the new one as well.
Then put back the plastic covers of the fridge and put it back in it’s place. Powering it. Yes dead so far. The boards has had not been configured yet so that was just what I expected. To be honest I would have need disappointed if the fridge started to work at this stage.
Connecting things
Drilling drilling drilling, cables, cables, cables till it all is down at the office.
A wall in the office used as test site.
So time to set things up down at the office. A power supply of course. 24V and connected to an UPS so things will work also if the power fails. Two CAN4VSCP modules and a Raspberry Pi is also mounter here on the DIN rail. As you see I expect more modules to be installed here later as the demo project goes on with other parts.
The modules I install here is another Paris relay controller module which I need for some light control. More about that in a later post.
The other module is Frankfurt RS-232 module which connects with the USB to serial converter that comes with it to a Raspberry Pi.
Note that the Raspberry Pi is powered from one of the CAN4VSCP modules. Plenty of juice for that in a CAN4VSCP module.
Software and configuration
On the Raspberry Pi is the VSCP Daemon installed. Instructions for setting it up on the Raspberry Pi is here. I use a read only file system to make things stable as documented on the linked page. The risk one face otherwise is a corrupted SD card when power fails which happens also when an UPS is used as in this case when disconnecting cables etc. I can really recommend that approach.
The Raspberry Pi is just used as a link between the CAN4VSCP bus and TCP/IP. But as documented later in this document it does some other work to. When the Frankfurt Eth board is available I will probably replace both the Raspberry Pi and the Frankfurt RS-232 with it. Time will tell.
The CAN4VSCP driver is used for the Frankfurt RS-232 module. The settings in the VSCP daemon configuration file looks like this
From the config string we can see that /dev/ttyUSB0 is the port used. This is what was assigned or the USB serial adapter. Use
ls /dev/ttyUSB*
to list available adapters. Normally the Frankfurt RS-232 adapter communicate using 11520 baud but the 5 in the configuration string tells that we here use 500000 baud in this setup. Speed is good.
The path to the driver is the standard place on a Linux box after installation of VSCP & Friends.
The flags value of 32 may need an explanation. This is a bit array so it may be easier to see it in binary form which is 0b00100000. That is bit 5 is set. Looking at the driver documentation CAN4VSCP driver we see that this means that hardware handshake should be enabled.
So nothing strange really. All we need to do to get things working is to restart the VSCP daemon with
/etc/initd/vscpd restart
whih will connect things to the world or to our local net.
But before doing that we can use the diagnostic feature of the Frankfurt RS-232 and see if we can see all modules on the bus. We can do this by using a terminal program on the Raspberry Pi. I use minicom (sudo apt-get install minicom) for my needs. Starting it with
minicom -b115200 -D/dev/ttyUSB0
will connect to the Frankfurt RS-232. If we issue
open
the connection to the CAN4VSCP bus will open. Issue
scan
to scan for available devices on the CAN4VSCP bus. In my case I got
I can see that I have the Kelvin NTC10K module at nickname = 1 and two Paris relay modules at nickname =2 and nickname = 3. The question is which module is which of the two Paris modules. The easiest way to determine this is to push the init. button on one of the devices which will make it go through the nickname discovery process and at the end show it’s discovered nickname. I used that method and found the the node with nickname=3 is the one installed in the fridge and the one with nickname=2 is the one installed in the office. I can change this of course but it really did not matter in this case.
A reader that is on his/hers toes notice that the GUID’s for two nodes are set to all FF’s which is wrong and not unique at all. I had to fix that at this stage. The reason was that I use nodes that are left overs from production and a GUID had never been set on these modules.
Knowing that the nodes are reachable and working makes things easier (and me happier). I restarted the VSCP daemon on the Raspberry Pi and could then do the rest of the configuration work on my desktop computer over TCP/IP and using VSCP works.
To setup VSCP for this task is easy. Use any Windows or Linux computer. I use Linux in this sample as that is my main working system.
Using VSCP Works t he first one has to do is to configure how we want to talk to the devices. There is two possible ways to do this. One is to talk directly to the driver. This means it must be connected to the computer on which you are located. So if we had the Frankfurt RS-232 connected to this computer we could have configured the CAN4VSCP driver in VSCP Works to connect to it and to the CAN4VSCP bus.
In this case the Frankfurt RS-232 is connected to a VSCP daemon on a remote device and this is the other way we can connect to it. So ee connect to it over TCP/IP and via the VSCP daemon on the Raspberry Pi. This works if the remote device is in another room as in my office or equally well if it where located on the other side of the earth. SSL is available for protection.
The configuration looks like this in VSCP Works
Basically the settings is the name we want to give this connection. The ip-address of the daemon and the port which usually is the VSCP assigned one (9598). Username and password and interface name. The interface name is important. You select it by choosing one of the available interfaces from the list you get when you click on the “Get Interface” button. This tells which interface you want to talk to on the remote daemon. After this is done you can connect to this location with all the tools available in VSCP Works.
The interface is important because we use nickname to talk to devices on a bus when usinge VSCP Level I. Many interfaces can be conected on a VSCP daemon and therefore the same nicknames will be present on multiple interfaces. In VSCP Level II where the full GUID is used this is no problem of course.
I can now use the configuration interface of VSCP Works and set register 3 to one. This will start the compressor of the fridge. And it did so it works. But we need to automate this. Making an autonomous system of it. This is one of the great advantages of VSCP. The possibility to leave out a central computer and by that a central point of failure. When things are configured a group of modules just work.
Configuring the Kelvin NTC10K
As the Paris relay module is dependent on the Kelvin NTC10K module for it’s work it was best to start to configure this module.
We want this module to send out temperature values with a certain interval so we can log temperature data. We also want it to send CLASS1.CONTROL, TurnOn events when the temperature is higher than a l high set point and CLASS1.CONTROL,TurnOff events when the temperature in the fridge is lower than a low set point.
Temperature sensors are connected like this
- Sensor 0: On board temperature.
- Sensor 1: Fridge temperature.
- Sensor 2: Compressor temperature.
- Sensor 3: Currently not used.
- Sensor 4: Temperature in kitchen.
- Sensor 5: Currently not used.
The compressor temperature should be reported with 10 second intervals. So we configure that by setting register 0x16 to 10 (0x0A). That is all we need to do for that sensor.
We do the same for the kitchen room temperature by writing 10 to register 0x18 so it also is reported every ten seconds.
And then we do the same thing for the fridge temperature by setting register 0x15 to 10.
This is all we have to do to get a system that report temperatures every ten seconds. In the picture above we see the sensor value for the fridge (-20.86 degrees Celsius). We can change the unit to Fahrenheit or Kelvin if we prefer that instead of the default degrees Celsius. For a logging system this is all we need to configure.
But this system should do more and for sensor 1, the fridge temperature sensor, we need to configure some more registers to get the functionality we wanted as of above.
We get the requested functionality by writing 0xB9 to register 3 which is the control register for sensor 1. 0xB9 is 0b10111001 in binary. An the functionality we set is
- 0b10111001 – Bit 0/1 – Report temperature in degrees Celsius.
- 0b10111001 – Bit 2 – Reserved not used.
- 0b10111001 – Bit 3 – Enable low alarm.
- 0b10111001 – Bit 4 – Enable high alarm.
- 0b10111001 – Bit 5 – Send TurnOn/TurnOff events instead of alarm.
- 0b10111001 – Bit 6 – Don’t invert meaning,
- 0b10111001 – Bit 7 – Continuous alarm.
The enable of alarms (Bit 3/4) makes it possible to get alarms when temperature goes over or below set points. Normally an alarm event is sent out and alarm bits set in the alarm register. It is however possible to get TurnOn/TurnOff events sent out instead at the alarm points. This is configured by setting Bit 5 to one.
Last Bit 7 is set to one which makes the alarm or in this case TurnOn/TurnOff being repeated very second as long as the condition is valid. This can be good to use as a precaution for communication errors.
There is no need with alarm points without setting them so we set the low alarm point by writing 0xff to register 0x34 and 0xFB to register 0x35 which is the 16-bit register for the low alarm point in degrees. This is equal to -21 degrees Celsius which is the lowest temperature we want the fridge to have.
We also write the high alarm point by writing 0xFF to register 0x40 and 0xED to register 0x41. This is equal to -19 degrees which then is the highest temperature we accept.
We should note here also that there is a hysteresis value for alarms that default to two degrees. That is an alarm condition is valid until the temperature goes either above the low set point with that amount or below the high set point with that amount. This is why the low and the high temperature set points are two degrees apart. It is possible to set them further apart but always equal to more the the configures hysteresis.
So what have we accomplished here now?
- If the temperature is higher than -21 degrees Celsius continuous TurnOn events (one very second) will be sent out until the temperature has reached -21 degrees Celsius.
- When the temperature goes below -21 degrees Celsius continuous TurnOff events (one every second) will be sent our until it goes up to -19 degrees Celsius.
- We get temperature events sent out every ten seconds telling the actual temperature for three sensors.
Before we start to configure the Paris relay module we need to configure one more thing.
When events are sent all of them except CLASS1.PROTOCOL is sent without a destination address. The receiver decides if it is interested in the event or not. As a means of grouping things together zones and subzones can be used. They are both 8-bit identifiers that define a zone and a subzone within that zone. Its good to set up a schema for a specific setup and here in my house I use the following
- The zone is divided into two 4-bit parts. The high part is the floor plane. 0=cellar, 1=office, 2=Apartment, 3=Attic, 4=Garage…
- The rooms is then coded into the lower four bits of the zone.
- A zone=255 always mean all zones.
- Subzone is used for specific group of things in a room that needs to be grouped or be identified. A sunzone=255 always mean all subzones.
So the fridge, which is at in the apartment, the zone is 0x22 as the kitchen is coded as 2 and the fridges s set to subzone=1.
So we program that in for the sensors as well. Register 0x4D holds the zone for sensor 1 and register 9x4D holds the subzone. We use the same setting for the other sensors as well but it really only matters at this point for sensor 1.
We used the default NTC 10K sensor with this setup so the B value for the sensors are already set. If we have used another sensor we needed to code this value for all sensors as well. For best precision we also could have programmed a calibration value but a fault of about one degree is OK in this setup. Information about all Kelvin NTC10K registers is available in the manual.
Configuring the Paris relay module
The Paris module has one task to perform. It should turn on the relay when told to do so and turn it of when told to do that. Simple enough. With a server in the system it could have written a one in register 3 of the module to turn on the compressor when the temperature was to high and turn it of by writing a zero into register 3 when the set temp is reached. But we want this to work in an autonomous way without a server so we need to set this up.
We again start with the control register for relay 1 which is connected to the solid state relay which driver the compressor. This is register 0x0B and the default value is actually OK here so it is no need to change it but we go through the bits and there meaning anyway. The full Paris relay controller manual is here.
The programmed byte is 0x98 which in binary is 0b10011000 and have the following meaning.
- 0b10011000Bit 0 – Set to zero no pulse output activated.
- 0b10011000 Bit 1 – Set to zero so no alarm. The protection timer is not used anyway in this sample.
- 0b10011000 Bit 2 – Set to zero meaning protection timer is disabled. This timer can be used to automatically turn of a relay after a configurable time and optionally send an alarm when doing so.
- 0b10011000 Bit 3 – Set to one so an CLASS1.INFORMATION, ON-event will be sent when the relay is activated.
- 0b10011000 Bit 4 – Set to one so an CLASS1.INFORMATION, OFF-event will be sent when the relay is deactivated.
- 0b10011000 Bit 5 – Set to zero no CLASS1.INFORMATION, Start-event is sent.
- 0b10011000 Bit 6 – Set to zero no CLASS1.INFORMATION, Stop-event is sent.
- 0b10011000 Bit 7 – Set to one which enables functionality.
The only interesting for us here is that we get confirmation events when relays are activated/deactivated.
We set zone/subzone info here also just as we did for the Kelvin NTC10K. Again we use zone=0x22 and subzone=1 which groups the two modules together, saying this is events belonging to the fridge in the kitchen on the apartment floor.
But still nothing happens. The Paris relay module will just disregard the TurnOn/TurnOff events sent out from the Kelvin NTC 10K.
The solution is to program the Decision Matrix (DM) of the Paris module. This matrix is a event-decision-action matrix. That is when an event is received, a decision is made if it is useful and if so a specified action is performed. Every VSCP module with a DM implemented have a series of well defined actions specified. So what we need to do is to program what should happen when the TurnOn event is received from the Kelvin NTC10K module and likewise what should happen when the TurnOff event is received.
In this case the task is straight forward.
- TurnOn received: We need to activate the relay.
- TurnOff received: We need to deactivate the relay.
The tool to use is as always VSCP Works and the configuration view and the Decision Matrix tab. Double clicking a row here makes it possible to edit the row
The first row is used to turn on the relay. We specify that the zone and the subzone should be the same as we programmed for both of the modules (zone=22/subzone=1) by selecting that zone and subzone should be checked. In the class mask and filter we set the class mask to 0xff meaning all bits of the class filter are valid. Then we set the class id for the TurnOn event into class filter which is 0x1E. This means that when a CLASS1.CONTROL(x1E), Type=TurnOn(0x05) event with zone=0x22 and subzone 0x01 is received the action we choose here will be performed. In this case we want it to activate relay one which is the second relay channel, that is bit 2. So we select “Activate relay(s)” for action and put 0x02 as action parameter meaning relay 1 (bit 1 is set) using zero offset.
We know do the same thing on the second DM row but now trigger on TurnOff which is CLASS1.CONTROL(0x1E), Type=TrunOff(0x06), And we select “Deactivate relays(s)” as action instead.
That’s it. We have now created our autonomous fridge control.
In the above picture we see how things looks like in the working system when the temperature inside the fridge is below -21 degrees Celsius. The Kelvin NTC 10K send the TurnOn event every second and the Paris relay node replies with an ON-event for all of them indicating it has done the requested relay activation. Most of the time the relay is already on but if it was not it would have been turned on. With ten second intervals temperature events for the sensor are sent and highlighted here is the fridge sensor which is at this point is about -20 degrees Celsius.
This picture show the events when the temperature has been reached. And this is therefore the message stream that will be visible until the high set point has been reached. Here TurnOff events are sent every second from the Kelvin NTC10K module and the Paris relay module respond with an OFF event when the relays has been turned off or is already off.
Extensions is alarms such as sounding an alarm when the fridge temperature goes above a certain value and/or sending an SMS informing of the condition. I will come back to these extensions later in another post.
If you want to look at the register content or copy it to your own modules the register files for the sample are here
The easiest way to view the files is to open an empty configuration session and load the file there.
Logging data
It may be useful to log data into a database or similar for later use. Here I use a MySQL database located in the cloud for this purpose. It can be a local database equally well of course.
One way to do this is to use the VSCP helper lib with your favourite programming language and write some code that performs this. It is usually just a few lines of code for a simple task like this.
Another way is to use the capabilities of the internal decision matrix of the VSCP daemon. This is a more powerful decision matrix than the simple one that is available on low end VSCP modules. It however works mostly the same as every event received by the VSCP daemon is feed through this matrix and is able to perform an action when it matches some criteria.
The decision matrix of the VSCP daemon can be edited in the configuration file/dm.xml file which resides in /srv/vscp on Linux (ProgramData\vscp on windows) or it can be edited in the web interface of the VSCP daemon which is at http://ip-address:8080/vscp. The web interface is the easiest way to use IMO. If you edit the dm.xml file directly remember to restart the VSCP daemon so that the new file is read.
This is how the DM row look like to log data to an external MySQL database with a database structure defined as below
The table definition can be downloaded here with 200 sample records.
The action used in this case is 0x10 which executes an external program on the machine where the VSCP Daemon is installed.
In the web interface the DM list looks like this
If we click on this we get the content for this DM row
If we walk through the parts of it
- groupid – This is any textual id you want to use to group a number of rows together. It is mainly intended for use by external applications that work with the DM.
- priority – Let you set a specific priority you are interested in. The left part is the priority and the right part (blue) is the mask. The mask tells what bits in the left column that is of interest. Set to zero (default) if non is interesting or 0xFF if all is interesting. Here we do not care about the priority and therefore set the mask to zero meaning events with all priorities will trigger this row condition.
- class we recognize from the DM in the decision matrix of the modules. Again the left part is the class and the right part (blue) is the mask. The main difference here is that the class is a 16-bit number. If you are interested in events of a specific class enter the class in the left field and set the mask to 0xFFFF (default). If you are interested in events of all classes set the mask to zero (don’t care). Here we are only interested in CLASS1.MEASUREMENT which is coded as 10.
- type we also recognize from the DM of the lower end modules. Again it is 16-bit here. If you are interested in events of a specific type enter the type in the left field and set the mask to 0xFFFF (default). If you are interested in events of all types set the mask to zero (don’t care). Here we are only interested in CLASS1.MEASUREMENT, Type=6, Temperature which is coded as 6.
- GUID – The nickname we saw earlier is just that, a nickname for a full GUID. The nickname is there to save bandwidth so the full GUID does not have to be used. Every node have a GUID and also every interface of the VSCP daemon gor one. In the case of an interface the nickname will be repeated in the LSB byte of the GUID and we see here that the GUID LSB is set to 1 which was the nickname for our Kelvin NTC 10K node and the corresponding mask is set to 0xFF with all other bytes set to zero. So all events from modules with nickname = 1 will be fulfilling this requirement. This is OK as we just have one interface on the test machine but we would have needed to check more bytes of the GUID in a real world scenario where there was more interfaces used.
- Index – Here we can check for the content of the first data byte of an event or check the measurement sensor index. In this case we don’t need this check. Corresponding control checkbox must be checked for the check to be performed.
- Zone – Here we can accept only events with zone set to a specific value. We don’t use this in this example. Corresponding control checkbox must be checked for the check to be performed.
- Subzone – Here we can accept only events with subzone set to a specific value. We don’t use this in this example. Corresponding control checkbox must be checked for the check to be performed.
- Control checkboxes – You can enable the DM row here, you can tell the parsing mechanism that this is the last row that should be checked which can be good for certain debugging. You can also enable check index, check zone and check subzone here. If check index is checked together with the “Use measurement index” to the right of the index input field the measurement index is used for the compare instead of the index byte (byte 0) of the data.
- Allowed from – is the time from which the action is allowed to occur. The format is YY-MM-DD HH:MM:SS. In the web interface ‘*’ can be entered to mean “beginning of time” or any date far back in time.
- Allowed to – This is the end time up to which the action is allowed to occur. The format is YY-MM-DD HH:MM:SS. In the web interface ‘*’ can be entered to mean “end of time” or any date far in the future.
- Allowed Time – This makes it possible to make actions happen every ten minutes etc etc. See the documentation for full info. All times is *-*-* *:*:* As an example *-*-* *:*:0/10/20/30/40/50 will allow he action to occur every ten seconds.
- Allowed day – Days when the action is allowed to occur. Here every day.
- Action – Is the action to perform. There are many available. See the documentation. Here we execute an external program.
- Action Parameter – What is entered in this fields depends on the chosen action. For execute external program the command to execute and parameters for that command is entered. Here we call the mysql client.
- Comment – Here a comment about the DM row can be entered.
Lets look a bit closer at the action parameter. Most of it is pure SQL and we will not go through that. But we have some items with a percent in front of them that are of interest. When action parameters are feed to the DM certain keywords (words starting with %) will be replaced by something else (they are escapes). In our expression we have
- %event.guid – Which will be replaced by the full GUID of the event that triggered this action.
- %measurement.index – Which will be replaced by the measurement index of the sensor that triggered this action.
- %isodate – Will be replaced by the current date on the form YY-MM_DD
- %isotime – Will be replaced by the current time on the form HH:MM:SS
- %measurement.float – Will be replaced by the measurement value as a floating point value.
There are of course a lot of other escapes available. The full list is here.
I think you understand what will happen. Real floating point values will be written into the database with real date/time stamps and GUID and sensor index to identify the sensor that originated the measurement.
I hope its also clear that if you have an executable that can control something you will be able to control that ‘thing’ with the VSCP daemon.
Sending data to the cloud – method one.
ThingSpeak is a popular and free cloud service for visualisation and handling of measurement data. There are probably about ten thousand more services like it. Search. You can use ThingSpeak to, among other things, show real time diagrams of your data.
This is how it looks for the sensors from the fridge. Lets go through each of them before we explain how to generate them
The first diagram is data from the Kitchen temperature sensor, that is temperature sensor 4 of the Kelvin NTC 10K board.
The second diagram is the fridge temperature. That is data from temperature sensor 1 of the Kelvin NTC10K. We see that it works as expected and stays in the interval -21 — -19 degrees Celsius.
The third diagram is the compressor temperature. That is temperature sensor 2 of the Kelvin NTC10K.
The fourth diagram just shows when the fridge compressor is on or off over time.
Sending data to ThingSpeak can be done using HTTP POST or HTTP GET. The syntax for GET’s are
GET https://api.thingspeak.com/update?api_key=xxxxxxxxxxxxxxxx&field1=0
and for POST’s
POST https://api.thingspeak.com/update.json api_key=xxxxxxxxxxxxxxxx field1=73
xxxxxxxxxxxxxxxx is a key you get from ThingSpeak when you create a channel.
We will use POST in this sample.
Curl is a program that can be used to send HTTP data and is which is quite easy to understand and use so I decided to use it for this demo.
To do what we need we issue a command like this in curl
curl –request POST –header “X-THINGSPEAKAPIKEY: xxxxxxxxxxxxxxxx” –data “field1=20.5” “http://api.thingspeak.com/update”
which will update field1 with the value 20.5 using the current date/time.
To be able to handle all sensors with one external command I made a script thingspeak.sh that looks like this
#!/bin/sh
# Arguments
# =========
# 1 – Write key
# 2 – Filed number 1 .. n
# 3 – Value
#echo() { :; } # comment line to enable debugging
update=$(curl –silent –request POST –header “X-THINGSPEAKAPIKEY: $1” –data “field$2=$3” “http://api.thingspeak.com/update”)
echo “Update #$update”
You can download this script here. Remember to make the script runnable before using it (sudo chmod a+x thingspeak.sh).
The script takes three parameters
- $1 – This is the TingSpeak key.
- $2 – This is the field number to update. 1,2,3,4…
- $3 – This is the value to write into the field.
All we have to do now is to add the rows to the decision matrix of the VSCP daemon that call this scripts when temperature events are received.
<row enable=”true” groupid=”” >
<mask priority=”0″ class=”0″ type=”65535″ GUID=” 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:FF” > </mask>
<filter priority=”0″ class=”10″ type=”6″ GUID=” 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:01″ > </filter>
<control>0x20</control>
<action>0x10</action>
<param>/srv/vscp/thingspeak.sh xxxxxxxxxxxxxxxxxxx 1 %measurement.string
<comment>Send value for Room temperature</comment>
<allowed_from>0000-01-01 00:00:00</allowed_from>
<allowed_to>9999-12-31 23:59:59</allowed_to>
<allowed_weekdays>mtwtfss</allowed_weekdays>
<allowed_time>*-*-* *:*:*</allowed_time>
<index bMeasurement=”true” > 4</index>
<zone>0</zone>
<subzone>0</subzone>
</row>
This row update field1 and is thus the event from the sensor that measure the kitchen temperature.
<row enable=”true” groupid=”” >
<mask priority=”0″ class=”65535″ type=”65535″ GUID=” 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:FF” > </mask>
<filter priority=”0″ class=”10″ type=”6″ GUID=” 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:01″ > </filter>
<control>0x20</control>
<action>0x10</action>
<param>/srv/vscp/thingspeak.sh xxxxxxxxxxxxxxxxxxx 2 %measurement.string
<comment>Send vaule for fridge temperature</comment>
<allowed_from>0000-01-01 00:00:00</allowed_from>
<allowed_to>9999-12-31 23:59:59</allowed_to>
<allowed_weekdays>mtwtfss</allowed_weekdays>
<allowed_time>*-*-* *:*:*</allowed_time>
<index bMeasurement=”true” > 1</index>
<zone>0</zone>
<subzone>0</subzone>
</row>
This row update field2 and is thus the event from the sensor that measure the fridge temperature.
<row enable=”true” groupid=”” >
<mask priority=”0″ class=”0″ type=”65535″ GUID=” 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:FF” > </mask>
<filter priority=”0″ class=”10″ type=”6″ GUID=” 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:01″ > </filter>
<control>0x20</control>
<action>0x10</action>
<param>/srv/vscp/thingspeak.sh xxxxxxxxxxxxxxxxx 1 %measurement.string
<comment>Send value for Room temperature</comment>
<allowed_from>0000-01-01 00:00:00</allowed_from>
<allowed_to>9999-12-31 23:59:59</allowed_to>
<allowed_weekdays>mtwtfss</allowed_weekdays>
<allowed_time>*-*-* *:*:*</allowed_time>
<index bMeasurement=”true” > 4</index>
<zone>0</zone>
<subzone>0</subzone>
</row>
This row update field3 and is thus the event from the sensor that measure the compressor temperature.
For the compressor on/off diagram we need two Decision matrix rows.
<row enable=”true” groupid=”” >
<mask priority=”0″ class=”65535″ type=”65535″ GUID=” 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:FF” > </mask>
<filter priority=”0″ class=”20″ type=”3″ GUID=” 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:03″ > </filter>
<control>0x18</control>
<action>0x10</action>
<param>/srv/vscp/thingspeak.sh xxxxxxxxxxxxxxxxx 4 1</param>
<comment>Record compressor ON</comment>
<allowed_from>0000-01-01 00:00:00</allowed_from>
<allowed_to>9999-12-31 23:59:59</allowed_to>
<allowed_weekdays>mtwtfss</allowed_weekdays>
<allowed_time>*-*-* *:*:*</allowed_time>
<index bMeasurement=”false” > 0</index>
<zone>34</zone>
<subzone>1</subzone>
</row>
The first row records ON events received from the Paris relay module and writes a one to filed4 when they are received. That is whene the compressor is active.
<row enable=”true” groupid=”” >
<mask priority=”0″ class=”65535″ type=”65535″ GUID=” 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:FF” > </mask>
<filter priority=”0″ class=”20″ type=”4″ GUID=” 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:03″ > </filter>
<control>0x18</control>
<action>0x10</action>
<param>/srv/vscp/thingspeak.sh xxxxxxxxxxxxxxxxx 4 0</param>
<comment>Record compressor OFF</comment>
<allowed_from>0000-01-01 00:00:00</allowed_from>
<allowed_to>9999-12-31 23:59:59</allowed_to>
<allowed_weekdays>mtwtfss</allowed_weekdays>
<allowed_time>*-*-* *:*:*</allowed_time>
<index bMeasurement=”false” > 0</index>
<zone>34</zone>
<subzone>1</subzone>
</row>
The second row records OFF events received from the Paris relay module and writes a zero to filed4 when they are received. That is when the compressor is inactive.
That’s it. Not so complicated is it? You can use this method for most other cloud services as well.
Sending data to the cloud – method two.
As we wrote earlier the VSCP daemon have many more actions available than the execute external program we have used so far. One that is perfectly suited for sending data to a cloud service is the HTTP GET,POST,PUT action.
If you follow the link you will find two examples. The first use POST to update a field on ThingSpeak and the second use GET.
What method you chose is much a matter of preference.
Sending timed data using variables
If you look at the sample above you have learned that we can do timed actions as well using the VSCP daemon decision matrix. That is running an action every minute, very second or every hour or whatever. That is mor or less just like cron on a Unix/Linux system. This is possible using the internal events of the VSCP daemon. The events in this class is feed into the DM on regular intervals or when special things occurs.
So if we want to send data to a cloud service every minute we can trigger on the CLASS2.VSCPD, Type=6, Minute event. This event is generated once every minute. Now if we want to send updates to the cloud service every minute we have a problem if the sensor, as for the fridge in this example, updates every ten seconds.
The solution is to firts write the sensor value to a variable when the temperature event is received.
<row enable=”true” groupid=”” >
<mask priority=”0″ class=”65535″ type=”65535″ GUID=” 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:FF” > </mask>
<filter priority=”0″ class=”10″ type=”6″ GUID=” 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:01″ > </filter>
<control>0x20</control>
<action>0x50</action>
<param>fridgetemp;float;false;%meaurement.float</param>
<comment>Store fridge temperature in variable</comment>
<allowed_from>0000-01-01 00:00:00</allowed_from>
<allowed_to>9999-12-31 23:59:59</allowed_to>
<allowed_weekdays>mtwtfss</allowed_weekdays>
<allowed_time>*-*-* *:*:*</allowed_time>
<index bMeasurement=”true” > 1</index>
<zone>0</zone>
<subzone>0</subzone>
</row>
This is how this looks for the fridge temperature sensor. Action is 0x50 which is “store in variable”. This action is documented here. According to the documentation the action parameter format is
name-of-variable;variable-type;persistence;value
So we can create/write a variable fridgetemp with
fridgetemp;FLOAT;false;%meaurement.float
That is the floating point measurement value is written to the non persistent floating point variable “fridgetemp” every time the temperature event from sensor 1 of the Kelvin NTC10K sensor in the fridge is received. We can use this variable from other programs.
Now all we have to do is to send this variable to the cloud service every minute.
<row enable="true" groupid="" > <mask priority="0" class="65535" type="65535" GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" > </mask> <filter priority="0" class="65535" type="6" GUID=" 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" > </filter> <control>0x0</control> <action>0x75</action> <param>POST;http://api.thingspeak.com/update;field1=%variable:fridgetemp;X-THINGSPEAKAPIKEY: xxxxxxxxxxxxxxxx\n</param> <comment></comment> <allowed_from>0000-01-01 00:00:00</allowed_from> <allowed_to>9999-12-31 23:59:59</allowed_to> <allowed_weekdays>mtwtfss</allowed_weekdays> <allowed_time>*-*-* *:*:*</allowed_time> <index bMeasurement="false" > 0</index> <zone>0</zone> <subzone>0</subzone> </row>
The new item here is the escape
field1=%variable:fridgetemp
where %variable:fridgetemp is replaced by the content in the variable fridgetemp.
VSCP has it’s own functionality for tables and diagrams. We will continue this demo with some samples of this functionality on a later time.
To be continued…
Hope you found this writeup useful.
/Ake
Paradise of the Frog AB
The manual for the Kelvin NTC10K temperature module is now available in web format as the rest of the manuals.
The product page is here.
A Kelvin NTC 10K node and a Paris node sitting on a DIN rail on a desk in the lab. But why does that red LED blink?