Posted on Leave a comment

How to Create a Resistor Color Code Calculator with GUI using Tkinter in Python

Resistor Color Code Calculator

exasub.com

This code is a Resistor Color Code Calculator. A resistor is an electronic component used in circuits to control the flow of electricity. The colors of the bands on the resistor indicate the resistance value of the resistor. This code allows you to select the color of the four bands on the resistor and then calculate the resistance value of the resistor.

The code uses a graphical user interface (GUI) built using a library called tkinter. The GUI consists of labels, dropdown menus, a button, and a link. The dropdown menus allow you to select the colors of the four bands on the resistor. The button, when pressed, calculates the resistance value of the resistor and displays it on the screen. The link is a hyperlink that takes you to a website.

The code defines two dictionaries that hold the color codes and tolerance values for resistors. The calculate_resistance function uses the selected colors to calculate the resistance value of the resistor. The open_website function opens a website when the link is clicked.

Code

import tkinter as tk
import webbrowser

# Define the color code values
color_codes = {
    "black": {"value": 0, "color": "#000000"},
    "brown": {"value": 1, "color": "#964B00"},
    "red": {"value": 2, "color": "#FF0000"},
    "orange": {"value": 3, "color": "#FFA500"},
    "yellow": {"value": 4, "color": "#FFFF00"},
    "green": {"value": 5, "color": "#008000"},
    "blue": {"value": 6, "color": "#0000FF"},
    "violet": {"value": 7, "color": "#8B00FF"},
    "gray": {"value": 8, "color": "#808080"},
    "white": {"value": 9, "color": "#FFFFFF"}
}

# Define the tolerance values
tolerances = {
    "brown": {"value": 1, "color": "#964B00"},
    "gold": {"value": 5, "color": "#FFD700"},
    "silver": {"value": 10, "color": "#C0C0C0"}
}

# Define the GUI
root = tk.Tk()
root.title("Resistor Color Code Calculator")

# Define the functions
def calculate_resistance(band1, band2, band3, band4):
    resistance_value = (color_codes[band1]["value"] * 10 + color_codes[band2]["value"]) * (10 ** color_codes[band3]["value"])
    if band4 != "none":
        tolerance_value = tolerances[band4]["value"]
        return f"Resistance value: {resistance_value} ohms, Tolerance: ±{tolerance_value}%"
    else:
        return f"Resistance value: {resistance_value} ohms"

def open_website():
    webbrowser.open_new("http://www.exasub.com")

# Define the GUI elements
label1 = tk.Label(root, text="Select the color of the first band:")
label1.grid(row=0, column=0)

band1_var = tk.StringVar(root)
band1_var.set("black")

band1_color_label = tk.Label(root, bg=color_codes[band1_var.get()]["color"], width=10)
band1_color_label.grid(row=0, column=1)

band1_dropdown = tk.OptionMenu(root, band1_var, *color_codes.keys(), command=lambda _: band1_color_label.config(bg=color_codes[band1_var.get()]["color"]))
band1_dropdown.grid(row=0, column=2)

label2 = tk.Label(root, text="Select the color of the second band:")
label2.grid(row=1, column=0)

band2_var = tk.StringVar(root)
band2_var.set("black")

band2_color_label = tk.Label(root, bg=color_codes[band2_var.get()]["color"], width=10)
band2_color_label.grid(row=1, column=1)

band2_dropdown = tk.OptionMenu(root, band2_var, *color_codes.keys(), command=lambda _: band2_color_label.config(bg=color_codes[band2_var.get()]["color"]))
band2_dropdown.grid(row=1, column=2)

label3 = tk.Label(root, text="Select the color of the third band:")
label3.grid(row=2, column=0)

band3_var = tk.StringVar(root)
band3_var.set("black")

band3_color_label = tk.Label(root, bg=color_codes[band3_var.get()]["color"], width=10)
band3_color_label.grid(row=2, column=1)

band3_dropdown = tk.OptionMenu(root, band3_var, *color_codes.keys(), command=lambda _: band3_color_label.config(bg=color_codes[band3_var.get()]["color"]))
band3_dropdown.grid(row=2, column=2)

label4 = tk.Label(root, text="Select the color of the fourth band (optional):")
label4.grid(row=3, column=0)

