Skip to content

Commit d59f3f3

Browse files
committed
0.1.0 AGS02MA
1 parent 8909f42 commit d59f3f3

File tree

15 files changed

+820
-0
lines changed

15 files changed

+820
-0
lines changed

libraries/AGS02MA/.arduino-ci.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
compile:
2+
# Choosing to run compilation tests on 2 different Arduino platforms
3+
platforms:
4+
- uno
5+
- leonardo
6+
- due
7+
- zero
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
name: Arduino-lint
3+
4+
on: [push, pull_request]
5+
jobs:
6+
lint:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v2
10+
- uses: arduino/arduino-lint-action@v1
11+
with:
12+
library-manager: update
13+
compliance: strict
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
name: Arduino CI
3+
4+
on: [push, pull_request]
5+
6+
jobs:
7+
arduino_ci:
8+
runs-on: ubuntu-latest
9+
10+
steps:
11+
- uses: actions/checkout@v2
12+
- uses: Arduino-CI/action@master
13+
# Arduino-CI/[email protected]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: JSON check
2+
3+
on:
4+
push:
5+
paths:
6+
- '**.json'
7+
pull_request:
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v2
14+
- name: json-syntax-check
15+
uses: limitusus/json-syntax-check@v1
16+
with:
17+
pattern: "\\.json$"
18+

