I got this pack from a local shop. It was a recycled item used to store Dosa in it. When I found out it was in German. So I decided to translate a few words written on it. I wrote them on a page.
-
How to use S109AFTG Microstep Driver with ATmega328PB Programmed using Microchip Studio
When I opened the case. I found a PCB which is screwed to a big heatsink. I unscrewed the bolts and saw that there is S109AFTG. The IC is sandwiched between the PCB and the heatsink. A small aluminum block is also used for heat transfer between the IC and the heatsink.
It has a different step size which can be selected by the DIP switches.
The motor driver has a maximum of 1/32 step size.which means 1.8°/ 32 = 0.05625°
360°/ 0.05625° = 6400 steps
So a full rotation will be in 6400 steps.
You will need a power source such as a Switched Mode Power Supply which can supply at least 2 Amps.
If your application needs more torque you will need a power source that can provide a high current without dropping the voltage.
Or you can use the battery for a short duration.
Schematic Diagram
Code
/* * main.c * * Created: 7/4/2023 5:51:21 PM * Author: abhay */ #define F_CPU 16000000 #include <xc.h> #include <util/delay.h> int PUL=PIND6; //define Pulse pin int DIR=PINB1; //define Direction pin int ENA=PIND2; //define Enable Pin #define DirLow PORTB &= ~(1<<DIR) #define DirHigh PORTB |= (1<<DIR) #define PulLow PORTD &= ~(1<<PUL) #define PulHigh PORTD |= (1<<PUL) #define EnaLow PORTD &= ~(1<<ENA) #define EnaHigh PORTD |= (1<<ENA) #define delayus50 _delay_us(50) int main(void) { DDRB |= (1<<DIR); DDRD |= (1<<PUL)|(1<<ENA); while(1) { //TODO:: Please write your application code for (int i=0; i<6400; i++) //Forward 6400 steps { DirLow; EnaHigh; PulHigh; delayus50; PulLow; delayus50; } _delay_ms(5000); for (int i=0; i<6400; i++) //Backward 6400 steps { DirHigh; EnaHigh; PulHigh; delayus50; PulLow; delayus50; } _delay_ms(2000); } }
-
Derivative Control Demo in Control Systems Engineering Using Slider in Tkinter
Control systems engineering plays a crucial role in various industries, enabling precise and efficient control of processes and systems. One fundamental concept in control systems is derivative control, which helps improve the system’s response to changes and disturbances. In this blog post, we’ll explore a simple demonstration of derivative control using a slider in Tkinter, a popular Python GUI toolkit.
Understanding Derivative Control
Derivative control is a control strategy that utilizes the derivative of the error signal to adjust the control output. By calculating the rate of change of the error, derivative control can anticipate the system’s response to changes and take corrective actions to minimize the error. It provides a damping effect and improves the system’s stability and responsiveness.
The derivative control algorithm consists of three main components:
- Derivative Control Function: The derivative control function calculates the derivative term based on the current error, previous error, and a time interval. The derivative term is obtained by multiplying the derivative gain (
Kd
) with the difference in error divided by the time interval. - Main Loop: The main loop of the control system continuously monitors the process variable and applies derivative control to update the control output. It calculates the error by subtracting the desired setpoint from the process variable. The derivative control function is then invoked to compute the derivative term. The control output is actuated, and the previous error is updated.
- Slider and GUI: To interact with the control system, we’ll create a graphical user interface (GUI) using Tkinter. A slider widget allows us to adjust the feedback stimulus, representing the process variable. Labels display the feedback stimulus value and the computed derivative term in real-time. Additionally, a hyperlink is provided to visit a website for further information.
Implementation with Tkinter
Let’s delve into the implementation of the derivative control demo using Tkinter. Here’s the code:
import tkinter as tk import time import webbrowser # Derivative control function def derivative_control(error, prev_error, dt): # Derivative gain Kd = 0.2 derivative_term = Kd * (error - prev_error) / dt return derivative_term # Main loop def main_loop(): setpoint = 50 # Desired setpoint process_variable = 0 # Initial process variable prev_error = 0 # Previous error dt = 0.1 * 9 # Time interval for derivative control while True: # Read process variable from the slider process_variable = slider.get() # Calculate the error error = setpoint - process_variable # Apply derivative control derivative_term = derivative_control(error, prev_error, dt) # Actuate the control signal (in this example, update the label) control_label.configure(text="Derivative Term: {:.2f}".format(derivative_term)) # Update the previous error prev_error = error time.sleep(dt) # Sleep for the time interval # Callback function for the slider def slider_callback(value): feedback_label.configure(text="Feedback Stimulus: {:.2f}".format(float(value))) # Open exasub.com in a web browser def open_link(event): webbrowser.open("http://www.exasub.com") # Create the main Tkinter window window = tk.Tk() window.title("Derivative Control Demo") # Create the slider for adjusting the feedback stimulus slider = tk.Scale(window, from_=0, to=100, orient=tk.HORIZONTAL, length=300, command=slider_callback) slider.pack() # Create a label to display the feedback stimulus value feedback _label = tk.Label(window, text="Feedback Stimulus: {:.2f}".format(slider.get())) feedback_label.pack() # Create a label to display the derivative term value control_label = tk.Label(window, text="Derivative Term: ") control_label.pack() # Add a link to exasub.com link = tk.Label(window, text="Visit exasub.com", fg="blue", cursor="hand2", font=("Arial", 14)) link.pack() link.bind("<Button-1>", open_link) # Start the main loop in a separate thread import threading main_loop_thread = threading.Thread(target=main_loop) main_loop_thread.start() # Start the Tkinter event loop window.mainloop()
Exploring the Code
Let’s break down the code to understand how the derivative control demo works:
- We begin by importing the necessary modules:
tkinter
for GUI,time
for time-related operations, andwebbrowser
for opening web links. - The
derivative_control
function calculates the derivative control term based on the error, previous error, and a specified time interval. It multiplies the derivative gain (Kd
) with the difference in error and divides it by the time interval. Adjusting the value ofKd
can impact the system’s response. - The
main_loop
function serves as the central control loop of the demo. It sets the desired setpoint and initializes variables for the process variable and previous error. The time interval (dt
) determines the frequency of derivative control updates. Within the loop, the process variable is read from the slider, the error is calculated, derivative control is applied, and the control output is displayed in the GUI label. The previous error is updated, and the loop pauses for the specified time interval. - The
slider_callback
function is triggered whenever the slider value changes. It updates the feedback label to display the current value of the feedback stimulus, representing the process variable. - The
open_link
function opens the “exasub.com” website in a web browser when the “Visit exasub.com” link is clicked. This functionality provides an opportunity to learn more about derivative control or related topics. - The main Tkinter window is created, titled “Derivative Control Demo”.
- A slider widget is added to the window, allowing the user to adjust the feedback stimulus. It spans from 0 to 100, is oriented horizontally, and has a length of 300 pixels. The
slider_callback
function is bound to this slider to update the feedback label. - A label is created to display the current value of the feedback stimulus.
- Another label is created to display the computed derivative term. Initially, it displays the placeholder text “Derivative Term: “.
- A hyperlink labeled “Visit exasub.com” is added to the window. It appears in blue and changes the cursor to a hand when hovered over. The
open_link
function is bound to this label to open the specified website. - The main loop is started in a separate thread using the
threading
module. This allows the control loop to run concurrently with the Tkinter event loop and ensures the GUI remains responsive. - Finally, the Tkinter event loop is started using the
mainloop()
method of the window object. It listens for user interactions and updates the GUI accordingly.
Running the Derivative Control Demo
To run the derivative control demo, you’ll need to have Python and the Tkinter library installed. Save the code in a Python file (e.g.,
derivative_control_demo.py
) and execute it. A window will appear with a slider and two labels.Adjusting the slider will update the feedback stimulus
value label in real-time. As you adjust the slider, the derivative control algorithm will calculate the derivative term, which will be displayed in the “Derivative Term” label. The calculated derivative term reflects the system’s response to changes in the feedback stimulus.
Additionally, clicking the “Visit exasub.com” link will open a web browser and direct you to the “exasub.com” website, providing an opportunity to explore further resources on derivative control or related topics.
Conclusion
In this blog post, we’ve explored a derivative control demo implemented using Tkinter in Python. By adjusting a slider representing the feedback stimulus, you can observe the real-time calculation of the derivative term. This demonstration showcases the principles of derivative control and its role in control systems engineering.
Understanding derivative control and its application can be valuable in various fields, such as robotics, industrial automation, and process control. By manipulating the derivative gain and other control parameters, engineers can fine-tune the system’s response to optimize performance, stability, and efficiency.
By experimenting with this derivative control demo and further exploring control systems engineering, you can deepen your understanding of control strategies and their impact on system behavior.
- Derivative Control Function: The derivative control function calculates the derivative term based on the current error, previous error, and a time interval. The derivative term is obtained by multiplying the derivative gain (
-
How to use bipolar stepper motor using l298n module and raspberry pi pico w
The stepper motor that i have is a bipolar stepper motor.
On it one side there is information about it.
TYPE: 17PM-k310-33VS NO. T4508-03 Minebea-Matsushita Motor Corporation Made in Thailand
It is a NEMA 17
17 stands for 1.7inchesRaspberry Pi Pico W L298N Module GND GND GP0 IN1 GP1 IN2 GP2 IN3 GP3 IN4 The two coils pair are found using the multimeter in resistance mode.
Since I am using a regular motor driver. I cannot do the micro stepping.
But even with micro stepping, it can do a lot of stuff.So there are two coil pair.
step angle of 1.8o degrees.So to make a 360o
we need 360o / 1.8o = 200 stepsSo we can make a full rotation with 200 steps of 1.8 degrees each.
This is what is known as the full step.
In full step, we only excite 1 pole at a time. There are two poles per coil.We can excite two poles at a time. Which will half the step angle to 0.9 degrees.
The following is the table I have made to see how many steps I will be made by employing a 0.9 deg angle. It is only up to 300 steps or 270 deg. You can calculate from then on.Micropython Code
from machine import Pin import utime motor_pins = [Pin(0, Pin.OUT), Pin(1, Pin.OUT), Pin(2, Pin.OUT), Pin(3, Pin.OUT)] step_sequence = [ [1,0,0,0],#1 [1,0,1,0],#13 [0,0,1,0],#3 [0,1,1,0],#23 [0,1,0,0],#2 [0,1,0,1],#24 [0,0,0,1],#4 [1,0,0,1]#41 ] off_seq = [(0,0,0,0)] length_step_sequence = len(step_sequence) one_rotation_length = 400/length_step_sequence step_delay = (1/1000)*10 #ms def step_off(): #print("step off") motor_pins[0].value(0) motor_pins[1].value(0) motor_pins[2].value(0) motor_pins[3].value(0) utime.sleep(step_delay) ''' Function Name: move_step Description: It takes the step sequence and assigns the motor pins to the value according to the step sequence. It moves one step seqence at a time. For a half step sequence each step will be 0.9 degrees. For a full step sequence each step will be 1.8 degrees. ''' def move_step(seq): ygh = seq #print(ygh) for step1,pins in zip(ygh,motor_pins): pins.value(step1) ''' Function Name: move one step Description: It moves all the steps in the sequence. For a half wave steps => 8 * 0.9 = 7.2 deg For a full wave steps => 4 * 1.8 = 7.2 deg ''' def move_one_step(forward,reverse): for i in range(0,length_step_sequence,1): if forward == 1: move_step((step_sequence[i])) elif reverse == 1: move_step(reversed(step_sequence[i])) utime.sleep(step_delay) def rotation(steps,forward,reverse): if forward == 1: for i in range(steps): move_one_step(1,0) print("Forward steps: ",steps) elif reverse == 1: for i in range(steps): move_one_step(0,1) print("Reverse steps: ",steps) #step_off() ''' Half step calculations 8 Steps of 0.9 deg each. total degree of 8 steps => 8 * 0.9 = 7.2 (8 step sequence) * (50 repeated steps) * 0.9 deg = 360 So, a total of 400 steps are required to make 360 degree. 7.2 deg x (50 repeated steps) = 360 degrees 7.2 deg x 25 = 180 degree ''' while True: rotation(25,1,0) # move 180 forward(CW) utime.sleep(1) rotation(50,0,1) # move 366 reverse (CCW) utime.sleep(1)
-
12V PC Fan Control Using Raspberry Pi Pico W By PWM
How to control a 12V PC fan using Pulse Width Modulation (PWM) signals with the Raspberry Pi Pico W board and an L298N motor driver module. I will use the MicroPython programming language and the Thonny IDE to write and run the code.
Raspberry Pi Pico W L298n Module GP9 IN1 GND GND VSYS
(Connect this only when you save as “main.py” in raspberry pi.)+5V 12V PC FAN L298n Module Positive Lead(+12V wire) OUT1 Negative Lead OUT2 Micropython Code
import network import socket import time from time import sleep from picozero import pico_temp_sensor, pico_led import machine ssid = 'Abhay' password = 'AK26@#36' wdt = machine.WDT(timeout=5000) # Timeout in milliseconds (e.g., 5000ms = 5 seconds) def feed_watchdog(timer): wdt.feed() # Feed the watchdog timer to reset the countdown timerWdt = machine.Timer() timerWdt.init(period=1000, mode=machine.Timer.PERIODIC, callback=feed_watchdog) GPIO_PIN_9 = machine.Pin(9) pwm9 = machine.PWM(GPIO_PIN_9) pwm9.freq(25000) current_pwm_duty = 0 sleep_duration = 0.01 def updateFan(x,y): global current_pwm_duty,sleep_duration current_pwm_duty = x if sleep_duration > 0 and sleep_duration <= 2: sleep_duration = y else: sleep_duration = 0.01 def fanon(timer): global current_pwm_duty,sleep_duration pwm9.duty_u16(current_pwm_duty) time.sleep(sleep_duration) pwm9.duty_u16(0) def fanoff(): pwm9.duty_u16(0) timerUpdate = machine.Timer() timerUpdate.init(period=2000, mode=machine.Timer.PERIODIC, callback=fanon) def connect(): #Connect to WLAN wlan = network.WLAN(network.STA_IF) wlan.active(True) wlan.connect(ssid, password) while wlan.isconnected() == False: print('Waiting for connection...') sleep(1) ip = wlan.ifconfig()[0] print(f'Connected on {ip}') return ip def open_socket(ip): # Open a socket address = (ip, 80) connection = socket.socket() connection.bind(address) connection.listen(1) return connection def webpage(temperature, state,user_value): #Template HTML html = f""" <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <form action="./lighton" style="display: flex; justify-content: center;"> <input type="submit" value="Light on" style="font-size: 40px;" /> </form> <form action="./lightoff" style="display: flex; justify-content: center;"> <input type="submit" value="Light off" style="font-size: 40px;" /> </form> <p style="font-size: 20px;">LED is {state}</p> <p style="font-size: 20px;">Temperature is {temperature}</p> <form action="./fanon_LOW" style="display: flex; justify-content: center;"> <input type="submit" value="FAN on LOW" style="font-size: 40px;" /> </form> <form action="./fanon_MID" style="display: flex; justify-content: center;"> <input type="submit" value="FAN on MID" style="font-size: 40px;" /> </form> <form action="./fanon_FULL" style="display: flex; justify-content: center;"> <input type="submit" value="FAN off FULL" style="font-size: 40px;" /> </form> <form action="./fanoff" style="display: flex; justify-content: center;"> <input type="submit" value="FAN off" style="font-size: 40px;" /> </form> <h1>Numeric Form</h1> <form method=POST action="/usrval"> <label for="value">Enter a numeric value:</label><br> <input type="number" id="value" name="value" min="30" max="65" value="30"required><br><br> <input type="submit" value="Submit"> </form> <p>User value: {user_value}</p> <!-- Display the user-submitted value --> </body> </html> """ return str(html) def serve(connection): #Start a web server state = 'OFF' pico_led.off() temperature = 0 user_value = None # Variable to store the user-submitted value usr_int = 0 while True: client = connection.accept()[0] request = client.recv(1024) request = str(request) rqst1 = request.split() ''' for x1 in rqst1: if(x1.find("usrval") != -1): print(rqst1) #print(x1) #print(rqstfind) ''' try: for x1 in rqst1: if "value=" in x1: user_value = x1.split("=")[2].strip("'") usr_int = int(user_value) * 1000 if usr_int >= 65535: usr_int = 65535 if usr_int <= 0: usr_int = 0 print(user_value," ",type(user_value)," int:",usr_int," ",type(usr_int)) except: pass try: request = request.split()[1] except IndexError: pass if request == '/lighton?': pico_led.on() state = 'ON' elif request =='/lightoff?': pico_led.off() state = 'OFF' elif request == '/fanon_LOW?': #put the usr value in the pwm duty updateFan(30000,1.75) elif request == '/fanon_MID?': #put the usr value in the pwm duty updateFan(45000,1.5) elif request == '/fanon_FULL?': #put the usr value in the pwm duty updateFan(65000,1.6) elif request == '/fanoff?': updateFan(0,1) temperature = pico_temp_sensor.temp html = webpage(temperature, state,user_value) client.send(html) client.close() try: ip = connect() connection = open_socket(ip) serve(connection) except KeyboardInterrupt: machine.reset()
-
How to Use C SDK to Create UF2 file which Interface Ultrasonic Sensor with Raspberry Pi Pico
Hardware setup
HC-SR04 Raspberry Pi Pico VCC VSYS GND GND Trig GP2 ECHO GP3 I am using raspberry pi model 3 b+ for the code compilation.
- Create the folder named “distance” inside the pico folder
- Then Create the test.c and CMakeLists.txt files using touch command.
touch test.c CMakeLists.txt
- Copy the pico_sdk_import.cmake file from pico/pico-sdk/external
- make the build directory using mkdir command
mkdir build
- Here is the CMakeLists.txt code
# Set the minimum required version of CMake cmake_minimum_required(VERSION 3.13) # Import the Pico SDK CMake configuration file include(pico_sdk_import.cmake) # Set the project name and languages project(test_project C CXX ASM) # Set the C and C++ language standards set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 17) # Initialize the Pico SDK pico_sdk_init() # Create an executable target called "test" from the source file "test.c" add_executable(test test.c ) # Enable USB stdio for the "test" target (used for serial communication) pico_enable_stdio_usb(test 1) # Disable UART stdio for the "test" target pico_enable_stdio_uart(test 0) # Add extra outputs for the "test" target (e.g., UF2 file) pico_add_extra_outputs(test) # Link the "test" target with the pico_stdlib library target_link_libraries(test pico_stdlib)
- Here is the c code that you put inside the test.c file
#include <stdio.h> #include "pico/stdlib.h" #include "hardware/gpio.h" #include "hardware/timer.h" #define TRIG_PIN 2 #define ECHO_PIN 3 float measure_distance() { gpio_put(TRIG_PIN, 1); sleep_us(10); gpio_put(TRIG_PIN, 0); uint32_t start_ticks = 0; uint32_t end_ticks = 0; while (gpio_get(ECHO_PIN) == 0) { start_ticks = time_us_32(); } while (gpio_get(ECHO_PIN) == 1) { end_ticks = time_us_32(); } uint32_t elapsed_time_us = end_ticks - start_ticks; float distance_cm = elapsed_time_us * 0.0343 / 2; return distance_cm; } int main() { stdio_init_all(); sleep_ms(2000); // Wait for sensor to stabilize gpio_init(TRIG_PIN); gpio_set_dir(TRIG_PIN, GPIO_OUT); gpio_init(ECHO_PIN); gpio_set_dir(ECHO_PIN, GPIO_IN); while (1) { float distance = measure_distance(); printf("Distance: %.2f cm\n", distance); sleep_ms(1000); } return 0; }
- after this you need to execute this line of code in the terminal
export PICO_SDK_PATH=../../pico
- then execute the following code in the given order
cd build
cmake ..
make
If everything worked, you will have your ulf2 file in your build directory
-
Interfacing a 5V Ultrasonic Sensor with 3.3V GPIO of Raspberry Pi Pico: A Voltage Divider Solution
I have an old HC-Sr04 ultrasonic sensor. I don’t know if it’s GPIO voltage compatible with the 3.3V microcontroller.
On the internet, I found that the old sensors work with 5V.So, I used a voltage divider made of 1K ohm and 1.5K ohm Surface mount resistors. To bring down the 5V to a suitable 3V.
I want to reduce the voltage level on the ECHO pin of the ultrasonic sensor to a safe level for the Raspberry Pi Pico’s GPIO pins. Let’s assume we have chosen resistors R1 and R2 with values of 1K and 1.5K, respectively.
You can also use the voltage divider calculator for this
Voltage Divider CalculatorUsing the voltage divider formula, we can calculate the output voltage at the midpoint (E_3) of the voltage divider circuit:
V_out = V_in * (R2 / (R1 + R2))
Since the Vsys pin of the Raspberry Pi Pico provides a voltage of 5V, we can calculate the output voltage:
V_out = 5V * (1.5K / (1K + 1.5K))
= 5V * (1.5K / 2.5K)
= 5V * 0.6
= 3VWith the given resistor values, the output voltage at the midpoint of the voltage divider circuit will be 3V. This 3V output is within the safe voltage range for the GPIO pins of the Raspberry Pi Pico.
Code Implementation:
To implement the interface between the ultrasonic sensor and the Raspberry Pi Pico, we will utilize MicroPython, a lightweight Python implementation for microcontrollers. The following code snippet demonstrates the necessary steps:
from machine import Pin import utime trigger = Pin(2, Pin.OUT) echo = Pin(3, Pin.IN) def ultra(): trigger.low() utime.sleep_us(2) trigger.high() utime.sleep_us(10) trigger.low() while echo.value() == 0: signaloff = utime.ticks_us() while echo.value() == 1: signalon = utime.ticks_us() timepassed = signalon - signaloff distance = (timepassed * 0.0343) / 2 print("The distance from object is ",distance,"cm") while True: ultra() utime.sleep(1)
-
Integral Control Demo in Control Systems Engineering Using Slider in Tkinter
Introduction:
Control systems engineering plays a crucial role in regulating and optimizing various processes in industries, robotics, and automation. One fundamental concept in control systems is integral control, which aims to reduce steady-state error and improve system performance. In this blog post, we will explore integral control, its implementation in Python using tkinter, and discuss its importance in control systems.
Understanding Integral Control:
Integral control is a control technique that integrates the error signal over time and uses the accumulated integral term to adjust the control signal. It helps to compensate for any steady-state error and drive the system towards the desired setpoint. The integral control component is typically employed alongside proportional and derivative control, forming the PID control algorithm.
Implementation using Python tkinter:
To better grasp the concept of integral control, let’s examine a Python code snippet that demonstrates its implementation using the tkinter library:
import tkinter as tk import time import threading import webbrowser # Integral control function def integral_control(error, integral_sum): # Integral gain Ki = 0.1 integral_sum += error integral_term = Ki * integral_sum return integral_term, integral_sum # Main loop def main_loop(): setpoint = 50 # Desired setpoint process_variable = 0 # Initial process variable integral_sum = 0 # Accumulated integral sum while True: # Read process variable from the slider process_variable = slider.get() # Calculate the error error = setpoint - process_variable # Apply integral control integral_term, integral_sum = integral_control(error, integral_sum) # Actuate the control signal (in this example, update the label) control_label.configure(text="Integral Term: {:.2f}".format(integral_term)) time.sleep(0.1) # Sleep for 0.1 seconds # Callback function for the slider def slider_callback(value): feedback_label.configure(text="Feedback Stimulus: {:.2f}".format(float(value))) # Open exasub.com in a web browser def open_link(event): webbrowser.open("http://www.exasub.com") # Create the main Tkinter window window = tk.Tk() window.title("Integral Control Demo") # Create the slider for adjusting the feedback stimulus slider = tk.Scale(window, from_=0, to=100, orient=tk.HORIZONTAL, length=300, command=slider_callback) slider.pack() # Create a label to display the feedback stimulus value feedback_label = tk.Label(window, text="Feedback Stimulus: {:.2f}".format(slider.get())) feedback_label.pack() # Create a label to display the integral term value control_label = tk.Label(window, text="Integral Term: ") control_label.pack() # Add a link to exasub.com link = tk.Label(window, text="Visit exasub.com", fg="blue", cursor="hand2", font=("Arial", 14)) link.pack() link.bind("<Button-1>", open_link) # Start the main loop in a separate thread import threading main_loop_thread = threading.Thread(target=main_loop) main_loop_thread.start() # Start the Tkinter event loop window.mainloop()
Explanation:
In the code snippet, we begin by setting up the graphical user interface (GUI) using tkinter. The GUI consists of a slider for adjusting the feedback stimulus, labels to display the feedback stimulus value and the integral term value, and a link to a website. The slider is used to simulate the process variable, while the labels provide real-time feedback on the control system’s behavior.
The integral control algorithm is implemented within the
integral_control
function. It calculates the integral term based on the error and the accumulated integral sum. The integral gain, represented byKi
, determines the contribution of the integral term to the control signal. By adjusting the integral gain, the system’s response can be fine-tuned.The main loop continuously reads the process variable from the slider and calculates the error by comparing it to the desired setpoint. It then calls the
integral_control
function to compute the integral term. The integral term is used to actuate the control signal or update the label in the GUI, providing a visual representation of the control system’s behavior.Importance of Integral Control:
Integral control is essential in control systems engineering for several reasons:
- Reducing Steady-state Error: Integral control helps to eliminate or minimize any steady-state error, ensuring that the system reaches and maintains the desired setpoint accurately.
- System Stability: By continuously adapting the control signal based on the accumulated error, integral control improves the system’s stability and responsiveness. It enables the system to overcome disturbances and maintain optimal performance.
- Robustness: Integral control enhances the control system’s robustness by accounting for systematic biases and external disturbances. It enables the system to adapt to changing conditions and maintain accurate control.
Conclusion:
Integral control is a key component of control systems engineering, enabling precise regulation and optimization of processes. By integrating the error over time, integral control reduces steady-state error and enhances system performance. In this blog post, we explored integral control and its implementation using Python’s tkinter library. We also discussed the importance of integral control in achieving robust and stable control systems.
As you delve further into control systems engineering, consider exploring additional control techniques, such as proportional and derivative control, to create more advanced control systems. Experimenting with different control strategies will deepen your understanding of control systems and their practical applications.
-
Proportional Control Demo using Slider in Tkinter
Understanding Proportional Control:
Proportional control is a basic feedback control technique that adjusts the control signal proportionally to the error between a desired setpoint and the process variable. The process variable represents the current state of the system being controlled. By continuously monitoring and adjusting the control signal, the system strives to minimize the error and achieve the desired setpoint.I have created this simple program using python and tkinter library.
When this program is run. A slider will appear which you can move.
A set point of 50 is given as the default value.
When you start the program the slider will be at 0 position. As you increase your slider you will see a change in the control signal parameter.This Control Signal will be 0 at your set point which is 50.
As you go past the set point the control signal will become negative.The system will keep changing the control signal to make the slider reach it’s set point.
Code
import tkinter as tk import time import webbrowser # Proportional control function def proportional_control(error): # Proportional gain Kp = 0.5 control_signal = Kp * error return control_signal # Main loop def main_loop(): setpoint = 50 # Desired setpoint process_variable = 0 # Initial process variable while True: # Read process variable from the slider process_variable = slider.get() # Calculate the error error = setpoint - process_variable # Apply proportional control control_signal = proportional_control(error) # Actuate the control signal (in this example, update the label) control_label.configure(text="Control Signal: {:.2f}".format(control_signal)) time.sleep(0.1) # Sleep for 0.1 seconds # Callback function for the slider def slider_callback(value): feedback_label.configure(text="Feedback Stimulus: {:.2f}".format(float(value))) # Open exasub.com in a web browser def open_link(event): webbrowser.open("http://www.exasub.com") # Create the main Tkinter window window = tk.Tk() window.title("Proportional Control Demo") # Create the slider for adjusting the feedback stimulus slider = tk.Scale(window, from_=0, to=100, orient=tk.HORIZONTAL, length=300, command=slider_callback) slider.grid(row=0, column=0, columnspan=2, padx=10, pady=10) # Create a label to display the feedback stimulus value feedback_label = tk.Label(window, text="Feedback Stimulus: {:.2f}".format(slider.get())) feedback_label.grid(row=1, column=0, padx=10, pady=5) # Create a label to display the control signal value control_label = tk.Label(window, text="Control Signal: ") control_label.grid(row=1, column=1, padx=10, pady=5) # Add a link to exasub.com link = tk.Label(window, text="Visit exasub.com", fg="blue", cursor="hand2", font=("Arial", 14)) link.grid(row=2, column=0, columnspan=2, padx=10, pady=5) link.bind("<Button-1>", open_link) # Start the main loop in a separate thread import threading main_loop_thread = threading.Thread(target=main_loop) main_loop_thread.start() # Start the Tkinter event loop window.mainloop()
Let’s dive into the code provided and understand how the proportional control demo works.# Main loop def main_loop(): setpoint = 50 # Desired setpoint process_variable = 0 # Initial process variable while True: # Read process variable from the slider process_variable = slider.get() # Calculate the error error = setpoint - process_variable # Apply proportional control control_signal = proportional_control(error) # Actuate the control signal (in this example, update the label) control_label.configure(text="Control Signal: {:.2f}".format(control_signal)) time.sleep(0.1) # Sleep for 0.1 seconds
Explanation of the Code:
The provided code demonstrates a simple scenario where the process variable is obtained from a slider widget. Here’s a breakdown of the code’s key components:- Setpoint: The
setpoint
variable represents the desired value or setpoint that we want the process variable to reach. - Process Variable: The
process_variable
variable holds the current value of the system being controlled, obtained from the slider widget. - Error Calculation: The error is calculated by subtracting the process variable from the setpoint. The error represents the deviation of the process variable from the desired value.
- Proportional Control: The
proportional_control
function, not provided in the code snippet, applies the proportional control algorithm. This function takes the error as input and computes the control signal accordingly. - Actuation: In this example, the control signal is applied by updating a label (
control_label
) to display the control signal value. In a real-world scenario, the control signal would be used to actuate a physical system, such as adjusting a motor’s speed or a valve’s position. - Timing: To ensure the control loop operates at a reasonable speed, a small delay of 0.1 seconds is introduced using
time.sleep(0.1)
. This delay allows the control system to stabilize before the next iteration.
Understanding Proportional Control:
Proportional control works by adjusting the control signal in proportion to the error. The control signal can be interpreted as an effort or corrective action to reduce the error. In this demo, the control signal is calculated by theproportional_control
function, which is not provided in the code snippet.The proportional control algorithm typically involves multiplying the error by a constant gain, known as the proportional gain (Kp). The control signal is then obtained by multiplying the error with Kp. The value of Kp determines the system’s responsiveness to the error, and finding the appropriate gain is crucial for stable and efficient control.
Conclusion:
The proportional control demo showcased in this blog post provides a basic understanding of how proportional control operates within a control system. By continuously adjusting the control signal based on the error between the setpoint and the process variable, proportional control helps bring the system closer to the desired state. Proportional control is just one of many control techniques, and understanding its principles is vital for delving into more advanced control strategies.Remember that proportional control alone may not be sufficient for complex systems, as it lacks the ability to anticipate and account for system dynamics. Nonetheless, it forms the foundation for more advanced control techniques like PID (Proportional-Integral-Derivative) control.
So go ahead, experiment with the demo code, and explore the fascinating world of control systems!
- Setpoint: The
-
How to Transmit Data via UART with ATmega328P in AVR C using Arduino IDE
EnglishDeutschHindiTo transmit data via UART with the ATmega328P microcontroller in AVR C using the Arduino IDE, you can follow these steps:
- Include the necessary header files:
#include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <stdlib.h>
- Define the UART settings:
#define BAUDRATE 9600 #define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
- Initialize UART by configuring the baud rate and other settings:
void uart_init() { UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8); UBRR0L = (uint8_t)(BAUD_PRESCALLER); UCSR0B = (1 << TXEN0); // Enable transmitter UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8-bit data format }
- Implement the function to transmit data:
void uart_transmit(uint8_t data) { while (!(UCSR0A & (1 << UDRE0))); // Wait for empty transmit buffer UDR0 = data; // Put data into the buffer, sends the data }
- Call the uart_init() function in your setup() function to initialize UART communication:
void setup() { // Other setup code... uart_init(); // More setup code... }
- Use uart_transmit() to send data:
void loop() { // Transmit a character uart_transmit('A'); // Delay between transmissions _delay_ms(1000); }
Make sure to connect the appropriate UART pins (TX) to the corresponding pins on your Arduino board. Additionally, set the correct BAUDRATE value based on your desired communication speed.
Demo Program That Transmits String of Characters
#include <avr/io.h> #include <util/delay.h> #define BAUDRATE 9600 #define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1) void uart_init() { UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8); UBRR0L = (uint8_t)(BAUD_PRESCALLER); UCSR0B = (1 << TXEN0); // Enable transmitter UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8-bit data format } void uart_transmit(uint8_t data) { while (!(UCSR0A & (1 << UDRE0))); // Wait for empty transmit buffer UDR0 = data; // Put data into the buffer, sends the data } void uart_transmit_string(const char* str) { for (size_t i = 0; str[i] != '\0'; ++i) { uart_transmit(str[i]); _delay_ms(100); // Delay between character transmissions } } void setup() { // Initialize UART uart_init(); } void loop() { // Transmit a string uart_transmit_string("Hello, world!"); // Delay before transmitting again _delay_ms(2000); }
Um Daten über UART mit dem ATmega328P Mikrocontroller in AVR C unter Verwendung der Arduino IDE zu übertragen, können Sie die folgenden Schritte befolgen:
Fügen Sie die erforderlichen Header-Dateien ein:
#include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <stdlib.h>
Definieren Sie die UART-Einstellungen:
#define BAUDRATE 9600 #define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
Initialisieren Sie UART, indem Sie die Baudrate und andere Einstellungen konfigurieren:
void uart_init() { UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8); UBRR0L = (uint8_t)(BAUD_PRESCALLER); UCSR0B = (1 << TXEN0); // Sender aktivieren UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8-Bit Datenformat }
Implementieren Sie die Funktion zum Senden von Daten:
void uart_transmit(uint8_t data) { while (!(UCSR0A & (1 << UDRE0))); // Warten auf leeren Sendepuffer UDR0 = data; // Daten in den Puffer schreiben und senden }
Rufen Sie die Funktion uart_init() in Ihrer setup() Funktion auf, um die UART-Kommunikation zu initialisieren:
void setup() { // Andere Setup-Code... uart_init(); // Weitere Setup-Code... }
Verwenden Sie uart_transmit(), um Daten zu senden:
void loop() { // Ein Zeichen übertragen uart_transmit('A'); // Verzögerung zwischen den Übertragungen _delay_ms(1000); }
Stellen Sie sicher, dass Sie die entsprechenden UART-Pins (TX) mit den entsprechenden Pins auf Ihrem Arduino-Board verbinden. Stellen Sie außerdem den korrekten BAUDRATE-Wert entsprechend Ihrer gewünschten Kommunikationsgeschwindigkeit ein.
Demo-Programm zum Senden einer Zeichenkette von Zeichen
#include <avr/io.h> #include <util/delay.h> #define BAUDRATE 9600 #define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1) void uart_init() { UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8); UBRR0L = (uint8_t)(BAUD_PRESCALLER); UCSR0B = (1 << TXEN0); // Enable transmitter UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8-bit data format } void uart_transmit(uint8_t data) { while (!(UCSR0A & (1 << UDRE0))); // Wait for empty transmit buffer UDR0 = data; // Put data into the buffer, sends the data } void uart_transmit_string(const char* str) { for (size_t i = 0; str[i] != '\0'; ++i) { uart_transmit(str[i]); _delay_ms(100); // Delay between character transmissions } } void setup() { // Initialize UART uart_init(); } void loop() { // Transmit a string uart_transmit_string("Hello, world!"); // Delay before transmitting again _delay_ms(2000); }
एटीमेगा328पी माइक्रोकंट्रोलर के साथ AVR C और Arduino IDE का उपयोग करके UART के माध्यम से डेटा भेजने के लिए, आप निम्नलिखित चरणों का पालन कर सकते हैं:
आवश्यक हेडर फ़ाइलें शामिल करें:
#include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <stdlib.h>
UART सेटिंग्स को परिभाषित करें:
#define BAUDRATE 9600 #define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)
बॉड दर और अन्य सेटिंग्स को कॉन्फ़िगर करके UART को प्रारंभ करें:
void uart_init() { UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8); UBRR0L = (uint8_t)(BAUD_PRESCALLER); UCSR0B = (1 << TXEN0); // ट्रांसमीटर सक्षम करें UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8-बिट डेटा फ़ॉर्मेट }
डेटा भेजने के लिए फ़ंक्शन को लागू करें:
void uart_transmit(uint8_t data) { while (!(UCSR0A & (1 << UDRE0))); // खाली ट्रांसमिट बफर के लिए प्रतीक्षा करें UDR0 = data; // डेटा को बफर में डालें, डेटा भेजें }
आपकी सेटअप() फ़ंक्शन में uart_init() फ़ंक्शन को कॉल करें, UART संचार को प्रारंभ करने के लिए:
void setup() { // अन्य सेटअप कोड... uart_init(); // अधिक सेटअप कोड... }
डेटा भेजने के लिए uart_transmit() का उपयोग करें:
void loop() { // एक वर्ण भेजें uart_transmit('A'); // भेजने के बीच में विलंब _delay_ms(1000); }
उचित UART पिन (TX) को अपने Arduino बोर्ड के संबंधित पिनों से कनेक्ट करने का सुनिश्चित करें। इसके अलावा, अपनी इच्छित संचार गति के आधार पर सही BAUDRATE मान सेट करें।
वर्ण स्ट्रिंग भेजने का डेमो प्रोग्राम
#include <avr/io.h> #include <util/delay.h> #define BAUDRATE 9600 #define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1) void uart_init() { UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8); UBRR0L = (uint8_t)(BAUD_PRESCALLER); UCSR0B = (1 << TXEN0); // Enable transmitter UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); // 8-bit data format } void uart_transmit(uint8_t data) { while (!(UCSR0A & (1 << UDRE0))); // Wait for empty transmit buffer UDR0 = data; // Put data into the buffer, sends the data } void uart_transmit_string(const char* str) { for (size_t i = 0; str[i] != '\0'; ++i) { uart_transmit(str[i]); _delay_ms(100); // Delay between character transmissions } } void setup() { // Initialize UART uart_init(); } void loop() { // Transmit a string uart_transmit_string("Hello, world!"); // Delay before transmitting again _delay_ms(2000); }