Skip to content

Commit 480fa51

Browse files
flight checked
1 parent ae5ba40 commit 480fa51

14 files changed

Lines changed: 833 additions & 161 deletions

README.md

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,9 @@ Students will be recreating a model of the pedestrian crossing on Unwins Bridge
5555

5656
![A street view image of the system we will be modeling](/images/real_world_situation.png "The traffic lights, pedestrian warning lights, pedestrian button and control system.")
5757

58-
From the above real world control system we will model:
59-
60-
- Overloading and overriding polymorphism
61-
- Inheritance, multilevel inheritance and multiple class inheritance
62-
- Abstraction
63-
- Decomposition and composition
64-
- Generalisation
65-
- Encapsulation
66-
- Object instantiation, objects as instance variables
58+
### Final Product
59+
60+
![Video of Final Project in Operations](/images/demonstration.gif)
6761

6862
### Wire your system
6963

images/demonstration.gif

2.21 MB
Loading

images/physical_prototype.png

147 KB
Loading

project/lib/audio_notification.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,29 @@
11
from machine import Pin, PWM
2-
from time import sleep
2+
from time import sleep, time
3+
34

45
class Audio_Notification(PWM):
56
def __init__(self, pin, debug=False):
67
super().__init__(Pin(pin))
78
self.__debug = debug
89
self.duty_u16(0) # Start with buzzer off
10+
self._last_toggle_time = time()
911

1012
def warning_on(self):
1113
if self.__debug:
1214
print("Warning on")
13-
# Generate 3 beeps
14-
for _ in range(3):
15-
self.beep(freq=1500, duration=100)
16-
sleep(0.1)
15+
now = time()
16+
if now - self._last_toggle_time >= 0.5:
17+
self.beep(freq=500, duration=100)
18+
self._last_toggle_time = now
1719

1820
def warning_off(self):
1921
if self.__debug:
2022
print("Warning off")
2123
self.duty_u16(0) # Turn off sound
2224

2325
def beep(self, freq=1000, duration=500):
24-
"""
25-
Generate a beep on a piezo buzzer.
26-
27-
:param freq: frequency in Hz
28-
:param duration: duration in milliseconds
29-
"""
3026
self.freq(freq)
3127
self.duty_u16(32768) # 50% duty cycle
3228
sleep(duration / 1000)
33-
self.duty_u16(0) # Turn off after beep
29+
self.duty_u16(0) # Turn off after beep

