Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove mode check on analog read #354

Merged
merged 4 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 14 additions & 16 deletions sbot/arduino.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,6 @@ class AnalogPins(IntEnum):
A5 = 19


DIGITAL_READ_MODES = {GPIOPinMode.INPUT, GPIOPinMode.INPUT_PULLUP, GPIOPinMode.OUTPUT}
DIGITAL_WRITE_MODES = {GPIOPinMode.OUTPUT}
ANALOG_READ_MODES = {GPIOPinMode.INPUT}


class Arduino(Board):
"""
The Arduino board interface.
Expand Down Expand Up @@ -319,8 +314,6 @@ def digital_value(self) -> bool:
:return: The digital value of the pin.
"""
self._check_if_disabled()
if self.mode not in DIGITAL_READ_MODES:
raise IOError(f'Digital read is not supported in {self.mode}')
response = self._serial.query(f'PIN:{self._index}:DIGITAL:GET?')
return (response == '1')

Expand All @@ -335,12 +328,14 @@ def digital_value(self, value: bool) -> None:
:raises IOError: If this pin cannot be controlled.
"""
self._check_if_disabled()
if self.mode not in DIGITAL_WRITE_MODES:
raise IOError(f'Digital write is not supported in {self.mode}')
if value:
self._serial.write(f'PIN:{self._index}:DIGITAL:SET:1')
else:
self._serial.write(f'PIN:{self._index}:DIGITAL:SET:0')
try:
if value:
self._serial.write(f'PIN:{self._index}:DIGITAL:SET:1')
else:
self._serial.write(f'PIN:{self._index}:DIGITAL:SET:0')
except RuntimeError as e:
if 'is not supported in' in str(e):
raise IOError(str(e))

@property
@log_to_debug
Expand All @@ -358,11 +353,14 @@ def analog_value(self) -> float:
ADC_MIN = 0

self._check_if_disabled()
if self.mode not in ANALOG_READ_MODES:
raise IOError(f'Analog read is not supported in {self.mode}')
if not self._supports_analog:
raise IOError('Pin does not support analog read')
response = self._serial.query(f'PIN:{self._index}:ANALOG:GET?')
try:
response = self._serial.query(f'PIN:{self._index}:ANALOG:GET?')
except RuntimeError as e:
# The firmware returns a NACK if the pin is not in INPUT mode
if 'is not supported in' in str(e):
raise IOError(str(e))
# map the response from the ADC range to the voltage range
return map_to_float(int(response), ADC_MIN, ADC_MAX, 0.0, 5.0)

Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def query(self, request: str) -> str:
"""
# Assert that we have not run out of responses
# and that the request is the next one we expect
assert self.request_index < len(self.responses)
assert self.request_index < len(self.responses), f"Unexpected request: {request}"
assert request == self.responses[self.request_index][0]

# Fetch the response and increment the request index
Expand Down
19 changes: 0 additions & 19 deletions tests/test_arduino.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,8 @@ def test_arduino_pins(arduino_serial: MockArduino) -> None:

# Test that we can get the digital value of a pin
arduino_serial.serial_wrapper._add_responses([
("PIN:2:MODE:GET?", "OUTPUT"), # mode is read before digital value
("PIN:2:DIGITAL:GET?", "1"),
("PIN:10:MODE:GET?", "INPUT_PULLUP"),
("PIN:10:DIGITAL:GET?", "0"),
("PIN:14:MODE:GET?", "INPUT"),
("PIN:14:DIGITAL:GET?", "1"),
])
assert arduino.pins[2].digital_value is True
Expand All @@ -129,32 +126,16 @@ def test_arduino_pins(arduino_serial: MockArduino) -> None:

# Test that we can set the digital value of a pin
arduino_serial.serial_wrapper._add_responses([
("PIN:2:MODE:GET?", "OUTPUT"), # mode is read before digital value
("PIN:2:DIGITAL:SET:1", "ACK"),
("PIN:2:MODE:GET?", "OUTPUT"),
("PIN:2:DIGITAL:SET:0", "ACK"),
("PIN:10:MODE:GET?", "INPUT_PULLUP"),
("PIN:10:MODE:GET?", "INPUT_PULLUP"),
("PIN:14:MODE:GET?", "INPUT"),
("PIN:14:MODE:GET?", "INPUT"),
])
arduino.pins[2].digital_value = True
arduino.pins[2].digital_value = False
with pytest.raises(IOError, match=r"Digital write is not supported.*"):
arduino.pins[10].digital_value = False
with pytest.raises(IOError, match=r"Digital write is not supported.*"):
arduino.pins[AnalogPins.A0].digital_value = True

# Test that we can get the analog value of a pin
arduino_serial.serial_wrapper._add_responses([
("PIN:2:MODE:GET?", "OUTPUT"), # mode is read before analog value
("PIN:2:MODE:GET?", "OUTPUT"),
("PIN:10:MODE:GET?", "INPUT"),
("PIN:14:MODE:GET?", "INPUT"),
("PIN:14:ANALOG:GET?", "1000"),
])
with pytest.raises(IOError, match=r"Analog read is not supported.*"):
arduino.pins[2].analog_value
with pytest.raises(IOError, match=r"Pin does not support analog read"):
arduino.pins[10].analog_value
# 4.888 = round((5 / 1023) * 1000, 3)
Expand Down
Loading