remove duplicates + minor

This commit is contained in:
rob tillaart 2021-02-06 15:52:51 +01:00
parent e5bc4a1d9a
commit f9cf7e8124
125 changed files with 492 additions and 6649 deletions

View File

@ -1,233 +0,0 @@
//
// FILE: BH1750FVI.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.4
// PURPOSE: library for BH1750FVI lux sensor Arduino
// URL: https://github.com/RobTillaart/BH1750FVI
//
// 0.1.0 2020-02-02 initial version
// 0.1.1 2020-03-28 refactor
// 0.1.2 2020-03-29 unique name in repo, and new release tag.
// 0.1.3 2020-06-05 fix library.json file
// 0.1.4 2020-08-14 cleanup tabs/spaces;
// 0.2.0 2020-08-18 implement logic for LOW & HIGH2;
// implement correctionfactor; examples;
// 0.2.1 2020-08-31 implement angle factor
// 0.2.2 2020-09-04 implement temperature compensation
// 0.2.3 2020-09-04 implement wavelength compensation
// 0.2.4 2020-11-27 fix #10 rename _sensitivityFactor for ESP32
#include "BH1750FVI.h"
#if defined(ESP8266) || defined(ESP32)
BH1750FVI::BH1750FVI(const uint8_t address, const uint8_t dataPin, const uint8_t clockPin)
{
_address = address;
_data = 0;
_error = BH1750FVI_OK;
_sensitivityFactor = BH1750FVI_REFERENCE_TIME;
_mode = BH1750FVI_MODE_HIGH;
_wire = &Wire;
if ((dataPin < 255) && (clockPin < 255))
{
_wire->begin(dataPin, clockPin);
} else {
_wire->begin();
}
}
#endif
BH1750FVI::BH1750FVI(const uint8_t address, TwoWire *wire)
{
_address = address;
_data = 0;
_error = BH1750FVI_OK;
_sensitivityFactor = BH1750FVI_REFERENCE_TIME; // P11
_mode = BH1750FVI_MODE_HIGH;
_wire = wire;
_wire->begin();
}
bool BH1750FVI::isReady()
{
// max times from datasheet P2 + P11;
uint8_t timeout[3] = { 16, 120, 120 };
if (_mode < 3)
{
float f = timeout[_mode] * _sensitivityFactor / BH1750FVI_REFERENCE_TIME;
return (millis() - _requestTime) > f;
}
return false;
}
float BH1750FVI::getRaw(void)
{
return readData() * 0.833333333333f; // == 1 / 1.2;
}
float BH1750FVI::getLux(void)
{
// lux without mode correction
float lux = getRaw();
// sensitivity factor
if (_sensitivityFactor != BH1750FVI_REFERENCE_TIME)
{
lux *= (1.0 * BH1750FVI_REFERENCE_TIME) / _sensitivityFactor;
}
// angle compensation
if (_angle != 0)
{
lux *= _angleFactor;
}
// temperature compensation.
if (_temp != 20)
{
float tempFactor = 1.0f - (_temp - 20.0f) / 2000.0f;
lux *= tempFactor;
}
// wavelength compensation.
if (_waveLength != 580)
{
lux *= _waveLengthFactor;
}
if (_mode == BH1750FVI_MODE_HIGH2)
{
lux *= 0.5f; // P11
}
return lux;
}
int BH1750FVI::getError()
{
int e = _error;
_error = BH1750FVI_OK;
return e;
}
////////////////////////////////////////////
//
// operational mode
//
void BH1750FVI::setContHighRes()
{
_mode = BH1750FVI_MODE_HIGH;
command(BH1750FVI_CONT_HIGH);
_requestTime = millis();
};
void BH1750FVI::setContHigh2Res()
{
_mode = BH1750FVI_MODE_HIGH2;
command(BH1750FVI_CONT_HIGH2);
_requestTime = millis();
};
void BH1750FVI::setContLowRes()
{
_mode = BH1750FVI_MODE_LOW;
command(BH1750FVI_CONT_LOW);
_requestTime = millis();
};
void BH1750FVI::setOnceHighRes()
{
_mode = BH1750FVI_MODE_HIGH;
command(BH1750FVI_ONCE_HIGH);
_requestTime = millis();
};
void BH1750FVI::setOnceHigh2Res()
{
_mode = BH1750FVI_MODE_HIGH2;
command(BH1750FVI_ONCE_HIGH2);
_requestTime = millis();
};
void BH1750FVI::setOnceLowRes()
{
_mode = BH1750FVI_MODE_LOW;
command(BH1750FVI_ONCE_LOW);
_requestTime = millis();
};
////////////////////////////////////////////
//
// measurement timing
//
// P11 datasheet
void BH1750FVI::changeTiming(uint8_t val)
{
val = constrain(val, 31, 254);
_sensitivityFactor = val;
// P5 instruction set table
uint8_t Hbits = 0x40 | (val >> 5);
uint8_t Lbits = 0x60 | (val & 0x1F);
command(Hbits);
command(Lbits);
}
void BH1750FVI::setCorrectionFactor(float f)
{
// 31 .. 254 are range P11 - constrained in changeTIming call
uint8_t timingValue = round(BH1750FVI_REFERENCE_TIME * f);
changeTiming(timingValue);
}
float BH1750FVI::getCorrectionFactor()
{
float f = 1.0f / BH1750FVI_REFERENCE_TIME;
return _sensitivityFactor * f;
}
void BH1750FVI::setAngle(int degrees)
{
_angle = constrain(degrees, -89, 89);
// Lamberts Law.
_angleFactor = 1.0f / cos(_angle * (PI / 180.0f));
}
// interpolation tables uses more RAM (versus progmem)
void BH1750FVI::setWaveLength(int waveLength)
{
_waveLength = constrain(waveLength, 400, 715);
float tmp = 1.0f;
if (_waveLength < 440) tmp = 0.01f + (_waveLength - 400) * 0.09f / 40.0f;
else if (_waveLength < 510) tmp = 0.10f + (_waveLength - 440) * 0.80f / 70.0f;
else if (_waveLength < 545) tmp = 0.90f - (_waveLength - 510) * 0.10f / 35.0f;
else if (_waveLength < 580) tmp = 0.80f + (_waveLength - 545) * 0.20f / 35.0f;
else if (_waveLength < 700) tmp = 1.00f - (_waveLength - 580) * 0.93f / 120.0f;
else if (_waveLength < 715) tmp = 0.07f - (_waveLength - 700) * 0.07f / 15.0f;
else if (_waveLength == 715) tmp = 0.01f;
_waveLengthFactor = 1.0f / tmp;
}
///////////////////////////////////////////////////////////
//
// PRIVATE
//
uint16_t BH1750FVI::readData()
{
if (_wire->requestFrom(_address, (uint8_t) 2) != 2)
{
_error = BH1750FVI_ERROR_WIRE_REQUEST;
return _data; // last value
}
_data = _wire->read();
_data <<= 8;
_data += _wire->read();
return _data;
}
void BH1750FVI::command(uint8_t value)
{
_wire->beginTransmission(_address);
_wire->write(value);
_error = _wire->endTransmission();
}
// --- END OF FILE ---

View File

@ -1,133 +0,0 @@
#pragma once
//
// FILE: BH1750FVI_H.h
// AUTHOR: Rob dot Tillaart at gmail dot com
// VERSION: 0.2.4
// PURPOSE: Arduino library for BH1750FVI (GY-30) lux sensor
// HISTORY: See BH1750FVI.cpp
//
// breakout BH1750FVI / GY-30
//
// +-----------------------+
// GND |o |
// ADD |o |
// SDA |o + | + = sensor
// SCL |o |
// VCC |o |
// +-----------------------+
//
// ADD = ADDRESS:
// 0 = 0x23
// 1 = 0x5C
//
#include "Wire.h"
#include "Arduino.h"
#define BH1750FVI_LIB_VERSION "0.2.4"
#define BH1750FVI_DEFAULT_ADDRESS 0x23
#define BH1750FVI_ALT_ADDRESS 0x5C
// COMMANDS P5
#define BH1750FVI_POWER_ON 0x00
#define BH1750FVI_POWER_OFF 0x01
#define BH1750FVI_RESET 0x07
#define BH1750FVI_CONT_HIGH 0x10
#define BH1750FVI_CONT_HIGH2 0x11
#define BH1750FVI_CONT_LOW 0x13
#define BH1750FVI_ONCE_HIGH 0x20
#define BH1750FVI_ONCE_HIGH2 0x21
#define BH1750FVI_ONCE_LOW 0x23
#define BH1750FVI_REFERENCE_TIME 0x45 // 69
#define BH1750FVI_MODE_LOW 0x00
#define BH1750FVI_MODE_HIGH 0x01
#define BH1750FVI_MODE_HIGH2 0x02
// ERROR CODES
#define BH1750FVI_OK 0
#define BH1750FVI_ERROR_WIRE_REQUEST -10
class BH1750FVI
{
public:
#if defined(ESP8266) || defined(ESP32)
// dataPin and clockPin can be used for ESP8266
BH1750FVI(const uint8_t address , const uint8_t dataPin, const uint8_t clockPin);
#endif
BH1750FVI(const uint8_t address, TwoWire *wire = &Wire);
float getRaw(); // no HIGH2 mode + no sensitivity factor.
float getLux();
int getError();
void powerOn() { command(BH1750FVI_POWER_ON); };
void powerOff() { command(BH1750FVI_POWER_OFF); };
void reset() { command(BH1750FVI_RESET); };
// MODE TIME RESOLUTION
// 2 HIGH2 120 ms 0.5 lux // recommended max * 1.5 = 180 ms
// 1 HIGH 120 ms 1.0 lux
// 0 LOW 16 ms 4.0 lux
uint8_t getMode() { return _mode; };
void setContHighRes();
void setContHigh2Res();
void setContLowRes();
void setOnceHighRes();
void setOnceHigh2Res();
void setOnceLowRes();
bool isReady(); // only after setOnce...Res();
// read datasheet P11 about details of the correction or sensitivity factor
// to be used for very high and very low brightness
// or to correct for e.g. transparancy
void changeTiming(uint8_t val); // 69 is default = BH1750FVI_REFERENCE_TIME
void setCorrectionFactor(float f); // 0.45 .. 3.68
float getCorrectionFactor();
// read datasheet P3 and check figure 4 and 5.
// setAngle is constrained to -89..+89
void setAngle(int degrees);
int getAngle() { return _angle; };
// datasheet P3 figure 7
// Effect of temperature is about 3% / 60°C ~~ 1% / 20°C
// to be used if temp is really hot or cold.
void setTemperature(int temp) { _temp = temp; };
int getTemperature() { return _temp; };
// datasheet Page 3 figure 1 (experimental correction)
// Effect of wavelength can be substantial,
// correctionfactor is calculated by multiple linear approximations.
void setWaveLength(int waveLength);
int getWaveLength() { return _waveLength; };
private:
uint16_t readData();
void command(uint8_t value);
uint8_t _address;
uint16_t _data;
int _error;
uint8_t _sensitivityFactor;
uint8_t _mode;
uint32_t _requestTime = 0;
float _angleFactor = 1;
int _angle = 0;
int _temp = 20;
float _waveLengthFactor = 1;
int _waveLength = 580;
TwoWire* _wire;
};
// -- END OF FILE --

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2020 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

@ -1,94 +0,0 @@
//
// FILE: BH1750FVI_angle_measurement.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// PURPOSE: demo of BH1750FVI lux scanner library
// DATE: 2020-08-31
//
/*
BH1750FVI_angle_measurement
Experimental application
first take a reference measurement for 5 seconds
holding the sensor flat under a light source.
Then take a second reference for 5 seconds
holding the sensor at 90 degrees.
Thereafter hold the sensor at any angle and the
Arduino will estimate the angle based upon the
Lux level compared to the references.
First trials are not not too bad, roughly within 15° accuracy
*/
#include "BH1750FVI.h"
BH1750FVI myLux(0x23);
float ref1 = 0;
float ref2 = 0;
float measure(int seconds, bool minimum = false)
{
float mn = 1e8;
float mx = 0;
uint32_t start = millis();
while (millis() - start < (seconds * 1000UL))
{
float val = myLux.getLux();
if (val > mx) mx = val;
if (val < mn) mn = val;
delay(200);
}
if (minimum) return mn;
return mx;
}
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.print(__FILE__);
Serial.println();
Wire.begin();
myLux.powerOn();
myLux.setContHighRes();
Serial.println("Reference 1");
ref1 = measure(5, false);
Serial.println("Reference 2");
ref2 = measure(5, true);
Serial.println("Start");
Serial.println(ref1);
Serial.println(ref2);
}
void loop()
{
float val = measure(1, false);
val = map(val, ref2, ref1, 0, ref1); // does not constrain...
// prevent NAN
float f = val / ref1; // map to 0..1
if (f > 1) f = 1; // constrain upper
if (f < -1) f = -1; // constrain lower
Serial.print(val, 1);
Serial.print("\t");
Serial.print(f);
Serial.print("\t");
Serial.print(acos(f) * 180 / PI);
Serial.print("\t");
Serial.println();
}
// -- END OF FILE --

View File

@ -1,18 +0,0 @@
/*
BH1750FVI_angle_measurement.ino
Experimental application
first take a reference measurement for 5 seconds
holding the sensor flat under a light source.
Then take a second reference for 5 seconds
holding the sensor at 90 degrees.
Thereafter hold the sensor at any angle and the
Arduino will estimate the angle based upon the
Lux level compared to the references.
First trials are not not too bad, roughly within 15° accuracy
*/

View File

@ -1,65 +0,0 @@
//
// FILE: BH1750FVI_async.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo of BH1750FVI lux scanner library
// DATE: 2020-08-20
//
#include "BH1750FVI.h"
BH1750FVI myLux(0x23);
float correctionFactor = 0.45; // min value see datasheet
uint32_t count = 0;
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.print(__FILE__);
Serial.println();
Wire.begin();
myLux.powerOn();
myLux.setContHighRes();
}
void loop()
{
if (myLux.isReady())
{
float val = myLux.getLux();
if (count % 20 == 0)
{
Serial.println("\nCNT \tLUX \tMODE \tFACTOR \tRAWLUX");
}
Serial.print(count);
Serial.print("\t");
Serial.print(val, 1);
Serial.print("\t");
Serial.print(myLux.getMode());
Serial.print("\t");
Serial.print(myLux.getCorrectionFactor(), 2);
Serial.print("\t");
Serial.println(val / myLux.getCorrectionFactor(), 1);
// note correctionfactor are steps of 1/69 internally, see datasheet
correctionFactor += 0.05;
if (correctionFactor > 3.68) // 0.45 - 3.68 = 45 steps of 0.05
{
correctionFactor = 0.45;
Serial.println();
}
myLux.setCorrectionFactor(correctionFactor); // 0.45 .. 3.68
count++;
}
delay(1000);
// do other things here
}
// -- END OF FILE --

View File

@ -1,44 +0,0 @@
//
// FILE: BH1750FVI_cont_high_res.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo of BH1750FVI lux scanner library
// DATE: 2020-02-02
//
// This is a minimal version, which can be optimized by
// using mylux.getRaw() instead of myLux.getLux(); line38
// gain on UNO: ~350 bytes smaller
#include "BH1750FVI.h"
BH1750FVI myLux(0x23);
uint32_t lastUpdate = 0;
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.print(__FILE__);
Serial.println();
Wire.begin();
myLux.powerOn();
myLux.setContHighRes();
}
void loop()
{
uint16_t interval = 100;
if (millis() - lastUpdate >= interval)
{
lastUpdate += interval;
float val = myLux.getLux();
Serial.println(val, 1);
}
}
// -- END OF FILE --

View File

@ -1,43 +0,0 @@
//
// FILE: BH1750FVI_cont_low_res.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// PURPOSE: demo of BH1750FVI lux scanner library
// DATE: 2020-02-02
//
// Released to the public domain
//
#include "BH1750FVI.h"
BH1750FVI myLux(0x23);
uint32_t lastUpdate = 0;
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.print(__FILE__);
Serial.println();
Wire.begin();
myLux.powerOn();
myLux.setContLowRes();
}
void loop()
{
uint16_t interval = 100;
if (millis() - lastUpdate >= interval)
{
lastUpdate += interval;
float val = myLux.getLux();
Serial.println(val, 1);
}
}
// END OF FILE

View File

@ -1,43 +0,0 @@
//
// FILE: BH1750FVI_setAngle.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo of BH1750FVI lux scanner library
// DATE: 2020-08-31
//
#include "BH1750FVI.h"
BH1750FVI myLux(0x23);
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.print(__FILE__);
Serial.println();
Wire.begin();
myLux.powerOn();
myLux.setContHighRes();
}
void loop()
{
for (int x = -90; x < 90; x += 1)
{
myLux.setAngle(x);
float val = myLux.getLux();
Serial.print(val, 1);
Serial.print("\t");
Serial.print(myLux.getAngle());
Serial.print("\t");
Serial.println();
delay(20);
}
Serial.println();
}
// -- END OF FILE --

View File

@ -1,55 +0,0 @@
//
// FILE: setCorrectionFactor.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// PURPOSE: demo of BH1750FVI lux scanner library
// DATE: 2020-02-02
//
#include "BH1750FVI.h"
BH1750FVI myLux(0x23);
uint32_t lastUpdate = 0;
float correctionFactor = 0.45; // min value see datasheet
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.print(__FILE__);
Serial.println();
Wire.begin();
myLux.powerOn();
myLux.setContHighRes();
}
void loop()
{
uint16_t interval = 180; // max time see datasheet P2
if (millis() - lastUpdate >= interval)
{
lastUpdate += interval;
float val = myLux.getLux();
Serial.print(val, 1);
Serial.print("\t");
Serial.print(myLux.getCorrectionFactor(), 3);
Serial.print("\t");
Serial.println(val / myLux.getCorrectionFactor(), 1);
// note correctionfactor are steps of 1/69 internally, see datasheet
myLux.setCorrectionFactor(correctionFactor); // 0.45 .. 3.68
correctionFactor += 0.05;
if (correctionFactor > 3.68)
{
correctionFactor = 0.45;
Serial.println();
}
}
}
// -- END OF FILE --

View File

@ -1,44 +0,0 @@
//
// FILE: BH1750FVI_setTemperature.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo of BH1750FVI lux scanner library
// DATE: 2020-09-04
//
#include "BH1750FVI.h"
BH1750FVI myLux(0x23);
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.print(__FILE__);
Serial.println();
Wire.begin();
myLux.powerOn();
myLux.setContHighRes();
}
void loop()
{
for (int t = -60; t < 100; t += 10)
{
myLux.setTemperature(t);
float val = myLux.getLux();
Serial.print(val, 1);
Serial.print("\t");
Serial.print(myLux.getTemperature());
Serial.print("\t");
Serial.println();
delay(20);
}
Serial.println();
delay(1000);
}
// -- END OF FILE --

View File

