update libs

This commit is contained in:
rob tillaart 2021-02-03 17:20:20 +01:00
parent 7661eee8b4
commit e5bc4a1d9a
56 changed files with 1596 additions and 414 deletions

View File

@ -1,7 +1,7 @@
//
// FILE: AM232X.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.4
// VERSION: 0.3.1
// PURPOSE: AM232X library for AM2320 for Arduino.
//
// HISTORY:
@ -19,12 +19,14 @@
// 0.2.3 2020-05-27 update library.json
// 0.2.4 2020-12-09 arduino-ci
// 0.3.0 2021-01-12 isConnected() + Wire0..Wire5 support
// 0.3.1 2021-01-28 fix TODO's in code
#include "AM232X.h"
#define AM232X_ADDRESS ((uint8_t)0x5C)
const uint8_t AM232X_ADDRESS = 0x5C;
////////////////////////////////////////////////////////////////////
//
@ -173,67 +175,31 @@ int AM232X::setUserRegisterB(int value)
//
int AM232X::_readRegister(uint8_t reg, uint8_t count)
{
// wake up the sensor - see 8.2
_wire->beginTransmission(AM232X_ADDRESS);
int rv = _wire->endTransmission();
delayMicroseconds(1000); // TODO tune
if (! _wakeup() ) return AM232X_ERROR_CONNECT;
// request the data
_wire->beginTransmission(AM232X_ADDRESS);
_wire->write(0x03);
_wire->write(reg);
_wire->write(count);
rv = _wire->endTransmission();
int rv = _wire->endTransmission();
if (rv < 0) return rv;
// request 4 extra, 2 for cmd + 2 for CRC
uint8_t length = count + 4;
int bytes = _wire->requestFrom(AM232X_ADDRESS, 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
uint16_t 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;
rv = _getData(count + 4);
return rv;
}
int AM232X::_writeRegister(uint8_t reg, uint8_t cnt, int16_t value)
{
// wake up the sensor - see 8.2
_wire->beginTransmission(AM232X_ADDRESS);
int rv = _wire->endTransmission();
delayMicroseconds(1000); // TODO tune
if (! _wakeup() ) return AM232X_ERROR_CONNECT;
// prepare data to send
bits[0] = 0x10;
bits[1] = reg;
bits[2] = cnt;
// TODO: is the order correct? MSB LSB
if (cnt == 2)
{
bits[4] = value & 0xFF;
@ -247,20 +213,43 @@ int AM232X::_writeRegister(uint8_t reg, uint8_t cnt, int16_t value)
// send data
uint8_t length = cnt + 3; // 3 = cmd, startReg, #bytes
_wire->beginTransmission(AM232X_ADDRESS);
for (int i=0; i< length; i++)
for (int i = 0; i < length; i++)
{
_wire->write(bits[i]);
}
// send the CRC
uint16_t crc = crc16(bits, length);
uint16_t crc = _crc16(bits, length);
_wire->write(crc & 0xFF);
_wire->write(crc >> 8);
rv = _wire->endTransmission();
int rv = _wire->endTransmission();
if (rv < 0) return rv;
// wait for the answer
rv = _getData(length);
return rv;
}
bool AM232X::_wakeup()
{
// wake up the sensor - see 8.2
// min 800 us max 3000 us
uint32_t start = micros();
while (! isConnected())
{
if (micros() - start > 3000) return false;
yield();
delayMicroseconds(100);
}
return true;
}
int AM232X::_getData(uint8_t length)
{
int bytes = _wire->requestFrom(AM232X_ADDRESS, length);
for (int i = 0; i < bytes; i++)
{
bits[i] = _wire->read();
@ -269,23 +258,23 @@ int AM232X::_writeRegister(uint8_t reg, uint8_t cnt, int16_t value)
// 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.
// design a fix if it becomes a problem.
if (bytes != length)
{
switch(bits[3])
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;
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)
uint16_t 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
}
@ -294,14 +283,14 @@ int AM232X::_writeRegister(uint8_t reg, uint8_t cnt, int16_t value)
}
uint16_t AM232X::crc16(uint8_t *ptr, uint8_t len)
uint16_t AM232X::_crc16(uint8_t *ptr, uint8_t len)
{
uint16_t crc =0xFFFF;
uint16_t crc = 0xFFFF;
while (len--)
{
crc ^= *ptr++;
for(int i = 0; i < 8; i++)
for (int i = 0; i < 8; i++)
{
if (crc & 0x01)
{

View File

@ -3,12 +3,12 @@
// FILE: AM232X.h
// AUTHOR: Rob Tillaart
// PURPOSE: AM232X library for Arduino
// VERSION: 0.3.0
// VERSION: 0.3.1
// HISTORY: See AM232X.cpp
// URL: https://github.com/RobTillaart/AM232X
//
// Bottom view
// Bottom view
// +---+
// VDD |o |
// SDA |o |
@ -21,7 +21,7 @@
#include "Wire.h"
#define AM232X_LIB_VERSION (F("0.3.0"))
#define AM232X_LIB_VERSION (F("0.3.1"))
@ -39,51 +39,54 @@
/*
* from datasheet
* 0x80: not support function code
* 0x81: Read an illegal address
* 0x82: write data beyond the scope
* 0x83: CRC checksum error
* 0x84: Write disabled
from datasheet
0x80: not support function code
0x81: Read an illegal address
0x82: write data beyond the scope
0x83: CRC checksum error
0x84: Write disabled
*/
class AM232X
{
public:
explicit AM232X(TwoWire *wire = &Wire);
public:
explicit AM232X(TwoWire *wire = &Wire);
#if defined (ESP8266) || defined(ESP32)
bool begin(uint8_t sda, uint8_t scl);
bool begin(uint8_t sda, uint8_t scl);
#endif
bool begin();
bool isConnected();
int read();
int getModel();
int getVersion();
uint32_t getDeviceID();
bool begin();
bool isConnected();
int getStatus();
int getUserRegisterA();
int getUserRegisterB();
int read();
int getModel();
int getVersion();
uint32_t getDeviceID();
int setStatus(uint8_t value);
int setUserRegisterA(int value);
int setUserRegisterB(int value);
int getStatus();
int getUserRegisterA();
int getUserRegisterB();
inline float getHumidity() { return humidity; };
inline float getTemperature() { return temperature; };
int setStatus(uint8_t value);
int setUserRegisterA(int value);
int setUserRegisterB(int value);
private:
uint8_t bits[8];
float humidity;
float temperature;
inline float getHumidity() { return humidity; };
inline float getTemperature() { return temperature; };
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);
private:
uint8_t bits[8];
float humidity;
float temperature;
TwoWire* _wire;
int _readRegister(uint8_t reg, uint8_t cnt);
int _writeRegister(uint8_t reg, uint8_t cnt, int16_t value);
bool _wakeup();
int _getData(uint8_t length);
uint16_t _crc16(uint8_t *ptr, uint8_t len);
TwoWire* _wire;
};
// -- END OF FILE --

View File

@ -76,13 +76,12 @@ variables temperature and humidity.
To access these values one must use **getTemperature()** and **getHumidity()**.
## Planned changes
## Future
Fix several TODO's in the code.
## Warning
The library has several open ends so use at own risk.
The library has not been tested extensively yet so use at own risk.
See also LICENSE

View File

@ -1,31 +1,48 @@
//
// FILE: AM2320.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// VERSION: 0.1.2
// PURPOSE: AM2320 demo sketch for AM2320 I2C humidity & temperature sensor
//
// HISTORY:
// 0.1.0 2017-12-11 initial version
// 0.1.1 2020-05-03 updated to 0.2.0 version of lib.
// 0.1.0 2017-12-11 initial version
// 0.1.1 2020-05-03 updated to 0.2.0 version of lib.
// 0.1.2 2021-01-28 added begin() ++
// Bottom view
// +---+
// VDD |o |
// SDA |o |
// GND |o |
// SCL |o |
// +---+
//
// do not forget pull up resistors between SDA, SCL and VDD.
#include <AM232X.h>
AM232X AM2320;
void setup()
{
Wire.begin();
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("LIBRARY VERSION: ");
Serial.println(AM232X_LIB_VERSION);
Serial.println();
if (! AM2320.begin() )
{
Serial.println("Sensor not found");
while (1);
}
Serial.println("Type,\tStatus,\tHumidity (%),\tTemperature (C)");
}
void loop()
{
// READ DATA
@ -33,13 +50,13 @@ void loop()
int status = AM2320.read();
switch (status)
{
case AM232X_OK:
Serial.print("OK,\t");
break;
default:
Serial.print(status);
Serial.print("\t");
break;
case AM232X_OK:
Serial.print("OK,\t");
break;
default:
Serial.print(status);
Serial.print("\t");
break;
}
// DISPLAY DATA, sensor only returns one decimal.
Serial.print(AM2320.getHumidity(), 1);

View File

@ -1,29 +1,44 @@
//
// FILE: AM2320_test.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.2
// VERSION: 0.1.3
// 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
// 0.1.2 2020-05-03 updated to 0.2.0 version of lib.
// 0.1.3 2021-01-28 added begin() ++
// Bottom view
// +---+
// VDD |o |
// SDA |o |
// GND |o |
// SCL |o |
// +---+
//
// do not forget pull up resistors between SDA, SCL and VDD.
#include <AM232X.h>
AM232X AM2320;
void setup()
{
Wire.begin();
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("LIBRARY VERSION: ");
Serial.println(AM232X_LIB_VERSION);
Serial.println();
if (! AM2320.begin() )
{
Serial.println("Sensor not found");
while (1);
}
// sensor only returns one decimal.
Serial.println();
@ -76,6 +91,7 @@ void setup()
Serial.println("done...");
}
void loop()
{
}

View File

@ -1,13 +1,13 @@
//
// FILE: AM2322.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// VERSION: 0.1.2
// PURPOSE: demo sketch for AM2322 I2C humidity & temperature sensor
//
// HISTORY:
// 0.1.0 2017-12-11 initial version
// 0.1.1 2020-05-03 updated to 0.2.0 version of lib.
//
// 0.1.2 2021-01-28 added begin() ++
// Bottom view
// +---+
@ -18,23 +18,31 @@
// +---+
//
// do not forget pull up resistors between SDA, SCL and VDD.
#include <AM232X.h>
AM232X AM2322;
void setup()
{
Wire.begin();
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("LIBRARY VERSION: ");
Serial.println(AM232X_LIB_VERSION);
Serial.println();
if (! AM2322.begin() )
{
Serial.println("Sensor not found");
while (1);
}
Serial.println("Type,\tStatus,\tHumidity (%),\tTemperature (C)");
}
void loop()
{
// READ DATA

View File

@ -1,11 +1,13 @@
//
// FILE: AM2322_plotter.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// PURPOSE: demo sketch for AM2322 I2C humidity & temperature sensor
//
// HISTORY:
// 0.1.0 2020-09-01 simple program to dump for plotter.
// 0.1.1 2021-01-28 added begin() ++
//
// Bottom view
// +---+
@ -17,18 +19,26 @@
//
// do not forget pull up resistors between SDA, SCL and VDD.
#include <AM232X.h>
AM232X AM2322;
void setup()
{
Wire.begin();
Serial.begin(115200);
if (! AM2322.begin() )
{
Serial.println("Sensor not found");
while (1);
}
Serial.println("Humidity(%),\tTemperature(C)");
}
void loop()
{
AM2322.read();

View File

@ -1,8 +1,10 @@
# Syntax Coloring Map For DHT_I2C
# Datatypes (KEYWORD1)
AM232X KEYWORD1
# Methods and Functions (KEYWORD2)
begin KEYWORD2
isConnected KEYWORD2
@ -19,6 +21,7 @@ setUserRegisterB KEYWORD2
getHumidity KEYWORD2
getTemperature KEYWORD2
# Constants (LITERAL1)
AM232X_LIB_VERSION LITERAL1
AM232X_OK LITERAL1

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/AM232X"
},
"version":"0.3.0",
"version":"0.3.1",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -1,5 +1,5 @@
name=AM232X
version=0.3.0
version=0.3.1
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for AM2320 AM2321 and AM2323 I2C temperature and humidity sensor.

View File

@ -1,64 +0,0 @@
//
// FILE: demo0.ino
// AUTHOR: Rob Tillaart
// DATE: 2020-05-17
// VERSION: 0.1.0
// PUPROSE: demo of the Correlation Library
//
/*
X Y x y xy x2 b a EY ei ei2
---------------------------------------------------------
4 11 21 10 2,1 2,6 1,9
2 7 -2 -4 8 4 6,8 0,2 0,04
3 9 -1 -2 2 1 8,9 0,1 0,01
4 10 0 -1 0 0 11 -1 1
5 14 1 3 3 1 13,1 0,9 0,81
6 15 2 4 8 4 15,2 -0,2 0,04
*/
#include "Correlation.h"
Correlation C;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
C.clear();
C.add(2, 7);
C.add(3, 9);
C.add(4, 10);
C.add(5, 14);
C.add(6, 15);
C.calculate();
Serial.print("A:\t");
Serial.println(C.getA(), 3);
Serial.print("B:\t");
Serial.println(C.getB(), 3);
Serial.print("R:\t");
Serial.println(C.getR(), 6);
Serial.print("Rsq:\t");
Serial.println(C.getRsquare(), 6);
Serial.print("Esq:\t");
Serial.println(C.getEsquare(), 3);
Serial.println();
for (int i = 2; i <= 6; i++)
{
Serial.print(i);
Serial.print("\t");
Serial.println(C.getEstimateY(i), 4);
}
Serial.println("\nDone...");
}
void loop()
{
}
// -- END OF FILE --

View File

@ -1,50 +0,0 @@
//
// FILE: demo1.ino
// AUTHOR: Rob Tillaart
// DATE: 2020-05-17
// VERSION: 0.1.0
// PUPROSE: demo of the Correlation Library
//
#include "Correlation.h"
Correlation C;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
C.clear();
for (int i = 0; i < 20; i++)
{
C.add(i * 10, i * 40 + 0.1 * random(10));
}
C.calculate();
Serial.print("A:\t");
Serial.println(C.getA(), 3);
Serial.print("B:\t");
Serial.println(C.getB(), 3);
Serial.print("Rsq:\t");
Serial.println(C.getRsquare(), 6);
Serial.print("Esq:\t");
Serial.println(C.getEsquare(), 3);
Serial.println();
for (int i = 0; i <= 20; i++)
{
Serial.print(i * 5);
Serial.print("\t");
Serial.println(C.getEstimateY(i * 5), 4);
}
Serial.println("\nDone...");
}
void loop()
{
}
// -- END OF FILE --

View File

@ -1,78 +0,0 @@
//
// FILE: demo_performance.ino
// AUTHOR: Rob Tillaart
// DATE: 2020-05-18
// VERSION: 0.1.0
// PUPROSE: demo of the Correlation Library
//
// performance test: only ADD and CALCULATE as these are the most used
// and could be optimized in the future
#include "Correlation.h"
Correlation C;
uint32_t start, stop, sum = 0;
volatile float f;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.println("ADD");
delay(10);
C.clear();
for (int i = 0; i < 20; i++)
{
f = i * 40 + 0.1 * random(10);
start = micros();
C.add(i * 10, f );
stop = micros();
sum += stop - start;
}
Serial.println(sum / 20.0);
Serial.println("\nCALCULATE - needed ");
delay(10);
start = micros();
C.calculate();
stop = micros();
Serial.println(stop - start);
Serial.println("\nCALCULATE - no new values added");
delay(10);
start = micros();
C.calculate();
stop = micros();
Serial.println(stop - start);
Serial.println("\ngetEstimateX");
delay(10);
start = micros();
f = C.getEstimateX(42);
stop = micros();
Serial.println(stop - start);
Serial.println("\ngetEstimateY");
delay(10);
start = micros();
f = C.getEstimateY(42);
stop = micros();
Serial.println(stop - start);
Serial.println("\nDone...");
}
void loop()
{
}
// -- END OF FILE --

View File

@ -8,29 +8,141 @@
Arduino library for COZIR range of temperature, humidity and CO2 sensors.
## Description
The Cozir library is still experimental as I do not have a sensor to test the library.
The Cozir library is **experimental** as I do not have a sensor to test the library.
The polling mode as used in the examples seems to work quite well.
Note: the **CozirDemoHWSerial.ino** example needs to run on a MEGA or a Teensy,
#### Notes
- the **CozirDemoHWSerial.ino** example needs to run on a MEGA or a Teensy,
at least a board with more than one Serial port.
- Read the datasheet before using this library. It helps to understand the working of the Cozir sensor.
## Interface
Read the datasheet (again)
### Constructor and initialisation
- **COZIR(Stream \*)** constructor
- **void init()** sets operatingMode to CZR_POLLING
- **void SetOperatingMode(uint8_t mode)** set the operating mode either to **CZR_COMMAND**, **CZR_POLLING** or **CZR_STREAMING**
### Core
- **float Celsius()** idem
- **float Fahrenheit()** idem, wrapper around **Celsius()**
- **float Humidity()** idem
- **float Light()** idem
- **uint32_t CO2() ** idem.
- **uint16_t getPPMFactor()** returns 1, 10, 100 See Page 14.
### Calibration
Read datasheet before use
- **uint16_t FineTuneZeroPoint(uint16_t v1, uint16_t v2)**
- **uint16_t CalibrateFreshAir()**
- **uint16_t CalibrateNitrogen()**
- **uint16_t CalibrateKnownGas(uint16_t value)**
#### Calibration NOT Recommended
Following 3 functions are **NOT RECOMMENDED** by the datasheet.
Feel free to uncomment but use at your own risk. Read datasheet before use.
- **uint16_t CalibrateManual(uint16_t value)**
- **uint16_t SetSpanCalibrate(uint16_t value)**
- **uint16_t GetSpanCalibrate()**
### Digifilter
use with care, read datasheet before use
| value | meaning |
|:-----:|:--------|
| 0 | Special, see datasheet page ... |
| 1 | fast, but can be noisy |
| 32 | default, good average |
| 255 | slow, max smoothed |
- **void SetDigiFilter(uint8_t value)**
- **uint8_t GetDigiFilter()**
### Streaming MODE
Warning: Not tested ,
- **void SetOutputFields(uint16_t fields)** Sets the fields in the output stream.
- **void ClrOutputFields()** clears all the fields.
- **void GetRecentFields()** After a call to GetRecentFields() you must read the serial port yourself as the internal buffer of this Class cannot handle the possible large output. It can be over 100 bytes long lines!
The fields must be set as a bit mask, the order of the fields in the output is undetermined. So parse carefully.
| Field | Value | Notes |
|:------------------|:-------|:------|
| CZR_LIGHT | 0x2000 | |
| CZR_HUMIDITY | 0x1000 | |
| CZR_FILTLED | 0x0800 | |
| CZR_RAWLED | 0x0400 | |
| CZR_MAXLED | 0x0200 | |
| CZR_ZEROPOINT | 0x0100 | |
| CZR_RAWTEMP | 0x0080 | |
| CZR_FILTTEMP | 0x0040 | |
| CZR_FILTLEDSIGNAL | 0x0020 | |
| CZR_RAWLEDSIGNAL | 0x0010 | |
| CZR_SENSTEMP | 0x0008 | |
| CZR_FILTCO2 | 0x0004 | |
| CZR_RAWCO2 | 0x0002 | |
| CZR_NONE | 0x0001 | reset |
| CZR_HTC | 0x1082 | shortcut |
| CZR_ALL | 0x3FFE | debug |
### EEPROM
Read datasheet Page 11-12 about the addresses and their meaning.
Use with care.
- **void SetEEPROM(uint8_t address, uint8_t value)**
- **uint8_t GetEEPROM(uint8_t address)**
| Name | Address | Default | Notes |
|:---------|:-------:|:-------:|:------|
| AHHI | 0x00 | | reserved |
| ANLO | 0x01 | | reserved |
| ANSOURCE | 0x02 | | reserved |
| ACINITHI | 0x03 | 87 | |
| ACINITLO | 0x04 | 192 | |
| ACHI | 0x05 | 94 | |
| ACLO | 0x06 | 128 | |
| ACONOFF | 0x07 | 0 | |
| ACPPMHI | 0x08 | 1 | |
| ACPPMLO | 0x09 | 194 | |
| AMBHI | 0x0A | 1 | |
| AMBLO | 0x0B | 194 | |
| BCHI | 0x0C | 0 | |
| BCLO | 0x0D | 8 | |
### Misc
- **void GetVersionSerial()** requests version over serial. The user should read (and parse) the serial output as it can become large. Also the user must reset the operating mode either to **CZR_POLLING** or **CZR_STREAMING**
- **void GetConfiguration()** requests configuration over serial. The user should read (and parse) the serial output as it can become large. Also the user must reset the operating mode either to **CZR_POLLING** or **CZR_STREAMING**
## Operation
See examples.
There are functions commented that are **NOT RECOMMENDED** by the datasheet.
Feel free to uncomment but use at your own risk.
## Notes
Note: the 0.2.0 library is still experimental, see several TODO's in the code.
That said, the default polling mode used in the examples works stable (last version tested).
## Test sensor

View File

@ -1,24 +1,25 @@
//
// FILE: Cozir.cpp
// AUTHOR: DirtGambit & Rob Tillaart
// VERSION: 0.2.5
// VERSION: 0.2.6
// PURPOSE: library for COZIR range of sensors for Arduino
// Polling Mode
// URL: https://github.com/RobTillaart/Cozir
// http://forum.arduino.cc/index.php?topic=91467.0
//
// HISTORY:
// 0.2.5 2020-12-26 fix software Serial + version number (oops)
// 0.2.2 2020-12-17 add arduino-ci + unit tests
// 0.2.1 2020-06-05 fix library.json
// 0.2.0 2020-03-30 some refactor and own repo
// 0.1.06 added support for HardwareSerial for MEGA (Rob T)
// 0.2.6 2021-01-31 fix #4 use Mode0 for versions and configuration
// 0.2.5 2020-12-26 fix software Serial + version number (oops)
// 0.2.2 2020-12-17 add arduino-ci + unit tests
// 0.2.1 2020-06-05 fix library.json
// 0.2.0 2020-03-30 some refactor and own repo
// 0.1.06 added support for HardwareSerial for MEGA (Rob T)
// removed support for NewSoftSerial ==> stop pre 1.0 support)
// 0.1.05 fixed bug: uint16_t request() to uint32_t request() in .h file (Rob T)
// 0.1.04 changed CO2 to support larger values (Rob T)
// 0.1.03 added setOperatingMode
// 0.1.02 added support Arduino 1.x
// 0.1.01 initial version
// 0.1.05 fixed bug: uint16_t request() to uint32_t request() in .h file (Rob T)
// 0.1.04 changed CO2 to support larger values (Rob T)
// 0.1.03 added setOperatingMode
// 0.1.02 added support Arduino 1.x
// 0.1.01 initial version
//
// READ DATASHEET BEFORE USE OF THIS LIB !
//
@ -225,12 +226,16 @@ uint8_t COZIR::GetEEPROM(uint8_t address)
//
void COZIR::GetVersionSerial()
{
// overide modes to prevent interference in output
SetOperatingMode(CZR_COMMAND);
Command("Y");
}
void COZIR::GetConfiguration()
{
// overide modes to prevent interference in output
SetOperatingMode(CZR_COMMAND);
Command("*");
}

View File

@ -2,18 +2,18 @@
//
// FILE: Cozir.h
// AUTHOR: DirtGambit & Rob Tillaart
// VERSION: 0.2.5
// VERSION: 0.2.6
// PURPOSE: library for COZIR range of sensors for Arduino
// Polling Mode
// URL: https://github.com/RobTillaart/Cozir
// http://forum.arduino.cc/index.php?topic=91467.0
// http://forum.arduino.cc/index.php?topic=91467.0
//
// READ DATASHEET BEFORE USE OF THIS LIB !
//
#include "Arduino.h"
#define COZIR_LIB_VERSION "0.2.5"
#define COZIR_LIB_VERSION (F("0.2.6"))
// OUTPUTFIELDS
// See datasheet for details.

View File

@ -0,0 +1,6 @@
compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
- leonardo
- due
- zero

View File

@ -0,0 +1,64 @@
//
// FILE: Cozir_getVersion.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo of Cozir lib (>= 0.1.06)
// DATE: 2021-01-31
// URL: http://forum.arduino.cc/index.php?topic=91467.0
//
// Note: this sketch needs a MEGA or a Teensy that supports a second
// Serial port named Serial1
#include "cozir.h"
COZIR czr(&Serial1);
void setup()
{
Serial1.begin(9600);
czr.init();
Serial.begin(115200);
Serial.print("Cozir HardwareSerial: ");
Serial.println(COZIR_LIB_VERSION);
Serial.println();
delay(100);
czr.GetVersionSerial();
delay(5);
while (Serial1.available())
{
Serial.write(Serial1.read());
}
delay(100);
czr.GetConfiguration();
delay(5);
while (Serial1.available())
{
Serial.write(Serial1.read());
}
delay(1000);
// reset to polling again.
czr.SetOperatingMode(CZR_POLLING);
}
void loop()
{
float t = czr.Celsius();
float f = czr.Fahrenheit();
float h = czr.Humidity();
uint32_t c = czr.CO2();
Serial.print("Celcius =\t"); Serial.println(t);
Serial.print("Fahrenheit =\t"); Serial.println(f);
Serial.print("Humidity =\t"); Serial.println(h);
Serial.print("CO2 =\t"); Serial.println(c);
Serial.println();
delay(3000);
}
// -- END OF FILE --

View File

@ -18,7 +18,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/Cozir.git"
},
"version":"0.2.5",
"version":"0.2.6",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -1,5 +1,5 @@
name=Cozir
version=0.2.5
version=0.2.6
author=Rob Tillaart <rob.tillaart@gmail.com>, DirtGambit
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for COZIR range of CO2 sensors. Polling mode only.

View File

@ -84,13 +84,13 @@ unittest(test_constructor)
state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = "";
co.GetVersionSerial();
assertEqual("Y\r\n", state->serialPort[0].dataOut);
assertEqual("K 0\r\nY\r\n", state->serialPort[0].dataOut);
fprintf(stderr, "COZIR.GetConfiguration()\n");
state->serialPort[0].dataIn = "";
state->serialPort[0].dataOut = "";
co.GetConfiguration();
assertEqual("*\r\n", state->serialPort[0].dataOut);
assertEqual("K 0\r\n*\r\n", state->serialPort[0].dataOut);
}

View File

@ -1,7 +1,7 @@
//
// FILE: dhtnew.cpp
// AUTHOR: Rob.Tillaart@gmail.com
// VERSION: 0.4.3
// VERSION: 0.4.4
// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino
// URL: https://github.com/RobTillaart/DHTNEW
//
@ -36,6 +36,7 @@
// 2020-12-12 add arduino -CI + readme
// 0.4.2 2020-12-15 fix negative temperatures
// 0.4.3 2021-01-13 add reset(), add lastRead()
// 0.4.4 2021-02-01 fix negative temperatures DHT22 (again)
#include "dhtnew.h"
@ -186,16 +187,13 @@ int DHTNEW::_read()
if (_type == 22) // DHT22, DHT33, DHT44, compatible
{
_humidity = (_bits[0] * 256 + _bits[1]) * 0.1;
_temperature = ((_bits[2] & 0x7F) * 256 + _bits[3]) * 0.1;
if (_bits[2] & 0x80)
{
_temperature = -_temperature;
}
_humidity = (_bits[0] * 256 + _bits[1]) * 0.1;
int16_t t = (_bits[2] * 256 + _bits[3]);
_temperature = t * 0.1;
}
else // if (_type == 11) // DHT11, DH12, compatible
{
_humidity = _bits[0] + _bits[1] * 0.1;
_humidity = _bits[0] + _bits[1] * 0.1;
_temperature = _bits[2] + _bits[3] * 0.1;
}

View File

@ -2,7 +2,7 @@
//
// FILE: dhtnew.h
// AUTHOR: Rob Tillaart
// VERSION: 0.4.3
// VERSION: 0.4.4
// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino
// URL: https://github.com/RobTillaart/DHTNEW
//
@ -22,7 +22,7 @@
#include "Arduino.h"
#define DHTNEW_LIB_VERSION (F("0.4.3"))
#define DHTNEW_LIB_VERSION (F("0.4.4"))
#define DHTLIB_OK 0

View File

@ -13,7 +13,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/DHTNEW.git"
},
"version":"0.4.3",
"version":"0.4.4",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -1,5 +1,5 @@
name=DHTNEW
version=0.4.3
version=0.4.4
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for DHT temperature and humidity sensor, with automatic sensortype recognition.

View File

@ -1,12 +1,13 @@
//
// FILE: dht.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.31
// VERSION: 0.1.32
// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino, AVR optimized
// URL: https://github.com/RobTillaart/DHTlib
// http://arduino.cc/playground/Main/DHTLib
//
// HISTORY:
// 0.1.32 2021-02-01 fix negative temperature DHT22 again (code from DHTNew)
// 0.1.31 2020-12-15 fix negative temperature DHT22 (code from DHTNew)
// 0.1.30 2020-06-30 own repo;
// 0.1.29 2018-09-02 fix negative temperature DHT12 - issue #111
@ -113,12 +114,9 @@ int8_t dht::read(uint8_t pin)
bits[2] &= 0x83;
// CONVERT AND STORE
humidity = (bits[0] * 256 + bits[1]) * 0.1;
temperature = ((bits[2] & 0x7F) * 256 + bits[3]) * 0.1;
if (bits[2] & 0x80) // negative temperature
{
temperature = -temperature;
}
humidity = (bits[0] * 256 + bits[1]) * 0.1;
int16_t t = (bits[2] * 256 + bits[3]);
temperature = t * 0.1;
// HEXDUMP DEBUG
/*

View File

@ -1,7 +1,7 @@
//
// FILE: dht.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.31
// VERSION: 0.1.32
// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino. AVR optimized
// URL: https://github.com/RobTillaart/DHTlib
// http://arduino.cc/playground/Main/DHTLib
@ -20,20 +20,22 @@
#include <Arduino.h>
#endif
#define DHT_LIB_VERSION "0.1.31"
#define DHTLIB_OK 0
#define DHTLIB_ERROR_CHECKSUM -1
#define DHTLIB_ERROR_TIMEOUT -2
#define DHTLIB_ERROR_CONNECT -3
#define DHTLIB_ERROR_ACK_L -4
#define DHTLIB_ERROR_ACK_H -5
#define DHT_LIB_VERSION (F("0.1.32"))
#define DHTLIB_DHT11_WAKEUP 18
#define DHTLIB_DHT_WAKEUP 1
#define DHTLIB_OK 0
#define DHTLIB_ERROR_CHECKSUM -1
#define DHTLIB_ERROR_TIMEOUT -2
#define DHTLIB_ERROR_CONNECT -3
#define DHTLIB_ERROR_ACK_L -4
#define DHTLIB_ERROR_ACK_H -5
#define DHTLIB_DHT11_WAKEUP 18
#define DHTLIB_DHT_WAKEUP 1
#define DHTLIB_DHT11_LEADING_ZEROS 1
#define DHTLIB_DHT_LEADING_ZEROS 6
#define DHTLIB_DHT11_LEADING_ZEROS 1
#define DHTLIB_DHT_LEADING_ZEROS 6
// max timeout is 100 usec.
// For a 16 Mhz proc 100 usec is 1600 clock cycles
@ -46,6 +48,7 @@
#define DHTLIB_TIMEOUT (F_CPU/40000)
#endif
class dht
{
public:

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/DHTlib.git"
},
"version":"0.1.31",
"version":"0.1.32",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -1,5 +1,5 @@
name=DHTlib
version=0.1.31
version=0.1.32
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=AVR Optimized Library for DHT Temperature & Humidity Sensor on AVR only.

View File

@ -1,11 +1,12 @@
//
// FILE: dht.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.7
// VERSION: 0.2.8
// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino
// URL: https://github.com/RobTillaart/DHTstable
//
// HISTORY:
// 0.2.8 2021-02-01 fix negative temperature (from dhtnew)
// 0.2.7 2020-12-20 add arduino-CI, unit test,
// reset(), getTemperature(), getHumidity()
// 0.2.6 2020-07-20 update URL in .cpp
@ -34,8 +35,10 @@
// inspired by DHT11 library
//
#include "dht.h"
/////////////////////////////////////////////////////
//
// PUBLIC
@ -104,12 +107,9 @@ int dht::read(uint8_t pin)
}
// CONVERT AND STORE
humidity = word(bits[0], bits[1]) * 0.1;
temperature = word(bits[2] & 0x7F, bits[3]) * 0.1;
if (bits[2] & 0x80) // negative temperature
{
temperature = -temperature;
}
humidity = word(bits[0], bits[1]) * 0.1;
int16_t t = bits[2] * 256 + bits[3];
temperature = t * 0.1;
// TEST CHECKSUM
uint8_t sum = bits[0] + bits[1] + bits[2] + bits[3];

View File

@ -1,7 +1,7 @@
//
// FILE: dht.h
// AUTHOR: Rob Tillaart
// VERSION: 0.2.7
// VERSION: 0.2.8
// PURPOSE: DHT Temperature & Humidity Sensor library for Arduino
// URL: https://github.com/RobTillaart/DHTstable
//
@ -18,7 +18,9 @@
#include <Arduino.h>
#endif
#define DHT_LIB_VERSION "0.2.7 - dhtstable"
#define DHT_LIB_VERSION (F("0.2.8 - dhtstable"))
const int DHTLIB_OK = 0;
const int DHTLIB_ERROR_CHECKSUM = -1;
@ -35,6 +37,7 @@ const int DHTLIB_DHT_WAKEUP = 1;
// so by dividing F_CPU by 40000 we "fail" as fast as possible
const int DHTLIB_TIMEOUT = (F_CPU/40000);
class dht
{
public:

View File

@ -1,2 +0,0 @@
2015-08-20 these examples are retrofitted from version 0.1.20 which supports more errors.

View File

@ -13,9 +13,9 @@
"repository":
{
"type": "git",
"url": "https://github.com/RobTillaart/DHTstable
"url": "https://github.com/RobTillaart/DHTstable"
},
"version":"0.2.7",
"version":"0.2.8",
"frameworks": "arduino",
"platforms": "atmelavr"
}

View File

@ -1,5 +1,5 @@
name=DHTStable
version=0.2.7
version=0.2.8
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Stable version of library for DHT Temperature & Humidity Sensor

View File

@ -1,3 +0,0 @@
TODO
- examples

View File

@ -0,0 +1,7 @@
compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
- uno
- leonardo
- due
- zero

View File

@ -0,0 +1,13 @@
---
name: Arduino CI
on: [push, pull_request]
jobs:
arduino_ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: Arduino-CI/action@master
# Arduino-CI/action@v0.1.1

View File

@ -0,0 +1,278 @@
//
// FILE: I2C_24LC1025.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.3
// PURPOSE: I2C_24LC1025 library for Arduino with EEPROM I2C_24LC1025 et al.
//
// HISTORY:
// 0.1.0 2019-12-11 initial version (not tested)
// 0.1.1 2021-01-20 major redo
// 0.1.2 2021-01-31 fix reading over 64K block border
// 0.1.3 2021-02-02 add updateBlock();
#include "I2C_24LC1025.h"
// TWI buffer needs max 2 bytes for eeprom address
// 1 byte for eeprom register address is available in txbuffer
#if defined(ESP32) || defined(ESP8266)
#define I2C_BUFFERSIZE 128
#else
#define I2C_BUFFERSIZE 30 // AVR, STM
#endif
////////////////////////////////////////////////////////////////////
//
// PUBLIC FUNCTIONS
//
I2C_24LC1025::I2C_24LC1025(uint8_t deviceAddress, TwoWire * wire)
{
_deviceAddress = deviceAddress;
_deviceSize = I2C_DEVICESIZE_24LC512;
_pageSize = I2C_24LC1025_PAGESIZE;
_wire = wire;
}
#if defined (ESP8266) || defined(ESP32)
bool I2C_24LC1025::begin(uint8_t sda, uint8_t scl)
{
if ((sda < 255) && (scl < 255))
{
_wire->begin(sda, scl);
}
else
{
_wire->begin();
}
_lastWrite = 0;
return isConnected();
}
#endif
bool I2C_24LC1025::begin()
{
_wire->begin();
_lastWrite = 0;
return isConnected();
}
bool I2C_24LC1025::isConnected()
{
_wire->beginTransmission(_deviceAddress);
return (_wire->endTransmission() == 0);
}
int I2C_24LC1025::writeByte(const uint32_t memoryAddress, const uint8_t value)
{
int rv = _WriteBlock(memoryAddress, &value, 1);
return rv;
}
int I2C_24LC1025::setBlock(const uint32_t memoryAddress, const uint8_t data, const uint32_t length)
{
uint8_t buffer[I2C_BUFFERSIZE];
for (uint8_t i = 0; i < I2C_BUFFERSIZE; i++)
{
buffer[i] = data;
}
int rv = _pageBlock(memoryAddress, buffer, length, false);
return rv;
}
int I2C_24LC1025::writeBlock(const uint32_t memoryAddress, const uint8_t* buffer, const uint32_t length)
{
int rv = _pageBlock(memoryAddress, buffer, length, true);
return rv;
}
uint8_t I2C_24LC1025::readByte(const uint32_t memoryAddress)
{
uint8_t rdata;
_ReadBlock(memoryAddress, &rdata, 1);
return rdata;
}
uint32_t I2C_24LC1025::readBlock(const uint32_t memoryAddress, uint8_t* buffer, const uint32_t length)
{
uint32_t addr = memoryAddress;
uint32_t len = length;
uint32_t rv = 0;
if ((addr < 0x10000) && ((addr + len) > 0x10000))
{
uint32_t sublen = 0x10000 - addr;
rv = readBlock(addr, (uint8_t *) buffer, sublen);
rv += readBlock(0x10000, (uint8_t *) &buffer[sublen], len - sublen);
return rv;
}
while (len > 0)
{
uint8_t cnt = I2C_BUFFERSIZE;
if (cnt > len) cnt = len;
rv += _ReadBlock(addr, buffer, cnt);
addr += cnt;
buffer += cnt;
len -= cnt;
yield(); // For OS scheduling etc
}
return rv;
}
int I2C_24LC1025::updateByte(const uint32_t memoryAddress, const uint8_t data)
{
if (data == readByte(memoryAddress)) return 0;
return writeByte(memoryAddress, data);
}
int I2C_24LC1025::updateBlock(const uint32_t memoryAddress, const uint8_t* buffer, const uint32_t length)
{
uint32_t addr = memoryAddress;
uint32_t len = length;
uint32_t rv = 0;
while (len > 0)
{
uint8_t buf[I2C_BUFFERSIZE];
uint8_t cnt = I2C_BUFFERSIZE;
if (cnt > len) cnt = len;
rv += _ReadBlock(addr, buf, cnt);
if (memcmp(buffer, buf, cnt) != 0)
{
_pageBlock(addr, buffer, cnt, true);
}
addr += cnt;
buffer += cnt;
len -= cnt;
yield(); // For OS scheduling etc
}
return rv;
}
////////////////////////////////////////////////////////////////////
//
// PRIVATE
//
// _pageBlock aligns buffer to page boundaries for writing.
// and to TWI buffer size
// returns 0 = OK otherwise error
int I2C_24LC1025::_pageBlock(uint32_t memoryAddress, const uint8_t * buffer, const uint16_t length, const bool incrBuffer)
{
uint32_t addr = memoryAddress;
uint16_t len = length;
while (len > 0)
{
uint8_t bytesUntilPageBoundary = this->_pageSize - addr % this->_pageSize;
uint8_t cnt = I2C_BUFFERSIZE;
if (cnt > len) cnt = len;
if (cnt > bytesUntilPageBoundary) cnt = bytesUntilPageBoundary;
int rv = _WriteBlock(addr, buffer, cnt);
if (rv != 0) return rv;
addr += cnt;
if (incrBuffer) buffer += cnt;
len -= cnt;
}
return 0;
}
void I2C_24LC1025::_beginTransmission(uint32_t memoryAddress)
{
// chapter 5+6 - datasheet - need three bytes for address
_actualAddress = _deviceAddress;
if (memoryAddress >= 0x10000) _actualAddress |= 0x04; // addresbit 16
#define I2C_WRITEDELAY 5000
// Wait until EEPROM gives ACK again.
// this is a bit faster than the hardcoded 5 milliSeconds // chapter 7
while ( (micros() - _lastWrite) <= I2C_WRITEDELAY )
{
_wire->beginTransmission(_actualAddress);
if (_wire->endTransmission() == 0) break;
yield();
delayMicroseconds(50);
}
uint16_t memAddr = (memoryAddress & 0xFFFF);
_wire->beginTransmission(_actualAddress); // device addres + bit 16
_wire->write((memAddr >> 8) & 0xFF); // highByte
_wire->write(memAddr & 0xFF); // lowByte
}
// pre: length <= this->_pageSize && length <= I2C_BUFFERSIZE;
// returns 0 = OK otherwise error
int I2C_24LC1025::_WriteBlock(uint32_t memoryAddress, const uint8_t* buffer, const uint8_t length)
{
yield();
this->_beginTransmission(memoryAddress);
_wire->write(buffer, length);
int rv = _wire->endTransmission();
_lastWrite = micros();
if (rv != 0)
{
if (_debug)
{
Serial.print("mem addr w: ");
Serial.print(memoryAddress, HEX);
Serial.print("\t");
Serial.println(rv);
}
return -(abs(rv)); // error
}
return rv;
}
// pre: buffer is large enough to hold length bytes
// returns bytes read
int I2C_24LC1025::_ReadBlock(uint32_t memoryAddress, uint8_t* buffer, const uint8_t length)
{
yield();
this->_beginTransmission(memoryAddress);
int rv = _wire->endTransmission();
if (rv != 0)
{
if (_debug)
{
Serial.print("mem addr r: ");
Serial.print(memoryAddress, HEX);
Serial.print("\t");
Serial.println(rv);
}
return -(abs(rv)); // error
}
// readbytes will always be equal or smaller to length
uint8_t readBytes = _wire->requestFrom(_actualAddress, length);
uint8_t cnt = 0;
while (cnt < readBytes)
{
buffer[cnt++] = _wire->read();
yield();
}
return readBytes;
}
// -- END OF FILE --

View File

@ -0,0 +1,82 @@
#pragma once
//
// FILE: I2C_24LC1025.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.3
// PURPOSE: I2C_24LC1025 library for Arduino with EEPROM 24FC1025 et al.
// HISTORY: See I2C_24LC1025.cpp
// URL: https://github.com/RobTillaart/I2C_24LC1025
#include "Arduino.h"
#include "Wire.h"
#define I2C_24LC1025_VERSION (F("0.1.3"))
#define I2C_DEVICESIZE_24LC512 131072
#define I2C_24LC1025_PAGESIZE 128
class I2C_24LC1025
{
public:
I2C_24LC1025(uint8_t deviceAddress, TwoWire *wire = &Wire);
#if defined (ESP8266) || defined(ESP32)
bool begin(uint8_t sda, uint8_t scl);
#endif
bool begin();
bool isConnected();
// writes a byte to memaddr
int writeByte(const uint32_t memoryAddress, const uint8_t value);
// writes length bytes from buffer to EEPROM
int writeBlock(const uint32_t memoryAddress, const uint8_t *buffer, const uint32_t length);
// set length bytes in the EEPROM to the same value.
int setBlock(const uint32_t memoryAddress, const uint8_t value, const uint32_t length);
// returns the value stored in memaddr
uint8_t readByte(const uint32_t memoryAddress);
// reads length bytes into buffer
uint32_t readBlock(const uint32_t memoryAddress, uint8_t *buffer, const uint32_t length);
// updates a byte at memory address, writes only if there is a new value.
// return 0 if data is same or written OK, error code otherwise.
int updateByte(const uint32_t memoryAddress, const uint8_t value);
// updates a block in memory, writes only if there is a new value.
// only to be used when you expect to write same buffer multiple times.
// test your performance gains!
int updateBlock(const uint32_t memoryAddress, const uint8_t* buffer, const uint32_t length);
uint32_t getDeviceSize() { return _deviceSize; };
uint8_t getPageSize() { return _pageSize; };
uint32_t getLastWrite() { return _lastWrite; };
private:
uint8_t _deviceAddress;
uint8_t _actualAddress; // a.k.a. controlByte
uint32_t _lastWrite;
uint32_t _deviceSize = I2C_DEVICESIZE_24LC512;
uint8_t _pageSize = I2C_24LC1025_PAGESIZE;
int _error; // TODO.
void _beginTransmission(uint32_t memoryAddress);
int _pageBlock(uint32_t memoryAddress, const uint8_t* buffer, const uint16_t length, const bool incrBuffer);
int _WriteBlock(uint32_t memoryAddress, const uint8_t* buffer, const uint8_t length);
int _ReadBlock(uint32_t memoryAddress, uint8_t* buffer, const uint8_t length);
TwoWire * _wire;
bool _debug = true;
};
// -- END OF FILE --

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021-2021 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
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,85 @@
[![Arduino CI](https://github.com/RobTillaart/I2C_24LC1025/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/I2C_24LC1025/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/I2C_24LC1025.svg?maxAge=3600)](https://github.com/RobTillaart/I2C_24LC1025/releases)
# I2C_24FC1025 - I2C 1MB EEPROM
Arduino library for for external I2C EEPROM - 24LC1025 and equivalents.
## Description
This library is to access external I2C EEPROM of 128 KB in size,
typically the 24LC1025 and equivalents.
**Warning**
A2 = Non-Configurable Chip Select.
This pin must be connected to VCC (+5V).
The device will **NOT** work when this pin floats or is connected to GND (0V).
## Interface
The interface is kept quite identical to the I2C_EEPROM library.
https://github.com/RobTillaart/I2C_EEPROM
Most important change is 32 bit memory addresses.
### Constructor
- **I2C_24LC1025(uint8_t deviceAddress, TwoWire \*wire = &Wire)** constructor, optional Wire interface
- **bool begin()** initializes the I2C bus and checks if the device is available on the I2C bus.
- **bool begin(uint8_t sda, uint8_t scl)** idem for ESP32 / ESP8266 and alike.
- **bool isConnected()** test to see if device is on the bus.
### Core functions
- **int writeByte(uint32_t memoryAddress, uint8_t value)** write a single byte to the specified memory address.
- **int updateByte(uint32_t memoryAddress, uint8_t value)** write a single byte, but only if changed. Returns 0 if value was same or write succeeded.
- **int writeBlock(uint32_t memoryAddress, uint8_t \* buffer, uint32_t length)** write a buffer starting at the specified memory address.
- **int updateBlock(uint32_t memoryAddress, uint8_t \* buffer, uint32_t length)** write a buffer starting at the specified memory address, but only if changed
- **int setBlock(uint32_t memoryAddress, uint8_t value, uint32_t length)** writes the same byte to length places starting at the specified memory address. Returns 0 if OK.
- **uint8_t readByte(uint32_t memoryAddress)** read a single byte from a given address
- **uint16_t readBlock(uint32_t memoryAddress, uint8_t \* buffer, uint32_t length)** read length bytes into buffer starting at specified memory address. Returns the number of bytes read, which should be length.
### Other
- **uint32_t getDeviceSize()** idem
- **uint8_t getPageSize()** idem
- **uint32_t getLastWrite()** idem
#### UpdateBlock()
(new since 0.1.3)
The function **updateBlock()** reads the block of data and compares it with the new values
to see if it needs rewriting.
As the function reads/writes the data in blocks with a maximum length of **I2C_TWIBUFFERSIZE**
(== 30 AVR limitation; 128 for ESP32) it does this comparison in chuncks if the length exceeds this number.
The result is that an **updateBlock()** call can result e.g. in 4 reads and only 2 writes under the hood.
If data is changed often between writes, **updateBlock()** is slower than **writeBlock()**.
So you should verify if your sketch can make use of the advantages of **updateBlock()**
## Limitation
The library does not offer multiple EEPROMS as one continuous storage device.
## Future
- See I2C EEPROM as this library is following.
## Operation
See examples

View File

@ -0,0 +1,44 @@
//
// FILE: 24LC1025_format.ino
// AUTHOR: Rob Tillaart
// PURPOSE: clear 24LC1025 EEPROM
// DATE: 2021-01-27
#include "I2C_24LC1025.h"
I2C_24LC1025 ee(0x50);
uint32_t start, stop;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
if (! ee.begin())
{
Serial.println("EEPROM not found...");
while (1);
}
Serial.println("Formatting takes 32 dots ( < 45 seconds).");
start = millis();
for (uint32_t i = 0; i < I2C_DEVICESIZE_24LC512; i+=128)
{
if (i % 0x1000 == 0) Serial.print('.');
ee.setBlock(i, 0x00, 128);
}
stop = millis();
Serial.print("\nTIME: \t");
Serial.println(stop - start);
Serial.println("\nDone...");
}
void loop()
{
}
// -- END OF FILE --

View File

@ -0,0 +1,96 @@
//
// FILE: 24LC1025_test.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo
// DATE: 2020
// (c) : MIT
//
#include "I2C_24LC1025.h"
I2C_24LC1025 ee(0x50);
uint32_t start, stop;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
if (! ee.begin())
{
Serial.println("EEPROM not found...");
while (1);
}
ee.writeByte(0, 21);
ee.writeByte(1, 22);
ee.writeByte(65536, 'A');
Serial.println(ee.readByte(0));
Serial.println(ee.readByte(65536));
start = micros();
dump(0x00, 0x0FFFF); // First block of 64K
stop = micros();
Serial.print("\nTIME: \t");
Serial.println(stop - start);
// dump(0xFFF0, 0x1000F);
// test(65530);
Serial.println("\nDone...");
}
void loop()
{
}
void dump(uint32_t from, uint32_t to)
{
for (uint32_t i = from; i < to; i++) // I2C_DEVICESIZE_24LC512
{
volatile int x = ee.readByte(i);
char buffer[24];
if (i % 16 == 0)
{
char buffer[24];
Serial.print('\n');
sprintf(buffer, "%08lX\t", i);
Serial.print(buffer);
}
sprintf(buffer, "%02X\t", ee.readByte(i));
Serial.print(buffer);
}
Serial.println();
}
void test(uint32_t offset)
{
Serial.println();
for (int i = 0; i < 10; i++)
{
ee.writeByte(offset + i, i);
Serial.println(offset + i);
delay(10);
}
for (int i = 0; i < 10; i++)
{
if (i % 10 == 0) Serial.print('\n');
Serial.print(ee.readByte(offset + i));
Serial.print('\t');
delay(10);
}
Serial.print('\n');
}
// -- END OF FILE --

View File

@ -0,0 +1,162 @@
//
// FILE: 24LC1025_test_read.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo
// DATE: 2020
// (c) : MIT
//
#include "I2C_24LC1025.h"
I2C_24LC1025 ee(0x50);
uint32_t start, stop;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
if (! ee.begin())
{
Serial.println("EEPROM not found...");
while (1);
}
Serial.println("\nwriting and reading in the low block");
ee.writeByte(0, 21);
ee.writeByte(1, 22);
Serial.println(ee.readByte(0));
Serial.println(ee.readByte(1));
Serial.println("\nwriting and reading in the high block");
ee.writeByte(65536, 'A');
Serial.println(ee.readByte(65536));
Serial.println("\nwriting and reading in the low block");
char buf1[24] = "aabbccddeeffgghhiijj";
char buf2[24];
ee.writeBlock(120, (uint8_t*) buf1, strlen(buf1) + 1);
dump(96, 160);
ee.readBlock(120, (uint8_t*) buf2, strlen(buf1) + 1);
Serial.println(buf2);
ee.setBlock(120, 42, strlen(buf1) + 1);
dump(96, 160);
Serial.println("\nwriting and reading in the high block");
char buf3[24] = "aabbccddeeffgghhiijj";
char buf4[24];
ee.writeBlock(0x10000 + 120, (uint8_t*) buf3, (uint32_t)strlen(buf3) + 1);
dump(0x10000 + 96, 0x10000 + 160);
ee.readBlock(0x10000 + 120, (uint8_t*) buf4, (uint32_t)strlen(buf3) + 1);
buf4[20] = 0;
Serial.println(buf4);
ee.setBlock(0x10000 + 120, 42, strlen(buf3) + 1);
dump(0x10000 + 96, 0x10000 + 160);
ee.readBlock(0x10000 + 120, (uint8_t*) buf4, strlen(buf3) + 1);
buf4[20] = 0;
Serial.println(buf4);
Serial.println("\nwriting over block boundary block");
ee.writeBlock(0xFFF0, (uint8_t *) "012345678901234567890123456789012345", (uint32_t) 32);
dump(0xFFE0, 0x10020);
char buf5[64];
ee.readBlock(0xFFF0, (uint8_t *)buf5, (uint32_t)32);
buf5[32] = 0;
Serial.println(buf5);
Serial.println("\nreadBlock timing 32 bytes");
start = micros();
ee.readBlock(0x0000, (uint8_t *)buf5, (uint32_t)32);
stop = micros();
Serial.print("TIME: \t");
Serial.println(stop - start);
delay(10);
start = micros();
ee.readBlock(0xFFF0, (uint8_t *)buf5, (uint32_t)32);
stop = micros();
Serial.print("TIME: \t");
Serial.println(stop - start);
delay(10);
start = micros();
ee.readBlock(0x1F0000, (uint8_t *)buf5, (uint32_t)32);
stop = micros();
Serial.print("TIME: \t");
Serial.println(stop - start);
delay(10);
/*
start = micros();
dump(0x00, 0x0FFFF); // First block of 64K
stop = micros();
Serial.print("\nTIME: \t");
Serial.println(stop - start);
*/
// dump(0xFFF0, 0x1000F);
// test(65530);
Serial.println("\nDone...");
}
void loop()
{
}
void dump(uint32_t from, uint32_t to)
{
for (uint32_t i = from; i < to; i++) // I2C_DEVICESIZE_24LC512
{
char buffer[24];
if (i % 16 == 0)
{
char buffer[24];
Serial.print('\n');
// sprintf(buffer, "%08X\t", i); // ESP cast (long unsigned int)
sprintf(buffer, "%08lX\t", i); // AVR needs lX
Serial.print(buffer);
}
sprintf(buffer, "%02X\t", ee.readByte(i));
Serial.print(buffer);
}
Serial.println();
}
void test(uint32_t offset)
{
Serial.println();
for (int i = 0; i < 10; i++)
{
ee.writeByte(offset + i, i);
Serial.println(offset + i);
delay(10);
}
for (int i = 0; i < 10; i++)
{
if (i % 10 == 0) Serial.print('\n');
Serial.print(ee.readByte(offset + i));
Serial.print('\t');
delay(10);
}
Serial.print('\n');
}
// -- END OF FILE --

