📜 ⬆️ ⬇️

Creating a smart home and developing your own protocol

I must say that the post is focused more on ordinary people than on those in the subject, and is rather a report of what I have been doing in recent days.

I decided here to score on all the work and do something for the soul. Again took up the soldering iron. I decided to automate everything at home. In the old apartment I had a smart house or something like that - could turn on the lights in the room via the Internet and all that.

This time I decided to take into account my mistakes. The main problem was that before I had one device responsible for everything, to which temperature, movement, display, buttons, and other sensors were connected. All this was great, but in the end, the device performed only the functionality that was originally incorporated into it. It was impossible so easy to take and connect some kind of sensor without modifying this device.
')
It was decided that it is better to do a lot of separate devices, each of which is responsible for a strictly specific task, having the ability to easily connect them to a common network. And so that each device has an address and its own set of commands. Something like CAN-bus in modern cars. At the same time, I want the network to be decentralized, without a master device, so that everything can be connected over a single wire, easily realized without buying an additional controller, and so that the long wires were not a problem.

On board the microcontroller there are all sorts of I²C, yes UART, but they clearly do not satisfy the conditions. As a result, it was decided to develop your bike protocol.




There are dominant and recessive signals, as in CAN. In the case of wires (who knows, maybe I will also use radio or infrared light) the dominant one is pressing the data line to the ground. In the normal state, the data line has a pull up to + 5V. Thus, when the device sees that the line is already pressed to the ground, it understands that some other device is already sending data, and is waiting for the line to be released. The data itself is encoded by the length of the dominant signals. 1T is zero, 3T is one, the pause between them is 1T. Each transmission begins with initialization as a long signal at 10T. After numerous experiments on a microcontroller centipede ...



... I decided that the optimal value of T = 0.000064 seconds. At the same time there are no losses (almost?). I do not think that a large amount of data will be transmitted over this network. Print messages from Twitter to display in the toilet if only.

The data packets themselves have the following structure: 2 bits of packet priority (in case the devices send them simultaneously, which is very unlikely), 8 bits - the sender's address, 8 bits - the recipient's address (0xFF - broadcast), 8 bits - the command number , 8 bits - the length of the data field in bytes, the corresponding number of data bytes and 8 bits - the checksum, where without it.

The result was a library that implements work with this protocol entirely at the interrupt level. Those. It turns out such a multitasking from the point of view of the rest of the program. It is enough to perform initialization once, and the microcontroller will respond to pings, even if the main program has entered an infinite loop. It does not hang, even if the line is busy when sending a packet, the library sends it as soon as the line is released. And when a package is received at its address, the specified function is called.

Thus, to connect a new device to the network, it is enough for me to simply configure the library, specifying the microcontroller’s feet, address and name.

We must pay tribute to one small box. I don’t have a normal oscilloscope, but a few years ago I ordered the cheapest oscilloscope on USB for a computer on ibei. Total at 1MHz. When I received it and tried it, I decided that it was useless Chinese consumer goods, and in vain I threw out the money, and put it in the back box. And now I decided to get it ... If it were not for him, I probably would still debug all this. And on it everything is immediately visible and understandable.



It turned out to sit down from three wires - earth, power and data. Yes, I didn’t want to mess around with the power supply of each device, so I decided to bring 9-12 volts of direct current everywhere, and on each device I would have to install a banal SUMMER.

However, this entire network still needs to be somehow connected to a computer and the Internet. To do this, I first made a device to the COM port:



This thing worked frankly bad. And why I did not decide to do right on USB? I do not know. Later, the FT232 microcircuit was purchased. Essentially in a QFN package.



For the first time soldered QFN case. It did not work out right away, the board was already blackened from overheating. But it worked! I stuck this thing into the router, because it works around the clock, and I need to communicate not just with the computer, but also with the Internet.



In a router as usual Linux. After small dances with a tambourine, it turned out to suck my device to him. Then I had to remember programming skills under the Nix. The task was not so difficult - to share a virtual COM port on the network with the ability to connect to it simultaneously several clients. Then I made it so that when I receive each packet, a simple script is executed. Thus, you can easily force the router to respond to various events by simply changing the shell script, without restarting the daemon. Then I did more work with the fifo pseudo-file, which gave me the opportunity to send packets to the network directly from the command line. For example, the command: echo "04010803"> fifo sends a packet with priority 04 to device 01 with command 08 (relay control) and data 03 (turn on the 1st and 2nd lamps). Of course, I don’t need to type all this manually, but it makes it much easier to write scripts that automate everything. Under Windows, a library was written that connects to the daemon on the server and receives / sends packets. There is no full-fledged software yet, but I can already turn on the lights in the room, TV and receiver with hot keys on the keyboard, which makes life much easier.

But then I decided to write my own bootloader. I can’t imagine how I could do without him. It allows you to update devices firmware right on my network! This is a small program that sits at the end of the microcontroller's memory and runs before the main program. Her whole task is to submit signs of life, and then either launch the main program after a few seconds, or download and update the firmware if such a command arrives. With great difficulty, I put all this code in one kilobyte. The score went literally bytes. Only the very basis is implemented - no checks on the freeness of the line, expectations and other features. Only data transfer and checksum verification, but for the loader this is quite enough. How great it is to save every byte of memory, work directly with registers, optimize the code to the full ... Low-level programming just brings a lot of fun =)

For the company, I wrote the corresponding command line utility, which sends the device a reboot command, a command to switch to the firmware mode and the firmware itself. Just write it in the project's Makefile, and ...



By pressing one key in Programmer's Notepad, I can update the firmware to any working device in my apartment. Without disconnecting, without a soldering iron, without leaving your computer. And the whole process takes 10-20 seconds. It's just mega-easy. The configuration of some devices is much easier to change, changing the firmware itself, than to provide everything in advance. For example, add to the wall switch response to broadcast packets sent by the remote control receiver, which now allows you to turn on the chandelier from the remote from the DVD player. I remind you that the presence of a wizard is not required for this, the devices communicate with each other directly :) At the same time, you cannot kill the device with unsuccessful firmware - the bootloader always starts earlier. Now it is enough to flash each device with a simple template, making minimal changes (legs and device ID), after which you can safely put it in its place, and then start writing firmware for it :)

Now I already have six devices in my network, and so far everything is working perfectly :) There were problems only with noise in the power supply, but again my oscilloscope saved me. It will be necessary to buy a full.

upd:
GitHub project: github.com/ClusterM/clunet

Source: https://habr.com/ru/post/160469/


All Articles