Ozone 2 click

Hi,

I have a weeny problem with this sensor:

It communicates though SPI and I am quite confused about it. I tried to write some basic code, but it surprisingly did not work, never mind… The main problem is that I have no experiences with SPI communication and I can not find my mistakes.

Would you be willing to help me with it?

ozone.ino (368 Bytes)

How is the sensor wired to the Arduino ?
MISO, MOSI and CLK, for instance ?

Please provide a link to the sensor

For the benefit of others here is the OPs code
OP please note

#include <Arduino.h>
#include <SPI.h>


// set pin 10 as the slave select for the digital pot:
const int slaveSelectPin = 10;
int val = 0;


void setup()
{
  // set the slaveSelectPin as an output:
  pinMode(slaveSelectPin, OUTPUT);
  // initialize SPI:
  SPI.begin();
}

void loop()
{
  val = SpiRead();
  Serial.println(val);
  delay(1000);
}

I have already mentioned link to the sensor...

Is there some command for getting data or some different way?

Let’s start with the basics

How is the sensor wired to your Arduino ?

How have you got the jumpers set on the sensor board ?

Have you tried a search for Ozone 2 or MQ131 in this forum ?

@Iridium1944, the URL you provided has a link to the datasheet for the analog-to-digital converter used on the board. I'd start by reading that, assuming that's it's properly connected to your processor board.

Try:

#include <SPI.h>

#define FULL_SCALE_22BIT    4194303.0

const byte pinSS = 8; //cs pin
const byte pinRDY = 12;

float
    fVolts;
    
union 
{
    long            lVal;
    unsigned char   grucB[sizeof(long)];
    
} uPack;

void setup( void ) 
{
    Serial.begin(9600);
    InitSPI();
       
}//setup

void InitSPI( void )
{
    pinMode( pinRDY, INPUT );       //RDY/SDO
    pinMode( pinSS, OUTPUT );       //slave select
    digitalWrite( pinSS, HIGH );    //ensure SS idles high

    //start the SPI
    SPI.begin();
    SPI.setBitOrder( MSBFIRST );
    SPI.setDataMode( SPI_MODE3 );
    SPI.setClockDivider( SPI_CLOCK_DIV16 );
    
}//InitSPI

void ReadSensor( void )
{
    //set SS low
    digitalWrite( pinSS, LOW );
    
    //wait for conversion complete from RDY pin (it goes low)
    //could add a timeout here if desired
    while( digitalRead( pinRDY ) );

    //
    for( byte i=0; i<3; i++ )
        uPack.grucB[2-i] = SPI.transfer(0x00);

    //long is 4 bytes; data fits in three, fourth is space filler for long in union
    uPack.grucB[3] = 0;

    digitalWrite( pinSS, HIGH );

    //22221111 111111
    //32109876 54321098 76543210
    //xysddddd dddddddd dddddddd
    //
    //x = overflow H
    //y = underflow L
    //s = sign
    //
    //According to device datasheet, the MCP3551 output is VSENS = DATA x VREF / FS
    // where Vref = 5V
    //  and     FS = 22 bits (23 and 24 should play no role)
    //
    fVolts = (float)uPack.lVal * 5.0 / FULL_SCALE_22BIT;
    
}//ReadSensor

void loop(void) 
{
    unsigned long
        tNow;
    static unsigned long
        timeReadSensor=0;

    tNow = millis();
    //read the sensor every 1/2-second
    if( millis() - timeReadSensor >= 500ul )
    {
        timeReadSensor = tNow;
        
        ReadSensor();
        Serial.println( fVolts, 5 );

        //do stuff with sensor reading...
            
    }//if

}//loop

Blackfin:
Try:

#include <SPI.h>

#define FULL_SCALE_22BIT    4194303.0

const byte pinSS = 8; //cs pin
const byte pinRDY = 12;

float
    fVolts;
   
union
{
    long            lVal;
    unsigned char  grucB[sizeof(long)];

Please tell me, what is pinRDY?
   
} uPack;

void setup( void )
{
    Serial.begin(9600);
    InitSPI();
     
}//setup

void InitSPI( void )
{
    pinMode( pinRDY, INPUT );      //RDY/SDO
    pinMode( pinSS, OUTPUT );      //slave select
    digitalWrite( pinSS, HIGH );    //ensure SS idles high

//start the SPI
    SPI.begin();
    SPI.setBitOrder( MSBFIRST );
    SPI.setDataMode( SPI_MODE3 );
    SPI.setClockDivider( SPI_CLOCK_DIV16 );
   
}//InitSPI

void ReadSensor( void )
{
    //set SS low
    digitalWrite( pinSS, LOW );
   
    //wait for conversion complete from RDY pin (it goes low)
    //could add a timeout here if desired
    while( digitalRead( pinRDY ) );

//
    for( byte i=0; i<3; i++ )
        uPack.grucB[2-i] = SPI.transfer(0x00);

//long is 4 bytes; data fits in three, fourth is space filler for long in union
    uPack.grucB[3] = 0;

digitalWrite( pinSS, HIGH );

//22221111 111111
    //32109876 54321098 76543210
    //xysddddd dddddddd dddddddd
    //
    //x = overflow H
    //y = underflow L
    //s = sign
    //
    //According to device datasheet, the MCP3551 output is VSENS = DATA x VREF / FS
    // where Vref = 5V
    //  and    FS = 22 bits (23 and 24 should play no role)
    //
    fVolts = (float)uPack.lVal * 5.0 / FULL_SCALE_22BIT;
   
}//ReadSensor

