⬆️ ⬇️

Collecting sensor readings and displaying them





People like beautiful presentations. Beautiful pictures, some text, changing slides. A beautiful picture allows you to quickly transfer information to a person, to communicate the most important. We all know that. I'm wondering how to “cross a hedgehog and a snake”?



How visually on the computer monitor to imagine the processes occurring inside the microcontroller or FPGA? Or how to show what is happening inside the entire automation system implemented on a microcontroller or FPGA?

')

In fact, I know the correct answer - you need to use SCADA systems.

SCADA is supervisory control and data acquisition, dispatch control and data collection. But we are not looking for easy ways, we want to reinvent our bicycle a bit.



I want to share my simple method of displaying data received from sensors and sensors from the control board.



Here, first of all, you need to separate the three components:





So, in order try to tell.



Data transfer protocol.



Currently, there are actually only two physical capabilities left to connect any device to a computer or laptop: a network connection via Ethernet / WiFi or USB. The "real" parallel and serial ports are practically gone. It was easy with them. Of course they can still be found if you search. But it is better not to think this way.



Ethernet while I set aside. To transfer over the network, you need to have TCP / IP stack drivers in the controller, as a rule, this means having an OS, usually Linux or ucLinux. Then you need a network configuration interface: what is the IP address? A static or dynamic? And what a mask and gateway? In general, it is not very easy to implement and configure.



USB seems much simpler, although there are many pitfalls here: what is the class / subclass of the device? Does he need drivers or are they using standard drivers of the same Windows?

And once again we are back "full circle" - the easiest way is to use the serial port via USB. In the simplest case, there are cords of type USB2Serial. Well, or as an excellent option for the developer of boards and controllers, various FTDI chips.



OK, still select the serial port via USB. And if so, then the transfer of data can be in the form of a sequence of characters. It means that it is even simpler: the sensor readings can be transmitted in the form of lines like "TRANSMITTER NAME = VALUE"



With this approach, we can easily increase the number of respondents sensors, and easily change their type. The status of the switch or reed switch will be transmitted, for example, in the form of the strings “but0 = 1” or “but1 = 0”. The temperature value can be transmitted as the string "t0 = 36.6". It is easiest to separate the lines with carriage-transfer characters: 0x0D 0x0A.



So, at first, even a visualization program on a computer is not needed. You can simply start a terminal program like Putty and look at the sensor readings from the controller.



Controller.



My controller is based on the Altera Cyclone III FPGA. In fact, this is a well-known developers board Mars Rover 2 . I already wrote about some projects executed on it. For example, once we made an FM radio transmitter on this board on a clean FPGA . We also made USB Tracker on it. There are other projects.



Here is a fee:







There are already 2 buttons on the board - these are the first two sensors for my experiments.

I also connected the ds18b20 thermometer chip - this is the second sensor.

You can also use the ADC board to measure something-yet-not-know-what. So far here is just a variable resistor instead of a sensor.



It is important that the board already has the FTDI FT2232HL chip, which provides communication with the computer via USB in the form of a virtual serial port. The transfer rate is already 12Mbps. This is conventionally 1.2 MB / s. If, for example, the board polls the sensors every 100 milliseconds, then it turns out that for each survey, the computer can transfer more than 100K bytes of data. Pretty decent.



Now I will not talk about the project for the board and FPGA Cyclone III. For this there is a separate article . This article details how the data is polled and the results are transmitted to the computer via the serial port. It is better to proceed to the consideration of the 3rd component - the program of visualization of sensor values, which runs on a computer.



Data visualization program.



Here I wanted to do everything quickly and simply. What to write the program, so it was easy to write, change, add?



I choose Python, although to be honest there is no experience. It just seems like it will be fine. As one of habrazhiteli said (sorry, I don’t remember who) I would like to additionally like to “tout my python”.



So, since the program will be graphical, I will try the Tkinter built into the python. To work with the serial port I will use pyserial.



I would like to write a kind of classes - for each type of sensor its own class.



The simplest class is the binary sensor. This can be a button, limit switch, reed switch. Its values ​​are 0 or 1. The Python class BinSensor corresponding to this sensor displays only 2 states. I suggest each state to draw their own image. The image is attached to the fixed coordinates of the program window on top of the background image.







As soon as the value “0” has arrived, we display the first picture. If the value “1” has come, then we show the second picture. Images can be any - it all depends on our imagination.



Here is this class:

