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

Add missing helper functions and logging #1

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
be0c7a0
can now pip instal in editable mode
Poofjunior Apr 14, 2022
ef9936e
updating readme
Poofjunior Apr 14, 2022
69e11f0
fixing readme bug
Poofjunior Apr 14, 2022
4fff7ba
adding udev rules
Poofjunior Apr 14, 2022
d974ee4
device_names is now a default dict; examples now also work on linux
Poofjunior Apr 14, 2022
fbdacbd
fixing pdf link; tweaking serial port to use ftdi rule
Poofjunior Apr 15, 2022
33d8cc8
Update README.md
Poofjunior Apr 15, 2022
0191b23
PEP 563 return type hints
Poofjunior Apr 18, 2022
6a73a99
grand messages.py refactor
Poofjunior Apr 19, 2022
4108f6b
more message.py refactor
Poofjunior Apr 19, 2022
e3457bb
adding harp rules
Poofjunior Apr 19, 2022
455de81
adding simple behavior io stuff
Poofjunior Apr 19, 2022
4e5e58f
adding prelim behavior driver
Poofjunior Apr 19, 2022
0e47767
adding a string representation
Poofjunior Apr 20, 2022
43629c0
added __str__ and active mode script
Poofjunior Apr 21, 2022
edfc361
printing DI event changes works
Poofjunior Apr 21, 2022
d5d835a
updating how payload is parsed
Poofjunior Apr 21, 2022
3a122a3
adding enabling of events
Poofjunior Apr 22, 2022
2fc5c58
adding inWaiting to reads
Poofjunior Apr 22, 2022
3f7dfba
read dumped registers
Poofjunior Sep 28, 2023
401bd36
expose more core features
Poofjunior Dec 21, 2023
ac57cb3
Merge pull request #1 from AllenNeuralDynamics/dev/editable_mode
Poofjunior Dec 21, 2023
c2bba09
add WriteU32 and WriteS32
Poofjunior Dec 21, 2023
fb54476
fix signed error in WriteS32
Poofjunior Dec 21, 2023
e7900d4
add debug level logging.
Poofjunior Jan 12, 2024
1b1e833
Added ReadS32 and refactored WriteS32 to handle array inputs
jessy-liao May 17, 2024
325769c
Merge pull request #2 from jessy-liao/master
Poofjunior Jul 18, 2024
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
3 changes: 3 additions & 0 deletions 10-harp.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# UDEV rules for a Harp Device (actually an ftdi RS232 Serial [Uart] IC)
SUBSYSTEMS=="usb", ENV{.LOCAL_ifNum}="$attr{bInterfaceNumber}"
SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE="0666", SYMLINK+="harp_device_%E{.LOCAL_ifNum}"
26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@


# pyharp

Harp implementation of the Harp protocol.

## Edit the code
## Install with Pip
From this directory, install in editable mode with
````
pip install -e .
````

Note that for the above to work, a fairly recent version of pip (>= 21.3) is required.

## Install with Poetry

Each Python user has is own very dear IDE for editing. Here, we are leaving instructions on how to edit this code using pyCharm, Anaconda and Poetry.

