"Like the apple of an eye ..." or make a simple security system based on a microcontroller (Canny or Arduino) and Raspberry PI

During the preparation of the article about the recognition of microcontrollers using TensorFlow and OpenCV, Craftduino, Canny 3 tiny and Raspberry PI caught my eye at the same time, after which I decided it would be great to combine them again in one article. I thought for a long time about what to write about, and then I am ashamed to admit, I remembered that I was a healthy uncle, and I had never connected anything via UART yet. “Everything needs to be tried in life,” I thought. But writing only about connecting to UART is boring, so all sorts of “toys” were immediately ordered, among which were the brand new Arduino, and a couple of sensors.

So, today we will make a security system for my favorite pen. Are you surprised why a pen? The secret is simple, I’m very inexperienced in all kinds of electronics matters, and therefore, when I ordered the pressure sensor, I thought that it would work over the entire area, but it turned out that it works only for a specific contact area. Oddly enough, but in the whole house there was nothing weighty enough, stable and suitable in size, except for this pen. Well, except for my finger, but I was not ready to experiment with it .

In the article, I will share my experience of connecting a pressure sensor and a Doppler motion sensor to microcontrollers. We will connect the controllers via the wired UART interface to the GPIO Raspberry PI 3. Then we will write a simple program to Python to display the status of the security system, and at the end we will connect the smartphone to the raspberry using VNC to monitor the security system at a distance from the computer.

Want to leave Indiana Jones out of work? Then you are welcome under cat.



As always, at the beginning, I will explain that I myself am new to DIY electronics issues and am slowly learning from article to article. Therefore, do not perceive what I will write as the ultimate truth. Surely everything can be done better.

Here's what we'll talk about today:

Part I: Introduction
Part II: Connecting the circuit and program for Canny 3 tiny
Part III: Connecting the circuit and program for Arduino Uno
Part IV: Raspberry PI and the monitoring program in Python
Part V: Conclusion

Part I: Introduction


An attentive reader may ask, “Why did you buy Arduino if you mentioned CraftDuino before?”, Everything is very commonplace. CraftDuino broke again. OnceDrzugrikI repaired it, and now it’s "self-isolation", and I didn’t want to disturb a person for nothing.

So, we smoothly approached the material base. For this article, I used:

  1. Pressure Resistor FSR402:


  2. Doppler motion sensor RCWL-0516:


    In the store where I bought both sensors in the description on the site it was written that they were for Arduino, but in practice it turned out that no special libraries were needed and everything started without problems on Canny.
  3. Microcontroller Arduino Uno:


  4. Canny 3 Tiny microcontroller - version with terminal block and cable harness:


  5. Raspberry PI 3 Model B Single Board Computer:

  6. Other: Breboard breadboards, crocodile wires and clips, Raspberry power adapter

Let's get down to business.

Part II: Connecting the circuit and program for Canny 3 tiny


There are many examples on the Internet how to connect Arduino via UART, there are much fewer examples about Canny, so let's start with it.
In order not to inflate the length of the article and not repeat myself, I remind you that I considered the most basic issues of how to work with Canny and the CannyLab development environment in this article , and an example of connecting sensors to an analog-to-digital converter (ADC) and transmitting a message via Virtual COM port, I made out in this article .

For those who do not read this, but immediately try to connect the sensors to the ADC, there is an important point. Do not repeat my mistake, in order for the outputs of the controller No. 5 and No. 6 to work in the ADC mode, jumpers must be set, as in the picture below. It’s not difficult, even I did it.


And another important point at the controller outputs will be the supply voltage, that is, if you connect from an external power source instead of USB, make sure that the output voltage does not exceed the allowable voltage for sensors and UART.

For this article, one jumper would have been enough for us, but if we got a soldering iron, why should we waste time on trifles?

Pay attention to the terminal block, the native cable harness comes standard for this version of the controller, it is tough and probably convenient if used inside the car, but not for experiments at the table. I came up with the know-how, replaced the native harness with harnesses that are often bundled with computer equipment, well, or sold in stores selling DIY electronics and it turned out to be very convenient. They do not sit badly in the block, soft and at the same time give additional lengthening.

Let's move on to the connection diagram:


Everything is quite simple and does not require any special skills, I think almost anyone can handle it.

