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: Arduino environment/analog readout hardware layer #211

Merged
merged 8 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
22 changes: 11 additions & 11 deletions .github/workflows/regression-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.8]
python-version: [3.11]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{matrix.python-version}}
Expand All @@ -31,32 +31,32 @@ jobs:
tests:

name: Python ${{matrix.python-version}} | ${{matrix.sim}}
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
env:
SIM: ${{matrix.sim}}

strategy:
fail-fast: false
matrix:
include:

- sim: icarus
python-version: 3.7
python-version: '3.11'

- sim: icarus
python-version: 3.8
python-version: '3.10'

- sim: verilator
sim-version: v4.106
python-version: 3.8
sim-version: v5.020
python-version: '3.10'
pytest-marker: "-m verilator"

steps:
- uses: actions/checkout@v1
- uses: conda-incubator/setup-miniconda@v2
- name: Set up Anaconda ${{matrix.python-version}}
uses: conda-incubator/setup-miniconda@v2
with:
auto-update-conda: true
python-version: ${{ matrix.python-version }}
python-version: ${{matrix.python-version}}

- name: Install Conda dependencies
shell: bash -l {0}
Expand All @@ -67,12 +67,12 @@ jobs:
- name: Install Python dependencies
shell: bash -l {0}
run: |
pip install pyvisa pyvisa-sim pytest coveralls pytest-cov cocotb==1.5.2
pip install pyvisa pyvisa-sim pytest coveralls pytest-cov cocotb>=1.8.1 cocotb-bus

- name: Install Verilator
if: matrix.sim == 'verilator'
run: |
sudo apt install -y --no-install-recommends make g++ perl python3 autoconf flex bison libfl2 libfl-dev zlibc zlib1g zlib1g-dev
sudo apt install -y --no-install-recommends make g++ help2man perl autoconf flex bison libfl2 libfl-dev zlib1g zlib1g-dev
git clone https://github.com/verilator/verilator.git -b ${{matrix.sim-version}}
cd verilator
autoconf
Expand Down
4 changes: 2 additions & 2 deletions basil/HL/JtagMaster.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def scan_ir(self, data, readback=True):
bit_number = self._test_input(data)
self.SIZE = bit_number

if type(data[0]) == BitLogic:
if isinstance(data[0], BitLogic):
data_byte = self._bitlogic2bytes(data)
else:
data_byte = self._raw_data2bytes(data)
Expand Down Expand Up @@ -135,7 +135,7 @@ def scan_dr(self, data, readback=True, word_size=None):
self.WORD_COUNT = bit_number // word_size
self.SIZE = word_size

if type(data[0]) == BitLogic:
if isinstance(data[0], BitLogic):
data_byte = self._bitlogic2bytes(data)
else:
data_byte = self._raw_data2bytes(data)
Expand Down
116 changes: 116 additions & 0 deletions basil/HL/arduino_env_readout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import logging
from basil.HL.arduino_ntc_readout import NTCReadout

import numpy as np

logger = logging.getLogger(__name__)


class EnvironmentReadout(NTCReadout):
"""Class to read from Arduino temperature or humidity/pressure sensor setup"""

def __init__(self, intf, conf):
self.CMDS.update({
'analog_read': 'A'})

super(EnvironmentReadout, self).__init__(intf, conf)

self.fixed_resistors = self._init.get('resistors')
if not isinstance(self.fixed_resistors, list):
self.fixed_resistors = [float(self.fixed_resistors)] * 8 if self.fixed_resistors is not None else [None] * 8

self.adc_range = float(self._init.get('adc_range', 1023))
self.operating_voltage = float(self._init.get('operating_voltage', 5.0))

self.humidity_pin = int(self._init.get('humidity_pin', -1))
self.pressure_pin = int(self._init.get('pressure_pin', -1))

self.steinharthart_params = dict(self._init.get('steinharthart_params', {
"A": 0.0,
"B": 0.0,
"C": 0.0,
"D": 0.0,
"R25": 0.0,
}))