Expand Down Expand Up @@ -69,3 +75,17 @@ Device info:
* Firmware version: 1.0
* Device user name: IBL_rig_0
```

## for Linux

### Install UDEV Rules

Install by either copying `10-harp.rules` over to your `/etc/udev/rules.d` folder or by symlinking it with:
````
sudo ln -s /absolute/path/to/vibratome-controller/10-harp.rules /etc/udev/rules.d/10-harp.rules
````

Then reload udev rules with
````
sudo udevadm control --reload-rules
````
53 changes: 53 additions & 0 deletions examples/behavior_device_driver_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env python3
from pyharp.drivers.behavior import Behavior
from pyharp.messages import HarpMessage
from pyharp.messages import MessageType
from struct import *
import os


# Open the device and print the info on screen
# Open serial connection and save communication to a file
device = None
if os.name == 'posix': # check for Linux.
device = Behavior("/dev/harp_device_00", "ibl.bin")
else: # assume Windows.
device = Behavior("COM95", "ibl.bin")

print(f"digital inputs: {device.all_input_states:03b}")
print(f"digital outputs: {device.all_output_states:016b}")
print(f"setting digital outputs")
#device.all_output_states = 0x0000 # Set the whole port directly.
#device.set_outputs(0xFFFF) # Set the values set to logic 1 only.
#device.clear_outputs(0xFFFF)# Clear values set to logic 1 only.
print(f"digital outputs: {device.all_output_states:016b}")
device.set_io_configuration(0b111)

# TODO: FIXME. IOs are not working
#device.set_io_configuration(0b111) # This is getting ignored?
#device.set_io_outputs(0b000)
#device.all_io_states = 0b000
#print(f"digital ios: {device.all_io_states:03b}")

#device.D0 = 0
#print(f"D0: {device.D0}")
#device.D0 = 1
#print(f"D0: {device.D0}")
#
#device.D1 = 0
#print(f"D1: {device.D1}")
#device.D1 = 1
#print(f"D1: {device.D1}")
#
#print(f"DI2: {device.DI2}")


#import time
#while True:
# print(f"PORT0 IN State: {device.port0_i0}")
# print(f"PORT0 IO State: {device.port0_io0}")
# print(f"PORT0 OUT State: {device.port0_o0}")
# print(f"all port io states: {device.all_port_io_states}")
# print(f"all port output states: {device.all_port_output_states}")
# print()
# time.sleep(0.1)
11 changes: 9 additions & 2 deletions examples/check_device_id.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#!/usr/bin/env python3
from pyharp.device import Device
from pyharp.messages import HarpMessage
from pyharp.messages import MessageType
from pyharp.device_names import device_names
from struct import *
import os


# ON THIS EXAMPLE
Expand All @@ -11,15 +14,19 @@


# Open the device
device = Device("COM95") # Open serial connection
# Open serial connection
if os.name == "posix": # check for Linux.
device = Device("/dev/harp_device_00")
else: # assume Windows.
device = Device("COM95")

# Get some of the device's parameters
device_id = device.WHO_AM_I # Get device's ID
device_id_description = device.WHO_AM_I_DEVICE # Get device's user name
device_user_name = device.DEVICE_NAME # Get device's user name

# Check if we are dealing with the correct device
if device_id == 2080:
if device_id in device_names:
print("Correct device was found!")
print(f"Device's ID: {device_id}")
print(f"Device's name: {device_id_description}")
Expand Down
18 changes: 15 additions & 3 deletions examples/get_info.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from pyharp.device import Device
#!/usr/bin/env python3
from pyharp.device import Device, DeviceMode
from pyharp.messages import HarpMessage
from pyharp.messages import MessageType
from struct import *
import os


# ON THIS EXAMPLE
Expand All @@ -11,7 +13,13 @@


# Open the device and print the info on screen
device = Device("COM95", "ibl.bin") # Open serial connection and save communication to a file
# Open serial connection and save communication to a file
if os.name == 'posix': # check for Linux.
#device = Device("/dev/harp_device_00", "ibl.bin")
#device = Device("/dev/ttyACM0")
device = Device("/dev/ttyUSB0")
else: # assume Windows.
device = Device("COM95", "ibl.bin")
device.info() # Display device's info on screen

# Get some of the device's parameters
Expand All @@ -28,5 +36,9 @@
device_harp_l = device.HARP_VERSION_L # Get device's harp core version
device_assembly = device.ASSEMBLY_VERSION # Get device's assembly version

reg_dump = device.dump_registers()
for i in range(11):
print(reg_dump[i])

# Close connection
device.disconnect()
device.disconnect()
30 changes: 30 additions & 0 deletions examples/wait_for_events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env python3
from pyharp.drivers.behavior import Behavior, Events
from pyharp.messages import HarpMessage
from pyharp.messages import MessageType
from struct import *
import os

from pyharp.device import Device, DeviceMode


# Open the device and print the info on screen
# Open serial connection and save communication to a file
device = None
if os.name == 'posix': # check for Linux.
#device = Behavior("/dev/harp_device_00", "ibl.bin")
#device = Device("/dev/ttyACM0",)
device = Device("/dev/ttyUSB0",)
else: # assume Windows.
device = Behavior("COM95", "ibl.bin")

print("Setting mode to active.")
# Mode will remain active for up to 3 seconds after CTS pin is brought low.
device.set_mode(DeviceMode.Active)
#device.disable_all_events()
#device.enable_events(Events.port_digital_inputs)
while True:
event_response = device._read() # read any incoming events.
if event_response is not None:# and event_response.address != 44:
print()
print(event_response)
64 changes: 45 additions & 19 deletions examples/write_and_read_from_registers.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#!/usr/bin/env python3
from pyharp.device import Device
from pyharp.messages import HarpMessage
from pyharp.messages import MessageType
from struct import *
import os


# ON THIS EXAMPLE
Expand All @@ -12,26 +14,50 @@


# Open the device and print the info on screen
device = Device("COM95", "ibl.bin") # Open serial connection and save communication to a file
# Open serial connection and save communication to a file
if os.name == 'posix': # check for Linux.
device = Device("/dev/harp_device_00", "ibl.bin")
else: # assume Windows.
device = Device("COM95", "ibl.bin")

# Read current analog sensor's higher threshold (ANA_SENSOR_TH0_HIGH) at address 42
analog_threshold_h = device.send(HarpMessage.ReadU16(42).frame).payload_as_int()
print(f"Analog sensor's higher threshold: {analog_threshold_h}")

# Increase current analog sensor's higher threshold by one unit
device.send(HarpMessage.WriteU16(42, analog_threshold_h+1).frame)

# Check if the register was well written
analog_threshold_h = device.send(HarpMessage.ReadU16(42).frame).payload_as_int()
print(f"Analog sensor's higher threshold: {analog_threshold_h}")

# Read 10 samples of the analog sensor and display the values
# The value is at register STREAM[0], address 33
analog_sensor = []
for x in range(10):
value = device.send(HarpMessage.ReadS16(33).frame).payload_as_int()
analog_sensor.append(value & 0xffff)
print(f"Analog sensor's values: {analog_sensor}")
#analog_threshold_h = device.send(HarpMessage.ReadU16(42).frame).payload_as_int()
#print(f"Analog sensor's higher threshold: {analog_threshold_h}")


import time

print(f"System time: {time.perf_counter():.6f}")
data_stream = device.send(HarpMessage.ReadU8(33).frame) # returns a ReplyHarpMessage
#data_stream = device.send(HarpMessage.ReadS16(33).frame).payload_as_int_array()
print(f"Data Stream payload type: {data_stream.payload_type.name}")
print(f"Data Stream message type: {data_stream.message_type.name}")
print(f"Data Stream timestamp: {data_stream.timestamp}")
print(f"Data Stream num bytes: {data_stream.length}")
print(f"Data Stream payload: {data_stream.payload}")

print(f"System time: {time.perf_counter():.6f}")
event_reg_response = device.send(HarpMessage.ReadU8(77).frame) # returns a ReplyHarpMessage
print(f"EVNT_ENABLE payload type: {event_reg_response.payload_type.name}")
print(f"EVNT_ENABLE message type: {event_reg_response.message_type.name}")
print(f"EVNT_ENABLE timestamp: {event_reg_response.timestamp}")
print(f"EVNT_ENABLE num bytes: {event_reg_response.length}")
print(f"EVNT_ENABLE payload: {event_reg_response.payload[0]:08b}")

## Increase current analog sensor's higher threshold by one unit
#device.send(HarpMessage.WriteU16(42, analog_threshold_h+1).frame)
#
## Check if the register was well written
#analog_threshold_h = device.send(HarpMessage.ReadU16(42).frame).payload_as_int()
#print(f"Analog sensor's higher threshold: {analog_threshold_h}")
#
## Read 10 samples of the analog sensor and display the values
## The value is at register STREAM[0], address 33
#analog_sensor = []
#for x in range(10):
# value = device.send(HarpMessage.ReadS16(33).frame).payload_as_int()
# analog_sensor.append(value & 0xffff)
#print(f"Analog sensor's values: {analog_sensor}")

# Close connection
device.disconnect()
device.disconnect()
Loading