From ba91a4389690beeb54f104a34c3af38d72e99993 Mon Sep 17 00:00:00 2001 From: RobTillaart Date: Tue, 12 Dec 2017 16:28:41 +0100 Subject: [PATCH] 0.1.2 added get and set functions; fix return values; cleaned up code --- libraries/AM232X/AM232X.cpp | 158 ++++++++++-------- libraries/AM232X/AM232X.h | 25 ++- libraries/AM232X/examples/AM2320/AM2320.ino | 6 +- .../examples/AM2320_test/AM2320_test.ino | 40 ++++- libraries/AM232X/examples/AM2322/AM2322.ino | 6 +- libraries/AM232X/keywords.txt | 13 +- libraries/AM232X/library.properties | 2 +- 7 files changed, 155 insertions(+), 95 deletions(-) diff --git a/libraries/AM232X/AM232X.cpp b/libraries/AM232X/AM232X.cpp index a2d50f16..76a1af10 100644 --- a/libraries/AM232X/AM232X.cpp +++ b/libraries/AM232X/AM232X.cpp @@ -1,12 +1,13 @@ // // FILE: AM232X.cpp // AUTHOR: Rob Tillaart -// VERSION: 0.1.1 +// VERSION: 0.1.2 // PURPOSE: AM232X library for AM2320 for Arduino. // // HISTORY: // 0.1.0 - 2017-12-11 initial version -// 0.1.1 = 2017-12-12 added CRC checking +// 0.1.1 - 2017-12-12 added CRC checking +// 0.1.2 - 2017-12-12 get and set functions. // // Released to the public domain // @@ -20,21 +21,18 @@ AM232X::AM232X() { _deviceAddress = AM232X_ADDRESS; - _model = -1; - _version = -1; - _deviceID = -1; } int AM232X::read() { // READ HUMIDITY AND TEMPERATURE REGISTERS int rv = _readRegister(0x00, 4); - if (rv < 0) return AM232X_ERROR_CONNECT; + if (rv < 0) return rv; // CONVERT AND STORE humidity = (bits[2]*256 + bits[3]) * 0.1; temperature = (bits[4] & 0x7F)*256 + bits[5] * 0.1; - + if (bits[4] & 0x80) { temperature = -temperature; @@ -45,59 +43,75 @@ int AM232X::read() int AM232X::getModel() { int rv = _readRegister(0x08, 2); - _model = (bits[2] * 256) + bits[3]; - if (rv < 0) return AM232X_ERROR_CONNECT; - return AM232X_OK; + if (rv < 0) return rv; + + return (bits[2] * 256) + bits[3]; } int AM232X::getVersion() { int rv = _readRegister(0x0A, 1); - _version = bits[2]; - if (rv < 0) return AM232X_ERROR_CONNECT; - return AM232X_OK; + if (rv < 0) return rv; + + return bits[2]; } uint32_t AM232X::getDeviceID() { int rv = _readRegister(0x0B, 4); - _deviceID = (bits[2] * 256) + bits[3]; + if (rv < 0) return rv; + + uint32_t _deviceID = (bits[2] * 256) + bits[3]; _deviceID = _deviceID * 256 + bits[4]; _deviceID = _deviceID * 256 + bits[5]; - if (rv < 0) return AM232X_ERROR_CONNECT; - - return AM232X_OK; + return _deviceID; } int AM232X::getStatus() { - _readRegister(0x0F, 1); + int rv = _readRegister(0x0F, 1); + if (rv < 0) return rv; + return bits[2]; } int AM232X::getUserRegisterA() { - _readRegister(0x10, 2); + int rv = _readRegister(0x10, 2); + if (rv < 0) return rv; + return (bits[2] * 256) + bits[3]; } int AM232X::getUserRegisterB() { - _readRegister(0x12, 2); + int rv = _readRegister(0x12, 2); + if (rv < 0) return rv; + return (bits[2] * 256) + bits[3]; } +int AM232X::setStatus(uint8_t value) +{ + int rv = _writeRegister(0x0F, 1, value); + if (rv < 0) return rv; + + return AM232X_OK; +} + int AM232X::setUserRegisterA(int value) { - // TODO - _writeRegister(0x10, 2, value); + int rv = _writeRegister(0x10, 2, value); + if (rv < 0) return rv; + return AM232X_OK; } int AM232X::setUserRegisterB(int value) { - // TODO - _writeRegister(0x12, 2, value); + int rv = _writeRegister(0x12, 2, value); + if (rv < 0) return rv; + return AM232X_OK; } @@ -107,8 +121,6 @@ int AM232X::setUserRegisterB(int value) // int AM232X::_readRegister(uint8_t reg, uint8_t count) { - bool debug = true; - // wake up the sensor - see 8.2 Wire.beginTransmission(_deviceAddress); int rv = Wire.endTransmission(); @@ -125,51 +137,38 @@ int AM232X::_readRegister(uint8_t reg, uint8_t count) // request 4 extra, 2 for cmd + 2 for CRC uint8_t length = count + 4; int bytes = Wire.requestFrom(_deviceAddress, length); - - if (debug) Serial.println(); + for (int i = 0; i < bytes; i++) { bits[i] = Wire.read(); - if (debug) - { - Serial.print(bits[i], HEX); - Serial.print("\t"); - } } - if (debug) Serial.println(); - // ANALYZE ERRORS - // will not detect if we requested 1 byte as that will + // will not detect if we requested 1 byte as that will // return 5 bytes as requested. E.g. getStatus() // TODO: design a fix. if (bytes != length) { switch(bits[3]) { - case 0x80: return AM232X_ERROR_FUNCTION; - case 0x81: return AM232X_ERROR_ADDRESS; - case 0x82: return AM232X_ERROR_REGISTER; - case 0x83: return AM232X_ERROR_CRC_1; // prev write had a wrong CRC - case 0x84: return AM232X_ERROR_WRITE_DISABLED; - default: return AM232X_MISSING_BYTES; + case 0x80: return AM232X_ERROR_FUNCTION; + case 0x81: return AM232X_ERROR_ADDRESS; + case 0x82: return AM232X_ERROR_REGISTER; + case 0x83: return AM232X_ERROR_CRC_1; // prev write had a wrong CRC + case 0x84: return AM232X_ERROR_WRITE_DISABLED; + default: return AM232X_ERROR_UNKNOWN; } } // CRC is LOW Byte first uint16_t crc = bits[bytes - 1]*256 + bits[bytes - 2]; - if (crc16(&bits[0], count-2) != crc) + if (crc16(&bits[0], bytes - 2) != crc) { - if (debug) - { - Serial.print("CRC: "); - Serial.println(crc); - } return AM232X_ERROR_CRC_2; // read itself has wrong CRC } return AM232X_OK; } -int AM232X::_writeRegister(uint8_t reg, uint8_t cnt, int32_t value) +int AM232X::_writeRegister(uint8_t reg, uint8_t cnt, int16_t value) { // wake up the sensor - see 8.2 Wire.beginTransmission(_deviceAddress); @@ -181,35 +180,63 @@ int AM232X::_writeRegister(uint8_t reg, uint8_t cnt, int32_t value) bits[1] = reg; bits[2] = cnt; - if (cnt == 4) - { - bits[6] = value & 0xFF; - bits[5] = (value >> 8) & 0xFF; - bits[4] = (value >> 8) & 0xFF; - bits[3] = (value >> 8) & 0xFF; - } - else if (cnt == 2) + // TODO: is the order correct? MSB LSB + if (cnt == 2) { bits[4] = value & 0xFF; bits[3] = (value >> 8) & 0xFF; } - else if (cnt == 1) + else { bits[3] = value & 0xFF; } - uint16_t crc = crc16(bits, cnt + 3); - + // send data + uint8_t length = cnt + 3; // 3 = cmd, startReg, #bytes Wire.beginTransmission(_deviceAddress); - for (int i=0; i< cnt+3; i++) + for (int i=0; i< length; i++) { Wire.write(bits[i]); } + // send the CRC + uint16_t crc = crc16(bits, length); Wire.write(crc & 0xFF); Wire.write(crc >> 8); + rv = Wire.endTransmission(); if (rv < 0) return rv; + // wait for the answer + int bytes = Wire.requestFrom(_deviceAddress, length); + for (int i = 0; i < bytes; i++) + { + bits[i] = Wire.read(); + } + + // ANALYZE ERRORS + // will not detect if we requested 1 byte as that will + // return 5 bytes as requested. E.g. getStatus() + // TODO: design a fix. + if (bytes != length) + { + switch(bits[3]) + { + case 0x80: return AM232X_ERROR_FUNCTION; + case 0x81: return AM232X_ERROR_ADDRESS; + case 0x82: return AM232X_ERROR_REGISTER; + case 0x83: return AM232X_ERROR_CRC_1; // prev write had a wrong CRC + case 0x84: return AM232X_ERROR_WRITE_DISABLED; + default: return AM232X_ERROR_UNKNOWN; + } + } + + // CRC is LOW Byte first + crc = bits[bytes - 1]*256 + bits[bytes - 2]; + if (crc16(&bits[0], bytes - 2) != crc) + { + return AM232X_ERROR_CRC_2; // read itself has wrong CRC + } + return AM232X_OK; } @@ -221,10 +248,10 @@ uint16_t AM232X::crc16(uint8_t *ptr, uint8_t len) { crc ^= *ptr++; for(int i = 0; i < 8; i++) - { + { if (crc & 0x01) { - crc >>= 1; + crc >>= 1; crc ^= 0xA001; } else @@ -235,6 +262,5 @@ uint16_t AM232X::crc16(uint8_t *ptr, uint8_t len) } return crc; } -// -// END OF FILE -// \ No newline at end of file + +// END OF FILE \ No newline at end of file diff --git a/libraries/AM232X/AM232X.h b/libraries/AM232X/AM232X.h index 79c5c55d..80dc53b9 100644 --- a/libraries/AM232X/AM232X.h +++ b/libraries/AM232X/AM232X.h @@ -4,9 +4,9 @@ // FILE: AM232X.h // AUTHOR: Rob Tillaart // PURPOSE: AM232X library for Arduino . -// VERSION: 0.1.1 +// VERSION: 0.1.2 // HISTORY: See AM232X.cpp -// URL: +// URL: https://github.com/RobTillaart/Arduino/tree/master/libraries/ // // Released to the public domain // @@ -14,10 +14,10 @@ #include "Wire.h" #include "Arduino.h" -#define AM232X_LIB_VERSION "0.1.1" +#define AM232X_LIB_VERSION "0.1.2" #define AM232X_OK 0 -#define AM232X_MISSING_BYTES -10 +#define AM232X_ERROR_UNKNOWN -10 #define AM232X_ERROR_CONNECT -11 #define AM232X_ERROR_FUNCTION -12 #define AM232X_ERROR_ADDRESS -13 @@ -25,12 +25,14 @@ #define AM232X_ERROR_CRC_1 -15 #define AM232X_ERROR_CRC_2 -16 #define AM232X_ERROR_WRITE_DISABLED -17 +#define AM232X_ERROR_WRITE_COUNT -18 +#define AM232X_MISSING_BYTES -19 /* from datasheet -0x80: not support function code -0x81: Read an illegal address +0x80: not support function code +0x81: Read an illegal address 0x82: write data beyond the scope -0x83: CRC checksum error +0x83: CRC checksum error 0x84: Write disabled */ @@ -50,6 +52,7 @@ public: int getUserRegisterA(); int getUserRegisterB(); + int setStatus(uint8_t value); int setUserRegisterA(int value); int setUserRegisterB(int value); @@ -58,14 +61,10 @@ public: private: uint8_t _deviceAddress; - int _model; - int _version; - uint32_t _deviceID; - uint8_t bits[8]; - int _readRegister(uint8_t reg, uint8_t cnt); - int _writeRegister(uint8_t reg, uint8_t cnt, int32_t value); + int _readRegister(uint8_t reg, uint8_t cnt); + int _writeRegister(uint8_t reg, uint8_t cnt, int16_t value); uint16_t crc16(uint8_t *ptr, uint8_t len); }; diff --git a/libraries/AM232X/examples/AM2320/AM2320.ino b/libraries/AM232X/examples/AM2320/AM2320.ino index be6bb355..c60503b7 100644 --- a/libraries/AM232X/examples/AM2320/AM2320.ino +++ b/libraries/AM232X/examples/AM2320/AM2320.ino @@ -37,11 +37,9 @@ void loop() case AM232X_OK: Serial.print("OK,\t"); break; - case AM232X_MISSING_BYTES: - Serial.print("Missing Bytes,\t"); - break; default: - Serial.print("Unknown error,\t"); + Serial.print(status); + Serial.print("\t"); break; } // DISPLAY DATA, sensor only returns one decimal. diff --git a/libraries/AM232X/examples/AM2320_test/AM2320_test.ino b/libraries/AM232X/examples/AM2320_test/AM2320_test.ino index bb6ba648..cc6d4b18 100644 --- a/libraries/AM232X/examples/AM2320_test/AM2320_test.ino +++ b/libraries/AM232X/examples/AM2320_test/AM2320_test.ino @@ -1,11 +1,12 @@ // // FILE: AM2320_test.ino // AUTHOR: Rob Tillaart -// VERSION: 0.1.0 +// VERSION: 0.1.1 // PURPOSE: demo sketch for AM2320 I2C humidity & temperature sensor // // HISTORY: // 0.1.0 - 2017-12-11 initial version +// 0.1.1 - 2017-12-12 added test for set* functions // // Released to the public domain // @@ -24,21 +25,36 @@ void setup() Serial.println(AM232X_LIB_VERSION); Serial.println(); - AM2320.read(); - + // sensor only returns one decimal. + Serial.println(); + Serial.println("Read: \t"); + int status = AM2320.read(); + switch (status) + { + case AM232X_OK: + Serial.println("OK"); + break; + default: + Serial.println(status); + break; + } Serial.print("Temp:\t"); Serial.println(AM2320.temperature, 1); Serial.print("Hum:\t"); Serial.println(AM2320.humidity, 1); - + + Serial.println(); + Serial.println("GET SENSOR INFO (experimental)"); Serial.print("Model:\t"); Serial.println(AM2320.getModel()); Serial.print("Version:\t"); Serial.println(AM2320.getVersion()); Serial.print("DevId:\t"); Serial.println(AM2320.getDeviceID()); - + + Serial.println(); + Serial.println("GET REGISTERS (experimental)"); Serial.print("Status:\t"); Serial.println(AM2320.getStatus()); Serial.print("UserA:\t"); @@ -46,6 +62,18 @@ void setup() Serial.print("UserB:\t"); Serial.println(AM2320.getUserRegisterB()); + Serial.println(); + Serial.println("SET REGISTERS (experimental)"); + AM2320.setStatus(42); + Serial.print("Status 42 ==> "); + Serial.println(AM2320.getStatus()); + AM2320.setUserRegisterA(1234); + Serial.print("UserA 1234 ==> "); + Serial.println(AM2320.getUserRegisterA()); + AM2320.setUserRegisterB(5678); + Serial.print("UserB 5678 ==> "); + Serial.println(AM2320.getUserRegisterB()); + Serial.println("done..."); } @@ -55,4 +83,4 @@ void loop() // // END OF FILE -// \ No newline at end of file +/// \ No newline at end of file diff --git a/libraries/AM232X/examples/AM2322/AM2322.ino b/libraries/AM232X/examples/AM2322/AM2322.ino index 87e21328..4f5968c9 100644 --- a/libraries/AM232X/examples/AM2322/AM2322.ino +++ b/libraries/AM232X/examples/AM2322/AM2322.ino @@ -37,11 +37,9 @@ void loop() case AM232X_OK: Serial.print("OK,\t"); break; - case AM232X_MISSING_BYTES: - Serial.print("Missing Bytes,\t"); - break; default: - Serial.print("Unknown error,\t"); + Serial.print(status); + Serial.print("\t"); break; } // DISPLAY DATA, sensor only returns one decimal. diff --git a/libraries/AM232X/keywords.txt b/libraries/AM232X/keywords.txt index 98e7884e..63d2b73e 100644 --- a/libraries/AM232X/keywords.txt +++ b/libraries/AM232X/keywords.txt @@ -12,7 +12,18 @@ AM232X KEYWORD1 # Methods and Functions (KEYWORD2) ####################################### -read KEYWORD2 +read KEYWORD2 +getModel KEYWORD2 +getVersion KEYWORD2 +getDeviceID KEYWORD2 +getStatus KEYWORD2 +getUserRegisterA KEYWORD2 +getUserRegisterB KEYWORD2 +setStatus KEYWORD2 +setUserRegisterA KEYWORD2 +setUserRegisterB KEYWORD2 +humidity KEYWORD2 +temperature KEYWORD2 ####################################### # Constants (LITERAL1) diff --git a/libraries/AM232X/library.properties b/libraries/AM232X/library.properties index 60aa8e49..56cf9b36 100644 --- a/libraries/AM232X/library.properties +++ b/libraries/AM232X/library.properties @@ -1,5 +1,5 @@ name=AM232X -version=0.1.1 +version=0.1.2 author=Rob Tillaart maintainer=Rob Tillaart sentence=Library for AM232X Temperature and Humidity sensor.