mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.3.0 SHT2x
This commit is contained in:
parent
cdd3ab20e6
commit
302b12e5e5
@ -6,7 +6,7 @@ jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: arduino/arduino-lint-action@v1
|
||||
with:
|
||||
library-manager: update
|
||||
|
@ -8,7 +8,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.6
|
||||
|
@ -10,7 +10,7 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: json-syntax-check
|
||||
uses: limitusus/json-syntax-check@v1
|
||||
with:
|
||||
|
@ -6,11 +6,23 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [0.3.0] - 2023-03-26
|
||||
- fix setResolution #13, #18
|
||||
- fix heater settings
|
||||
- add GY21 as derived class
|
||||
- fix derived constructors
|
||||
- move code from .h to .cpp
|
||||
- update readme.md
|
||||
- update GitHub actions
|
||||
- update license 2023
|
||||
- minor edits
|
||||
|
||||
----
|
||||
|
||||
## [0.2.2] - 2022-12-14
|
||||
- add experimental asynchronous interface
|
||||
- add async example
|
||||
|
||||
|
||||
## [0.2.1] - 2022-11-24
|
||||
- Add RP2040 support to build-CI.
|
||||
- Add CHANGELOG.md
|
||||
|
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-2022 Rob Tillaart
|
||||
Copyright (c) 2021-2023 Rob Tillaart
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -21,16 +21,17 @@ Furthermore there are a number of compatible sensors, these are not tested eithe
|
||||
|
||||
Accuracy table
|
||||
|
||||
| Sensor | Temperature | Humidity | Notes |
|
||||
|:-------:|:-----------:|:--------:|:-------|
|
||||
| SHT20 | ~0.3 | ±3.0 | |
|
||||
| SHT21 | ~0.3 | ±3.0 | |
|
||||
| SHT25 | ~0.3 | ±1.8 | |
|
||||
| HTU20 | | | to-do |
|
||||
| HTU21 | | | to-do |
|
||||
| Si7013 | | | to-do |
|
||||
| Si7020 | | | to-do |
|
||||
| Si7021 | | | to-do |
|
||||
| Sensor | Temperature | Humidity | Notes |
|
||||
|:---------:|:-----------:|:--------:|:--------|
|
||||
| SHT20 | ~0.3 | ±3.0 | |
|
||||
| SHT21 | ~0.3 | ±3.0 | |
|
||||
| SHT25 | ~0.3 | ±1.8 | |
|
||||
| HTU20 | | | to-do |
|
||||
| HTU21 | | | to-do |
|
||||
| Si7013 | | | to-do |
|
||||
| Si7020 | | | to-do |
|
||||
| Si7021 | | | to-do |
|
||||
| GY21 | | | to-do |
|
||||
|
||||
|
||||
All sensors in this family of sensors have address 0x40 (64 decimal).
|
||||
@ -40,6 +41,10 @@ or one should switch sensors on/off like the select in SPI communication.
|
||||
|
||||
## Interface
|
||||
|
||||
```cpp
|
||||
#include "SHT2x.h"
|
||||
```
|
||||
|
||||
#### Constructors
|
||||
|
||||
All classes below are derived from SHT2x class.
|
||||
@ -100,18 +105,18 @@ TODO elaborate documentation.
|
||||
- **int getError()** returns last set error flag and clear it.
|
||||
Be sure to clear the error flag by calling **getError()** before calling any command as the error flag could be from a previous command.
|
||||
|
||||
| Value | Symbolic | Description | Notes |
|
||||
|:------:|:--------------------------|:----------------------------|:---------|
|
||||
| 0x00 | SHT2x_OK | no error | |
|
||||
| 0x81 | SHT2x_ERR_WRITECMD | I2C write failed | |
|
||||
| 0x82 | SHT2x_ERR_READBYTES | I2C read failed | |
|
||||
| 0x83 | SHT2x_ERR_HEATER_OFF | Could not switch off heater | |
|
||||
| 0x84 | SHT2x_ERR_NOT_CONNECT | Could not connect | |
|
||||
| 0x85 | SHT2x_ERR_CRC_TEMP | CRC error in temperature | |
|
||||
| 0x86 | SHT2x_ERR_CRC_HUM | CRC error in humidity | |
|
||||
| 0x87 | SHT2x_ERR_CRC_STATUS | CRC error in status field | not used |
|
||||
| 0x88 | SHT2x_ERR_HEATER_COOLDOWN | Heater need to cool down | |
|
||||
| 0x88 | SHT2x_ERR_HEATER_ON | Could not switch on heater | |
|
||||
| Value | Symbolic | Description | Notes |
|
||||
|:-------:|:----------------------------|:------------------------------|:-----------|
|
||||
| 0x00 | SHT2x_OK | no error | |
|
||||
| 0x81 | SHT2x_ERR_WRITECMD | I2C write failed | |
|
||||
| 0x82 | SHT2x_ERR_READBYTES | I2C read failed | |
|
||||
| 0x83 | SHT2x_ERR_HEATER_OFF | Could not switch off heater | |
|
||||
| 0x84 | SHT2x_ERR_NOT_CONNECT | Could not connect | |
|
||||
| 0x85 | SHT2x_ERR_CRC_TEMP | CRC error in temperature | |
|
||||
| 0x86 | SHT2x_ERR_CRC_HUM | CRC error in humidity | |
|
||||
| 0x87 | SHT2x_ERR_CRC_STATUS | CRC error in status field | not used |
|
||||
| 0x88 | SHT2x_ERR_HEATER_COOLDOWN | Heater need to cool down | |
|
||||
| 0x88 | SHT2x_ERR_HEATER_ON | Could not switch on heater | |
|
||||
|
||||
Note: the HTU20 / HTU21 classes share the same error codes.
|
||||
|
||||
@ -175,12 +180,12 @@ From HTU20 datasheet
|
||||
|
||||
Datasheet SHT20 Table 8: (resolution)
|
||||
|
||||
| RES | Humidity | Temperature |
|
||||
|:-----:|:---------:|:-----------:|
|
||||
| 0 | 12 bit | 14 bit |
|
||||
| 1 | 08 bit | 12 bit |
|
||||
| 2 | 10 bit | 13 bit |
|
||||
| 3 | 11 bit | 11 bit |
|
||||
| RES | Humidity | Temperature |
|
||||
|:-----:|:----------:|:-------------:|
|
||||
| 0 | 12 bit | 14 bit |
|
||||
| 1 | 08 bit | 12 bit |
|
||||
| 2 | 10 bit | 13 bit |
|
||||
| 3 | 11 bit | 11 bit |
|
||||
|
||||
Datasheet SHT20 Table 7: (timing) and results of real measurements.
|
||||
( https://github.com/RobTillaart/SHT2x/pull/11 )
|
||||
@ -205,25 +210,24 @@ Timing in milliseconds.
|
||||
|
||||
#### Must
|
||||
- improve documentation
|
||||
- reorganize interface
|
||||
- clean up code.
|
||||
|
||||
|
||||
#### 0.3.0
|
||||
- add crc8 check (need sensor)
|
||||
#### 0.4.0
|
||||
- add crc8 check (need sensor to test)
|
||||
- improve error handling (all code paths)
|
||||
- investigate blocking delay() in read
|
||||
- add offset for temperature and humidity
|
||||
- move code from .h to .cpp
|
||||
- add GY21 as derived class name
|
||||
|
||||
|
||||
#### ASYNC 0.3.0
|
||||
#### ASYNC 0.4.0
|
||||
improvements for interface.
|
||||
|
||||
- **bool requestReady()** checks both.
|
||||
- **bool requestPending()** checks .
|
||||
- **uint8_t getRequestType()** returns 0, 1, 2
|
||||
- documentation
|
||||
- **bool requestReady()** checks both.
|
||||
- **bool requestPending()** checks.
|
||||
- **uint8_t getRequestType()** returns 0, 1, 2.
|
||||
- async documentation
|
||||
|
||||
|
||||
#### Should
|
||||
@ -236,9 +240,9 @@ improvements for interface.
|
||||
|
||||
|
||||
#### Could
|
||||
- investigate resolution anomalies
|
||||
- fix TODO in code (.cpp and .h) and documentation
|
||||
- update unit tests
|
||||
- add type info in derived classes?
|
||||
|
||||
|
||||
#### Wont
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// FILE: SHT2x.cpp
|
||||
// AUTHOR: Rob Tillaart, Viktor Balint
|
||||
// VERSION: 0.2.2
|
||||
// VERSION: 0.3.0
|
||||
// DATE: 2021-09-25
|
||||
// PURPOSE: Arduino library for the SHT2x temperature and humidity sensor
|
||||
// URL: https://github.com/RobTillaart/SHT2x
|
||||
@ -253,6 +253,18 @@ float SHT2x::getHumidity()
|
||||
}
|
||||
|
||||
|
||||
uint16_t SHT2x::getRawTemperature()
|
||||
{
|
||||
return _rawTemperature;
|
||||
}
|
||||
|
||||
|
||||
uint16_t SHT2x::getRawHumidity()
|
||||
{
|
||||
return _rawHumidity;
|
||||
}
|
||||
|
||||
|
||||
bool SHT2x::reset()
|
||||
{
|
||||
bool b = writeCmd(SHT2x_SOFT_RESET);
|
||||
@ -265,6 +277,13 @@ uint8_t SHT2x::getStatus()
|
||||
return _status;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SHT2x::lastRead()
|
||||
{
|
||||
return _lastRead;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// HEATER
|
||||
@ -276,6 +295,12 @@ void SHT2x::setHeatTimeout(uint8_t seconds)
|
||||
}
|
||||
|
||||
|
||||
uint8_t SHT2x::getHeatTimeout()
|
||||
{
|
||||
return _heatTimeout;
|
||||
}
|
||||
|
||||
|
||||
bool SHT2x::heatOn()
|
||||
{
|
||||
if (isHeaterOn()) return true;
|
||||
@ -296,7 +321,7 @@ bool SHT2x::heatOn()
|
||||
// HEAT BIT ON
|
||||
userReg |= SHT2x_USRREG_HEATER;
|
||||
|
||||
if (writeCmd(SHT2x_READ_USER_REGISTER, userReg) == false)
|
||||
if (writeCmd(SHT2x_WRITE_USER_REGISTER, userReg) == false)
|
||||
{
|
||||
_error = SHT2x_ERR_HEATER_ON;
|
||||
return false;
|
||||
@ -320,7 +345,7 @@ bool SHT2x::heatOff()
|
||||
// HEAT BIT OFF
|
||||
userReg &= ~SHT2x_USRREG_HEATER;
|
||||
|
||||
if (writeCmd(SHT2x_READ_USER_REGISTER, userReg) == false)
|
||||
if (writeCmd(SHT2x_WRITE_USER_REGISTER, userReg) == false)
|
||||
{
|
||||
_error = SHT2x_ERR_HEATER_OFF; // can be serious!
|
||||
return false;
|
||||
@ -477,7 +502,7 @@ bool SHT2x::setResolution(uint8_t res)
|
||||
userReg |= ((res & 0x02) << 6);
|
||||
userReg |= (res & 0x01);
|
||||
|
||||
if (writeCmd(SHT2x_READ_USER_REGISTER, userReg) == false)
|
||||
if (writeCmd(SHT2x_WRITE_USER_REGISTER, userReg) == false)
|
||||
{
|
||||
_error = SHT2x_ERR_RESOLUTION;
|
||||
return false;
|
||||
@ -510,8 +535,6 @@ bool SHT2x::batteryOK()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
//
|
||||
// PROTECTED
|
||||
@ -590,53 +613,62 @@ bool SHT2x::readBytes(uint8_t n, uint8_t *val, uint8_t maxDuration)
|
||||
//
|
||||
// DERIVED SHT
|
||||
//
|
||||
SHT20::SHT20()
|
||||
SHT20::SHT20() : SHT2x()
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
SHT21::SHT21()
|
||||
SHT21::SHT21() : SHT2x()
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
SHT25::SHT25()
|
||||
SHT25::SHT25() : SHT2x()
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
// DERIVED HTU
|
||||
//
|
||||
HTU20::HTU20()
|
||||
HTU20::HTU20() : SHT2x()
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
HTU21::HTU21()
|
||||
HTU21::HTU21() : SHT2x()
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
// DERIVED Si70xx
|
||||
//
|
||||
Si7013::Si7013()
|
||||
Si7013::Si7013() : SHT2x()
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Si7020::Si7020()
|
||||
Si7020::Si7020() : SHT2x()
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Si7021::Si7021()
|
||||
Si7021::Si7021() : SHT2x()
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
// DERIVED Si70xx
|
||||
//
|
||||
GY21::GY21() : SHT2x()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
// -- END OF FILE --
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// FILE: SHT2x.h
|
||||
// AUTHOR: Rob Tillaart, Viktor Balint
|
||||
// VERSION: 0.2.2
|
||||
// VERSION: 0.3.0
|
||||
// DATE: 2021-09-25
|
||||
// PURPOSE: Arduino library for the SHT2x temperature and humidity sensor
|
||||
// URL: https://github.com/RobTillaart/SHT2x
|
||||
@ -13,7 +13,7 @@
|
||||
#include "Wire.h"
|
||||
|
||||
|
||||
#define SHT2x_LIB_VERSION (F("0.2.2"))
|
||||
#define SHT2x_LIB_VERSION (F("0.3.0"))
|
||||
|
||||
|
||||
// fields getStatus
|
||||
@ -53,13 +53,18 @@ public:
|
||||
// check sensor is reachable over I2C
|
||||
bool isConnected();
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEMPERATURE AND HUMIDTY
|
||||
//
|
||||
// read must be called get getTemperature / getHumidity
|
||||
bool read();
|
||||
bool read();
|
||||
|
||||
float getTemperature();
|
||||
float getHumidity();
|
||||
uint16_t getRawTemperature() { return _rawTemperature; };
|
||||
uint16_t getRawHumidity() { return _rawHumidity; };
|
||||
uint16_t getRawTemperature();
|
||||
uint16_t getRawHumidity();
|
||||
|
||||
// might take up to 15 milliseconds.
|
||||
bool reset();
|
||||
@ -76,15 +81,18 @@ public:
|
||||
uint8_t getStatus();
|
||||
|
||||
// lastRead is in milliSeconds since start
|
||||
uint32_t lastRead() { return _lastRead; };
|
||||
uint32_t lastRead();
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// HEATER
|
||||
//
|
||||
// do not use heater for long periods,
|
||||
// use it for max 3 minutes to heat up
|
||||
// and let it cool down at least 3 minutes.
|
||||
void setHeatTimeout(uint8_t seconds);
|
||||
uint8_t getHeatTimeout() { return _heatTimeout; };
|
||||
uint8_t getHeatTimeout();
|
||||
|
||||
bool heatOn();
|
||||
bool heatOff();
|
||||
@ -96,11 +104,22 @@ public:
|
||||
|
||||
int getError(); // clears error flag
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// Electronic Identification Code
|
||||
//
|
||||
// Sensirion_Humidity_SHT2x_Electronic_Identification_Code_V1.1.pdf
|
||||
// Electronic ID bytes
|
||||
uint32_t getEIDA();
|
||||
uint32_t getEIDB();
|
||||
uint8_t getFirmwareVersion();
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// RESOLUTION
|
||||
//
|
||||
// experimental 0.2.0 - needs testing.
|
||||
// table 8 SHT20 datasheet
|
||||
// table 7 shows different timing per resolution
|
||||
@ -115,9 +134,11 @@ public:
|
||||
// returns RES set (cached value)
|
||||
uint8_t getResolution();
|
||||
|
||||
bool batteryOK();
|
||||
|
||||
// Experimental ASYNC interface
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// ASYNCHRONOUS INTERFACE (experimental)
|
||||
//
|
||||
bool requestTemperature();
|
||||
bool requestHumidity();
|
||||
bool reqTempReady();
|
||||
@ -127,6 +148,13 @@ public:
|
||||
uint32_t lastRequest();
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//
|
||||
// OTHER
|
||||
//
|
||||
bool batteryOK();
|
||||
|
||||
|
||||
protected:
|
||||
uint8_t crc8(const uint8_t *data, uint8_t len);
|
||||
|
||||
@ -160,7 +188,7 @@ protected:
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
// DERIVED SHT
|
||||
// DERIVED SHT classes
|
||||
//
|
||||
class SHT20 : public SHT2x
|
||||
{
|
||||
@ -185,7 +213,7 @@ public:
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
// DERIVED HTU
|
||||
// DERIVED HTU classes
|
||||
//
|
||||
class HTU20 : public SHT2x
|
||||
{
|
||||
@ -203,7 +231,7 @@ public:
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
// DERIVED Si70xx
|
||||
// DERIVED Si70xx classes
|
||||
//
|
||||
class Si7013 : public SHT2x
|
||||
{
|
||||
@ -226,4 +254,16 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
// DERIVED GY21 classes
|
||||
//
|
||||
class GY21 : public SHT2x
|
||||
{
|
||||
public:
|
||||
GY21();
|
||||
};
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "SHT2x",
|
||||
"keywords": "SHT20,SHT21,SHT25,HTU20D,HTU21D",
|
||||
"keywords": "SHT20,SHT21,SHT25,HTU20D,HTU21D,Si7013,Si7020,Si7021,GY21",
|
||||
"description": "Arduino library for the I2C SHT20 SHT21 SHT25 series temperature and humidity sensor. Works also for HTU2xD(F) series.",
|
||||
"authors":
|
||||
[
|
||||
@ -18,7 +18,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/SHT2x.git"
|
||||
},
|
||||
"version": "0.2.2",
|
||||
"version": "0.3.0",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
|
@ -1,9 +1,9 @@
|
||||
name=SHT2x
|
||||
version=0.2.2
|
||||
version=0.3.0
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library for the I2C SHT20 SHT21 SHT25 series temperature and humidity sensor.
|
||||
paragraph=Works also for HTU20D(F) and HTU21D(F) series.
|
||||
paragraph=Derived classes for HTU20D(F), HTU21D(F), Si7013, Si7020, Si7021, GY21.
|
||||
category=Sensors
|
||||
url=https://github.com/RobTillaart/SHT2x
|
||||
architectures=*
|
||||
|
@ -23,14 +23,17 @@
|
||||
// assertEqualFloat(expected, actual, epsilon); // fabs(a - b) <= epsilon
|
||||
|
||||
/*
|
||||
most unit tests will test for fail
|
||||
most unit tests will test for fail
|
||||
as there is no sensor connected
|
||||
and there is no mockup.
|
||||
|
||||
|
||||
It appears that Wire.write does not fail without sensor...
|
||||
*/
|
||||
|
||||
|
||||
// TODO test for derives classes?
|
||||
|
||||
|
||||
#include <ArduinoUnitTests.h>
|
||||
|
||||
#include "Arduino.h"
|
||||
@ -88,7 +91,6 @@ unittest(test_constructor)
|
||||
}
|
||||
|
||||
|
||||
|
||||
unittest(test_begin)
|
||||
{
|
||||
SHT2x sht;
|
||||
@ -123,7 +125,7 @@ unittest(test_read)
|
||||
expect = SHT2x_OK;
|
||||
assertEqual(expect, sht.getError());
|
||||
|
||||
// assertion wire.available fails ...
|
||||
// assertion wire.available fails ...
|
||||
// assertFalse(sht.read());
|
||||
// expect = SHT2x_ERR_READBYTES;
|
||||
// assertEqual(expect, sht.getError());
|
||||
@ -149,7 +151,7 @@ unittest(test_getStatus)
|
||||
SHT2x sht;
|
||||
bool b = sht.begin();
|
||||
assertEqual(b, true);
|
||||
|
||||
|
||||
assertEqual(0x00, sht.getStatus());
|
||||
expect = SHT2x_OK;
|
||||
assertEqual(expect, sht.getError());
|
||||
@ -161,8 +163,8 @@ unittest(test_heater)
|
||||
SHT2x sht;
|
||||
bool b = sht.begin();
|
||||
assertEqual(b, true);
|
||||
|
||||
// assertion wire.available fails ...
|
||||
|
||||
// assertion wire.available fails ...
|
||||
// assertFalse(sht.heatOn());
|
||||
// expect = SHT2x_ERR_READBYTES;
|
||||
// assertEqual(expect, sht.getError());
|
||||
@ -177,6 +179,21 @@ unittest(test_heater)
|
||||
}
|
||||
|
||||
|
||||
unittest(test_resolution)
|
||||
{
|
||||
SHT2x sht;
|
||||
bool b = sht.begin();
|
||||
assertEqual(b, true);
|
||||
|
||||
// not set yet
|
||||
assertEqual(0, sht.getResolution());
|
||||
// out of range
|
||||
assertFalse(sht.setResolution(4));
|
||||
}
|
||||
|
||||
|
||||
unittest_main()
|
||||
|
||||
// --------
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user