band4_var = tk.StringVar(root)
band4_var.set("gold")

band4_color_label = tk.Label(root, bg=tolerances[band4_var.get()]["color"], width=10)
band4_color_label.grid(row=3, column=1)

band4_dropdown = tk.OptionMenu(root, band4_var, *(["none"] + list(tolerances.keys())), command=lambda _: band4_color_label.config(bg=tolerances[band4_var.get()]["color"]))
band4_dropdown.grid(row=3, column=2)

calculate_button = tk.Button(root, text="Calculate", command=lambda: result_label.config(text=calculate_resistance(band1_var.get(), band2_var.get(), band3_var.get(), band4_var.get())))
calculate_button.grid(row=4, column=1)

result_label = tk.Label(root, text="", font=("Arial", 14))
result_label.grid(row=5, column=0, columnspan=3)

link_label = tk.Label(root, text="exasub.com", font=("Arial", 14), fg="blue", cursor="hand2")
link_label.grid(row=6, column=0, pady=10)
link_label.bind("<Button-1>", lambda event: open_website())

root.mainloop()

Posted on Leave a comment

How to Create a Digital Clock Using Python

A digital clock is a very common type of clock that displays the time in digits, as opposed to an analog clock that displays the time using clock hands. With Python, you can easily create a digital clock using the Tkinter GUI toolkit. In this article, we will show you how to create a digital clock using Python.

Step 1: Importing Required Libraries We need to import the following libraries to create a digital clock in Python:

from tkinter import *
import time

Here, we import the Tkinter library for creating the graphical user interface, and the time library for working with time and dates in Python.

Step 2: Creating the Digital Clock Class We will create a class called DigitalClock that contains the code for creating the digital clock.

class DigitalClock:
    def __init__(self, root):
        self.root = root
        self.root.title("Digital Clock")
        self.root.geometry("300x200")
        self.root.resizable(False, False)

        # Create a label for displaying the current time
        self.time_label = Label(root, text="", font=("Arial", 50))
        self.time_label.pack(pady=20)

        # Add your website name with a hyperlink
        self.link_label = Label(root, text="exasub.com", font=("Arial", 14), fg="blue", cursor="hand2")
        self.link_label.pack(pady=10)
        self.link_label.bind("<Button-1>", lambda event: self.open_website())

        # Update the time every second
        self.update_clock()

Here, we define the __init__ method that initializes the class with the root argument. We set the title of the window to “Digital Clock”, and set the window size to 300×200. We then create a label called time_label to display the current time with a font size of 50.

We also create another label called link_label that displays your website name with a hyperlink. When the user clicks on the link, the open_website method will be called.

Finally, we call the update_clock method to update the time every second.

Step 3: Updating the Clock We will now define the update_clock method that will update the clock every second.

def update_clock(self):
    # Get the current time and format it
    current_time = time.strftime("%H:%M:%S")
    self.time_label.config(text=current_time)

    # Schedule the next update after 1 second
    self.root.after(1000, self.update_clock)

Here, we get the current time using the strftime method of the time library, and format it in the HH:MM:SS format. We then set the text of the time_label to the current time using the config method.

We also schedule the next update after 1 second using the after method of the root window.

Step 4: Opening the Website We will define the open_website method that will open your website when the user clicks on the hyperlink.

def open_website(self):
    import webbrowser
    webbrowser.open_new("http://www.exasub.com")

Here, we import the webbrowser library and use the open_new method to open your website.

Step 5: Running the Program Finally, we will create the main method and run the program.

if __name__ == "__main__":
    root = Tk()
    clock = DigitalClock(root)
    root.mainloop()

Here is the complete code for creating a digital clock using Python:

from tkinter import *
import time

class DigitalClock:
    def __init__(self, root):
        self.root = root
        self.root.title("Digital Clock")
        self.root.geometry("300x200")
        self.root.resizable(False, False)

        # Create a label for displaying the current time
        self.time_label = Label(root, text="", font=("Arial", 50))
        self.time_label.pack(pady=20)

        # Add your website name with a hyperlink
        self.link_label = Label(root, text="exasub.com", font=("Arial", 14), fg="blue", cursor="hand2")
        self.link_label.pack(pady=10)
        self.link_label.bind("<Button-1>", lambda event: self.open_website())

        # Update the time every second
        self.update_clock()

    def update_clock(self):
        # Get the current time and format it
        current_time = time.strftime("%H:%M:%S")
        self.time_label.config(text=current_time)

        # Schedule the next update after 1 second
        self.root.after(1000, self.update_clock)

    def open_website(self):
        import webbrowser
        webbrowser.open_new("http://www.exasub.com")

