Hello, looking for a way to read the measured values off the ozone sensor board using Pi 3 click shield and the ozone 2 click board on a raspberry pi 3.
Do you have e.g. python code or C headers/libraries for configuring and communication using SPI?
Thank you
ozone 2 click
- filip.grujcic
- Posts: 822
- Joined: 14 May 2018 08:34
Re: ozone 2 click
Hello,
We do not officially provide examples or libraries for Raspberry Pi, as it is not a Mikroe product.
If you would like us to provide you with a source code of our library for Ozone 2 Click board which you could try porting over to RPi, please submit a ticket on our helpdesk: https://www.mikroe.com/support
Kind regards,
We do not officially provide examples or libraries for Raspberry Pi, as it is not a Mikroe product.
If you would like us to provide you with a source code of our library for Ozone 2 Click board which you could try porting over to RPi, please submit a ticket on our helpdesk: https://www.mikroe.com/support
Kind regards,
Filip Grujcic
Re: ozone 2 click
For those who might be looking for some starting point - reading of the mcp3551:
Reading ADC mcp3204/3208 on MikroE Pi 3 Shield: see https://pypi.org/project/mcp3208/
Reading O3 sensor and calculating Rs:
Sample output:
Remaining questions I have not figured out yet: how to actually correlate the readings with actual O3 ppm without having a reference of 50ppm of CL2 (as per the MQ131 doc).
Code: Select all
$ cat mcp3551.py
#!/usr/bin/python3
#
import spidev
import time
class MCP3551:
def __init__(self, spi_channel=0, spi_ce=0, speed_hz=1000000, spi_mode=0b00):
self.conn = spidev.SpiDev()
self.conn.open(spi_channel, spi_ce)
self.max_speed_hz = speed_hz
self.conn.max_speed_hz = speed_hz
self.spi_mode = spi_mode
self.conn.mode = spi_mode
def __del__( self ):
self.close
def close(self):
if self.conn != None:
self.conn.close
self.conn = None
def read(self, adc_channel=0):
count_safeguard = 0
COUNT_SAFEGUARD_LIMIT = 10000
while True:
count_safeguard = count_safeguard + 1
if (count_safeguard > COUNT_SAFEGUARD_LIMIT):
return -1
res = 0
if self.spi_mode == 0b00:
# In SPI mode 0,0, data is read using 25 clocks or four
#byte transfers. Please note that the data ready bit is
#included in the transfer as the first bit in this mode.
reply_bytes = self.conn.readbytes(4)
#print(reply_bytes)
# see http://ww1.microchip.com/downloads/en/DeviceDoc/20001950F.pdf, Figure 5-7
if (reply_bytes[0] < 0b1000000): # Ready bit present - good read
res = (reply_bytes[0] << 17) + (reply_bytes[1] << 9) + (reply_bytes[2] << 1) + (reply_bytes[3] >> 7)
return res
else: #self.spi_mode == 0b11
# See Figure 5-6
#
reply_bytes = self.conn.readbytes(3)
#print(reply_bytes)
if (reply_bytes[0] < 0b11000000):
# good read
res = (reply_bytes[0] << 16) + (reply_bytes[1] << 8) + (reply_bytes[2] << 0)
return res
if __name__ == '__main__':
spi = MCP3551(0, 0)
a0 = spi.read()
print("%04d" % a0)
Reading O3 sensor and calculating Rs:
Code: Select all
$ cat O3Sens.py
#!/usr/bin/python3
# Reading sensor data
# MikroE Ozone 2 sensor with MQ131 gas sensor
# and MCP3551 22-bit ADC
#
import mcp3551
import mcp3208
import time
SAMPLE_PERIOD=10 # seconds
# On the MikroE O3 sensor, Vin- is GND and delta measured is always positive,
# 0..Vdd
maxADCValue = 0x1FFFFF # MCP3551 doc, figure 5-1
# Initialize mcp3551 spi communication
SPI = 0 # MikroE click boards are on SPI0
SPI_CS = 0 # Pi 3 Shield from MikroE, slot 1
# SPI_CS = 1 # Pi 3 Shield from MikroE, slot 2
sensor = mcp3551.MCP3551(SPI, SPI_CS)
# microchip Pi 3 shield on board adc
# 100000 hz is sufficient
PI3SHIELD_ADC_SPI_CH = 1
PI3SHIELD_ADC_CE = 2
PI3SHIELD_ADC_CLK_HZ = 100000 # 100 kHz
pi3shieldadc = mcp3208.MCP3208(PI3SHIELD_ADC_SPI_CH, PI3SHIELD_ADC_CE, PI3SHIELD_ADC_CLK_HZ)
Vcc = 5 # 5V nominal
# Actual Vref can be measured on the board between Gnd and +5V
# Alternatively, another ADC can be used to read real-time like in the example
# below
# Rl - MikroE O3 sensor has a potentiometer. Rl has to be
# adjusted and measured using an ohm meter, then entered here.
# Rl on the board comprises VR1 and R2, measurement needs to
# be performed from MQ131 B to GND
Rl = 5100 # Ohms
def SampleVcc():
count = 0
sample_size = 10
v_1_2 = 0 # half of the measurement
# range of the onboard ADC can't go over 4.096V so use two divider resistors
# and AN2 of the slot 2 of the MikroE Pi 3 Shield (empty slot)
while True:
count += 1
#AN1_adc_chan = 0
AN2_adc_chan = 1
v_1_2 += pi3shieldadc.read(AN2_adc_chan)
if count == sample_size:
count = 0
return 2 * v_1_2 / sample_size / 1000.0
Rs_running_avg = 0
n_iters = 0
sample_start_time = time.time()
while True:
if n_iters == 0:
sample_start_time = time.time()
print("Sampling for {} seconds...".format(SAMPLE_PERIOD))
value = sensor.read()
if value < 0:
print("Error reading ADC")
continue
Vref = SampleVcc()
Vrl = (Vref * value) / maxADCValue
#print("Raw ADC reading: {}".format(value))
Rs = (Vref / Vrl - 1) * Rl # Rs - sensor resistance
n_iters = n_iters + 1
Rs_running_avg = (Rs_running_avg * (n_iters - 1) + Rs) / n_iters
if int(time.time() - sample_start_time) >= SAMPLE_PERIOD:
Rs = Rs_running_avg
Rs_running_avg = 0
n_iters = 0
print("Sensor reading: Vrl={:.4f}[V] Rs={:.4f}[Ohm] Vref={:.4f}[V] R_L={}[Ohm]".format(Vrl, Rs, Vref, Rl))
Sample output:
Code: Select all
$ ./O3Sens.py
Sampling for 10 seconds...
Sensor reading: Vrl=4.4436[V] Rs=392.7957[Ohm] Vref=4.7836[V] R_L=5100[Ohm]
Sampling for 10 seconds...
Sensor reading: Vrl=4.4385[V] Rs=388.7485[Ohm] Vref=4.7758[V] R_L=5100[Ohm]
Remaining questions I have not figured out yet: how to actually correlate the readings with actual O3 ppm without having a reference of 50ppm of CL2 (as per the MQ131 doc).