Skip to content

Commit 8cc5a5e

Browse files
update
1 parent 147bd01 commit 8cc5a5e

26 files changed

Lines changed: 320 additions & 71 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ __pycache__/
33
*.py[cod]
44
*$py.class
55

6+
tutorials/*
7+
tutorials/*.pptx
8+
69
# C extensions
710
*.so
811

_includes/youtube.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<div class="embed-container">
2+
<iframe width="640" height="390"
3+
src="https://www.youtube.com/embed/{{ include.id }}"
4+
frameborder="0" allowfullscreen></iframe>
5+
</div>
6+
<style>
7+
.embed-container {
8+
position: relative;
9+
padding-bottom: 56.25%;
10+
height: 0;
11+
overflow: hidden;
12+
max-width: 100%;
13+
}
14+
.embed-container iframe,
15+
.embed-container object,
16+
.embed-container embed {
17+
position: absolute;
18+
top: 0;
19+
left: 0;
20+
width: 100%;
21+
height: 100%;
22+
}
23+
</style>

deleteme.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import pickle
2+
import numpy as np
3+
4+
filename = 'my_saved_model.sav'
5+
6+
loaded_model = pickle.load(open(filename, 'rb'))
7+
predict = np.array([4]).reshape(1, -1)
8+
result = loaded_model.predict(predict)
9+
print(result[0])

docs/servo.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Servo Class
2+
3+
The `Servo` class provides an interface for controlling standard hobby servo motors using PWM signals on the Raspberry Pi Pico. It allows you to set the servo angle, control the duty cycle directly, and safely stop or deinitialize the servo.
4+
5+
## Constructor
6+
7+
```python
8+
Servo(pwm, min_us=500, max_us=2500, dead_zone_us=1500, freq=50)
9+
```
10+
- `pwm` (`PWM`): A `machine.PWM` object for the servo control pin.
11+
- `min_us` (`int`, optional): Minimum pulse width in microseconds (default: 500).
12+
- `max_us` (`int`, optional): Maximum pulse width in microseconds (default: 2500).
13+
- `dead_zone_us` (`int`, optional): Pulse width for the servo's neutral position (default: 1500).
14+
- `freq` (`int`, optional): PWM frequency in Hz (default: 50).
15+
16+
## Example Usage
17+
18+
```python
19+
from machine import Pin, PWM
20+
from servo import Servo
21+
from time import sleep
22+
23+
# Create a PWM object on GPIO 16
24+
pwm = PWM(Pin(16))
25+
servo = Servo(pwm, freq=50)
26+
27+
# Move servo to 0, 90, and 180 degrees
28+
servo.set_angle(0)
29+
sleep(1)
30+
servo.set_angle(90)
31+
sleep(1)
32+
servo.set_angle(180)
33+
sleep(1)
34+
35+
# Stop the servo (move to neutral position)
36+
servo.stop()
37+
38+
# Deinitialize when done
39+
servo.deinit()
40+
```
41+
42+
## Methods
43+
44+
- **set_angle(angle)**
45+
Set the servo to a specific angle (0–180 degrees).
46+
47+
- **set_duty(duty_us)**
48+
Set the PWM pulse width in microseconds directly.
49+
50+
- **get_duty()**
51+
Get the current PWM pulse width in microseconds.
52+
53+
- **stop()**
54+
Move the servo to the neutral (dead zone) position.
55+
56+
- **deinit()**
57+
Deinitialize the PWM object to free hardware resources.
58+
59+
---
60+
61+
**Notes:**
62+
- The servo must be powered appropriately; do not power directly from the Pico's 3.3V pin if your servo draws significant current.
63+
- The control pin must support PWM output.
64+
- Typical servos expect a 50Hz PWM signal with pulse widths between 500μs (0°) and 2500μs (180°).
65+
66+
## Class Unit Test
67+
68+
```python
69+
from machine import Pin, PWM
70+
from servo import Servo
71+
from time import sleep
72+
73+
pwm = PWM(Pin(16))
74+
servo = Servo(pwm)
75+
76+
print("Testing set_angle()")
77+
for angle in [0, 90, 180, 90, 0]:
78+
servo.set_angle(angle)
79+
print(f"Set angle to {angle}°; duty = {servo.get_duty()}us")
80+
sleep(1)
81+
82+
print("Testing stop()")
83+
servo.stop()
84+
print(f"Servo stopped at duty = {servo.get_duty()}us")
85+
86+
servo.deinit()
87+
print("Servo deinitialized.")
88+
```
89+
90+
## Class Implementation
91+
92+
```python
93+
from machine import PWM
94+
95+
class Servo:
96+
"""Servo Class for controlling pulse density modulation servos.
97+
98+
This class provides an interface for controlling servo motors using PWM signals.
99+
It handles the conversion between angles (0-180 degrees) and pulse widths.
100+
101+
Args:
102+
pwm (PWM): A PWM object to control the servo.
103+
min_us (int, optional): Minimum pulse width in microseconds. Defaults to 500.
104+
max_us (int, optional): Maximum pulse width in microseconds. Defaults to 2500.
105+
dead_zone_us (int, optional): Pulse width for the servo's neutral position. Defaults to 1500.
106+
freq (int, optional): PWM frequency in Hz. Defaults to 50.
107+
"""
108+
109+
def __init__(
110+
self,
111+
pwm: PWM,
112+
min_us=500,
113+
max_us=2500,
114+
dead_zone_us=1500,
115+
freq=50,
116+
):
117+
self.pwm = pwm
118+
self.pwm.freq(freq)
119+
self._move_period_ms = 1000 // freq
120+
min_us = min_us if min_us > 0 else 0
121+
max_us = max_us if min_us < max_us < (1000 // freq) * 1000 else 0
122+
self._curr_duty = 0
123+
self.dead_zone_us = dead_zone_us
124+
125+
def set_duty(self, duty_us: int):
126+
self._curr_duty = duty_us
127+
self.pwm.duty_ns(duty_us * 1000)
128+
129+
def set_angle(self, angle: int):
130+
angle = min(max(angle, 0), 180)
131+
duty_us = int(500 + (angle / 180) * 2000)
132+
self.set_duty(duty_us)
133+
134+
def get_duty(self) -> int:
135+
return self._curr_duty
136+
137+
def stop(self):
138+
self.set_duty(self.dead_zone_us)
139+
140+
def deinit(self):
141+
self.pwm.deinit()
142+
```

examples/v03.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
"""
2+
Instantiation Example
3+
"""
14
from machine import Pin
25
from time import sleep
36

examples/v04.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@
55
from machine import Pin
66
from time import sleep
77

8-
98
class Led_Light(Pin):
10-
# Sub Class inherits the 'Pin' Class
9+
# Sub Class inherits the 'Pin' Class
1110
def __init__(self, pin):
1211
super().__init__(pin, Pin.OUT)
1312

14-
1513
red_light = Led_Light(3)
1614

1715
while True:
@@ -26,4 +24,4 @@ def __init__(self, pin):
2624
red_light.toggle()
2725
sleep(4)
2826
red_light.toggle()
29-
sleep(4)
27+
sleep(4)

examples/v05.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from machine import Pin
66
from time import sleep
77

8-
98
class Led_Light(Pin):
109
# Sub Class inherits the 'Pin' Class
1110
def __init__(self, pin, flashing=False, debug=False):
@@ -27,10 +26,10 @@ def off(self):
2726
print(f"LED connected to Pin {self.__pin} is low")
2827

2928

30-
red_light = Led_Light(3)
29+
red_light = Led_Light(3, False, False)
3130

3231
while True:
3332
red_light.on()
3433
sleep(1)
3534
red_light.off()
36-
sleep(1)
35+
sleep(1)

examples/v08.py

Lines changed: 15 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,23 @@
11
"""
22
Encapsulation Example
3+
RUN AS PYTHON NOT MICROPYTHON
34
"""
45

5-
from machine import Pin
6-
from time import sleep, time
7-
8-
9-
class Led_Light(Pin):
10-
# Sub Class inherits the Super 'Pin' Class
6+
class Led_Light():
117
def __init__(self, pin, flashing=False, debug=False):
12-
super().__init__(pin, Pin.OUT)
13-
self.led_light_state
14-
self.__debug = debug
15-
self.__pin = pin
16-
self.__flashing = flashing
17-
18-
def on(self):
19-
# method overriding polymorphism of the Super Class
20-
self.high()
21-
if self.__debug:
22-
print(f"LED connected to Pin {self.__pin} is {self.led_light_state}")
23-
24-
def off(self):
25-
# method overriding polymorphism of the Super Class
26-
self.low()
27-
if self.__debug:
28-
print(f"LED connected to Pin {self.__pin} is {self.led_light_state}")
29-
30-
def toggle(self):
31-
# method overriding polymorphism of the Super Class
32-
if self.value() == 0:
33-
self.on()
34-
elif self.value() == 1:
35-
self.off()
36-
37-
@property
38-
def led_light_state(self):
39-
# method overloading polymorphism in this Class
40-
return self.value()
41-
42-
@led_light_state.setter
43-
def led_light_state(self, value):
44-
# method overloading polymorphism in this Class
45-
if value == 1:
46-
self.off()
47-
elif value == 0:
48-
self.on()
49-
8+
self.debug = debug #PUBLIC attribute
9+
self.__pin = pin #Encapsulated PRIVATE attribute
5010

5111
red_light = Led_Light(3, False, False)
5212

53-
while True:
54-
print(red_light.led_light_state) # Allowed
55-
red_light.led_light_state = 1 # Allowed
56-
print(
57-
f"Not allowed: {red_light.__pin} ???"
58-
) # Not allowed, should raise AttributeError
13+
try:
14+
print(red_light.debug)
15+
print("SUCCESS: Accessed a public attribute")
16+
except AttributeError:
17+
print("ERROR: AttributeError not expected!")
18+
19+
try:
20+
print(red_light.__pin)
21+
print("ERROR: Accessed private attribute when it should be hidden!")
22+
except AttributeError:
23+
print("SUCCESS: AttributeError raised as expected")

examples/v09.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ def led_light_state(self, value):
5151
red_light = Led_Light(3, False, False)
5252

5353
while True:
54-
print(red_light.led_light_state) # Allowed
55-
red_light.led_light_state = 1 # Allowed
56-
print(
57-
f"Not allowed: {red_light.__pin} ???"
58-
) # Not allowed, should raise AttributeError
54+
print(red_light.led_light_state)
55+
red_light.led_light_state = 1
56+
sleep(0.25)
57+
print(red_light.led_light_state)
58+
red_light.led_light_state = 0
59+
sleep(0.25)

examples/v10.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Abstraction Example
33
"""
44

5-
from project.py_scripts.LL_unit_Test import Led_Light
5+
from led_light import Led_Light
66
from time import sleep
77

88
red_light = Led_Light(3, True, True)

0 commit comments

Comments
 (0)