First, let's deal with the power of the board. We will take the “ground” from the “-” output of the controller, but with the plus, everything is not so clear. At first glance, it seems logical to connect to the “+” terminal, but in practice it is apparently a terminal for + 5V INPUT. Therefore, instead of it, we will configure one of the outputs as a + 5V output, supplying a logical unit to it and pulling it to the “plus”. I decided to take exit number 3.

The pressure sensor is connected very simply. In fact, this is a resistor. We bring power to one of its “legs”, and from the second “legs” we wind the wire to the controller input connected to the ADC (either No. 5 or No. 6). I chose No. 6.

By the way, I lost the pressure sensor twice. My second mistake was connecting the sensor. It does not fit into the breadboard, it turns out that it must be connected to a screw terminal block or something similar. I had to get out with the "crocodiles".

The motion sensor is not connected much more complicated, we put + 5V from the board into the Vin jack, connect it to the GND jack on the breadboard, and connect the OUT jack to any digital input of the controller, I connected it to output No. 5 (we we will not switch it to ADC mode).

It remains to connect the controller to the "Raspberry" through UART. To do this, controller output No. 2, which in our UART mode becomes the TX output, must be connected to the Raspberry GPIO RX input, and the ground on the board and the Raspberry PI GPIO GND must also be connected.