libraries/AGS02MA/AGS02MA.cpp

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
//
2+
// FILE: AGS02MA.cpp
3+
// AUTHOR: Rob Tillaart
4+
// DATE: 2021-08-12
5+
// VERSION: 0.1.0
6+
// PURPOSE: Arduino library for AGS02MA TVOC
7+
// URL: https://github.com/RobTillaart/AGS02MA
8+
9+
10+
#include "AGS02MA.h"
11+
12+
13+
// REGISTERS
14+
#define AGS02MA_DATA 0x00
15+
#define AGS02MA_CALIBRATION 0x01
16+
#define AGS02MA_VERSION 0x11
17+
#define AGS02MA_SLAVE_ADDRESS 0x21
18+
19+
20+
21+
22+
AGS02MA::AGS02MA(const uint8_t deviceAddress, TwoWire *wire)
23+
{
24+
_address = deviceAddress;
25+
_wire = wire;
26+
_error = AGS02MA_OK;
27+
}
28+
29+
30+
#if defined (ESP8266) || defined(ESP32)
31+
bool AGS02MA::begin(uint8_t dataPin, uint8_t clockPin)
32+
{
33+
_startTime = millis(); // PREHEAT
34+
_wire = &Wire;
35+
if ((dataPin < 255) && (clockPin < 255))
36+
{
37+
_wire->begin(dataPin, clockPin);
38+
} else {
39+
_wire->begin();
40+
}
41+
return isConnected();
42+
}
43+
#endif
44+
45+
46+
bool AGS02MA::begin()
47+
{
48+
_startTime = millis(); // PREHEAT TIMING
49+
_wire->begin();
50+
return isConnected();
51+
}
52+
53+
54+
bool AGS02MA::isConnected()
55+
{
56+
#if defined (__AVR__)
57+
TWBR = 255;
58+
#else
59+
_wire->setClock(AGS02MA_I2C_CLOCK);
60+
#endif
61+
_wire->beginTransmission(_address);
62+
bool rv = ( _wire->endTransmission() == 0);
63+
_wire->setClock(_I2CReseSpeed);
64+
return rv;
65+
}
66+
67+
68+
bool AGS02MA::setAddress(const uint8_t deviceAddress)
69+
{
70+
if (deviceAddress < 10 or deviceAddress > 119) return false;
71+
_buffer[2] = _buffer[0] = deviceAddress;
72+
_buffer[3] = _buffer[1] = 0xFF ^ deviceAddress;
73+
_buffer[4] = _CRC8(_buffer, 4);
74+
if (_writeRegister(AGS02MA_SLAVE_ADDRESS))
75+
{
76+
_address = deviceAddress;
77+
}
78+
return isConnected();
79+
}
80+
81+
82+
uint8_t AGS02MA::getSensorVersion()
83+
{
84+
uint8_t version = 0xFF;
85+
if (_readRegister(AGS02MA_VERSION))
86+
{
87+
version = _buffer[3];
88+
if (_CRC8(_buffer, 5) != 0)
89+
{
90+
_error = AGS02MA_CRC_ERROR;
91+
}
92+
}
93+
return version;
94+
}
95+
96+
97+
bool AGS02MA::setPPBMode()
98+
{
99+
_buffer[0] = 0x00;
100+
_buffer[1] = 0xFF;
101+
_buffer[2] = 0x00;
102+
_buffer[3] = 0xFF;
103+
_buffer[4] = 0x30;
104+
if (_writeRegister(AGS02MA_DATA))
105+
{
106+
_mode = 0;
107+
return true;
108+
}
109+
return false;
110+
}
111+
112+
113+
bool AGS02MA::setUGM3Mode()
114+
{
115+
_buffer[0] = 0x02;
116+
_buffer[1] = 0xFD;
117+
_buffer[2] = 0x02;
118+
_buffer[3] = 0xFD;
119+
_buffer[4] = 0x00;
120+
if (_writeRegister(AGS02MA_DATA))
121+
{
122+
_mode = 1;
123+
return true;
124+
}
125+
return false;
126+
}
127+
128+
129+
uint32_t AGS02MA::readPPB()
130+
{
131+
uint32_t val = 0xFFFFFFFF;
132+
_lastRead = millis();
133+
if (_readRegister(AGS02MA_DATA))
134+
{
135+
_status = _buffer[0];
136+
val = _buffer[1] * 65536UL;
137+
val += _buffer[2] * 256;
138+
val += _buffer[3];
139+
if (_CRC8(_buffer, 5) != 0)
140+
{
141+
_error = AGS02MA_CRC_ERROR;
142+
}
143+
}
144+
return val;
145+
}
146+
147+
148+
uint32_t AGS02MA::readUGM3()
149+
{
150+
uint32_t val = 0xFFFFFFFF;
151+
_lastRead = millis();
152+
if (_readRegister(AGS02MA_DATA))
153+
{
154+
_status = _buffer[0];
155+
val = _buffer[1] * 65536UL;
156+
val += _buffer[2] * 256;
157+
val += _buffer[3];
158+
if (_CRC8(_buffer, 5) != 0)
159+
{
160+
_error = AGS02MA_CRC_ERROR;
161+
}
162+
}
163+
return val;
164+
}
165+
166+
167+
bool AGS02MA::zeroCalibration()
168+
{
169+
_buffer[0] = 0x00;
170+
_buffer[1] = 0x0C;
171+
_buffer[2] = 0xFF;
172+
_buffer[3] = 0xF3;
173+
_buffer[4] = 0xFC;
174+
return _writeRegister(AGS02MA_CALIBRATION);
175+
}
176+
177+
178+
int AGS02MA::lastError()
179+
{
180+
int e = _error;
181+
_error = AGS02MA_OK; // reset error after read
182+
return e;
183+
}
184+
185+
186+
187+
/////////////////////////////////////////////////////////
188+
//
189+
// PRIVATE
190+
//
191+
bool AGS02MA::_readRegister(uint8_t reg)
192+
{
193+
#if defined (__AVR__)
194+
TWBR = 255;
195+
#else
196+
_wire->setClock(AGS02MA_I2C_CLOCK);
197+
#endif
198+
_wire->beginTransmission(_address);
199+
_wire->write(reg);
200+
_error = _wire->endTransmission();
201+
202+
if (_wire->requestFrom(_address, (uint8_t)5) != 5)
203+
{
204+
_error = AGS02MA_ERROR;
205+
_wire->setClock(_I2CReseSpeed);
206+
return false;
207+
}
208+
for (int i = 0; i < 5; i++)
209+
{
210+
_buffer[i] = _wire->read();
211+
}
212+
_wire->setClock(_I2CReseSpeed);
213+
return true;
214+
}
215+
216+
217+
bool AGS02MA::_writeRegister(uint8_t reg)
218+
{
219+
#if defined (__AVR__)
220+
TWBR = 255;
221+
#else
222+
_wire->setClock(AGS02MA_I2C_CLOCK);
223+
#endif
224+
_wire->beginTransmission(_address);
225+
_wire->write(reg);
226+
for (int i = 0; i < 5; i++)
227+
{
228+
_wire->write(_buffer[i]);
229+
}
230+
_error = _wire->endTransmission();
231+
_wire->setClock(_I2CReseSpeed);
232+
return (_error == 0);
233+
}
234+
235+
236+
uint8_t AGS02MA::_CRC8(uint8_t * buf, uint8_t size)
237+
{
238+
uint8_t crc = 0xFF; // start value
239+
for (uint8_t b = 0; b < size; b++)
240+
{
241+
crc ^= buf[b];
242+
for (uint8_t i = 0; i < 8; i++)
243+
{
244+
if (crc & 0x80) crc = (crc << 1) ^ 0x31;
245+
else crc = (crc << 1);
246+
}
247+
}
248+
return crc;
249+
}
250+
251+
252+
// -- END OF FILE --

