Objectives
Group assignment: demonstrate and compare the toolchains and development workflows for available embedded architectures
Individual assignment: browse through the data sheet for your microcontroller write a program for a microcontroller, and simulate its operation, to interact (with local input &/or output devices) and communicate (with remote wired or wireless connections) extra credit: test it on a development board extra credit: try different languages &/or development environments
Group Assignment
Embedded architecture refers to the hardware and software structure of an embedded system, which is a specialized computing system designed for a specific function within a larger application. Unlike general-purpose computers, embedded systems are optimized for dedicated tasks with constraints on power, size, and real-time performance. In our group assignment different embedded architectures were explored, their toolchains and development workflows were compared.
Group Assignment4. Embedded Programming
RP 2040
RP2040 is the debut microcontroller from Raspberry Pi

Key Features
- Dual ARM Cortex-M0+
- The RP2040 microcontroller has a clock speed of 133 MHz. This means each of its dual ARM Cortex-M0+ cores operates at 133 MHz.
- 264kB on-chip SRAM in six independent banks
- Support for up to 16MB of off-chip Flash memory via dedicated QSPI bus; meaning the RP2040 itself does not have internal flash memory, but relies on external flash for storing program code and data.
- 30 GPIO pins, 4 of which can be used as analogue inputs
- Communication protocols
- I2C:A widely used protocol for communicating with multiple devices on a single bus, requiring only two data lines (SDA and SCL).
- SPI:Another common protocol for high-speed data transfer between devices, typically utilizing four data lines
- UART: Used for simple serial communication with devices, sending data one byte at a time.
- Built-in Analog-to-Digital Converter (ADC) with 5 channels, offering 12-bit resolution, meaning it can read analog voltage levels with a precision of 4096 possible values between 0 and 3.3 volts on each channel
- Logic levels: High logic is considered near 3.3V, low logic is near 0V. High (1): ≥ 2.0V Low (0): ≤ 0.8V
- Maximum output current per GPIO pin: 12 mA
- Operating voltage: 3.3V
RP2040 has a dual M0+ processor cores, DMA, internal memory and peripheral blocks connected via AHB/APB bus fabric.

Wokwi
Wokwi is an online Electronics simulator. You can use it to simulate Arduino, ESP32, STM32, and many other popular boards, parts and sensors.
I worked on Raspberry Pi Pico RP2040 using microphyton.
open wokwi -> My projects -> New project ->Raspberry Pi Pico -> Microphyton
- I wrote a program to blink an led using push button

The program code is given below
import machine
import time
It allows you to access and utilize functions, classes, and variables defined in external files, known as modules.
LED_PIN = 2
BUTTON_PIN = 14
led = machine.Pin(LED_PIN, machine.Pin.OUT)
button = machine.Pin(BUTTON_PIN, machine.Pin.IN, machine.Pin.PULL_UP)
The LED is connected to GPIO2.The button is connected to GPIO14 with an internal pull-up resistor, meaning it reads high (1) when not pressed and low (0) when pressed.
while True:
if not button.value():
led.on()
print("LED ON!")
time.sleep(0.5)
else:
led.off()
print("LED OFF!")
time.sleep(0.5)
If the button is pressed (button.value() is 0), the LED turns on, and "LED ON!" is printed.If the button is not pressed, the LED turns off, and "LED OFF!" is printed.There's a time.sleep(0.5) delay to prevent rapid toggling.
- I wrote a program for ultrasonic distance sensor LED