Many people advise coordinating the voltage level to 3.3 V, and I even tried to connect Canny through a voltage divider, but it works worse with it than without it (or doesn't work at all), so in this case I connected directly to the Raspberry UART. It seems that nothing burned out. Everything is working.


Perhaps you had the thought: “Why is it connected” with wires to the UART, when possible via Bluetooth? ” Indeed, there are many examples of connecting Arduino through the UART to the HC-06 module on the network. If you believe the forum , then Canny also connects to it without problems. But I have not tried it myself. I wanted to connect using wires, and I decided to postpone the Bluetooth connection until next time.

Here's what the circuit looks like:


Let's move on to the program for the controller (diagram):


In the "Parameter Setting" block , we turn on the ADC mode for channel (input) No. 6, transfer channel No. 3 to discrete output mode and feed in a logical unit (+ 5V in our case), almost everything was analyzed in this article .

Only UART settings are unfamiliar to us. Fortunately, everything is simple. Canny 3 tiny has only 1 UART interface (for example, Canny 7 has two of them). When the UART mode is activated, output No. 1 becomes RX, output No. 2 TX. We will choose the usual 9600 baud rate, but the data transfer mode is limited. The available number of data bits is only 8 bytes and 1 stop bit (for “older” controller models there is more choice). In order to enable UART, it is necessary to enter the UART1 config register in the corresponding register write a predefined constant:


In fact, in our case it was possible to choose a constant that included only the UART transmission mode, because we do not plan to take anything back. But I decided to show a more general example.

If you selected the correct controller when creating the diagram, then CannyLab will not allow you to choose the constant that would not suit him. Therefore, choosing a knowingly dangerous mode does not work. The truth is always the opportunity to enter a constant manually, but it’s better not to do this.

We will send 10 characters in the message (including 2 problems), so we will write a constant equal to 10 in the message register.

I’m not sure about 1 TX lift to one, but just in case I turned on this item, as I understand it, I need it Do not tighten with a resistor.

In block“Periodic sending via UART and VCP”
We use the PWM generator to send 1 time in 2 seconds so that the controller does not clog the channel for a second by constantly sending a message, we use the “Trailing Edge Detector”. Which will work only once at the moment of switching from one to zero, if the controller is ready at that moment to send a message via UART, then two units will come to the input of the logical multiplication block, respectively, also “1”, which will instruct the controller to send a message via UART , and also just in case for debugging in a USB-COM port (I wrote about this in detail in a previous article ).

In the "Display" blockeverything is quite simple, if the values ​​from the pressure sensor are less than a certain threshold and the motion sensor has triggered (it will give “1” to the output), then we will turn on the green LED of the controller as an alarm signal.

It would be cool if the system worked like in a movie:



But we will limit ourselves to turning on the LED.

Here is a visual demonstration:


There is the last block “Message Formation” left .

We receive data from the ADC, the ADC resolution is from 0 to 1023. We send characters to UART, which means the readings from the pressure sensor must be converted to a string. Since the maximum number is 1023 (4 digits), then we need 4 bytes. “Number to String Converter” outputs a couple of characters at the outputs, we will have 2 pairs of characters, each of them we will send UART and VCP messages to the installation registers. Next, we need to write a separator so that the readings do not merge, since CannyLab uses a couple of characters, then we take two “space” characters as a separator. Similarly, we convert the readings of the motion sensor, it gives a discrete either 00 or 01, which means we need only one pair of characters. At the very end of the message, write the carriage return and newline characters.

As I already wrote in the article about the photoresistor, Canny does not have its own COM port monitor, but you can use any third-party one, and since we will use the Arduino IDE a bit later, we will use the built-in COM port monitor.

So, I put a finger on the pressure sensor and move along the way:



The diagram, like the entire code below, can be downloaded from GitHub .

Now let's move on to the Arduino.


Part III: Wiring Diagram and Program for Arduino Uno


I won’t talk about Arduino in such detail, because everything is quite trivial.

Wiring diagram:



Note! Since the Arduino RX / TX output operates at 5V, and the Raspberry PI has 3.3V, people advise connecting the Arduino to the Raspberry UART using special modules or at least using a voltage divider. I don’t have a special module, but the voltage divider is always welcome. I took 3 resistors with a nominal value of 1000 ohms. And he made a tap after the second resistor, on which 2/3 of the voltage will drop. If you round off the power via USB to 5 V, then it just turns out 5*0.66=3.3 .

Although I also connected Arduino directly to the UART Raspberry PI and everything seemed to work.

We connect the pressure sensor to “+” and to the analog input “A1”. The motion sensor for power and digital input No. 5.

This is how the circuit looks like when assembled:



Here is the sketch code for Ardino: The code is simple, the only thing worth explaining is the “adjustment” variable. The fact is that when connected to the Arduino, the pressure sensor sometimes showed non-zero values ​​even without load, and I didn’t think of anything better than subtracting the average value of “noise” to unify the readings with Canny. Also, as in the previous case, we implemented the display with a built-in LED, in case the sensors worked:

byte photoPin = A0;

void setup() {
Serial.begin(9600);
pinMode(photoPin, INPUT);
pinMode(5, INPUT);
pinMode(13, OUTPUT);
}

void loop() {
int adjustment = 250;
int pressure_sensor = analogRead(A1) - adjustment;
int motion_sensor = digitalRead(5);

Serial.print(pressure_sensor);
Serial.print(" ");
Serial.println(motion_sensor);
if ((pressure_sensor<380) && (motion_sensor==1))
{
digitalWrite(LED_BUILTIN, HIGH);
}
else {
digitalWrite(LED_BUILTIN, LOW);
}
delay(1000);
}









Part IV: Raspberry PI and the monitoring program in Python


First you need to enable UART, as well as SSH and VNC, then connect to Raspberry using a smartphone.

Go to the Raspberry PI settings and enable SSH, VNC, UART, as in the picture:



Just in case, I turned off Bluetooth.

We will write a simple Python program, I used the built-in IDE and did not install any additional Python modules. I had a Raspbian with desktop image, medium in size, which takes up approximately 1.1 GB.

In our monitoring program, we will use both the console and the graphical interface to display information. To implement the GUI, I decided to use Tkinter. I really use it for the second time in my life, but I just needed a couple of text fields and a dialog box.

Here is the program code:

import serial
import time
from tkinter import *
from tkinter import ttk
from tkinter import messagebox

serialport = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=1.0) 

window = Tk()  
window.title("Security system for my pen")  
window.geometry('400x170')
#Presure sensor label
lbl_ps = ttk.Label(window, text="Pressure sensor", font=("Arial Bold", 20))
lbl_ps.grid(column=0, row=0)
lbl_ps_status = ttk.Label(window, text=" ",  font=("Arial Bold", 20))
lbl_ps_status.grid(column=1, row=0)
#Motion sensor label
lbl_ms = ttk.Label(window, text="Motion sensor", font=("Arial Bold", 20))
lbl_ms.grid(column=0, row=1)
lbl_ms_status = ttk.Label(window, text=" ", font=("Arial Bold", 20))
lbl_ms_status.grid(column=1, row=1)