@ -1,47 +0,0 @@
//
// FILE: BH1750FVI_setWaveLength.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo of BH1750FVI lux scanner library
// DATE: 2020-09-04
//
#include "BH1750FVI.h"
BH1750FVI myLux(0x23);
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.print(__FILE__);
Serial.println();
Wire.begin();
myLux.powerOn();
myLux.setContHighRes();
for (int wl = 400; wl < 715; wl++)
{
myLux.setWaveLength(wl);
float val = myLux.getLux();
Serial.print(val, 1);
Serial.print("\t");
Serial.print(myLux.getWaveLength());
Serial.print("\t");
Serial.println();
delay(20);
}
Serial.println();
delay(1000);
}
void loop()
{
}
// -- END OF FILE --

View File

@ -1,64 +0,0 @@
//
// FILE: BH1750FVI_single_shot_3_res.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo of BH1750FVI lux scanner library
// DATE: 2020-08-20
//
#include "BH1750FVI.h"
BH1750FVI myLux(0x23);
uint32_t lastUpdate = 0;
float val;
uint32_t count = 0;
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.print(__FILE__);
Serial.println();
Wire.begin();
myLux.powerOn();
myLux.setContLowRes();
}
void loop()
{
if (count % 20 == 0)
{
Serial.println("\nLOW \tHIGH \tHIGH2 \tRAW");
}
count++;
myLux.setOnceLowRes();
delay(200);
val = myLux.getLux();
Serial.print(val, 1);
Serial.print('\t');
myLux.setOnceHighRes();
delay(200);
val = myLux.getLux();
Serial.print(val, 1);
Serial.print('\t');
myLux.setOnceHigh2Res();
delay(200);
val = myLux.getLux();
Serial.print(val, 1);
Serial.print('\t');
myLux.setOnceHighRes();
delay(200);
val = myLux.getRaw();
Serial.print(val, 1);
Serial.print('\t');
Serial.println();
}
// -- END OF FILE --

View File

@ -1,37 +0,0 @@
# Syntax Coloring Map For BH1750FVI
# Datatypes (KEYWORD1)
BH1750FVI KEYWORD1
# Methods and Functions (KEYWORD2)
getRaw KEYWORD2
getLux KEYWORD2
getError KEYWORD2
powerOn KEYWORD2
powerOff KEYWORD2
reset KEYWORD2
setContHighRes KEYWORD2
setContHigh2Res KEYWORD2
setContLowRes KEYWORD2
setOnceHighRes KEYWORD2
setOnceHigh2Res KEYWORD2
setOnceLowRes KEYWORD2
isReady KEYWORD2
changeTiming KEYWORD2
setCorrectionFactor KEYWORD2
getCorrectionFactor KEYWORD2
setAngle KEYWORD2
getAngle KEYWORD2
setTemperature KEYWORD2
getTemperature KEYWORD2
setWaveLength KEYWORD2
getWaveLength KEYWORD2
# Instances (KEYWORD2)
# Constants (LITERAL1)

View File

@ -1,21 +0,0 @@
{
"name": "BH1750FVI_RT",
"keywords": "BH1750FVI, BH1750, Lux, light, GY-30, GY30",
"description": "Arduino library for BH1750FVI (GY-30) lux sensor. Includes compensation for angle, temperature and (experimental) wavelength.",
"authors":
[
{
"name": "Rob Tillaart",
"email": "Rob.Tillaart@gmail.com",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/RobTillaart/BH1750FVI_RT.git"
},
"version": "0.2.4",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -1,11 +0,0 @@
name=BH1750FVI_RT
version=0.2.4
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for BH1750FVI (GY-30) lux sensor
paragraph=Includes compensation for angle, temperature and (experimental) wavelength.
category=Sensors
url=https://github.com/RobTillaart/BH1750FVI_RT
architectures=*
includes=BH1750FVI.h
depends=

View File

@ -1,153 +0,0 @@
# BH1750FVI_RT
Arduino library for BH1750FVI (GY-30) 16 bit I2C Lux sensor
## Description
The BH1750FVI is a 16 bit lux sensor with an I2C interface
It is possible to detect a wide range from 0.11 - 100000 lux.
To be able to support this wide range, the sensor can operate in three modi.
| ID | Mode | Integration time | Resolution | Notes |
|:----:|:----:|:----:|:----:|:----|
| 0 | LOW | 16 ms | 4.0 Lux | to measure very bright light |
| 1 | HIGH | 120 ms | 1.0 lux | default |
| 2 | HIGH2 | 120 ms | 0.5 lux | to measure very dim light |
Furthermore one can set a correction factor to reduce / increase the
integration time of the sensor.
The factor should be between 0.45 - 3.68.
It can be used to increase the working range like very bright or very low light conditions.
Another aplication is to correct the transparancy of material, or the type of light used.
Note that the typical integration time will differ if the correction factor is changed.
The **isReady()** an **getLux()** functions keep track of the adjustment needed.
## Interface hardware
Library was tested with a breakout board.
```
// breakout BH1750FVI / GY-30
//
// +-----------------------+
// GND |o |
// ADD |o |
// SDA |o + | + = sensor
// SCL |o |
// VCC |o |
// +-----------------------+
//
// ADD = ADDRESS:
// 0 = 0x23
// 1 = 0x5C
//
```
The sensor works on 2.4 - 3.6 volt so be careful not to connect directly to 5.0 volt.
(Note: the breakout board was 5 volt tolerant)
## Interface API
- **BH1750FVI(address, dataPin, clockPin)** ESP constructor with I2C parameters
- **BH1750FVI(address, TwoWire \*wire = &Wire)** constructor for other platforms
- **getRaw()** reads the lux sensor,
- **getLux()** reads the lux sensor and corrects for correctionFactor and for HIGH2 mode,
- **getError()** get the latest error, mainly for debugging,
- **powerOn()** wakes up the sensor,
- **powerOff()** set sensor to sleep,
- **reset()** resets the dataregister to 0, effectively removing last measurement.
- **getMode()** gets the mode set by one of the set functions. See table above.
- **setContHighRes()** continuous mode in HIGH resolution
- **setContHigh2Res()** continuous mode in HIGH2 resolution
- **setContLowRes()** continuous mode in LOW resolution
- **setOnceHighRes()** single shot mode in HIGH resolution
- **setOnceHigh2Res()** single shot mode in HIGH2 resolution
- **setOnceLowRes()** single shot mode in LOW resolution
- **isReady()** can be used to check if the sensor is ready.
This is based on a calculated time, the sensor does not have a means to indicate ready directly.
Needed only for the single shot modi.
The function **isReady()** takes the correctionfactor into account.
**CorrectionFactor**
Please read datasheet P11 about details of the correction factor.
- **changeTiming(uint8_t val)** 69 is default = BH1750FVI_REFERENCE_TIME
- **setCorrectionFactor(float f)** prefered wrapper around changeTiming f = 0.45 .. 3.68
- **getCorrectionFactor()** returns the correction factor.
Note this can differ as it is stores as an integer internally.
**Angle sensitivity**
Note: experimental - use carefully
The lux sensor is really sensitive for the angle of the light.
If one makes measurements outside, the position of the sun changes
during the day. The **setAngle(degrees)** function provides a mean to correct that.
The angle adjustments is based upon the figure 4 and 5 (directional characteristics.)
which describe **Lamberts Cosine Law**. (details see wikipedia)
So the correction factor is ```factor = 1.0 / cos(angle)```.
At 90 degrees it would fail (divide by zero) so the input is constrained
to angles between -89 - +89 degrees.
If the light is perpendicular on the sensor the angle to use is 0 degrees.
Light coming from the side is 90 degrees.
- **setAngle(int degrees)** adjust the lux to incoming angle in dgrees
- **getAngle()** returns set angle in degrees, 0 by default is perpendicular
**Temperature Compensation**
The reference temperature of the sensor = 20°C.
The effect of temperature is small, about 3% per 60°C ==> 1% per 20°C
so only on either a hot roof or on a icy cold day the effect is measurable.
- **setTemperature(int T)** see datasheet P3 fig7
- **getTemperature()** returns temperature set, default = 20°C
**Spectral Compensation ! EXPERIMENTAL !**
Spectral compensation is experimental and not tested. It is a compensation based upon the
graph figure 1, page 3 of the datasheet. If one has light of a known wavelength one can
compensate for it by setting the wavelength. It can also be used when using filters.
As said it is not tested so use at your own risk, but I am interested in your experiences
if you do real tests with it.
- **void setSpectral(int wavelength)** set wavelength,
- **int getSpectral()** returns wavelength
As the graph (figure 1) is not lineair it is approximated by linear interpolation with the
following six points.
| WaveLength | Perc % |
|:----|:----:|
| 400 | 1 |
| 440 | 10 |
| 510 | 90 |
| 545 | 80 |
| 580 | 100 |
| 700 | 07 |
| 725 | 1 |
Values outside the range will be mapped upon 400 or 715.
Default wavelength will be 580 as that gives 100%
## Ideas
**Intelligent isReady()**
After a **getLux()** call one can clean the dataregister explicitly with
**reset()**. Then a call to **isReady()** fetches data and as long as
data equals zero the sensor is not ready.
**DVI interface**
To investigate, sort of external reset?
## Operation
See samples...

View File

@ -1,107 +0,0 @@
Complex numbers test for Arduino: 0.1.06
1. Print Complex, set, real, imag
1.000 0.000i
10.000 -2.000i
3.000 0.000i
-10.000 4.000i
-5.000 -5.000i
0.000 0.000i
0.00
0.00
2. == !=
ok :)
ok :)
ok :)
3. negation -
-10.000 2.000i
10.000 -2.000i
ok :)
4. + -
13.000 -2.000i
13.000 -2.000i
7.000 -2.000i
7.000 -2.000i
5. * /
30.000 -6.000i
90.000 -18.000i
30.000 -6.000i
10.000 -2.000i
10.000 -2.000i
10.000 -2.000i
6. assign += -= *= /=
20.000 -4.000i
23.000 -4.000i
13.000 -2.000i
10.000 -2.000i
96.000 -40.000i
288.000 -120.000i
30.000 -6.000i
10.000 -2.000i
7. phase modulus polar
10.000 -2.000i
10.20
-0.20
10.000 -2.000i
8. conjugate reciprocal
10.000 2.000i
10.000 -2.000i
0.096 0.019i
10.000 -2.000i
9. power: exp log pow sqrt sqr logn log10
96.000 -40.000i
-9166.239 -20028.597i
10.000 -2.000i
96.000 -40.000i
10.000 -2.000i
96.000 -40.000i
880.000 -592.000i
10.000 -2.000i
0.534 0.542i
10.000 -2.000i
1.009 -0.086i
10. gonio: sin cos tan asin acos atan
0.541 0.457i
0.500 0.500i
0.990 -0.250i
0.500 0.500i
0.404 0.564i
0.500 0.500i
11. gonio csc sec cot acsc asec acot
1.078 -0.912i
0.500 0.500i
0.950 0.240i
0.500 0.500i
0.839 -1.172i
0.500 0.500i
12. gonio hyperbolicus I
0.457 0.541i
0.500 0.500i
0.990 0.250i
0.500 0.500i
0.564 0.404i
0.500 0.500i
13. gonio hyperbolicus II
0.912 -1.078i
0.500 0.500i
0.950 -0.240i
0.500 0.500i
1.172 -0.839i
0.500 0.500i
.. Complex done
465072
1.000 0.000i

View File

@ -1,110 +0,0 @@
Complex numbers test for Arduino: 0.1.11
1. Print Complex, set, real, imag
1.000 0.000i
10.000 -2.000i
3.000 0.000i
-10.000 4.000i
-5.000 -5.000i
0.000 0.000i
0.00
0.00
2. == !=
ok :)
ok :)
ok :)
3. negation -
-10.000 2.000i
10.000 -2.000i
ok :)
4. + -
13.000 -2.000i
13.000 -2.000i
7.000 -2.000i
7.000 -2.000i
5. * /
30.000 -6.000i
90.000 -18.000i
30.000 -6.000i
10.000 -2.000i
10.000 -2.000i
10.000 -2.000i
6. assign += -= *= /=
20.000 -4.000i
23.000 -4.000i
13.000 -2.000i
10.000 -2.000i
96.000 -40.000i
288.000 -120.000i
30.000 -6.000i
10.000 -2.000i
7. phase modulus polar
10.000 -2.000i
10.20
-0.20
10.000 -2.000i
8. conjugate reciprocal
10.000 2.000i
10.000 -2.000i
0.096 0.019i
10.000 -2.000i
9. power: exp log pow sqrt sqr logn log10
96.000 -40.000i
-9166.239 -20028.597i
10.000 -2.000i
96.000 -40.000i
10.000 -2.000i
96.000 -40.000i
880.000 -592.000i
10.000 -2.000i
0.534 0.542i
10.000 -2.000i
1.009 -0.086i
10. gonio: sin cos tan asin acos atan
0.541 0.457i
0.500 0.500i
0.990 -0.250i
0.500 0.500i
0.404 0.564i
0.500 0.500i
11. gonio csc sec cot acsc asec acot
1.078 -0.912i
0.500 0.500i
0.950 0.240i
0.500 0.500i
0.839 -1.172i
0.500 0.500i
12. gonio hyperbolicus I
0.457 0.541i
0.500 0.500i
0.990 0.250i
0.500 0.500i
0.564 0.404i
0.500 0.500i
13. gonio hyperbolicus II
0.912 -1.078i
0.500 0.500i
0.950 -0.240i
0.500 0.500i
1.172 -0.839i
0.500 0.500i
14. gonio bug fix (minimal) test
3.000 4.000i
1.000 0.000i
.. Complex done
520444
1.000 0.000i

View File

@ -1,110 +0,0 @@
Complex numbers test for Arduino: 0.1.12
1. Print Complex, set, real, imag
1.000 0.000i
10.000 -2.000i
3.000 0.000i
-10.000 4.000i
-5.000 -5.000i
0.000 0.000i
0.00
0.00
2. == !=
ok :)
ok :)
ok :)
3. negation -
-10.000 2.000i
10.000 -2.000i
ok :)
4. + -
13.000 -2.000i
13.000 -2.000i
7.000 -2.000i
7.000 -2.000i
5. * /
30.000 -6.000i
90.000 -18.000i
30.000 -6.000i
10.000 -2.000i
10.000 -2.000i
10.000 -2.000i
6. assign += -= *= /=
20.000 -4.000i
23.000 -4.000i
13.000 -2.000i
10.000 -2.000i
96.000 -40.000i
288.000 -120.000i
30.000 -6.000i
10.000 -2.000i
7. phase modulus polar
10.000 -2.000i
10.20
-0.20
10.000 -2.000i
8. conjugate reciprocal
10.000 2.000i
10.000 -2.000i
0.096 0.019i
10.000 -2.000i
9. power: exp log pow sqrt sqr logn log10
96.000 -40.000i
-9166.239 -20028.597i
10.000 -2.000i
96.000 -40.000i
10.000 -2.000i
96.000 -40.000i
880.000 -592.000i
10.000 -2.000i
0.534 0.542i
10.000 -2.000i
1.009 -0.086i
10. gonio: sin cos tan asin acos atan
0.541 0.457i
0.500 0.500i
0.990 -0.250i
0.500 0.500i
0.404 0.564i
0.500 0.500i
11. gonio csc sec cot acsc asec acot
1.078 -0.912i
0.500 0.500i
0.950 0.240i
0.500 0.500i
0.839 -1.172i
0.500 0.500i
12. gonio hyperbolicus I
0.457 0.541i
0.500 0.500i
0.990 0.250i
0.500 0.500i
0.564 0.404i
0.500 0.500i
13. gonio hyperbolicus II
0.912 -1.078i
0.500 0.500i
0.950 -0.240i
0.500 0.500i
1.172 -0.839i
0.500 0.500i
14. gonio bug fix (minimal) test
3.000 4.000i
1.000 0.000i
.. Complex done
520444
1.000 0.000i

View File

@ -1,67 +0,0 @@
Complex numbers performance test for Arduino: 0.1.12
5 constructors 12
set(0,0) 4
c1 + 1 1588
c1 + c2 1608
+= c2 1616
c5 = -c1 260
c1 - 3 1012
c1 - c2 1676
c5 -= c2 1612
c1 * 3 5720
c1 * c2 5444
c5 *= c2 4304
c1 / 3 12188
c1 / c2 12064
c5 /= c2 6476
real() 4
imag() 4
modulus() 68
phase 216
polar() 260
conjugate() 8
reciprocal(); 8008
c_sqr() 4280
c_exp() 41732
c_log() 39484
c_pow(2) 87740
c_sqrt() 8464
c_logn(c4) 72420
c_pow(c5) 61004
c_log10() 40080
c_sin() 57768
c_asin() 74980
c_cos() 57880
c_acos() 73392
c_tan() 128928
c_atan() 66740
c_csc() 70168
c_acsc() 85272
c_sec() 70232
c_asec() 86948
c_cot() 141432
c_acot() 74292
c_sinh() 57764
c_asinh() 64392
c_cosh() 57864
c_acosh() 61956
c_tanh() 128920
c_atanh() 90900
c_csch() 70252
c_acsch() 66284
c_sech() 70220
c_asech() 77312
c_coth() 141352
c_acoth() 98056
2317680
.. Complex done

View File

@ -1,67 +0,0 @@
Complex numbers performance test for Arduino: 0.1.07
5 constructors 8
set(0,0) 4
c1 + 1 2580
c1 + c2 2392
+= c2 2104
c5 = -c1 760
c1 - 3 2464
c1 - c2 2296
c5 -= c2 1976
c1 * 3 5700
c1 * c2 5560
c5 *= c2 5152
c1 / 3 13864
c1 / c2 13724
c5 /= c2 12248
real() 4
imag() 4
modulus() 68
phase 204
polar() 24476
conjugate() 4
reciprocal(); 8572
c_sqr() 5092
c_exp() 43100
c_log() 40144
c_pow(2) 89248
c_sqrt() 8616
c_logn(c4) 70780
c_pow(c5) 62192
c_log10() 38220
c_sin() 51772
c_asin() 76844
c_cos() 51860
c_acos() 75248
c_tan() 118520
c_atan() 69332
c_csc() 66048
c_acsc() 85060
c_sec() 66292
c_asec() 90756
c_cot() 132736
c_acot() 77304
c_sinh() 51764
c_asinh() 66212
c_cosh() 51860
c_acosh() 64388
c_tanh() 118524
c_atanh() 92468
c_csch() 66140
c_acsch() 70128
c_sech() 66292
c_asech() 81692
c_coth() 132664
c_acoth() 100032
2308648
.. Complex done

View File

@ -1,67 +0,0 @@
Complex numbers performance test for Arduino: 0.1.11
5 constructors 12
set(0,0) 4
c1 + 1 1588
c1 + c2 1608
+= c2 1616
c5 = -c1 260
c1 - 3 1012
c1 - c2 1676
c5 -= c2 1612
c1 * 3 5720
c1 * c2 5444
c5 *= c2 4304
c1 / 3 12188
c1 / c2 12064
c5 /= c2 6476
real() 4
imag() 4
modulus() 68
phase 216
polar() 260
conjugate() 8
reciprocal(); 8008
c_sqr() 4280
c_exp() 41732
c_log() 39484
c_pow(2) 87740
c_sqrt() 8464
c_logn(c4) 72420
c_pow(c5) 61004
c_log10() 40080
c_sin() 57768
c_asin() 74980
c_cos() 57880
c_acos() 73392
c_tan() 128928
c_atan() 66740
c_csc() 70168
c_acsc() 85272
c_sec() 70232
c_asec() 86948
c_cot() 141432
c_acot() 74292
c_sinh() 57764
c_asinh() 64392
c_cosh() 57864
c_acosh() 61956
c_tanh() 128920
c_atanh() 90900
c_csch() 70252
c_acsch() 66284
c_sech() 70220
c_asech() 77312
c_coth() 141352
c_acoth() 98056
2317680
.. Complex done