if __name__ == "__main__":
    root = Tk()
    clock = DigitalClock(root)
    root.mainloop()
Posted on Leave a comment

What are Computer vision libraries?

Computer Vision is a rapidly growing field that deals with enabling machines to interpret, analyze, and understand digital images and videos. Here are some of the top computer vision libraries that can help developers to build powerful computer vision applications.

OpenCV

OpenCV is a widely-used open-source computer vision library that provides developers with a range of tools for image and video analysis, object detection, face recognition, and more. OpenCV is written in C++ and supports multiple programming languages such as Python, Java, and MATLAB.

  • Official website: https://opencv.org/
  • User-friendliness: Easy to use with extensive documentation and tutorials.
  • Community support: Large and active community with frequent updates and contributions.

TensorFlow

TensorFlow is an open-source machine learning framework that includes a range of tools for image recognition, object detection, and classification. TensorFlow supports multiple programming languages, including Python, C++, and Java.

  • Official website: https://www.tensorflow.org/
  • User-friendliness: Easy to use with extensive documentation and tutorials.
  • Community support: Large and active community with frequent updates and contributions.

PyTorch

PyTorch is an open-source machine-learning library that includes a range of tools for image recognition, object detection, and segmentation. PyTorch supports multiple programming languages, including Python, C++, and Java.

  • Official website: https://pytorch.org/
  • User-friendliness: Easy to use with extensive documentation and tutorials.
  • Community support: Large and active community with frequent updates and contributions.

Caffe

Caffe is a deep learning framework that includes tools for image classification, segmentation, and detection. Caffe is written in C++ and supports multiple programming languages such as Python and MATLAB.

  • Official website: http://caffe.berkeleyvision.org/
  • User-friendliness: Moderate difficulty with a learning curve.
  • Community support: Medium-sized community with frequent updates and contributions.

Keras

Keras is an open-source deep-learning library that provides tools for image recognition, object detection, and classification. Keras supports multiple programming languages, including Python and R.

  • Official website: https://keras.io/
  • User-friendliness: Easy to use with extensive documentation and tutorials.
  • Community support: Large and active community with frequent updates and contributions.

scikit-image

scikit-image is a Python library that provides tools for image processing, including filtering, segmentation, and feature extraction.

  • Official website: https://scikit-image.org/
  • User-friendliness: Easy to use with extensive documentation and tutorials.
  • Community support: Large and active community with frequent updates and contributions.

These computer vision libraries offer a wide range of tools and functionalities for developers to work with. Choosing the right library largely depends on the requirements and specific use cases of the project.

Posted on Leave a comment

Introduction to Numerical Integration using C

Numerical integration plays a crucial role in many applications related to embedded systems, such as control systems, signal processing, and digital filters. However, implementing numerical integration algorithms on embedded systems presents unique challenges due to limited computing resources such as memory, processing power, and clock speed.

To address these challenges, developers must carefully choose numerical integration methods that are well-suited for embedded systems. The choice of method depends on the specific requirements of the problem being solved and the available computing resources.

Some of the most commonly used numerical integration methods in embedded systems include the Trapezoidal Rule, Simpson’s Rule, and the Midpoint Rule. These methods are relatively simple to implement and require minimal memory and processing power, making them well-suited for use in low-power embedded systems.

In addition to these basic methods, more advanced numerical integration methods can also be used in embedded systems with larger amounts of memory and processing power. These methods include Gaussian Quadrature, Monte Carlo Integration, Romberg Integration, Adaptive Quadrature, Runge-Kutta Method, Newton-Cotes Formulas, and Chebyshev Quadrature.

Implementing numerical integration algorithms on embedded systems requires careful consideration of factors such as memory usage, processing power, and clock speed. Developers must also optimize their code to ensure efficient use of available resources and avoid memory leaks, stack overflows, and other common pitfalls.

