Skip to content

Commit

Permalink
Improvements based on feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
ZodiusInfuser committed Nov 13, 2023
1 parent 444fe26 commit 5891632
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 33 deletions.
32 changes: 27 additions & 5 deletions docs/modules/bench_power.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This is the library reference for the [Bench Power Module for Yukon](https://pim
- [Using the Module](#using-the-module)
- [Controlling its Output](#controlling-its-output)
- [Changing its Voltage](#changing-its-voltage)
- [Reading back Voltage](#reading-back-voltage)
- [Onboard Sensors](#onboard-sensors)
- [References](#references)
- [Constants](#constants)
Expand Down Expand Up @@ -72,11 +73,32 @@ The first is by calling `.set_voltage(voltage)`, and providing it with a voltage
The second is by calling `.set_percent(percent)`, and providing it with a value from `0.0` to `1.0`.


### Onboard Sensors
### Reading back Voltage

The Bench Power module features a voltage divider, letting its output be measured by calling `.read_voltage()`.

There is also an onboard thermistor, letting its temperature be monitored. This can be read by calling `.read_temperature()`.
:warning: Due to variations in component values on the Bench Power module and Yukon board itself, the voltage returned by this function may over or under report what is actually output. The `BenchPowerModule` class performs a 3-point conversion to mitigate this, but if absolute accuracy is needed for your application then the following constants should be modified with assistance of an external multimeter:

```python
# The three voltage points used for conversion
VOLTAGE_MIN = 0.6713
VOLTAGE_MID = 6.5052
VOLTAGE_MAX = 12.3953

# The ADC values (between 0.0 and 3.3) measured at the three voltage points
MEASURED_AT_VOLTAGE_MIN = 0.1477
MEASURED_AT_VOLTAGE_MID = 1.1706
MEASURED_AT_VOLTAGE_MAX = 2.2007

# The PWM range the voltage points are over, with 0.0 resulting in the maximum voltage
PWM_MIN = 0.3
PWM_MAX = 0.0
```


### Onboard Sensors

The Bench Power module features an onboard thermistor, letting its temperature be monitored. This can be read by calling `.read_temperature()`.

Additionally, the power good status of the onboard regulator can be read by calling `.read_power_good()`. This will be `True` during normal operation, but will switch to `False` under various conditions such as the input voltage dropping below what is needed for the module to achieve a stable output. For details of other conditions, check the [TPS54A24 datasheet](https://www.ti.com/lit/ds/symlink/tps54a24.pdf).

Expand All @@ -90,9 +112,9 @@ NAME = "Bench Power"
VOLTAGE_MAX = 12.3953
VOLTAGE_MID = 6.5052
VOLTAGE_MIN = 0.6713
VOLTAGE_MIN_MEASURE = 0.1477
VOLTAGE_MID_MEASURE = 1.1706
VOLTAGE_MAX_MEASURE = 2.2007
MEASURED_AT_VOLTAGE_MIN = 0.1477
MEASURED_AT_VOLTAGE_MID = 1.1706
MEASURED_AT_VOLTAGE_MAX = 2.2007
PWM_MIN = 0.3
PWM_MAX = 0.0
TEMPERATURE_THRESHOLD = 80.0
Expand Down
2 changes: 1 addition & 1 deletion examples/modules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ You will need to copy the files "ahoy.wav" and "bye.wav" over to the root of you
### Single Power
[bench_power/single_power.py](bench_power/single_power.py)

Control the variable output of a Bench Power Module connected to Slot1.
Control the variable output of a Bench Power Module connected to Slot1, and print out the voltage that is measured.


### Multiple Powers
Expand Down
8 changes: 6 additions & 2 deletions examples/modules/audio_amp/tone_song.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,7 @@


# Variables for recording the button state and if it has been toggled
# Starting as True makes the song play automatically
button_toggle = True
button_toggle = False
last_button_state = False


Expand All @@ -147,6 +146,11 @@ def check_button_toggle():
amp.enable() # Enable the audio amp. This includes I2C configuration
amp.set_volume(NOTE_VOLUME) # Set the output volume of the audio amp

print() # New line
print("Controls:")
print("- Press 'A' to start or stop the tone song")
print() # New line

# Loop until the BOOT/USER button is pressed
while not yukon.is_boot_pressed():

Expand Down
10 changes: 10 additions & 0 deletions examples/modules/audio_amp/wav_play.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ def button_newly_pressed(btn):

amp.enable() # Enable the audio amplifier

print() # New line
print("Controls:")
print(f"- Press 'A' to play '{WAV_FILE_A}', or stop what is currently playing")
print(f"- Press 'B' to play '{WAV_FILE_B}', or stop what is currently playing")
print() # New line

# Loop until the BOOT/USER button is pressed
while not yukon.is_boot_pressed():

Expand All @@ -52,8 +58,10 @@ def button_newly_pressed(btn):
amp.player.play_wav(WAV_FILE_A) # Play file A
amp.set_volume(VOLUME_A) # Set the volume to play file A at
yukon.set_led('A', True) # Show that file A is playing
print("Playing the first WAV file")
else:
amp.player.stop() # Stop whichever file is currently playing
print("Stopping playback")

# Has the button been pressed?
if button_newly_pressed('B'):
Expand All @@ -62,8 +70,10 @@ def button_newly_pressed(btn):
amp.player.play_wav(WAV_FILE_B) # Play file B
amp.set_volume(VOLUME_B) # Set the volume to play file B at
yukon.set_led('B', True) # Show that file B is playing
print("Playing the second WAV file")
else:
amp.player.stop() # Stop whichever file is currently playing
print("Stopping playback")

# Has either file stopped playing?
if not amp.player.is_playing():
Expand Down
42 changes: 25 additions & 17 deletions examples/modules/bench_power/single_power.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,36 @@
from pimoroni_yukon.modules import BenchPowerModule

"""
Control the variable output of a Bench Power Module connected to Slot1.
Control the variable output of a Bench Power Module connected to Slot1,
and print out the voltage that is measured.
Press "A" to increase the output voltage.
Press "B" to decrease the output voltage.
Press "Boot/User" to exit the program.
Note: Due to variations in component values on the Bench Power module and Yukon
board itself, the measured voltage may over or under report what is actually output.
It is always best to verify the output voltage with a multimeter.
"""

# Constants
INITIAL_VOLTAGE = 5.0 # The voltage to start the BenchPowerModule with
VOLTAGE_STEP = 0.1 # How much to increase/decrease the voltage by each update loop
DELAY = 0.2 # The time to sleep after setting a new voltage before it can be read back
SAMPLES = 100 # How many voltage readings to take to produce an average
DELAY = 0.5 # The time to monitor before reading back what was measured

# Variables
yukon = Yukon() # Create a new Yukon object
module = BenchPowerModule() # Create a BenchPowerModule object
voltage = INITIAL_VOLTAGE # The voltage to have the BenchPowerModule output


# Function to print out the target and measured voltages
def print_voltages():
# Function to monitor for a set duration, then print out the bench power's measured output voltage
def monitor_and_print(duration):
global voltage
global module
yukon.monitored_sleep(DELAY)
measured = module.read_voltage(SAMPLES) # Measure the voltage that is actually being output
print(f"Target = {voltage} V, Measured = {measured} V") # Print out intended and measured voltages
yukon.monitored_sleep(duration)
measured_avg = module.get_readings()["Vo_avg"]
print(f"Target = {voltage} V, Measured = {measured_avg} V")


# Wrap the code in a try block, to catch any exceptions (including KeyboardInterrupt)
Expand All @@ -39,7 +43,14 @@ def print_voltages():
yukon.enable_main_output() # Turn on power to the module slots
module.set_voltage(voltage) # Set the initial voltage to output
module.enable() # Enable the BenchPowerModule's onboard regulator
print_voltages() # Print out the new voltages

print() # New line
print("Controls:")
print(f"- Press 'A' to increase the output voltage by {VOLTAGE_STEP}V")
print(f"- Press 'B' to decrease the output voltage by {VOLTAGE_STEP}V")
print() # New line

monitor_and_print(DELAY) # Monitor for the set duration, then print out the measured voltage

# Loop until the BOOT/USER button is pressed
while not yukon.is_boot_pressed():
Expand All @@ -55,18 +66,15 @@ def print_voltages():
if state_a != state_b:
# Has the A button been newly pressed?
if state_a is True:
voltage -= 0.1 # Decrease the voltage
module.set_voltage(voltage) # Set the new voltage to output
print_voltages() # Print out the new voltages
voltage -= VOLTAGE_STEP # Decrease the voltage
module.set_voltage(voltage) # Set the new voltage to output

# Has the B button been newly pressed?
if state_b is True:
voltage += 0.1 # Increase the voltage
module.set_voltage(voltage) # Set the new voltage to output
print_voltages() # Print out the new voltages
voltage += VOLTAGE_STEP # Increase the voltage
module.set_voltage(voltage) # Set the new voltage to output

# Perform a single check of Yukon's internal voltage, current, and temperature sensors
yukon.monitor_once()
monitor_and_print(DELAY) # Monitor for the set duration, then print out the measured voltage

finally:
# Put the board back into a safe state, regardless of how the program may have ended
Expand Down
6 changes: 6 additions & 0 deletions examples/modules/dual_output/two_outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
yukon.enable_main_output() # Turn on power to the module slots
module.enable() # Enable the output switches

print() # New line
print("Controls:")
print(f"- Press 'A' to toggle the state of the '{OUTPUT_NAMES[0]}' output")
print(f"- Press 'B' to toggle the state of the '{OUTPUT_NAMES[1]}' output")
print() # New line

# Loop until the BOOT/USER button is pressed
while not yukon.is_boot_pressed():

Expand Down
7 changes: 7 additions & 0 deletions examples/modules/serial_servo/calibrate_servo.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ def button_newly_pressed(btn):
# giving it access to the module's UART and Duplexer
servo = LXServo(SERVO_ID, module.uart, module.duplexer)

print() # New line
print("Controls:")
print(f"- Press 'A' to increment the servo angle offset by {ANGLE_INCREMENT}")
print(f"- Press 'B' to decrement the servo angle offset by {ANGLE_INCREMENT}")
print("- Press 'Boot/User' to save the angle offset to the servo and exit the program.")
print() # New line

# Print out the initial angle offset stored on the servo
print(f"Angle Offset: {servo.angle_offset()}")

Expand Down
6 changes: 6 additions & 0 deletions examples/modules/serial_servo/drive_servo.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ def button_newly_pressed(btn):
# giving it access to the module's UART and Duplexer
servo = LXServo(SERVO_ID, module.uart, module.duplexer)

print() # New line
print("Controls:")
print(f"- Press 'A' to drive the servo at {SPEED}")
print("- Press 'B' to stop the servo")
print() # New line

current_time = ticks_ms() # Record the start time of the program loop

# Loop until the BOOT/USER button is pressed
Expand Down
6 changes: 6 additions & 0 deletions examples/modules/serial_servo/move_servo.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ def button_newly_pressed(btn):
# giving it access to the module's UART and Duplexer
servo = LXServo(SERVO_ID, module.uart, module.duplexer)

print() # New line
print("Controls:")
print(f"- Press 'A' to move the servo to {ANGLE_A} degrees")
print(f"- Press 'B' to move the servo to {ANGLE_B} degrees")
print() # New line

current_time = ticks_ms() # Record the start time of the program loop

# Loop until the BOOT/USER button is pressed
Expand Down
16 changes: 8 additions & 8 deletions lib/pimoroni_yukon/modules/bench_power.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
class BenchPowerModule(YukonModule):
NAME = "Bench Power"

VOLTAGE_MAX = 12.3953
VOLTAGE_MID = 6.5052
VOLTAGE_MIN = 0.6713
VOLTAGE_MIN_MEASURE = 0.1477
VOLTAGE_MID_MEASURE = 1.1706
VOLTAGE_MAX_MEASURE = 2.2007
VOLTAGE_MID = 6.5052
VOLTAGE_MAX = 12.3953
MEASURED_AT_VOLTAGE_MIN = 0.1477
MEASURED_AT_VOLTAGE_MID = 1.1706
MEASURED_AT_VOLTAGE_MAX = 2.2007
PWM_MIN = 0.3
PWM_MAX = 0.0

Expand Down Expand Up @@ -92,10 +92,10 @@ def set_percent(self, percent):
def read_voltage(self, samples=1):
# return (self.__read_adc1(samples) * (100 + 22)) / 22
voltage = self.__read_adc1(samples)
if voltage >= self.VOLTAGE_MID_MEASURE:
return ((voltage - self.VOLTAGE_MID_MEASURE) * (self.VOLTAGE_MAX - self.VOLTAGE_MID)) / (self.VOLTAGE_MAX_MEASURE - self.VOLTAGE_MID_MEASURE) + self.VOLTAGE_MID
if voltage >= self.MEASURED_AT_VOLTAGE_MID:
return ((voltage - self.MEASURED_AT_VOLTAGE_MID) * (self.VOLTAGE_MAX - self.VOLTAGE_MID)) / (self.MEASURED_AT_VOLTAGE_MAX - self.MEASURED_AT_VOLTAGE_MID) + self.VOLTAGE_MID
else:
return max(((voltage - self.VOLTAGE_MIN_MEASURE) * (self.VOLTAGE_MID - self.VOLTAGE_MIN)) / (self.VOLTAGE_MID_MEASURE - self.VOLTAGE_MIN_MEASURE) + self.VOLTAGE_MIN, 0.0)
return max(((voltage - self.MEASURED_AT_VOLTAGE_MIN) * (self.VOLTAGE_MID - self.VOLTAGE_MIN)) / (self.MEASURED_AT_VOLTAGE_MID - self.MEASURED_AT_VOLTAGE_MIN) + self.VOLTAGE_MIN, 0.0)

def read_power_good(self):
return self.__power_good.value() == 1
Expand Down

0 comments on commit 5891632

Please sign in to comment.