View File

@ -1,39 +0,0 @@
#include <cozir.h>
#if defined(ARDUINO) && ARDUINO >= 100
#include <SoftwareSerial.h>
SoftwareSerial nss(3,2);
#else
#include <NewSoftSerial.h>
NewSoftSerial nss(3,2);
#endif
COZIR czr(nss);
void setup()
{
Serial.begin(9600);
Serial.println("Setup");
delay(1000);
}
void loop()
{
Serial.println("Loop");
float t = czr.Celsius();
float f = czr.Fahrenheit();
float h = czr.Humidity();
uint16_t c = czr.CO2();
Serial.print("Celcius = ");
Serial.println(t);
Serial.print("Fahrenheit = ");
Serial.println(f);
Serial.print("Humidity = ");
Serial.println(h);
Serial.print("CO2 = ");
Serial.println(c);
delay(3000);
}

View File

@ -2,7 +2,7 @@
// FILE: DAC8551.cpp
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for DAC8551 SPI Digital Analog Convertor
// VERSION: 0.2.1
// VERSION: 0.2.2
// URL: https://github.com/RobTillaart/DAC8551
//
// HISTORY
@ -12,6 +12,7 @@
// 0.1.3 2020-06-07 fix library.json
// 0.2.0 2020-12-18 add slaveSelect to hardware SPI
// 0.2.1 2020-12-18 add arduino-ci + unit tests
// 0.2.2 2021-02-04 add DAC8550 DAC8501 DAC8501 derived class + minor refactor
#include "DAC8551.h"
@ -23,14 +24,16 @@ DAC8551::DAC8551(uint8_t slaveSelect)
_slaveSelect = slaveSelect;
}
DAC8551::DAC8551(uint8_t spiData, uint8_t spiClock, uint8_t slaveSelect)
{
_hwSPI = false;
_hwSPI = false;
_spiData = spiData;
_spiClock = spiClock;
_slaveSelect = slaveSelect;
}
// initializes the SPI
// and sets internal state
void DAC8551::begin()
@ -62,47 +65,50 @@ void DAC8551::setValue(uint16_t value)
updateDevice();
}
// returns 0..65535
uint16_t DAC8551::getValue()
{
return _value;
}
void DAC8551::setPowerDown(uint8_t powerDownMode)
{
_register = powerDownMode;
updateDevice();
}
uint8_t DAC8551::getPowerDownMode()
{
return _register & 0x03;
}
void DAC8551::updateDevice()
{
uint8_t configRegister = _register;
digitalWrite(_slaveSelect, LOW);
if (_hwSPI)
{
SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE1));
digitalWrite(_slaveSelect, LOW);
SPI.transfer(configRegister);
SPI.transfer(_value >> 8);
SPI.transfer(_value & 0xFF);
digitalWrite(_slaveSelect, HIGH);
SPI.endTransaction();
}
else // Software SPI
{
digitalWrite(_slaveSelect, LOW);
swSPI_transfer(configRegister);
swSPI_transfer(_value >> 8);
swSPI_transfer(_value & 0xFF);
digitalWrite(_slaveSelect, HIGH);
}
digitalWrite(_slaveSelect, LOW);
}
// simple one mode version
void DAC8551::swSPI_transfer(uint8_t value)
{
@ -114,4 +120,39 @@ void DAC8551::swSPI_transfer(uint8_t value)
}
}
/////////////////////////////////////////////////////////
//
// derive 8501, 8531 and 8550 from 8551
//
DAC8501::DAC8501(uint8_t slaveSelect) : DAC8551(slaveSelect)
{
}
DAC8501::DAC8501(uint8_t spiData, uint8_t spiClock, uint8_t slaveSelect)
: DAC8551(spiData, spiClock, slaveSelect)
{
}
DAC8531::DAC8531(uint8_t slaveSelect) : DAC8551(slaveSelect)
{
}
DAC8531::DAC8531(uint8_t spiData, uint8_t spiClock, uint8_t slaveSelect)
: DAC8551(spiData, spiClock, slaveSelect)
{
}
DAC8550::DAC8550(uint8_t slaveSelect) : DAC8551(slaveSelect)
{
}
DAC8550::DAC8550(uint8_t spiData, uint8_t spiClock, uint8_t slaveSelect)
: DAC8551(spiData, spiClock, slaveSelect)
{
}
// -- END OF FILE --

View File

@ -4,7 +4,7 @@
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for DAC8551 SPI Digital Analog Convertor
// could work with DAC8550, not tested
// VERSION: 0.2.1
// VERSION: 0.2.2
// HISTORY: See DAC8551.cpp
// URL: https://github.com/RobTillaart/DAC8551
//
@ -13,7 +13,7 @@
#include "SPI.h"
#define DAC8551_LIB_VERSION (F("0.2.1"))
#define DAC8551_LIB_VERSION (F("0.2.2"))
#define DAC8551_POWERDOWN_NORMAL 0
@ -36,7 +36,7 @@ public:
void setPowerDown(uint8_t powerDownMode);
uint8_t getPowerDownMode();
private:
protected:
uint8_t _spiData;
uint8_t _spiClock;
uint8_t _slaveSelect;
@ -48,4 +48,58 @@ private:
void swSPI_transfer(uint8_t value);
};
/////////////////////////////////////////////////////////
//
// derive 8501, 8531 and 8550 from 8551
//
#define DAC8501_POWERDOWN_NORMAL 0
#define DAC8501_POWERDOWN_1K 1
#define DAC8501_POWERDOWN_100K 2
#define DAC8501_POWERDOWN_HIGH_IMP 3
class DAC8501 : public DAC8551
{
public:
DAC8501(uint8_t slaveSelect);
DAC8501(uint8_t spiData, uint8_t spiClock, uint8_t slaveSelect);
};
#define DAC8531_POWERDOWN_NORMAL 0
#define DAC8531_POWERDOWN_1K 1
#define DAC8531_POWERDOWN_100K 2
#define DAC8531_POWERDOWN_HIGH_IMP 3
class DAC8531 : public DAC8551
{
public:
DAC8531(uint8_t slaveSelect);
DAC8531(uint8_t spiData, uint8_t spiClock, uint8_t slaveSelect);
};
#define DAC8550_POWERDOWN_NORMAL 0
#define DAC8550_POWERDOWN_1K 1
#define DAC8550_POWERDOWN_100K 2
#define DAC8550_POWERDOWN_HIGH_IMP 3
class DAC8550 : public DAC8551
{
public:
DAC8550(uint8_t slaveSelect);
DAC8550(uint8_t spiData, uint8_t spiClock, uint8_t slaveSelect);
};
// -- END OF FILE --

View File

@ -5,13 +5,16 @@
# DAC8551
Arduino library for DAC8551 SPI Digital Analog Convertor
Arduino library for DAC8501 DAC8531, DAC8550, DAC8551 SPI Digital Analog Convertor
## Description
The DAC8551 is a SPI based 16 bit DAC with one channel.
The DAC8501, DAC8531 and DAC8550 are drop in compatible
They all have classed derived 1 to 1 from DAC8551.
**Warning** this library is not tested extensively
@ -19,13 +22,20 @@ The DAC8551 is a SPI based 16 bit DAC with one channel.
### Core
- **DAC8551(uint8_t slaveSelect)** Constructor for hardware SPI,
- **DAC8501(uint8_t slaveSelect)** Constructor for DAC8501 with hardware SPI,
- **DAC8531(uint8_t slaveSelect)** Constructor for DAC8531 with hardware SPI,
- **DAC8550(uint8_t slaveSelect)** Constructor for DAC8550 with hardware SPI,
- **DAC8551(uint8_t slaveSelect)** Constructor for DAC8551 with hardware SPI,
since 0.2.0 the slaveSelect pin needs to be defined.
- **DAC8501(uint8_t spiData, uint8_t spiClock, uint8_t slaveSelect)** Constructor for the software SPI
- **DAC8531(uint8_t spiData, uint8_t spiClock, uint8_t slaveSelect)** Constructor for the software SPI
- **DAC8550(uint8_t spiData, uint8_t spiClock, uint8_t slaveSelect)** Constructor for the software SPI
- **DAC8551(uint8_t spiData, uint8_t spiClock, uint8_t slaveSelect)** Constructor for the software SPI
- **void begin()** initializes all pins to default state
- **void setValue(uint16_t value)** set the value of the channel to 0 - 65535
- **uint16_t getValue()** returns the last value written.
### Power down
check datasheet for details.
@ -41,6 +51,15 @@ check datasheet for details.
| DAC8551_POWERDOWN_HIGH_IMP | 3 |
DAC8501, DAC8531 and DAC8550 uses the same constants.
## Future
- more testing
- investigate differences between 8551 and 8550.
## Operation
See examples
@ -56,6 +75,3 @@ See examples
**demo_powerdown.ino**
- idem
## TODO
more testing

View File

@ -1,6 +1,9 @@
# Syntax Coloring Map For DAC8551
# Datatypes (KEYWORD1)
DAC8501 KEYWORD1
DAC8531 KEYWORD1
DAC8550 KEYWORD1
DAC8551 KEYWORD1
@ -14,6 +17,22 @@ getPowerDownMode KEYWORD2
# Constants (LITERAL1)
DAC8551_LIB_VERSION LITERAL1
DAC8501_POWERDOWN_NORMAL LITERAL1
DAC8501_POWERDOWN_1K LITERAL1
DAC8501_POWERDOWN_100K LITERAL1
DAC8501_POWERDOWN_HIGH_IMP LITERAL1
DAC8531_POWERDOWN_NORMAL LITERAL1
DAC8531_POWERDOWN_1K LITERAL1
DAC8531_POWERDOWN_100K LITERAL1
DAC8531_POWERDOWN_HIGH_IMP LITERAL1
DAC8550_POWERDOWN_NORMAL LITERAL1
DAC8550_POWERDOWN_1K LITERAL1
DAC8550_POWERDOWN_100K LITERAL1
DAC8550_POWERDOWN_HIGH_IMP LITERAL1
DAC8551_POWERDOWN_NORMAL LITERAL1
DAC8551_POWERDOWN_1K LITERAL1
DAC8551_POWERDOWN_100K LITERAL1

View File

@ -1,7 +1,7 @@
{
"name": "DAC8551",
"keywords": "DAC8551, SPI, digital, analog, convertor",
"description": "Arduino library for DAC8551 SPI Digital Analog Convertor",
"keywords": "DAC8551, DAC8550, DAC8501, DAC8531, SPI, digital, analog, convertor",
"description": "Arduino library for DAC8501, DAC8531, DAC8550 and DAC8551 SPI 16-bit Digital Analog Convertor",
"authors":
[
{
@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/DAC8551"
},
"version":"0.2.1",
"version":"0.2.2",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -1,9 +1,9 @@
name=DAC8551
version=0.2.1
version=0.2.2
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for DAC8551 SPI Digital Analog Convertor
paragraph=could work with DAC8550 (not tested)
sentence=Arduino library for DAC8501, DAC8531, DAC8550 and DAC8551 SPI 16-bit Digital Analog Convertor
paragraph=
category=Sensors
url=https://github.com/RobTillaart/DAC8551
architectures=*

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/DHTstable"
},
"version":"0.2.8",
"version": "0.2.8",
"frameworks": "arduino",
"platforms": "atmelavr"
}

View File

@ -1,149 +0,0 @@
//
// FILE: DS18B20.cpp
// AUTHOR: Rob.Tillaart@gmail.com
// VERSION: 0.1.6
// DATE: 2017-07-25
// PUPROSE: library for DS18B20 temperature sensor with minimal footprint
//
// HISTORY:
// 0.1.0 2017-07-25 initial version
// 0.1.1 2020-02-18 added getAddress()
// 0.1.2 2020-04-11 #pragma once, refactor
// 0.1.3 2020-04-22 #1 fix library.json file
// 0.1.4 2020-04-23 #2 add retry in begin() to support Wemos
// 0.1.5 2020-04-29 #4 added set/getConfig + DEVICE_CRC_ERROR + example
// 0.1.6 2020-06-07 fix library.json
#include "DS18B20.h"
// OneWire commands
#define STARTCONVO 0x44
#define READSCRATCH 0xBE
#define WRITESCRATCH 0x4E
// Scratchpad locations
#define TEMP_LSB 0
#define TEMP_MSB 1
#define HIGH_ALARM_TEMP 2
#define LOW_ALARM_TEMP 3
#define CONFIGURATION 4
#define INTERNAL_BYTE 5
#define COUNT_REMAIN 6
#define COUNT_PER_C 7
#define SCRATCHPAD_CRC 8
// Device resolution
#define TEMP_9_BIT 0x1F // 9 bit
#define TEMP_10_BIT 0x3F // 10 bit
#define TEMP_11_BIT 0x5F // 11 bit
#define TEMP_12_BIT 0x7F // 12 bit
DS18B20::DS18B20(OneWire* _oneWire)
{
_wire = _oneWire;
_addresFound = false;
_config = DS18B20_CLEAR;
}
bool DS18B20::begin(void)
{
_config = DS18B20_CLEAR;
_addresFound = false;
for (uint8_t retries = 3; (retries > 0) && (_addresFound == false); retries--)
{
_wire->reset_search();
_deviceAddress[0] = 0x00;
_wire->search(_deviceAddress);
_addresFound = _deviceAddress[0] != 0x00 &&
_wire->crc8(_deviceAddress, 7) == _deviceAddress[7];
}
return _addresFound;
}
void DS18B20::readScratchPad(uint8_t *scratchPad, uint8_t fields)
{
_wire->reset();
_wire->select(_deviceAddress);
_wire->write(READSCRATCH);
for (uint8_t i = 0; i < fields; i++)
{
scratchPad[i] = _wire->read();
}
_wire->reset();
}
bool DS18B20::isConversionComplete(void)
{
return (_wire->read_bit() == 1);
}
void DS18B20::requestTemperatures(void)
{
_wire->reset();
_wire->skip();
_wire->write(STARTCONVO, 0);
}
float DS18B20::getTempC(void)
{
ScratchPad scratchPad;
if (_config & DS18B20_CRC)
{
readScratchPad(scratchPad, 9);
if (_wire->crc8(scratchPad, 8) != scratchPad[SCRATCHPAD_CRC])
{
return DEVICE_CRC_ERROR;
}
}
else
{
readScratchPad(scratchPad, 2);
}
int16_t rawTemperature = (((int16_t)scratchPad[TEMP_MSB]) << 8) | scratchPad[TEMP_LSB];
float temp = 0.0625 * rawTemperature;
if (temp < -55) return DEVICE_DISCONNECTED;
return temp;
}
void DS18B20::setResolution(uint8_t newResolution)
{
_wire->reset();
_wire->select(_deviceAddress);
_wire->write(WRITESCRATCH);
// two dummy values for LOW & HIGH ALARM
_wire->write(0);
_wire->write(100);
switch (newResolution)
{
case 12:
_wire->write(TEMP_12_BIT);
break;
case 11:
_wire->write(TEMP_11_BIT);
break;
case 10:
_wire->write(TEMP_10_BIT);
break;
case 9:
default:
_wire->write(TEMP_9_BIT);
break;
}
_wire->reset();
}
bool DS18B20::getAddress(uint8_t* buf)
{
if (_addresFound)
{
for (uint8_t i = 0; i < 8; i++)
{
buf[i] = _deviceAddress[i];
}
}
return _addresFound;
}
// -- END OF FILE --

View File

@ -1,60 +0,0 @@
#pragma once
//
// FILE: DS18B20.h
// AUTHOR: Rob.Tillaart@gmail.com
// VERSION: 0.1.6
// DATE: 2017-07-25
// PUPROSE: library for DS18B20 temperature sensor with minimal footprint
//
//
// BOTTOM VIEW
//
// PIN MEANING
// /---+
// / o | 1 GND
// | o | 2 DATA
// \ o | 3 VCC
// \---+
//
#define DS18B20_LIB_VERSION "0.1.6"
#include <OneWire.h>
// Error Code
#define DEVICE_DISCONNECTED -127
#define DEVICE_CRC_ERROR -128
// config codes
#define DS18B20_CLEAR 0x00
#define DS18B20_CRC 0x01
typedef uint8_t DeviceAddress[8];
typedef uint8_t ScratchPad[9];
class DS18B20
{
public:
explicit DS18B20(OneWire *);
bool begin(void);
void setResolution(uint8_t);
void requestTemperatures(void);
float getTempC(void);
bool isConversionComplete(void);
bool getAddress(uint8_t*);
void setConfig(uint8_t config) { _config = config; };
uint8_t getConfig() { return _config; };
private:
void readScratchPad(uint8_t *, uint8_t);
DeviceAddress _deviceAddress;
OneWire* _wire;
bool _addresFound;
uint8_t _config;
};
// -- END OF FILE --

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2017-2020 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

@ -1,68 +0,0 @@
//
// FILE: DS18B20_diagnose.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.0.1
// PURPOSE: Minimal DS18B20 lib with async support.
//
// HISTORY:
// 0.0.1 = 2020-04-23 initial version
#include <OneWire.h>
#include <DS18B20.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DS18B20 sensor(&oneWire);
uint32_t start, stop;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("DS18B20 Library version: ");
Serial.println(DS18B20_LIB_VERSION);
if (sensor.begin() == false)
{
Serial.println("Error: Could not find sensor.");
while (1);
}
sensor.setResolution(12);
sensor.requestTemperatures();
start = millis();
while (!sensor.isConversionComplete());
stop = millis();
Serial.print(stop - start);
Serial.print("\t");
Serial.println(sensor.getTempC(), 2);
Serial.println();
}
void loop()
{
for (int res = 9; res < 13; res++)
{
sensor.setResolution(res);
start = millis();
sensor.requestTemperatures();
while (!sensor.isConversionComplete());
float temperature = sensor.getTempC();
stop = millis();
Serial.print(res);
Serial.print("\t");
Serial.print(stop - start);
Serial.print("\t");
Serial.println(temperature, 1); // 1 decimal makes perfect sense
}
Serial.println();
delay(1000);
}
// -- END OF FILE --

View File

@ -1,56 +0,0 @@
//
// FILE: DS18B20_getAddress.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.0.1
// PURPOSE: DS18B20 lib getAddress demo
//
// HISTORY:
// 0.0.1 = 2020-02-18 initial version
#include <OneWire.h>
#include <DS18B20.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DS18B20 sensor(&oneWire);
DeviceAddress da;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("DS18B20 Library version: ");
Serial.println(DS18B20_LIB_VERSION);
Serial.print("\ngetAddress: ");
Serial.println(sensor.getAddress(da));
sensor.begin();
Serial.print("\ngetAddress: ");
Serial.println(sensor.getAddress(da));
if (!sensor.getAddress(da))
{
Serial.println("No address found!");
return;
}
Serial.print("Address: ");
for (uint8_t i = 0; i < 8; i++)
{
if (da[i] < 0x10) Serial.print('0');
Serial.print(da[i], HEX);
}
Serial.println();
}
void loop()
{
}
// END OF FILE