View File

@ -0,0 +1,26 @@
# Syntax Coloring Map For I2C_24LC1025
# Datatypes (KEYWORD1)
I2C_24LC1025 KEYWORD1
# Methods and Functions (KEYWORD2)
begin KEYWORD2
isConnected KEYWORD2
# 24LC1025
readByte KEYWORD2
writeByte KEYWORD2
setBlock KEYWORD2
readBlock KEYWORD2
writeBlock KEYWORD2
updateByte KEYWORD2
getDeviceSize KEYWORD2
getPageSize KEYWORD2
getLastWrite KEYWORD2
# Constants (LITERAL1)

View File

@ -0,0 +1,21 @@
{
"name": "I2C_24LC1025",
"keywords": "24FC1025 24xx1025",
"description": "24FC1025 I2C EEPROM",
"authors":
[
{
"name": "Rob Tillaart",
"email": "Rob.Tillaart@gmail.com",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/RobTillaart/I2C_24LC1025"
},
"version":"0.1.3",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -0,0 +1,9 @@
name=I2C_24LC1025
version=0.1.3
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Library for 24FC1025 I2C EEPROM
paragraph=Class for 24FC1025 I2C EEPROM
category=Storage
url=https://github.com/RobTillaart/I2C_24LC1025
architectures=*

View File

@ -0,0 +1,61 @@
//
// FILE: unit_test_001.cpp
// AUTHOR: Rob Tillaart
// DATE: 2020-12-22
// PURPOSE: unit tests for the I2C_24LC1025 library
// https://github.com/RobTillaart/I2C_24LC1025
// https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md
//
// supported assertions
// ----------------------------
// assertEqual(expected, actual); // a == b
// assertNotEqual(unwanted, actual); // a != b
// assertComparativeEquivalent(expected, actual); // abs(a - b) == 0 or (!(a > b) && !(a < b))
// assertComparativeNotEquivalent(unwanted, actual); // abs(a - b) > 0 or ((a > b) || (a < b))
// assertLess(upperBound, actual); // a < b
// assertMore(lowerBound, actual); // a > b
// assertLessOrEqual(upperBound, actual); // a <= b
// assertMoreOrEqual(lowerBound, actual); // a >= b
// assertTrue(actual);
// assertFalse(actual);
// assertNull(actual);
// // special cases for floats
// assertEqualFloat(expected, actual, epsilon); // fabs(a - b) <= epsilon
// assertNotEqualFloat(unwanted, actual, epsilon); // fabs(a - b) >= epsilon
// assertInfinity(actual); // isinf(a)
// assertNotInfinity(actual); // !isinf(a)
// assertNAN(arg); // isnan(a)
// assertNotNAN(arg); // !isnan(a)
#include <ArduinoUnitTests.h>
#include "Arduino.h"
#include "I2C_24LC1025.h"
unittest_setup()
{
}
unittest_teardown()
{
}
unittest(test_constructor)
{
Wire.resetMocks();
I2C_24LC1025 EE(0x50);
assertTrue(EE.begin());
assertEqual(1, 1);
}
unittest_main()
// --------

View File

@ -1,7 +1,7 @@
//
// FILE: I2C_eeprom.cpp
// AUTHOR: Rob Tillaart
// VERSION: 1.4.1
// VERSION: 1.4.2
// PURPOSE: Arduino Library for external I2C EEPROM 24LC256 et al.
// URL: https://github.com/RobTillaart/I2C_EEPROM.git
//
@ -36,6 +36,7 @@
// See determineSize for all tested.
// 1.4.1 2021-01-28 fixed addressing bug 24LC04/08/16 equivalents from ST e.g. m24c08w
// add Wire1..WireN;
// 1.4.2 2021-01-31 add updateBlock()
#include <I2C_eeprom.h>
@ -169,6 +170,30 @@ int I2C_eeprom::updateByte(const uint16_t memoryAddress, const uint8_t data)
return writeByte(memoryAddress, data);
}
int I2C_eeprom::updateBlock(const uint16_t memoryAddress, const uint8_t* buffer, const uint16_t length)
{
uint16_t addr = memoryAddress;
uint16_t len = length;
uint16_t rv = 0;
while (len > 0)
{
uint8_t buf[I2C_TWIBUFFERSIZE];
uint8_t cnt = I2C_TWIBUFFERSIZE;
if (cnt > len) cnt = len;
rv += _ReadBlock(addr, buf, cnt);
if (memcmp(buffer, buf, cnt) != 0)
{
_pageBlock(addr, buffer, cnt, true);
}
addr += cnt;
buffer += cnt;
len -= cnt;
yield(); // For OS scheduling etc
}
return rv;
}
// returns size in bytes
// returns 0 if not connected

View File

@ -2,7 +2,7 @@
//
// FILE: I2C_eeprom.h
// AUTHOR: Rob Tillaart
// VERSION: 1.4.1
// VERSION: 1.4.2
// PURPOSE: Arduino Library for external I2C EEPROM 24LC256 et al.
// URL: https://github.com/RobTillaart/I2C_EEPROM.git
//
@ -13,7 +13,7 @@
#include "Wire.h"
#define I2C_EEPROM_VERSION (F("1.4.1"))
#define I2C_EEPROM_VERSION (F("1.4.2"))
#define I2C_DEVICESIZE_24LC512 65536
@ -76,6 +76,10 @@ public:
// updates a byte at memory address, writes only if there is a new value.
// return 0 if data is same or written OK, error code otherwise.
int updateByte(const uint16_t memoryAddress, const uint8_t value);
// updates a block in memory, writes only if there is a new value.
// only to be used when you expect to write same buffer multiple times.
// test your performance gains!
int updateBlock(const uint16_t memoryAddress, const uint8_t* buffer, const uint16_t length);
uint32_t determineSize(const bool debug = false);

View File

@ -0,0 +1,77 @@
D:\Rob\WORK\Arduino\libraries\I2C_EEPROM\examples\I2C_eeprom_updateBlock\I2C_eeprom_updateBlock.ino
VERSION: 1.4.1
1
TEST: writeBlock() 32840
TEST: readBlock() 11792
TEST: updateBlock() 44672
2
TEST: writeBlock() 65720
TEST: readBlock() 23588
TEST: updateBlock() 60764
3
TEST: writeBlock() 98544
TEST: readBlock() 35384
TEST: updateBlock() 72628
4
TEST: writeBlock() 131348
TEST: readBlock() 47172
TEST: updateBlock() 84464
5
TEST: writeBlock() 164200
TEST: readBlock() 58976
TEST: updateBlock() 96340
6
TEST: writeBlock() 197068
TEST: readBlock() 70756
TEST: updateBlock() 108236
7
TEST: writeBlock() 229872
TEST: readBlock() 82576
TEST: updateBlock() 120072
8
TEST: writeBlock() 262684
TEST: readBlock() 94352
TEST: updateBlock() 131952
9
TEST: writeBlock() 295568
TEST: readBlock() 106144
TEST: updateBlock() 143808
10
TEST: writeBlock() 328388
TEST: readBlock() 117928
TEST: updateBlock() 155688
TEST: 100x writeBlock()
DUR1: 3284020
00000000 64 63 62 61 60 5F 5E 5D 5C 5B 5A 59 58 57 56 55
00000010 54 53 52 51 50 4F 4E 4D 4C 4B 4A 49 48 47 46 45
00000020 44 43 42 41 40 3F 3E 3D 3C 3B 3A 39 38 37 36 35
00000030 34 33 32 31 30 2F 2E 2D 2C 2B 2A 29 28 27 26 25
00000040 24 23 22 21 20 1F 1E 1D 1C 1B 1A 19 18 17 16 15
00000050 14 13 12 11 10 0F 0E 0D 0C 0B 0A 09 08 07 06 05
00000060 04 03 02 01
TEST: 100x updateBlock()
DUR2: 1223896
00000000 64 63 62 61 60 5F 5E 5D 5C 5B 5A 59 58 57 56 55
00000010 54 53 52 51 50 4F 4E 4D 4C 4B 4A 49 48 47 46 45
00000020 44 43 42 41 40 3F 3E 3D 3C 3B 3A 39 38 37 36 35
00000030 34 33 32 31 30 2F 2E 2D 2C 2B 2A 29 28 27 26 25
00000040 24 23 22 21 20 1F 1E 1D 1C 1B 1A 19 18 17 16 15
00000050 14 13 12 11 10 0F 0E 0D 0C 0B 0A 09 08 07 06 05
00000060 04 03 02 01
done...

View File

@ -0,0 +1,139 @@
//
// FILE: I2C_eeprom_updateBlock.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo I2C_EEPROM library - performance gain updateBlock
//
// uses a 24LC256 (32KB) EEPROM
// as this test writes a lot it might wear out EEPROMs eventually.
//
#include "Wire.h"
#include "I2C_eeprom.h"
I2C_eeprom ee(0x50, I2C_DEVICESIZE_24LC256);
uint32_t start, dur1, dur2;
uint8_t ar[100];
void setup()
{
Serial.begin(115200);
while (!Serial); // wait for SERIAL_OUT port to connect. Needed for Leonardo only
Serial.println(__FILE__);
Serial.print("VERSION: ");
Serial.println(I2C_EEPROM_VERSION);
Serial.println();
ee.begin();
if (! ee.isConnected())
{
Serial.println("ERROR: Can't find eeprom\nstopped...");
while (1);
}
for (int i = 0; i < 100; i++) ar[i] = 100 - i;
for (int i = 1; i < 11; i++)
{
test_1(i);
}
test_2();
Serial.println("\ndone...");
}
void loop()
{
}
void test_1(int n)
{
Serial.println(n);
Serial.print("TEST:\twriteBlock()");
delay(10);
ee.setBlock(0, 0, 100); // clear first 100 bytes
start = micros();
for (int i = 0; i < n; i++) ee.writeBlock(0, ar, 100);
dur1 = micros() - start;
Serial.print("\t");
Serial.println(dur1);
delay(10);
Serial.print("TEST:\treadBlock()");
delay(10);
start = micros();
for (int i = 0; i < n; i++) ee.readBlock(0, ar, 100);
dur1 = micros() - start;
Serial.print("\t");
Serial.println(dur1);
delay(10);
Serial.print("TEST:\tupdateBlock()");
delay(10);
ee.setBlock(0, 0, 100); // clear first 100 bytes
start = micros();
for (int i = 0; i < n; i++) ee.updateBlock(0, ar, 100);
dur1 = micros() - start;
Serial.print("\t");
Serial.println(dur1);
delay(10);
Serial.println();
}
void test_2()
{
Serial.println("\nTEST: 100x writeBlock()");
delay(10);
ee.setBlock(0, 0, 100); // clear first 100 bytes
start = micros();
for (int i = 0; i < 100; i++)
{
ee.writeBlock(0, ar, 100);
}
dur1 = micros() - start;
Serial.print("DUR1: ");
Serial.println(dur1);
dump(0, 100);
delay(100);
Serial.println("\nTEST: 100x updateBlock()");
ee.setBlock(0, 0, 100); // clear first 100 bytes
start = micros();
for (int i = 0; i < 100; i++)
{
ee.updateBlock(0, ar, 100);
}
dur2 = micros() - start;
Serial.print("DUR2: ");
Serial.println(dur2);
dump(0, 100);
delay(100);
}
void dump(uint32_t from, uint32_t to)
{
for (uint32_t i = from; i < to; i++) // I2C_DEVICESIZE_24LC512
{
char buffer[24];
if (i % 16 == 0)
{
char buffer[24];
Serial.print('\n');
sprintf(buffer, "%08lX\t", i);
Serial.print(buffer);
}
sprintf(buffer, "%02X\t", ee.readByte(i));
Serial.print(buffer);
}
Serial.println();
}
// -- END OF FILE

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/I2C_EEPROM.git"
},
"version":"1.4.1",
"version":"1.4.2",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -1,5 +1,5 @@
name=I2C_EEPROM
version=1.4.1
version=1.4.2
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Library for I2C EEPROMS

