-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Arduino control for odors delivery
- Loading branch information
Showing
3 changed files
with
159 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from stytra import Stytra, Protocol | ||
from stytra.stimulation.stimuli.set_arduino_pin import WriteArduinoPin | ||
|
||
LAYOUT = (dict(pin=5, mode="pwm", ad="d"), | ||
dict(pin=11, mode="pwm", ad="d")) | ||
|
||
|
||
class MotorProtocol(Protocol): | ||
name = 'motor_protocol' | ||
|
||
def get_stim_sequence(self): | ||
stimuli = [ | ||
WriteArduinoPin(port='COM3', layout=LAYOUT, pin=5, value=0.8, duration=4.0), | ||
WriteArduinoPin(port='COM3', layout=LAYOUT, pin=5, value=0) | ||
] | ||
return stimuli | ||
|
||
|
||
if __name__ == "__main__": | ||
|
||
st = WriteArduinoPin(port='COM3', layout=LAYOUT, pin=5, value=0.8, duration=4.0) | ||
#Stytra(protocol=MotorProtocol()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
try: | ||
import pyfirmata as pyfi | ||
except ImportError: | ||
print('Pyfirmata is not installed') | ||
|
||
# direct mode to call pins with pyfirmata | ||
from time import sleep | ||
|
||
MODE_DICT = dict(input=pyfi.INPUT, output=pyfi.OUTPUT, pwm=pyfi.PWM, servo=pyfi.SERVO) | ||
AD_ATTR_DICT = dict(a="analog", d="digital") | ||
|
||
|
||
class PyfirmataConnection: | ||
'''Using StandardFirmata and pyfirmata to control an Arduino board with Python''' | ||
|
||
def __init__(self, com_port, layout, iterator=True): | ||
'''If using analog ports is handy to start an iterator thread''' | ||
|
||
self.board = pyfi.Arduino(com_port) | ||
print('Connection successfully established') | ||
sleep(1) | ||
|
||
# Convert configuration list of dictionaries in a dictionary of configurations: | ||
self.layout = dict() | ||
for pin_conf in layout: | ||
pin_conf["mode"] = MODE_DICT[pin_conf["mode"]] | ||
self.layout[pin_conf.pop("pin")] = pin_conf | ||
|
||
if iterator: | ||
self.it = pyfi.util.Iterator(self.board) | ||
self.it.start() | ||
|
||
self.initialize() | ||
|
||
def initialize(self): | ||
""" | ||
""" | ||
for pin_n, pin_conf in self.layout.items(): | ||
getattr(self.board, AD_ATTR_DICT[pin_conf["ad"]])[pin_n].mode = pin_conf["mode"] | ||
|
||
def read(self, pin_n): | ||
"""Access and read from a pin. | ||
Parameters | ||
---------- | ||
pin_n : int | ||
Integer indicating pin to be read | ||
Returns | ||
------- | ||
float or int | ||
""" | ||
|
||
pin_conf = self.layout[pin_n] | ||
value = getattr(self.board, AD_ATTR_DICT[pin_conf["ad"]])[pin_n].read() | ||
|
||
return value | ||
|
||
def read_all(self): | ||
"""Read all pins that are set as inputs | ||
Returns | ||
------- | ||
list of floats or ints | ||
""" | ||
return [self.read(pin_n) for pin_n, pin_conf in self.layout.items() if pin_conf["mode"]=="input"] | ||
|
||
def write(self, pin_n, value): | ||
""" | ||
Parameters | ||
---------- | ||
pin_n: | ||
Integer indicating pin to be written | ||
Returns | ||
------- | ||
""" | ||
pin_conf = self.layout[pin_n] | ||
sel_pins = getattr(self.board, AD_ATTR_DICT[pin_conf["ad"]])[pin_n] | ||
sel_pins.write(value) | ||
|
||
def write_multiple(self, values=None): | ||
for pin_n, value in values.items(): | ||
self.write(pin_n, value) | ||
return True | ||
|
||
def close(self): | ||
"""Close connection""" | ||
|
||
self.board.exit() | ||
return print('Communication successfully interrupted') | ||
|
||
|
||
if __name__ == "__main__": | ||
LAYOUT = (dict(pin=5, mode="pwm", ad="d"), | ||
dict(pin=11, mode="pwm", ad="d")) | ||
|
||
write_multiple = {5: 0, | ||
11: 0} | ||
|
||
try_pumps = PyfirmataConnection(com_port='COM3', layout=LAYOUT) | ||
#try_pumps.write(5, 0) | ||
|
||
sleep(5) | ||
try_pumps.write_multiple(write_multiple) | ||
print("sending pulse") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
from stytra.stimulation.stimuli import Stimulus | ||
from stytra.hardware.external_pyfirmata import PyfirmataConnection | ||
|
||
|
||
class WriteArduinoPin(Stimulus): | ||
"""Simple class to write a value on an arduino pin. Mostly a simple example to implement | ||
your own fancy arduino classes. | ||
Parameters | ||
---------- | ||
pin : int | ||
Pin number. | ||
value : float or int | ||
Value to be set on the pin. | ||
""" | ||
|
||
name = "set_arduino_pin" | ||
|
||
def __init__(self, pin_values_dict, *args, **kwargs): | ||
self.pin_values = pin_values_dict | ||
super().__init__(*args, **kwargs) | ||
|
||
def start(self): | ||
super().start() | ||
self._experiment.arduino_board.write_multiple(self.pin_values) | ||
|
||
|