while True:
   counter = 0
   rcv = serialport.readline().decode('utf-8').replace("\r\n","").split('  ')
   if (len(rcv)==2):
       ps=rcv[0]
       ms=rcv[1]
       print (ps+ " " +ms)
       if (int(ps)<380):
           lbl_ps_status.config(text = " Warning!")
           counter += 1
       else:
           lbl_ps_status.config(text = " Ok")

       if (int(ms)>0):
           lbl_ms_status['text']=" Warning!"
           counter += 1
       else:
           lbl_ms_status['text']=" Ok"  
       window.update_idletasks()  
       window.update()
       if (counter == 2):
            messagebox.showinfo("Alarm!", "heck your pen!")     
       time.sleep(1)


I will probably skip the import of libraries.

After import, we set the settings for UART, the port itself, speed and timeout.

serialport = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=1.0) 


Next, we place text fields (Label) on the table layout (on the grid)
We will have 4 fields of which 2 are unchanged, and the status of the sensor will be displayed in the other two.

window.title("Security system for my pen")  
window.geometry('400x170')
#Presure sensor label
lbl_ps = ttk.Label(window, text="Pressure sensor", font=("Arial Bold", 20))
lbl_ps.grid(column=0, row=0)
lbl_ps_status = ttk.Label(window, text=" ",  font=("Arial Bold", 20))
lbl_ps_status.grid(column=1, row=0)
#Motion sensor label
lbl_ms = ttk.Label(window, text="Motion sensor", font=("Arial Bold", 20))
lbl_ms.grid(column=0, row=1)
lbl_ms_status = ttk.Label(window, text=" ", font=("Arial Bold", 20))
lbl_ms_status.grid(column=1, row=1)


Next, create an endless loop.
At the beginning of the cycle, we will reset the alarm label counter .
Then read the data from the serial port.
In order not to look at all entries like “\ x00”, we re-encode the message into UTF-8.
Then we remove the beginning and end of the line so that only numbers remain.
Next, we divide the line, pay attention to the separator 2 spaces, not 1.
So that the program does not crash when the message is incorrect, the further code that is tied to receiving the message is crammed into a conditional structure that will work only if the message can be divided into 2 parts.
Well, display the pressure sensor and the motion sensor in the console.

while True:
   counter = 0
   rcv = serialport.readline().decode('utf-8').replace("\r\n","").split('  ')
   if (len(rcv)==2):
       ps=rcv[0]
       ms=rcv[1]
       print (ps+ " " +ms)


We check the sensors worked, if everything is fine, the system writes “OK”, if one of the sensors works, the counter increases by 1 and a warning is issued.


       if (int(ps)<380):
           lbl_ps_status.config(text = " Warning!")
           counter += 1
       else:
           lbl_ps_status.config(text = " Ok")

       if (int(ms)>0):
           lbl_ms_status['text']=" Warning!"
           counter += 1
       else:
           lbl_ms_status['text']=" Ok"  


In the last block, we update the elements of the Tkinter form, after which we check how many sensors worked. If both sensors have worked in the cycle, a modal window appears with an alarm message.


       window.update_idletasks()  
       window.update()
       if (counter == 2):
            messagebox.showinfo("Alarm!", "heck your pen!")     
       time.sleep(1)


It is important to note here that the motion sensor keeps output “1” for two seconds from the moment the motion is detected. So, as a rule, the system manages to work.

Below are screenshots showing the operation of the program:

All sensors are calm:



One of two things worked:



Both worked, the system waits for the operator to acknowledge:



It seems that everything was as planned.


Conclusion


In conclusion, consider connecting to a Raspberry PI from a smartphone. In principle, there is nothing complicated, if you can connect from a computer, then you can from a phone. All you need to know is the Raspberry IP, username and password. I installed VNC Viewer on my Android smartphone, but you can certainly have another client.

It’s not very convenient to use, but it works:


Let me remind you once again that all the code can be downloaded from GitHub .

Each time I promise myself that I will not write a long article, but here again the draft has exceeded 10 printed pages. The article shows an easy-to-implement example of a home-made security system, the scope for imagination is huge.

If I understand that the article was interesting to you, then I will outline later another one about connecting via a Bluetooth adapter.

UPD:
It seems that I got a small series of articles, so for your convenience I will leave links to other related articles:


  1. “One, two, three - burn the Christmas tree!” or my first look at the CANNY 3 tiny controller .
  2. “Destination has a lot of guises ...” or we automate the control of an autolamp using CANNY 3 tiny and a photoresistor .
  3. “What marinas?” or we control the controller via bluetooth using a mobile application on Xamarin (Android) .

All Articles