Despite these challenges, numerical integration remains an essential tool for many applications related to embedded systems. With the right choice of method and careful optimization of code, developers can achieve high accuracy and efficiency in numerical integration calculations on embedded systems.

The Need for Numerical Integration

In many cases, it is not possible to find the exact analytical solution for a definite integral, either due to the complexity of the function or the limits of integration. In such cases, numerical integration provides a useful alternative for approximating the integral by dividing the interval into smaller subintervals, and then computing the area under the curve for each subinterval.

Here’s a list of functions that can solve definite integrals in embedded C:

  • Trapezoidal Rule
  • Simpson’s Rule
  • Gaussian Quadrature
  • Monte Carlo Integration
  • Romberg Integration
  • Adaptive Quadrature
  • Runge-Kutta Method (for solving ODEs)

Each of these methods has its advantages and disadvantages, and the choice of which method to use depends on the specific problem being solved and the available computing resources.

The Trapezoidal Rule and Simpson’s Rule are commonly used in embedded systems with limited RAM. These methods are relatively simple to implement and require minimal memory usage, making them well-suited for use in microcontrollers with limited resources. Additionally, these methods provide reasonably accurate results for many common functions, which further makes them popular choices for numerical integration in embedded systems.

Depending on the availability of RAM, different methods are available.

If the RAM is up to 32K, then integration methods considered, such as:

The Trapezoidal Rule and Simpson’s Rule are commonly used in embedded systems with limited RAM. These methods are relatively simple to implement and require minimal memory usage, making them well-suited for use in microcontrollers with limited resources. Additionally, these methods provide reasonably accurate results for many common functions, which further makes them popular choices for numerical integration in embedded systems.

If the RAM is increased to 60K, then some of the more computationally intensive integration methods can also be considered, such as:

  • Gaussian Quadrature: This method uses a weighted sum of function values at specific points to approximate the integral. It can provide higher accuracy than the Trapezoidal Rule and Simpson’s Rule for certain functions, but requires more memory and computational resources.
  • Monte Carlo Integration: This method uses random sampling to approximate the integral. It can provide accurate results for high-dimensional integrals, but can require a large number of function evaluations to achieve acceptable accuracy.
  • Romberg Integration: This method uses a recursive procedure to improve the accuracy of the Trapezoidal Rule. It can provide higher accuracy than the Trapezoidal Rule and Simpson’s Rule, but requires more memory and computational resources.
  • Adaptive Quadrature: This method adaptively subdivides the integration interval into smaller subintervals to achieve a desired level of accuracy. It can provide accurate results for functions with complex behavior, but can require a large number of function evaluations for high accuracy.

Note that the choice of integration method also depends on the specific requirements of the application and the available computing resources.

With an increased RAM of 512K, there are many numerical integration methods that can be used. Some of the most popular methods include:

  1. Gaussian Quadrature: This method provides high accuracy for a wide range of integrals but requires more memory than the Trapezoidal Rule or Simpson’s Rule.
  2. Monte Carlo Integration: This method involves randomly sampling points within the integration domain and is particularly useful for high-dimensional integrals. However, it requires a larger amount of memory than the Trapezoidal Rule or Simpson’s Rule due to the need to store a large number of random points.
  3. Romberg Integration: This method is a recursive extension of the Trapezoidal Rule and can achieve higher accuracy for a given number of function evaluations. However, it requires more memory to store the intermediate results of each recursive step.
  4. Adaptive Quadrature: This method dynamically adjusts the number of function evaluations based on the local behavior of the integrand, which can lead to higher accuracy for a given number of function evaluations. However, it requires more memory to store the intermediate results of each recursive step.
  5. Runge-Kutta Method: This method is commonly used for solving differential equations but can also be used for numerical integration. It provides higher accuracy than simple integration methods such as Trapezoidal Rule and Simpson’s Rule, but requires more memory to store the intermediate results of each step.
  6. Newton-Cotes Formulas: These are a family of numerical integration formulas that can achieve higher accuracy than simple integration methods. However, they require more memory to store the intermediate results of each step.
  7. Chebyshev Quadrature: This method uses the roots of Chebyshev polynomials to approximate the integral and can achieve high accuracy with fewer function evaluations than other methods. However, it requires more memory to store the coefficients of the Chebyshev polynomials.