View File

@ -1,36 +0,0 @@
//
// FILE: DS18B20_minimum.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.0.1
// PURPOSE: most minimal sketch
//
// WARNING: this sketch does not wait for isConversionComplete()
// and therefor temperature read is probably incorrect
// but it is fast and maybe accurate enough...
//
// HISTORY:
// 0.0.1 = 2017-07-25 initial version
#include <OneWire.h>
#include <DS18B20.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DS18B20 sensor(&oneWire);
void setup(void)
{
Serial.begin(115200);
Serial.println(__FILE__);
sensor.begin();
}
void loop(void)
{
sensor.requestTemperatures();
Serial.println(sensor.getTempC());
}

View File

@ -1,70 +0,0 @@
//
// FILE: DS18B20_performance.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.0.1
// PURPOSE: show performance of DS18B20 lib
// compared to datasheet times per resolution
//
// HISTORY:
// 0.0.1 = 2017-07-25 initial version
#include <OneWire.h>
#include <DS18B20.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DS18B20 sensor(&oneWire);
uint32_t start, stop;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("DS18B20 Library version: ");
Serial.println(DS18B20_LIB_VERSION);
sensor.begin();
}
void loop()
{
float ti[4] = { 94, 188, 375, 750 };
Serial.println();
Serial.println("Test takes about 30 seconds for 4 resolutions, 20 measurements");
Serial.println("RES\tTIME\tACTUAL\tGAIN");
for (int r = 9; r < 13; r++)
{
sensor.setResolution(r);
uint32_t duration = run(20);
float avgDuration = duration / 20.0;
Serial.print(r);
Serial.print("\t");
Serial.print(ti[r - 9]);
Serial.print("\t");
Serial.print(avgDuration, 2);
Serial.print("\t");
Serial.print(avgDuration * 100 / ti[r - 9], 1);
Serial.println("%");
}
delay(1000);
}
uint32_t run(int runs)
{
float t;
start = millis();
for (int i = 0; i < runs; i++)
{
sensor.requestTemperatures();
while (!sensor.isConversionComplete());
t = sensor.getTempC();
}
stop = millis();
return stop - start;
}

View File

@ -1,38 +0,0 @@
//
// FILE: DS18B20_simple.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.0.1
// PURPOSE: equivalent of DallasTemperature library Simple
//
// HISTORY:
// 0.0.1 = 2017-07-25 initial version
#include <OneWire.h>
#include <DS18B20.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DS18B20 sensor(&oneWire);
void setup(void)
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("DS18B20 Library version: ");
Serial.println(DS18B20_LIB_VERSION);
sensor.begin();
}
void loop(void)
{
sensor.requestTemperatures();
while (!sensor.isConversionComplete()); // wait until sensor is ready
Serial.print("Temp: ");
Serial.println(sensor.getTempC());
}

View File

@ -1,70 +0,0 @@
//
// FILE: DS18B20_test.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.0.1
// PURPOSE: Minimal DS18B20 lib with async support.
//
// HISTORY:
// 0.0.1 = 2017-07-25 initial version
#include <OneWire.h>
#include <DS18B20.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DS18B20 sensor(&oneWire);
uint32_t start, stop;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("DS18B20 Library version: ");
Serial.println(DS18B20_LIB_VERSION);
sensor.begin();
sensor.setResolution(12);
sensor.requestTemperatures();
start = millis();
int n = 0;
// wait until sensor ready, do some counting for fun.
while (!sensor.isConversionComplete()) n++;
stop = millis();
Serial.print(stop - start);
Serial.print("\t");
Serial.print(n);
Serial.print("\t");
Serial.println(sensor.getTempC(), 4); // 4 decimals is too much ...
Serial.println();
}
void loop()
{
float t;
for (int r = 9; r < 13; r++)
{
sensor.setResolution(r);
int n = 0;
start = millis();
sensor.requestTemperatures();
while (!sensor.isConversionComplete()) n++;
t = sensor.getTempC();
stop = millis();
Serial.print(r);
Serial.print("\t");
Serial.print(stop - start);
Serial.print("\t");
Serial.print(n);
Serial.print("\t");
Serial.println( t, 1); // 1 decimal makes perfect sense
}
Serial.println();
delay(1000);
}

View File

@ -1,74 +0,0 @@
//
// FILE: DS18B20_test_disconnect.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.0.1
// PURPOSE: Minimal DS18B20 lib with async support.
//
// HISTORY:
// 0.0.1 = 2020-04-29 initial version
#include <OneWire.h>
#include <DS18B20.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DS18B20 sensor(&oneWire);
uint32_t start, stop;
uint8_t res = 12;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("DS18B20 Library version: ");
Serial.println(DS18B20_LIB_VERSION);
// wait until address found
if (sensor.begin() == false)
{
Serial.println("ERROR: No device found");
while (!sensor.begin()); // wait until device comes available.
}
sensor.setResolution(12);
sensor.setConfig(DS18B20_CRC); // or 1
sensor.requestTemperatures();
}
void loop()
{
start = millis();
sensor.requestTemperatures();
// wait for data AND detect disconnect
uint32_t timeout = millis();
while (!sensor.isConversionComplete())
{
if (millis() - timeout >= 800) // check for timeout
{
Serial.println("ERROR: timeout or disconnect");
break;
}
}
float t = sensor.getTempC();
if (t == DEVICE_CRC_ERROR)
{
Serial.println("ERROR: CRC error");
}
stop = millis();
Serial.print(res);
Serial.print("\t");
Serial.print(stop - start);
Serial.print("\t");
Serial.println( t, 1); // 1 decimal makes perfect sense
delay(1000);
}
// -- END OF FILE --

View File

@ -1,58 +0,0 @@
//
// FILE: DS18B20_two_sensors.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.0.1
// PURPOSE: demo with two sensors (on two pins)
//
// HISTORY:
// 0.0.1 = 2017-07-25 initial version
#include <OneWire.h>
#include <DS18B20.h>
// numbers chosen to match pin numbers..
#define ONE_WIRE_BUS2 2
#define ONE_WIRE_BUS3 3
OneWire oneWire2(ONE_WIRE_BUS2);
OneWire oneWire3(ONE_WIRE_BUS3);
DS18B20 inside(&oneWire2);
DS18B20 outside(&oneWire3);
void setup(void)
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("DS18B20 Library version: ");
Serial.println(DS18B20_LIB_VERSION);
inside.begin();
outside.begin();
// different resolution shows nicely the async behavior
inside.setResolution(12);
outside.setResolution(10);
inside.requestTemperatures();
outside.requestTemperatures();
}
void loop(void)
{
// print the temperature when available and request a new reading
if (inside.isConversionComplete())
{
Serial.print("inside:\t");
Serial.println(inside.getTempC(),1);
inside.requestTemperatures();
}
if (outside.isConversionComplete())
{
Serial.print("outside:\t\t");
Serial.println(outside.getTempC(),1);
outside.requestTemperatures();
}
}

View File

@ -1,67 +0,0 @@
//
// FILE: oneWireSearch.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.02
// PURPOSE: scan for 1-Wire devices + code snippet generator
// DATE: 2015-june-30
// URL: http://forum.arduino.cc/index.php?topic=333923
//
// inspired by http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html
//
// Released to the public domain
//
// 0.1.00 initial version
// 0.1.01 first published version
// 0.1.02 small output changes
#include <OneWire.h>
void setup()
{
Serial.begin(115200);
Serial.println("//\n// Start oneWireSearch.ino \n//");
for (uint8_t pin = 2; pin < 13; pin++)
{
findDevices(pin);
}
Serial.println("\n//\n// End oneWireSearch.ino \n//");
}
void loop()
{
}
uint8_t findDevices(int pin)
{
OneWire ow(pin);
uint8_t address[8];
uint8_t count = 0;
if (ow.search(address))
{
Serial.print("\nuint8_t pin");
Serial.print(pin, DEC);
Serial.println("[][8] = {");
do {
count++;
Serial.println(" {");
for (uint8_t i = 0; i < 8; i++)
{
Serial.print("0x");
if (address[i] < 0x10) Serial.print("0");
Serial.print(address[i], HEX);
if (i < 7) Serial.print(", ");
}
Serial.println(" },");
} while (ow.search(address));
Serial.println("};");
Serial.print("// nr devices found: ");
Serial.println(count);
}
return count;
}

View File

@ -1,23 +0,0 @@
# Syntax Coloring Map For DS18B20
# Datatypes (KEYWORD1)
DS18B20 KEYWORD1
OneWire KEYWORD1
DeviceAddress KEYWORD1
# Methods and Functions (KEYWORD2)
begin KEYWORD2
setResolution KEYWORD2
getTempC KEYWORD2
requestTemperatures KEYWORD2
isConversionComplete KEYWORD2
getAddress KEYWORD2
setConfig KEYWORD2
getConfig KEYWORD2
# Constants (LITERAL1)
DS18B20_LIB_VERSION LITERAL1
DEVICE_DISCONNECTED LITERAL1
DEVICE_CRC_ERROR LITERAL1
DS18B20_CLEAR LITERAL1
DS18B20_CRC LITERAL1

View File