libraries/AGS02MA/AGS02MA.h

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#pragma once
2+
//
3+
// FILE: AGS02MA.h
4+
// AUTHOR: Rob Tillaart
5+
// DATE: 2021-08-12
6+
// VERSION: 0.1.0
7+
// PURPOSE: Arduino library for AGS02MA TVOC
8+
// URL: https://github.com/RobTillaart/AGS02MA
9+
//
10+
11+
12+
#include "Arduino.h"
13+
#include "Wire.h"
14+
15+
16+
#define AGS02MA_LIB_VERSION (F("0.1.0"))
17+
18+
#define AGS02MA_OK 0
19+
#define AGS02MA_ERROR -10
20+
#define AGS02MA_CRC_ERROR -11
21+
22+
23+
#define AGS02MA_I2C_CLOCK 25000
24+
#define AGS02MA_I2C_RESET 400000
25+
26+
27+
class AGS02MA
28+
{
29+
public:
30+
explicit AGS02MA(const uint8_t deviceAddress = 26, TwoWire *wire = &Wire);
31+
32+
#if defined (ESP8266) || defined(ESP32)
33+
bool begin(uint8_t sda, uint8_t scl);
34+
#endif
35+
bool begin();
36+
bool isConnected();
37+
38+
bool isHeated() { return (millis() - _startTime) > 120000UL; };
39+
uint32_t lastRead() { return _lastRead; };
40+
41+
bool setAddress(const uint8_t deviceAddress);
42+
uint8_t getAddress() { return _address; };
43+
44+
uint8_t getSensorVersion();
45+
void setI2CResetSpeed(uint32_t s) { _I2CReseSpeed = s; };
46+
uint32_t getI2CResetSpeed() { return _I2CReseSpeed; };
47+
48+
49+
bool setPPBMode();
50+
bool setUGM3Mode();
51+
uint8_t getMode() { return _mode; };
52+
53+
uint32_t readPPB();
54+
uint32_t readUGM3();
55+
56+
// to be called after at least 5 minutes in fresh air.
57+
bool zeroCalibration();
58+
59+
int lastError();
60+
uint8_t lastStatus() { return _status; };
61+
62+
private:
63+
bool _readRegister(uint8_t reg);
64+
bool _writeRegister(uint8_t reg);
65+
uint8_t _CRC8(uint8_t * buf, uint8_t size);
66+
67+
uint32_t _I2CReseSpeed = 100000;
68+
uint32_t _startTime = 0;
69+
uint32_t _lastRead = 0;
70+
uint8_t _address = 0;
71+
uint8_t _mode = 255;
72+
uint8_t _status = 0;
73+
74+
uint8_t _buffer[5];
75+
76+
int _error = AGS02MA_OK;
77+
78+
TwoWire* _wire;
79+
};
80+
81+
82+
// -- END OF FILE --

0 commit comments

Comments
 (0)