self.humidity_params = dict(self._init.get('humidity_params', {
"slope": 0.0,
"offset": 0.0,
}))

self.humidity_temp_correction_params = dict(self._init.get('humidity_temp_correction_params', {
"slope": 0.0,
"offset": 0.0,
}))

self.pressure_params = dict(self._init.get('pressure_params', {
"slope": 0.0,
"offset": 0.0,
}))

def setFixedResistance(self, pin, resistance):
cbespin marked this conversation as resolved.
Show resolved Hide resolved
self.fixed_resistors[pin] = resistance

def getResistance(self, sensor, adc_range=None):
analog_read = self.analog_read(sensor)

# Make int sensors to list
sensor = sensor if isinstance(sensor, list) else [sensor]

if adc_range is None:
adc_range = self.adc_range

return {s: self.fixed_resistors[s] / (adc_range / analog_read[s] - 1.0) if abs(adc_range / analog_read[s] - 1) > 0.01 else None for s in sensor}

def getVoltage(self, sensor, adc_range=None):
analog_read = self.analog_read(sensor)

# Make int sensors to list
sensor = sensor if isinstance(sensor, list) else [sensor]

if adc_range is None:
adc_range = self.adc_range

return {s: analog_read[s] * (self.operating_voltage / adc_range) for s in sensor}

def steinhartHart(self, R, A, B, C, D, R25=10e3):
E = np.log(R / R25)

return 1.0 / (A + B * E + C * E**2 + D * E**3) - 273.15

def temperature(self, sensor, adc_range=None):
# Make int sensors to list
sensor = sensor if isinstance(sensor, list) else [sensor]

if adc_range is None:
adc_range = self.adc_range

resistances = self.getResistance(sensor, adc_range)

return {s: self.steinhartHart(resistances[s], **self.steinharthart_params) if resistances[s] is not None else None for s in sensor}

def humidity(self, temperature_correction=None, adc_range=None):
if self.humidity_pin < 0:
logger.warning('No humidity pin specified!')
return

voltage = self.getVoltage(self.humidity_pin, adc_range)[self.humidity_pin]

RH = (voltage - self.humidity_params['offset']) / self.humidity_params['slope']

if temperature_correction is not None:
RH = RH / (self.humidity_temp_correction_params['slope'] * temperature_correction + self.humidity_temp_correction_params['offset'])

return max(float(RH), 0.0)

def pressure(self, adc_range=None):
if self.pressure_pin < 0:
logger.warning('No pressure pin specified!')
return

voltage = self.getVoltage(self.pressure_pin, adc_range)[self.pressure_pin]

return self.pressure_params['slope'] * voltage - self.pressure_params['offset']

def analog_read(self, sensor):
return self._get_measurement(sensor, kind='analog_read')
8 changes: 8 additions & 0 deletions basil/HL/keithley_2400.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ identifier : KEITHLEY INSTRUMENTS INC.,MODEL 2400
on : OUTP ON
off : OUTP OFF
get_on: OUTP?
get_source_current: SOUR:CURR?
get_current : SENSE:FUNC 'CURR';:READ?
set_current : SOUR:CURR
get_source_voltage: SOUR:VOLT?
set_voltage : SOUR:VOLT
get_voltage : SENSE:FUNC 'VOLT';:READ?
set_current_limit : SENS:CURR:PROT
Expand All @@ -23,3 +25,9 @@ get_autorange : SOUR:CURR:RANG:AUTO?
four_wire_on: SYST:RSEN ON
four_wire_off: SYST:RSEN OFF
get_remote_sense: SYST:RSEN ?
# Special keyword for formatting query results to allow direct conversions to numeric types (e.g. float(get_current()))
__scpi_query_fmt:
fmt_sep: ','
fmt_method:
get_voltage: '{0}'
get_current: '{1}'
2 changes: 1 addition & 1 deletion basil/TL/Socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def close(self):
self._sock.close()

def write(self, data):
if type(data) == bytes:
if isinstance(data, bytes):
cmd = data
else:
cmd = data.encode(self.encoding)
Expand Down
Loading
Loading