Skip to content

Commit

Permalink
Add JosenePM example.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpmeijers committed Jun 1, 2017
1 parent aa01fb7 commit 77955fa
Show file tree
Hide file tree
Showing 6 changed files with 423 additions and 0 deletions.
96 changes: 96 additions & 0 deletions Examples/JosenePM/IntemoPM.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/************************************************************************************
* JosenePM.cpp - Library for JosenePM PM sensor *
* Copyright (c) 2014-2016 Antoine van de Cruyssen. All rights reserved *
* Edited for KISS LoRa compatibility by Rene Schalks. *
*************************************************************************************
* Rev 1.0 - September 2016 *
* - Initial release *
*************************************************************************************
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
************************************************************************************/

#include "IntemoPM.h"

// Constructor
JosenePM::JosenePM()
{
this->pm = new uint16_t[2];
}

//Initialize communication with the UART.
//Params:
//uint8_t UARTI2CAddress; The I2C address of the UART. This *SHOULD* be 0x4E. If not, check the datasheet for the proper address. It should be specified there.
//uint8_t UARTChannel; The channel the UART device sends data to.
void JosenePM::begin(uint8_t UARTI2CAddress, uint8_t UARTChannel)
{
SC16IS752::begin(UARTI2CAddress,false);
SC16IS752::setup(PM,BAUD_9600,UART_8N1);

SC16IS752::setGPIODir(0xFF);
//SC16IS752::writeGPIO(0x10);
}

//Turns on the PM sensor.
void JosenePM::powerOn() {
SC16IS752::writeGPIO(SC16IS752::readGPIO() | 0x10);
}

//Turns off the PM sensor.
void JosenePM::powerOff() {
SC16IS752::writeGPIO(SC16IS752::readGPIO() & 0xEF);
}

//Retrieves the PM values from the sensor.
//Params:
//boolean dbg; Determines if the function should print the values to the Serial port. Can be ommitted, and is false by default.
//Returns:
//uint16_t[2]; an array of the retrieved PM values. The first index of this array contains the PM10 value, the second index contains the PM2.5 value.
uint16_t * JosenePM::getData(boolean dbg)
{
uint8_t rx[63]={ };
uint8_t x = SC16IS752::readUART_Array(PM,rx);
if(dbg==true)
{
for(uint8_t y = 0; y<x; y++) {
Serial.print (rx[y],HEX);
Serial.print (",");
}
}
if(x>=10 && rx[0]==0xAA && rx[1]==0xC0 && rx[9]==0xAB)
{
this->pm[0]=((uint16_t)rx[5] << 8) | rx[4];
this->pm[1]=((uint16_t)rx[3] << 8) | rx[2];
//pm[1];
if(dbg==true) {
Serial.print("PM10:"); Serial.print(this->pm[0]); Serial.print(" ");
Serial.print("PM2.5:"); Serial.print(this->pm[1]); Serial.print(" ");
Serial.println("");
}
}
else
{
if(dbg==true) Serial.println(" ?");
}
return this->pm;
}

//Checks how much data is currently in the RX buffer.
//Returns:
//uint8_t; the amount of bytes currently in the RX buffer.
uint8_t JosenePM::checkRxLevel(uint8_t channel)
{
return SC16IS752::checkRxLevel(channel);
}

57 changes: 57 additions & 0 deletions Examples/JosenePM/IntemoPM.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/************************************************************************************
* JosenePM.h - Header for JosenePM PM sensor *
* Copyright (c) 2014-2016 Antoine van de Cruyssen. All rights reserved *
* Edited for KISS LoRa compatibility by Rene Schalks. *
*************************************************************************************
* Rev 1.0 - September 2016 *
* - Initial release *
*************************************************************************************
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
************************************************************************************/
#ifndef JosenePM_h
#define JosenePM_h
#include <Arduino.h>
#include "SC16IS752.h"

class JosenePM : public SC16IS752
{
private:
//An array of the latest retrieved PM values.
uint16_t *pm;
public:
JosenePM();
//Initializes communication with the UART.
//Params:
//uint8_t UARTI2CAddress; The I2C address of the UART. This *SHOULD* be 0x4E. If not, check the datasheet for the proper address. It should be specified there.
//uint8_t UARTChannel; The channel the UART device sends data to.
void begin(uint8_t UARTI2CAddress, uint8_t UARTChannel);
//Retrieves the PM values from the sensor.
//Params:
//boolean dbg; Determines if the function should print the values to the Serial port. Can be ommitted, and is false by default.
//Returns:
//uint16_t[2]; an array of the retrieved PM values. The first index of this array contains the PM10 value, the second index contains the PM2.5 value.
uint16_t * getData(boolean dbg=false);
//Checks how much data is currently in the RX buffer.
//Returns:
//uint8_t; the amount of bytes currently in the RX buffer.
uint8_t checkRxLevel(uint8_t channel);
//Turns on the PM sensor.
void powerOn();
//Turns off the PM sensor.
void powerOff();
};

#endif

22 changes: 22 additions & 0 deletions Examples/JosenePM/JosenePM.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <IntemoPM.H>

#define joseneAddress 0x4E

JosenePM JosenePM;

