📜 ⬆️ ⬇️

Arduino controller with temperature sensor and Python interface for dynamic identification of control objects

Introduction


The possibility of obtaining real information about the state of real objects in real time allows us to proceed reasonably to the next stage of the analysis and synthesis of systems — mathematical modeling of the dynamic characteristics of control objects.

This publication discusses the design of a system for measuring a technological parameter — temperature — available in implementation, with remote transmission of a signal to a computing environment for further processing of measurement information.

This project is based on hardware for prototyping based on the Arduino platform with a variety of compatible modules and free Python software that make up the Arduino Software integrated development environment.

Temperature measurement circuit


The temperature measurement circuit consists of a primary digital measuring transducer - DS18B20 (Maxim Integrated), which is controlled by a 1-wire microprocessor controller - Atmega328 (5V 16MHz (Microchip) on the Arduino Pro Mini platform).
')
The output signal of the measurement information from DS18B20 via the 1-wire interface is fed to the microcontroller's discrete input, processed, converted into a string of ASCII characters of measured temperatures in the range from -55 to +125 ° C and, via a standard serial interface, via a TTL-USB converter, enters the computer for further software processing:



Measuring subsystem


The measuring subsystem is based on the Arduino Nano V3 platform:



The software is based on the example presented on the site [1], using the OneWire library, which can be connected via the library manager in the Arduino Software integrated development environment:

#include <OneWire.h> // OneWire DS18B20 Temperature Example // http://www.pjrc.com/teensy/td_libs_OneWire.html // The DallasTemperature library can do all this work for you! // http://milesburton.com/Dallas_Temperature_Control_Library // Data  DS18B20   7-  // Arduino OneWire ds(7); void setup(void) { Serial.begin(9600); } void loop(void) { byte i; byte present = 0; byte type_s = 0; byte data[12]; byte addr[8]; float celsius; ds.search(addr); ds.reset(); ds.select(addr); ds.write(0x44, 1); delay(800); present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { data[i] = ds.read(); } int16_t raw = (data[1] << 8) | data[0]; celsius = (float)raw / 16.0; Serial.println(celsius); } 

After debugging and testing the controller’s firmware program, we proceed to the installation of the components and elements of the measuring subsystem, and the assembly into the case:



In terms of the requirements for minimizing the case, use the platform Arduino Pro Mini. The hardware of the subsystem for processing and presentation of measurement information is provided via the USB port of the computer.

Python interface for processing the “acceleration curve” and its graphical implementation


The main tasks solved by the subsystem of processing and presentation of measurement information to the operator:

  1. Management and polling of virtual COM port via USB port; it uses the functions of the pySerial library.
  2. Interactive interaction with the operator; Here we enter the required number of measurements and the serial port number (we look in the Device Manager of MS Windows). If the port number is entered correctly and is not occupied by other programs, the current measured values ​​of the technological parameter are displayed on the console and in the graphic window. At the end of the measurements, the console displays the duration of the measurement time, the sensor polling period and the indication in which txt file the table with measurement results is located, and the graph window displays the measurement graph, date, time, experiment number, sensor polling period.
  3. Automatic registration of measurement results; here on the disk in the folder with the script, you must have a file count.txt, which contains an integer without a signed number, used as an experiment counter; each subsequent experiment increases the counter by one and adds the value of the counter to the name of the file with the table of experiment results.

Program Listing:

 import numpy as np import matplotlib.pyplot as plt import serial from drawnow import drawnow import datetime, time #     def cur_graf(): plt.title("DS18B20") plt.ylim( 20, 40 ) plt.plot(nw, lw1, "r.-") plt.ylabel(r'$, \degree $') plt.xlabel(r'$ \ $') plt.grid(True) #      def all_graf(): plt.close() plt.figure() plt.title("DS18B20\n" + str(count_v) + "-  " + "(" + now.strftime("%d-%m-%Y %H:%M") + ")") plt.plot( n, l1, "r-") plt.ylabel(r'$, \degree $') plt.xlabel(r'$ \ $' + '; (  : {:.6f}, c)'.format(Ts)) plt.grid(True) plt.show() #   #    str_m = input("  : ") m = eval(str_m) #    mw = 16 #    ser = serial.Serial() ser.baudrate = 9600 port_num = input("   : ") ser.port = 'COM' + port_num ser #   try: ser.open() ser.is_open print(" : " + ser.portstr) except serial.SerialException: print("   : " + ser.portstr) raise SystemExit(1) #  l1 = [] #    t1 = [] lw1 = [] #     n = [] #     nw = [] #      #      filename = 'count.txt' in_file = open(filename,"r") count = in_file.read() count_v = eval(count) + 1 in_file.close() in_file = open(filename,"w") count = str(count_v) in_file.write(count) in_file.close() filename = count + '_' + filename out_file = open(filename,"w") #      print("\n :\n") print("n -  ;") print("T - , . ;") print("\n    \n") print('{0}{1}\n'.format('n'.rjust(4),'T'.rjust(10))) #     #  #   #       i = 0 while i < m: n.append(i) nw.append(n[i]) if i >= mw: nw.pop(0) line1 = ser.readline().decode('utf-8')[:-2] t1.append(time.time()) if line1: l1.append(eval(line1)) lw1.append(l1[i]) if i >= mw: lw1.pop(0) print('{0:4d} {1:10.2f}'.format(n[i],l1[i])) drawnow(cur_graf) i += 1 #   ser.close() ser.is_open #time_tm -= time_t0 time_tm = t1[m - 1] - t1[0] print("\n   : {0:.3f}, c".format(time_tm)) Ts = time_tm / (m - 1) print("\n   : {0:.6f}, c".format(Ts)) #    print("\n     {}\n".format(filename)) for i in np.arange(0,len(n),1): count = str(n[i]) + "\t" + str(l1[i]) + "\n" out_file.write(count) #    out_file.close() out_file.closed #    now = datetime.datetime.now() #     all_graf() end = input("\n  Ctrl-C,   ") 