#!/usr/bin/env python import Tkinter from Tkinter import * root = Tk() class BinSensor: def __init__(self,name,img0,img1,x,y): self.name=name self.x=x self.y=y self.img0=PhotoImage(file=img0) self.img1=PhotoImage(file=img1) self.val=0 self.label_img=Label(root,image=self.img0) self.label_img.place(x=self.x,y=self.y) def set(self,state): if(self.val==state): return self.val=state if( int(state)==0 ): self.label_img.configure(image=self.img0) else: self.label_img.configure(image=self.img1) 


Parameters are passed to the __init__ function, which is called when creating an instance of a class:

Name - sensor name

Img0 and img1 are the names of the image files used to display the status of the sensor.

X and y - coordinates of the window where the sensor will be displayed.



When creating a sensor object, a Label with a picture is immediately created and placed in the Tkinter window.



The set function accepts a string parameter — this is the new sensor state “0” or “1”. Depending on the new value, the image inside the Label is reconfigured, changed to another. In general, that's all.



The second class vBarSensor is implemented in a similar way.

 class vBarSensor: def __init__(self,name,scale,min,max,x,y,w,h): self.name=name self.scale=scale self.x=x self.y=y self.h=h self.val=min self.min=min self.max=max self.delta=max-min h1=self.h*(self.val-self.min)/self.delta h0=self.h-h1 self.canv0 = Canvas(root, width = w, height = h0, bg = "lightblue", bd=1, relief='ridge') self.canv1 = Canvas(root, width = w, height = h1, bg = "red", bd=1, relief='ridge') self.barLabel = Label(root, text = "0") self.canv0.place(x=self.x,y=self.y) self.canv1.place(x=self.x,y=self.y+h0) self.barLabel.place(x=self.x,y=self.y+h+5) def set(self,newval): #newval is signed hex string like "83A5" val=int(newval,16) if(val>0x7fff): val=-val val=val/self.scale if(self.val==val): return self.val=val h1=self.h*(self.val-self.min)/self.delta h0=self.h-h1 self.barLabel.configure(text=str(self.val)) self.canv0.configure(height = h0) self.canv1.configure(height = h1) self.canv1.place(y=self.y+h0) 


This class graphically represents a thermometer type sensor. Values ​​from the sensor may vary in a certain range. Also, when creating an instance of this class, you must specify the name of the sensor. In addition, the thermometer has a possible minimum and maximum value, and also indicate the coordinates of the column in the visualization window, the width and height of the column.



The thermometer's column, as it were, consists of two parts: the lower red and the upper light.

It would be possible to create one Tkinter canvas and draw these bars on it, but for some reason I did not. I made two canvas of different colors and in the set () function I change their vertical size. In principle, it does not matter. Works. By the way, if you want to see exactly the image of the thermometer in the visualization window, you can draw it on the background image of the window, and place an instance of vBarSensor on top of it.







Probably be nice.



Wrote another class GridDisplay to display the sensor readings and change them over time. I will not give its source code here, so as not to overload the article with unnecessary details. Who will need to download the entire project from the site , along with the source code for the FPGA for Altera Quartus II.



But I'll show the main program alls.py. There are not many things here:

 #!/usr/bin/env python import sensor from sensor import * import serial from serial import * class AllSensors: def __init__(self): #open serial port self.s=serial.Serial("COM27",115200,timeout=10) #load background image self.bgnd=PhotoImage(file="bgnd.gif") self.label_bgnd=Label(root,image=self.bgnd) self.label_bgnd.place(x=0,y=0) #add all sensors and indicators self.all=[] self.all.append( BinSensor("b0","f0.gif","f1.gif",32,32) ) self.all.append( BinSensor("b1","f0.gif","f1.gif",32,128) ) self.all.append( vBarSensor("a0",1,0,255,128,32,32,160) ) self.all.append( GridDisplay("t0",16,-55,125,10,16,180,32,256,160) ) def set(self,name,val): for sens in self.all: if(sens.name==name): sens.set(val) return def setline(self,line): p=line.split("=") if(len(p)==2): self.set( p[0], p[1] ) def run(self): while(1): line=self.s.readline() line=line.rstrip() #print(line) self.setline(line) root.update() a=AllSensors() a.run() 


In this program, I open the serial port for reading. I load the background image into the window. I create a list of all available sensors. Next, I read the lines from the port, parse them, and by the sensor name transfer the new value to the appropriate class instance.



Starting a program from Python is easy: “import alls”, where alls is the name of the main program file alls.py. This is what my program looks like now:







Here is a video that shows how it all works (just don’t get scared, I’ll turn on the hair dryer to heat the temperature sensor, so I’d better screw the sound):







Now that the “skeleton” of the application is working, we can proceed to a detailed drawing of the floor plan and the sensors installed in it.

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



All Articles