The program code is given below
from machine
import Pin, PWM
import utime
TRIG = Pin(3, Pin.OUT)
This line sets up GPIO pin 3 as an output pin for the trigger of the ultrasonic sensor. This pin sends a pulse to the ultrasonic sensor to trigger a measurement.
ECHO = Pin(2, Pin.IN)
This line sets up GPIO pin 2 as an input pin for the echo signal from the ultrasonic sensor. This pin receives the signal reflected from the object (the echo) after the pulse is sent, and it is used to calculate the distance.
led = PWM(Pin(15))
This line creates a PWM object on GPIO pin 15 to control the brightness of an LED.
led.freq(1000)
This line sets the frequency of the PWM signal to 1000 Hz
def get_distance():
TRIG.low()
This sets the TRIG pin to low (0V). The TRIG pin must be low for at least a short duration before triggering the ultrasonic sensor to send a pulse.
utime.sleep_us(2)
This waits for 2 microseconds means sleep in microseconds to ensure a clean low-to-high transition when the pulse is sent.
TRIG.high()
This sets the TRIG pin to high. This triggers the ultrasonic sensor to send out a pulse of sound.
utime.sleep_us(10)
The TRIG pin needs to be high for at least 10 microseconds to send a pulse. This is the duration of the pulse sent by the ultrasonic sensor.
TRIG.low()
while ECHO.value() == 0:
This loop runs while the ECHO pin is low (0V). When the ultrasonic pulse is sent, the ECHO pin remains low until the pulse is reflected back.The ECHO pin will go high once the pulse is reflected back to the sensor. This first while loop ensures the code waits until the ECHO pin goes high.
signal_off = utime.ticks_us()
When the ECHO pin transitions from low to high, the current time in microseconds is recorded by utime.ticks_us(). This is the moment the signal is sent out. The signal_off variable captures the time at which the pulse was sent.
while ECHO.value() == 1:
This second loop keeps running while the ECHO pin is high. The ECHO pin stays high as long as the pulse is traveling back to the sensor from the object. The code will stop when the ECHO pin goes low again, which indicates the pulse has returned to the sensor.
signal_on = utime.ticks_us()
When the ECHO pin goes low again, the time in microseconds is captured with utime.ticks_us(). This is the moment the reflected pulse has been received by the sensor. The signal_on variable captures the time at which the pulse was received.
time_passed = signal_on - signal_off
distance = (time_passed * 0.0343) / 2
0.0343 is the speed of sound in centimeters per microsecond.Since the time measured includes the round trip (to the object and back), we divide the time by 2 to get the one-way time.
return distance
while True:
dist = get_distance()
print("Distance:", dist, "cm")
if dist > 100:
Here I set the distance as 100 cm
brightness = 0
else:
brightness = int((1 - (dist / 100)) * 65535) >
Dividing dist by 100 scales the distance to a value between 0 and 1 if the distance is between 0 and 100 cm.Subtracting the scaled distance from 1 inverts the mapping.
- If the object is close to the sensor (e.g., 0 cm), dist / 100 would be 0, so 1 - 0 gives 1.
- If the object is farther away (e.g., 100 cm), dist / 100 would be 1, so 1 - 1 gives 0.
- When the object is very close (0 cm), the brightness will be 65535 (maximum brightness).
- When the object is far (100 cm), the brightness will be 0 (LED turned off).
led.duty_u16(brightness)
duty_u16() is a method that sets the PWM duty cycle using a 16-bit value (0–65535).
utime.sleep(0.1)
from machine import Pin, PWM import utime TRIG = Pin(3, Pin.OUT) ECHO = Pin(2, Pin.IN) led = PWM(Pin(15)) led.freq(1000) def get_distance(): TRIG.low() utime.sleep_us(2) TRIG.high() utime.sleep_us(10) TRIG.low() while ECHO.value() == 0: signal_off = utime.ticks_us() while ECHO.value() == 1: signal_on = utime.ticks_us() time_passed = signal_on - signal_off distance = (time_passed * 0.0343) / 2 return distance while True: dist = get_distance() print("Distance:", dist, "cm") if dist > 100: brightness = 0 else: brightness = int((1 - (dist / 100)) * 65535) led.duty_u16(brightness) utime.sleep(0.1)
I used chatgpt to refer the code.
promt:-How to code for ultrasonic sensor and led varing intensity using rp 2040 and microphyton
- I tried to blink LED using Ardino UNO in wokwi

const int buttonPin = 2; const int ledPin = 13; void setup() { pinMode(buttonPin, INPUT_PULLUP); pinMode(ledPin, OUTPUT); Serial.begin(9600); } void loop() { int buttonstate = digitalRead(buttonPin); if (buttonstate==LOW){ digitalWrite(ledPin, HIGH); Serial.println("LED is ON"); }else{ digitalWrite(ledPin, LOW); Serial.println("LED is OFF"); } delay(200); }
I used chatgpt to refer the code.
promt:-how to write a code in wokwi adrino uno to blink led using pushbutton
Code is explained below
const int buttonPin = 2;
const int ledPin = 13;
Defines constant integer for button and LED connected to pin 2 and pin 13 respectively
void setup() { pinMode(buttonPin, INPUT_PULLUP); pinMode(ledPin, OUTPUT); Serial.begin(9600); }
setup() function runs once the ardino is powered on/ reset. Button pin defines pin 2 as input. INPUT_PULLUP enables internal pull up resistor,which keeps the pin value high when the button is not pressed. ledPin defines pin 13 as output. In Serial.begin(9600) serial communication begins at 9600 bits per second.
void loop() { int buttonstate = digitalRead(buttonPin);
In void loop, the function runs continuosly.Digital read reads the state of button pin
- If not pressed -> buttonstate=HIGH
- If pressed -> buttonstate=LOW
if (buttonstate==LOW){ digitalWrite(ledPin, HIGH); Serial.println("LED is ON");
If the buttonstate is low, the LED turns ON and serial monitor prints "LED is ON"
else{ digitalWrite(ledPin, LOW); Serial.println("LED is OFF");
Otherwise the LED turns OFF and serial monitor prints "LED is OFF"
delay(200)
Pauses execution for 200 milliseconds. Prevents rapid toggling and reduces flickering.
- I tested the code in Arduino UNO
Hardware setup
The resistor is selected using resistor colourcode
LEDs do not have internal resistance to limit current, so they can draw too much current and burn out if connected directly to a voltage source.
Using Ohm's law
𝑅 = V/I
Arduino outputs 5V. A typical LED forward voltage drop is about 2V. Desired current is ~15-20mA (0.02A).150Ω is a minimum safe value, 220Ω is commonly used to ensure safety and longevity while keeping the LED bright enough.

I changed the LED pin to pin 9. Change is made in the code. circuit is connected and code is uploaded using arduino IDE


Conclusion
This week I learned about embedded programming. I learned about various embedded architectures, their toolchains and development workflows. Went through the datasheet of rp2040. Simulated programs in wokwi. Wrote programs for Raspberry Pi Pico and adruino UNO.Tested the program on AdruinoUNO.
Useful links
WokwiArduino
RP2040 Datasheet