• Wireless Plant Watering System using Raspberry Pi Pico W

    Every morning my mom waters the plant. She has to water them every day and sometimes in summer, she must provide water twice a day.

    In winter plant needs water when necessary.

    Solution:

    For the above problem, I developed this project using raspberry pi pico w.

    Here is what it does:

    1. It connects to the WiFi router. The wifi router allocates a fixed IP address. For that, I created a new entry in the DHCP bindings of the router.
    2. When you visit the IP address 192.168.1.101
    3. It samples the soil moisture sensor through the ADC. And display an HTML page that shows the status of ADC and the onboard LED.
    4. The HTML page also has a button for turning on the pump.
      I have kept it manual.
    5. When the PUMP ON button is pressed the water pump is turned ON. The water pump is connected via the L298n module. Which is controlled by a PWM signal of 1Khz frequency. The duty cycle is slowly increased to 75%.
      There is a timeout of 10 Seconds. If the timeout is reached the water pump will be turned off.

    Schematic Diagram

    Schematic Diagram

    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'
    '''
    # Pin GP9 (physical pin 5) on PicoZero
    GPIO_PIN = 9
    
    # Set up the GPIO pin as an output
    pin9 = machine.Pin(GPIO_PIN, machine.Pin.OUT)
    
    # Turn off the GPIO pin
    pin9.off()
    '''
    GPIO_PIN_9 = machine.Pin(9)
    pwm9 = machine.PWM(GPIO_PIN_9)
    
        
    def ADC():
        adc = machine.ADC(0)  # Initialize ADC on pin A0
        sensor_value = adc.read_u16()  # Read the analog value from the sensor
        # Add your code to process and display the sensor value as per your requirements
        #print(sensor_value)
        #time.sleep_ms(500)  # Delay between readings (adjust as needed)
        #sensor_value = 18756
        percentage = 100 - ((sensor_value / 65535) * 100)
        #print(f"sensor_value: {sensor_value} percentage: {percentage}")
        return sensor_value,percentage
        
        
    def gen_pwm(duration, timeout):
        # Set PWM frequency
        pwm9.freq(1000)  # Set frequency to 1 kHz
    
        start_time = time.ticks_ms()  # Get the initial timestamp
        pump_started = False
    
        while time.ticks_diff(time.ticks_ms(), start_time) < timeout:
            # Check water level using ADC
            ADC_Read = ADC()
            water_level = ADC_Read[1]
            #adc.read()
    
            if not pump_started and water_level < 50:
                # Start the pump by gradually increasing the duty cycle
                for duty in range(0, 32767, 100):
                    pwm9.duty_u16(duty)
                    time.sleep_ms(duration)  # Adjust the delay as needed for smooth transition
                    ADC_Read = ADC()
                    water_level = ADC_Read[1]
                    
                    if water_level >=50 :
                        break
                pump_started = True
    
            if water_level >= 50 or pump_started and water_level <= 0:
                # Stop the pump by setting the duty cycle to 0
                pwm9.duty_u16(0)
                break
    
        # Stop the PWM signal
        pwm9.duty_u16(0)
    
    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
        ADC_Value = ADC()
        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>
        <p style="font-size: 20px;">ADC Value is {ADC_Value[0]}</p>
        <p style="font-size: 20px;">ADC % is {ADC_Value[1]}</p>
        
        <form action="./pumpon" style="display: flex; justify-content: center;">
            <input type="submit" value="Pump on" style="font-size: 40px;" />
        </form>
        <form action="./pumpoff" style="display: flex; justify-content: center;">
            <input type="submit" value="Pump 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" 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
        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("'")
                        print(user_value)
            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 =='/pumpon?':
                #pin9.on()
                gen_pwm(10,10000)
                print("\n\n"+request)
                #state = 'OFF'
            elif request =='/pumpoff?':
                #pin9.off()
                print("Pump OFF")
            elif request == '/usrval':
              #  print("\n\n"+request)
                index = request.find('value=')
                
                if index != -1:
                    end_index = request.find(' ', index)
                    if end_index == -1:
                        end_index = len(request)
                    user_value = request[index + len('value='):end_index]
                    print(f"\n\nValue: \t {user_value}\n\n")
            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 2.8 inch LCD driver on Mini Stm32 V3.0 using STM32CubeIDE

    To use the 2.8-inch LCD.

    I first checked the hardware schematic to find out all the pins attached to the LCD.

    The LCD has a driver ic on its flex cable.
    when I read the device code from the IC. The IC is ILI9325

    You can check this post here for that

    Mini STM32 V3.0

    After checking the schematic diagram of both the development board and the LCD. It is time to create a project in STM32 Cube IDE.

    After creating the project this is what the pin arrangment looks like in the integrated cubemx of stm32cube ide.

    Download the LCD Library from below

    1. Download and extract the zip file.
    2. Inside you will find a folder named “LCD28”
    3. Copy that folder and place it into the driver folder of your stm32cubeide project.
    4. Insert the following header files into your main.c file
    /* USER CODE BEGIN Includes */
    #include "stm32f103xb.h"
    #include "stdio.h"
    #include "stdlib.h"
    #include "../../Drivers/LCD28/ili932x.h"
    
    /* USER CODE END Includes */
    1. Add the following code to initialize the LCD
    /* USER CODE BEGIN 2 */
      
    
    	HAL_GPIO_WritePin(LCD_BL_EN_GPIO_Port, LCD_BL_EN_Pin, GPIO_PIN_SET);
    	LCD_Init();
    	LCD_Clear(BLACK);
    
      /* USER CODE END 2 */
    1. Here are the list of functions you can use to make graphic on the 2.8 inch display
    void LCD_Clear(uint16_t Color);
    void LCD_Delay(uint32_t nCount);
    void LCD_DrawPoint(uint16_t x,uint16_t y);
    void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
    void Draw_Circle(uint8_t x0,uint16_t y0,uint8_t r);
    void LCD_Fill(uint8_t xsta,uint16_t ysta,uint8_t xend,uint16_t yend,uint16_t color);
    uint16_t WriteOneASCII(uint8_t *pucMsk,
                                  uint16_t x0,
                                  uint16_t y0,
                                  uint16_t color);
    uint16_t WriteOneHzChar(uint8_t *pucMsk,
                                   uint16_t x0,
                                   uint16_t y0,
                                   uint16_t color);
    void WriteString(uint16_t x0, uint16_t y0,uint8_t *pcStr, uint16_t color);

    Demo Program

    /* USER CODE BEGIN WHILE */
    
    	HAL_GPIO_WritePin(LCD_BL_EN_GPIO_Port, LCD_BL_EN_Pin, GPIO_PIN_SET);
    	HAL_Delay(1000);
    	LCD_Init();
    	LCD_Clear(BLACK);
    
    	uint8_t *textPtr;
    
    	// Example usage of the provided LCD functions
    	LCD_Clear(0xFFFF); // Clear the LCD screen with white color
    
    	// Draw a blue line from (10, 10) to (100, 50)
    	LCD_DrawLine(10, 10, 100, 50);
    
    	// Draw a filled rectangle from (120, 50) to (180, 150) with red color
    	LCD_Fill(120, 50, 180, 150, 0xF800);
    
    	// Draw a green circle with center at (200, 200) and radius 20
    	Draw_Circle(200, 200, 20);
    
    	// Write a string at (50, 250) with black color
    
    	textPtr = ((uint8_t *)"Hello www.EXASUB.com");
    	WriteString(50,(250),textPtr,RED);
    
    
    
    	// Color array in the desired order
    	uint16_t colors[] = {BLACK, NAVY, DGREEN, DCYAN, MAROON, PURPLE, OLIVE, LGRAY,
    			DGRAY, BLUE, GREEN, CYAN, RED, MAGENTA, YELLOW, WHITE};
    	uint8_t numColors = sizeof(colors) / sizeof(colors[0]);
    
    	// Index variable for cycling through colors
    	uint8_t colorIndex = 0;
    	while (1)
    	{
    		/* USER CODE END WHILE */
    		textPtr = ((uint8_t *)"Hello www.EXASUB.com");
    		WriteString(50,(250),textPtr,colors[colorIndex]);
    		// Increment the color index and wrap around if necessary
    		colorIndex = (colorIndex + 1) % numColors;
    		textPtr = ((uint8_t *)"ScIeNcE TeCh EnG MaTh ");
    		WriteString(10,(270),textPtr,colors[colorIndex]);
    
    		HAL_Delay(250);
    
    
    		/* USER CODE BEGIN 3 */
    	}
    	/* USER CODE END 3 */
  • Tiny2313 Dev Board

    This is a Tiny development board I made. It is a small size and is ideal for quick prototyping. I made for the Attiny2313 microcontrollers. I started programming with this microcontroller board. Back then I did it on a breadboard. But since now I can know a few things about PCB etching I made this PCB.


    Attiny2313 Datasheet
    https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2543-AVR-ATtiny2313_Datasheet.pdf

    I made this circuit schematic.

    Schematic Diagram of Tiny2313 Dev Board
    Schematic Diagram of Tiny2313 Dev Board

    I changed a few components from the schematic. The current limiting resistor for the LED is 330 ohm in the schematic whereas I used 1.8k ohm. While performing few tests on the LED I found that the LED is visible at that lower current value.

    For a 5 V supply and an 1800 ohm resistor, the current will be 2.7 mA. Which is enough for visual identification at short distances.

    The Two buttons are not yet populated. They are provided as a future provision.

    The Tiny2313 Dev Board is programmed using the USBASP v2 programmer.

    The 6-pin male header is connected to the programmer. When not doing the programming the pins can be used as GPIO.

    Here is the table of components I used for this PCB.

    ComponentsDescriptionQuantityPopulated
    ATtiny2313 PDIPMicrocontroller1yes
    PDIP 20 Pin IC SocketMicrocontroller IC Socket1yes
    8Mhz Crystal Oscillator HC49Crystal Oscillator1yes
    12pf Ceramic Disc CapacitorCrystal Load Capacitors2yes
    1×2 Male Berg HeaderFor Power Connection1yes
    1×3 Male Berg HeaderFor UART (RX, TX) and INT01yes
    1×6 Male Berg HeaderFor Programming and as GPIO1yes
    LED 3mm Red clear lensLED1yes
    1.8k Resistor 1/8w LED Current Limiting Resistor1yes
    10k Resistor 1/4wPull Up Resistor For RESET1yes
    10k Resistor 1/8wPull Up resistors2no
    Tactile Switch 2 pinPush Buttons 2no

    I designed the PCB in KiCad. And made the PCB using etching photoresist.

    You can read How to make single-layer PCB using Dry Photoresist Film Etching Method

    As you can see in the image bellow . Home PCB making is not a perfect solution. But it gives you immense learning about the process.

  • How to make single-layer PCB using Dry Photoresist Film Etching Method

    There are various methods to create PCBs, and using dry photoresist film offers a convenient and cost-effective solution.

    The step-by-step process of making a PCB using dry photoresist film.

    Materials Needed:

    1. Copper-clad PCB board
    2. Dry photoresist film
    3. UV exposure unit
    4. PCB layout design (printed or digital)
    5. Chemical etchant (e.g., ferric chloride)
    6. Developer solution (Sodium carbonate, sodium hydroxide etc)
    7. Etching tank or tray
    8. Protective gloves and eyewear
    9. Fine-grit sandpaper

    Step 1: Design and Print the PCB Layout

    In the image below you can see the PCB. I first designed the layout and then i printed the layout on a transparent OHP sheet using a black laser printer.

    Tiny2313 Dev Board Layout Printed on an OHP sheet using Laser printer

    Step 2: Prepare the Copper-Clad PCB Board

    Then I cut a piece of Copper Clad board.

    Then I cleaned the Copper Clad board first by scrubbing using a kitchen utensil scrubber which has a small grit size. I also applied utensil cleaning powder as a compound. Which is basically calcium carbonate(CaCO3).

    Clean the copper-clad board with fine-grit sandpaper to remove any dirt or oxidation. Ensure a smooth and clean surface for optimal adhesion of the dry photoresist film.

    Step 3: Apply the Dry Photoresist Film

    After that, I cut the photoresist film. Then I peeled the protective plastic from it. And placed it on the PCB. I then used a visiting card to squeeze out any air. I ensured it is as smooth as possible.
    Then I place it on a wooden plank and covered it with a piece of cotton cloth. And I applied Hot cloth iron (Set the temperature setting for Cotton). While I applied it I also put some pressure so that it get stuck to the PCB.
    NOTE: it is a very delicate process. Only by trial and error, you will find the right temperature setting and duration of heat application.

    Step 4: Expose the PCB to UV Light

    After that, I placed the OHP sheet cutout which has the layout printed on it. Then I put this sandwich of PCB and OHP under a homemade UV box.

    The UV box is made from a shoebox that has a Phillips UV tube light strapped on the side using two zip ties. I do not remember the exact timings now, but it is somewhere between 1 minute to 2 minutes.

    Step 5: Developing Photoresist Film

    After that, the Copper clad board with photoresist is put into a solution made of water and sodium carbonate.
    Why sodium carbonate?
    Because at that time there was a lockdown so that’s why.
    Sodium carbonate was the only chemical available at that time for the development of the photoresist.
    NOTE: You need to develop the photoresist in a completely dark room or under red light(zero-watt bulb).

    Step 6: Etching the PCB

    After the developing process, you can put it into the etching solution made of water and ferric chloride. Make sure to vibrate the solution. As it will fasten the etching process.

    Note: you can set up a double boiler for faster results.
    I place a stainless steel vessel filled with water on an induction stove. and placed another plastic bowl filled with the etching solution and the PCB, inside the stainless steel vessel. Remember to heat it slowly as you want the etching solution to heat up every so slightly and not vapourize.

    Step 7: Removing Photoresist

    After the etching process is complete. You need to remove the photoresist film.
    You can remove the photoresist by various methods :

    1. Sanding the photoresist using sandpaper (abrasive paper).
      you use a high grit for better results.
    2. Use Lye or sodium hydroxide solution
      Make a solution of sodium hydroxide and water in a container and dip the PCB in it. The solution will dissolve the photoresist. And then you can wash it in running water under a ceramic wash basin.

      I did not have sodium hydroxide as Lye available. So I improvised and used the “HARPIC bathroom cleaner” which has a small percentage of sodium hydroxide in it.

    Step 8: Drill Holes and Solder Components

    Using a drill with PCB drill bits, create holes at the designated locations on the PCB for component mounting. Ensure the hole sizes match the component leads or pads. Once drilled, solder the components onto the PCB following standard soldering techniques.

  • How to setup ESP32 on Arduino IDE

    Prerequisites: Before we dive into the setup process, there are a few things you’ll need to gather:

    1. An ESP32 development board: You can find numerous options available online, including the ESP32 DevKitC, NodeMCU-32S, and Wemos D1 R32, among others.
    2. A USB cable: Ensure you have a suitable USB cable to connect your ESP32 board to your computer.
    3. Arduino IDE: Download and install the latest version of the Arduino IDE from the official Arduino website (https://www.arduino.cc/en/software). The IDE provides an easy-to-use interface for writing and uploading code to your ESP32.

    Now that you have everything you need, let’s get started with the setup process.

    Step 1: Install the ESP32 Board in Arduino IDE:

    1. Open the Arduino IDE.
    2. Go to “File” > “Preferences” to open the Preferences window.
    3. In the “Additional Boards Manager URLs” field, add the following URL:
    https://dl.espressif.com/dl/package_esp32_index.json
    1. Click “OK” to save the preferences.
    2. Navigate to “Tools” > “Board” > “Boards Manager.”
    3. In the Boards Manager window, search for “ESP32” and select the “esp32” package by Espressif Systems.
    4. Click the “Install” button to begin the installation process.
    5. Once the installation is complete, close the Boards Manager window.

    Step 2: Select the ESP32 Board:

    1. Connect your ESP32 board to your computer using the USB cable.
    2. In the Arduino IDE, go to “Tools” > “Board” and select your ESP32 board from the list of available options. Choose the appropriate board variant based on the specific ESP32 module you are using.

    Step 3: Choose the Correct Port:

    1. Navigate to “Tools” > “Port” and select the port to which your ESP32 board is connected. The port name will vary depending on your operating system.
      • On Windows, it will typically be in the format “COMX” (e.g., COM3, COM4).
      • On macOS, it will usually appear as “/dev/cu.SLAB_USBtoUART” or “/dev/cu.usbserial-XXXX” (X represents some alphanumeric characters).
      • On Linux, it may appear as “/dev/ttyUSBX” or “/dev/ttyACMX” (X represents a number).

    Step 4: Upload a Test Sketch:

    1. Open the “Blink” example sketch by going to “File” > “Examples” > “01.Basics” > “Blink.”
    2. Make any necessary modifications to the sketch if required.
    3. Click on the “Upload” button (the rightward-pointing arrow) to compile and upload the sketch to your ESP32 board.
    4. Wait for the upload process to complete.
    5. Once the upload is successful, you should see the onboard LED blinking at a regular interval.

    Congratulations! You have successfully set up your ESP32 board on the Arduino IDE. You are now ready to unleash the power of the ESP32 and start

    Troubleshoot

    ImportError: No module named serial in Linux

    Traceback (most recent call last):
      File "/home/abhay/.arduino15/packages/esp32/tools/esptool_py/3.0.0/esptool.py", line 38, in <module>
        import serial
    ImportError: No module named serial
    
    exit status 1
    
    Compilation error: exit status 1

    here’s an alternative solution you can try:

    1. Install pySerial via apt-get:
    • Open a terminal.
    • Run the following command to install pySerial using apt-get:
    sudo apt-get install python-serial
    1. Restart Arduino IDE: Close the Arduino IDE completely and then open it again.
    2. Upload the code to the ESP32 board: Try uploading your code to the ESP32 board once again.

    By installing python-serial using apt-get, you should be able to resolve the missing serial module error. If you still encounter any issues, please provide any error messages or specific problems you’re facing, along with any additional details about your setup.

  • How to use Neo 6m GPS Module with Raspberry Pi Pico

    Connect the GPS module to the Raspberry Pi Pico as follows:

    1. Connect the VCC pin of the GPS module to the 3.3V pin on the Pico.
    2. Connect the GND pin of the GPS module to the GND pin on the Pico.
    3. Connect the TX pin of the GPS module to any GPIO pin1 on the Pico
    4. Connect the RX pin of the GPS module to any GPIO pin0 on the Pico

    Note: Since Raspberry Pi Pico operates at 3.3V logic level, you can directly connect the GPS module without voltage level shifting.

    The module will output something like this

    $GPRMC,103255.00,V,,,,,,,180523,,,N*70
    $GPVTG,,,,,,,,,N*30
    $GPGGA,103255.00,,,,,0,00,99.99,,,,,,*66
    $GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
    $GPGSV,1,1,01,18,,,31*73
    $GPGLL,,,,,103255.00,V,N*4A

    These are the NMEA messages. by decoding these messages we get our data.

    You can read about them at http://aprs.gids.nl/nmea/
       $GPGGA - Global Positioning System Fix Data
       $GPGLL - Geographic position, latitude / longitude
       $GPGSA - GPS DOP and active satellites 
       $GPGSV - GPS Satellites in view
       $GPRMC - Recommended minimum specific GPS/Transit data
       $GPVTG - Track made good and ground speed
    

    Micropython Code

    import machine
    import utime
    
    # UART configuration
    uart = machine.UART(0, baudrate=9600, tx=machine.Pin(0), rx=machine.Pin(1))
    date = ""
    time = ""
    altitude = ""
    course = ""
    speed = ""
    sats = ""
    hdop = ""
    latitude = ""
    latitude_dir = ""
    latitude_decimal =""
    longitude = ""
    longitude_dir = ""
    longitude_decimal = ""
    fix = ""
    
    
    def dms_to_decimal(degrees, minutes, seconds):
        degrees = int(degrees)
        minutes = int(minutes)
        seconds = float(seconds)
        decimal = degrees + (minutes / 60) + (seconds / 3600)
        return decimal
    
    while True:
        
        if uart.any():
            data = uart.readline()
            if data:
                try:
                    # Decode the GPS data
                    data_str = data.decode('utf-8').strip()
                    
                    if data_str.startswith('$GPRMC'):
                        values = data_str.split(',')
                        
                        if len(values) == 13:
                            date = values[9][0:2] + '/' + values[9][2:4] + '/' + values[9][4:]
                        #print(date)
                            
                    if data_str.startswith('$GPVTG'):
                        values = data_str.split(',')
                        if len(values) >= 9:
                            #print(values)
                            course = values[1]  # Course over ground
                            speed = values[7]   # Speed over ground
                            
                            
                    if data_str.startswith('$GPGGA'):
                        # Split the data string into individual values
                        values = data_str.split(',')
                        
                        #print(values)
                        if len(values) >= 15:
                            # Extract the required values
                            sats = values[7] if values[7] else ''  # Number of satellites
                            hdop = values[8] if values[8] else ''  # HDOP
                            latitude = values[2][:2] + '°' + values[2][2:4] + "'" + values[2][4:] + '"' + values[3]  # Latitude
                            latitude_dir = values[3]
                            longitude = values[4][:3] + '°' + values[4][3:5] + "'" + values[4][5:] + '"' + values[5]  # Longitude
                            longitude_dir = values[5]
                            latitude_decimal = dms_to_decimal((values[2][:2]),(values[2][2:4]),(values[2][4:]))
                            longitude_decimal = dms_to_decimal(values[4][:3],values[4][3:5],values[4][5:])
                            fix = values[6] if values[6] else ''  # Fix status
                            time = values[1][0:2] + ':' + values[1][2:4] + ':' + values[1][4:6]  # Time
                            altitude = values[9] if values[9] else ''  # Altitude
                            
                            
                        
                except UnicodeError:
                    pass
    
        utime.sleep(0.1)
        # Print the data
        
        print(f"Sats: {sats} HDOP: {hdop}")
        print("Latitude:", latitude)
        print("Longitude:", longitude)
        print(f"Latitude: {latitude_decimal} {latitude_dir} \t Longitude: {longitude_decimal} {longitude_dir}")
        print("Fix:", fix)
        print(f"Time: {time} Date: {date}")
        print(f"Altitude: {altitude}\n")
        # Print the GPVTG data
        print(f"GPVTG: Course: {course} Speed:{speed} km/h")
        
    
    

    Output

    GPVTG: Course: 49.43 Speed:2.164 km/h
    Sats: 06 HDOP: 1.39
    Latitude: 28°36'.51385"N
    Longitude: 077°03'.89436"E
    Latitude: 28.60014 N 	 Longitude: 77.05025 E
    Fix: 1
    Time: 14:24:37 Date: 18/05/23
    Altitude: 216.4
  • Voltage Divider Calculator

    Note: Enter resistance values in Ohm. Do not use kilo ohm. convert to ohm and then use.
    Enter voltage values in fraction or in decimal. Do not use something like 3v3 or 5v5. Convert it to fraction and then use
    Example 1: 10k ohm = 10000 ohm
    Example 2: 3v3 = 3.3

    How to use this calculator

    Enter any three values.
    Press the button “Calculate Missing Value”

    Explanation of voltage divider

    A voltage divider consists of two resistors connected in series across a voltage source. It divides the input voltage into two parts based on the ratio of the resistor values. The output voltage is obtained across one of the resistors.

    The voltage divider formula provides a simple way to calculate the output voltage:

    Vout = Vin * (R2 / (R1 + R2))

    where:

    • Vin is the input voltage applied across the series resistors.
    • R1 is the resistance value of the first resistor.
    • R2 is the resistance value of the second resistor.
    • Vout is the output voltage obtained across the second resistor.

    Exploring Different Resistor Combinations

    Voltage dividers offer flexibility in selecting resistor values to achieve specific output voltage ratios. By varying the resistor values while maintaining the same ratio, we can obtain different output voltages. Let’s explore some examples using different resistor combinations, assuming an input voltage of 5 V.

    R1 (Ω)R2 (Ω)Vout (V)
    1000100000.4545
    2000200000.4545
    5000500000.4545
    100001000000.4545

    As you can see, regardless of the specific resistor values, as long as the ratio R2 / (R1 + R2) remains constant, the output voltage remains the same. This property allows designers to choose different resistor combinations while maintaining the desired output voltage proportion.

  • Interfacing an external +5V power supply with Raspberry Pi Pico

    From the section 4.5 Powering Pico of the official Raspberry Pi Datasheet. I have decided to use the first method which is suggest to use a schottky diode with the VSYS pin.

    I have used 1N5819 Schottky diode.which has
    VRRM = 40V,
    Maximum average forward rectified current IF(AV) = 1A

    The schottky diode and the diode on the Pico PCB makes a power OR-ring. In this system the pico will take power which is greater. So if the power is greater from USB it will take power from USB. and if the voltage is greater from the power supply it will take power from it. Because of the use of schottky diode there will be a diode drop. To reduce it you can use a P-MOS as suggested in the datasheet. But for simpler circuits the Schottky diode works.

    Using the suggestion from the datasheet. I made a schematic in KiCad.

    The 1N5819 schottky connects to a custom switching step down voltage regulator made using the MC34063A IC.

    This is the micropython program code that i used

    import machine
    import time
    
    # Set up the button on GPIO22 with external pull-up resistor
    button = machine.Pin(22, machine.Pin.IN, machine.Pin.PULL_UP)
    
    # Set up the LED
    LED = machine.Pin(4, machine.Pin.OUT)
    
    # Set up debounce delay
    debounce_delay = 50
    
    # Initialize previous button value
    prev_button = 1
    
    # Loop forever
    while True:
        # Read the current button value
        curr_button = button.value()
    
        # If the button is pressed, print a message
        if curr_button == 0 and prev_button == 1:
            print("Button pressed!")
            # Wait for a short delay to debounce
            time.sleep_ms(debounce_delay)
            #toggle the LED
            LED.value(not LED.value())
    
        # Update the previous button value
        prev_button = curr_button
    
    
  • How to use button with Raspberry Pi Pico using micropython

    The Pico has internal pull up /down circuits inside it.

    I have made this simple circuit for demonstration.

    Schematic showing LED connected to GP4 and a Button connected to GP22

    Button could be connected in two ways.

    1. Internal Pull Up/Down
    2. External Pull UP/Down

    In the schematic i connected a button to GP22 using a external pull up of resistor 10k. I also used a capacitor in parallel with the button to debounce the button externally.

    Using a external pull-up resistor can also help to protect the GPIO pin from damage due to excessive current flow. Without a pull-up resistor, a short circuit or other electrical fault in the switch or button could potentially allow a large current to flow through the GPIO pin, damaging it or the microcontroller itself.

    Sample Code

    import machine
    
    # Set up the button on GPIO22 with external pull-up resistor
    button = machine.Pin(22, machine.Pin.IN, machine.Pin.PULL_UP)
    
    # Set up the LED on GPIO4
    led = machine.Pin(4, machine.Pin.OUT)
    
    # Loop forever
    while True:
        # Read the current button value
        curr_button = button.value()
    
        # If the button is pressed, turn on the LED
        if curr_button == 0:
            led.value(1)
        # Otherwise, turn off the LED
        else:
            led.value(0)