@ -1,21 +0,0 @@
{
"name": "DS18B20",
"keywords": "DS18B20,Dallas,Semiconductor,Temperature,sensor,asynchronuous",
"description": "Arduino library for the DS18B20 temperature sensor. Restricted to a single sensor per pin. Minimalistic version.",
"authors":
[
{
"name": "Rob Tillaart",
"email": "Rob.Tillaart@gmail.com",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/RobTillaart/DS18B20"
},
"version":"0.1.6",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -1,11 +0,0 @@
name=DS18B20_RT
version=0.1.6
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for the DS18B20 temperature sensor.
paragraph=Minimalistic version, restricted to one sensor per pin, asynchronuous mode only.
category=Sensors
url=https://github.com/RobTillaart/DS18B20
architectures=*
includes=OneWire.h,DS18B20.h
depends=OneWire

View File

@ -1,85 +0,0 @@
# DS18B20
Arduino library for the DS18B20 sensor - restricted to one sensor per pin.
## Arduino Temperature Control Library (ATCL)
This DS18B20 library is not a full featured library for the DS18B20 family.
This library supports only one DS18B20 per Arduino/ MCU pin.
If you need more functions or control over the DS18B20 family I refer to the library
of Miles Burton - https://github.com/milesburton/Arduino-Temperature-Control-Library
## Description
I'm a great fan of the above library however some time ago I needed to strip it down
to save a few dozen bytes. I reworked that minimalistic version into a library and I
added a number of Arduino examples to help you get started.
The DS18B20 library supports only the DS18B20, only one sensor per pin, no parasite
mode, no Fahrenheit and no alarm functions. The only feature the class supports is
the asynchronous reading of the temperature by means of three core functions:
* void requestTemperatures()
* bool isConversionComplete()
* float readTempC()
The other main functions are
* bool begin(void); *// returns true if the sensor is configured (available)*
* void setResolution(uint8_t);
* bool getAddress(uint8_t*) *// returns true if the sensor is configured (available)*
This allowed the class to be both minimal in size and non-blocking. In fact the class
has no support for a synchronous read in one call. This choice will teach people
how to work in a non-blocking way from the start.
Effort has been taken to keep the code, variables and function names compatible with
ATCL library mentioned above. This way you can step over to that one with relatively
few problems when you need more functionality like multiple sensors on one pin.
Finally this library will probably make it easier to use a DS18B20 with processing
boards or IC's with small memory footprint.
## Operation
```
// BOTTOM VIEW
//
// PIN MEANING
// /---+
// / o | 1 GND
// | o | 2 DATA
// \ o | 3 VCC
// \---+
```
This library supports only one DS18B20 per Arduino/ MCU pin.
Connect a pull-up resistor 4.7 KOhm between pin3 and pin2. When the wires are longer
this resistor needs to be smaller.
### Pull up resistor
An **indicative** table for pull up resistors, (E12 series), to get started.
Note: thicker wires require smaller resistors (typically 1 step in E12 series)
| Length | - 5.0 Volt | - 3.3 Volt |
|--------------:|------------:|----------:|
| 10cm (4") | 10K0 | 6K8 |
| 20cm (8") | 8K2 | 4K7 |
| 50cm (20") | 4K7 | 3K3 |
| 100cm (3'4") | 3K3 | 2K2 |
| 200cm (6'8") | 2K2 | 1K0 |
| 500cm (16'8") | 1K0 | * |
| longer | * | * |
\* = no info, smaller
## Credits
Miles Burton who originally developed the Arduino Temperature Control Library.
and all people who contributed to that lib.

View File

@ -1,203 +0,0 @@
//
// FILE: FRAM.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.1
// DATE: 2018-01-24
// PURPOSE: Arduino library for I2C FRAM
// URL: https://github.com/RobTillaart/FRAM_I2C
//
// HISTORY:
// 0.1.0 2018-01-24 initial version
// 0.1.1 2019-07-31 added suppport for Fujitsu 64Kbit MB85RC64T (kudos ysoyipek)
// 0.2.0 2020-04-30 refactor, add writeProtectPin code
// 0.2.1 2020-06-10 fix library.json
#include "FRAM.h"
const uint8_t FRAM_SLAVE_ID_= 0x7C;
/////////////////////////////////////////////////////
//
// PUBLIC
//
FRAM::FRAM()
{}
int FRAM::begin(uint8_t address, int8_t writeProtectPin)
{
if (address < 0x50 || address > 0x57)
{
return FRAM_ERROR_ADDR;
}
_address = address;
Wire.begin();
if (writeProtectPin > -1)
{
_writeProtectPin = writeProtectPin;
pinMode(_writeProtectPin, OUTPUT);
}
return FRAM_OK;
}
void FRAM::write8(uint16_t memaddr, uint8_t value)
{
uint8_t val = value;
writeBlock(memaddr, (uint8_t *)&val, 1);
}
void FRAM::write16(uint16_t memaddr, uint16_t value)
{
uint16_t val = value;
writeBlock(memaddr, (uint8_t *)&val, 2);
}
void FRAM::write32(uint16_t memaddr, uint32_t value)
{
uint32_t val = value;
writeBlock(memaddr, (uint8_t *)&val, 4);
}
void FRAM::write(uint16_t memaddr, uint8_t * obj, uint16_t size)
{
const int blocksize = 24;
uint8_t * p = obj;
while (size >= blocksize)
{
writeBlock(memaddr, p, blocksize);
memaddr += blocksize;
p += blocksize;
size -= blocksize;
}
// remaining
if (size > 0)
{
writeBlock(memaddr, p, size);
}
}
uint8_t FRAM::read8(uint16_t memaddr)
{
uint8_t val;
readBlock(memaddr, (uint8_t *)&val, 1);
return val;
}
uint16_t FRAM::read16(uint16_t memaddr)
{
uint16_t val;
readBlock(memaddr, (uint8_t *)&val, 2);
return val;
}
uint32_t FRAM::read32(uint16_t memaddr)
{
uint32_t val;
readBlock(memaddr, (uint8_t *)&val, 4);
return val;
}
void FRAM::read(uint16_t memaddr, uint8_t * obj, uint16_t size)
{
const uint8_t blocksize = 24;
uint8_t * p = obj;
while (size >= blocksize)
{
readBlock(memaddr, p, blocksize);
memaddr += blocksize;
p += blocksize;
size -= blocksize;
}
// remainder
if (size > 0)
{
readBlock(memaddr, p, size);
}
}
bool FRAM::setWriteProtect(bool b)
{
if (_writeProtectPin == -1) return false;
digitalWrite(_writeProtectPin, b ? HIGH : LOW);
return true;
}
uint16_t FRAM::getManufacturerID()
{
return getMetaData(0);
}
uint16_t FRAM::getProductID()
{
return getMetaData(1);
}
uint16_t FRAM::getSize()
{
uint16_t val = getMetaData(2); // density bits
if (val > 0) return 1 << val;
return 0;
}
///////////////////////////////////////////////////////////
//
// PRIVATE
//
// metadata is packed as [....MMMM][MMMMDDDD][PPPPPPPP]
// M = manufacturerID
// D = density => memsize = 2^D KB
// P = product ID (together with D)
uint16_t FRAM::getMetaData(uint8_t field)
{
if (field > 2) return 0;
Wire.beginTransmission(FRAM_SLAVE_ID_);
Wire.write(_address << 1);
Wire.endTransmission(false);
int x = Wire.requestFrom(FRAM_SLAVE_ID_, (uint8_t)3);
if (x != 3) return -1;
uint32_t value = 0;
value = Wire.read();
value |= Wire.read();
value |= Wire.read();
// MANUFACTURER
if (field == 0) return (value >> 12) & 0xFF;
// PRODUCT ID
if (field == 1) return value & 0x0FFF;
// DENSITY
if (field == 2) return (value >> 8) & 0x0F;
return 0;
}
void FRAM::writeBlock(uint16_t memaddr, uint8_t * obj, uint8_t size)
{
// TODO constrain size < 30 ??
Wire.beginTransmission(_address);
Wire.write(memaddr >> 8);
Wire.write(memaddr & 0xFF);
uint8_t * p = obj;
for (uint8_t i = 0; i < size; i++)
{
Wire.write(*p++);
}
Wire.endTransmission();
}
void FRAM::readBlock(uint16_t memaddr, uint8_t * obj, uint8_t size)
{
Wire.beginTransmission(_address);
Wire.write(memaddr >> 8);
Wire.write(memaddr & 0xFF);
Wire.endTransmission();
Wire.requestFrom(_address, size);
uint8_t * p = obj;
for (uint8_t i = 0; i < size; i++)
{
*p++ = Wire.read();
}
}
// -- END OF FILE --

View File

@ -1,55 +0,0 @@
#pragma once
//
// FILE: FRAM.h
// AUTHOR: Rob Tillaart
// VERSION: 0.2.1
// DATE: 2018-01-24
// PURPOSE: Arduino library for I2C FRAM
// URL: https://github.com/RobTillaart/FRAM_I2C
//
// HISTORY:
// see FRAM.cpp file
//
#include "Arduino.h"
#include "Wire.h"
#define FRAM_LIB_VERSION (F("0.2.1"))
#define FRAM_OK 0
#define FRAM_ERROR_ADDR -10
class FRAM
{
public:
FRAM();
// writeProtectPin is optional
int begin(const uint8_t address = 0x50, int8_t writeProtectPin = -1);
void write8(uint16_t memaddr, uint8_t value);
void write16(uint16_t memaddr, uint16_t value);
void write32(uint16_t memaddr, uint32_t value);
void write(uint16_t memaddr, uint8_t * obj, uint16_t size);
uint8_t read8(uint16_t memaddr);
uint16_t read16(uint16_t memaddr);
uint32_t read32(uint16_t memaddr);
void read(uint16_t memaddr, uint8_t * obj, uint16_t size);
bool setWriteProtect(bool b);
uint16_t getManufacturerID();
uint16_t getProductID();
uint16_t getSize();
private:
uint8_t _address;
int8_t _writeProtectPin = -1; // default no pin ==> no write protect.
uint16_t getMetaData(uint8_t id);
void writeBlock(uint16_t memaddr, uint8_t * obj, uint8_t size);
void readBlock(uint16_t memaddr, uint8_t * obj, uint8_t size);
};
// -- END OF FILE --

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2018-2020 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

@ -1,23 +0,0 @@
# FRAM_I2C
Arduino library for I2C FRAM
# Description
FRAM is a library to read and write (over I2C) to an FRAM module.
FRAM is much faster than EEPROM and almost as fast as Arduino UNO RAM.
Another imaportant feature is that FRAM keeps its content after a reboot (non-volatile)
Types of FRAM it should work with
| SIZE | TYPE |
|:---:|:---:|
| 8KB | MB85RC64T |
| 32KB | MB85RC256V |
| 64KB | MB85RC512T |
| 128KB | MB85RC1MT |
# Operational
See examples

View File

@ -1,240 +0,0 @@
//
// FILE: testFRAM.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: test for FRAM library for Arduino
// URL: https://github.com/RobTillaart/FRAM_I2C
//
// Released to the public domain
//
#include "FRAM.h"
FRAM fram;
uint32_t start;
uint32_t stop;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("FRAM_LIB_VERSION: ");
Serial.println(FRAM_LIB_VERSION);
Wire.begin();
int rv = fram.begin(0x50);
if (rv != 0)
{
Serial.println(rv);
}
else
{
testID();
testFRAMmemory();
testReadWriteSmall();
testReadWriteLarge();
testWriteText();
testReadText1();
testReadText2();
}
Serial.println("done...");
}
void loop()
{
}
void testID()
{
Serial.println();
Serial.println(__FUNCTION__);
Serial.println("takes ~32 seconds");
Serial.print("ManufacturerID: ");
Serial.println(fram.getManufacturerID());
Serial.print(" ProductID: ");
Serial.println(fram.getProductID());
Serial.print(" memory size: ");
Serial.println(fram.getSize());
Serial.println();
}
void testFRAMmemory()
{
Serial.println();
Serial.println(__FUNCTION__);
Serial.println("takes ~32 seconds");
start = millis();
uint8_t val = 0x55;
for (uint16_t addr = 0; addr < 32768; addr++)
{
fram.write8(addr, val);
if (fram.read8(addr) != 0x55)
{
Serial.print("FAIL: \t");
Serial.println(addr);
}
if (addr % 1000 == 0)
{
Serial.print(".");
}
}
stop = millis();
Serial.println();
Serial.print("TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
Serial.println();
}
void testReadWriteSmall()
{
Serial.println();
Serial.println(__FUNCTION__);
Serial.print("test8:\t");
uint8_t t8 = 0xFE;
fram.write8(1000, t8);
if (fram.read8(1000) != 0xFE)
{
Serial.println("failed.");
}
else
{
Serial.println("ok.");
}
Serial.print("test16:\t");
uint16_t t16 = 0xFADE;
fram.write16(1000, t16);
if (fram.read16(1000) != 0xFADE)
{
Serial.println("failed.");
}
else
{
Serial.println("ok.");
}
Serial.print("test32:\t");
uint32_t t32 = 0xFADEFACE;
fram.write32(1000, t32);
if (fram.read32(1000) != 0xFADEFACE)
{
Serial.println("failed.");
}
else
{
Serial.println("ok.");
}
Serial.println();
}
void testReadWriteLarge()
{
Serial.println();
Serial.println(__FUNCTION__);
uint8_t ar[100];
for (int i = 0; i < 100; i++) ar[i] = i;
start = millis();
fram.write(1000, ar, 100);
stop = millis();
Serial.print("WRITE 100 bytes TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
for (int i = 0; i < 100; i++) ar[i] = 0;
start = millis();
fram.read(1000, ar, 100);
stop = millis();
Serial.print("READ 100 bytes TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
for (int i = 0; i < 100; i++)
{
if (ar[i] != i)
{
Serial.print("FAIL: \t");
Serial.println(i);
}
}
Serial.println();
}
void testWriteText()
{
char str[10][20] =
{
"Hello world 0",
"Hello world 1",
"Hello world 2",
"Hello world 3",
"Hello world 4",
"Hello world 5",
"Hello world 6",
"Hello world 7",
"Hello world 8",
"Hello world 9",
};
Serial.println();
Serial.println(__FUNCTION__);
start = millis();
fram.write(2000, (uint8_t *)str, 200);
stop = millis();
Serial.print("WRITE 200 bytes TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
Serial.println();
}
void testReadText1()
{
char str[10][20];
Serial.println();
Serial.println(__FUNCTION__);
start = millis();
fram.read(2000, (uint8_t *)str, 200);
stop = millis();
Serial.print("READ 200 bytes TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
Serial.println();
for (int i = 0; i < 10; i++)
{
Serial.println(str[i]);
}
Serial.println();
}
void testReadText2()
{
char str[20];
Serial.println();
Serial.println(__FUNCTION__);
for (int i = 0; i < 10; i++)
{
fram.read(2000 + 20 * i, (uint8_t *)str, 20);
Serial.println(str);
}
Serial.println();
}
// END OF FILE

View File

@ -1,89 +0,0 @@
//
// FILE: testFRAMPerformance.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: test for FRAM library for Arduino
// URL: https://github.com/RobTillaart/FRAM_I2C
//
#include "FRAM.h"
FRAM fram;
uint32_t start;
uint32_t stop;
int ar[600];
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("FRAM_LIB_VERSION: ");
Serial.println(FRAM_LIB_VERSION);
Serial.println();
Serial.println();
Wire.begin();
int rv = fram.begin(0x50);
if (rv != 0)
{
Serial.println(rv);
}
else
{
for (int s = 1; s < 9; s++) // test up to 800 KB
{
uint32_t speed = s * 100000UL;
Serial.print("CLOCK: ");
Serial.println(speed);
Wire.setClock(speed);
testReadWriteLarge();
}
Wire.setClock(100000);
}
Serial.println("done...");
}
void loop()
{
}
void testReadWriteLarge()
{
Serial.println();
Serial.println(__FUNCTION__);
for (int i = 0; i < 600; i++) ar[i] = i;
start = millis();
fram.write(1000, (uint8_t*)ar, 1200);
stop = millis();
Serial.print("WRITE 1200 bytes TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
for (int i = 0; i < 600; i++) ar[i] = 0;
start = millis();
fram.read(1000, (uint8_t*)ar, 1200);
stop = millis();
Serial.print("READ 1200 bytes TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
for (int i = 0; i < 600; i++)
{
if (ar[i] != i)
{
Serial.print("FAIL: \t");
Serial.print(ar[i]);
Serial.print('\t');
Serial.println(i);
}
}
Serial.println();
}
// END OF FILE

View File

@ -1,25 +0,0 @@
# Syntax Coloring Map for FRAM
# Datatypes (KEYWORD1)
FRAM KEYWORD1
# Methods and Functions (KEYWORD2)
begin KEYWORD2
write8 KEYWORD2
write16 KEYWORD2
write32 KEYWORD2
write KEYWORD2
read8 KEYWORD2
read16 KEYWORD2
read32 KEYWORD2
read KEYWORD2
getManufacturerID KEYWORD2
getProductID KEYWORD2
getSize KEYWORD2
# Constants (LITERAL1)
FRAM_OK LITERAL1
FRAM_ERROR_ADDR LITERAL1

View File

@ -1,21 +0,0 @@
{
"name": "FRAM_I2C",
"keywords": "FRAM, storage",
"description": "Library for FRAM for Arduino.",
"authors":
[
{
"name": "Rob Tillaart",
"email": "Rob.Tillaart@gmail.com",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/RobTillaart/FRAM_I2C.git"
},
"version":"0.2.1",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -1,11 +0,0 @@
name=FRAM_I2C
version=0.2.1
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for I2C FRAM.
paragraph=
category=Data Storage
url=https://github.com/RobTillaart/FRAM_I2C.git
architectures=*
includes=Wire.h,FRAM.h
depends=Wire.h

View File

@ -1,7 +1,7 @@
//
// FILE: FRAM.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.3.0
// VERSION: 0.3.1
// DATE: 2018-01-24
// PURPOSE: Arduino library for I2C FRAM
// URL: https://github.com/RobTillaart/FRAM_I2C
@ -14,6 +14,7 @@
// 0.2.2 2020-12-23 arduino-CI + unit test + getWriteProtect()
// 0.2.3 2021-01-ii fix getMetaData (kudos to PraxisSoft
// 0.3.0 2021-01-13 fix #2 ESP32 + WireN support
// 0.3.1 2021-02-05 fix #7 typo in .cpp
#include "FRAM.h"
@ -34,7 +35,7 @@ FRAM::FRAM(TwoWire *wire)
#if defined (ESP8266) || defined(ESP32)
int PCF8574::begin(uint8_t sda, uint8_t scl, const uint8_t address = 0x50, int8_t writeProtectPin = -1);
int FRAM::begin(uint8_t sda, uint8_t scl, const uint8_t address, int8_t writeProtectPin)
{
if (address < 0x50 || address > 0x57) return FRAM_ERROR_ADDR;

View File

@ -2,7 +2,7 @@
//
// FILE: FRAM.h
// AUTHOR: Rob Tillaart
// VERSION: 0.3.0
// VERSION: 0.3.1
// DATE: 2018-01-24
// PURPOSE: Arduino library for I2C FRAM
// URL: https://github.com/RobTillaart/FRAM_I2C
@ -13,7 +13,7 @@
#include "Wire.h"
#define FRAM_LIB_VERSION (F("0.3.0"))
#define FRAM_LIB_VERSION (F("0.3.1"))
#define FRAM_OK 0
@ -29,7 +29,7 @@ public:
#if defined (ESP8266) || defined(ESP32)
// address and writeProtectPin is optional
int begin(uint8_t sda, uint8_t scl, const uint8_t address = 0x50, int8_t writeProtectPin = -1);
int begin(uint8_t sda, uint8_t scl, const uint8_t address = 0x50, int8_t writeProtectPin = -1);
#endif
// address and writeProtectPin is optional
int begin(const uint8_t address = 0x50, int8_t writeProtectPin = -1);

View File

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

View File

@ -1,5 +1,5 @@
name=FRAM_I2C
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 I2C FRAM.

View File

@ -21,6 +21,26 @@ It has three examples
- test sketch to test get / set values.
## Breakout board
left to right
| pin | pinname | description |
|:----:|:--------|:----------------|
| 0 | VCC | +5V |
| 1 | GND | ground |
| 2 | SCL | I2C clock |
| 3 | SDA | I2C data |
| 4 | XDA | auxiliary data | see datasheet
| 5 | XCL | auxiliary clock | see datasheet
| 6 | AD0 | address |
| 7 | INT | interrupt |
#### Address
AD0 connected to GND => 0x68
AD0 connected to VCC => 0x69
## Calibration (short version for now)
1. load and run calibration example
@ -31,7 +51,6 @@ It has three examples
## Interface
TODO
### Constructor

View File

@ -8,7 +8,8 @@
Arduino library for HX711 24 bit ADC used for load cells and scales.
# Description
## Description
This HX711 library has an interface which is a superset of a library made by bogde.
Some missing functions were added to get more info from the lib.
@ -17,9 +18,10 @@ Another important difference is that this library uses floats. The 23 bits manti
of the IEE754 float matches the 24 bit ADC very well. Furthermore it gave a smaller
footprint.
### Main flow
First action is to call **begin(dataPin, clockPin)** to make connetion to the **HX711**.
## Main flow
First action is to call **begin(dataPin, clockPin)** to make connection to the **HX711**.
Second step is callibration for which a number of functions exist.
- **tare()** measures zero point
@ -35,7 +37,7 @@ Steps to take for callibration
1. save the offset and scale for later use e.g. EEPROM.
### Pricing
## Pricing
Some price functions were added to make it easy to use this library
for pricing goods or for educational purposes. These functions are under discussion
@ -44,8 +46,10 @@ the 0.2.0 release, it is on a todo list.
For weight conversion functions see https://github.com/RobTillaart/weight
## Notes
### Scale values for loadcells
These scale values worked pretty well with a set of loadcells,
@ -54,11 +58,13 @@ Use callibrate to find your values.
- 5 KG loadcell scale.set_scale(420.52);
- 20 KG loadcell scale.set_scale(127.15);
### Connections HX711
- A+/A- uses gain of 128 or 64
- B+/B- uses gain of 32
### Connections
| HX711 Pin | Color |
@ -80,6 +86,7 @@ Use callibrate to find your values.
| B- | not connected |
| B+ | not connected |
## Operation
See examples

View File

@ -56,9 +56,11 @@
// TWI buffer needs max 2 bytes for eeprom address
// 1 byte for eeprom register address is available in txbuffer
// NOTE this is typical on an UNO.
// TODO investigate
#define I2C_TWIBUFFERSIZE 30
#if defined(ESP32) || defined(ESP8266)
#define I2C_BUFFERSIZE 128
#else
#define I2C_BUFFERSIZE 30 // AVR, STM
#endif
I2C_eeprom::I2C_eeprom(const uint8_t deviceAddress, TwoWire *wire)
@ -120,8 +122,8 @@ int I2C_eeprom::writeByte(const uint16_t memoryAddress, const uint8_t data)
int I2C_eeprom::setBlock(const uint16_t memoryAddress, const uint8_t data, const uint16_t length)
{
uint8_t buffer[I2C_TWIBUFFERSIZE];
for (uint8_t i = 0; i < I2C_TWIBUFFERSIZE; i++)
uint8_t buffer[I2C_BUFFERSIZE];
for (uint8_t i = 0; i < I2C_BUFFERSIZE; i++)
{
buffer[i] = data;
}
@ -152,7 +154,7 @@ uint16_t I2C_eeprom::readBlock(const uint16_t memoryAddress, uint8_t* buffer, co
uint16_t rv = 0;
while (len > 0)
{
uint8_t cnt = I2C_TWIBUFFERSIZE;
uint8_t cnt = I2C_BUFFERSIZE;
if (cnt > len) cnt = len;
rv += _ReadBlock(addr, buffer, cnt);
addr += cnt;
@ -177,8 +179,8 @@ int I2C_eeprom::updateBlock(const uint16_t memoryAddress, const uint8_t* buffer,
uint16_t rv = 0;
while (len > 0)
{
uint8_t buf[I2C_TWIBUFFERSIZE];
uint8_t cnt = I2C_TWIBUFFERSIZE;
uint8_t buf[I2C_BUFFERSIZE];
uint8_t cnt = I2C_BUFFERSIZE;
if (cnt > len) cnt = len;
rv += _ReadBlock(addr, buf, cnt);
@ -281,7 +283,7 @@ int I2C_eeprom::_pageBlock(const uint16_t memoryAddress, const uint8_t* buffer,
{
uint8_t bytesUntilPageBoundary = this->_pageSize - addr % this->_pageSize;
uint8_t cnt = I2C_TWIBUFFERSIZE;
uint8_t cnt = I2C_BUFFERSIZE;
if (cnt > len) cnt = len;
if (cnt > bytesUntilPageBoundary) cnt = bytesUntilPageBoundary;
@ -316,7 +318,7 @@ void I2C_eeprom::_beginTransmission(const uint16_t memoryAddress)
}
// pre: length <= this->_pageSize && length <= I2C_TWIBUFFERSIZE;
// pre: length <= this->_pageSize && length <= I2C_BUFFERSIZE;
// returns 0 = OK otherwise error
int I2C_eeprom::_WriteBlock(const uint16_t memoryAddress, const uint8_t* buffer, const uint8_t length)
{

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2014-2020 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

@ -1,184 +0,0 @@
//
// FILE: MAX31855.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.3
// PURPOSE: Arduino library for MAX31855 chip for K type thermocouple
// DATE: 2014-01-01
// URL: https://github.com/RobTillaart/MAX31855_RT
//
// HISTORY:
//
// 0.2.3 2020-08-30 fix #8 support hardware SPI + example
// 0.2.2 2020-08-30 fix#9 + fix failing examples + minor refactor
// 0.2.1 2020-08-26 read rawData and STATUS_NO_COMMUNICATION recognition (thanks to FabioBrondo)
// 0.2.0 2020-06-20 #pragma once; major refactor; removed pre 1.0 support; fix offset
// 0.1.10 2019-07-31 add 3 inline functions to test errors + demo sketch
// 0.1.9 2017-07-27 reverted double -> float (issue33)
// 0.1.08 2015-12-06 replaced all temperature calls with one TCfactor + update demos.
// 0.1.07 2015-12-06 updated TC factors from the MAX31855 datasheet
// 0.1.06 2015-12-05 added support for other types of TC's (experimental)
// 0.1.05 2015-07-12 refactor robust constructor
// 0.1.04 2015-03-09 replaced float -> double (ARM support)
// 0.1.03 2014-01-24 fixed negative temperature
// 0.1.02 2014-01-03 added offset
// 0.1.01 2014-01-02 refactored speed/performance
// 0.1.00 2014-01-02 initial version.
//
#include "MAX31855.h"
MAX31855::MAX31855(const uint8_t cs)
{
_cs = cs;
_hwSPI = true;
_offset = 0;
_SC = K_TC;
_status = STATUS_NOREAD;
_temperature = -999;
_internal = -999;
}
MAX31855::MAX31855(const uint8_t sclk, const uint8_t cs, const uint8_t miso)
{
_sclk = sclk;
_cs = cs;
_miso = miso;
_hwSPI = false;
_offset = 0;
_SC = K_TC;
_status = STATUS_NOREAD;
_temperature = -999;
_internal = -999;
}
void MAX31855::begin()
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH);
if (_hwSPI)
{
SPI.begin();
delay(1);
}
else
{
pinMode(_sclk, OUTPUT);
pinMode(_miso, INPUT);
}
}
uint8_t MAX31855::read()
{
// return value of _read()
// BITS DESCRIPTION
// ----------------------
// 00 - 02 STATUS
// 03 RESERVED
// 04 - 15 INTERNAL
// 16 FAULT-BIT
// 17 RESERVED
// 18 - 30 TEMPERATURE (RAW)
// 31 SIGN
uint32_t value = _read();
if (value == 0xFFFFFFFF) // needs a pull up on miso pin to work properly!
{
// bit 3 and bit 17 should always be 0 - P10 datasheet
_status = STATUS_NO_COMMUNICATION;
return _status;
}
_lastRead = millis();
// process status bit 0-2
_status = value & 0x0007;
if (_status != STATUS_OK)
{
return _status;
}
value >>= 3;
// reserved bit 3, always 0
value >>= 1;
// process internal bit 4-15
_internal = (value & 0x07FF) * 0.0625;
// negative flag set ?
if (value & 0x0800)
{
_internal = -128 + _internal;
}
value >>= 12;
// Fault bit ignored as we have the 3 status bits
// _fault = value & 0x01;
value >>= 1;
// reserved bit 17, always 0
value >>= 1;
// process temperature bit 18-30 + sign bit = 31
_temperature = (value & 0x1FFF) * 0.25;
// negative flag set ?
if (value & 0x2000)
{
_temperature = -2048 + _temperature;
}
return _status;
}
uint32_t MAX31855::_read(void)
{
_rawData = 0;
digitalWrite(_cs, LOW);
if (_hwSPI)
{
SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
for (uint8_t i = 0; i < 4; i++)
{
_rawData <<= 8;
_rawData += SPI.transfer(0);
}
SPI.endTransaction();
}
else
{
for (int8_t i = 31; i >= 0; i--)
{
_rawData <<= 1;
digitalWrite(_sclk, LOW);
// delayMicroseconds(1); // DUE
if ( digitalRead(_miso) ) _rawData++;
digitalWrite(_sclk, HIGH);
// delayMicroseconds(1); // DUE
}
}
digitalWrite(_cs, HIGH);
return _rawData;
}
float MAX31855::getTemperature()
{
// offset needs to be added after multiplication TCfactor
// not before otherwise offset will be larger / smaller
// default behavior
if (_SC == K_TC) return _temperature + _offset;
// EXPERIMENTAL OTHER THERMOCOUPLES
// in practice this works also for K_TC but is way slower..
// 1: reverse calculate the Voltage measured
float Vout = K_TC * (_temperature - _internal); // PAGE 8 datasheet
// 2: from Voltage to corrected temperature using the Seebeck Coefficient
float _temp = Vout / _SC + _internal;
return _temp;
}
// -- END OF FILE --

View File

@ -1,110 +0,0 @@
#pragma once
//
// FILE: MAX31855.h
// AUTHOR: Rob Tillaart
// VERSION: 0.2.3
// PURPOSE: Arduino library for MAX31855 chip for K type thermocouple
// DATE: 2014-01-01
// URL: https://github.com/RobTillaart/MAX31855_RT
// http://forum.arduino.cc/index.php?topic=208061
//
// Bbreakout board
//
// +---------+
// Vin | o |
// 3Vo | o |
// GND | o O | Thermocouple
// D0 | o O | Thermocouple
// CS | o |
// CLK | o |
// +---------+
#include "Arduino.h"
#include "SPI.h"
#define MAX31855_VERSION "0.2.3"
// STATE constants returnd by read()
#define STATUS_OK 0x00
#define STATUS_OPEN_CIRCUIT 0x01
#define STATUS_SHORT_TO_GND 0x02
#define STATUS_SHORT_TO_VCC 0x04
#define STATUS_ERROR 0x07
#define STATUS_NOREAD 0x80
#define STATUS_NO_COMMUNICATION 0x81
// Thermocouples working is based upon Seebeck effect.
// Different TC have a different Seebeck Coefficient (µV/°C)
// See http://www.analog.com/library/analogDialogue/archives/44-10/thermocouple.html
//
// As the MAX31855 is designed for K type sensors, one can calculate
// the factor needed to convert other sensors measurements.
// NOTE: this is only a linear approximation.
//
// Seebeck Coefficients (sensitivity) from the MAX31855 datasheet page 8
// to be used in setSeebeckCoefficient()
//
// TYPE COEFFICIENT
#define E_TC 76.373
#define J_TC 57.953
#define K_TC 41.276
#define N_TC 36.256
#define R_TC 10.506
#define S_TC 9.587
#define T_TC 52.18
class MAX31855
{
public:
// HW SPI
MAX31855(uint8_t CS);
// SW SPI
MAX31855(uint8_t SCLK, uint8_t CS, uint8_t MISO);
void begin();
// returns state - bitfield: 0 = STATUS_OK
uint8_t read();
float getInternal(void) const { return _internal; }
float getTemperature(void);
uint8_t getStatus(void) const { return _status; };
inline bool openCircuit() { return _status == STATUS_OPEN_CIRCUIT; };
inline bool shortToGND() { return _status == STATUS_SHORT_TO_GND; };
inline bool shortToVCC() { return _status == STATUS_SHORT_TO_VCC; };
inline bool genericError() { return _status == STATUS_ERROR; };
inline bool noRead() { return _status == STATUS_NOREAD; };
inline bool noCommunication() { return _status == STATUS_NO_COMMUNICATION; };
// use offset to callibrate the TC.
void setOffset(const float t) { _offset = t; };
float getOffset() const { return _offset; };
// set the above E_TC (etc) Seebrecht Coefficients
// one can also set your own optimized values.
void setSeebeckCoefficient(const float SC) { _SC = SC; };
float getSeebeckCoefficient() const { return _SC; };
uint32_t lastRead() { return _lastRead; };
uint32_t getRawData() { return _rawData;};
private:
uint32_t _read();
uint8_t _status;
float _internal;
float _temperature;
float _offset;
float _SC;
uint32_t _lastRead;
uint32_t _rawData;
bool _hwSPI;
uint8_t _sclk;
uint8_t _miso;
uint8_t _cs;
};
// -- END OF FILE --

View File

@ -1,46 +0,0 @@
//
// FILE: Demo_getRawData.ino
// AUTHOR: FabioBrondo
// VERSION: 0.1.1
// PURPOSE: thermocouple lib demo application
// DATE: 2020-08-24
// URL: https://github.com/RobTillaart/MAX31855_RT
//
#include <SPI.h>
#include <MAX31855.h>
#define MAXDO 7 // Defining the MISO pin
#define MAXCS 6 // Defining the CS pin
#define MAXCLK 5 // Defining the SCK pin
MAX31855 thermocouple(MAXCLK, MAXCS, MAXDO);
void setup ()
{
Serial.begin(115200);
delay(250);
thermocouple.begin();
}
void loop ()
{
int status = thermocouple.read();
if (status == STATUS_NO_COMMUNICATION)
{
Serial.println("NO COMMUNICATION");
}
uint32_t value = thermocouple.getRawData(); // Read the raw Data value from the module
Serial.print("RAW:\t");
Serial.println(value, BIN); // Display the raw data value in BIN format
Serial.print("TMP:\t");
Serial.println(thermocouple.getTemperature());
delay(100);
}
// -- END OF FILE --

View File

@ -1,69 +0,0 @@
//
// FILE: max31855_array.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// PURPOSE: demo of array of thermocouples
// DATE: 2020-08-26
// URL: https://github.com/RobTillaart/MAX31855_RT
//
// kudos to FabioBrondo for the idea.
//
#include "MAX31855.h"
// note: pins are slightly different than other examples!
const int dataPin = 7;
const int clockPin = 6;
MAX31855 sensors[] =
{
MAX31855(clockPin, 5, dataPin),
MAX31855(clockPin, 4, dataPin),
MAX31855(clockPin, 3, dataPin)
};
const uint8_t sensorCount = sizeof(sensors) / sizeof(MAX31855);
void setup()
{
Serial.begin(115200);
Serial.print("Start max31855_array.ino : ");
Serial.println(MAX31855_VERSION);
Serial.println();
Serial.println(sensorCount);
for (int i = 0; i < sensorCount; i++)
{
sensors[i].begin();
}
}
void loop()
{
Serial.print("\tTime:\t");
Serial.println(millis());
for (int i = 0; i < sensorCount; i++)
{
int status = sensors[i].read();
if (status != STATUS_OK)
{
Serial.print(i);
Serial.print("\tstatus:\t");
Serial.println(status);
}
else
{
float temp = sensors[i].getTemperature();
Serial.print(i);
Serial.print("\ttemp:\t");
Serial.println(temp);
}
}
Serial.println();
delay(1000);
}
// -- END OF FILE --

View File

@ -1,42 +0,0 @@
//
// FILE: max31855_demo0.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.3
// PURPOSE: thermocouple lib demo application
// DATE: 2014-01-01
// URL: https://github.com/RobTillaart/MAX31855_RT
//
#include "MAX31855.h"
const int doPin = 7;
const int csPin = 6;
const int clPin = 5;
MAX31855 tc(clPin, csPin, doPin);
void setup()
{
Serial.begin(115200);
Serial.print("Start max31855_demo0: ");
Serial.println(MAX31855_VERSION);
Serial.println();
tc.begin();
}
void loop()
{
int status = tc.read();
Serial.print("stat:\t\t");
Serial.println(status);
float internal = tc.getInternal();
Serial.print("internal:\t");
Serial.println(internal);
float temp = tc.getTemperature();
Serial.print("temperature:\t");
Serial.println(temp);
delay(1000);
}

View File

@ -1,46 +0,0 @@
//
// FILE: max31855_demo1.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.4
// PURPOSE: thermocouple lib demo application
// DATE: 2014-01-02
// URL: https://github.com/RobTillaart/MAX31855_RT
//
#include "MAX31855.h"
const int doPin = 7;
const int csPin = 6;
const int clPin = 5;
MAX31855 tc(clPin, csPin, doPin);
void setup()
{
Serial.begin(115200);
Serial.print("Start max31855_demo1: ");
Serial.println(MAX31855_VERSION);
Serial.println();
tc.begin();
}
void loop()
{
int status = tc.read();
if (status != 0)
{
Serial.print("stat:\t\t");
Serial.println(status);
}
float temp = tc.getTemperature();
int m = temp * 10 - 200;
Serial.print(temp);
Serial.print('\t');
for (int i = 0; i < m; i++) Serial.write(']');
Serial.println();
}
// -- END OF FILE --

View File

@ -1,43 +0,0 @@
//
// FILE: max31855_demo2.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.4
// PURPOSE: thermocouple lib demo application
// DATE: 2014-01-02
// URL: https://github.com/RobTillaart/MAX31855_RT
//
#include "MAX31855.h"
const int doPin = 7;
const int csPin = 6;
const int clPin = 5;
MAX31855 tc(clPin, csPin, doPin);
float t1, t2;
void setup()
{
Serial.begin(115200);
Serial.print("Start max31855_demo2: ");
Serial.println(MAX31855_VERSION);
Serial.println();
tc.begin();
tc.read();
t1 = tc.getTemperature();
delay(1000);
}
void loop()
{
tc.read();
t2 = tc.getTemperature();
Serial.print("delta:\t");
Serial.println(t2 - t1, 2);
t1 = t2;
delay(1000);
}
// -- END OF FILE --

View File

@ -1,76 +0,0 @@
//
// FILE: max31855_demo3.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.4
// PURPOSE: thermocouple lib demo application
// DATE: 2014-01-02
// URL: https://github.com/RobTillaart/MAX31855_RT
//
#include "MAX31855.h"
const int doPin = 7;
const int csPin = 6;
const int clPin = 5;
MAX31855 tc(clPin, csPin, doPin);
void setup()
{
Serial.begin(115200);
Serial.print("Start max31855_demo3: ");
Serial.println(MAX31855_VERSION);
Serial.println();
tc.begin();
uint32_t start = micros();
tc.read();
uint32_t stop = micros();
Serial.print("read:\t");
Serial.println(stop - start);
start = micros();
float t1 = tc.getTemperature();
stop = micros();
Serial.print("getTemperature:\t");
Serial.println(stop - start);
start = micros();
float t2 = tc.getInternal();
stop = micros();
Serial.print("getInternal:\t");
Serial.println(stop - start);
Serial.println();
Serial.println(t1, 2);
Serial.println(t2, 2);
Serial.println();
}
void loop()
{
// this loop returns multiples of about 73mSec (counter multiples of ~143)
// so the # measurements per second is about 14?
uint32_t counter = 0;
float t1 = tc.getTemperature();
float t2 = t1;
uint32_t start = micros();
while (t2 == t1)
{
tc.read();
t1 = tc.getTemperature();
counter++;
}
uint32_t stop = micros();
Serial.print("change:\t");
Serial.println(stop - start);
Serial.print("counter:\t");
Serial.println(counter);
Serial.println(t2, 2);
Serial.println(t1, 2);
Serial.println();
}

View File

@ -1,77 +0,0 @@
//
// FILE: max31855_demo4.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.2
// PURPOSE: thermocouple lib demo application
// DATE: 2014-01-02
// URL: https://github.com/RobTillaart/MAX31855_RT
//
#include "MAX31855.h"
const int doPin = 7;
const int csPin = 6;
const int clPin = 5;
MAX31855 tc(clPin, csPin, doPin);
void setup()
{
Serial.begin(115200);
Serial.print("Start max31855_demo4: ");
Serial.println(MAX31855_VERSION);
Serial.println();
tc.begin();
uint32_t start = micros();
for (int i = 0; i < 10; i++) tc.read();
uint32_t stop = micros();
Serial.print("10x read:\t");
Serial.println(stop - start);
start = micros();
float t1 = tc.getTemperature();
stop = micros();
Serial.print("getTemperature:\t");
Serial.println(stop - start);
Serial.println(t1, 2);
Serial.println();
start = micros();
tc.setOffset(2.0);
stop = micros();
Serial.print("setOffset:\t");
Serial.println(stop - start);
start = micros();
tc.getOffset();
stop = micros();
Serial.print("getOffset:\t");
Serial.println(stop - start);
tc.read();
start = micros();
t1 = tc.getTemperature();
stop = micros();
Serial.print("getTemperature:\t");
Serial.println(stop - start);
Serial.println(t1, 2);
Serial.println();
start = micros();
float t2 = tc.getInternal();
stop = micros();
Serial.print("getInternal:\t");
Serial.println(stop - start);
Serial.println(t2, 4);
Serial.println();
}
void loop()
{
}
// -- END OF FILE --

View File

@ -1,55 +0,0 @@
//
// FILE: max31855_demo5.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.4
// PURPOSE: thermocouple lib demo application
// DATE: 2014-01-02
// URL: https://github.com/RobTillaart/MAX31855_RT
//
#include "MAX31855.h"
const int doPin = 7;
const int csPin = 6;
const int clPin = 5;
MAX31855 tc(clPin, csPin, doPin);
void setup()
{
Serial.begin(115200);
Serial.print("Start max31855_demo5: ");
Serial.println(MAX31855_VERSION);
Serial.println();
tc.begin();
tc.read();
float t1 = tc.getTemperature();
Serial.print(" temp before:\t");
Serial.println(t1, 2);
float offset = tc.getOffset();
Serial.print("offset before:\t");
Serial.println(offset, 2);
tc.setOffset(3.14);
offset = tc.getOffset();
Serial.print(" offset after:\t");
Serial.println(offset, 2);
tc.read();
float t2 = tc.getTemperature();
Serial.print(" temp after:\t");
Serial.println(t2, 2);
Serial.print(" temp delta:\t");
Serial.println(abs(t1 - t2), 2);
Serial.println("\ndone...");
}
void loop()
{
}
// -- END OF FILE --

View File

@ -1,54 +0,0 @@
//
// FILE: max31855_demo6.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// PURPOSE: thermocouple lib demo setSeebeckCoefficient()
// DATE: 2015-12-06
// URL: https://github.com/RobTillaart/MAX31855_RT
//
#include "MAX31855.h"
const int doPin = 7;
const int csPin = 6;
const int clPin = 5;
MAX31855 tc(clPin, csPin, doPin);
void setup()
{
Serial.begin(115200);
Serial.print("Start max31855_demo6: ");
Serial.println(MAX31855_VERSION);
Serial.println();
tc.begin();
tc.read();
float t1 = tc.getTemperature();
Serial.print(" temp before:\t");
Serial.println(t1, 2);
float tcf = tc.getSeebeckCoefficient();
Serial.print("SeebeckCoefficient before:\t");
Serial.println(tcf, 4);
Serial.println("\nChange default K-type to J-type ThermoCouple");
tc.setSeebeckCoefficient(J_TC);
tcf = tc.getSeebeckCoefficient();
Serial.print(" SeebeckCoefficient after:\t");
Serial.println(tcf, 4);
tc.read();
float t2 = tc.getTemperature();
Serial.print(" temp after:\t");
Serial.println(t2, 2);
Serial.print(" temp delta:\t");
Serial.println(abs(t1 - t2), 2);
Serial.println("\ndone...");
}
void loop()
{
}

View File

@ -1,68 +0,0 @@
//
// FILE: max31855_hw_SPI.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: thermocouple lib demo application
// DATE: 2020-08-30
// URL: https://github.com/RobTillaart/MAX31855_RT
//
#include "MAX31855.h"
//
// | HW SPI | UNO | ESP32 |
// |:---------|:-----:|:-------:|
// | CLOCKPIN | 13 | 18 |
// | MISO | 12 | 19 |
// | MOSI | 11 | 23 |
// read() timing UNO
// HWSPI 16000000 ~68 us
// HWSPI 4000000 ~72 us
// HWSPI 1000000 ~100 us
// HWSPI 500000 ~128 us
// SWSPI bitbang ~500 us
const int csPin = 6;
uint32_t start, stop;
MAX31855 tc(csPin);
// MAX31855 tc(13, 6, 12); // sw SPI
void setup()
{
Serial.begin(115200);
Serial.print("Start max31855_demo0: ");
Serial.println(MAX31855_VERSION);
Serial.println();
tc.begin();
}
void loop()
{
start = micros();
int status = tc.read();
stop = micros();
Serial.println();
Serial.print("time:\t\t");
Serial.println(stop - start);
Serial.print("stat:\t\t");
Serial.println(status);
uint32_t raw = tc.getRawData();
Serial.print("raw:\t\t");
Serial.println(raw, BIN);
float internal = tc.getInternal();
Serial.print("internal:\t");
Serial.println(internal);
float temp = tc.getTemperature();
Serial.print("temperature:\t");
Serial.println(temp);
delay(1000);
}

View File

@ -1,55 +0,0 @@
//
// FILE: max31855_test_error.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// PURPOSE: thermocouple lib inline tests
// DATE: 2019-07-31
// URL: https://github.com/RobTillaart/MAX31855_RT
//
#include "MAX31855.h"
const int doPin = 7;
const int csPin = 6;
const int clPin = 5;
MAX31855 tc(clPin, csPin, doPin);
void setup()
{
Serial.begin(115200);
Serial.print("Start max31855_test_error: ");
Serial.println(MAX31855_VERSION);
Serial.println();
tc.begin();
}
void loop()
{
int status = tc.read();
Serial.print("stat:\t\t");
Serial.println(status);
if (tc.getStatus())
{
Serial.print("error:\t\t");
if (tc.shortToGND()) Serial.println("SHORT TO GROUND");
if (tc.shortToVCC()) Serial.println("SHORT TO VCC");
if (tc.openCircuit()) Serial.println("OPEN CIRCUIT");
if (tc.genericError()) Serial.println("GENERIC ERROR");
if (tc.noRead()) Serial.println("NO READ");
if (tc.noCommunication()) Serial.println("NO COMMUNICATION");
}
float internal = tc.getInternal();
Serial.print("internal:\t");
Serial.println(internal, 3);
float temp = tc.getTemperature();
Serial.print("temperature:\t");
Serial.println(temp, 2);
delay(1000);
}
// -- END OF FILE --

View File

@ -1,49 +0,0 @@
# Syntax Coloring Map For MAX31855
# Datatypes (KEYWORD1)
MAX31855 KEYWORD1
# Methods and Functions (KEYWORD2)
begin KEYWORD2
read KEYWORD2
getInternal KEYWORD2
getTemperature KEYWORD2
getStatus KEYWORD2
shortToGND KEYWORD2
shortToVCC KEYWORD2
openCircuit KEYWORD2
genericError KEYWORD2
noRead KEYWORD2
noCommunication KEYWORD2
setOffset KEYWORD2
getOffset KEYWORD2
setSeebeckCoefficient KEYWORD2
getSeebeckCoefficient KEYWORD2
lastRead KEYWORD2
getRawData KEYWORD2
# Instances (KEYWORD2)
# Constants (LITERAL1)
MAX31855_VERSION LITERAL1
STATUS_OK LITERAL1
STATUS_OPEN_CIRCUIT LITERAL1
STATUS_SHORT_TO_GND LITERAL1
STATUS_SHORT_TO_VCC LITERAL1
STATUS_ERROR LITERAL1
STATUS_NOREAD LITERAL1
STATUS_NO_COMMUNICATION LITERAL1
E_TC LITERAL1
J_TC LITERAL1
K_TC LITERAL1
N_TC LITERAL1
R_TC LITERAL1
S_TC LITERAL1
T_TC LITERAL1

View File

@ -1,21 +0,0 @@
{
"name": "MAX31855",
"keywords": "MAX31855,Thermocouple,K type,temperature, offset, MAX31855K",
"description": "Arduino library for MAX31855 chip for K type thermocouple. Has experimental support for other types of thermocouples.",
"authors":
[
{
"name": "Rob Tillaart",
"email": "Rob.Tillaart@gmail.com",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/RobTillaart/MAX31855_RT"
},
"version":"0.2.3",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -1,11 +0,0 @@
name=MAX31855_RT
version=0.2.3
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for MAX31855 chip for K type thermocouple.
paragraph=Experimental support for "E, J, K, N, R, S, T" type TC.
category=Sensors
url=https://github.com/RobTillaart/MAX31855_RT
architectures=*
includes=MAX31855.h
depends=

View File

@ -1,219 +0,0 @@
# MAX31855_RT
Arduino library for MAX31855 chip for K type thermocouple
## Description
The MAX38155 is a chip to convert the reading of a K-type thermocouple to a temperature.
The working of thermocouples (TC) is based upon Seebeck effect.
Different TC's have a different Seebeck Coefficient (SC) expressed in µV/°C.
See http://www.analog.com/library/analogDialogue/archives/44-10/thermocouple.html
For every type of TC there exist an MAX31855 variant, this library is primary
developed for the K-type sensor. However it has experimental support for all
other types of TC's. See details below.
Library tested with breakout board
```
+---------+
Vin | o |
3Vo | o |
GND | o O | Thermocouple
D0 | o O | Thermocouple
CS | o |
CLK | o |
+---------+
```
## Hardware SPI vs software SPI
Default pin connections (ESP32 has more options)
| HW SPI | UNO | ESP32 |
|:---------|:-----:|:-------:|
| CLOCKPIN | 13 | 18 |
| MISO | 12 | 19 |
| MOSI | 11 | 23 |
Performance read() function, timing in us.
| mode | clock | timng UNO |
|:----|----:|----:|
| HWSPI | 16000000 | ~68 |
| HWSPI | 4000000 | ~72 |
| HWSPI | 1000000 | ~100 |
| HWSPI | 500000 | ~128 |
| SWSPI | bitbang | ~500 |
## Interface
To make a temperature reading call **tc.read()**.
It returns the status of the read which is a value between 0..7
The function **getStatus()** returns the same status value.
Table: values returned from **read()** and **getStatus()**
| value | Description | Action |
|:----:|:----|:----|
| 0 | OK | - |
| 1 | Thermocouple open circuit | check wiring |
| 2 | Thermocouple short to GND | check wiring |
| 4 | Thermocouple short to VCC | check wiring |
| 7 | Generic error | |
| 128 | No read done yet | check wiring |
| 129 | No communication | check wiring |
There are six functions to check the individual error conditions mentioned above.
These make it easier to check them.
- **openCircuit()**
- **shortToGND()**
- **shortToVCC()**
- **genericError()**
- **noRead()**
- **noCommunication()**
After a **tc.read()** you can get the temperature with **tc.getTemperature()**
and **tc.getInternal()** for the interrnal temperature of the chip / board itself.
Repeated calls to **tc.getTemperature()** will give the same value until a new **tc.read()**.
The latter fetches a new value from the sensor. Note that if the **tc.read()** fails
the value of **tc.getTemperature()** can become incorrect.
The library supports a fixed offset to callibrate the thermocouple.
For this the functions **tc.getOffset()** and **tc.setOffset(offset)** are available.
This offset is included in the **tc.getTemperature()** function.
As the **tc** object holds its last known temperature it is easy to determine the delta
with the last known temperature, e.g. for trend analysis.
```cpp
float last = tc.getTemperature();
int state = tc.read();
if (state == STATUS_OK)
{
float new = tc.getTemperature();
float delta = new - last;
// process data
}
```
The **tc** object keeps track of the last time **tc.read()** is called in the function **tc.lastRead()**.
The time is tracked in **millis()**. This makes it easy to read the sensor at certain intervals.
```cpp
if (millis() - tc.lastRead() >= interval)
{
int state = tc.read();
if (state == STATUS_OK)
{
float new = tc.getTemperature();
// process read value.
}
else
{
// handle error
}
}
```
## GetRawData
The function **tc.getRawData()** allows you to get all the 32 bits raw data from the board,
after the standard **tc.read()** call.
Example code can be found in the examples folder.
```cpp
int state = thermocouple.read();
uint32_t value = thermocouple.getRawData(); // Read the raw Data value from the module
```
## Pull Up Resistor
To have proper working of the MAX31855 board, you need to add a pull-up resistor
(e.g. 4K7 - 1K depending on wirelength) between the MISO pin (from constructor call) and the
VCC (5Volt). This improves the signal quality and will allow you to detect if there is
proper communication with the board. WIthout pull-up one might get random noise that could
look like real data.
**Note:** the MISO pin can be different from each board, please refer to your board datasheet.
If the MAX31855 board is not connected **tc.read()** will return **STATUS_NO_COMMUNICATION**.
You can verify this by **tc.getRawData()** which will give 32 HIGH bits or 0xFFFFFFFF).
You can use a simple code to detect connection error board:
```cpp
uint8_t status = thermocouple.read();
if (status == STATUS_NO_COMMUNICATION)
{
Serial.println("NO COMMUNICATION");
}
```
or
```cpp
uint8_t status = thermocouple.read();
if (thermocouple.getRawData() == 0xFFFFFFFF)
{
Serial.println("NO COMMUNICATION");
}
```
## Operation
See examples
## Experimental part (to be tested)
**NOTE:**
The support for other thermocouples is experimental **use at your own risk**.
The MAX31855 is designed for K type sensors. It essentially measures a
voltage difference and converts this voltage using the Seebeck Coefficient (SC)
to the temperature. As the SC is lineair in its nature it is possible
to replace the K-type TC with one of the other types of TC.
Datasheet Table 1, page 8
| Sensor type | Seebeck Coefficient (µV/°C) | Temp Range (°C) | Material |
|:----:|:----|:----|:----|
| E_TC | 76.373 | -270 to +1000 | Constantan Chromel |
| J_TC | 57.953 | -210 to +1200 | Constantan Iron |
| K_TC | 41.276 | -270 to +1372 | Alumel Chromel |
| N_TC | 36.256 | -270 to +1300 | Nisil Nicrosil |
| R_TC | 10.506 | -50 to +1768 | Platinum Platinum/Rhodium |
| S_TC | 9.587 | +50 to +1768 | Platinum Platinum/Rhodium |
| T_TC | 52.18 | -270 to +400 | Constantan Copper |
The core formula to calculate the temperature is (Datasheet page 8)
```
Vout = (41.276µV/°C) x (Temp_R - Temp_internal)
```
As we know the internal temperature and the returned temperature from the sensor
the library can calculate the Vout measured (as the chip assumes that a K-type
thermocouple is connected.
Having that Vout we can redo the math for the actual thermocouple type and
calculate the real temperature.
The library has two functions **tc.setSeebeckCoefficient(factor)** and
**tc.getSeebeckCoefficient()**
to get/set the Seebeck Coefficient (== thermocouple) to be used.
One can adjust the values to improve the accuracy of the temperature read.
The **tc.getTemperature()** has implemented this algorithm, however as long
as one does not set the Seebeck Coefficient it will use the K_TC as default.

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2019-2020 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

@ -1,159 +0,0 @@
//
// FILE: MCP23017.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// PURPOSE: Arduino library for I2C MCP23017 16 channel port expander
// DATE: 2019-10-12
// URL: https://github.com/RobTillaart/MCP23017_RT
// LICENSE: MIT
//
// HISTORY:
// 0.1.0 2019-10-12 initial version
// 0.1.1 2020-06-19 refactor; #pragma once
//
// TODO:
// interrupts
// caching for performance?
// INPUT_PULLUP
//
#include "MCP23017.h"
#define MCP23017_DDR_A 0x00 // Data Direction Register
#define MCP23017_DDR_B 0x01
#define MCP23017_PUR_A 0x0C // Pull Up Resistors
#define MCP23017_PUR_B 0x0D
#define MCP23017_IOCR 0x0A // IO control register
#define MCP23017_GPIOA 0x12
#define MCP23017_GPIOB 0x13
MCP23017::MCP23017(uint8_t addr)
{
_addr = addr;
}
#if defined(ESP8266) || defined(ESP32)
void MCP23017::begin(const uint8_t dataPin, const uint8_t clockPin)
{
Wire.begin(dataPin, clockPin);
// Force INPUT_PULLUP
writeReg(MCP23017_PUR_A, 0xFF);
writeReg(MCP23017_PUR_B, 0xFF);
}
#endif
void MCP23017::begin()
{
Wire.begin();
// Force INPUT_PULLUP
writeReg(MCP23017_IOCR, 0b00100000); // disable addres increment (datasheet)
writeReg(MCP23017_PUR_A, 0xFF);
writeReg(MCP23017_PUR_B, 0xFF);
}
// single pin interface
// pin 0..15
// value INPUT, OUTPUT, INPUT_PULLUP
// TODO: split INPUT_PULLUP and INPUT, for now they are the same
void MCP23017::pinMode(uint8_t pin, uint8_t value)
{
if (pin > 15) return;
if (value != INPUT && value != INPUT_PULLUP && value != OUTPUT) return;
uint8_t DDR = MCP23017_DDR_A; // Data Direction Register
if (pin > 7)
{
DDR = MCP23017_DDR_B;
pin -= 8;
}
uint8_t val = readReg(DDR);
uint8_t mask = 1 << pin;
// only work with valid
if (value == INPUT || value == INPUT_PULLUP)
{
val |= mask;
}
else if (value == OUTPUT)
{
val &= ~mask;
}
// other values won't change val ....
writeReg(DDR, val);
}
void MCP23017::digitalWrite(uint8_t pin, uint8_t value) // pin = 0..15
{
if (pin > 15) return;
uint8_t IOR = MCP23017_GPIOA;
if (pin > 7)
{
IOR = MCP23017_GPIOB;
pin -= 8;
}
uint8_t val = readReg(IOR);
uint8_t mask = 1 << pin;
if (value) val |= mask;
else val &= ~mask;
writeReg(IOR, val);
}
uint8_t MCP23017::digitalRead(uint8_t pin)
{
if (pin > 15) return -100; // TODO magic number
uint8_t IOR = MCP23017_GPIOA;
if (pin > 7)
{
IOR = MCP23017_GPIOB;
pin -= 8;
}
uint8_t val = readReg(IOR);
uint8_t mask = 1 << pin;
if (val & mask) return HIGH;
return LOW;
}
// 8 pins interface
// whole register at once
void MCP23017::pinMode8(uint8_t port, uint8_t value)
{
if (port == 0) writeReg(MCP23017_DDR_A, value);
if (port == 1) writeReg(MCP23017_DDR_B, value);
// explicitely ignore other values.
}
void MCP23017::write8(uint8_t port, uint8_t value) // port = 0..1
{
if (port == 0) writeReg(MCP23017_GPIOA, value);
if (port == 1) writeReg(MCP23017_GPIOB, value);
// explicitely ignore other values.
}
int MCP23017::read8(uint8_t port)
{
if (port == 0) return readReg(MCP23017_GPIOA);
if (port == 1) return readReg(MCP23017_GPIOB);
return -100; // TODO magic number
}
void MCP23017::writeReg(uint8_t reg, uint8_t value)
{
Wire.beginTransmission(_addr);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
uint8_t MCP23017::readReg(uint8_t reg)
{
Wire.beginTransmission(_addr);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(_addr, (uint8_t)1);
return Wire.read();
}
// -- END OF FILE --

View File

@ -1,42 +0,0 @@
#pragma once
//
// FILE: MCP23017.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// PURPOSE: Arduino library for I2C MCP23017 16 channel port expander
// DATE: 2019-10-12
// URL: https://github.com/RobTillaart/MCP23017_RT
// LICENSE: MIT
#include "Arduino.h"
#include "Wire.h"
#define MCP23017_LIB_VERSION "0.1.1"
class MCP23017
{
public:
MCP23017(uint8_t addr);
#if defined(ESP8266) || defined(ESP32)
void begin(const uint8_t dataPin, const uint8_t clockPin);
#endif
void begin();
// single pin interface
void pinMode(uint8_t pin, uint8_t value);
void digitalWrite(uint8_t pin, uint8_t value);
uint8_t digitalRead(uint8_t pin);
// 8 pins interface
void pinMode8(uint8_t port, uint8_t value);
void write8(uint8_t port, uint8_t value);
int read8(uint8_t port);
private:
void writeReg(uint8_t reg, uint8_t value);
uint8_t readReg(uint8_t reg);
uint8_t _addr;
};
// -- END OF FILE --

View File

@ -1,26 +0,0 @@
# MCP23017_RT
Arduino library for I2C MCP23017 16 channel port expander
## Description
Short discription of the interface
* **MCP23017(address)** constructor
* **begin()**
* **begin(sda, scl)** for ESP32
single pin interface
* **pinMode(pin, value)** pin = 0..16 value = INPUT,OUTPUT
* **digitalWrite(pin, value)** pin = 0..16 value = LOW(0) HIGH (!0)
* **digitalRead(pin)** pin = 0..16
8 pins interface
* **pinMode8(port, value)** port = 0, 1 value =
* **write8(port, value)** port = 0, 1 value =
* **read8(port)** port = 0, 1
## Operation
See examples

View File

@ -1,42 +0,0 @@
//
// FILE: MCP23017_test.ino
// AUTHOR: Rob Tillaart
// DATE: 2019-10-14
//
// PUPROSE: test MCP23017 library
//
#include "MCP23017.h"
#include <Wire.h>
MCP23017 MCP(0x38);
void setup()
{
Serial.begin(230400);
Serial.print("MCP23017_test version: ");
Serial.println(MCP23017_LIB_VERSION);
Wire.begin();
MCP.begin();
MCP.pinMode8(0, 0x00); // CHECK
MCP.pinMode8(1, 0x00);
Serial.println("TEST digitalRead(pin)");
for (int pin = 0; pin < 16; pin++)
{
int val = MCP.digitalRead(pin);
Serial.print(val);
Serial.print('\t');
}
Serial.println();
}
void loop()
{
}

View File

@ -1,65 +0,0 @@
//
// FILE: MCP23017_test.ino
// AUTHOR: Rob Tillaart
// DATE: 2019-10-14
//
// PUPROSE: test MCP23017 library
//
#include "MCP23017.h"
#include <Wire.h>
MCP23017 MCP(0x27);
void setup()
{
Serial.begin(230400);
Serial.print("MCP23017_test version: ");
Serial.println(MCP23017_LIB_VERSION);
Wire.begin();
MCP.begin();
MCP.pinMode8(0, 0x00); // 0 = output , 1 = input
MCP.pinMode8(1, 0x00);
Wire.setClock(50);
Serial.println("TEST digitalWrie(0)");
for (int i = 0; i < 16; i++)
{
MCP.digitalWrite(0, i % 2); // alternating HIGH/LOW
Serial.print(i % 2);
Serial.print('\t');
delay(250);
}
Serial.println();
Serial.println();
Serial.println("TEST digitalWrie(pin)");
for (int pin = 0; pin < 16; pin++)
{
MCP.digitalWrite(pin, 1 - pin % 2); // alternating HIGH/LOW
Serial.print(1 - pin % 2);
Serial.print('\t');
}
Serial.println();
Serial.println();
Serial.println("TEST read back");
for (int pin = 0; pin < 16; pin++)
{
int val = MCP.digitalRead(pin);
Serial.print(val);
Serial.print('\t');
}
Serial.println();
Serial.println();
}
void loop()
{
}
// -- END OF FILE --

View File

@ -1,21 +0,0 @@
{
"name": "MCP23017",
"keywords": "MCP23017,I2C,16 I/O",
"description": "Arduino library for I2C MCP23017 16 channel port expander",
"authors":
[
{
"name": "Rob Tillaart",
"email": "Rob.Tillaart@gmail.com",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/RobTillaart/MCP23017_RT.git"
},
"version":"0.1.1",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -1,11 +0,0 @@
name=MCP23017_RT
version=0.1.1
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for I2C MCP23017 16 channel port expander 16 IO-lines
paragraph=
category=Signal Input/Output
url=https://github.com/RobTillaart/MCP23017_RT
architectures=*
includes=MCP23017.h
depends=

View File

@ -1,20 +1,22 @@
//
// FILE: MCP_ADC.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.2
// VERSION: 0.1.3
// DATE: 2019-10-24
// PURPOSE: Arduino library for MCP3002, MCP3004, MCP3008, MCP3202, MCP3204, MCP3208
// URL: https://github.com/RobTillaart/MCP_ADC
//
#include "MCP_ADC.h"
MCP_ADC::MCP_ADC(uint8_t dataIn, uint8_t dataOut, uint8_t clock)
{
_dataIn = dataIn;
_dataOut = dataOut;
_clock = clock;
_hwSPI = (dataIn == 255) && (dataOut == 255) && (clock == 255);
_hwSPI = (dataIn == 255) || (dataOut == 255) || (clock == 255);
if (_hwSPI == false)
{
pinMode(_dataIn, INPUT);
@ -22,10 +24,14 @@ MCP_ADC::MCP_ADC(uint8_t dataIn, uint8_t dataOut, uint8_t clock)
pinMode(_clock, OUTPUT);
digitalWrite(_dataOut, LOW);
digitalWrite(_clock, LOW);
// _SPIspeed = 0; TODO set to zero if SW SPI
}
else
{
SPI.begin();
}
}
void MCP_ADC::begin(uint8_t select)
{
_select = select;
@ -33,18 +39,21 @@ void MCP_ADC::begin(uint8_t select)
digitalWrite(_select, HIGH);
}
int16_t MCP_ADC::analogRead(uint8_t channel)
{
if (channel >= _channels) return 0;
return readADC(channel, true);
}
int16_t MCP_ADC::differentialRead(uint8_t channel)
{
if (channel >= _channels) return 0;
return readADC(channel, false);
}
int16_t MCP_ADC::deltaRead(uint8_t channel)
{
if (channel >= _channels) return 0;
@ -58,16 +67,6 @@ int16_t MCP_ADC::deltaRead(uint8_t channel)
return val0 - val1;
}
void MCP_ADC::setSPIspeed(uint32_t speed)
{
_SPIspeed = speed;
};
uint32_t MCP_ADC::getSPIspeed()
{
return _SPIspeed;
};
int16_t MCP_ADC::readADC(uint8_t channel, bool single)
{
@ -76,33 +75,31 @@ int16_t MCP_ADC::readADC(uint8_t channel, bool single)
uint8_t data[3] = { 0,0,0 };
uint8_t bytes = buildRequest(channel, single, data);
// TODO optimize _select handling
digitalWrite(_select, LOW);
if (_hwSPI)
{
SPI.beginTransaction(SPISettings(_SPIspeed, MSBFIRST, SPI_MODE0));
digitalWrite(_select, LOW);
for (uint8_t b = 0; b < bytes; b++)
{
data[b] = SPI.transfer(data[b]);
}
digitalWrite(_select, HIGH);
SPI.endTransaction();
}
else // Software SPI
{
digitalWrite(_select, LOW);
for (uint8_t b = 0; b < bytes; b++)
{
data[b] = swSPI_transfer(data[b]);
}
digitalWrite(_select, HIGH);
}
digitalWrite(_select, HIGH);
if (bytes == 2) return ((256 * data[0] + data[1]) & _maxValue);
// data[0]?
return ((256 * data[1] + data[2]) & _maxValue);
}
// MSBFIRST
uint8_t MCP_ADC::swSPI_transfer(uint8_t val)
{

View File

@ -2,20 +2,24 @@
//
// FILE: MCP_ADC.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.2
// VERSION: 0.1.3
// DATE: 2019-10-24
// PURPOSE: Arduino library for MCP_ADC
// URL: https://github.com/RobTillaart/MCP_ADC
//
#include "Arduino.h"
#include "SPI.h"
#define MCP_ADC_LIB_VERSION (F("0.1.3"))
class MCP_ADC
{
public:
MCP_ADC(uint8_t dataIn = 255, uint8_t dataOut = 255, uint8_t clock = 255);
// if only select is given ==> HW SPI
void begin(uint8_t select);
uint8_t channels() { return _channels; };
@ -23,9 +27,9 @@ public:
int16_t analogRead(uint8_t channel);
int16_t differentialRead(uint8_t channel);
int16_t deltaRead(uint8_t channel);
// speed in Hz
void setSPIspeed(uint32_t speed);
uint32_t getSPIspeed();
// speed in Hz
void setSPIspeed(uint32_t speed) { _SPIspeed = speed; };
uint32_t getSPIspeed() { return _SPIspeed; };
protected:
uint8_t _dataIn;

View File

@ -14,7 +14,8 @@
MCP3002 mcp2;
MCP3004 mcp4;
MCP3008 mcp8;
// MCP3008 mcp8(11,12,13); // software spi
MCP3008 mcp8; // hardware spi
MCP3202 mcp22;
MCP3204 mcp24;
MCP3208 mcp28;
@ -26,9 +27,9 @@ void setup()
Serial.begin(115200);
Serial.println(__FILE__);
mcp2.begin(10);
mcp2.begin(8);
mcp4.begin(9);
mcp8.begin(8);
mcp8.begin(10);
Serial.println();
@ -71,11 +72,12 @@ void setup()
test_2();
test_3();
// on UNO there is no difference above 8MHz (half CPU clock)
Serial.println("***************************************\n");
for (int s = 1; s <= 16; s++)
for (int s = 1; s <= 16; s *= 2)
{
Serial.println(s * 1000000);
mcp8.setSPIspeed(s);
Serial.println(s * 1000000UL);
mcp8.setSPIspeed(s * 1000000UL);
test_3();
}
@ -163,7 +165,7 @@ void test_3()
uint32_t val = 0;
start = micros();
for (int channel = 0 ; channel < mcp8.channels(); channel++)
for (int channel = 0; channel < mcp8.channels(); channel++)
{
val += mcp8.analogRead(channel);
}
@ -173,7 +175,7 @@ void test_3()
delay(10);
start = micros();
for (int channel = 0 ; channel < mcp8.channels(); channel++)
for (int channel = 0; channel < mcp8.channels(); channel++)
{
val += mcp8.differentialRead(channel);
}
@ -183,7 +185,7 @@ void test_3()
delay(10);
start = micros();
for (int channel = 0 ; channel < mcp8.channels(); channel++)
for (int channel = 0; channel < mcp8.channels(); channel++)
{
val += mcp8.deltaRead(channel);
}

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/MCP_ADC.git"
},
"version":"0.1.2",
"version":"0.1.3",
"frameworks": "*",
"platforms": "*"
}

View File

@ -1,5 +1,5 @@
name=MCP_ADC
version=0.1.2
version=0.1.3
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for MCP3002, MCP3004, MCP3008, MCP3202, MCP3204, MCP3208

1
libraries/MCP_DAC Submodule

@ -0,0 +1 @@
Subproject commit 781afba9a2c362b05401c9a894be53b565b56842

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2016-2020 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

@ -1,258 +0,0 @@
//
// FILE: PCA9685.cpp
// AUTHOR: Rob Tillaart
// DATE: 24-apr-2016
// VERSION: 0.3.0
// PURPOSE: Arduino library for I2C PCA9685 16 channel PWM
// URL: https://github.com/RobTillaart/PCA9685_RT
//
// HISTORY:
// 0.1.0 2016-04-24 initial BETA version
// 0.1.1 2019-01-30 testing && fixing
// 0.2.0 2020-05-25 refactor; ESP32 begin(sda,scl)
// 0.2.1 2020-06-19 fix library.json
// 0.2.2 2020-09-21 fix #1 + add getFrequency()
// 0.2.3 2020-11-21 fix digitalWrite (internal version only)
// 0.3.0 2020-11-22 fix setting frequency
#include "PCA9685.h"
// REGISTERS CONFIGURATION - check datasheet for details
#define PCA9685_MODE1 0x00
#define PCA9685_MODE2 0x01
// MODE1 REGISTERS
#define PCA9685_RESTART 0x80
#define PCA9685_EXTCLK 0x40
#define PCA9685_AUTOINCR 0x20
#define PCA9685_SLEEP 0x10
#define PCA9685_SUB1 0x08
#define PCA9685_SUB2 0x04
#define PCA9685_SUB3 0x02
#define PCA9685_ALLCALL 0x01
// MODE2 REGISTERS (see datasheet)
#define PCA9685_INVERT 0x10
#define PCA9685_OCH 0x08
#define PCA9685_OUTDRV 0x04
#define PCA9685_OUTNE 0x03
// REGISTERS - CHANNELS
#define PCA9685_CHANNEL_0 0x06 // 0x06 + 4*channel is base per channel
// REGISTERS - FREQUENCY
#define PCA9685_PRE_SCALER 0xFE
// REGISTERS - Subaddressing I2C - not implemented
#define PCA9685_SUBADR(x) (0x01+(x)) // x = 1..3
#define PCA9685_ALLCALLADR 0x05
// REGISTERS - ALL_ON ALL_OFF - partly implemented
#define PCA9685_ALL_ON_L 0xFA
#define PCA9685_ALL_ON_H 0xFB
#define PCA9685_ALL_OFF_L 0xFC
#define PCA9685_ALL_OFF_H 0xFD // used for allOFF()
// NOT IMPLEMENTED YET
#define PCA9685_TESTMODE 0xFF // do not be use. see datasheet.
//////////////////////////////////////////////////////////////
//
// Constructor
//
PCA9685::PCA9685(const uint8_t deviceAddress)
{
_address = deviceAddress;
_error = 0;
}
#if defined (ESP8266) || defined(ESP32)
void PCA9685::begin(uint8_t sda, uint8_t scl)
{
Wire.begin(sda, scl);
reset();
}
#endif
void PCA9685::begin()
{
Wire.begin();
reset();
}
void PCA9685::reset()
{
_error = 0;
writeMode(PCA9685_MODE1, PCA9685_AUTOINCR | PCA9685_ALLCALL);
writeMode(PCA9685_MODE2, PCA9685_OUTDRV);
}
void PCA9685::writeMode(uint8_t reg, uint8_t value)
{
if ((reg != PCA9685_MODE1) && (reg != PCA9685_MODE2))
{
_error = PCA9685_ERR_MODE;
return;
}
writeReg(reg, value);
}
uint8_t PCA9685::readMode(uint8_t reg)
{
if ((reg != PCA9685_MODE1) && (reg != PCA9685_MODE2))
{
_error = PCA9685_ERR_MODE;
return 0;
}
uint8_t value = readReg(reg);
return value;
}
// write value to single PWM channel
void PCA9685::setPWM(uint8_t channel, uint16_t onTime, uint16_t offTime)
{
if (channel > 15)
{
_error = PCA9685_ERR_CHANNEL;
return;
}
offTime &= 0x0FFFF; // non-doc feature - to easy set figure 8 P.17
uint8_t reg = PCA9685_CHANNEL_0 + (channel << 2);
writeReg2(reg, onTime, offTime);
}
// write value to single PWM channel
void PCA9685::setPWM(uint8_t channel, uint16_t offTime)
{
setPWM(channel, 0, offTime);
}
// read value from single PWM channel
void PCA9685::getPWM(uint8_t channel, uint16_t* onTime, uint16_t* offTime)
{
if (channel > 15)
{
_error = PCA9685_ERR_CHANNEL;
return;
}
uint8_t reg = PCA9685_CHANNEL_0 + (channel << 2);
Wire.beginTransmission(_address);
Wire.write(reg);
_error = Wire.endTransmission();
if (Wire.requestFrom(_address, (uint8_t)4) != 4)
{
_error = PCA9685_ERR_I2C;
return;
}
uint16_t _data = Wire.read();
*onTime = (Wire.read() * 256) + _data;
_data = Wire.read();
*offTime = (Wire.read() * 256) + _data;
}
// set update frequency for all channels
void PCA9685::setFrequency(uint16_t freq, int offset)
{
_freq = freq;
if (_freq < 24) _freq = 24; // page 25 datasheet
if (_freq > 1526) _freq = 1526;
// removed float operation for speed
// faster but equal accurate
// uint8_t scaler = round(25e6 / (_freq * 4096)) - 1;
uint8_t scaler = 48828 / (_freq * 8) - 1;
uint8_t mode1 = readMode(PCA9685_MODE1);
writeMode(PCA9685_MODE1, mode1 | PCA9685_SLEEP);
scaler += offset;
writeReg(PCA9685_PRE_SCALER, scaler);
writeMode(PCA9685_MODE1, mode1);
}
int PCA9685::getFrequency(bool cache)
{
if (cache) return _freq;
uint8_t scaler = readReg(PCA9685_PRE_SCALER);
scaler++;
_freq = 48828 / scaler;
_freq /= 8;
return _freq;
}
// datasheet P.18 - fig. 9:
// Note: bit[11-0] ON should NOT equal timer OFF in ON mode
// in OFF mode it doesn't matter.
void PCA9685::digitalWrite(uint8_t channel, uint8_t mode)
{
if (channel > 15)
{
_error = PCA9685_ERR_CHANNEL;
return;
}
uint8_t reg = PCA9685_CHANNEL_0 + (channel << 2);
if (mode != LOW) writeReg2(reg, 0x1000, 0x0000);
else writeReg2(reg, 0x0000, 0x0000);
}
void PCA9685::allOFF()
{
writeReg(PCA9685_ALL_OFF_H, 0x10);
}
int PCA9685::lastError()
{
int e = _error;
_error = 0;
return e;
}
//////////////////////////////////////////////////////////////
//
// PRIVATE
//
void PCA9685::writeReg(uint8_t reg, uint8_t value)
{
Wire.beginTransmission(_address);
Wire.write(reg);
Wire.write(value);
_error = Wire.endTransmission();
}
void PCA9685::writeReg2(uint8_t reg, uint16_t a, uint16_t b)
{
Wire.beginTransmission(_address);
Wire.write(reg);
Wire.write(a & 0xFF);
Wire.write((a >> 8) & 0x1F);
Wire.write(b & 0xFF);
Wire.write((b >> 8) & 0x1F);
_error = Wire.endTransmission();
}
uint8_t PCA9685::readReg(uint8_t reg)
{
Wire.beginTransmission(_address);
Wire.write(reg);
_error = Wire.endTransmission();
if (Wire.requestFrom(_address, (uint8_t)1) != 1)
{
_error = PCA9685_ERR_I2C;
return 0;
}
uint8_t _data = Wire.read();
return _data;
}
// -- END OF FILE --

View File

@ -1,82 +0,0 @@
#pragma once
//
// FILE: PCA9685.H
// AUTHOR: Rob Tillaart
// DATE: 24-apr-2016
// VERSION: 0.3.0
// PURPOSE: Arduino library for I2C PCA9685 16 channel PWM
// URL: https://github.com/RobTillaart/PCA9685_RT
//
// HISTORY:
// see PCA9685.cpp file
//
#include "Arduino.h"
#include "Wire.h"
#define PCA9685_LIB_VERSION "0.3.0"
// ERROR CODES
#define PCA9685_OK 0x00
#define PCA9685_ERROR 0xFF
#define PCA9685_ERR_CHANNEL 0xFE
#define PCA9685_ERR_MODE 0xFD
#define PCA9685_ERR_I2C 0xFC
class PCA9685
{
public:
explicit PCA9685(const uint8_t deviceAddress);
#if defined (ESP8266) || defined(ESP32)
void begin(uint8_t sda, uint8_t scl);
#endif
void begin();
void reset();
// reg = 1, 2 check datasheet for values
void writeMode(uint8_t reg, uint8_t value);
uint8_t readMode(uint8_t reg);
// single PWM setting, channel = 0..15,
// onTime = 0..4095, offTime = 0..4095
// allows shifted PWM's e.g. 2 servo's that do not start at same time.
void setPWM(uint8_t channel, uint16_t onTime, uint16_t offTime);
void getPWM(uint8_t channel, uint16_t* onTime, uint16_t* offTime);
// single PWM setting, channel = 0..15, offTime = 0..4095 (onTime = 0)
void setPWM(uint8_t channel, uint16_t offTime);
// set update frequency for all channels
// freq = 24 - 1526 Hz
// note: as the frequency is converted to an 8 bit prescaler
// the frequency set will seldom be exact, but best effort.
void setFrequency(uint16_t freq, int offset = 0);
int getFrequency(bool cache = true);
// set channel HIGH or LOW (effectively no PWM)
void digitalWrite(uint8_t channel, uint8_t mode);
// for backwards compatibility; will be removed in future
void setON(uint8_t channel) { digitalWrite(channel, HIGH); };
void setOFF(uint8_t channel) { digitalWrite(channel, LOW); };
// experimental for 0.3.0
void allOFF();
int lastError();
private:
// DIRECT CONTROL
void writeReg(uint8_t reg, uint8_t value);
void writeReg2(uint8_t reg, uint16_t a, uint16_t b);
uint8_t readReg(uint8_t reg);
uint8_t _address;
int _error;
int _freq = 200; // default PWM frequency - P25 datasheet
};
// -- END OF FILE --

View File

@ -1,89 +0,0 @@
# PCA9685_RT
Arduino library for I2C PCA9685 16 channel PWM extender
# Description
This library is to control the I2C PCA9685 PWM extender.
The 16 channels are independently configurable in steps of 1/4096.
This allows for better than 0.1% finetuning of the duty-cycle
of the PWM signal.
The PWM's of the different channels have individual start and stop moments.
This can be used to distribute the power more evenly over multiple servo's
or give special effects when used in an RGB LED.
The frequency of the PWM can be set from 24 to 1526 according to the datasheet, however in practice not all frequencies are set accurate.
Lower frequencies do better than higher frequencies.
### interface
**begin()** initializes the library after startup. Mandatory.
**begin(sda, scl)** idem, ESP32 ESP8266 only. Library does not support
multiple Wire instances (yet).
**reset()** resets the library to start up conditions.
**writeMode(reg, mode)** configuration of one of the two configuration registers.
check datasheet for details.
**readMode(reg)** reads back the configured mode, useful to add or remove a
single flag (bit masking)
**setPWM(channel, ontime, offtime)** The chip has 16 channels to do PWM.
The signal is divided in 4096 steps, 0..4095.
The pulse can begin =**ontime** on any step and it can stop on any step =**offtime**.
This allows e.g. to distribute the power over the 16 channels, e.g. the
channels do not need to start at the same moment with HIGH.
**setPWM(channel, offtime)** simple PWM that always start on **ontime = 0**
**getPWM(channel, ontime, offtime)** read back the configuration of the channel.
**setFrequency(freq, int offset = 0)** set the update speed of the channels.
This value is set the same for all channels at once.
The frequency is constrained to be between 24 and 1526 Hz.
As the frequency is converted to an 8 bit **prescaler**,
the frequency set will seldom be exact.
After changing the frequency, one must set all channels (again),
so one should set the frequency in **setup()**
The parameter offset can be used to tune the **prescaler** to get a frequency
closer to the requested value. See **PCA9685_setFrequency_offset** example.
Default the offset = 0. As the prescaler is smaller at higher frequencies
higher frequencies are less accurate.
Making offset too large can result in very incorrect frequencies.
When using offset, the **getFrequency(false)** will return the adjusted prescaler.
**getFrequency(cache = true)** get the current update frequency of the channels.
This is same for all channels. If cache is false, the frequency is fetched and
calculated from the **prescaler** register and will probably differ from the
value set with **setFrequency()**.
**digitalWrite(channel, mode)** mode = HIGH or LOW, just use the PCA9685 as
a digitalpin.
This single function replaces the setON() and setOFF() that will become
obsolete in the future.
**allOFF()** switches all PWM channels OFF. **Experimental** in 0.3.0
To "undo" the allOFF one can call the **reset()** function and set all
PWM channels again.
**lastError()** returns **PCA9685_OK = 0** if all is OK, and
| Error code | Value | Description |
|:----|:----:|:----|
| PCA9685_OK | 0x00 | Everything went well
| PCA9685_ERROR | 0xFF | generic error
| PCA9685_ERR_CHANNEL | 0xFE | Channel out of range
| PCA9685_ERR_MODE | 0xFD | Invalid mode register chosen |
| PCA9685_ERR_I2C | 0xFC | PCA9685 I2C communication error
# Operation
See examples

View File

@ -1,53 +0,0 @@
//
// FILE: PCA9685_allOFF_test.ino
// AUTHOR: Rob Tillaart
// DATE: 2020-11-22
// VERSION: 0.1.0
// PUPROSE: test PCA9685 library
//
/*
sets all channels to a PWM
then switches them all off
you can check it by testing all channels.
*/
#include "PCA9685.h"
PCA9685 PCA(0x40);
const uint8_t PIN = 2;
void setup()
{
Wire.begin();
PCA.begin();
Serial.begin(115200);
Serial.print("PCA9685 LIB version: ");
Serial.println(PCA9685_LIB_VERSION);
Serial.println();
pinMode(PIN, INPUT_PULLUP);
for (int channel = 0; channel < 16; channel++)
{
PCA.setPWM(channel, 0, 1000);
}
delay(100); // to be sure they started.
PCA.allOFF();
// delay(100);
// PCA.reset(); // needed to reset the allOFF()
// for (int channel = 0; channel < 16; channel++)
// {
// PCA.digitalWrite(channel, HIGH);
// }
}
void loop()
{
Serial.println(digitalRead(PIN)); // you can measure all pins
}
// -- END OF FILE --

Some files were not shown because too many files have changed in this diff Show More