Understanding electronic circuits and components

A basic electrical circuit consists of a power source, a resistance element and a ground.They operate under the Ohm's Law which states that resistance is directly proportional to the voltage drop across it but inversely proportional to the current flowing through it.
To demonstrate a simple electrical circuit, we'll use an external LED, 470 Ohm resistor (to regulate the current) ,a 9 Volt power source(battery) and a push button to light up an led.


This simple project can also be done using a microcontroller and an almost identical code of blinking the onboard led except for the GPIO pin selected, is found following this link to Wokwi.
Resistors have a wide range of uses in electronics but the following are the main uses:

Interfacing external LEDs, switches and pushbuttons with RP2040

The next step is toggling the led using a push button which will teach us how to use a GPIO pin as an input pin. Its code is as shown below: (Uploaded to Raspberry Pi Pico W)

                        
            from machine import Pin
            from time import sleep

            #initialize the led Pin and Button Pin
            led=Pin(0,Pin.OUT)
            Button=Pin(10,Pin.IN)
            #Make the led off initially
            led.value(0)

            while True:
                #Check if button has been pressed.
                if Button.value():
                    led.value(1)
                else:
                    led.value(0)
                #Delay to ensure the is enough time between button presses to prevent 
                #the led from flickering as it reads the button state too quickly.
                sleep(0.3)
                        
                    
A link of this simulation can be found by following this link to Wokwi.

Now that we know how to use a GPIO pin as an output or input, we can make the following simple projects:

To implement the above projects,I combined all 3 into one project with a push button that is used to change which project is being executed on the same circuitry. The use of functions in very important to make this possible in the most efficient way possible.
The following Micropython code is used:
Simulation in Wokwi.
                        
    #In this project, we'll use a button to toggle btwn snake lights, binary counter and traffic lights
    from machine import Pin
    from time import sleep
    
    button_state=0
    btn_Pn=Pin(10, Pin.IN, Pin.PULL_DOWN)
    
    red=0
    yellow=2
    green=3
    Led1=Pin(red,Pin.OUT)
    Led2=Pin(yellow,Pin.OUT)
    Led3=Pin(green,Pin.OUT)
    
    
    def Snake_lights():
        print("------------------- ")
        arr=[red,yellow,green]
        i=0
        T=0
        while True:
            led=Pin(arr[i],Pin.OUT)
            led.value(1)
            sleep(0.5)
            led.value(0)
            i=i+1
            if i==3:
                i=0
                T=T+1
                if T==3:
                    Led1.value(0)
                    Led2.value(0)
                    Led3.value(0)
                    print("Snake Lights done ")
                    print("------------------- ")
                    break
    def Binary_Counter():
        print("------------------- ")
        Binry=[0,0,0]
        T=0
        while True:
            for x in range(8):
                Binry[2]= x%2    
                x=x//2
                Binry[1]= x%2    
                x=x//2
                Binry[0]= x%2    
                x=x//2
                print(Binry)
                Led1.value(Binry[0])
                Led2.value(Binry[1])
                Led3.value(Binry[2])
                sleep(0.5)
                Led1.value(0)
                Led2.value(0)
                Led3.value(0)
                sleep(0.5)
            print("------------------- ")
            T=T+1
            if T==1:
                Led1.value(0)
                Led2.value(0)
                Led3.value(0)
                print("Binary Counter done ")
                print("------------------- ")
                break;
    def Traffic_Lights():
        print("------------------- ")
        T=0
        while True:
            Led1.value(1)
            Led2.value(0)
            Led3.value(0)
            print("STOP ")
            sleep(5)
            Led1.value(1)
            Led2.value(1)
            Led3.value(0)
            print("HOLD ON ")
            sleep(1)
            Led1.value(0)
            Led2.value(1)
            Led3.value(0)
            print("WAIT ")
            sleep(3)
            Led1.value(0)
            Led2.value(1)
            Led3.value(1)
            print("ALMOST ")
            sleep(1)
            Led1.value(0)
            Led2.value(0)
            Led3.value(1)
            print("GO! ")
            sleep(3)
            Led1.value(1)
            Led2.value(0)
            Led3.value(1)
            print("START BRAKING ")
            sleep(1)
            
            T=T+1
            if T==1:
                Led1.value(0)
                Led2.value(0)
                Led3.value(0)
                print("Traffic Lights done ")
                print("------------------- ")
                break;
        
    def disp_project():
        n=0
        while True:
            if btn_Pn.value():
                if n==0:
                    print("------------------- ")
                    print("BUTTON PRESSED ")
                    print("Snake Lights ")
                    Snake_lights()
                    
                    
                if n==1:
                    print("------------------- ")
                    print("BUTTON PRESSED ")
                    print("Binary Counter ")
                    Binary_Counter()
                    
                
                if n==2:
                    print("------------------- ")
                    print("BUTTON PRESSED ")
                    print("Traffic Lights ")
                    Traffic_Lights()
                n=n+1
                if n==3:
                    n=0
            sleep(0.3)
    disp_project()
                        
                        