View File

@ -32,6 +32,7 @@ The **I2C_eeprom_cyclic_store** interface is documented [here](README_cyclic_sto
- **int writeByte(uint16_t memoryAddress, uint8_t value)** write a single byte to the specified memory address.
- **int updateByte(uint16_t memoryAddress, uint8_t value)** write a single byte, but only if changed. Returns 0 if value was same or write succeeded.
- **int writeBlock(uint16_t memoryAddress, uint8_t \* buffer, uint16_t length)** write a buffer starting at the specified memory address.
- **int updateBlock(uint16_t memoryAddress, uint8_t \* buffer, uint16_t length)** write a buffer starting at the specified memory address, but only if changed
- **int setBlock(uint16_t memoryAddress, uint8_t value, uint16_t length)** writes the same byte to length places starting at the specified memory address. Returns 0 if OK.
- **uint8_t readByte(uint16_t memoryAddress)** read a single byte from a given address
- **uint16_t readBlock(uint16_t memoryAddress, uint8_t \* buffer, uint16_t length)** read length bytes into buffer starting at specified memory address. Returns the number of bytes read, which should be length.
@ -69,6 +70,18 @@ Testresults
The function cannot detect smaller than 128 bit EEPROMS.
#### UpdateBlock()
(new since 1.4.2)
The function **updateBlock()** reads the block of data and compares it with the new values to see if it needs rewriting.
As the function reads/writes the data in blocks with a maximum length of **I2C_TWIBUFFERSIZE** (== 30 AVR limitation) it does this comparison in chuncks if the length exceeds this number. The result is that an **updateBlock()** call can result e.g. in 4 reads and only 2 writes under the hood.
If data is changed often between writes, **updateBlock()** is slower than **writeBlock()**.
So you should verify if your sketch can make use of the advantages of **updateBlock()**
## Limitation
The library does not offer multiple EEPROMS as one continuous storage device.
@ -79,6 +92,7 @@ The library does not offer multiple EEPROMS as one continuous storage device.
- improve error handling, write functions should return bytes written or so.
- what can we do with the print interface? (investigate)
- investigate multi-EEPROM storage,
- investigate smarter strategy for updateBlock() => find first and last changed position would possibly result in less writes.
## Operational

View File

@ -1,19 +0,0 @@
notes on PCF8574
2015-11-29 - 0.1.04
======================
On some platforms (reported on an ESP8266) the PCF8574 constructor is causing problems e.g. continuous reboots.
This is caused by the call to Wire.begin() in the constructor of the PCF8574 object. It might be called before
the Wire object is created, especially when both are global objects the order of instantiating might differ.
Solution is moving the call to Wire.begin() from the constructor to void setup() before any call to an PCF8574 object.
FIXED in 0.1.08 @ 2016-05-20
2016-07-26 note on adress ranges
==================================
from https://github.com/RobTillaart/Arduino/issues/44
- TYPE ADDRESS-RANGE
- PCF8574 0x20 to 0x27,
- PCF8574A 0x38 to 0x3F