void setup()
{
Serial.begin(9600);

JosenePM.begin(joseneAddress, 1);
JosenePM.powerOn();
}
void loop()
{
uint16_t *data = JosenePM.getData(false);
Serial.print("Josene PM Data:\nPM10: ");
Serial.println(data[0]);
Serial.print("PM2.5: ");
Serial.println(data[1]);
delay(2000);
}
46 changes: 46 additions & 0 deletions Examples/JosenePM/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Introduction

At the E&A fair, in the boiler room, a few JosenePM sensors are available for experimentation. This example shows how to read the air quality form these devices, using your KISS LoRa gadget.


## Library usage
Copy both folders in /Libraries to (USER FOLDER)\Arduino\Libraries.
First, we need to enable the PM sensor class, then enable the physical PM sensor.
```
#include <IntemoPM.H>
#define joseneAddress 0x4E
JosenePM JosenePM;
void setup()
{
Serial.begin(9600);
JosenePM.begin(joseneAddress, 1);
}
```
JosenePM.begin(uint8_t address, uint8_t channel) sends an initialization command to the sensor, setting it up to allow data transferring.
Then, we need to turn on the PM sensor.
```
...
JosenePM.begin(joseneAddress, 1);
JosenePM.powerOn();
}
```
JosenePM.powerOn() turns on the sensor, allowing the device to register the amount of particles in its chamber, which is stored in an internal buffer. To retrieve the data, we use the following method:
```
...
void loop()
{
uint16_t *data = JosenePM.getData(false);
Serial.print("Josene PM Data:\nPM10: ");
Serial.println(data[0]);
Serial.print("PM2.5: ");
Serial.println(data[1]);
delay(2000);
}
```
JosenePM.getData(boolean debug) reads the data from the device, and stores it in an array with a length of two unsigned, sixteen bit integers. The first element in the array is the PM10 value, the second element in the array is the PM2.5 value.

**It is important to make sure a delay exists after reading, with at least 1.8 seconds. Otherwise, you will receive random values.**
114 changes: 114 additions & 0 deletions Examples/JosenePM/SC16IS752.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/************************************************************************************
* SC16IS752.cpp - Library for SC16IS752 dual uart *
* Copyright (c) 2014-2016 Antoine van de Cruyssen. All rights reserved *
* Edited by Rene Schalks to be compatible with KISS LoRa. *
*************************************************************************************
* Rev 1.0 - September 2016 *
* - Initial release *
*************************************************************************************
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
************************************************************************************/

#include "SC16IS752.h"
//i2c_device Test;

// Constructor
SC16IS752::SC16IS752()
{

}

void SC16IS752::begin(uint8_t Address, boolean TWI_Begin)
{
this->Address = Address;
if (TWI_Begin)
{
I2c.begin();
}
//i2c_device::begin(Address, TWI_Begin);
}

/****************
* Channel Setup *
****************/
void SC16IS752::setup(uint8_t Channel, uint8_t BaudrateDevisor, uint8_t LineControl)
{
SC16IS752::writeUART(LCR, Channel, 0x80); // 0x80 to program baud rate divisor
SC16IS752::writeUART(DLL, Channel, BaudrateDevisor); // 12=9600 baud
SC16IS752::writeUART(DLH, Channel, 0x00);
SC16IS752::writeUART(LCR, Channel, 0xBF); // access EFR register
SC16IS752::writeUART(EFR, Channel, 0x10); // enable enhanced registers
SC16IS752::writeUART(LCR, Channel, LineControl); // 8 data bits, 1 stop bit, no parity
SC16IS752::writeUART(FCR, Channel, 0x07); // reset TXFIFO, reset RXFIFO, enable FIFO mode
}

/*********************
* Write data to UART *
*********************/
void SC16IS752::writeUART(uint8_t RegAddr, uint8_t Channel, uint8_t Data)
{
I2c.write(this->Address, ((RegAddr << 3) | (Channel << 1)), Data);
}

/***********************
* Read array from UART *
***********************/
uint8_t SC16IS752::readUART_Array(uint8_t Channel, uint8_t *Data)
{
uint8_t num = SC16IS752::checkRxLevel(Channel);
I2c.read(this->Address, ((RHR << 3) | (Channel << 1)), num, Data);
//i2c_device::read_many(((RHR << 3) | (Channel << 1)), num, Data);
return num;
}

/******************************
* Get number of bytes in FIFO *
******************************/
uint8_t SC16IS752::checkRxLevel(uint8_t Channel)
{
byte result;
I2c.read(this->Address, ((RXLVL << 3) | (Channel << 1)) & 0x7F, 1, &result);
return result;
//return i2c_device::read(((RXLVL << 3) | (Channel << 1)) & 0x7F);
}

/************************************
* Set GPIO directions *
* GPIO0 to GPIO7, 0=input, 1=Output *
************************************/
void SC16IS752::setGPIODir(uint8_t Bits) {
I2c.write(this->Address, (IOControl << 3), 0x00);
I2c.write(this->Address, (IODir << 3), Bits);
}

/*******************
* Read GPIO inputs *
* GPIO0 to GPIO7 *
*******************/
uint8_t SC16IS752::readGPIO() {
//return readI2c(IOState << 3);
byte result;
I2c.read(this->Address, IOState << 3, 1, &result);
return result;
}

/*********************
* Write GPIO outputs *
* GPIO0 to GPIO7 *
*********************/
void SC16IS752::writeGPIO(uint8_t Data) {
I2c.write(this->Address, (IOState << 3), Data);
}

Loading

0 comments on commit 77955fa

Please sign in to comment.