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

Ccs811 fixes #219

Merged
merged 2 commits into from
Nov 14, 2023
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
67 changes: 48 additions & 19 deletions pslab/external/ccs811.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,40 @@ class CCS811(I2CSlave):

# Figure 14: CCS811 Application Register Map
_STATUS = 0x00 # STATUS # R 1 byte Status register
# MEAS_MODE # R/W 1 byte Measurement mode and conditions register Algorithm result. The most significant 2 bytes contain a up to ppm estimate of the equivalent CO2 (eCO2) level, and
# MEAS_MODE # R/W 1 byte Measurement mode and conditions register Algorithm result.
# The most significant 2 bytes contain a up to ppm estimate of the equivalent
# CO2 (eCO2) level, and
_MEAS_MODE = 0x01
_ALG_RESULT_DATA = 0x02 # ALG_RESULT_DATA # R 8 bytes the next two bytes contain a ppb estimate of the total VOC level. Raw ADC data values for resistance and current source
_RAW_DATA = 0x03 # RAW_DATA # R 2 bytes used. Temperature and humidity data can be written to
_ENV_DATA = 0x05 # ENV_DATA # W 4 bytes enable compensation Thresholds for operation when interrupts are only
_THRESHOLDS = 0x10 # THRESHOLDS # W 4 bytes generated when eCO2 ppm crosses a threshold The encoded current baseline value can be read. A
# ALG_RESULT_DATA # R 8 bytes the next two bytes contain appb estimate of the total
# VOC level. Raw ADC data values for resistance and current source.
_ALG_RESULT_DATA = 0x02
# RAW_DATA # R 2 bytes used. Temperature and humidity data can be written to
_RAW_DATA = 0x03
# ENV_DATA # W 4 bytes enable compensation Thresholds for operation when interrupts
# are only
_ENV_DATA = 0x05
# THRESHOLDS # W 4 bytes generated when eCO2 ppm crosses a threshold The encoded
# current baseline value can be read. A
_THRESHOLDS = 0x10
# BASELINE # R/W 2 bytes previously saved encoded baseline can be written.
_BASELINE = 0x11
_HW_ID = 0x20 # HW_ID # R 1 byte Hardware ID. The value is 0x81
_HW = 0x21 # HW Version # R 1 byte Hardware Version. The value is 0x1X Firmware Boot Version. The first 2 bytes contain the
_FW_BOOT_VERSION = 0x23 # FW_Boot_Version # R 2 bytes firmware version number for the boot code. Firmware Application Version. The first 2 bytes contain
# HW Version # R 1 byte Hardware Version. The value is 0x1X FirmwareBoot Version.
# The first 2 bytes contain the
_HW = 0x21
# FW_Boot_Version # R 2 bytes firmware version number for the boot code. Firmware
# Application Version. The first 2 bytes contain
_FW_BOOT_VERSION = 0x23
# FW_App_Version # R 2 bytes the firmware version number for the application code
_FW_APP_VERSION = 0x24
# Internal_State # R 1 byte Internal Status register Error ID. When the status register reports an error its
# Internal_State # R 1 byte Internal Status register Error ID. When the status
# register reports an error its
_INTERNAL_STATE = 0xA0
# ERROR_ID # R 1 byte source is located in this register If the correct 4 bytes ( 0x11 0xE5 0x72 0x8A) are written
# ERROR_ID # R 1 byte source is located in this register If the correct 4 bytes
# ( 0x11 0xE5 0x72 0x8A) are written
_ERROR_ID = 0xE0
# SW_RESET # W 4 bytes to this register in a single sequence the device will reset and return to BOOT mode.
# SW_RESET # W 4 bytes to this register in a single sequence the device will reset
# and return to BOOT mode.
_SW_RESET = 0xFF

# Figure 25: CCS811 Bootloader Register Map
Expand Down Expand Up @@ -69,11 +85,11 @@ def fetchID(self):
}

def app_erase(self):
ignore = self.write([0xE7, 0xA7, 0xE6, 0x09], self._APP_ERASE)
self.write([0xE7, 0xA7, 0xE6, 0x09], self._APP_ERASE)
time.sleep(0.3)

def app_start(self):
ignore = self.write([], self._APP_START)
self.write([], self._APP_START)

def set_measure_mode(self, mode):
self.write([mode << 4], self._MEAS_MODE)
Expand Down Expand Up @@ -104,14 +120,27 @@ def decode_status(self, status):
return s

def decode_error(self, error_id):
s = ""
if (error_id & (1 << 0)) > 0:
s += ", The CCS811 received an I²C write request addressed to this station but with invalid register address ID"
s += (
", The CCS811 received an I²C write request addressed to this station "
"but with invalid register address ID"
)
if (error_id & (1 << 1)) > 0:
s += ", The CCS811 received an I²C read request to a mailbox ID that is invalid"
s += (
", The CCS811 received an I²C read request to a mailbox ID that is "
"invalid"
)
if (error_id & (1 << 2)) > 0:
s += ", The CCS811 received an I²C request to write an unsupported mode to MEAS_MODE"
s += (
", The CCS811 received an I²C request to write an unsupported mode to "
"MEAS_MODE"
)
if (error_id & (1 << 3)) > 0:
s += ", The sensor resistance measurement has reached or exceeded the maximum range"
s += (
", The sensor resistance measurement has reached or exceeded the "
"maximum range"
)
if (error_id & (1 << 4)) > 0:
s += ", The Heater current in the CCS811 is not in range"
if (error_id & (1 << 5)) > 0:
Expand All @@ -124,9 +153,9 @@ def measure(self):
eTVOC = data[2] * 256 + data[3]
status = data[4]
error_id = data[5]
raw_data = 256 * data[6] + data[7]
raw_current = raw_data >> 10
raw_voltage = (raw_data & ((1 << 10) - 1)) * (1.65 / 1023)
# raw_data = 256 * data[6] + data[7]
# raw_current = raw_data >> 10
# raw_voltage = (raw_data & ((1 << 10) - 1)) * (1.65 / 1023)

result = {"eCO2": eCO2, "eTVOC": eTVOC, "status": status, "error_id": error_id}

Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ commands = coverage run --source pslab -m pytest --record
[testenv:lint]
deps = -rlint-requirements.txt
setenv =
INCLUDE_PSL_FILES = pslab/bus/ pslab/instrument/ pslab/serial_handler.py pslab/cli.py pslab/external/motor.py pslab/external/gas_sensor.py pslab/external/hcsr04.py pslab/external/ccs811.py
INCLUDE_PSL_FILES = pslab/bus/ pslab/instrument/ pslab/serial_handler.py pslab/cli.py pslab/external/motor.py pslab/external/gas_sensor.py pslab/external/hcsr04.py
commands =
black --check {env:INCLUDE_PSL_FILES}
flake8 --show-source {env:INCLUDE_PSL_FILES}
Expand Down
Loading