Overall, the choice of numerical integration method will depend on the specific requirements of the problem being solved and the available computing resources. With a larger amount of RAM, more memory-intensive methods can be used, which can provide higher accuracy for a given number of function evaluations.

Posted on Leave a comment

What is turtle.Turtle() in python?

In Python, turtle.Turtle() is a function that creates and returns a new turtle object that can be used to draw graphics on a canvas.

The turtle graphics library in Python provides a simple way to create graphics and animations by allowing you to control a virtual turtle that moves on a canvas. The turtle can be moved around the canvas using commands such as forward(), backward(), left(), right(), etc.

To use the turtle graphics library, you first need to import the turtle module. Then, you can create a new turtle object using the turtle.Turtle() function. For example, the following code creates a new turtle and moves it forward by 100 units:

import turtle

t = turtle.Turtle()
t.forward(100)

You can also customize the appearance and behavior of the turtle object by setting various attributes such as its color, size, shape, and speed. For example, the following code creates a red turtle with a size of 5 and a speed of 2:

import turtle

t = turtle.Turtle()
t.color("red")
t.pensize(5)
t.speed(2)
t.forward(100)

Overall, the turtle.Turtle() function is the starting point for creating and controlling turtle objects in the turtle graphics library.

Posted on Leave a comment

How to make comments in python