Introduction to sensors and actuators

A sensor is a device that detects a physical parameter and converts it to electrical signals that convey information about the parameter.Some people refer to sensors as special actuators which only produce electrical output.There are different types of sensors each differentiated by what it detects e.g soil moisture sensor,light intensity sensor e.t.c
An actuator is a device that receives electrical signal input and converts it to another form of energy such as such as mechanical energy e.g a motor converts electrical enegy to mechanical energy. Actuators are usually used to perform an action after receiving an electical input e.g from a sensor , microcontroller or just a power source.
Before incorporating sensors into our projects, we need to understand the following terms:

For this module,we'll use the Ultrasonic sensor and PIR(Passive Infrared sensor) to detect motion and measure the distace from the moving object. Other peripherals used will be an alerting system in the form of a buzzer and 2 leds(one lights up when a motion is detected while the other changes brightness based on the distance of object), a display system form of an OLED to show the status i.e if motion is detected or not and the distance from the object.
Before making this whole project, we must first learn how to program the individial sensors and display in Micropython.

Ultrasonic sensor

This is a sensor that sends a pulse and measures the time it takes for it to be received back as an echo and uses this time value together with the speed of sound to calculate the distance
The following shows the Micropython code used to read distance and display it on an OLED:

                        
    from machine import Pin,PWM,SoftSPI
    import utime
    
    #Initializw the OLED display
    spi = SoftSPI(baudrate=500000, polarity=1, phase=0, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
    
    dc = Pin(6)   # data/command
    rst = Pin(5)  # reset
    cs = Pin(15)  # chip select, some modules do not have a pin for this
    
    display = ssd1306.SSD1306_SPI(128, 64, spi, dc, rst, cs)
    
    Trig=Pin(3,Pin.OUT)
    Echo=Pin(2,Pin.IN)
    #Setting the LED pin to simulate an analogue output using PWM
    LED=PWM(Pin(26))
    LED.freq(1000)
    LED.duty_u16(0)
    #Calibrating the maximum distance your sensor can measure, this value will change depending on your sensor.
    max_Ultrasonic_distance_cm=205
    #Raspberry Pi Pico has a PMW duty cycle ranging from 0-65025
    max_12bit_value=65025;
    
    def read_distance():
        #Make the oled display nothing initially
        display.fill(0)
        #Sending a pulse
        Trig.value(0)
        utime.sleep_us(2)
        Trig.value(1)
        utime.sleep_us(5)
        Trig.value(0)
        
        #time between pulse release and its arrival as an echo.
        while Echo.value()==0:
            travel_time=utime.ticks_us()
        #time during which the echo is detected     
        while Echo.value()==1:
            pulse_received_time=utime.ticks_us()
        
        timeTaken=pulse_received_time-travel_time
        distance=((0.0343*timeTaken)/2)
        #Display on oled 
        display.text("Distance - "+distance+" cm away. ",1,1,0)
        #display on terminal
        print("The distance object is ",distance," cm away ")
        
        #To prevent brightness values being higher than 3.3 volts
        if distance>max_Ultrasonic_distance_cm:
            distance=max_Ultrasonic_distance_cm
        #Make the brightness value directly proportional to distance of object
        #Also mapping the distance value to an analogue value(0-65025)
        brightness=(max_12bit_value/max_Ultrasonic_distance_cm)*distance
        LED.duty_u16(int(brightness))
    
    while True:
        read_distance()
        utime.sleep(0.5)                        
                        
                    

PIR sensor

This sensor is used to detect the presence of an object moving in its radius of view. The following Micropython code is used to use a PIR sensor to detect motion and display status on an oled and use a buzzer to alert the user.

                        
        from machine import Pin
        import utime
        
        #initialize the OLED display
        spi = SoftSPI(baudrate=500000, polarity=1, phase=0, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
        
        dc = Pin(6)   # data/command
        rst = Pin(5)  # reset
        cs = Pin(15)  # chip select, some modules do not have a pin for this
        display = ssd1306.SSD1306_SPI(128, 64, spi, dc, rst, cs)
        
        #initialize the green led and buzzer
        buzzer=Pin(0,Pin.OUT)
        LED2=Pin(1,Pin.OUT)
        PIR=Pin(16,Pin.IN,Pin.PULL_DOWN)
        
        while True:
            display.fill(0)
            if PIR.value()==1:
                display.text(" Motion Detected ! ! ",1,1,1)
                buzzer.value(1)
                LED2.value(0)
            else:
                display.text("NO Motion Detected ! ! ",1,1,1)
                LED2.value(1)
                buzzer.value(0)
                
            utime.sleep(0.5)
                                    
                        
                        
A video of this sensor in action using esp32 is as shown below :

Module2 project

Here, we'll apply all that we have learnt to build a project that senses the presence of an object moving and measures its distance.
Components used include :

                        
    from machine import Pin,PWM
    import utime
    
    #Initilizing the OLED
    spi = SoftSPI(baudrate=500000, polarity=1, phase=0, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
    
    dc = Pin(6)   # data/command
    rst = Pin(5)  # reset
    cs = Pin(15)  # chip select, some modules do not have a pin for this
    
    display = ssd1306.SSD1306_SPI(128, 64, spi, dc, rst, cs)
    
    #Initializing the Ultrasonic and led2(Red led)
    Trig=Pin(3,Pin.OUT)
    Echo=Pin(2,Pin.IN)
    LED2=PWM(Pin(26))
    LED2.freq(1000)
    LED2.duty_u16(0)
    
    #Initializing the PIR sensor and led1(Green led)
    PIR=Pin(16,Pin.IN,Pin.PULL_DOWN)
    LED1=Pin(0,Pin.OUT)
    
    #Function for detecting motion
    def motion():
            display.fill(0)
            LED1.value(PIR.value())
            if PIR.value()==1:
                display.text("Motion Detected ",1,1,1)
            else:
                display.text("No Motion! ",1,1,1)
            utime.sleep(0.5)
    
    #Function for measuring distance
    def read_distance():
        
        Trig.value(0)
        utime.sleep_us(2)
        Trig.value(1)
        utime.sleep_us(5)
        Trig.value(0)
        while Echo.value()==0:
            Time_taken_go=utime.ticks_us()
        
        while Echo.value()==1:
            Time_taken_received=utime.ticks_us()
        
        timeTaken=Time_taken_received-Time_taken_go
        distance=((0.0343*timeTaken)/2)
        brightness=(65550/150)*distance
        LED2.duty_u16(int(brightness))
        display.fill(0)
        display.text("The distance object is "+distance+" cm away ",1,1,1)
    
    while True:
        read_distance()
        motion()
        utime.sleep(1)                            
                        
                    

A link of this from wokwi of this project is : Module_2 project.