kopia lustrzana https://github.com/pimoroni/pimoroni-pico
Added sensor reading example, with mux support
rodzic
3375a9ec20
commit
e41a8bd6e5
|
@ -0,0 +1,42 @@
|
|||
import time
|
||||
from machine import Pin
|
||||
from pimoroni import Analog, AnalogMux, Button
|
||||
from servo import servo2040
|
||||
|
||||
# Press "Boot" to exit the program.
|
||||
|
||||
# Create the user button
|
||||
user_sw = Button(servo2040.USER_SW)
|
||||
|
||||
# Set up the shared analog inputs
|
||||
sen_adc = Analog(servo2040.SHARED_ADC)
|
||||
vol_adc = Analog(servo2040.SHARED_ADC, servo2040.VOLTAGE_GAIN)
|
||||
cur_adc = Analog(servo2040.SHARED_ADC, servo2040.CURRENT_GAIN,
|
||||
servo2040.SHUNT_RESISTOR, servo2040.CURRENT_OFFSET)
|
||||
|
||||
# Set up the analog multiplexer, including the pin for controlling pull-up/pull-down
|
||||
mux = AnalogMux(servo2040.ADC_ADDR_0, servo2040.ADC_ADDR_1, servo2040.ADC_ADDR_2,
|
||||
muxed_pin=Pin(servo2040.SHARED_ADC))
|
||||
|
||||
# Set up the sensor addresses and have them pulled down by default
|
||||
sensor_addrs = list(range(servo2040.SENSOR_1_ADDR, servo2040.SENSOR_6_ADDR + 1))
|
||||
for addr in sensor_addrs:
|
||||
mux.configure_pull(addr, Pin.PULL_DOWN)
|
||||
|
||||
|
||||
# Read sensors until the user button is pressed
|
||||
while user_sw.raw() is not True:
|
||||
|
||||
# Read each sensor in turn and print its voltage
|
||||
for i in range(len(sensor_addrs)):
|
||||
mux.select(sensor_addrs[i])
|
||||
print("S", i + 1, " = ", round(sen_adc.read_voltage(), 3), sep="", end=", ")
|
||||
|
||||
# Read the voltage sense and print the value
|
||||
mux.select(servo2040.VOLTAGE_SENSE_ADDR)
|
||||
print("Voltage =", round(vol_adc.read_voltage(), 4), end=", ")
|
||||
|
||||
mux.select(servo2040.CURRENT_SENSE_ADDR)
|
||||
print("Current =", round(cur_adc.read_current(), 4))
|
||||
|
||||
time.sleep(0.5)
|
|
@ -14,7 +14,7 @@ from servo import ServoCluster, servo2040
|
|||
|
||||
SPEED = 5 # The speed that the LEDs will cycle at
|
||||
BRIGHTNESS = 0.4 # The brightness of the LEDs
|
||||
UPDATES = 50 # How many times the LEDs and Servos will be updated per second
|
||||
UPDATES = 50 # How many times to update LEDs and Servos per second
|
||||
SERVO_EXTENT = 80.0 # How far from zero to move the servos
|
||||
|
||||
# Create a servo cluster for pins 0 to 7, using PIO 0 and State Machine 0
|
||||
|
|
|
@ -167,6 +167,8 @@ typedef struct _mp_obj_float_t {
|
|||
mp_float_t value;
|
||||
} mp_obj_float_t;
|
||||
mp_obj_float_t servo2040_shunt_resistor = {{&mp_type_float}, 0.003f};
|
||||
mp_obj_float_t servo2040_voltage_gain = {{&mp_type_float}, 0.5f};
|
||||
mp_obj_float_t servo2040_current_offset = {{&mp_type_float}, -0.02f};
|
||||
|
||||
/***** Globals Table *****/
|
||||
STATIC const mp_map_elem_t servo2040_globals_table[] = {
|
||||
|
@ -211,7 +213,9 @@ STATIC const mp_map_elem_t servo2040_globals_table[] = {
|
|||
{ MP_ROM_QSTR(MP_QSTR_VOLTAGE_SENSE_ADDR), MP_ROM_INT(0b110) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_CURRENT_SENSE_ADDR), MP_ROM_INT(0b111) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SHUNT_RESISTOR), MP_ROM_PTR(&servo2040_shunt_resistor) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ADC_GAIN), MP_ROM_INT(69) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_CURRENT_GAIN), MP_ROM_INT(69) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_VOLTAGE_GAIN), MP_ROM_PTR(&servo2040_voltage_gain) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_CURRENT_OFFSET), MP_ROM_PTR(&servo2040_current_offset) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_servo2040_globals, servo2040_globals_table);
|
||||
|
||||
|
|
|
@ -7,13 +7,14 @@ PICO_EXPLORER_I2C_PINS = {"sda": 20, "scl": 21}
|
|||
|
||||
|
||||
class Analog:
|
||||
def __init__(self, pin, amplifier_gain=1, resistor=0):
|
||||
def __init__(self, pin, amplifier_gain=1, resistor=0, offset=0):
|
||||
self.gain = amplifier_gain
|
||||
self.resistor = resistor
|
||||
self.offset = offset
|
||||
self.pin = ADC(pin)
|
||||
|
||||
def read_voltage(self):
|
||||
return self.pin.read_u16() * 3.3 / 65535 / self.gain
|
||||
return max((((self.pin.read_u16() * 3.3) / 65535) + self.offset) / self.gain, 0.0)
|
||||
|
||||
def read_current(self):
|
||||
if self.resistor > 0:
|
||||
|
@ -22,6 +23,58 @@ class Analog:
|
|||
return self.read_voltage()
|
||||
|
||||
|
||||
class AnalogMux:
|
||||
def __init__(self, addr0, addr1=None, addr2=None, en=None, muxed_pin=None):
|
||||
self.addr0_pin = Pin(addr0, Pin.OUT)
|
||||
self.addr1_pin = Pin(addr1, Pin.OUT) if addr1 is not None else None
|
||||
self.addr2_pin = Pin(addr2, Pin.OUT) if addr2 is not None else None
|
||||
self.en_pin = Pin(en, Pin.OUT) if en is not None else None
|
||||
self.max_address = 0b001
|
||||
if addr1 is not None:
|
||||
self.max_address = 0b011
|
||||
if addr2 is not None:
|
||||
self.max_address = 0b111
|
||||
self.pulls = [None] * (self.max_address + 1)
|
||||
self.muxed_pin = muxed_pin
|
||||
|
||||
def select(self, address):
|
||||
if address < 0:
|
||||
raise ValueError("address is less than zero")
|
||||
elif address > self.max_address:
|
||||
raise ValueError("address is greater than number of available addresses")
|
||||
else:
|
||||
if self.muxed_pin and self.pulls[address] is None:
|
||||
self.muxed_pin.init(Pin.IN, None)
|
||||
|
||||
self.addr0_pin.value(address & 0b001)
|
||||
|
||||
if self.addr1_pin is not None:
|
||||
self.addr1_pin.value(address & 0b010)
|
||||
|
||||
if self.addr2_pin is not None:
|
||||
self.addr2_pin.value(address & 0b100)
|
||||
|
||||
if self.en_pin is not None:
|
||||
self.en_pin.value(1)
|
||||
|
||||
if self.muxed_pin and self.pulls[address] is not None:
|
||||
self.muxed_pin.init(Pin.IN, self.pulls[address])
|
||||
|
||||
def disable(self):
|
||||
if self.en_pin is not None:
|
||||
self.en_pin.value(0)
|
||||
else:
|
||||
raise RuntimeError("there is no enable pin assigned to this mux")
|
||||
|
||||
def configure_pull(self, address, pull=None):
|
||||
if address < 0:
|
||||
raise ValueError("address is less than zero")
|
||||
elif address > self.max_address:
|
||||
raise ValueError("address is greater than number of available addresses")
|
||||
else:
|
||||
self.pulls[address] = pull
|
||||
|
||||
|
||||
class Button:
|
||||
def __init__(self, button, invert=True, repeat_time=200, hold_time=1000):
|
||||
self.invert = invert
|
||||
|
|
Ładowanie…
Reference in New Issue