project/lib/controller.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
from led_light import Led_Light
2+
from pedestrian_button import Pedestrian_Button
3+
from audio_notification import Audio_Notification
4+
from time import sleep, time
5+
6+
7+
class Controller:
8+
def __init__(
9+
self, ped_red, ped_green, car_red, car_amber, car_green, button, buzzer, debug
10+
):
11+
self.__Ped_Red = ped_red
12+
self.__Ped_Green = ped_green
13+
self.__Car_Red = car_red
14+
self.__Car_Amber = car_amber
15+
self.__Car_Green = car_green
16+
self.__Buzzer = buzzer
17+
self.__Button = button
18+
self.__debug = debug
19+
self.state = "IDLE"
20+
self.last_state_change = time()
21+
22+
def walk_on(self):
23+
if self.__debug:
24+
print("Walking")
25+
self.__Ped_Red.off()
26+
self.__Ped_Green.on()
27+
self.__Car_Green.off()
28+
self.__Car_Amber.off()
29+
self.__Car_Red.on()
30+
self.__Buzzer.warning_on()
31+
32+
def walk_warning(self):
33+
if self.__debug:
34+
print("No Walking Warning")
35+
self.__Ped_Red.flash()
36+
self.__Ped_Green.off()
37+
self.__Car_Green.off()
38+
self.__Car_Amber.off()
39+
self.__Car_Red.on()
40+
self.__Buzzer.warning_off()
41+
42+
def walk_off(self):
43+
if self.__debug:
44+
print("No Walking")
45+
self.__Ped_Red.on()
46+
self.__Ped_Green.off()
47+
self.__Car_Green.on()
48+
self.__Car_Amber.off()
49+
self.__Car_Red.off()
50+
self.__Ped_Green.off()
51+
self.__Buzzer.warning_off()
52+
53+
def change(self):
54+
if self.__debug:
55+
print("Changing")
56+
self.__Ped_Red.on()
57+
self.__Ped_Green.off()
58+
self.__Car_Green.off()
59+
self.__Car_Amber.on()
60+
self.__Car_Red.off()
61+
self.__Ped_Green.off()
62+
self.__Buzzer.warning_off()
63+
64+
def update(self):
65+
# State machine logic
66+
if self.state == "IDLE":
67+
if self.__Button.button_state:
68+
if self.__debug:
69+
print("Pedestrian waiting detected, switching to CAR_AMBER")
70+
self.state = "CAR_AMBER"
71+
self.last_state_change = time()
72+
self.change()
73+
else:
74+
self.walk_off()
75+
elif self.state == "CAR_AMBER":
76+
# Wait 10 seconds before allowing walk
77+
self.change()
78+
if time() - self.last_state_change > 5:
79+
if self.__debug:
80+
print("Switching to WALK_ON")
81+
self.state = "WALK_ON"
82+
self.last_state_change = time()
83+
self.walk_on()
84+
elif self.state == "WALK_ON":
85+
# Walk signal for 5 seconds
86+
self.walk_on()
87+
if time() - self.last_state_change > 5:
88+
if self.__debug:
89+
print("Switching to No Walk Warning")
90+
self.state = "WALK_WARNING"
91+
self.last_state_change = time()
92+
self.walk_warning()
93+
elif self.state == "WALK_WARNING":
94+
# Walk signal for 5 seconds
95+
self.walk_warning()
96+
if time() - self.last_state_change > 5:
97+
if self.__debug:
98+
print("Returning to IDLE")
99+
self.state = "IDLE"
100+
self.last_state_change = time()
101+
self.walk_off()
102+
self.__Button.button_state = False
103+
else: # error
104+
self.__Ped_Red.on()
105+
self.__Ped_Green.off()
106+
self.__Car_Green.off()
107+
self.__Car_Amber.toggle()
108+
self.__Car_Red.off()
109+
self.__Ped_Green.off()
110+
sleep(1)

project/lib/led_light.py

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from machine import Pin
22
from time import sleep, time
33

4+
45
class Led_Light(Pin):
56
# child class inherits the parent 'Pin' class
67
def __init__(self, pin, flashing=False, debug=False):
@@ -9,6 +10,7 @@ def __init__(self, pin, flashing=False, debug=False):
910
self.__debug = debug
1011
self.__pin = pin
1112
self.__flashing = flashing
13+
self._last_toggle_time = time()
1214

1315
def on(self):
1416
# method overiding polymorphism of the parent class
@@ -27,7 +29,7 @@ def toggle(self):
2729
if self.value() == 0:
2830
self.on()
2931
elif self.value() == 1:
30-
self.off()
32+
self.off()
3133

3234
@property
3335
def led_light_state(self):
@@ -42,22 +44,9 @@ def led_light_state(self, value):
4244
elif value == 0:
4345
self.on()
4446

45-
def flash(self, duration=5):
46-
# Method to flash the LED on and off every 0.5 seconds for a given duration
47-
if self.__flashing:
48-
if self.__debug:
49-
print(f"LED connected to Pin {self.__pin} is flashing for {duration} seconds")
50-
end_time = time() + duration
51-
while time() < end_time:
52-
self.toggle()
53-
sleep(0.5) # Delay for 0.5 seconds
54-
55-
def on_for(self, duration):
56-
# Turns the LED on for a specified duration (in seconds) and then turns it off.
57-
self.on()
58-
if self.__debug:
59-
print(f"LED connected to Pin {self.__pin} is ON for {duration} seconds")
60-
sleep(duration)
61-
self.off()
62-
if self.__debug:
63-
print(f"LED connected to Pin {self.__pin} is OFF after {duration} seconds")
47+
def flash(self):
48+
# Non-blocking flash: toggles LED every 0.5s for the given duration
49+
now = time()
50+
if self.__flashing and now - self._last_toggle_time >= 0.5:
51+
self.toggle()
52+
self._last_toggle_time = now

project/lib/pedestrian_button.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from machine import Pin
22
import time
33

