Added sensor reading example, with mux support

pull/259/head
ZodiusInfuser 2022-03-18 22:35:59 +00:00
rodzic 3375a9ec20
commit e41a8bd6e5
4 zmienionych plików z 103 dodań i 4 usunięć

Wyświetl plik

@ -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)

Wyświetl plik

@ -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

Wyświetl plik

@ -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);

Wyświetl plik

@ -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