We get:

enter the number of measurements: 256
enter serial number: 3
connected with: com3
options:
n is the measurement number;
T - temperature, hail. WITH;
measured temperature values
n T
0 24.75
1 24.75
2 24.75
3 24.75
4 24.75
5 24.75
6 24.75
…………….



Python interface to obtain the transfer function and assess the adequacy of the model


To solve this problem, you can use numerical methods, since the model does not contain differentiation, and the proposed method of solving according to ratios does not imply a change in the time coordinate. In addition, we apply interpolation by a cubic spline in accordance with the following listing:

Determination of the transfer function of the object by temperature control channel
 # -*- coding: utf8 -*- import matplotlib.pyplot as plt import time start = time.time() from scipy.interpolate import splev, splrep import scipy.integrate as spint import numpy as np from scipy.integrate import quad xx =np.array(np.arange(0,230,1)) yy1 =np.array([ 24.87, 25.06, 25.31, 25.5, 25.81, 26.06, 26.37, 26.62, 26.87, 27.12, 27.44, 27.69, 27.87, 28.12, 28.31, 28.56, 28.75, 28.94, 29.12, 29.31, 29.5, 29.69, 29.81, 30.0, 30.12, 30.25, 30.37, 30.56, 30.69, 30.81, 30.87, 31.0, 31.12, 31.25, 31.31, 31.44, 31.5, 31.62, 31.69, 31.81, 31.87, 31.94, 32.06, 32.13, 32.19, 32.25, 32.31, 32.38, 32.44, 32.5, 32.56, 32.63, 32.69, 32.75, 32.75, 32.81, 32.88, 32.94, 32.94, 33.0, 33.06, 33.13, 33.13, 33.19, 33.25, 33.25, 33.31, 33.31, 33.38, 33.38, 33.44, 33.44, 33.5, 33.5, 33.56, 33.56, 33.56, 33.63, 33.63, 33.69, 33.69, 33.69, 33.75, 33.75, 33.81, 33.81, 33.81, 33.88, 33.88, 33.88, 33.88, 33.94, 33.94, 33.94, 34.0, 34.0, 34.0, 34.0, 34.06, 34.06, 34.06, 34.06, 34.06, 34.13, 34.13, 34.13, 34.13, 34.13, 34.19, 34.19, 34.19, 34.19, 34.19, 34.25, 34.25, 34.25, 34.25, 34.25, 34.25, 34.31, 34.31, 34.31, 34.31, 34.31, 34.31, 34.31, 34.38, 34.38, 34.38, 34.38, 34.38, 34.38, 34.38, 34.38, 34.38, 34.44, 34.44, 34.44, 34.44, 34.44, 34.44, 34.44, 34.44, 34.44, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.5, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.56, 34.63, 34.56, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.63, 34.69, 34.63, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.69, 34.75, 34.69, 34.75, 34.69, 34.69, 34.75, 34.75, 34.75, 34.75, 34.75]) yy2=yy1-24.87#   yy=yy2/max(yy2)# """      """ def h(x): spl = splrep(xx , yy ) return splev(x, spl) """          (6)""" S1=(spint.quad(lambda x:1-h(x),xx[0],xx[len(xx)-1])[0]) S2=(spint.quad(lambda x:(1-h(x))*(S1-x),xx[0],xx[len(xx)-1])[0]) S3=(spint.quad(lambda x:(1-h(x))*(S2-S1*x+(1/2)*x**2),xx[0],xx[len(xx)-1])[0]) S4=(spint.quad(lambda x:(1-h(x))*(S3-S2*x+S1*(1/2)*x**2-(1/6)*x**3),xx[0],xx[len(xx)-1])[0]) """    """ b1=-S4/S3 a1=b1+S1 a2=b1*S1+S2 a3=b1*S2+S3 """    """ def ff(x,t): j=(-1)**0.5 return (2/np.pi)*( ((b1*x*j+1)*np.e**(-25*x)/(a3*(x*j)**3+a2*(x*j)**2+a1*x*j+1)).real)*(np.sin(x*t)/x) y=np.array([round(quad(lambda x: ff(x,t),0, 0.6)[0],2) for t in xx]) """     """ k=round(1-sum([(yy[i]-y[i])**2 for i in np.arange(0,len(yy)-1,1)])/sum([(yy[i])**2 for i in np.arange(0,len(yy)-1,1)]),5) stop = time.time() print ("   :",round(stop-start,3)) plt.title('   .\n  : %s'%k) plt.plot(xx, yy,label='W=(%s*p+1)/(%s*p**3+%s*p**2+%s*p+1)'%(round(b1,1),round(a3,1),round(a2,1),round(a1,1))) plt.legend(loc='best') plt.grid(True) plt.show() 


We get:

Program working time: 1.144



The transfer function of the object (capacity with heater) was obtained, while the adequacy of the “acceleration curve” was 0.97.

findings


An Arduino controller with a temperature sensor and a Python interface for the dynamic identification of control objects via a temperature control channel was developed and tested.

Link:

1. OneWire Library

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


All Articles