In Python, you can make comments using the hash symbol (#).

Any text that appears after the hash symbol (#) on the same line is considered a comment and is ignored by the Python interpreter.

For example:

# This is a comment
print("Hello, world!")  # This is also a comment

In the above example, the first line is a comment, and it is ignored by the Python interpreter. The second line is a print statement, which will print “Hello, world!” to the console when executed. The third line is another comment, which is also ignored.

You can also use multi-line comments by enclosing them in triple quotes (“”” “””). For example:

"""
This is a multi-line
comment in Python.
"""

print("Hello, world!")

In this example, the first three lines are a multi-line comment, and they are ignored by the Python interpreter. The fourth line is a print statement, which will print “Hello, world!” to the console when executed.

Posted on Leave a comment

Merge Sort is bad for Embedded System

Merge sort is good if your system has plenty of memory to accommodate the temporary array.

Embedded systems have very limited memory and it is often fixed.

If the system has some other function that also runs concurrently. Then that memory also gets shortened.

Merge sort is good for a bigger system like the personal computer and business computer which have the bigger memory in which all the temporary array can reside.

The advantage of merge sort is that it is stable.

Since it takes a lot of space it is not useful for an embedded system, as they have a very small memory sometimes it is just KilloByte.
example:
ATmega328p = 2KB SRAM
ATtiny85 = 512B SRAM

Code for STM32F429ZIT6

This code redirects the printf statements towards the asynchronous UART.
As the size of input array for merge sort increases the space required to store temporary element increases, which eventually leads to stalling of the program.
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "stdlib.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/*
* Function Name: _write
* Function Description: Redirect the printf() statement towards the UART using the HAL_UART_Transmit
Author: Abhay

*/
int _write(int fd, char* ptr, int len) {
    HAL_UART_Transmit(&huart1, (uint8_t *) ptr, len, HAL_MAX_DELAY);
 //   HAL_UART_Transmit(&huart1, ptr, len, Timeout)
    return len;
}

// Merges two subarrays of arr[].
// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
void merge(int arr[], int l, int m, int r)
{
	int i, j, k;
	int n1 = m - l + 1;
	int n2 = r - m;

	/* create temp arrays */
	int L[n1], R[n2];

	/* Copy data to temp arrays L[] and R[] */
	for (i = 0; i < n1; i++)
		L[i] = arr[l + i];
	for (j = 0; j < n2; j++)
		R[j] = arr[m + 1 + j];

	/* Merge the temp arrays back into arr[l..r]*/
	i = 0; // Initial index of first subarray
	j = 0; // Initial index of second subarray
	k = l; // Initial index of merged subarray
	while (i < n1 && j < n2) {
		if (L[i] <= R[j]) {
			arr[k] = L[i];
			i++;
		}
		else {
			arr[k] = R[j];
			j++;
		}
		k++;
	}

	/* Copy the remaining elements of L[], if there
	are any */
	while (i < n1) {
		arr[k] = L[i];
		i++;
		k++;
	}

	/* Copy the remaining elements of R[], if there
	are any */
	while (j < n2) {
		arr[k] = R[j];
		j++;
		k++;
	}
}

/* l is for left index and r is right index of the
sub-array of arr to be sorted */
void mergeSort(int arr[], int l, int r)
{
	if (l < r) {
		// Same as (l+r)/2, but avoids overflow for
		// large l and h
		int m = l + (r - l) / 2;

		// Sort first and second halves
		mergeSort(arr, l, m);
		mergeSort(arr, m + 1, r);

		merge(arr, l, m, r);
	}
}

/* UTILITY FUNCTIONS */
/* Function to print an array */
void printArray(int A[], int size)
{
	int i;
	for (i = 0; i < size; i++)
		printf("%d ", A[i]);
	printf("\n");
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  int arr[] = { 12, 11, 13, 5, 6, 7,12};
        int arr_size = sizeof(arr) / sizeof(arr[0]);

//        for( int temp=0; temp<1023;temp++){
//  	arr[temp] = rand()*1000;
//  }
        printf("Given array is \n");
        printArray(arr, arr_size);

        mergeSort(arr, 0, arr_size - 1);

        printf("\nSorted array is \n");
        printArray(arr, arr_size);
     //   return 0;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOG, ledg_Pin|ledr_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pins : ledg_Pin ledr_Pin */
  GPIO_InitStruct.Pin = ledg_Pin|ledr_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
Posted on Leave a comment

Swapping of two numbers

Before Swapping :
a = 10
b = 2

After Swapping:
a = 2
b = 10

To do the swapping we have different approaches.
1. Swapping using a temporary variable
2. Swapping without using a temporary variable
3. Swapping using pointers

NOTE: We do not use of the second method in embedded system software writing. Because it would have to execute more instructions to perform the same operation with a temporary variable.

Swapping using a temporary variable

#include <stdio.h>
#include <stdlib.h>

int main(void) {
	int a = 10;
	int b = 3;
	int temp = 0;
	printf("Before Swapping");
	printf("\na = %d\tb = %d\n",a,b);

	temp = a;
	a = b;
	b = temp;

	printf("After Swapping");
	printf("\na = %d\tb = %d\n",a,b);

	return EXIT_SUCCESS;
}

Swapping without using a temporary variable

#include <stdio.h>
#include <stdlib.h>

int main(void) {
	int a = 10;
	int b = 3;
	int temp = 0;
	printf("Before Swapping");
	printf("\na = %d\tb = %d\n",a,b);

	a = a - b;
	b = a + b;
	a = b - a;

	printf("After Swapping");
	printf("\na = %d\tb = %d\n",a,b);

	return 1;
}

Swapping using pointers

When the memory size is very limited we prefer to do this.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
	int a = 10;
	int b = 3;
	int temp;
	int *x , *y;

	printf("Before Swapping");
	printf("\na = %d\tb = %d\n",a,b);

	x = &a;
	y = &b;
	temp = *x;
	*x = *y;
	*y = temp;

	printf("After Swapping");
	printf("\na = %d\tb = %d\n",a,b);
	
	return 1;
}
Posted on Leave a comment

How to make UART Serial Console using Pyserial, Tkinter in python

Screenshot

The serial console is written in a python programming language. The GUI is made using the Tkinter library and the serial interface functions are provided by the pyserial library.

you can install pyserial from command prompt(windows)/terminal(linux)

Python Code

from tkinter import *
from tkinter import ttk
import serial
import serial.tools.list_ports
import datetime
import threading
import multiprocessing
import os

#for printing debugging messages in console
dbg = 0

gRoot = Tk()
#gRoot.geometry("480x280")
gRoot.title("Serial Console")
sty = ttk.Style()
sty.theme_use("alt")
gRoot.columnconfigure(0,weight=1)
gRoot.rowconfigure(0,weight=1)
#sty.configure("gframe.TFrame",background="white")
gFrame = ttk.LabelFrame(gRoot,text="Connection Setting",padding=10)
gFrame.grid(column=1,row=1, sticky=(W,E))

#Frame for COM messages

gFrame21 = ttk.Frame(gRoot,padding=10)
gFrame21.grid(column=2,row=1, sticky=(W))
#gRoot.resizable(0,0)


for x in range(10):
    gFrame.columnconfigure(x,weight = x)
    gFrame.rowconfigure(x,weight = x)
    
label1=ttk.Label(gFrame, text = "Serial Console")
label1.grid(column=2,row=0)
gFrame.rowconfigure(0,weight=2)

sty.configure("label2.TLabel",borderwidth=4,relief="ridge",foreground="red",ipadx=10)
label2=ttk.Label(gFrame,sty="label2.TLabel", text = "Select Com Port")
label2.grid(column=1,row=1, sticky = (N,E,W,S))

"""
Com Port List
"""
#Start
ports = serial.tools.list_ports.comports()
com_port_list = [com[0] for com in ports]
com_port_list.insert(0,"Select an Option")
if dbg == 1:
    print(com_port_list)
#END
com_value_inside = StringVar()
baud_value_inside = StringVar()
baud_menu = ttk.OptionMenu(gFrame,baud_value_inside,"select baud rate","9600",
                           '19200','28800','38400','57600','76800',
                           '115200','128000','153600','230400','256000','460800','921600')
baud_menu.grid(column=3, row=1, sticky = (E))
def com_port_list_update():
    global ports
    global com_port_list
    ports = serial.tools.list_ports.comports()
    com_port_list = [com[0] for com in ports]
    com_port_list.insert(0,"Select an Option")
    if dbg == 1:
        print(com_port_list)
    com_menu = ttk.OptionMenu(gFrame,com_value_inside,*com_port_list)
    com_menu.grid(column=2, row=1, sticky = (E))
    #Frame for the COM LIST
    gRoot_com_list = Toplevel(gRoot)
    x = gRoot.winfo_x()
    y = gRoot.winfo_y()
    gRoot_com_list.geometry("+%d+%d" %(x+200,y+200))
    gFrame01 = ttk.Frame(gRoot_com_list,padding=10)
    gFrame01.grid(column=0,row=1, sticky=(W))
    #Create a horizontal scrollbar
    scrollbar = ttk.Scrollbar(gFrame01, orient= 'horizontal')
    scrollbar.grid(column=1,row=2, sticky=W+E)

    Lb1 = Listbox(gFrame01, xscrollcommand = 1, width = 50, font= ('Helvetica 8 bold'))
    counter = 0;
    for x in ports:
        Lb1.insert(counter, str(x))
    #print (counter)
    counter += 1
    Lb1.grid(column=1,row=1, sticky=W+E)
    Lb1.config(xscrollcommand= scrollbar.set)

    #Configure the scrollbar
    scrollbar.config(command= Lb1.xview)


def serial_print():
    global serFlag
    global ser
    global counter1
    x =""
    #print("Task 1 assigned to thread: {}".format(threading.current_thread().name))
    #print("ID of process running task 1: {}".format(os.getpid()))
    if(serFlag):
        if(ser.in_waiting>0):
            #
            try:
                x = ser.read(ser.in_waiting)
                #x = ser.readline(ser.in_waiting)
                #x = ser.read_until(expected='\n', size=ser.in_waiting)
                #print(x)
                y = str(counter1)+": "+str(datetime.datetime.now())+" -> "+str(x.decode())
                Lb2.insert(counter1, str(y))
                Lb2.see("end")
                #print (counter1)
                counter1 += 1
                #gFrame.after(100,serial_print)
            except:
                pass
        ser.flush()
        gFrame.after(100,serial_print)


ser = serial.Serial()
serFlag = 0
def serial_connect(com_port,baud_rate):
    global ser
    ser.baudrate = baud_rate
    ser.port = com_port
    ser.timeout = 1
    ser._xonxoff=1
    ser.bytesize=serial.EIGHTBITS
    ser.parity=serial.PARITY_NONE
    ser.stopbits=serial.STOPBITS_ONE
    ser.open()
    global serFlag
    serFlag = 1
    
    t1 = threading.Thread(target = serial_print, args = (), daemon=1)
    t1.start()
    #t1.join()
    """
    P1 = multiprocessing.Process(target = serial_print, args=())
    P1.start()
    P1.join()
    """
    #serial_print()
counter1 = 0;


    
def serial_close():
    global ser
    global serFlag
    serFlag = 0
    ser.close()
    
def submit_value():
    if dbg == 1:
        print("selected option: {}".format(com_value_inside.get()))
        print(" Baud Rate {}".format(baud_value_inside.get()))
    serial_connect(com_value_inside.get(),baud_value_inside.get())


Lb2 = Listbox(gFrame21, width = 100, xscrollcommand = 1)
Lb2.grid(column=1, row = 1, sticky = W+E)
Sb2 = ttk.Scrollbar(gFrame21,orient = 'vertical')
Sb2.config(command=Lb2.yview)
Sb2.grid(column = 2,row =1, sticky=N+S)
Sb2v = ttk.Scrollbar(gFrame21,orient = 'horizontal')
Sb2v.grid(column = 1,row =2, sticky=W+E)
Sb2v.config(command = Lb2.xview)
Lb2.configure(xscrollcommand = Sb2v.set, yscrollcommand = Sb2.set)

def clear_listbox():
    Lb2.delete(0,END)
    
subBtn = ttk.Button(gFrame,text="submit",command = submit_value)
subBtn.grid(column=4,row=1, sticky = (E))

RefreshBtn = ttk.Button(gFrame,text="Get List",command = com_port_list_update)
RefreshBtn.grid(column=2,row=2, sticky = (E))



closeBtn = ttk.Button(gFrame,text="Disconnect",command = serial_close)
closeBtn.grid(column=4,row=2, sticky = (E))

clearBtn = ttk.Button(gFrame,text="Clear Messages",command = clear_listbox)
clearBtn.grid(column=3,row=2, sticky = (E))



"""
#Add a Listbox Widget
listbox = Listbox(win, width= 350, font= ('Helvetica 15 bold'))
listbox.pack(side= LEFT, fill= BOTH)

#Add values to the Listbox
for values in range(1,101):
   listbox.insert(END, values)
"""
def donothing():
   filewin = Toplevel(gRoot)
   button = Button(filewin, text="Do nothing button")
   button.pack()

def About_me():
   filewin = Toplevel(gRoot)
   Label1 = Label(filewin, text = "EXASUB.COM").pack()
   button = Button(filewin, text="Quit", command = filewin.destroy)
   button.pack()

menubar = Menu(gRoot)
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="New", command=donothing)
filemenu.add_command(label="Open", command=donothing)
filemenu.add_command(label="Save", command=donothing)
filemenu.add_command(label="Save as...", command=donothing)
filemenu.add_command(label="Close", command=donothing)

filemenu.add_separator()

filemenu.add_command(label="Exit", command=gRoot.quit)
menubar.add_cascade(label="File", menu=filemenu)
editmenu = Menu(menubar, tearoff=0)
editmenu.add_command(label="Undo", command=donothing)

editmenu.add_separator()

editmenu.add_command(label="Cut", command=donothing)
editmenu.add_command(label="Copy", command=donothing)
editmenu.add_command(label="Paste", command=donothing)
editmenu.add_command(label="Delete", command=donothing)
editmenu.add_command(label="Select All", command=donothing)

menubar.add_cascade(label="Edit", menu=editmenu)
helpmenu = Menu(menubar, tearoff=0)
helpmenu.add_command(label="Help Index", command=donothing)
helpmenu.add_command(label="About...", command=donothing)
menubar.add_cascade(label="Help", menu=helpmenu)
menubar.add_command(label = "EXASUB.com", command = About_me)
menubar.add_separator()
menubar.add_command(label = "Quit", command = gRoot.destroy)

gRoot.config(menu=menubar)
gRoot.mainloop()
Posted on Leave a comment

How to install and also uninstall python packages using PIP

Python’s functionality can be extended with scripts that are made to do different tasks. They are sometimes super easy to work with and can perform a myriad of tasks with just a few lines of code.

You can browse through many packages here: https://pypi.org/

to install these packages you need to have python software already installed in your computer.

Open Command Prompt

syntax for installing a package using PIP

pip install your-package-name-here

And let’s say you want to work with UART or serial data. You can install pyserial.

pip install pyserial

after your work is done you can also remove or uninstall the package using

pip uninstall pyserial