4+
45
class Pedestrian_Button(Pin):
56
# child class inherits the parent 'Pin' class
67

@@ -11,26 +12,29 @@ def __init__(self, pin, debug):
1112
self.__last_pressed = 0 # Track the last time the button was pressed
1213
self.__pedestrian_waiting = False
1314
self.button_state
14-
self.irq(trigger=Pin.IRQ_RISING, handler=self.callback) # Set up interrupt on rising edge
15+
self.irq(
16+
trigger=Pin.IRQ_RISING, handler=self.callback
17+
) # Set up interrupt on rising edge
1518

1619
@property
1720
def button_state(self):
18-
state = self.value() # Directly read the pin's value
1921
if self.__debug:
20-
print(f"Button connected to Pin {self.__pin} is {'PRESSED' if state else 'NOT PRESSED'}")
21-
self.__pedestrian_waiting = state
22-
return state
22+
print(
23+
f"Button connected to Pin {self.__pin} is {'WAITING' if self.__pedestrian_waiting else 'NOT WAITING'}"
24+
)
25+
return self.__pedestrian_waiting
2326

2427
@button_state.setter
2528
def button_state(self, value):
2629
self.__pedestrian_waiting = value
2730
if self.__debug:
2831
print(f"Button state on Pin {self.__pin} set to {value}")
2932

30-
3133
def callback(self, pin):
3234
current_time = time.ticks_ms() # Get the current time in milliseconds
33-
if time.ticks_diff(current_time, self.__last_pressed) > 200: # 200ms debounce delay
35+
if (
36+
time.ticks_diff(current_time, self.__last_pressed) > 200
37+
): # 200ms debounce delay
3438
self.__last_pressed = current_time
3539
self.__pedestrian_waiting = True
3640
if self.__debug:

project/py_scripts/v06.py

Lines changed: 0 additions & 16 deletions
This file was deleted.

project/py_scripts/v99.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from led_light import Led_Light
2+
from pedestrian_button import Pedestrian_Button
3+
from audio_notification import Audio_Notification
4+
from controller import Controller
5+
from time import sleep, time
6+
7+
8+
debug = False
9+
10+
led_pedestrian_red = Led_Light(19, True, debug)
11+
led_pedestrian_green = Led_Light(17, False, debug)
12+
led_car_red = Led_Light(3, False, debug)
13+
led_car_orange = Led_Light(5, False, debug)
14+
led_car_green = Led_Light(6, False, debug)
15+
16+
17+
pedestrian_button = Pedestrian_Button(22, debug)
18+
19+
buzzer = Audio_Notification(27, debug)
20+
21+
controller = Controller(
22+
led_pedestrian_red,
23+
led_pedestrian_green,
24+
led_car_red,
25+
led_car_orange,
26+
led_car_green,
27+
pedestrian_button,
28+
buzzer,
29+
True,
30+
)
31+
32+
while True:
33+
controller.update()
34+
sleep(0.1)

tutorials/Lecture0.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ The Introduction projects should be completed before starting the OOP Mini Proje
1616
| ![Analog Sensor](../introduction_projects/images/analog_sensor.png)<br/>Analog Sensor | ![Servo Control](../introduction_projects/images/servo_control.png)<br/>Servo Control |
1717
| ![Ultrasonic Sensor](../introduction_projects/images/ultrasonic_sensor.png)<br/>Ultrasonic Sensor | ![I2C Module](../introduction_projects/images/I2C_module.png)<br/>I2C Module |
1818

19+
## Final Product
20+
21+
![Video of Final Project in Operations](/images/demonstration.gif)
22+
1923
## Wokwi
2024

2125
Wokwi is an online Electronics simulator. You can use it to simulate Arduino, ESP32, STM32, and many other popular boards, parts and sensors. We will be using it for Pi Pico, you can also use the integrated IDE.
@@ -47,7 +51,7 @@ Watch the [Pi Pico Breadboard Introduction Video](https://www.youtube.com/watch?
4751

4852
### Physical Prototype
4953

50-
![Physical Prototype](/images/prototype_model.png)
54+
![Physical Prototype](/images/physical_prototype.png)
5155

5256
### Physical Unit Testing
5357

0 commit comments

Comments
 (0)