void loop(void)
{
    unsigned long
        tNow;
    static unsigned long
        timeReadSensor=0;

tNow = millis();
    //read the sensor every 1/2-second
    if( millis() - timeReadSensor >= 500ul )
    {
        timeReadSensor = tNow;
       
        ReadSensor();
        Serial.println( fVolts, 5 );

//do stuff with sensor reading…
           
    }//if

}//loop

whoops
Please tell me, what is pinRDY?
By the way it has only one problem:

"'InitSPI' was not declared in this scope",

Hi Iridium.

Please can you let me know how to connect the ozone_2_click to an ARDUINO MEGA and if possible an example code.

Thank you in advance.

I have to connect 2 click2 board of Ozone sensor and log it to a MicroSD Card all by Arduino,Please help for interfacing as all are on SPI and i am facing problem with above code as the board doesnt have MOSI pin

Hi Blackfin,
Thank you so much for providing this code! It’s awesome, and on my end it compiles. However, when I upload it to my Arduino MEGA, it does not display the ozone sensor readings in the serial monitor. The serial monitor does not come up at all. Could I ask what should be changed here?
I have wired the SDO pin to Pin 12 and the CS pin to Pin 8, as per your directions.

Try this instead.

For a Mega2560, note the different pin connections.

#include <SPI.h>

#define FULL_SCALE_22BIT    4194303.0

const uint8_t 
    pinSS = 53,       //SS slave select pin     connect to CS pin of O3_2click
    pinMISO = 50,     //master in, slave out    connect to SDO pin of O3_2click
    pinSCK = 52;      //serial clock            connect to SCK pin of O3_2click
float
    fVolts;
    
union 
{
    long            lVal;
    unsigned char   grucB[sizeof(long)];
    
} uPack;

void setup( void ) 
{
    Serial.begin(115200);
    InitSPI();
       
}//setup

void InitSPI( void )
{
    pinMode( pinMISO, INPUT_PULLUP );
    pinMode( pinSCK, OUTPUT );
    pinMode( pinSS, OUTPUT );       //slave select
    digitalWrite( pinSS, HIGH );    //ensure SS idles high

    //start the SPI
    SPI.begin();
    SPI.setBitOrder( MSBFIRST );
    SPI.setDataMode( SPI_MODE3 );
    SPI.setClockDivider( SPI_CLOCK_DIV16 );
    
}//InitSPI

void ReadSensor( void )
{
    //set SS low
    digitalWrite( pinSS, LOW );
    
    //wait for conversion complete from nRDY pin (goes low when data is ready)
    //could add a timeout here if desired
    while( digitalRead( pinMISO ) );

    //read 3 bytes from the sensor (24 bit total)
    for( uint8_t i=0; i<3; i++ )
        uPack.grucB[2-i] = SPI.transfer(0x00);

    //long is 4 bytes; data fits in three; fourth is space filler for long in union
    uPack.grucB[3] = 0;

    digitalWrite( pinSS, HIGH );

    //22221111 111111
    //32109876 54321098 76543210
    //xysddddd dddddddd dddddddd
    //
    //x = overflow H
    //y = underflow L
    //s = sign

    //check for overflow or underflow
    if( (uPack.grucB[2] & (1<<6) ) | (uPack.grucB[2] & (1<<7) ) )
    {
        uPack.grucB[2] &= ~(1<<6);        
        
    }//if
    else if( uPack.grucB[2] & (1<<5) )
    {
        //check for sign bit; if so, subtract from 2^n        
        //22221111 111111
        //32109876 54321098 76543210
        //xysddddd dddddddd dddddddd
        uPack.lVal = 0x400000 - uPack.lVal;        
        
    }//else    
    
    //
    //According to device datasheet, the MCP3551 output is VSENS = DATA x VREF / FS
    // where Vref = 5V
    //  and     FS = 22 bits (23 and 24 should play no role)
    //
    fVolts = (float)uPack.lVal * 5.0 / FULL_SCALE_22BIT;
    
}//ReadSensor

void loop(void) 
{
    unsigned long
        tNow;
    static unsigned long
        timeReadSensor=0;

    tNow = millis();
    //read the sensor every 1/2-second
    if( millis() - timeReadSensor >= 500ul )
    {
        timeReadSensor = tNow;
        
        ReadSensor();
        Serial.println( fVolts, 5 );

        //do stuff with sensor reading...
            
    }//if

}//loop

My dude, you rock.
Thanks a ton!

I want to check in to see if anyone has used the analog pin on the Ozone 2-Click sensor to take readings. I've been trying to but I am having trouble understanding what value it is spitting out, i.e. whether it is the sensor-resistance to load-resistor ratio on the sensor datasheet for the MQ-131 sensor or the voltage in the equation on the 2-Click datasheet, i.e. VSENS = DATA x VREF / FS. I'm getting values of around 400, no matter how I turn the potentiometer, but I will see if it changes after I let it preheat for 48 hours and I will post an update here. Using the SPI pins is working fine, but I need those pins on my Arduino MEGA to record the data on a microSD card.

I just bought NO2 sensor from the same company and was wondering if you could help me with the code with arduino.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.