Compare commits
3 Commits
ea0f514c2b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| a54f29e21e | |||
| ca8f70a887 | |||
| ae617cade4 |
Binary file not shown.
646
libraries/Adafruit_BME280_Library/Adafruit_BME280.cpp
Normal file
646
libraries/Adafruit_BME280_Library/Adafruit_BME280.cpp
Normal file
@@ -0,0 +1,646 @@
|
|||||||
|
/*!
|
||||||
|
* @file Adafruit_BME280.cpp
|
||||||
|
*
|
||||||
|
* @mainpage Adafruit BME280 humidity, temperature & pressure sensor
|
||||||
|
*
|
||||||
|
* @section intro_sec Introduction
|
||||||
|
*
|
||||||
|
* Driver for the BME280 humidity, temperature & pressure sensor
|
||||||
|
*
|
||||||
|
* These sensors use I2C or SPI to communicate, 2 or 4 pins are required
|
||||||
|
* to interface.
|
||||||
|
*
|
||||||
|
* Designed specifically to work with the Adafruit BME280 Breakout
|
||||||
|
* ----> http://www.adafruit.com/products/2652
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* @section author Author
|
||||||
|
*
|
||||||
|
* Written by Kevin "KTOWN" Townsend for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* @section license License
|
||||||
|
*
|
||||||
|
* BSD license, all text here must be included in any redistribution.
|
||||||
|
* See the LICENSE file for details.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Adafruit_BME280.h"
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief class constructor
|
||||||
|
*/
|
||||||
|
Adafruit_BME280::Adafruit_BME280() {}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief class constructor if using hardware SPI
|
||||||
|
* @param cspin the chip select pin to use
|
||||||
|
* @param *theSPI
|
||||||
|
* optional SPI object
|
||||||
|
*/
|
||||||
|
Adafruit_BME280::Adafruit_BME280(int8_t cspin, SPIClass *theSPI) {
|
||||||
|
spi_dev = new Adafruit_SPIDevice(cspin, 1000000, SPI_BITORDER_MSBFIRST,
|
||||||
|
SPI_MODE0, theSPI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief class constructor if using software SPI
|
||||||
|
* @param cspin the chip select pin to use
|
||||||
|
* @param mosipin the MOSI pin to use
|
||||||
|
* @param misopin the MISO pin to use
|
||||||
|
* @param sckpin the SCK pin to use
|
||||||
|
*/
|
||||||
|
Adafruit_BME280::Adafruit_BME280(int8_t cspin, int8_t mosipin, int8_t misopin,
|
||||||
|
int8_t sckpin) {
|
||||||
|
spi_dev = new Adafruit_SPIDevice(cspin, sckpin, misopin, mosipin);
|
||||||
|
}
|
||||||
|
|
||||||
|
Adafruit_BME280::~Adafruit_BME280(void) {
|
||||||
|
if (spi_dev) {
|
||||||
|
delete spi_dev;
|
||||||
|
}
|
||||||
|
if (i2c_dev) {
|
||||||
|
delete i2c_dev;
|
||||||
|
}
|
||||||
|
if (temp_sensor) {
|
||||||
|
delete temp_sensor;
|
||||||
|
}
|
||||||
|
if (pressure_sensor) {
|
||||||
|
delete pressure_sensor;
|
||||||
|
}
|
||||||
|
if (humidity_sensor) {
|
||||||
|
delete humidity_sensor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Initialise sensor with given parameters / settings
|
||||||
|
* @param addr the I2C address the device can be found on
|
||||||
|
* @param theWire the I2C object to use, defaults to &Wire
|
||||||
|
* @returns true on success, false otherwise
|
||||||
|
*/
|
||||||
|
bool Adafruit_BME280::begin(uint8_t addr, TwoWire *theWire) {
|
||||||
|
if (spi_dev == NULL) {
|
||||||
|
// I2C mode
|
||||||
|
if (i2c_dev)
|
||||||
|
delete i2c_dev;
|
||||||
|
i2c_dev = new Adafruit_I2CDevice(addr, theWire);
|
||||||
|
if (!i2c_dev->begin())
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// SPI mode
|
||||||
|
if (!spi_dev->begin())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Initialise sensor with given parameters / settings
|
||||||
|
* @returns true on success, false otherwise
|
||||||
|
*/
|
||||||
|
bool Adafruit_BME280::init() {
|
||||||
|
// check if sensor, i.e. the chip ID is correct
|
||||||
|
_sensorID = read8(BME280_REGISTER_CHIPID);
|
||||||
|
if (_sensorID != 0x60)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// reset the device using soft-reset
|
||||||
|
// this makes sure the IIR is off, etc.
|
||||||
|
write8(BME280_REGISTER_SOFTRESET, 0xB6);
|
||||||
|
|
||||||
|
// wait for chip to wake up.
|
||||||
|
delay(10);
|
||||||
|
|
||||||
|
// if chip is still reading calibration, delay
|
||||||
|
while (isReadingCalibration())
|
||||||
|
delay(10);
|
||||||
|
|
||||||
|
readCoefficients(); // read trimming parameters, see DS 4.2.2
|
||||||
|
|
||||||
|
setSampling(); // use defaults
|
||||||
|
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief setup sensor with given parameters / settings
|
||||||
|
*
|
||||||
|
* This is simply a overload to the normal begin()-function, so SPI users
|
||||||
|
* don't get confused about the library requiring an address.
|
||||||
|
* @param mode the power mode to use for the sensor
|
||||||
|
* @param tempSampling the temp samping rate to use
|
||||||
|
* @param pressSampling the pressure sampling rate to use
|
||||||
|
* @param humSampling the humidity sampling rate to use
|
||||||
|
* @param filter the filter mode to use
|
||||||
|
* @param duration the standby duration to use
|
||||||
|
*/
|
||||||
|
void Adafruit_BME280::setSampling(sensor_mode mode,
|
||||||
|
sensor_sampling tempSampling,
|
||||||
|
sensor_sampling pressSampling,
|
||||||
|
sensor_sampling humSampling,
|
||||||
|
sensor_filter filter,
|
||||||
|
standby_duration duration) {
|
||||||
|
_measReg.mode = mode;
|
||||||
|
_measReg.osrs_t = tempSampling;
|
||||||
|
_measReg.osrs_p = pressSampling;
|
||||||
|
|
||||||
|
_humReg.osrs_h = humSampling;
|
||||||
|
_configReg.filter = filter;
|
||||||
|
_configReg.t_sb = duration;
|
||||||
|
_configReg.spi3w_en = 0;
|
||||||
|
|
||||||
|
// making sure sensor is in sleep mode before setting configuration
|
||||||
|
// as it otherwise may be ignored
|
||||||
|
write8(BME280_REGISTER_CONTROL, MODE_SLEEP);
|
||||||
|
|
||||||
|
// you must make sure to also set REGISTER_CONTROL after setting the
|
||||||
|
// CONTROLHUMID register, otherwise the values won't be applied (see
|
||||||
|
// DS 5.4.3)
|
||||||
|
write8(BME280_REGISTER_CONTROLHUMID, _humReg.get());
|
||||||
|
write8(BME280_REGISTER_CONFIG, _configReg.get());
|
||||||
|
write8(BME280_REGISTER_CONTROL, _measReg.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Writes an 8 bit value over I2C or SPI
|
||||||
|
* @param reg the register address to write to
|
||||||
|
* @param value the value to write to the register
|
||||||
|
*/
|
||||||
|
void Adafruit_BME280::write8(byte reg, byte value) {
|
||||||
|
byte buffer[2];
|
||||||
|
buffer[1] = value;
|
||||||
|
if (i2c_dev) {
|
||||||
|
buffer[0] = reg;
|
||||||
|
i2c_dev->write(buffer, 2);
|
||||||
|
} else {
|
||||||
|
buffer[0] = reg & ~0x80;
|
||||||
|
spi_dev->write(buffer, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Reads an 8 bit value over I2C or SPI
|
||||||
|
* @param reg the register address to read from
|
||||||
|
* @returns the data byte read from the device
|
||||||
|
*/
|
||||||
|
uint8_t Adafruit_BME280::read8(byte reg) {
|
||||||
|
uint8_t buffer[1];
|
||||||
|
if (i2c_dev) {
|
||||||
|
buffer[0] = uint8_t(reg);
|
||||||
|
i2c_dev->write_then_read(buffer, 1, buffer, 1);
|
||||||
|
} else {
|
||||||
|
buffer[0] = uint8_t(reg | 0x80);
|
||||||
|
spi_dev->write_then_read(buffer, 1, buffer, 1);
|
||||||
|
}
|
||||||
|
return buffer[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Reads a 16 bit value over I2C or SPI
|
||||||
|
* @param reg the register address to read from
|
||||||
|
* @returns the 16 bit data value read from the device
|
||||||
|
*/
|
||||||
|
uint16_t Adafruit_BME280::read16(byte reg) {
|
||||||
|
uint8_t buffer[2];
|
||||||
|
|
||||||
|
if (i2c_dev) {
|
||||||
|
buffer[0] = uint8_t(reg);
|
||||||
|
i2c_dev->write_then_read(buffer, 1, buffer, 2);
|
||||||
|
} else {
|
||||||
|
buffer[0] = uint8_t(reg | 0x80);
|
||||||
|
spi_dev->write_then_read(buffer, 1, buffer, 2);
|
||||||
|
}
|
||||||
|
return uint16_t(buffer[0]) << 8 | uint16_t(buffer[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Reads a signed 16 bit little endian value over I2C or SPI
|
||||||
|
* @param reg the register address to read from
|
||||||
|
* @returns the 16 bit data value read from the device
|
||||||
|
*/
|
||||||
|
uint16_t Adafruit_BME280::read16_LE(byte reg) {
|
||||||
|
uint16_t temp = read16(reg);
|
||||||
|
return (temp >> 8) | (temp << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Reads a signed 16 bit value over I2C or SPI
|
||||||
|
* @param reg the register address to read from
|
||||||
|
* @returns the 16 bit data value read from the device
|
||||||
|
*/
|
||||||
|
int16_t Adafruit_BME280::readS16(byte reg) { return (int16_t)read16(reg); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Reads a signed little endian 16 bit value over I2C or SPI
|
||||||
|
* @param reg the register address to read from
|
||||||
|
* @returns the 16 bit data value read from the device
|
||||||
|
*/
|
||||||
|
int16_t Adafruit_BME280::readS16_LE(byte reg) {
|
||||||
|
return (int16_t)read16_LE(reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Reads a 24 bit value over I2C
|
||||||
|
* @param reg the register address to read from
|
||||||
|
* @returns the 24 bit data value read from the device
|
||||||
|
*/
|
||||||
|
uint32_t Adafruit_BME280::read24(byte reg) {
|
||||||
|
uint8_t buffer[3];
|
||||||
|
|
||||||
|
if (i2c_dev) {
|
||||||
|
buffer[0] = uint8_t(reg);
|
||||||
|
i2c_dev->write_then_read(buffer, 1, buffer, 3);
|
||||||
|
} else {
|
||||||
|
buffer[0] = uint8_t(reg | 0x80);
|
||||||
|
spi_dev->write_then_read(buffer, 1, buffer, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return uint32_t(buffer[0]) << 16 | uint32_t(buffer[1]) << 8 |
|
||||||
|
uint32_t(buffer[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Take a new measurement (only possible in forced mode)
|
||||||
|
@returns true in case of success else false
|
||||||
|
*/
|
||||||
|
bool Adafruit_BME280::takeForcedMeasurement(void) {
|
||||||
|
bool return_value = false;
|
||||||
|
// If we are in forced mode, the BME sensor goes back to sleep after each
|
||||||
|
// measurement and we need to set it to forced mode once at this point, so
|
||||||
|
// it will take the next measurement and then return to sleep again.
|
||||||
|
// In normal mode simply does new measurements periodically.
|
||||||
|
if (_measReg.mode == MODE_FORCED) {
|
||||||
|
return_value = true;
|
||||||
|
// set to forced mode, i.e. "take next measurement"
|
||||||
|
write8(BME280_REGISTER_CONTROL, _measReg.get());
|
||||||
|
// Store current time to measure the timeout
|
||||||
|
uint32_t timeout_start = millis();
|
||||||
|
// wait until measurement has been completed, otherwise we would read the
|
||||||
|
// the values from the last measurement or the timeout occurred after 2 sec.
|
||||||
|
while (read8(BME280_REGISTER_STATUS) & 0x08) {
|
||||||
|
// In case of a timeout, stop the while loop
|
||||||
|
if ((millis() - timeout_start) > 2000) {
|
||||||
|
return_value = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Reads the factory-set coefficients
|
||||||
|
*/
|
||||||
|
void Adafruit_BME280::readCoefficients(void) {
|
||||||
|
_bme280_calib.dig_T1 = read16_LE(BME280_REGISTER_DIG_T1);
|
||||||
|
_bme280_calib.dig_T2 = readS16_LE(BME280_REGISTER_DIG_T2);
|
||||||
|
_bme280_calib.dig_T3 = readS16_LE(BME280_REGISTER_DIG_T3);
|
||||||
|
|
||||||
|
_bme280_calib.dig_P1 = read16_LE(BME280_REGISTER_DIG_P1);
|
||||||
|
_bme280_calib.dig_P2 = readS16_LE(BME280_REGISTER_DIG_P2);
|
||||||
|
_bme280_calib.dig_P3 = readS16_LE(BME280_REGISTER_DIG_P3);
|
||||||
|
_bme280_calib.dig_P4 = readS16_LE(BME280_REGISTER_DIG_P4);
|
||||||
|
_bme280_calib.dig_P5 = readS16_LE(BME280_REGISTER_DIG_P5);
|
||||||
|
_bme280_calib.dig_P6 = readS16_LE(BME280_REGISTER_DIG_P6);
|
||||||
|
_bme280_calib.dig_P7 = readS16_LE(BME280_REGISTER_DIG_P7);
|
||||||
|
_bme280_calib.dig_P8 = readS16_LE(BME280_REGISTER_DIG_P8);
|
||||||
|
_bme280_calib.dig_P9 = readS16_LE(BME280_REGISTER_DIG_P9);
|
||||||
|
|
||||||
|
_bme280_calib.dig_H1 = read8(BME280_REGISTER_DIG_H1);
|
||||||
|
_bme280_calib.dig_H2 = readS16_LE(BME280_REGISTER_DIG_H2);
|
||||||
|
_bme280_calib.dig_H3 = read8(BME280_REGISTER_DIG_H3);
|
||||||
|
_bme280_calib.dig_H4 = ((int8_t)read8(BME280_REGISTER_DIG_H4) << 4) |
|
||||||
|
(read8(BME280_REGISTER_DIG_H4 + 1) & 0xF);
|
||||||
|
_bme280_calib.dig_H5 = ((int8_t)read8(BME280_REGISTER_DIG_H5 + 1) << 4) |
|
||||||
|
(read8(BME280_REGISTER_DIG_H5) >> 4);
|
||||||
|
_bme280_calib.dig_H6 = (int8_t)read8(BME280_REGISTER_DIG_H6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief return true if chip is busy reading cal data
|
||||||
|
* @returns true if reading calibration, false otherwise
|
||||||
|
*/
|
||||||
|
bool Adafruit_BME280::isReadingCalibration(void) {
|
||||||
|
uint8_t const rStatus = read8(BME280_REGISTER_STATUS);
|
||||||
|
|
||||||
|
return (rStatus & (1 << 0)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Returns the temperature from the sensor
|
||||||
|
* @returns the temperature read from the device
|
||||||
|
*/
|
||||||
|
float Adafruit_BME280::readTemperature(void) {
|
||||||
|
int32_t var1, var2;
|
||||||
|
|
||||||
|
int32_t adc_T = read24(BME280_REGISTER_TEMPDATA);
|
||||||
|
if (adc_T == 0x800000) // value in case temp measurement was disabled
|
||||||
|
return NAN;
|
||||||
|
adc_T >>= 4;
|
||||||
|
|
||||||
|
var1 = (int32_t)((adc_T / 8) - ((int32_t)_bme280_calib.dig_T1 * 2));
|
||||||
|
var1 = (var1 * ((int32_t)_bme280_calib.dig_T2)) / 2048;
|
||||||
|
var2 = (int32_t)((adc_T / 16) - ((int32_t)_bme280_calib.dig_T1));
|
||||||
|
var2 = (((var2 * var2) / 4096) * ((int32_t)_bme280_calib.dig_T3)) / 16384;
|
||||||
|
|
||||||
|
t_fine = var1 + var2 + t_fine_adjust;
|
||||||
|
|
||||||
|
int32_t T = (t_fine * 5 + 128) / 256;
|
||||||
|
|
||||||
|
return (float)T / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Returns the pressure from the sensor
|
||||||
|
* @returns the pressure value (in Pascal) read from the device
|
||||||
|
*/
|
||||||
|
float Adafruit_BME280::readPressure(void) {
|
||||||
|
int64_t var1, var2, var3, var4;
|
||||||
|
|
||||||
|
readTemperature(); // must be done first to get t_fine
|
||||||
|
|
||||||
|
int32_t adc_P = read24(BME280_REGISTER_PRESSUREDATA);
|
||||||
|
if (adc_P == 0x800000) // value in case pressure measurement was disabled
|
||||||
|
return NAN;
|
||||||
|
adc_P >>= 4;
|
||||||
|
|
||||||
|
var1 = ((int64_t)t_fine) - 128000;
|
||||||
|
var2 = var1 * var1 * (int64_t)_bme280_calib.dig_P6;
|
||||||
|
var2 = var2 + ((var1 * (int64_t)_bme280_calib.dig_P5) * 131072);
|
||||||
|
var2 = var2 + (((int64_t)_bme280_calib.dig_P4) * 34359738368);
|
||||||
|
var1 = ((var1 * var1 * (int64_t)_bme280_calib.dig_P3) / 256) +
|
||||||
|
((var1 * ((int64_t)_bme280_calib.dig_P2) * 4096));
|
||||||
|
var3 = ((int64_t)1) * 140737488355328;
|
||||||
|
var1 = (var3 + var1) * ((int64_t)_bme280_calib.dig_P1) / 8589934592;
|
||||||
|
|
||||||
|
if (var1 == 0) {
|
||||||
|
return 0; // avoid exception caused by division by zero
|
||||||
|
}
|
||||||
|
|
||||||
|
var4 = 1048576 - adc_P;
|
||||||
|
var4 = (((var4 * 2147483648) - var2) * 3125) / var1;
|
||||||
|
var1 = (((int64_t)_bme280_calib.dig_P9) * (var4 / 8192) * (var4 / 8192)) /
|
||||||
|
33554432;
|
||||||
|
var2 = (((int64_t)_bme280_calib.dig_P8) * var4) / 524288;
|
||||||
|
var4 = ((var4 + var1 + var2) / 256) + (((int64_t)_bme280_calib.dig_P7) * 16);
|
||||||
|
|
||||||
|
float P = var4 / 256.0;
|
||||||
|
|
||||||
|
return P;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Returns the humidity from the sensor
|
||||||
|
* @returns the humidity value read from the device
|
||||||
|
*/
|
||||||
|
float Adafruit_BME280::readHumidity(void) {
|
||||||
|
int32_t var1, var2, var3, var4, var5;
|
||||||
|
|
||||||
|
readTemperature(); // must be done first to get t_fine
|
||||||
|
|
||||||
|
int32_t adc_H = read16(BME280_REGISTER_HUMIDDATA);
|
||||||
|
if (adc_H == 0x8000) // value in case humidity measurement was disabled
|
||||||
|
return NAN;
|
||||||
|
|
||||||
|
var1 = t_fine - ((int32_t)76800);
|
||||||
|
var2 = (int32_t)(adc_H * 16384);
|
||||||
|
var3 = (int32_t)(((int32_t)_bme280_calib.dig_H4) * 1048576);
|
||||||
|
var4 = ((int32_t)_bme280_calib.dig_H5) * var1;
|
||||||
|
var5 = (((var2 - var3) - var4) + (int32_t)16384) / 32768;
|
||||||
|
var2 = (var1 * ((int32_t)_bme280_calib.dig_H6)) / 1024;
|
||||||
|
var3 = (var1 * ((int32_t)_bme280_calib.dig_H3)) / 2048;
|
||||||
|
var4 = ((var2 * (var3 + (int32_t)32768)) / 1024) + (int32_t)2097152;
|
||||||
|
var2 = ((var4 * ((int32_t)_bme280_calib.dig_H2)) + 8192) / 16384;
|
||||||
|
var3 = var5 * var2;
|
||||||
|
var4 = ((var3 / 32768) * (var3 / 32768)) / 128;
|
||||||
|
var5 = var3 - ((var4 * ((int32_t)_bme280_calib.dig_H1)) / 16);
|
||||||
|
var5 = (var5 < 0 ? 0 : var5);
|
||||||
|
var5 = (var5 > 419430400 ? 419430400 : var5);
|
||||||
|
uint32_t H = (uint32_t)(var5 / 4096);
|
||||||
|
|
||||||
|
return (float)H / 1024.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Calculates the altitude (in meters) from the specified atmospheric
|
||||||
|
* pressure (in hPa), and sea-level pressure (in hPa).
|
||||||
|
* @param seaLevel Sea-level pressure in hPa
|
||||||
|
* @returns the altitude value read from the device
|
||||||
|
*/
|
||||||
|
float Adafruit_BME280::readAltitude(float seaLevel) {
|
||||||
|
// Equation taken from BMP180 datasheet (page 16):
|
||||||
|
// http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf
|
||||||
|
|
||||||
|
// Note that using the equation from wikipedia can give bad results
|
||||||
|
// at high altitude. See this thread for more information:
|
||||||
|
// http://forums.adafruit.com/viewtopic.php?f=22&t=58064
|
||||||
|
|
||||||
|
float atmospheric = readPressure() / 100.0F;
|
||||||
|
return 44330.0 * (1.0 - pow(atmospheric / seaLevel, 0.1903));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Calculates the pressure at sea level (in hPa) from the specified
|
||||||
|
* altitude (in meters), and atmospheric pressure (in hPa).
|
||||||
|
* @param altitude Altitude in meters
|
||||||
|
* @param atmospheric Atmospheric pressure in hPa
|
||||||
|
* @returns the pressure at sea level (in hPa) from the specified altitude
|
||||||
|
*/
|
||||||
|
float Adafruit_BME280::seaLevelForAltitude(float altitude, float atmospheric) {
|
||||||
|
// Equation taken from BMP180 datasheet (page 17):
|
||||||
|
// http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf
|
||||||
|
|
||||||
|
// Note that using the equation from wikipedia can give bad results
|
||||||
|
// at high altitude. See this thread for more information:
|
||||||
|
// http://forums.adafruit.com/viewtopic.php?f=22&t=58064
|
||||||
|
|
||||||
|
return atmospheric / pow(1.0 - (altitude / 44330.0), 5.255);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Returns Sensor ID found by init() for diagnostics
|
||||||
|
* @returns Sensor ID 0x60 for BME280, 0x56, 0x57, 0x58 BMP280
|
||||||
|
*/
|
||||||
|
uint32_t Adafruit_BME280::sensorID(void) { return _sensorID; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Returns the current temperature compensation value in degrees Celsius
|
||||||
|
* @returns the current temperature compensation value in degrees Celsius
|
||||||
|
*/
|
||||||
|
float Adafruit_BME280::getTemperatureCompensation(void) {
|
||||||
|
return float((t_fine_adjust * 5) >> 8) / 100.0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Sets a value to be added to each temperature reading. This adjusted
|
||||||
|
* temperature is used in pressure and humidity readings.
|
||||||
|
* @param adjustment Value to be added to each temperature reading in Celsius
|
||||||
|
*/
|
||||||
|
void Adafruit_BME280::setTemperatureCompensation(float adjustment) {
|
||||||
|
// convert the value in C into and adjustment to t_fine
|
||||||
|
t_fine_adjust = ((int32_t(adjustment * 100) << 8)) / 5;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Gets an Adafruit Unified Sensor object for the temp sensor component
|
||||||
|
@return Adafruit_Sensor pointer to temperature sensor
|
||||||
|
*/
|
||||||
|
Adafruit_Sensor *Adafruit_BME280::getTemperatureSensor(void) {
|
||||||
|
if (!temp_sensor) {
|
||||||
|
temp_sensor = new Adafruit_BME280_Temp(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return temp_sensor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Gets an Adafruit Unified Sensor object for the pressure sensor
|
||||||
|
component
|
||||||
|
@return Adafruit_Sensor pointer to pressure sensor
|
||||||
|
*/
|
||||||
|
Adafruit_Sensor *Adafruit_BME280::getPressureSensor(void) {
|
||||||
|
if (!pressure_sensor) {
|
||||||
|
pressure_sensor = new Adafruit_BME280_Pressure(this);
|
||||||
|
}
|
||||||
|
return pressure_sensor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Gets an Adafruit Unified Sensor object for the humidity sensor
|
||||||
|
component
|
||||||
|
@return Adafruit_Sensor pointer to humidity sensor
|
||||||
|
*/
|
||||||
|
Adafruit_Sensor *Adafruit_BME280::getHumiditySensor(void) {
|
||||||
|
if (!humidity_sensor) {
|
||||||
|
humidity_sensor = new Adafruit_BME280_Humidity(this);
|
||||||
|
}
|
||||||
|
return humidity_sensor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the sensor_t data for the BME280's temperature sensor
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
void Adafruit_BME280_Temp::getSensor(sensor_t *sensor) {
|
||||||
|
/* Clear the sensor_t object */
|
||||||
|
memset(sensor, 0, sizeof(sensor_t));
|
||||||
|
|
||||||
|
/* Insert the sensor name in the fixed length char array */
|
||||||
|
strncpy(sensor->name, "BME280", sizeof(sensor->name) - 1);
|
||||||
|
sensor->name[sizeof(sensor->name) - 1] = 0;
|
||||||
|
sensor->version = 1;
|
||||||
|
sensor->sensor_id = _sensorID;
|
||||||
|
sensor->type = SENSOR_TYPE_AMBIENT_TEMPERATURE;
|
||||||
|
sensor->min_delay = 0;
|
||||||
|
sensor->min_value = -40.0; /* Temperature range -40 ~ +85 C */
|
||||||
|
sensor->max_value = +85.0;
|
||||||
|
sensor->resolution = 0.01; /* 0.01 C */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the temperature as a standard sensor event
|
||||||
|
@param event Sensor event object that will be populated
|
||||||
|
@returns True
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
bool Adafruit_BME280_Temp::getEvent(sensors_event_t *event) {
|
||||||
|
/* Clear the event */
|
||||||
|
memset(event, 0, sizeof(sensors_event_t));
|
||||||
|
|
||||||
|
event->version = sizeof(sensors_event_t);
|
||||||
|
event->sensor_id = _sensorID;
|
||||||
|
event->type = SENSOR_TYPE_AMBIENT_TEMPERATURE;
|
||||||
|
event->timestamp = millis();
|
||||||
|
event->temperature = _theBME280->readTemperature();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the sensor_t data for the BME280's pressure sensor
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
void Adafruit_BME280_Pressure::getSensor(sensor_t *sensor) {
|
||||||
|
/* Clear the sensor_t object */
|
||||||
|
memset(sensor, 0, sizeof(sensor_t));
|
||||||
|
|
||||||
|
/* Insert the sensor name in the fixed length char array */
|
||||||
|
strncpy(sensor->name, "BME280", sizeof(sensor->name) - 1);
|
||||||
|
sensor->name[sizeof(sensor->name) - 1] = 0;
|
||||||
|
sensor->version = 1;
|
||||||
|
sensor->sensor_id = _sensorID;
|
||||||
|
sensor->type = SENSOR_TYPE_PRESSURE;
|
||||||
|
sensor->min_delay = 0;
|
||||||
|
sensor->min_value = 300.0; /* 300 ~ 1100 hPa */
|
||||||
|
sensor->max_value = 1100.0;
|
||||||
|
sensor->resolution = 0.012; /* 0.12 hPa relative */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the pressure as a standard sensor event
|
||||||
|
@param event Sensor event object that will be populated
|
||||||
|
@returns True
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
bool Adafruit_BME280_Pressure::getEvent(sensors_event_t *event) {
|
||||||
|
/* Clear the event */
|
||||||
|
memset(event, 0, sizeof(sensors_event_t));
|
||||||
|
|
||||||
|
event->version = sizeof(sensors_event_t);
|
||||||
|
event->sensor_id = _sensorID;
|
||||||
|
event->type = SENSOR_TYPE_PRESSURE;
|
||||||
|
event->timestamp = millis();
|
||||||
|
event->pressure = _theBME280->readPressure() / 100; // convert Pa to hPa
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the sensor_t data for the BME280's humidity sensor
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
void Adafruit_BME280_Humidity::getSensor(sensor_t *sensor) {
|
||||||
|
/* Clear the sensor_t object */
|
||||||
|
memset(sensor, 0, sizeof(sensor_t));
|
||||||
|
|
||||||
|
/* Insert the sensor name in the fixed length char array */
|
||||||
|
strncpy(sensor->name, "BME280", sizeof(sensor->name) - 1);
|
||||||
|
sensor->name[sizeof(sensor->name) - 1] = 0;
|
||||||
|
sensor->version = 1;
|
||||||
|
sensor->sensor_id = _sensorID;
|
||||||
|
sensor->type = SENSOR_TYPE_RELATIVE_HUMIDITY;
|
||||||
|
sensor->min_delay = 0;
|
||||||
|
sensor->min_value = 0;
|
||||||
|
sensor->max_value = 100; /* 0 - 100 % */
|
||||||
|
sensor->resolution = 3; /* 3% accuracy */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Gets the humidity as a standard sensor event
|
||||||
|
@param event Sensor event object that will be populated
|
||||||
|
@returns True
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
bool Adafruit_BME280_Humidity::getEvent(sensors_event_t *event) {
|
||||||
|
/* Clear the event */
|
||||||
|
memset(event, 0, sizeof(sensors_event_t));
|
||||||
|
|
||||||
|
event->version = sizeof(sensors_event_t);
|
||||||
|
event->sensor_id = _sensorID;
|
||||||
|
event->type = SENSOR_TYPE_RELATIVE_HUMIDITY;
|
||||||
|
event->timestamp = millis();
|
||||||
|
event->relative_humidity = _theBME280->readHumidity();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
372
libraries/Adafruit_BME280_Library/Adafruit_BME280.h
Normal file
372
libraries/Adafruit_BME280_Library/Adafruit_BME280.h
Normal file
@@ -0,0 +1,372 @@
|
|||||||
|
/*!
|
||||||
|
* @file Adafruit_BME280.h
|
||||||
|
*
|
||||||
|
* Designed specifically to work with the Adafruit BME280 Breakout
|
||||||
|
* ----> http://www.adafruit.com/products/2650
|
||||||
|
*
|
||||||
|
* These sensors use I2C or SPI to communicate, 2 or 4 pins are required
|
||||||
|
* to interface.
|
||||||
|
*
|
||||||
|
* Adafruit invests time and resources providing this open source code,
|
||||||
|
* please support Adafruit and open-source hardware by purchasing
|
||||||
|
* products from Adafruit!
|
||||||
|
*
|
||||||
|
* Written by Kevin "KTOWN" Townsend for Adafruit Industries.
|
||||||
|
*
|
||||||
|
* BSD license, all text here must be included in any redistribution.
|
||||||
|
* See the LICENSE file for details.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BME280_H__
|
||||||
|
#define __BME280_H__
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
#include <Adafruit_I2CDevice.h>
|
||||||
|
#include <Adafruit_SPIDevice.h>
|
||||||
|
#include <Adafruit_Sensor.h>
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief default I2C address
|
||||||
|
*/
|
||||||
|
#define BME280_ADDRESS (0x77) // Primary I2C Address
|
||||||
|
/*!
|
||||||
|
* @brief alternate I2C address
|
||||||
|
*/
|
||||||
|
#define BME280_ADDRESS_ALTERNATE (0x76) // Alternate Address
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Register addresses
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
BME280_REGISTER_DIG_T1 = 0x88,
|
||||||
|
BME280_REGISTER_DIG_T2 = 0x8A,
|
||||||
|
BME280_REGISTER_DIG_T3 = 0x8C,
|
||||||
|
|
||||||
|
BME280_REGISTER_DIG_P1 = 0x8E,
|
||||||
|
BME280_REGISTER_DIG_P2 = 0x90,
|
||||||
|
BME280_REGISTER_DIG_P3 = 0x92,
|
||||||
|
BME280_REGISTER_DIG_P4 = 0x94,
|
||||||
|
BME280_REGISTER_DIG_P5 = 0x96,
|
||||||
|
BME280_REGISTER_DIG_P6 = 0x98,
|
||||||
|
BME280_REGISTER_DIG_P7 = 0x9A,
|
||||||
|
BME280_REGISTER_DIG_P8 = 0x9C,
|
||||||
|
BME280_REGISTER_DIG_P9 = 0x9E,
|
||||||
|
|
||||||
|
BME280_REGISTER_DIG_H1 = 0xA1,
|
||||||
|
BME280_REGISTER_DIG_H2 = 0xE1,
|
||||||
|
BME280_REGISTER_DIG_H3 = 0xE3,
|
||||||
|
BME280_REGISTER_DIG_H4 = 0xE4,
|
||||||
|
BME280_REGISTER_DIG_H5 = 0xE5,
|
||||||
|
BME280_REGISTER_DIG_H6 = 0xE7,
|
||||||
|
|
||||||
|
BME280_REGISTER_CHIPID = 0xD0,
|
||||||
|
BME280_REGISTER_VERSION = 0xD1,
|
||||||
|
BME280_REGISTER_SOFTRESET = 0xE0,
|
||||||
|
|
||||||
|
BME280_REGISTER_CAL26 = 0xE1, // R calibration stored in 0xE1-0xF0
|
||||||
|
|
||||||
|
BME280_REGISTER_CONTROLHUMID = 0xF2,
|
||||||
|
BME280_REGISTER_STATUS = 0XF3,
|
||||||
|
BME280_REGISTER_CONTROL = 0xF4,
|
||||||
|
BME280_REGISTER_CONFIG = 0xF5,
|
||||||
|
BME280_REGISTER_PRESSUREDATA = 0xF7,
|
||||||
|
BME280_REGISTER_TEMPDATA = 0xFA,
|
||||||
|
BME280_REGISTER_HUMIDDATA = 0xFD
|
||||||
|
};
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief calibration data
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
typedef struct {
|
||||||
|
uint16_t dig_T1; ///< temperature compensation value
|
||||||
|
int16_t dig_T2; ///< temperature compensation value
|
||||||
|
int16_t dig_T3; ///< temperature compensation value
|
||||||
|
|
||||||
|
uint16_t dig_P1; ///< pressure compensation value
|
||||||
|
int16_t dig_P2; ///< pressure compensation value
|
||||||
|
int16_t dig_P3; ///< pressure compensation value
|
||||||
|
int16_t dig_P4; ///< pressure compensation value
|
||||||
|
int16_t dig_P5; ///< pressure compensation value
|
||||||
|
int16_t dig_P6; ///< pressure compensation value
|
||||||
|
int16_t dig_P7; ///< pressure compensation value
|
||||||
|
int16_t dig_P8; ///< pressure compensation value
|
||||||
|
int16_t dig_P9; ///< pressure compensation value
|
||||||
|
|
||||||
|
uint8_t dig_H1; ///< humidity compensation value
|
||||||
|
int16_t dig_H2; ///< humidity compensation value
|
||||||
|
uint8_t dig_H3; ///< humidity compensation value
|
||||||
|
int16_t dig_H4; ///< humidity compensation value
|
||||||
|
int16_t dig_H5; ///< humidity compensation value
|
||||||
|
int8_t dig_H6; ///< humidity compensation value
|
||||||
|
} bme280_calib_data;
|
||||||
|
/*=========================================================================*/
|
||||||
|
|
||||||
|
class Adafruit_BME280;
|
||||||
|
|
||||||
|
/** Adafruit Unified Sensor interface for temperature component of BME280 */
|
||||||
|
class Adafruit_BME280_Temp : public Adafruit_Sensor {
|
||||||
|
public:
|
||||||
|
/** @brief Create an Adafruit_Sensor compatible object for the temp sensor
|
||||||
|
@param parent A pointer to the BME280 class */
|
||||||
|
Adafruit_BME280_Temp(Adafruit_BME280 *parent) { _theBME280 = parent; }
|
||||||
|
bool getEvent(sensors_event_t *);
|
||||||
|
void getSensor(sensor_t *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _sensorID = 280;
|
||||||
|
Adafruit_BME280 *_theBME280 = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Adafruit Unified Sensor interface for pressure component of BME280 */
|
||||||
|
class Adafruit_BME280_Pressure : public Adafruit_Sensor {
|
||||||
|
public:
|
||||||
|
/** @brief Create an Adafruit_Sensor compatible object for the pressure sensor
|
||||||
|
@param parent A pointer to the BME280 class */
|
||||||
|
Adafruit_BME280_Pressure(Adafruit_BME280 *parent) { _theBME280 = parent; }
|
||||||
|
bool getEvent(sensors_event_t *);
|
||||||
|
void getSensor(sensor_t *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _sensorID = 280;
|
||||||
|
Adafruit_BME280 *_theBME280 = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Adafruit Unified Sensor interface for humidity component of BME280 */
|
||||||
|
class Adafruit_BME280_Humidity : public Adafruit_Sensor {
|
||||||
|
public:
|
||||||
|
/** @brief Create an Adafruit_Sensor compatible object for the humidity sensor
|
||||||
|
@param parent A pointer to the BME280 class */
|
||||||
|
Adafruit_BME280_Humidity(Adafruit_BME280 *parent) { _theBME280 = parent; }
|
||||||
|
bool getEvent(sensors_event_t *);
|
||||||
|
void getSensor(sensor_t *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _sensorID = 280;
|
||||||
|
Adafruit_BME280 *_theBME280 = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Class that stores state and functions for interacting with BME280 IC
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
class Adafruit_BME280 {
|
||||||
|
public:
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief sampling rates
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
enum sensor_sampling {
|
||||||
|
SAMPLING_NONE = 0b000,
|
||||||
|
SAMPLING_X1 = 0b001,
|
||||||
|
SAMPLING_X2 = 0b010,
|
||||||
|
SAMPLING_X4 = 0b011,
|
||||||
|
SAMPLING_X8 = 0b100,
|
||||||
|
SAMPLING_X16 = 0b101
|
||||||
|
};
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief power modes
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
enum sensor_mode {
|
||||||
|
MODE_SLEEP = 0b00,
|
||||||
|
MODE_FORCED = 0b01,
|
||||||
|
MODE_NORMAL = 0b11
|
||||||
|
};
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief filter values
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
enum sensor_filter {
|
||||||
|
FILTER_OFF = 0b000,
|
||||||
|
FILTER_X2 = 0b001,
|
||||||
|
FILTER_X4 = 0b010,
|
||||||
|
FILTER_X8 = 0b011,
|
||||||
|
FILTER_X16 = 0b100
|
||||||
|
};
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief standby duration in ms
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
enum standby_duration {
|
||||||
|
STANDBY_MS_0_5 = 0b000,
|
||||||
|
STANDBY_MS_10 = 0b110,
|
||||||
|
STANDBY_MS_20 = 0b111,
|
||||||
|
STANDBY_MS_62_5 = 0b001,
|
||||||
|
STANDBY_MS_125 = 0b010,
|
||||||
|
STANDBY_MS_250 = 0b011,
|
||||||
|
STANDBY_MS_500 = 0b100,
|
||||||
|
STANDBY_MS_1000 = 0b101
|
||||||
|
};
|
||||||
|
|
||||||
|
// constructors
|
||||||
|
Adafruit_BME280();
|
||||||
|
Adafruit_BME280(int8_t cspin, SPIClass *theSPI = &SPI);
|
||||||
|
Adafruit_BME280(int8_t cspin, int8_t mosipin, int8_t misopin, int8_t sckpin);
|
||||||
|
~Adafruit_BME280(void);
|
||||||
|
bool begin(uint8_t addr = BME280_ADDRESS, TwoWire *theWire = &Wire);
|
||||||
|
bool init();
|
||||||
|
|
||||||
|
void setSampling(sensor_mode mode = MODE_NORMAL,
|
||||||
|
sensor_sampling tempSampling = SAMPLING_X16,
|
||||||
|
sensor_sampling pressSampling = SAMPLING_X16,
|
||||||
|
sensor_sampling humSampling = SAMPLING_X16,
|
||||||
|
sensor_filter filter = FILTER_OFF,
|
||||||
|
standby_duration duration = STANDBY_MS_0_5);
|
||||||
|
|
||||||
|
bool takeForcedMeasurement(void);
|
||||||
|
float readTemperature(void);
|
||||||
|
float readPressure(void);
|
||||||
|
float readHumidity(void);
|
||||||
|
|
||||||
|
float readAltitude(float seaLevel);
|
||||||
|
float seaLevelForAltitude(float altitude, float pressure);
|
||||||
|
uint32_t sensorID(void);
|
||||||
|
|
||||||
|
float getTemperatureCompensation(void);
|
||||||
|
void setTemperatureCompensation(float);
|
||||||
|
|
||||||
|
Adafruit_Sensor *getTemperatureSensor(void);
|
||||||
|
Adafruit_Sensor *getPressureSensor(void);
|
||||||
|
Adafruit_Sensor *getHumiditySensor(void);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Adafruit_I2CDevice *i2c_dev = NULL; ///< Pointer to I2C bus interface
|
||||||
|
Adafruit_SPIDevice *spi_dev = NULL; ///< Pointer to SPI bus interface
|
||||||
|
|
||||||
|
Adafruit_BME280_Temp *temp_sensor = NULL;
|
||||||
|
//!< Adafruit_Sensor compat temperature sensor component
|
||||||
|
|
||||||
|
Adafruit_BME280_Pressure *pressure_sensor = NULL;
|
||||||
|
//!< Adafruit_Sensor compat pressure sensor component
|
||||||
|
|
||||||
|
Adafruit_BME280_Humidity *humidity_sensor = NULL;
|
||||||
|
//!< Adafruit_Sensor compat humidity sensor component
|
||||||
|
|
||||||
|
void readCoefficients(void);
|
||||||
|
bool isReadingCalibration(void);
|
||||||
|
|
||||||
|
void write8(byte reg, byte value);
|
||||||
|
uint8_t read8(byte reg);
|
||||||
|
uint16_t read16(byte reg);
|
||||||
|
uint32_t read24(byte reg);
|
||||||
|
int16_t readS16(byte reg);
|
||||||
|
uint16_t read16_LE(byte reg); // little endian
|
||||||
|
int16_t readS16_LE(byte reg); // little endian
|
||||||
|
|
||||||
|
uint8_t _i2caddr; //!< I2C addr for the TwoWire interface
|
||||||
|
int32_t _sensorID; //!< ID of the BME Sensor
|
||||||
|
int32_t t_fine; //!< temperature with high resolution, stored as an attribute
|
||||||
|
//!< as this is used for temperature compensation reading
|
||||||
|
//!< humidity and pressure
|
||||||
|
|
||||||
|
int32_t t_fine_adjust = 0; //!< add to compensate temp readings and in turn
|
||||||
|
//!< to pressure and humidity readings
|
||||||
|
|
||||||
|
bme280_calib_data _bme280_calib; //!< here calibration data is stored
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief config register
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
struct config {
|
||||||
|
// inactive duration (standby time) in normal mode
|
||||||
|
// 000 = 0.5 ms
|
||||||
|
// 001 = 62.5 ms
|
||||||
|
// 010 = 125 ms
|
||||||
|
// 011 = 250 ms
|
||||||
|
// 100 = 500 ms
|
||||||
|
// 101 = 1000 ms
|
||||||
|
// 110 = 10 ms
|
||||||
|
// 111 = 20 ms
|
||||||
|
unsigned int t_sb : 3; ///< inactive duration (standby time) in normal mode
|
||||||
|
|
||||||
|
// filter settings
|
||||||
|
// 000 = filter off
|
||||||
|
// 001 = 2x filter
|
||||||
|
// 010 = 4x filter
|
||||||
|
// 011 = 8x filter
|
||||||
|
// 100 and above = 16x filter
|
||||||
|
unsigned int filter : 3; ///< filter settings
|
||||||
|
|
||||||
|
// unused - don't set
|
||||||
|
unsigned int none : 1; ///< unused - don't set
|
||||||
|
unsigned int spi3w_en : 1; ///< unused - don't set
|
||||||
|
|
||||||
|
/// @return combined config register
|
||||||
|
unsigned int get() { return (t_sb << 5) | (filter << 2) | spi3w_en; }
|
||||||
|
};
|
||||||
|
config _configReg; //!< config register object
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief ctrl_meas register
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
struct ctrl_meas {
|
||||||
|
// temperature oversampling
|
||||||
|
// 000 = skipped
|
||||||
|
// 001 = x1
|
||||||
|
// 010 = x2
|
||||||
|
// 011 = x4
|
||||||
|
// 100 = x8
|
||||||
|
// 101 and above = x16
|
||||||
|
unsigned int osrs_t : 3; ///< temperature oversampling
|
||||||
|
|
||||||
|
// pressure oversampling
|
||||||
|
// 000 = skipped
|
||||||
|
// 001 = x1
|
||||||
|
// 010 = x2
|
||||||
|
// 011 = x4
|
||||||
|
// 100 = x8
|
||||||
|
// 101 and above = x16
|
||||||
|
unsigned int osrs_p : 3; ///< pressure oversampling
|
||||||
|
|
||||||
|
// device mode
|
||||||
|
// 00 = sleep
|
||||||
|
// 01 or 10 = forced
|
||||||
|
// 11 = normal
|
||||||
|
unsigned int mode : 2; ///< device mode
|
||||||
|
|
||||||
|
/// @return combined ctrl register
|
||||||
|
unsigned int get() { return (osrs_t << 5) | (osrs_p << 2) | mode; }
|
||||||
|
};
|
||||||
|
ctrl_meas _measReg; //!< measurement register object
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief ctrl_hum register
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
struct ctrl_hum {
|
||||||
|
/// unused - don't set
|
||||||
|
unsigned int none : 5;
|
||||||
|
|
||||||
|
// pressure oversampling
|
||||||
|
// 000 = skipped
|
||||||
|
// 001 = x1
|
||||||
|
// 010 = x2
|
||||||
|
// 011 = x4
|
||||||
|
// 100 = x8
|
||||||
|
// 101 and above = x16
|
||||||
|
unsigned int osrs_h : 3; ///< pressure oversampling
|
||||||
|
|
||||||
|
/// @return combined ctrl hum register
|
||||||
|
unsigned int get() { return (osrs_h); }
|
||||||
|
};
|
||||||
|
ctrl_hum _humReg; //!< hum register object
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
27
libraries/Adafruit_BME280_Library/LICENSE
Normal file
27
libraries/Adafruit_BME280_Library/LICENSE
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2015, Limor Fried & Kevin Townsend for Adafruit Industries
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of Adafruit Industries nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
54
libraries/Adafruit_BME280_Library/README.md
Normal file
54
libraries/Adafruit_BME280_Library/README.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Adafruit BME280 Library [](https://github.com/adafruit/Adafruit_BME280_Library/actions)[](http://adafruit.github.io/Adafruit_BME280_Library/html/index.html)
|
||||||
|
|
||||||
|
|
||||||
|
<a href="http://www.adafruit.com/products/2652"><img src="./assets/board.jpg" width="500"/></a>
|
||||||
|
|
||||||
|
This is a library for the Adafruit BME280 Humidity, Barometric Pressure + Temp sensor
|
||||||
|
|
||||||
|
Designed specifically to work with the Adafruit BME280 Breakout
|
||||||
|
* http://www.adafruit.com/products/2652
|
||||||
|
|
||||||
|
Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
To install, use the Arduino Library Manager and search for "Adafruit BME280" and install the library.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
* [Adafruit Unified Sensor Driver](https://github.com/adafruit/Adafruit_Sensor)
|
||||||
|
|
||||||
|
# Contributing
|
||||||
|
|
||||||
|
Contributions are welcome! Please read our [Code of Conduct](https://github.com/adafruit/Adafruit_PM25AQI/blob/master/CODE_OF_CONDUCT.md>)
|
||||||
|
before contributing to help this project stay welcoming.
|
||||||
|
|
||||||
|
## Documentation and doxygen
|
||||||
|
Documentation is produced by doxygen. Contributions should include documentation for any new code added.
|
||||||
|
|
||||||
|
Some examples of how to use doxygen can be found in these guide pages:
|
||||||
|
|
||||||
|
https://learn.adafruit.com/the-well-automated-arduino-library/doxygen
|
||||||
|
|
||||||
|
https://learn.adafruit.com/the-well-automated-arduino-library/doxygen-tips
|
||||||
|
|
||||||
|
## Formatting and clang-format
|
||||||
|
This library uses [`clang-format`](https://releases.llvm.org/download.html) to standardize the formatting of `.cpp` and `.h` files.
|
||||||
|
Contributions should be formatted using `clang-format`:
|
||||||
|
|
||||||
|
The `-i` flag will make the changes to the file.
|
||||||
|
```bash
|
||||||
|
clang-format -i *.cpp *.h
|
||||||
|
```
|
||||||
|
If you prefer to make the changes yourself, running `clang-format` without the `-i` flag will print out a formatted version of the file. You can save this to a file and diff it against the original to see the changes.
|
||||||
|
|
||||||
|
Note that the formatting output by `clang-format` is what the automated formatting checker will expect. Any diffs from this formatting will result in a failed build until they are addressed. Using the `-i` flag is highly recommended.
|
||||||
|
|
||||||
|
### clang-format resources
|
||||||
|
* [Binary builds and source available on the LLVM downloads page](https://releases.llvm.org/download.html)
|
||||||
|
* [Documentation and IDE integration](https://clang.llvm.org/docs/ClangFormat.html)
|
||||||
|
|
||||||
|
## About this Driver
|
||||||
|
Written by Ladyada for Adafruit Industries.
|
||||||
|
|
||||||
|
BSD license, check license.txt for more information
|
||||||
|
|
||||||
|
All text above must be included in any redistribution
|
||||||
BIN
libraries/Adafruit_BME280_Library/assets/board.jpg
Normal file
BIN
libraries/Adafruit_BME280_Library/assets/board.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 431 KiB |
@@ -0,0 +1,159 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
This is a library for the BME280 humidity, temperature & pressure sensor
|
||||||
|
|
||||||
|
Designed specifically to work with the Adafruit BME280 Breakout
|
||||||
|
----> http://www.adafruit.com/products/2650
|
||||||
|
|
||||||
|
These sensors use I2C or SPI to communicate, 2 or 4 pins are required
|
||||||
|
to interface. The device's I2C address is either 0x76 or 0x77.
|
||||||
|
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit andopen-source hardware by purchasing products
|
||||||
|
from Adafruit!
|
||||||
|
|
||||||
|
Written by Limor Fried & Kevin Townsend for Adafruit Industries.
|
||||||
|
BSD license, all text above must be included in any redistribution
|
||||||
|
See the LICENSE file for details.
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Adafruit_Sensor.h>
|
||||||
|
#include <Adafruit_BME280.h>
|
||||||
|
|
||||||
|
#define BME_SCK 13
|
||||||
|
#define BME_MISO 12
|
||||||
|
#define BME_MOSI 11
|
||||||
|
#define BME_CS 10
|
||||||
|
|
||||||
|
#define SEALEVELPRESSURE_HPA (1013.25)
|
||||||
|
|
||||||
|
Adafruit_BME280 bme; // I2C
|
||||||
|
//Adafruit_BME280 bme(BME_CS); // hardware SPI
|
||||||
|
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI
|
||||||
|
|
||||||
|
unsigned long delayTime;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
Serial.println(F("BME280 test"));
|
||||||
|
|
||||||
|
if (! bme.begin(0x77, &Wire)) {
|
||||||
|
Serial.println("Could not find a valid BME280 sensor, check wiring!");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("-- Default Test --");
|
||||||
|
Serial.println("normal mode, 16x oversampling for all, filter off,");
|
||||||
|
Serial.println("0.5ms standby period");
|
||||||
|
delayTime = 5000;
|
||||||
|
|
||||||
|
|
||||||
|
// For more details on the following scenarious, see chapter
|
||||||
|
// 3.5 "Recommended modes of operation" in the datasheet
|
||||||
|
|
||||||
|
/*
|
||||||
|
// weather monitoring
|
||||||
|
Serial.println("-- Weather Station Scenario --");
|
||||||
|
Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
|
||||||
|
Serial.println("filter off");
|
||||||
|
bme.setSampling(Adafruit_BME280::MODE_FORCED,
|
||||||
|
Adafruit_BME280::SAMPLING_X1, // temperature
|
||||||
|
Adafruit_BME280::SAMPLING_X1, // pressure
|
||||||
|
Adafruit_BME280::SAMPLING_X1, // humidity
|
||||||
|
Adafruit_BME280::FILTER_OFF );
|
||||||
|
|
||||||
|
// suggested rate is 1/60Hz (1m)
|
||||||
|
delayTime = 60000; // in milliseconds
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
// humidity sensing
|
||||||
|
Serial.println("-- Humidity Sensing Scenario --");
|
||||||
|
Serial.println("forced mode, 1x temperature / 1x humidity / 0x pressure oversampling");
|
||||||
|
Serial.println("= pressure off, filter off");
|
||||||
|
bme.setSampling(Adafruit_BME280::MODE_FORCED,
|
||||||
|
Adafruit_BME280::SAMPLING_X1, // temperature
|
||||||
|
Adafruit_BME280::SAMPLING_NONE, // pressure
|
||||||
|
Adafruit_BME280::SAMPLING_X1, // humidity
|
||||||
|
Adafruit_BME280::FILTER_OFF );
|
||||||
|
|
||||||
|
// suggested rate is 1Hz (1s)
|
||||||
|
delayTime = 1000; // in milliseconds
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
// indoor navigation
|
||||||
|
Serial.println("-- Indoor Navigation Scenario --");
|
||||||
|
Serial.println("normal mode, 16x pressure / 2x temperature / 1x humidity oversampling,");
|
||||||
|
Serial.println("0.5ms standby period, filter 16x");
|
||||||
|
bme.setSampling(Adafruit_BME280::MODE_NORMAL,
|
||||||
|
Adafruit_BME280::SAMPLING_X2, // temperature
|
||||||
|
Adafruit_BME280::SAMPLING_X16, // pressure
|
||||||
|
Adafruit_BME280::SAMPLING_X1, // humidity
|
||||||
|
Adafruit_BME280::FILTER_X16,
|
||||||
|
Adafruit_BME280::STANDBY_MS_0_5 );
|
||||||
|
|
||||||
|
// suggested rate is 25Hz
|
||||||
|
// 1 + (2 * T_ovs) + (2 * P_ovs + 0.5) + (2 * H_ovs + 0.5)
|
||||||
|
// T_ovs = 2
|
||||||
|
// P_ovs = 16
|
||||||
|
// H_ovs = 1
|
||||||
|
// = 40ms (25Hz)
|
||||||
|
// with standby time that should really be 24.16913... Hz
|
||||||
|
delayTime = 41;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
// gaming
|
||||||
|
Serial.println("-- Gaming Scenario --");
|
||||||
|
Serial.println("normal mode, 4x pressure / 1x temperature / 0x humidity oversampling,");
|
||||||
|
Serial.println("= humidity off, 0.5ms standby period, filter 16x");
|
||||||
|
bme.setSampling(Adafruit_BME280::MODE_NORMAL,
|
||||||
|
Adafruit_BME280::SAMPLING_X1, // temperature
|
||||||
|
Adafruit_BME280::SAMPLING_X4, // pressure
|
||||||
|
Adafruit_BME280::SAMPLING_NONE, // humidity
|
||||||
|
Adafruit_BME280::FILTER_X16,
|
||||||
|
Adafruit_BME280::STANDBY_MS_0_5 );
|
||||||
|
|
||||||
|
// Suggested rate is 83Hz
|
||||||
|
// 1 + (2 * T_ovs) + (2 * P_ovs + 0.5)
|
||||||
|
// T_ovs = 1
|
||||||
|
// P_ovs = 4
|
||||||
|
// = 11.5ms + 0.5ms standby
|
||||||
|
delayTime = 12;
|
||||||
|
*/
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// Only needed in forced mode! In normal mode, you can remove the next line.
|
||||||
|
bme.takeForcedMeasurement(); // has no effect in normal mode
|
||||||
|
|
||||||
|
printValues();
|
||||||
|
delay(delayTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void printValues() {
|
||||||
|
Serial.print("Temperature = ");
|
||||||
|
Serial.print(bme.readTemperature());
|
||||||
|
Serial.println(" *C");
|
||||||
|
|
||||||
|
Serial.print("Pressure = ");
|
||||||
|
|
||||||
|
Serial.print(bme.readPressure() / 100.0F);
|
||||||
|
Serial.println(" hPa");
|
||||||
|
|
||||||
|
Serial.print("Approx. Altitude = ");
|
||||||
|
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
|
||||||
|
Serial.println(" m");
|
||||||
|
|
||||||
|
Serial.print("Humidity = ");
|
||||||
|
Serial.print(bme.readHumidity());
|
||||||
|
Serial.println(" %");
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
This is a library for the BME280 humidity, temperature & pressure sensor
|
||||||
|
This example shows how to take Sensor Events instead of direct readings
|
||||||
|
|
||||||
|
Designed specifically to work with the Adafruit BME280 Breakout
|
||||||
|
----> http://www.adafruit.com/products/2652
|
||||||
|
|
||||||
|
These sensors use I2C or SPI to communicate, 2 or 4 pins are required
|
||||||
|
to interface.
|
||||||
|
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit and open-source hardware by purchasing products
|
||||||
|
from Adafruit!
|
||||||
|
|
||||||
|
Written by Limor Fried & Kevin Townsend for Adafruit Industries.
|
||||||
|
BSD license, all text above must be included in any redistribution
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Adafruit_BME280.h>
|
||||||
|
|
||||||
|
Adafruit_BME280 bme; // use I2C interface
|
||||||
|
Adafruit_Sensor *bme_temp = bme.getTemperatureSensor();
|
||||||
|
Adafruit_Sensor *bme_pressure = bme.getPressureSensor();
|
||||||
|
Adafruit_Sensor *bme_humidity = bme.getHumiditySensor();
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
Serial.println(F("BME280 Sensor event test"));
|
||||||
|
|
||||||
|
if (!bme.begin()) {
|
||||||
|
Serial.println(F("Could not find a valid BME280 sensor, check wiring!"));
|
||||||
|
while (1) delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
bme_temp->printSensorDetails();
|
||||||
|
bme_pressure->printSensorDetails();
|
||||||
|
bme_humidity->printSensorDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
sensors_event_t temp_event, pressure_event, humidity_event;
|
||||||
|
bme_temp->getEvent(&temp_event);
|
||||||
|
bme_pressure->getEvent(&pressure_event);
|
||||||
|
bme_humidity->getEvent(&humidity_event);
|
||||||
|
|
||||||
|
Serial.print(F("Temperature = "));
|
||||||
|
Serial.print(temp_event.temperature);
|
||||||
|
Serial.println(" *C");
|
||||||
|
|
||||||
|
Serial.print(F("Humidity = "));
|
||||||
|
Serial.print(humidity_event.relative_humidity);
|
||||||
|
Serial.println(" %");
|
||||||
|
|
||||||
|
Serial.print(F("Pressure = "));
|
||||||
|
Serial.print(pressure_event.pressure);
|
||||||
|
Serial.println(" hPa");
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
This is a library for the BME280 humidity, temperature & pressure sensor
|
||||||
|
|
||||||
|
Designed specifically to work with the Adafruit BME280 Breakout
|
||||||
|
----> http://www.adafruit.com/products/2650
|
||||||
|
|
||||||
|
These sensors use I2C or SPI to communicate, 2 or 4 pins are required
|
||||||
|
to interface. The device's I2C address is either 0x76 or 0x77.
|
||||||
|
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit andopen-source hardware by purchasing products
|
||||||
|
from Adafruit!
|
||||||
|
|
||||||
|
Written by Limor Fried & Kevin Townsend for Adafruit Industries.
|
||||||
|
BSD license, all text above must be included in any redistribution
|
||||||
|
See the LICENSE file for details.
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Adafruit_Sensor.h>
|
||||||
|
#include <Adafruit_BME280.h>
|
||||||
|
|
||||||
|
#define BME_SCK 13
|
||||||
|
#define BME_MISO 12
|
||||||
|
#define BME_MOSI 11
|
||||||
|
#define BME_CS 10
|
||||||
|
|
||||||
|
#define SEALEVELPRESSURE_HPA (1013.25)
|
||||||
|
|
||||||
|
Adafruit_BME280 bme; // I2C
|
||||||
|
//Adafruit_BME280 bme(BME_CS); // hardware SPI
|
||||||
|
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI
|
||||||
|
|
||||||
|
unsigned long delayTime;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
while(!Serial); // time to get serial running
|
||||||
|
Serial.println(F("BME280 test"));
|
||||||
|
|
||||||
|
unsigned status;
|
||||||
|
|
||||||
|
// default settings
|
||||||
|
status = bme.begin();
|
||||||
|
// You can also pass in a Wire library object like &Wire2
|
||||||
|
// status = bme.begin(0x76, &Wire2)
|
||||||
|
if (!status) {
|
||||||
|
Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
|
||||||
|
Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
|
||||||
|
Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
|
||||||
|
Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n");
|
||||||
|
Serial.print(" ID of 0x60 represents a BME 280.\n");
|
||||||
|
Serial.print(" ID of 0x61 represents a BME 680.\n");
|
||||||
|
while (1) delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("-- Default Test --");
|
||||||
|
delayTime = 1000;
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
printValues();
|
||||||
|
delay(delayTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void printValues() {
|
||||||
|
Serial.print("Temperature = ");
|
||||||
|
Serial.print(bme.readTemperature());
|
||||||
|
Serial.println(" °C");
|
||||||
|
|
||||||
|
Serial.print("Pressure = ");
|
||||||
|
|
||||||
|
Serial.print(bme.readPressure() / 100.0F);
|
||||||
|
Serial.println(" hPa");
|
||||||
|
|
||||||
|
Serial.print("Approx. Altitude = ");
|
||||||
|
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
|
||||||
|
Serial.println(" m");
|
||||||
|
|
||||||
|
Serial.print("Humidity = ");
|
||||||
|
Serial.print(bme.readHumidity());
|
||||||
|
Serial.println(" %");
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
10
libraries/Adafruit_BME280_Library/library.properties
Normal file
10
libraries/Adafruit_BME280_Library/library.properties
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
name=Adafruit BME280 Library
|
||||||
|
version=2.2.4
|
||||||
|
author=Adafruit
|
||||||
|
maintainer=Adafruit <info@adafruit.com>
|
||||||
|
sentence=Arduino library for BME280 sensors.
|
||||||
|
paragraph=Arduino library for BME280 humidity and pressure sensors.
|
||||||
|
category=Sensors
|
||||||
|
url=https://github.com/adafruit/Adafruit_BME280_Library
|
||||||
|
architectures=*
|
||||||
|
depends=Adafruit Unified Sensor, Adafruit BusIO
|
||||||
384
libraries/Adafruit_BusIO/Adafruit_BusIO_Register.cpp
Normal file
384
libraries/Adafruit_BusIO/Adafruit_BusIO_Register.cpp
Normal file
@@ -0,0 +1,384 @@
|
|||||||
|
#include <Adafruit_BusIO_Register.h>
|
||||||
|
|
||||||
|
#if !defined(SPI_INTERFACES_COUNT) || \
|
||||||
|
(defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create a register we access over an I2C Device (which defines the
|
||||||
|
* bus and address)
|
||||||
|
* @param i2cdevice The I2CDevice to use for underlying I2C access
|
||||||
|
* @param reg_addr The address pointer value for the I2C/SMBus register, can
|
||||||
|
* be 8 or 16 bits
|
||||||
|
* @param width The width of the register data itself, defaults to 1 byte
|
||||||
|
* @param byteorder The byte order of the register (used when width is > 1),
|
||||||
|
* defaults to LSBFIRST
|
||||||
|
* @param address_width The width of the register address itself, defaults
|
||||||
|
* to 1 byte
|
||||||
|
*/
|
||||||
|
Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice,
|
||||||
|
uint16_t reg_addr,
|
||||||
|
uint8_t width,
|
||||||
|
uint8_t byteorder,
|
||||||
|
uint8_t address_width) {
|
||||||
|
_i2cdevice = i2cdevice;
|
||||||
|
_spidevice = nullptr;
|
||||||
|
_addrwidth = address_width;
|
||||||
|
_address = reg_addr;
|
||||||
|
_byteorder = byteorder;
|
||||||
|
_width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create a register we access over an SPI Device (which defines the
|
||||||
|
* bus and CS pin)
|
||||||
|
* @param spidevice The SPIDevice to use for underlying SPI access
|
||||||
|
* @param reg_addr The address pointer value for the SPI register, can
|
||||||
|
* be 8 or 16 bits
|
||||||
|
* @param type The method we use to read/write data to SPI (which is not
|
||||||
|
* as well defined as I2C)
|
||||||
|
* @param width The width of the register data itself, defaults to 1 byte
|
||||||
|
* @param byteorder The byte order of the register (used when width is > 1),
|
||||||
|
* defaults to LSBFIRST
|
||||||
|
* @param address_width The width of the register address itself, defaults
|
||||||
|
* to 1 byte
|
||||||
|
*/
|
||||||
|
Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice,
|
||||||
|
uint16_t reg_addr,
|
||||||
|
Adafruit_BusIO_SPIRegType type,
|
||||||
|
uint8_t width,
|
||||||
|
uint8_t byteorder,
|
||||||
|
uint8_t address_width) {
|
||||||
|
_spidevice = spidevice;
|
||||||
|
_spiregtype = type;
|
||||||
|
_i2cdevice = nullptr;
|
||||||
|
_addrwidth = address_width;
|
||||||
|
_address = reg_addr;
|
||||||
|
_byteorder = byteorder;
|
||||||
|
_width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create a register we access over an I2C or SPI Device. This is a
|
||||||
|
* handy function because we can pass in nullptr for the unused interface,
|
||||||
|
* allowing libraries to mass-define all the registers
|
||||||
|
* @param i2cdevice The I2CDevice to use for underlying I2C access, if
|
||||||
|
* nullptr we use SPI
|
||||||
|
* @param spidevice The SPIDevice to use for underlying SPI access, if
|
||||||
|
* nullptr we use I2C
|
||||||
|
* @param reg_addr The address pointer value for the I2C/SMBus/SPI register,
|
||||||
|
* can be 8 or 16 bits
|
||||||
|
* @param type The method we use to read/write data to SPI (which is not
|
||||||
|
* as well defined as I2C)
|
||||||
|
* @param width The width of the register data itself, defaults to 1 byte
|
||||||
|
* @param byteorder The byte order of the register (used when width is > 1),
|
||||||
|
* defaults to LSBFIRST
|
||||||
|
* @param address_width The width of the register address itself, defaults
|
||||||
|
* to 1 byte
|
||||||
|
*/
|
||||||
|
Adafruit_BusIO_Register::Adafruit_BusIO_Register(
|
||||||
|
Adafruit_I2CDevice *i2cdevice, Adafruit_SPIDevice *spidevice,
|
||||||
|
Adafruit_BusIO_SPIRegType type, uint16_t reg_addr, uint8_t width,
|
||||||
|
uint8_t byteorder, uint8_t address_width) {
|
||||||
|
_spidevice = spidevice;
|
||||||
|
_i2cdevice = i2cdevice;
|
||||||
|
_spiregtype = type;
|
||||||
|
_addrwidth = address_width;
|
||||||
|
_address = reg_addr;
|
||||||
|
_byteorder = byteorder;
|
||||||
|
_width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create a register we access over a GenericDevice
|
||||||
|
* @param genericdevice Generic device to use
|
||||||
|
* @param reg_addr Register address we will read/write
|
||||||
|
* @param width Width of the register in bytes (1-4)
|
||||||
|
* @param byteorder Byte order of register data (LSBFIRST or MSBFIRST)
|
||||||
|
* @param address_width Width of the register address in bytes (1 or 2)
|
||||||
|
*/
|
||||||
|
Adafruit_BusIO_Register::Adafruit_BusIO_Register(
|
||||||
|
Adafruit_GenericDevice *genericdevice, uint16_t reg_addr, uint8_t width,
|
||||||
|
uint8_t byteorder, uint8_t address_width) {
|
||||||
|
_i2cdevice = nullptr;
|
||||||
|
_spidevice = nullptr;
|
||||||
|
_genericdevice = genericdevice;
|
||||||
|
_addrwidth = address_width;
|
||||||
|
_address = reg_addr;
|
||||||
|
_byteorder = byteorder;
|
||||||
|
_width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write a buffer of data to the register location
|
||||||
|
* @param buffer Pointer to data to write
|
||||||
|
* @param len Number of bytes to write
|
||||||
|
* @return True on successful write (only really useful for I2C as SPI is
|
||||||
|
* uncheckable)
|
||||||
|
*/
|
||||||
|
bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) {
|
||||||
|
uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF),
|
||||||
|
(uint8_t)(_address >> 8)};
|
||||||
|
if (_i2cdevice) {
|
||||||
|
return _i2cdevice->write(buffer, len, true, addrbuffer, _addrwidth);
|
||||||
|
}
|
||||||
|
if (_spidevice) {
|
||||||
|
if (_spiregtype == ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE) {
|
||||||
|
// very special case!
|
||||||
|
// pass the special opcode address which we set as the high byte of the
|
||||||
|
// regaddr
|
||||||
|
addrbuffer[0] =
|
||||||
|
(uint8_t)(_address >> 8) & ~0x01; // set bottom bit low to write
|
||||||
|
// the 'actual' reg addr is the second byte then
|
||||||
|
addrbuffer[1] = (uint8_t)(_address & 0xFF);
|
||||||
|
// the address appears to be a byte longer
|
||||||
|
return _spidevice->write(buffer, len, addrbuffer, _addrwidth + 1);
|
||||||
|
}
|
||||||
|
if (_spiregtype == ADDRBIT8_HIGH_TOREAD) {
|
||||||
|
addrbuffer[0] &= ~0x80;
|
||||||
|
}
|
||||||
|
if (_spiregtype == ADDRBIT8_HIGH_TOWRITE) {
|
||||||
|
addrbuffer[0] |= 0x80;
|
||||||
|
}
|
||||||
|
if (_spiregtype == AD8_HIGH_TOREAD_AD7_HIGH_TOINC) {
|
||||||
|
addrbuffer[0] &= ~0x80;
|
||||||
|
addrbuffer[0] |= 0x40;
|
||||||
|
}
|
||||||
|
return _spidevice->write(buffer, len, addrbuffer, _addrwidth);
|
||||||
|
}
|
||||||
|
if (_genericdevice) {
|
||||||
|
return _genericdevice->writeRegister(addrbuffer, _addrwidth, buffer, len);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write up to 4 bytes of data to the register location
|
||||||
|
* @param value Data to write
|
||||||
|
* @param numbytes How many bytes from 'value' to write
|
||||||
|
* @return True on successful write (only really useful for I2C as SPI is
|
||||||
|
* uncheckable)
|
||||||
|
*/
|
||||||
|
bool Adafruit_BusIO_Register::write(uint32_t value, uint8_t numbytes) {
|
||||||
|
if (numbytes == 0) {
|
||||||
|
numbytes = _width;
|
||||||
|
}
|
||||||
|
if (numbytes > 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// store a copy
|
||||||
|
_cached = value;
|
||||||
|
|
||||||
|
for (int i = 0; i < numbytes; i++) {
|
||||||
|
if (_byteorder == LSBFIRST) {
|
||||||
|
_buffer[i] = value & 0xFF;
|
||||||
|
} else {
|
||||||
|
_buffer[numbytes - i - 1] = value & 0xFF;
|
||||||
|
}
|
||||||
|
value >>= 8;
|
||||||
|
}
|
||||||
|
return write(_buffer, numbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read data from the register location. This does not do any error
|
||||||
|
* checking!
|
||||||
|
* @return Returns 0xFFFFFFFF on failure, value otherwise
|
||||||
|
*/
|
||||||
|
uint32_t Adafruit_BusIO_Register::read(void) {
|
||||||
|
if (!read(_buffer, _width)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t value = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < _width; i++) {
|
||||||
|
value <<= 8;
|
||||||
|
if (_byteorder == LSBFIRST) {
|
||||||
|
value |= _buffer[_width - i - 1];
|
||||||
|
} else {
|
||||||
|
value |= _buffer[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read cached data from last time we wrote to this register
|
||||||
|
* @return Returns 0xFFFFFFFF on failure, value otherwise
|
||||||
|
*/
|
||||||
|
uint32_t Adafruit_BusIO_Register::readCached(void) { return _cached; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief Read a number of bytes from a register into a buffer
|
||||||
|
@param buffer Buffer to read data into
|
||||||
|
@param len Number of bytes to read into the buffer
|
||||||
|
@return true on successful read, otherwise false
|
||||||
|
*/
|
||||||
|
bool Adafruit_BusIO_Register::read(uint8_t *buffer, uint8_t len) {
|
||||||
|
uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF),
|
||||||
|
(uint8_t)(_address >> 8)};
|
||||||
|
if (_i2cdevice) {
|
||||||
|
return _i2cdevice->write_then_read(addrbuffer, _addrwidth, buffer, len);
|
||||||
|
}
|
||||||
|
if (_spidevice) {
|
||||||
|
if (_spiregtype == ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE) {
|
||||||
|
// very special case!
|
||||||
|
// pass the special opcode address which we set as the high byte of the
|
||||||
|
// regaddr
|
||||||
|
addrbuffer[0] =
|
||||||
|
(uint8_t)(_address >> 8) | 0x01; // set bottom bit high to read
|
||||||
|
// the 'actual' reg addr is the second byte then
|
||||||
|
addrbuffer[1] = (uint8_t)(_address & 0xFF);
|
||||||
|
// the address appears to be a byte longer
|
||||||
|
return _spidevice->write_then_read(addrbuffer, _addrwidth + 1, buffer,
|
||||||
|
len);
|
||||||
|
}
|
||||||
|
if (_spiregtype == ADDRBIT8_HIGH_TOREAD) {
|
||||||
|
addrbuffer[0] |= 0x80;
|
||||||
|
}
|
||||||
|
if (_spiregtype == ADDRBIT8_HIGH_TOWRITE) {
|
||||||
|
addrbuffer[0] &= ~0x80;
|
||||||
|
}
|
||||||
|
if (_spiregtype == AD8_HIGH_TOREAD_AD7_HIGH_TOINC) {
|
||||||
|
addrbuffer[0] |= 0x80 | 0x40;
|
||||||
|
}
|
||||||
|
return _spidevice->write_then_read(addrbuffer, _addrwidth, buffer, len);
|
||||||
|
}
|
||||||
|
if (_genericdevice) {
|
||||||
|
return _genericdevice->readRegister(addrbuffer, _addrwidth, buffer, len);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read 2 bytes of data from the register location
|
||||||
|
* @param value Pointer to uint16_t variable to read into
|
||||||
|
* @return True on successful write (only really useful for I2C as SPI is
|
||||||
|
* uncheckable)
|
||||||
|
*/
|
||||||
|
bool Adafruit_BusIO_Register::read(uint16_t *value) {
|
||||||
|
if (!read(_buffer, 2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_byteorder == LSBFIRST) {
|
||||||
|
*value = _buffer[1];
|
||||||
|
*value <<= 8;
|
||||||
|
*value |= _buffer[0];
|
||||||
|
} else {
|
||||||
|
*value = _buffer[0];
|
||||||
|
*value <<= 8;
|
||||||
|
*value |= _buffer[1];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read 1 byte of data from the register location
|
||||||
|
* @param value Pointer to uint8_t variable to read into
|
||||||
|
* @return True on successful write (only really useful for I2C as SPI is
|
||||||
|
* uncheckable)
|
||||||
|
*/
|
||||||
|
bool Adafruit_BusIO_Register::read(uint8_t *value) {
|
||||||
|
if (!read(_buffer, 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*value = _buffer[0];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Pretty printer for this register
|
||||||
|
* @param s The Stream to print to, defaults to &Serial
|
||||||
|
*/
|
||||||
|
void Adafruit_BusIO_Register::print(Stream *s) {
|
||||||
|
uint32_t val = read();
|
||||||
|
s->print("0x");
|
||||||
|
s->print(val, HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Pretty printer for this register
|
||||||
|
* @param s The Stream to print to, defaults to &Serial
|
||||||
|
*/
|
||||||
|
void Adafruit_BusIO_Register::println(Stream *s) {
|
||||||
|
print(s);
|
||||||
|
s->println();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create a slice of the register that we can address without
|
||||||
|
* touching other bits
|
||||||
|
* @param reg The Adafruit_BusIO_Register which defines the bus/register
|
||||||
|
* @param bits The number of bits wide we are slicing
|
||||||
|
* @param shift The number of bits that our bit-slice is shifted from LSB
|
||||||
|
*/
|
||||||
|
Adafruit_BusIO_RegisterBits::Adafruit_BusIO_RegisterBits(
|
||||||
|
Adafruit_BusIO_Register *reg, uint8_t bits, uint8_t shift) {
|
||||||
|
_register = reg;
|
||||||
|
_bits = bits;
|
||||||
|
_shift = shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read 4 bytes of data from the register
|
||||||
|
* @return data The 4 bytes to read
|
||||||
|
*/
|
||||||
|
uint32_t Adafruit_BusIO_RegisterBits::read(void) {
|
||||||
|
uint32_t val = _register->read();
|
||||||
|
val >>= _shift;
|
||||||
|
return val & ((1 << (_bits)) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write 4 bytes of data to the register
|
||||||
|
* @param data The 4 bytes to write
|
||||||
|
* @return True on successful write (only really useful for I2C as SPI is
|
||||||
|
* uncheckable)
|
||||||
|
*/
|
||||||
|
bool Adafruit_BusIO_RegisterBits::write(uint32_t data) {
|
||||||
|
uint32_t val = _register->read();
|
||||||
|
|
||||||
|
// mask off the data before writing
|
||||||
|
uint32_t mask = (1 << (_bits)) - 1;
|
||||||
|
data &= mask;
|
||||||
|
|
||||||
|
mask <<= _shift;
|
||||||
|
val &= ~mask; // remove the current data at that spot
|
||||||
|
val |= data << _shift; // and add in the new data
|
||||||
|
|
||||||
|
return _register->write(val, _register->width());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief The width of the register data, helpful for doing calculations
|
||||||
|
* @returns The data width used when initializing the register
|
||||||
|
*/
|
||||||
|
uint8_t Adafruit_BusIO_Register::width(void) { return _width; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Set the default width of data
|
||||||
|
* @param width the default width of data read from register
|
||||||
|
*/
|
||||||
|
void Adafruit_BusIO_Register::setWidth(uint8_t width) { _width = width; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Set register address
|
||||||
|
* @param address the address from register
|
||||||
|
*/
|
||||||
|
void Adafruit_BusIO_Register::setAddress(uint16_t address) {
|
||||||
|
_address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Set the width of register address
|
||||||
|
* @param address_width the width for register address
|
||||||
|
*/
|
||||||
|
void Adafruit_BusIO_Register::setAddressWidth(uint16_t address_width) {
|
||||||
|
_addrwidth = address_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SPI exists
|
||||||
112
libraries/Adafruit_BusIO/Adafruit_BusIO_Register.h
Normal file
112
libraries/Adafruit_BusIO/Adafruit_BusIO_Register.h
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
#ifndef Adafruit_BusIO_Register_h
|
||||||
|
#define Adafruit_BusIO_Register_h
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#if !defined(SPI_INTERFACES_COUNT) || \
|
||||||
|
(defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
|
||||||
|
|
||||||
|
#include <Adafruit_GenericDevice.h>
|
||||||
|
#include <Adafruit_I2CDevice.h>
|
||||||
|
#include <Adafruit_SPIDevice.h>
|
||||||
|
|
||||||
|
typedef enum _Adafruit_BusIO_SPIRegType {
|
||||||
|
ADDRBIT8_HIGH_TOREAD = 0,
|
||||||
|
/*!<
|
||||||
|
* ADDRBIT8_HIGH_TOREAD
|
||||||
|
* When reading a register you must actually send the value 0x80 + register
|
||||||
|
* address to the device. e.g. To read the register 0x0B the register value
|
||||||
|
* 0x8B is sent and to write 0x0B is sent.
|
||||||
|
*/
|
||||||
|
AD8_HIGH_TOREAD_AD7_HIGH_TOINC = 1,
|
||||||
|
|
||||||
|
/*!<
|
||||||
|
* ADDRBIT8_HIGH_TOWRITE
|
||||||
|
* When writing to a register you must actually send the value 0x80 +
|
||||||
|
* the register address to the device. e.g. To write to the register 0x19 the
|
||||||
|
* register value 0x99 is sent and to read 0x19 is sent.
|
||||||
|
*/
|
||||||
|
ADDRBIT8_HIGH_TOWRITE = 2,
|
||||||
|
|
||||||
|
/*!<
|
||||||
|
* ADDRESSED_OPCODE_LOWBIT_TO_WRITE
|
||||||
|
* Used by the MCP23S series, we send 0x40 |'rd with the opcode
|
||||||
|
* Then set the lowest bit to write
|
||||||
|
*/
|
||||||
|
ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE = 3,
|
||||||
|
|
||||||
|
} Adafruit_BusIO_SPIRegType;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief The class which defines a device register (a location to read/write
|
||||||
|
* data from)
|
||||||
|
*/
|
||||||
|
class Adafruit_BusIO_Register {
|
||||||
|
public:
|
||||||
|
Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, uint16_t reg_addr,
|
||||||
|
uint8_t width = 1, uint8_t byteorder = LSBFIRST,
|
||||||
|
uint8_t address_width = 1);
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice, uint16_t reg_addr,
|
||||||
|
Adafruit_BusIO_SPIRegType type, uint8_t width = 1,
|
||||||
|
uint8_t byteorder = LSBFIRST,
|
||||||
|
uint8_t address_width = 1);
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice,
|
||||||
|
Adafruit_SPIDevice *spidevice,
|
||||||
|
Adafruit_BusIO_SPIRegType type, uint16_t reg_addr,
|
||||||
|
uint8_t width = 1, uint8_t byteorder = LSBFIRST,
|
||||||
|
uint8_t address_width = 1);
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register(Adafruit_GenericDevice *genericdevice,
|
||||||
|
uint16_t reg_addr, uint8_t width = 1,
|
||||||
|
uint8_t byteorder = LSBFIRST,
|
||||||
|
uint8_t address_width = 1);
|
||||||
|
|
||||||
|
bool read(uint8_t *buffer, uint8_t len);
|
||||||
|
bool read(uint8_t *value);
|
||||||
|
bool read(uint16_t *value);
|
||||||
|
uint32_t read(void);
|
||||||
|
uint32_t readCached(void);
|
||||||
|
bool write(uint8_t *buffer, uint8_t len);
|
||||||
|
bool write(uint32_t value, uint8_t numbytes = 0);
|
||||||
|
|
||||||
|
uint8_t width(void);
|
||||||
|
|
||||||
|
void setWidth(uint8_t width);
|
||||||
|
void setAddress(uint16_t address);
|
||||||
|
void setAddressWidth(uint16_t address_width);
|
||||||
|
|
||||||
|
void print(Stream *s = &Serial);
|
||||||
|
void println(Stream *s = &Serial);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Adafruit_I2CDevice *_i2cdevice;
|
||||||
|
Adafruit_SPIDevice *_spidevice;
|
||||||
|
Adafruit_GenericDevice *_genericdevice;
|
||||||
|
Adafruit_BusIO_SPIRegType _spiregtype;
|
||||||
|
uint16_t _address;
|
||||||
|
uint8_t _width, _addrwidth, _byteorder;
|
||||||
|
uint8_t _buffer[4]; // we won't support anything larger than uint32 for
|
||||||
|
// non-buffered read
|
||||||
|
uint32_t _cached = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief The class which defines a slice of bits from within a device register
|
||||||
|
* (a location to read/write data from)
|
||||||
|
*/
|
||||||
|
class Adafruit_BusIO_RegisterBits {
|
||||||
|
public:
|
||||||
|
Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register *reg, uint8_t bits,
|
||||||
|
uint8_t shift);
|
||||||
|
bool write(uint32_t value);
|
||||||
|
uint32_t read(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Adafruit_BusIO_Register *_register;
|
||||||
|
uint8_t _bits, _shift;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SPI exists
|
||||||
|
#endif // BusIO_Register_h
|
||||||
82
libraries/Adafruit_BusIO/Adafruit_GenericDevice.cpp
Normal file
82
libraries/Adafruit_BusIO/Adafruit_GenericDevice.cpp
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
Written with help by Claude!
|
||||||
|
https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c (at this time
|
||||||
|
chats are not shareable :(
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Adafruit_GenericDevice.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create a Generic device with the provided read/write functions
|
||||||
|
* @param obj Pointer to object instance
|
||||||
|
* @param read_func Function pointer for reading raw data
|
||||||
|
* @param write_func Function pointer for writing raw data
|
||||||
|
* @param readreg_func Function pointer for reading registers (optional)
|
||||||
|
* @param writereg_func Function pointer for writing registers (optional) */
|
||||||
|
Adafruit_GenericDevice::Adafruit_GenericDevice(
|
||||||
|
void *obj, busio_genericdevice_read_t read_func,
|
||||||
|
busio_genericdevice_write_t write_func,
|
||||||
|
busio_genericdevice_readreg_t readreg_func,
|
||||||
|
busio_genericdevice_writereg_t writereg_func) {
|
||||||
|
_obj = obj;
|
||||||
|
_read_func = read_func;
|
||||||
|
_write_func = write_func;
|
||||||
|
_readreg_func = readreg_func;
|
||||||
|
_writereg_func = writereg_func;
|
||||||
|
_begun = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @brief Simple begin function (doesn't do much at this time)
|
||||||
|
@return true always
|
||||||
|
*/
|
||||||
|
bool Adafruit_GenericDevice::begin(void) {
|
||||||
|
_begun = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @brief Write a buffer of data
|
||||||
|
@param buffer Pointer to buffer of data to write
|
||||||
|
@param len Number of bytes to write
|
||||||
|
@return true if write was successful, otherwise false */
|
||||||
|
bool Adafruit_GenericDevice::write(const uint8_t *buffer, size_t len) {
|
||||||
|
if (!_begun)
|
||||||
|
return false;
|
||||||
|
return _write_func(_obj, buffer, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @brief Read data into a buffer
|
||||||
|
@param buffer Pointer to buffer to read data into
|
||||||
|
@param len Number of bytes to read
|
||||||
|
@return true if read was successful, otherwise false */
|
||||||
|
bool Adafruit_GenericDevice::read(uint8_t *buffer, size_t len) {
|
||||||
|
if (!_begun)
|
||||||
|
return false;
|
||||||
|
return _read_func(_obj, buffer, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @brief Read from a register location
|
||||||
|
@param addr_buf Buffer containing register address
|
||||||
|
@param addrsiz Size of register address in bytes
|
||||||
|
@param buf Buffer to store read data
|
||||||
|
@param bufsiz Size of data to read in bytes
|
||||||
|
@return true if read was successful, otherwise false */
|
||||||
|
bool Adafruit_GenericDevice::readRegister(uint8_t *addr_buf, uint8_t addrsiz,
|
||||||
|
uint8_t *buf, uint16_t bufsiz) {
|
||||||
|
if (!_begun || !_readreg_func)
|
||||||
|
return false;
|
||||||
|
return _readreg_func(_obj, addr_buf, addrsiz, buf, bufsiz);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @brief Write to a register location
|
||||||
|
@param addr_buf Buffer containing register address
|
||||||
|
@param addrsiz Size of register address in bytes
|
||||||
|
@param buf Buffer containing data to write
|
||||||
|
@param bufsiz Size of data to write in bytes
|
||||||
|
@return true if write was successful, otherwise false */
|
||||||
|
bool Adafruit_GenericDevice::writeRegister(uint8_t *addr_buf, uint8_t addrsiz,
|
||||||
|
const uint8_t *buf,
|
||||||
|
uint16_t bufsiz) {
|
||||||
|
if (!_begun || !_writereg_func)
|
||||||
|
return false;
|
||||||
|
return _writereg_func(_obj, addr_buf, addrsiz, buf, bufsiz);
|
||||||
|
}
|
||||||
55
libraries/Adafruit_BusIO/Adafruit_GenericDevice.h
Normal file
55
libraries/Adafruit_BusIO/Adafruit_GenericDevice.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#ifndef ADAFRUIT_GENERICDEVICE_H
|
||||||
|
#define ADAFRUIT_GENERICDEVICE_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
typedef bool (*busio_genericdevice_read_t)(void *obj, uint8_t *buffer,
|
||||||
|
size_t len);
|
||||||
|
typedef bool (*busio_genericdevice_write_t)(void *obj, const uint8_t *buffer,
|
||||||
|
size_t len);
|
||||||
|
typedef bool (*busio_genericdevice_readreg_t)(void *obj, uint8_t *addr_buf,
|
||||||
|
uint8_t addrsiz, uint8_t *data,
|
||||||
|
uint16_t datalen);
|
||||||
|
typedef bool (*busio_genericdevice_writereg_t)(void *obj, uint8_t *addr_buf,
|
||||||
|
uint8_t addrsiz,
|
||||||
|
const uint8_t *data,
|
||||||
|
uint16_t datalen);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Class for communicating with a device via generic read/write functions
|
||||||
|
*/
|
||||||
|
class Adafruit_GenericDevice {
|
||||||
|
public:
|
||||||
|
Adafruit_GenericDevice(
|
||||||
|
void *obj, busio_genericdevice_read_t read_func,
|
||||||
|
busio_genericdevice_write_t write_func,
|
||||||
|
busio_genericdevice_readreg_t readreg_func = nullptr,
|
||||||
|
busio_genericdevice_writereg_t writereg_func = nullptr);
|
||||||
|
|
||||||
|
bool begin(void);
|
||||||
|
|
||||||
|
bool read(uint8_t *buffer, size_t len);
|
||||||
|
bool write(const uint8_t *buffer, size_t len);
|
||||||
|
bool readRegister(uint8_t *addr_buf, uint8_t addrsiz, uint8_t *buf,
|
||||||
|
uint16_t bufsiz);
|
||||||
|
bool writeRegister(uint8_t *addr_buf, uint8_t addrsiz, const uint8_t *buf,
|
||||||
|
uint16_t bufsiz);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/*! @brief Function pointer for reading raw data from the device */
|
||||||
|
busio_genericdevice_read_t _read_func;
|
||||||
|
/*! @brief Function pointer for writing raw data to the device */
|
||||||
|
busio_genericdevice_write_t _write_func;
|
||||||
|
/*! @brief Function pointer for reading a 'register' from the device */
|
||||||
|
busio_genericdevice_readreg_t _readreg_func;
|
||||||
|
/*! @brief Function pointer for writing a 'register' to the device */
|
||||||
|
busio_genericdevice_writereg_t _writereg_func;
|
||||||
|
|
||||||
|
bool _begun; ///< whether we have initialized yet (in case the function needs
|
||||||
|
///< to do something)
|
||||||
|
|
||||||
|
private:
|
||||||
|
void *_obj; ///< Pointer to object instance
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ADAFRUIT_GENERICDEVICE_H
|
||||||
320
libraries/Adafruit_BusIO/Adafruit_I2CDevice.cpp
Normal file
320
libraries/Adafruit_BusIO/Adafruit_I2CDevice.cpp
Normal file
@@ -0,0 +1,320 @@
|
|||||||
|
#include "Adafruit_I2CDevice.h"
|
||||||
|
|
||||||
|
// #define DEBUG_SERIAL Serial
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create an I2C device at a given address
|
||||||
|
* @param addr The 7-bit I2C address for the device
|
||||||
|
* @param theWire The I2C bus to use, defaults to &Wire
|
||||||
|
*/
|
||||||
|
Adafruit_I2CDevice::Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire) {
|
||||||
|
_addr = addr;
|
||||||
|
_wire = theWire;
|
||||||
|
_begun = false;
|
||||||
|
#ifdef ARDUINO_ARCH_SAMD
|
||||||
|
_maxBufferSize = 250; // as defined in Wire.h's RingBuffer
|
||||||
|
#elif defined(ESP32)
|
||||||
|
_maxBufferSize = I2C_BUFFER_LENGTH;
|
||||||
|
#else
|
||||||
|
_maxBufferSize = 32;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Initializes and does basic address detection
|
||||||
|
* @param addr_detect Whether we should attempt to detect the I2C address
|
||||||
|
* with a scan. 99% of sensors/devices don't mind, but once in a while they
|
||||||
|
* don't respond well to a scan!
|
||||||
|
* @return True if I2C initialized and a device with the addr found
|
||||||
|
*/
|
||||||
|
bool Adafruit_I2CDevice::begin(bool addr_detect) {
|
||||||
|
_wire->begin();
|
||||||
|
_begun = true;
|
||||||
|
|
||||||
|
if (addr_detect) {
|
||||||
|
return detected();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief De-initialize device, turn off the Wire interface
|
||||||
|
*/
|
||||||
|
void Adafruit_I2CDevice::end(void) {
|
||||||
|
// Not all port implement Wire::end(), such as
|
||||||
|
// - ESP8266
|
||||||
|
// - AVR core without WIRE_HAS_END
|
||||||
|
// - ESP32: end() is implemented since 2.0.1 which is latest at the moment.
|
||||||
|
// Temporarily disable for now to give time for user to update.
|
||||||
|
#if !(defined(ESP8266) || \
|
||||||
|
(defined(ARDUINO_ARCH_AVR) && !defined(WIRE_HAS_END)) || \
|
||||||
|
defined(ARDUINO_ARCH_ESP32))
|
||||||
|
_wire->end();
|
||||||
|
_begun = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Scans I2C for the address - note will give a false-positive
|
||||||
|
* if there's no pullups on I2C
|
||||||
|
* @return True if I2C initialized and a device with the addr found
|
||||||
|
*/
|
||||||
|
bool Adafruit_I2CDevice::detected(void) {
|
||||||
|
// Init I2C if not done yet
|
||||||
|
if (!_begun && !begin()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A basic scanner, see if it ACK's
|
||||||
|
_wire->beginTransmission(_addr);
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print(F("Address 0x"));
|
||||||
|
DEBUG_SERIAL.print(_addr, HEX);
|
||||||
|
#endif
|
||||||
|
#ifdef ARDUINO_ARCH_MBED
|
||||||
|
_wire->write(0); // forces a write request instead of a read
|
||||||
|
#endif
|
||||||
|
if (_wire->endTransmission() == 0) {
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.println(F(" Detected"));
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.println(F(" Not detected"));
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write a buffer or two to the I2C device. Cannot be more than
|
||||||
|
* maxBufferSize() bytes.
|
||||||
|
* @param buffer Pointer to buffer of data to write. This is const to
|
||||||
|
* ensure the content of this buffer doesn't change.
|
||||||
|
* @param len Number of bytes from buffer to write
|
||||||
|
* @param prefix_buffer Pointer to optional array of data to write before
|
||||||
|
* buffer. Cannot be more than maxBufferSize() bytes. This is const to
|
||||||
|
* ensure the content of this buffer doesn't change.
|
||||||
|
* @param prefix_len Number of bytes from prefix buffer to write
|
||||||
|
* @param stop Whether to send an I2C STOP signal on write
|
||||||
|
* @return True if write was successful, otherwise false.
|
||||||
|
*/
|
||||||
|
bool Adafruit_I2CDevice::write(const uint8_t *buffer, size_t len, bool stop,
|
||||||
|
const uint8_t *prefix_buffer,
|
||||||
|
size_t prefix_len) {
|
||||||
|
if ((len + prefix_len) > maxBufferSize()) {
|
||||||
|
// currently not guaranteed to work if more than 32 bytes!
|
||||||
|
// we will need to find out if some platforms have larger
|
||||||
|
// I2C buffer sizes :/
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.println(F("\tI2CDevice could not write such a large buffer"));
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_wire->beginTransmission(_addr);
|
||||||
|
|
||||||
|
// Write the prefix data (usually an address)
|
||||||
|
if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
|
||||||
|
if (_wire->write(prefix_buffer, prefix_len) != prefix_len) {
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the data itself
|
||||||
|
if (_wire->write(buffer, len) != len) {
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
|
||||||
|
DEBUG_SERIAL.print(F("\tI2CWRITE @ 0x"));
|
||||||
|
DEBUG_SERIAL.print(_addr, HEX);
|
||||||
|
DEBUG_SERIAL.print(F(" :: "));
|
||||||
|
if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
|
||||||
|
for (uint16_t i = 0; i < prefix_len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(prefix_buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (uint16_t i = 0; i < len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
if (i % 32 == 31) {
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stop) {
|
||||||
|
DEBUG_SERIAL.print("\tSTOP");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (_wire->endTransmission(stop) == 0) {
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
// DEBUG_SERIAL.println("Sent!");
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.println("\tFailed to send!");
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read from I2C into a buffer from the I2C device.
|
||||||
|
* Cannot be more than maxBufferSize() bytes.
|
||||||
|
* @param buffer Pointer to buffer of data to read into
|
||||||
|
* @param len Number of bytes from buffer to read.
|
||||||
|
* @param stop Whether to send an I2C STOP signal on read
|
||||||
|
* @return True if read was successful, otherwise false.
|
||||||
|
*/
|
||||||
|
bool Adafruit_I2CDevice::read(uint8_t *buffer, size_t len, bool stop) {
|
||||||
|
size_t pos = 0;
|
||||||
|
while (pos < len) {
|
||||||
|
size_t read_len =
|
||||||
|
((len - pos) > maxBufferSize()) ? maxBufferSize() : (len - pos);
|
||||||
|
bool read_stop = (pos < (len - read_len)) ? false : stop;
|
||||||
|
if (!_read(buffer + pos, read_len, read_stop))
|
||||||
|
return false;
|
||||||
|
pos += read_len;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Adafruit_I2CDevice::_read(uint8_t *buffer, size_t len, bool stop) {
|
||||||
|
#if defined(TinyWireM_h)
|
||||||
|
size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len);
|
||||||
|
#elif defined(ARDUINO_ARCH_MEGAAVR)
|
||||||
|
size_t recv = _wire->requestFrom(_addr, len, stop);
|
||||||
|
#else
|
||||||
|
size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len, (uint8_t)stop);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (recv != len) {
|
||||||
|
// Not enough data available to fulfill our obligation!
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print(F("\tI2CDevice did not receive enough data: "));
|
||||||
|
DEBUG_SERIAL.println(recv);
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < len; i++) {
|
||||||
|
buffer[i] = _wire->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print(F("\tI2CREAD @ 0x"));
|
||||||
|
DEBUG_SERIAL.print(_addr, HEX);
|
||||||
|
DEBUG_SERIAL.print(F(" :: "));
|
||||||
|
for (uint16_t i = 0; i < len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
if (len % 32 == 31) {
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write some data, then read some data from I2C into another buffer.
|
||||||
|
* Cannot be more than maxBufferSize() bytes. The buffers can point to
|
||||||
|
* same/overlapping locations.
|
||||||
|
* @param write_buffer Pointer to buffer of data to write from
|
||||||
|
* @param write_len Number of bytes from buffer to write.
|
||||||
|
* @param read_buffer Pointer to buffer of data to read into.
|
||||||
|
* @param read_len Number of bytes from buffer to read.
|
||||||
|
* @param stop Whether to send an I2C STOP signal between the write and read
|
||||||
|
* @return True if write & read was successful, otherwise false.
|
||||||
|
*/
|
||||||
|
bool Adafruit_I2CDevice::write_then_read(const uint8_t *write_buffer,
|
||||||
|
size_t write_len, uint8_t *read_buffer,
|
||||||
|
size_t read_len, bool stop) {
|
||||||
|
if (!write(write_buffer, write_len, stop)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return read(read_buffer, read_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Returns the 7-bit address of this device
|
||||||
|
* @return The 7-bit address of this device
|
||||||
|
*/
|
||||||
|
uint8_t Adafruit_I2CDevice::address(void) { return _addr; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Change the I2C clock speed to desired (relies on
|
||||||
|
* underlying Wire support!
|
||||||
|
* @param desiredclk The desired I2C SCL frequency
|
||||||
|
* @return True if this platform supports changing I2C speed.
|
||||||
|
* Not necessarily that the speed was achieved!
|
||||||
|
*/
|
||||||
|
bool Adafruit_I2CDevice::setSpeed(uint32_t desiredclk) {
|
||||||
|
#if defined(__AVR_ATmega328__) || \
|
||||||
|
defined(__AVR_ATmega328P__) // fix arduino core set clock
|
||||||
|
// calculate TWBR correctly
|
||||||
|
|
||||||
|
if ((F_CPU / 18) < desiredclk) {
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
Serial.println(F("I2C.setSpeed too high."));
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint32_t atwbr = ((F_CPU / desiredclk) - 16) / 2;
|
||||||
|
if (atwbr > 16320) {
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
Serial.println(F("I2C.setSpeed too low."));
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (atwbr <= 255) {
|
||||||
|
atwbr /= 1;
|
||||||
|
TWSR = 0x0;
|
||||||
|
} else if (atwbr <= 1020) {
|
||||||
|
atwbr /= 4;
|
||||||
|
TWSR = 0x1;
|
||||||
|
} else if (atwbr <= 4080) {
|
||||||
|
atwbr /= 16;
|
||||||
|
TWSR = 0x2;
|
||||||
|
} else { // if (atwbr <= 16320)
|
||||||
|
atwbr /= 64;
|
||||||
|
TWSR = 0x3;
|
||||||
|
}
|
||||||
|
TWBR = atwbr;
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
Serial.print(F("TWSR prescaler = "));
|
||||||
|
Serial.println(pow(4, TWSR));
|
||||||
|
Serial.print(F("TWBR = "));
|
||||||
|
Serial.println(atwbr);
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
#elif (ARDUINO >= 157) && !defined(ARDUINO_STM32_FEATHER) && \
|
||||||
|
!defined(TinyWireM_h)
|
||||||
|
_wire->setClock(desiredclk);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#else
|
||||||
|
(void)desiredclk;
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
36
libraries/Adafruit_BusIO/Adafruit_I2CDevice.h
Normal file
36
libraries/Adafruit_BusIO/Adafruit_I2CDevice.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef Adafruit_I2CDevice_h
|
||||||
|
#define Adafruit_I2CDevice_h
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
|
///< The class which defines how we will talk to this device over I2C
|
||||||
|
class Adafruit_I2CDevice {
|
||||||
|
public:
|
||||||
|
Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire = &Wire);
|
||||||
|
uint8_t address(void);
|
||||||
|
bool begin(bool addr_detect = true);
|
||||||
|
void end(void);
|
||||||
|
bool detected(void);
|
||||||
|
|
||||||
|
bool read(uint8_t *buffer, size_t len, bool stop = true);
|
||||||
|
bool write(const uint8_t *buffer, size_t len, bool stop = true,
|
||||||
|
const uint8_t *prefix_buffer = nullptr, size_t prefix_len = 0);
|
||||||
|
bool write_then_read(const uint8_t *write_buffer, size_t write_len,
|
||||||
|
uint8_t *read_buffer, size_t read_len,
|
||||||
|
bool stop = false);
|
||||||
|
bool setSpeed(uint32_t desiredclk);
|
||||||
|
|
||||||
|
/*! @brief How many bytes we can read in a transaction
|
||||||
|
* @return The size of the Wire receive/transmit buffer */
|
||||||
|
size_t maxBufferSize() { return _maxBufferSize; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t _addr;
|
||||||
|
TwoWire *_wire;
|
||||||
|
bool _begun;
|
||||||
|
size_t _maxBufferSize;
|
||||||
|
bool _read(uint8_t *buffer, size_t len, bool stop);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // Adafruit_I2CDevice_h
|
||||||
10
libraries/Adafruit_BusIO/Adafruit_I2CRegister.h
Normal file
10
libraries/Adafruit_BusIO/Adafruit_I2CRegister.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _ADAFRUIT_I2C_REGISTER_H_
|
||||||
|
#define _ADAFRUIT_I2C_REGISTER_H_
|
||||||
|
|
||||||
|
#include <Adafruit_BusIO_Register.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
typedef Adafruit_BusIO_Register Adafruit_I2CRegister;
|
||||||
|
typedef Adafruit_BusIO_RegisterBits Adafruit_I2CRegisterBits;
|
||||||
|
|
||||||
|
#endif
|
||||||
508
libraries/Adafruit_BusIO/Adafruit_SPIDevice.cpp
Normal file
508
libraries/Adafruit_BusIO/Adafruit_SPIDevice.cpp
Normal file
@@ -0,0 +1,508 @@
|
|||||||
|
#include "Adafruit_SPIDevice.h"
|
||||||
|
|
||||||
|
// #define DEBUG_SERIAL Serial
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create an SPI device with the given CS pin and settings
|
||||||
|
* @param cspin The arduino pin number to use for chip select
|
||||||
|
* @param freq The SPI clock frequency to use, defaults to 1MHz
|
||||||
|
* @param dataOrder The SPI data order to use for bits within each byte,
|
||||||
|
* defaults to SPI_BITORDER_MSBFIRST
|
||||||
|
* @param dataMode The SPI mode to use, defaults to SPI_MODE0
|
||||||
|
* @param theSPI The SPI bus to use, defaults to &theSPI
|
||||||
|
*/
|
||||||
|
Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, uint32_t freq,
|
||||||
|
BusIOBitOrder dataOrder,
|
||||||
|
uint8_t dataMode, SPIClass *theSPI) {
|
||||||
|
#ifdef BUSIO_HAS_HW_SPI
|
||||||
|
_cs = cspin;
|
||||||
|
_sck = _mosi = _miso = -1;
|
||||||
|
_spi = theSPI;
|
||||||
|
_begun = false;
|
||||||
|
_spiSetting = new SPISettings(freq, dataOrder, dataMode);
|
||||||
|
_freq = freq;
|
||||||
|
_dataOrder = dataOrder;
|
||||||
|
_dataMode = dataMode;
|
||||||
|
#else
|
||||||
|
// unused, but needed to suppress compiler warns
|
||||||
|
(void)cspin;
|
||||||
|
(void)freq;
|
||||||
|
(void)dataOrder;
|
||||||
|
(void)dataMode;
|
||||||
|
(void)theSPI;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Create an SPI device with the given CS pin and settings
|
||||||
|
* @param cspin The arduino pin number to use for chip select
|
||||||
|
* @param sckpin The arduino pin number to use for SCK
|
||||||
|
* @param misopin The arduino pin number to use for MISO, set to -1 if not
|
||||||
|
* used
|
||||||
|
* @param mosipin The arduino pin number to use for MOSI, set to -1 if not
|
||||||
|
* used
|
||||||
|
* @param freq The SPI clock frequency to use, defaults to 1MHz
|
||||||
|
* @param dataOrder The SPI data order to use for bits within each byte,
|
||||||
|
* defaults to SPI_BITORDER_MSBFIRST
|
||||||
|
* @param dataMode The SPI mode to use, defaults to SPI_MODE0
|
||||||
|
*/
|
||||||
|
Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, int8_t sckpin,
|
||||||
|
int8_t misopin, int8_t mosipin,
|
||||||
|
uint32_t freq, BusIOBitOrder dataOrder,
|
||||||
|
uint8_t dataMode) {
|
||||||
|
_cs = cspin;
|
||||||
|
_sck = sckpin;
|
||||||
|
_miso = misopin;
|
||||||
|
_mosi = mosipin;
|
||||||
|
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
csPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(cspin));
|
||||||
|
csPinMask = digitalPinToBitMask(cspin);
|
||||||
|
if (mosipin != -1) {
|
||||||
|
mosiPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(mosipin));
|
||||||
|
mosiPinMask = digitalPinToBitMask(mosipin);
|
||||||
|
}
|
||||||
|
if (misopin != -1) {
|
||||||
|
misoPort = (BusIO_PortReg *)portInputRegister(digitalPinToPort(misopin));
|
||||||
|
misoPinMask = digitalPinToBitMask(misopin);
|
||||||
|
}
|
||||||
|
clkPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(sckpin));
|
||||||
|
clkPinMask = digitalPinToBitMask(sckpin);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_freq = freq;
|
||||||
|
_dataOrder = dataOrder;
|
||||||
|
_dataMode = dataMode;
|
||||||
|
_begun = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Release memory allocated in constructors
|
||||||
|
*/
|
||||||
|
Adafruit_SPIDevice::~Adafruit_SPIDevice() {
|
||||||
|
if (_spiSetting)
|
||||||
|
delete _spiSetting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Initializes SPI bus and sets CS pin high
|
||||||
|
* @return Always returns true because there's no way to test success of SPI
|
||||||
|
* init
|
||||||
|
*/
|
||||||
|
bool Adafruit_SPIDevice::begin(void) {
|
||||||
|
if (_cs != -1) {
|
||||||
|
pinMode(_cs, OUTPUT);
|
||||||
|
digitalWrite(_cs, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_spi) { // hardware SPI
|
||||||
|
#ifdef BUSIO_HAS_HW_SPI
|
||||||
|
_spi->begin();
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
pinMode(_sck, OUTPUT);
|
||||||
|
|
||||||
|
if ((_dataMode == SPI_MODE0) || (_dataMode == SPI_MODE1)) {
|
||||||
|
// idle low on mode 0 and 1
|
||||||
|
digitalWrite(_sck, LOW);
|
||||||
|
} else {
|
||||||
|
// idle high on mode 2 or 3
|
||||||
|
digitalWrite(_sck, HIGH);
|
||||||
|
}
|
||||||
|
if (_mosi != -1) {
|
||||||
|
pinMode(_mosi, OUTPUT);
|
||||||
|
digitalWrite(_mosi, HIGH);
|
||||||
|
}
|
||||||
|
if (_miso != -1) {
|
||||||
|
pinMode(_miso, INPUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_begun = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Transfer (send/receive) a buffer over hard/soft SPI, without
|
||||||
|
* transaction management
|
||||||
|
* @param buffer The buffer to send and receive at the same time
|
||||||
|
* @param len The number of bytes to transfer
|
||||||
|
*/
|
||||||
|
void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
|
||||||
|
//
|
||||||
|
// HARDWARE SPI
|
||||||
|
//
|
||||||
|
if (_spi) {
|
||||||
|
#ifdef BUSIO_HAS_HW_SPI
|
||||||
|
#if defined(SPARK)
|
||||||
|
_spi->transfer(buffer, buffer, len, nullptr);
|
||||||
|
#elif defined(STM32)
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
_spi->transfer(buffer[i]);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
_spi->transfer(buffer, len);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// SOFTWARE SPI
|
||||||
|
//
|
||||||
|
uint8_t startbit;
|
||||||
|
if (_dataOrder == SPI_BITORDER_LSBFIRST) {
|
||||||
|
startbit = 0x1;
|
||||||
|
} else {
|
||||||
|
startbit = 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool towrite, lastmosi = !(buffer[0] & startbit);
|
||||||
|
uint8_t bitdelay_us = (1000000 / _freq) / 2;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
uint8_t reply = 0;
|
||||||
|
uint8_t send = buffer[i];
|
||||||
|
|
||||||
|
/*
|
||||||
|
Serial.print("\tSending software SPI byte 0x");
|
||||||
|
Serial.print(send, HEX);
|
||||||
|
Serial.print(" -> 0x");
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Serial.print(send, HEX);
|
||||||
|
for (uint8_t b = startbit; b != 0;
|
||||||
|
b = (_dataOrder == SPI_BITORDER_LSBFIRST) ? b << 1 : b >> 1) {
|
||||||
|
|
||||||
|
if (bitdelay_us) {
|
||||||
|
delayMicroseconds(bitdelay_us);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_dataMode == SPI_MODE0 || _dataMode == SPI_MODE2) {
|
||||||
|
towrite = send & b;
|
||||||
|
if ((_mosi != -1) && (lastmosi != towrite)) {
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
if (towrite)
|
||||||
|
*mosiPort = *mosiPort | mosiPinMask;
|
||||||
|
else
|
||||||
|
*mosiPort = *mosiPort & ~mosiPinMask;
|
||||||
|
#else
|
||||||
|
digitalWrite(_mosi, towrite);
|
||||||
|
#endif
|
||||||
|
lastmosi = towrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
*clkPort = *clkPort | clkPinMask; // Clock high
|
||||||
|
#else
|
||||||
|
digitalWrite(_sck, HIGH);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (bitdelay_us) {
|
||||||
|
delayMicroseconds(bitdelay_us);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_miso != -1) {
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
if (*misoPort & misoPinMask) {
|
||||||
|
#else
|
||||||
|
if (digitalRead(_miso)) {
|
||||||
|
#endif
|
||||||
|
reply |= b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
*clkPort = *clkPort & ~clkPinMask; // Clock low
|
||||||
|
#else
|
||||||
|
digitalWrite(_sck, LOW);
|
||||||
|
#endif
|
||||||
|
} else { // if (_dataMode == SPI_MODE1 || _dataMode == SPI_MODE3)
|
||||||
|
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
*clkPort = *clkPort | clkPinMask; // Clock high
|
||||||
|
#else
|
||||||
|
digitalWrite(_sck, HIGH);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (bitdelay_us) {
|
||||||
|
delayMicroseconds(bitdelay_us);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_mosi != -1) {
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
if (send & b)
|
||||||
|
*mosiPort = *mosiPort | mosiPinMask;
|
||||||
|
else
|
||||||
|
*mosiPort = *mosiPort & ~mosiPinMask;
|
||||||
|
#else
|
||||||
|
digitalWrite(_mosi, send & b);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
*clkPort = *clkPort & ~clkPinMask; // Clock low
|
||||||
|
#else
|
||||||
|
digitalWrite(_sck, LOW);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (_miso != -1) {
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
if (*misoPort & misoPinMask) {
|
||||||
|
#else
|
||||||
|
if (digitalRead(_miso)) {
|
||||||
|
#endif
|
||||||
|
reply |= b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_miso != -1) {
|
||||||
|
buffer[i] = reply;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Transfer (send/receive) one byte over hard/soft SPI, without
|
||||||
|
* transaction management
|
||||||
|
* @param send The byte to send
|
||||||
|
* @return The byte received while transmitting
|
||||||
|
*/
|
||||||
|
uint8_t Adafruit_SPIDevice::transfer(uint8_t send) {
|
||||||
|
uint8_t data = send;
|
||||||
|
transfer(&data, 1);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Manually begin a transaction (calls beginTransaction if hardware
|
||||||
|
* SPI)
|
||||||
|
*/
|
||||||
|
void Adafruit_SPIDevice::beginTransaction(void) {
|
||||||
|
if (_spi) {
|
||||||
|
#ifdef BUSIO_HAS_HW_SPI
|
||||||
|
_spi->beginTransaction(*_spiSetting);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Manually end a transaction (calls endTransaction if hardware SPI)
|
||||||
|
*/
|
||||||
|
void Adafruit_SPIDevice::endTransaction(void) {
|
||||||
|
if (_spi) {
|
||||||
|
#ifdef BUSIO_HAS_HW_SPI
|
||||||
|
_spi->endTransaction();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Assert/Deassert the CS pin if it is defined
|
||||||
|
* @param value The state the CS is set to
|
||||||
|
*/
|
||||||
|
void Adafruit_SPIDevice::setChipSelect(int value) {
|
||||||
|
if (_cs != -1) {
|
||||||
|
digitalWrite(_cs, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write a buffer or two to the SPI device, with transaction
|
||||||
|
* management.
|
||||||
|
* @brief Manually begin a transaction (calls beginTransaction if hardware
|
||||||
|
* SPI) with asserting the CS pin
|
||||||
|
*/
|
||||||
|
void Adafruit_SPIDevice::beginTransactionWithAssertingCS() {
|
||||||
|
beginTransaction();
|
||||||
|
setChipSelect(LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Manually end a transaction (calls endTransaction if hardware SPI)
|
||||||
|
* with deasserting the CS pin
|
||||||
|
*/
|
||||||
|
void Adafruit_SPIDevice::endTransactionWithDeassertingCS() {
|
||||||
|
setChipSelect(HIGH);
|
||||||
|
endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write a buffer or two to the SPI device, with transaction
|
||||||
|
* management.
|
||||||
|
* @param buffer Pointer to buffer of data to write
|
||||||
|
* @param len Number of bytes from buffer to write
|
||||||
|
* @param prefix_buffer Pointer to optional array of data to write before
|
||||||
|
* buffer.
|
||||||
|
* @param prefix_len Number of bytes from prefix buffer to write
|
||||||
|
* @return Always returns true because there's no way to test success of SPI
|
||||||
|
* writes
|
||||||
|
*/
|
||||||
|
bool Adafruit_SPIDevice::write(const uint8_t *buffer, size_t len,
|
||||||
|
const uint8_t *prefix_buffer,
|
||||||
|
size_t prefix_len) {
|
||||||
|
beginTransactionWithAssertingCS();
|
||||||
|
|
||||||
|
// do the writing
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
if (_spi) {
|
||||||
|
if (prefix_len > 0) {
|
||||||
|
_spi->transferBytes((uint8_t *)prefix_buffer, nullptr, prefix_len);
|
||||||
|
}
|
||||||
|
if (len > 0) {
|
||||||
|
_spi->transferBytes((uint8_t *)buffer, nullptr, len);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < prefix_len; i++) {
|
||||||
|
transfer(prefix_buffer[i]);
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
transfer(buffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endTransactionWithDeassertingCS();
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print(F("\tSPIDevice Wrote: "));
|
||||||
|
if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
|
||||||
|
for (uint16_t i = 0; i < prefix_len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(prefix_buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (uint16_t i = 0; i < len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
if (i % 32 == 31) {
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Read from SPI into a buffer from the SPI device, with transaction
|
||||||
|
* management.
|
||||||
|
* @param buffer Pointer to buffer of data to read into
|
||||||
|
* @param len Number of bytes from buffer to read.
|
||||||
|
* @param sendvalue The 8-bits of data to write when doing the data read,
|
||||||
|
* defaults to 0xFF
|
||||||
|
* @return Always returns true because there's no way to test success of SPI
|
||||||
|
* writes
|
||||||
|
*/
|
||||||
|
bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
|
||||||
|
memset(buffer, sendvalue, len); // clear out existing buffer
|
||||||
|
|
||||||
|
beginTransactionWithAssertingCS();
|
||||||
|
transfer(buffer, len);
|
||||||
|
endTransactionWithDeassertingCS();
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print(F("\tSPIDevice Read: "));
|
||||||
|
for (uint16_t i = 0; i < len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
if (len % 32 == 31) {
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write some data, then read some data from SPI into another buffer,
|
||||||
|
* with transaction management. The buffers can point to same/overlapping
|
||||||
|
* locations. This does not transmit-receive at the same time!
|
||||||
|
* @param write_buffer Pointer to buffer of data to write from
|
||||||
|
* @param write_len Number of bytes from buffer to write.
|
||||||
|
* @param read_buffer Pointer to buffer of data to read into.
|
||||||
|
* @param read_len Number of bytes from buffer to read.
|
||||||
|
* @param sendvalue The 8-bits of data to write when doing the data read,
|
||||||
|
* defaults to 0xFF
|
||||||
|
* @return Always returns true because there's no way to test success of SPI
|
||||||
|
* writes
|
||||||
|
*/
|
||||||
|
bool Adafruit_SPIDevice::write_then_read(const uint8_t *write_buffer,
|
||||||
|
size_t write_len, uint8_t *read_buffer,
|
||||||
|
size_t read_len, uint8_t sendvalue) {
|
||||||
|
beginTransactionWithAssertingCS();
|
||||||
|
// do the writing
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
if (_spi) {
|
||||||
|
if (write_len > 0) {
|
||||||
|
_spi->transferBytes((uint8_t *)write_buffer, nullptr, write_len);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < write_len; i++) {
|
||||||
|
transfer(write_buffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print(F("\tSPIDevice Wrote: "));
|
||||||
|
for (uint16_t i = 0; i < write_len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(write_buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
if (write_len % 32 == 31) {
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// do the reading
|
||||||
|
for (size_t i = 0; i < read_len; i++) {
|
||||||
|
read_buffer[i] = transfer(sendvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
DEBUG_SERIAL.print(F("\tSPIDevice Read: "));
|
||||||
|
for (uint16_t i = 0; i < read_len; i++) {
|
||||||
|
DEBUG_SERIAL.print(F("0x"));
|
||||||
|
DEBUG_SERIAL.print(read_buffer[i], HEX);
|
||||||
|
DEBUG_SERIAL.print(F(", "));
|
||||||
|
if (read_len % 32 == 31) {
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG_SERIAL.println();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
endTransactionWithDeassertingCS();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Write some data and read some data at the same time from SPI
|
||||||
|
* into the same buffer, with transaction management. This is basicaly a wrapper
|
||||||
|
* for transfer() with CS-pin and transaction management. This /does/
|
||||||
|
* transmit-receive at the same time!
|
||||||
|
* @param buffer Pointer to buffer of data to write/read to/from
|
||||||
|
* @param len Number of bytes from buffer to write/read.
|
||||||
|
* @return Always returns true because there's no way to test success of SPI
|
||||||
|
* writes
|
||||||
|
*/
|
||||||
|
bool Adafruit_SPIDevice::write_and_read(uint8_t *buffer, size_t len) {
|
||||||
|
beginTransactionWithAssertingCS();
|
||||||
|
transfer(buffer, len);
|
||||||
|
endTransactionWithDeassertingCS();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
148
libraries/Adafruit_BusIO/Adafruit_SPIDevice.h
Normal file
148
libraries/Adafruit_BusIO/Adafruit_SPIDevice.h
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
#ifndef Adafruit_SPIDevice_h
|
||||||
|
#define Adafruit_SPIDevice_h
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#if !defined(SPI_INTERFACES_COUNT) || \
|
||||||
|
(defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
|
||||||
|
// HW SPI available
|
||||||
|
#include <SPI.h>
|
||||||
|
#define BUSIO_HAS_HW_SPI
|
||||||
|
#else
|
||||||
|
// SW SPI ONLY
|
||||||
|
enum { SPI_MODE0, SPI_MODE1, SPI_MODE2, _SPI_MODE4 };
|
||||||
|
typedef uint8_t SPIClass;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// some modern SPI definitions don't have BitOrder enum
|
||||||
|
#if (defined(__AVR__) && !defined(ARDUINO_ARCH_MEGAAVR)) || \
|
||||||
|
defined(ESP8266) || defined(TEENSYDUINO) || defined(SPARK) || \
|
||||||
|
defined(ARDUINO_ARCH_SPRESENSE) || defined(MEGATINYCORE) || \
|
||||||
|
defined(DXCORE) || defined(ARDUINO_AVR_ATmega4809) || \
|
||||||
|
defined(ARDUINO_AVR_ATmega4808) || defined(ARDUINO_AVR_ATmega3209) || \
|
||||||
|
defined(ARDUINO_AVR_ATmega3208) || defined(ARDUINO_AVR_ATmega1609) || \
|
||||||
|
defined(ARDUINO_AVR_ATmega1608) || defined(ARDUINO_AVR_ATmega809) || \
|
||||||
|
defined(ARDUINO_AVR_ATmega808) || defined(ARDUINO_ARCH_ARC32) || \
|
||||||
|
defined(ARDUINO_ARCH_XMC)
|
||||||
|
|
||||||
|
typedef enum _BitOrder {
|
||||||
|
SPI_BITORDER_MSBFIRST = MSBFIRST,
|
||||||
|
SPI_BITORDER_LSBFIRST = LSBFIRST,
|
||||||
|
} BusIOBitOrder;
|
||||||
|
|
||||||
|
#elif defined(ESP32) || defined(__ASR6501__) || defined(__ASR6502__)
|
||||||
|
|
||||||
|
// some modern SPI definitions don't have BitOrder enum and have different SPI
|
||||||
|
// mode defines
|
||||||
|
typedef enum _BitOrder {
|
||||||
|
SPI_BITORDER_MSBFIRST = SPI_MSBFIRST,
|
||||||
|
SPI_BITORDER_LSBFIRST = SPI_LSBFIRST,
|
||||||
|
} BusIOBitOrder;
|
||||||
|
|
||||||
|
#else
|
||||||
|
// Some platforms have a BitOrder enum but its named MSBFIRST/LSBFIRST
|
||||||
|
#define SPI_BITORDER_MSBFIRST MSBFIRST
|
||||||
|
#define SPI_BITORDER_LSBFIRST LSBFIRST
|
||||||
|
typedef BitOrder BusIOBitOrder;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__IMXRT1062__) // Teensy 4.x
|
||||||
|
// *Warning* I disabled the usage of FAST_PINIO as the set/clear operations
|
||||||
|
// used in the cpp file are not atomic and can effect multiple IO pins
|
||||||
|
// and if an interrupt happens in between the time the code reads the register
|
||||||
|
// and writes out the updated value, that changes one or more other IO pins
|
||||||
|
// on that same IO port, those change will be clobbered when the updated
|
||||||
|
// values are written back. A fast version can be implemented that uses the
|
||||||
|
// ports set and clear registers which are atomic.
|
||||||
|
// typedef volatile uint32_t BusIO_PortReg;
|
||||||
|
// typedef uint32_t BusIO_PortMask;
|
||||||
|
// #define BUSIO_USE_FAST_PINIO
|
||||||
|
|
||||||
|
#elif defined(__MBED__) || defined(__ZEPHYR__)
|
||||||
|
// Boards based on RTOS cores like mbed or Zephyr are not going to expose the
|
||||||
|
// low level registers needed for fast pin manipulation
|
||||||
|
#undef BUSIO_USE_FAST_PINIO
|
||||||
|
|
||||||
|
#elif defined(ARDUINO_ARCH_XMC)
|
||||||
|
#undef BUSIO_USE_FAST_PINIO
|
||||||
|
|
||||||
|
#elif defined(__AVR__) || defined(TEENSYDUINO)
|
||||||
|
typedef volatile uint8_t BusIO_PortReg;
|
||||||
|
typedef uint8_t BusIO_PortMask;
|
||||||
|
#define BUSIO_USE_FAST_PINIO
|
||||||
|
|
||||||
|
#elif defined(ESP8266) || defined(ESP32) || defined(__SAM3X8E__) || \
|
||||||
|
defined(ARDUINO_ARCH_SAMD)
|
||||||
|
typedef volatile uint32_t BusIO_PortReg;
|
||||||
|
typedef uint32_t BusIO_PortMask;
|
||||||
|
#define BUSIO_USE_FAST_PINIO
|
||||||
|
|
||||||
|
#elif (defined(__arm__) || defined(ARDUINO_FEATHER52)) && \
|
||||||
|
!defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_SILABS) && \
|
||||||
|
!defined(ARDUINO_UNOR4_MINIMA) && !defined(ARDUINO_UNOR4_WIFI)
|
||||||
|
typedef volatile uint32_t BusIO_PortReg;
|
||||||
|
typedef uint32_t BusIO_PortMask;
|
||||||
|
#if !defined(__ASR6501__) && !defined(__ASR6502__)
|
||||||
|
#define BUSIO_USE_FAST_PINIO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
#undef BUSIO_USE_FAST_PINIO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**! The class which defines how we will talk to this device over SPI **/
|
||||||
|
class Adafruit_SPIDevice {
|
||||||
|
public:
|
||||||
|
#ifdef BUSIO_HAS_HW_SPI
|
||||||
|
Adafruit_SPIDevice(int8_t cspin, uint32_t freq = 1000000,
|
||||||
|
BusIOBitOrder dataOrder = SPI_BITORDER_MSBFIRST,
|
||||||
|
uint8_t dataMode = SPI_MODE0, SPIClass *theSPI = &SPI);
|
||||||
|
#else
|
||||||
|
Adafruit_SPIDevice(int8_t cspin, uint32_t freq = 1000000,
|
||||||
|
BusIOBitOrder dataOrder = SPI_BITORDER_MSBFIRST,
|
||||||
|
uint8_t dataMode = SPI_MODE0, SPIClass *theSPI = nullptr);
|
||||||
|
#endif
|
||||||
|
Adafruit_SPIDevice(int8_t cspin, int8_t sck, int8_t miso, int8_t mosi,
|
||||||
|
uint32_t freq = 1000000,
|
||||||
|
BusIOBitOrder dataOrder = SPI_BITORDER_MSBFIRST,
|
||||||
|
uint8_t dataMode = SPI_MODE0);
|
||||||
|
~Adafruit_SPIDevice();
|
||||||
|
|
||||||
|
bool begin(void);
|
||||||
|
bool read(uint8_t *buffer, size_t len, uint8_t sendvalue = 0xFF);
|
||||||
|
bool write(const uint8_t *buffer, size_t len,
|
||||||
|
const uint8_t *prefix_buffer = nullptr, size_t prefix_len = 0);
|
||||||
|
bool write_then_read(const uint8_t *write_buffer, size_t write_len,
|
||||||
|
uint8_t *read_buffer, size_t read_len,
|
||||||
|
uint8_t sendvalue = 0xFF);
|
||||||
|
bool write_and_read(uint8_t *buffer, size_t len);
|
||||||
|
|
||||||
|
uint8_t transfer(uint8_t send);
|
||||||
|
void transfer(uint8_t *buffer, size_t len);
|
||||||
|
void beginTransaction(void);
|
||||||
|
void endTransaction(void);
|
||||||
|
void beginTransactionWithAssertingCS();
|
||||||
|
void endTransactionWithDeassertingCS();
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef BUSIO_HAS_HW_SPI
|
||||||
|
SPIClass *_spi = nullptr;
|
||||||
|
SPISettings *_spiSetting = nullptr;
|
||||||
|
#else
|
||||||
|
uint8_t *_spi = nullptr;
|
||||||
|
uint8_t *_spiSetting = nullptr;
|
||||||
|
#endif
|
||||||
|
uint32_t _freq;
|
||||||
|
BusIOBitOrder _dataOrder;
|
||||||
|
uint8_t _dataMode;
|
||||||
|
void setChipSelect(int value);
|
||||||
|
|
||||||
|
int8_t _cs, _sck, _mosi, _miso;
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
BusIO_PortReg *mosiPort, *clkPort, *misoPort, *csPort;
|
||||||
|
BusIO_PortMask mosiPinMask, misoPinMask, clkPinMask, csPinMask;
|
||||||
|
#endif
|
||||||
|
bool _begun;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // Adafruit_SPIDevice_h
|
||||||
11
libraries/Adafruit_BusIO/CMakeLists.txt
Normal file
11
libraries/Adafruit_BusIO/CMakeLists.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Adafruit Bus IO Library
|
||||||
|
# https://github.com/adafruit/Adafruit_BusIO
|
||||||
|
# MIT License
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
idf_component_register(SRCS "Adafruit_I2CDevice.cpp" "Adafruit_BusIO_Register.cpp" "Adafruit_SPIDevice.cpp"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES arduino-esp32)
|
||||||
|
|
||||||
|
project(Adafruit_BusIO)
|
||||||
21
libraries/Adafruit_BusIO/LICENSE
Normal file
21
libraries/Adafruit_BusIO/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2017 Adafruit Industries
|
||||||
|
|
||||||
|
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.
|
||||||
8
libraries/Adafruit_BusIO/README.md
Normal file
8
libraries/Adafruit_BusIO/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Adafruit Bus IO Library [](https://github.com/adafruit/Adafruit_BusIO/actions)
|
||||||
|
|
||||||
|
|
||||||
|
This is a helper library to abstract away I2C, SPI, and 'generic transport' (e.g. UART) transactions and registers
|
||||||
|
|
||||||
|
Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
|
||||||
|
|
||||||
|
MIT license, all text above must be included in any redistribution
|
||||||
1
libraries/Adafruit_BusIO/component.mk
Normal file
1
libraries/Adafruit_BusIO/component.mk
Normal file
@@ -0,0 +1 @@
|
|||||||
|
COMPONENT_ADD_INCLUDEDIRS = .
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
Advanced example of using bstracted transport for reading and writing
|
||||||
|
register data from a UART-based device such as a TMC2209
|
||||||
|
|
||||||
|
Written with help by Claude!
|
||||||
|
https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c (at this time
|
||||||
|
chats are not shareable :(
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Adafruit_BusIO_Register.h"
|
||||||
|
#include "Adafruit_GenericDevice.h"
|
||||||
|
|
||||||
|
// Debugging macros
|
||||||
|
#define DEBUG_SERIAL Serial
|
||||||
|
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
#define DEBUG_PRINT(x) DEBUG_SERIAL.print(x)
|
||||||
|
#define DEBUG_PRINTLN(x) DEBUG_SERIAL.println(x)
|
||||||
|
#define DEBUG_PRINT_HEX(x) \
|
||||||
|
do { \
|
||||||
|
if (x < 0x10) \
|
||||||
|
DEBUG_SERIAL.print('0'); \
|
||||||
|
DEBUG_SERIAL.print(x, HEX); \
|
||||||
|
DEBUG_SERIAL.print(' '); \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define DEBUG_PRINT(x)
|
||||||
|
#define DEBUG_PRINTLN(x)
|
||||||
|
#define DEBUG_PRINT_HEX(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TMC2209_IOIN 0x06
|
||||||
|
|
||||||
|
class TMC2209_UART {
|
||||||
|
private:
|
||||||
|
Stream *_uart_stream;
|
||||||
|
uint8_t _addr;
|
||||||
|
|
||||||
|
static bool uart_read(void *thiz, uint8_t *buffer, size_t len) {
|
||||||
|
TMC2209_UART *dev = (TMC2209_UART *)thiz;
|
||||||
|
uint16_t timeout = 100;
|
||||||
|
while (dev->_uart_stream->available() < len && timeout--) {
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
if (timeout == 0) {
|
||||||
|
DEBUG_PRINTLN("Read timeout!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_PRINT("Reading: ");
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
buffer[i] = dev->_uart_stream->read();
|
||||||
|
DEBUG_PRINT_HEX(buffer[i]);
|
||||||
|
}
|
||||||
|
DEBUG_PRINTLN("");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool uart_write(void *thiz, const uint8_t *buffer, size_t len) {
|
||||||
|
TMC2209_UART *dev = (TMC2209_UART *)thiz;
|
||||||
|
DEBUG_PRINT("Writing: ");
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
DEBUG_PRINT_HEX(buffer[i]);
|
||||||
|
}
|
||||||
|
DEBUG_PRINTLN("");
|
||||||
|
|
||||||
|
dev->_uart_stream->write(buffer, len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool uart_readreg(void *thiz, uint8_t *addr_buf, uint8_t addrsiz,
|
||||||
|
uint8_t *data, uint16_t datalen) {
|
||||||
|
TMC2209_UART *dev = (TMC2209_UART *)thiz;
|
||||||
|
while (dev->_uart_stream->available())
|
||||||
|
dev->_uart_stream->read();
|
||||||
|
|
||||||
|
uint8_t packet[4] = {0x05, uint8_t(dev->_addr << 1), addr_buf[0], 0x00};
|
||||||
|
|
||||||
|
packet[3] = calcCRC(packet, 3);
|
||||||
|
if (!uart_write(thiz, packet, 4))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Read back echo
|
||||||
|
uint8_t echo[4];
|
||||||
|
if (!uart_read(thiz, echo, 4))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Verify echo
|
||||||
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
|
if (echo[i] != packet[i]) {
|
||||||
|
DEBUG_PRINTLN("Echo mismatch");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t response[8]; // sync + 0xFF + reg + 4 data bytes + CRC
|
||||||
|
if (!uart_read(thiz, response, 8))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Verify response
|
||||||
|
if (response[0] != 0x05) {
|
||||||
|
DEBUG_PRINTLN("Invalid sync byte");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response[1] != 0xFF) {
|
||||||
|
DEBUG_PRINTLN("Invalid reply address");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response[2] != addr_buf[0]) {
|
||||||
|
DEBUG_PRINTLN("Register mismatch");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t crc = calcCRC(response, 7);
|
||||||
|
if (crc != response[7]) {
|
||||||
|
DEBUG_PRINTLN("CRC mismatch");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(data, &response[3], 4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool uart_writereg(void *thiz, uint8_t *addr_buf, uint8_t addrsiz,
|
||||||
|
const uint8_t *data, uint16_t datalen) {
|
||||||
|
TMC2209_UART *dev = (TMC2209_UART *)thiz;
|
||||||
|
while (dev->_uart_stream->available())
|
||||||
|
dev->_uart_stream->read();
|
||||||
|
|
||||||
|
uint8_t packet[8] = {0x05,
|
||||||
|
uint8_t(dev->_addr << 1),
|
||||||
|
uint8_t(addr_buf[0] | 0x80),
|
||||||
|
data[0],
|
||||||
|
data[1],
|
||||||
|
data[2],
|
||||||
|
data[3],
|
||||||
|
0x00};
|
||||||
|
|
||||||
|
packet[7] = calcCRC(packet, 7);
|
||||||
|
if (!uart_write(thiz, packet, 8))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint8_t echo[8];
|
||||||
|
if (!uart_read(thiz, echo, 8))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
|
if (echo[i] != packet[i]) {
|
||||||
|
DEBUG_PRINTLN("Write echo mismatch");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t calcCRC(uint8_t *data, uint8_t length) {
|
||||||
|
uint8_t crc = 0;
|
||||||
|
for (uint8_t i = 0; i < length; i++) {
|
||||||
|
uint8_t currentByte = data[i];
|
||||||
|
for (uint8_t j = 0; j < 8; j++) {
|
||||||
|
if ((crc >> 7) ^ (currentByte & 0x01)) {
|
||||||
|
crc = (crc << 1) ^ 0x07;
|
||||||
|
} else {
|
||||||
|
crc = crc << 1;
|
||||||
|
}
|
||||||
|
currentByte = currentByte >> 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
TMC2209_UART(Stream *serial, uint8_t addr)
|
||||||
|
: _uart_stream(serial), _addr(addr) {}
|
||||||
|
|
||||||
|
Adafruit_GenericDevice *createDevice() {
|
||||||
|
return new Adafruit_GenericDevice(this, uart_read, uart_write, uart_readreg,
|
||||||
|
uart_writereg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial)
|
||||||
|
;
|
||||||
|
delay(100);
|
||||||
|
Serial.println("TMC2209 Generic Device register read/write test!");
|
||||||
|
|
||||||
|
Serial1.begin(115200);
|
||||||
|
|
||||||
|
TMC2209_UART uart(&Serial1, 0);
|
||||||
|
Adafruit_GenericDevice *device = uart.createDevice();
|
||||||
|
device->begin();
|
||||||
|
|
||||||
|
// Create register object for IOIN
|
||||||
|
Adafruit_BusIO_Register ioin_reg(device,
|
||||||
|
TMC2209_IOIN, // device and register address
|
||||||
|
4, // width = 4 bytes
|
||||||
|
MSBFIRST, // byte order
|
||||||
|
1); // address width = 1 byte
|
||||||
|
Serial.print("IOIN = 0x");
|
||||||
|
Serial.println(ioin_reg.read(), HEX);
|
||||||
|
|
||||||
|
// Create RegisterBits for VERSION field (bits 31:24)
|
||||||
|
Adafruit_BusIO_RegisterBits version_bits(
|
||||||
|
&ioin_reg, 8, 24); // 8 bits wide, starting at bit 24
|
||||||
|
|
||||||
|
Serial.println("Reading VERSION...");
|
||||||
|
uint8_t version = version_bits.read();
|
||||||
|
|
||||||
|
Serial.print("VERSION = 0x");
|
||||||
|
Serial.println(version, HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() { delay(1000); }
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
Abstracted transport for reading and writing data from a UART-based
|
||||||
|
device such as a TMC2209
|
||||||
|
|
||||||
|
Written with help by Claude!
|
||||||
|
https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c (at this time
|
||||||
|
chats are not shareable :(
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Adafruit_GenericDevice.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic UART device class that demonstrates using GenericDevice with a Stream
|
||||||
|
* interface. This example shows how to wrap a Stream (like HardwareSerial or
|
||||||
|
* SoftwareSerial) with read/write callbacks that can be used by BusIO's
|
||||||
|
* register functions.
|
||||||
|
*/
|
||||||
|
class UARTDevice {
|
||||||
|
public:
|
||||||
|
UARTDevice(Stream *serial) : _serial(serial) {}
|
||||||
|
|
||||||
|
// Static callback for writing data to UART
|
||||||
|
// Called by GenericDevice when data needs to be sent
|
||||||
|
static bool uart_write(void *thiz, const uint8_t *buffer, size_t len) {
|
||||||
|
UARTDevice *dev = (UARTDevice *)thiz;
|
||||||
|
dev->_serial->write(buffer, len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static callback for reading data from UART
|
||||||
|
// Includes timeout and will return false if not enough data available
|
||||||
|
static bool uart_read(void *thiz, uint8_t *buffer, size_t len) {
|
||||||
|
UARTDevice *dev = (UARTDevice *)thiz;
|
||||||
|
uint16_t timeout = 100;
|
||||||
|
while (dev->_serial->available() < len && timeout--) {
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
if (timeout == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
buffer[i] = dev->_serial->read();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a GenericDevice instance using our callbacks
|
||||||
|
Adafruit_GenericDevice *createDevice() {
|
||||||
|
return new Adafruit_GenericDevice(this, uart_read, uart_write);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Stream *_serial; // Underlying Stream instance (HardwareSerial, etc)
|
||||||
|
};
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial)
|
||||||
|
;
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
Serial.println("Generic Device test!");
|
||||||
|
|
||||||
|
// Initialize UART for device communication
|
||||||
|
Serial1.begin(115200);
|
||||||
|
|
||||||
|
// Create UART wrapper and BusIO device
|
||||||
|
UARTDevice uart(&Serial1);
|
||||||
|
Adafruit_GenericDevice *device = uart.createDevice();
|
||||||
|
device->begin();
|
||||||
|
|
||||||
|
// Test write/read cycle
|
||||||
|
uint8_t write_buf[4] = {0x5, 0x0, 0x0, 0x48};
|
||||||
|
uint8_t read_buf[8];
|
||||||
|
|
||||||
|
Serial.println("Writing data...");
|
||||||
|
if (!device->write(write_buf, 4)) {
|
||||||
|
Serial.println("Write failed!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("Reading response...");
|
||||||
|
if (!device->read(read_buf, 8)) {
|
||||||
|
Serial.println("Read failed!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print response bytes
|
||||||
|
Serial.print("Got response: ");
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
Serial.print("0x");
|
||||||
|
Serial.print(read_buf[i], HEX);
|
||||||
|
Serial.print(" ");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() { delay(1000); }
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#include <Adafruit_I2CDevice.h>
|
||||||
|
|
||||||
|
Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(0x10);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) {
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("I2C address detection test");
|
||||||
|
|
||||||
|
if (!i2c_dev.begin()) {
|
||||||
|
Serial.print("Did not find device at 0x");
|
||||||
|
Serial.println(i2c_dev.address(), HEX);
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
Serial.print("Device found on address 0x");
|
||||||
|
Serial.println(i2c_dev.address(), HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#include <Adafruit_I2CDevice.h>
|
||||||
|
|
||||||
|
#define I2C_ADDRESS 0x60
|
||||||
|
Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) {
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("I2C device read and write test");
|
||||||
|
|
||||||
|
if (!i2c_dev.begin()) {
|
||||||
|
Serial.print("Did not find device at 0x");
|
||||||
|
Serial.println(i2c_dev.address(), HEX);
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
Serial.print("Device found on address 0x");
|
||||||
|
Serial.println(i2c_dev.address(), HEX);
|
||||||
|
|
||||||
|
uint8_t buffer[32];
|
||||||
|
// Try to read 32 bytes
|
||||||
|
i2c_dev.read(buffer, 32);
|
||||||
|
Serial.print("Read: ");
|
||||||
|
for (uint8_t i = 0; i < 32; i++) {
|
||||||
|
Serial.print("0x");
|
||||||
|
Serial.print(buffer[i], HEX);
|
||||||
|
Serial.print(", ");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
// read a register by writing first, then reading
|
||||||
|
buffer[0] = 0x0C; // we'll reuse the same buffer
|
||||||
|
i2c_dev.write_then_read(buffer, 1, buffer, 2, false);
|
||||||
|
Serial.print("Write then Read: ");
|
||||||
|
for (uint8_t i = 0; i < 2; i++) {
|
||||||
|
Serial.print("0x");
|
||||||
|
Serial.print(buffer[i], HEX);
|
||||||
|
Serial.print(", ");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#include <Adafruit_BusIO_Register.h>
|
||||||
|
#include <Adafruit_I2CDevice.h>
|
||||||
|
|
||||||
|
#define I2C_ADDRESS 0x60
|
||||||
|
Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) {
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("I2C device register test");
|
||||||
|
|
||||||
|
if (!i2c_dev.begin()) {
|
||||||
|
Serial.print("Did not find device at 0x");
|
||||||
|
Serial.println(i2c_dev.address(), HEX);
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
Serial.print("Device found on address 0x");
|
||||||
|
Serial.println(i2c_dev.address(), HEX);
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register id_reg =
|
||||||
|
Adafruit_BusIO_Register(&i2c_dev, 0x0C, 2, LSBFIRST);
|
||||||
|
uint16_t id;
|
||||||
|
id_reg.read(&id);
|
||||||
|
Serial.print("ID register = 0x");
|
||||||
|
Serial.println(id, HEX);
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register thresh_reg =
|
||||||
|
Adafruit_BusIO_Register(&i2c_dev, 0x01, 2, LSBFIRST);
|
||||||
|
uint16_t thresh;
|
||||||
|
thresh_reg.read(&thresh);
|
||||||
|
Serial.print("Initial threshold register = 0x");
|
||||||
|
Serial.println(thresh, HEX);
|
||||||
|
|
||||||
|
thresh_reg.write(~thresh);
|
||||||
|
|
||||||
|
Serial.print("Post threshold register = 0x");
|
||||||
|
Serial.println(thresh_reg.read(), HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#include <Adafruit_BusIO_Register.h>
|
||||||
|
|
||||||
|
// Define which interface to use by setting the unused interface to NULL!
|
||||||
|
|
||||||
|
#define SPIDEVICE_CS 10
|
||||||
|
Adafruit_SPIDevice *spi_dev = NULL; // new Adafruit_SPIDevice(SPIDEVICE_CS);
|
||||||
|
|
||||||
|
#define I2C_ADDRESS 0x5D
|
||||||
|
Adafruit_I2CDevice *i2c_dev = new Adafruit_I2CDevice(I2C_ADDRESS);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) {
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("I2C or SPI device register test");
|
||||||
|
|
||||||
|
if (spi_dev && !spi_dev->begin()) {
|
||||||
|
Serial.println("Could not initialize SPI device");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i2c_dev) {
|
||||||
|
if (i2c_dev->begin()) {
|
||||||
|
Serial.print("Device found on I2C address 0x");
|
||||||
|
Serial.println(i2c_dev->address(), HEX);
|
||||||
|
} else {
|
||||||
|
Serial.print("Did not find I2C device at 0x");
|
||||||
|
Serial.println(i2c_dev->address(), HEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register id_reg =
|
||||||
|
Adafruit_BusIO_Register(i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, 0x0F);
|
||||||
|
uint8_t id = 0;
|
||||||
|
id_reg.read(&id);
|
||||||
|
Serial.print("ID register = 0x");
|
||||||
|
Serial.println(id, HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#include <Adafruit_SPIDevice.h>
|
||||||
|
|
||||||
|
#define SPIDEVICE_CS 10
|
||||||
|
Adafruit_SPIDevice spi_dev =
|
||||||
|
Adafruit_SPIDevice(SPIDEVICE_CS, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1);
|
||||||
|
// Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 13, 12, 11,
|
||||||
|
// 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) {
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("SPI device mode test");
|
||||||
|
|
||||||
|
if (!spi_dev.begin()) {
|
||||||
|
Serial.println("Could not initialize SPI device");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
Serial.println("\n\nTransfer test");
|
||||||
|
for (uint16_t x = 0; x <= 0xFF; x++) {
|
||||||
|
uint8_t i = x;
|
||||||
|
Serial.print("0x");
|
||||||
|
Serial.print(i, HEX);
|
||||||
|
spi_dev.read(&i, 1, i);
|
||||||
|
Serial.print("/");
|
||||||
|
Serial.print(i, HEX);
|
||||||
|
Serial.print(", ");
|
||||||
|
delay(25);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#include <Adafruit_SPIDevice.h>
|
||||||
|
|
||||||
|
#define SPIDEVICE_CS 10
|
||||||
|
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) {
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("SPI device read and write test");
|
||||||
|
|
||||||
|
if (!spi_dev.begin()) {
|
||||||
|
Serial.println("Could not initialize SPI device");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t buffer[32];
|
||||||
|
|
||||||
|
// Try to read 32 bytes
|
||||||
|
spi_dev.read(buffer, 32);
|
||||||
|
Serial.print("Read: ");
|
||||||
|
for (uint8_t i = 0; i < 32; i++) {
|
||||||
|
Serial.print("0x");
|
||||||
|
Serial.print(buffer[i], HEX);
|
||||||
|
Serial.print(", ");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
// read a register by writing first, then reading
|
||||||
|
buffer[0] = 0x8F; // we'll reuse the same buffer
|
||||||
|
spi_dev.write_then_read(buffer, 1, buffer, 2, false);
|
||||||
|
Serial.print("Write then Read: ");
|
||||||
|
for (uint8_t i = 0; i < 2; i++) {
|
||||||
|
Serial.print("0x");
|
||||||
|
Serial.print(buffer[i], HEX);
|
||||||
|
Serial.print(", ");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {}
|
||||||
@@ -0,0 +1,268 @@
|
|||||||
|
/***************************************************
|
||||||
|
|
||||||
|
This is an example for how to use Adafruit_BusIO_RegisterBits from
|
||||||
|
Adafruit_BusIO library.
|
||||||
|
|
||||||
|
Designed specifically to work with the Adafruit RTD Sensor
|
||||||
|
----> https://www.adafruit.com/products/3328
|
||||||
|
uisng a MAX31865 RTD-to-Digital Converter
|
||||||
|
----> https://datasheets.maximintegrated.com/en/ds/MAX31865.pdf
|
||||||
|
|
||||||
|
This sensor uses SPI to communicate, 4 pins are required to
|
||||||
|
interface.
|
||||||
|
A fifth pin helps to detect when a new conversion is ready.
|
||||||
|
|
||||||
|
Adafruit invests time and resources providing this open source code,
|
||||||
|
please support Adafruit and open-source hardware by purchasing
|
||||||
|
products from Adafruit!
|
||||||
|
|
||||||
|
Example written (2020/3) by Andreas Hardtung/AnHard.
|
||||||
|
BSD license, all text above must be included in any redistribution
|
||||||
|
****************************************************/
|
||||||
|
|
||||||
|
#include <Adafruit_BusIO_Register.h>
|
||||||
|
#include <Adafruit_SPIDevice.h>
|
||||||
|
|
||||||
|
#define MAX31865_SPI_SPEED (5000000)
|
||||||
|
#define MAX31865_SPI_BITORDER (SPI_BITORDER_MSBFIRST)
|
||||||
|
#define MAX31865_SPI_MODE (SPI_MODE1)
|
||||||
|
|
||||||
|
#define MAX31865_SPI_CS (10)
|
||||||
|
#define MAX31865_READY_PIN (2)
|
||||||
|
|
||||||
|
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(
|
||||||
|
MAX31865_SPI_CS, MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER,
|
||||||
|
MAX31865_SPI_MODE, &SPI); // Hardware SPI
|
||||||
|
// Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( MAX31865_SPI_CS, 13, 12, 11,
|
||||||
|
// MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, MAX31865_SPI_MODE); // Software
|
||||||
|
// SPI
|
||||||
|
|
||||||
|
// MAX31865 chip related
|
||||||
|
// *********************************************************************************************
|
||||||
|
Adafruit_BusIO_Register config_reg =
|
||||||
|
Adafruit_BusIO_Register(&spi_dev, 0x00, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST);
|
||||||
|
Adafruit_BusIO_RegisterBits bias_bit =
|
||||||
|
Adafruit_BusIO_RegisterBits(&config_reg, 1, 7);
|
||||||
|
Adafruit_BusIO_RegisterBits auto_bit =
|
||||||
|
Adafruit_BusIO_RegisterBits(&config_reg, 1, 6);
|
||||||
|
Adafruit_BusIO_RegisterBits oneS_bit =
|
||||||
|
Adafruit_BusIO_RegisterBits(&config_reg, 1, 5);
|
||||||
|
Adafruit_BusIO_RegisterBits wire_bit =
|
||||||
|
Adafruit_BusIO_RegisterBits(&config_reg, 1, 4);
|
||||||
|
Adafruit_BusIO_RegisterBits faultT_bits =
|
||||||
|
Adafruit_BusIO_RegisterBits(&config_reg, 2, 2);
|
||||||
|
Adafruit_BusIO_RegisterBits faultR_bit =
|
||||||
|
Adafruit_BusIO_RegisterBits(&config_reg, 1, 1);
|
||||||
|
Adafruit_BusIO_RegisterBits fi50hz_bit =
|
||||||
|
Adafruit_BusIO_RegisterBits(&config_reg, 1, 0);
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register rRatio_reg =
|
||||||
|
Adafruit_BusIO_Register(&spi_dev, 0x01, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
|
||||||
|
Adafruit_BusIO_RegisterBits rRatio_bits =
|
||||||
|
Adafruit_BusIO_RegisterBits(&rRatio_reg, 15, 1);
|
||||||
|
Adafruit_BusIO_RegisterBits fault_bit =
|
||||||
|
Adafruit_BusIO_RegisterBits(&rRatio_reg, 1, 0);
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register maxRratio_reg =
|
||||||
|
Adafruit_BusIO_Register(&spi_dev, 0x03, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
|
||||||
|
Adafruit_BusIO_RegisterBits maxRratio_bits =
|
||||||
|
Adafruit_BusIO_RegisterBits(&maxRratio_reg, 15, 1);
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register minRratio_reg =
|
||||||
|
Adafruit_BusIO_Register(&spi_dev, 0x05, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
|
||||||
|
Adafruit_BusIO_RegisterBits minRratio_bits =
|
||||||
|
Adafruit_BusIO_RegisterBits(&minRratio_reg, 15, 1);
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register fault_reg =
|
||||||
|
Adafruit_BusIO_Register(&spi_dev, 0x07, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST);
|
||||||
|
Adafruit_BusIO_RegisterBits range_high_fault_bit =
|
||||||
|
Adafruit_BusIO_RegisterBits(&fault_reg, 1, 7);
|
||||||
|
Adafruit_BusIO_RegisterBits range_low_fault_bit =
|
||||||
|
Adafruit_BusIO_RegisterBits(&fault_reg, 1, 6);
|
||||||
|
Adafruit_BusIO_RegisterBits refin_high_fault_bit =
|
||||||
|
Adafruit_BusIO_RegisterBits(&fault_reg, 1, 5);
|
||||||
|
Adafruit_BusIO_RegisterBits refin_low_fault_bit =
|
||||||
|
Adafruit_BusIO_RegisterBits(&fault_reg, 1, 4);
|
||||||
|
Adafruit_BusIO_RegisterBits rtdin_low_fault_bit =
|
||||||
|
Adafruit_BusIO_RegisterBits(&fault_reg, 1, 3);
|
||||||
|
Adafruit_BusIO_RegisterBits voltage_fault_bit =
|
||||||
|
Adafruit_BusIO_RegisterBits(&fault_reg, 1, 2);
|
||||||
|
|
||||||
|
// Print the details of the configuration register.
|
||||||
|
void printConfig(void) {
|
||||||
|
Serial.print("BIAS: ");
|
||||||
|
if (bias_bit.read())
|
||||||
|
Serial.print("ON");
|
||||||
|
else
|
||||||
|
Serial.print("OFF");
|
||||||
|
Serial.print(", AUTO: ");
|
||||||
|
if (auto_bit.read())
|
||||||
|
Serial.print("ON");
|
||||||
|
else
|
||||||
|
Serial.print("OFF");
|
||||||
|
Serial.print(", ONES: ");
|
||||||
|
if (oneS_bit.read())
|
||||||
|
Serial.print("ON");
|
||||||
|
else
|
||||||
|
Serial.print("OFF");
|
||||||
|
Serial.print(", WIRE: ");
|
||||||
|
if (wire_bit.read())
|
||||||
|
Serial.print("3");
|
||||||
|
else
|
||||||
|
Serial.print("2/4");
|
||||||
|
Serial.print(", FAULTCLEAR: ");
|
||||||
|
if (faultR_bit.read())
|
||||||
|
Serial.print("ON");
|
||||||
|
else
|
||||||
|
Serial.print("OFF");
|
||||||
|
Serial.print(", ");
|
||||||
|
if (fi50hz_bit.read())
|
||||||
|
Serial.print("50HZ");
|
||||||
|
else
|
||||||
|
Serial.print("60HZ");
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check and print faults. Then clear them.
|
||||||
|
void checkFaults(void) {
|
||||||
|
if (fault_bit.read()) {
|
||||||
|
Serial.print("MAX: ");
|
||||||
|
Serial.println(maxRratio_bits.read());
|
||||||
|
Serial.print("VAL: ");
|
||||||
|
Serial.println(rRatio_bits.read());
|
||||||
|
Serial.print("MIN: ");
|
||||||
|
Serial.println(minRratio_bits.read());
|
||||||
|
|
||||||
|
if (range_high_fault_bit.read())
|
||||||
|
Serial.println("Range high fault");
|
||||||
|
if (range_low_fault_bit.read())
|
||||||
|
Serial.println("Range low fault");
|
||||||
|
if (refin_high_fault_bit.read())
|
||||||
|
Serial.println("REFIN high fault");
|
||||||
|
if (refin_low_fault_bit.read())
|
||||||
|
Serial.println("REFIN low fault");
|
||||||
|
if (rtdin_low_fault_bit.read())
|
||||||
|
Serial.println("RTDIN low fault");
|
||||||
|
if (voltage_fault_bit.read())
|
||||||
|
Serial.println("Voltage fault");
|
||||||
|
|
||||||
|
faultR_bit.write(1); // clear fault
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
#if (MAX31865_1_READY_PIN != -1)
|
||||||
|
pinMode(MAX31865_READY_PIN, INPUT_PULLUP);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (!Serial) {
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("SPI Adafruit_BusIO_RegisterBits test on MAX31865");
|
||||||
|
|
||||||
|
if (!spi_dev.begin()) {
|
||||||
|
Serial.println("Could not initialize SPI device");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up for automode 50Hz. We don't care about selfheating. We want the
|
||||||
|
// highest possible sampling rate.
|
||||||
|
auto_bit.write(0); // Don't switch filtermode while auto_mode is on.
|
||||||
|
fi50hz_bit.write(1); // Set filter to 50Hz mode.
|
||||||
|
faultR_bit.write(1); // Clear faults.
|
||||||
|
bias_bit.write(1); // In automode we want to have the bias current always on.
|
||||||
|
delay(5); // Wait until bias current settles down.
|
||||||
|
// 10.5 time constants of the input RC network is required.
|
||||||
|
// 10ms worst case for 10kω reference resistor and a 0.1µF capacitor
|
||||||
|
// across the RTD inputs. Adafruit Module has 0.1µF and only
|
||||||
|
// 430/4300ω So here 0.43/4.3ms
|
||||||
|
auto_bit.write(
|
||||||
|
1); // Now we can set automode. Automatically starting first conversion.
|
||||||
|
|
||||||
|
// Test the READY_PIN
|
||||||
|
#if (defined(MAX31865_READY_PIN) && (MAX31865_READY_PIN != -1))
|
||||||
|
int i = 0;
|
||||||
|
while (digitalRead(MAX31865_READY_PIN) && i++ <= 100) {
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
if (i >= 100) {
|
||||||
|
Serial.print("ERROR: Max31865 Pin detection does not work. PIN:");
|
||||||
|
Serial.println(MAX31865_READY_PIN);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
delay(100);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set ratio range.
|
||||||
|
// Setting the temperatures would need some more calculation - not related to
|
||||||
|
// Adafruit_BusIO_RegisterBits.
|
||||||
|
uint16_t ratio = rRatio_bits.read();
|
||||||
|
maxRratio_bits.write((ratio < 0x8fffu - 1000u) ? ratio + 1000u : 0x8fffu);
|
||||||
|
minRratio_bits.write((ratio > 1000u) ? ratio - 1000u : 0u);
|
||||||
|
|
||||||
|
printConfig();
|
||||||
|
checkFaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
#if (defined(MAX31865_READY_PIN) && (MAX31865_1_READY_PIN != -1))
|
||||||
|
// Is conversion ready?
|
||||||
|
if (!digitalRead(MAX31865_READY_PIN))
|
||||||
|
#else
|
||||||
|
// Warant conversion is ready.
|
||||||
|
delay(21); // 21ms for 50Hz-mode. 19ms in 60Hz-mode.
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// Read ratio, calculate temperature, scale, filter and print.
|
||||||
|
Serial.println(rRatio2C(rRatio_bits.read()) * 100.0f,
|
||||||
|
0); // Temperature scaled by 100
|
||||||
|
// Check, print, clear faults.
|
||||||
|
checkFaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do something else.
|
||||||
|
// delay(15000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Module/Sensor related. Here Adafruit PT100 module with a 2_Wire PT100 Class C
|
||||||
|
// *****************************
|
||||||
|
float rRatio2C(uint16_t ratio) {
|
||||||
|
// A simple linear conversion.
|
||||||
|
const float R0 = 100.0f;
|
||||||
|
const float Rref = 430.0f;
|
||||||
|
const float alphaPT = 0.003850f;
|
||||||
|
const float ADCmax = (1u << 15) - 1.0f;
|
||||||
|
const float rscale = Rref / ADCmax;
|
||||||
|
// Measured temperature in boiling water 101.08°C with factor a = 1 and b = 0.
|
||||||
|
// Rref and MAX at about 22±2°C. Measured temperature in ice/water bath 0.76°C
|
||||||
|
// with factor a = 1 and b = 0. Rref and MAX at about 22±2°C.
|
||||||
|
// const float a = 1.0f / (alphaPT * R0);
|
||||||
|
const float a = (100.0f / 101.08f) / (alphaPT * R0);
|
||||||
|
// const float b = 0.0f; // 101.08
|
||||||
|
const float b = -0.76f; // 100.32 > 101.08
|
||||||
|
|
||||||
|
return filterRing(((ratio * rscale) - R0) * a + b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// General purpose
|
||||||
|
// *********************************************************************************************
|
||||||
|
#define RINGLENGTH 250
|
||||||
|
float filterRing(float newVal) {
|
||||||
|
static float ring[RINGLENGTH] = {0.0};
|
||||||
|
static uint8_t ringIndex = 0;
|
||||||
|
static bool ringFull = false;
|
||||||
|
|
||||||
|
if (ringIndex == RINGLENGTH) {
|
||||||
|
ringFull = true;
|
||||||
|
ringIndex = 0;
|
||||||
|
}
|
||||||
|
ring[ringIndex] = newVal;
|
||||||
|
uint8_t loopEnd = (ringFull) ? RINGLENGTH : ringIndex + 1;
|
||||||
|
float ringSum = 0.0f;
|
||||||
|
for (uint8_t i = 0; i < loopEnd; i++)
|
||||||
|
ringSum += ring[i];
|
||||||
|
ringIndex++;
|
||||||
|
return ringSum / loopEnd;
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#include <Adafruit_BusIO_Register.h>
|
||||||
|
#include <Adafruit_SPIDevice.h>
|
||||||
|
|
||||||
|
#define SPIDEVICE_CS 10
|
||||||
|
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
while (!Serial) {
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println("SPI device register test");
|
||||||
|
|
||||||
|
if (!spi_dev.begin()) {
|
||||||
|
Serial.println("Could not initialize SPI device");
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register id_reg =
|
||||||
|
Adafruit_BusIO_Register(&spi_dev, 0x0F, ADDRBIT8_HIGH_TOREAD);
|
||||||
|
uint8_t id = 0;
|
||||||
|
id_reg.read(&id);
|
||||||
|
Serial.print("ID register = 0x");
|
||||||
|
Serial.println(id, HEX);
|
||||||
|
|
||||||
|
Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(
|
||||||
|
&spi_dev, 0x0C, ADDRBIT8_HIGH_TOREAD, 2, LSBFIRST);
|
||||||
|
uint16_t thresh = 0;
|
||||||
|
thresh_reg.read(&thresh);
|
||||||
|
Serial.print("Initial threshold register = 0x");
|
||||||
|
Serial.println(thresh, HEX);
|
||||||
|
|
||||||
|
thresh_reg.write(~thresh);
|
||||||
|
|
||||||
|
Serial.print("Post threshold register = 0x");
|
||||||
|
Serial.println(thresh_reg.read(), HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {}
|
||||||
9
libraries/Adafruit_BusIO/library.properties
Normal file
9
libraries/Adafruit_BusIO/library.properties
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
name=Adafruit BusIO
|
||||||
|
version=1.17.0
|
||||||
|
author=Adafruit
|
||||||
|
maintainer=Adafruit <info@adafruit.com>
|
||||||
|
sentence=This is a library for abstracting away UART, I2C and SPI interfacing
|
||||||
|
paragraph=This is a library for abstracting away UART, I2C and SPI interfacing
|
||||||
|
category=Signal Input/Output
|
||||||
|
url=https://github.com/adafruit/Adafruit_BusIO
|
||||||
|
architectures=*
|
||||||
@@ -151,7 +151,7 @@ typedef struct {
|
|||||||
float tvoc; /**< Total Volatile Organic Compounds, in ppb */
|
float tvoc; /**< Total Volatile Organic Compounds, in ppb */
|
||||||
float voc_index; /**< VOC (Volatile Organic Compound) index where 100 is
|
float voc_index; /**< VOC (Volatile Organic Compound) index where 100 is
|
||||||
normal (unitless) */
|
normal (unitless) */
|
||||||
float nox_index; /**< NOx (Nitrogen Oxides) index where 100 is normal
|
float nox_index; /**< NOx (Nitrogen Oxides) index where 1 is normal
|
||||||
(unitless) */
|
(unitless) */
|
||||||
float CO2; /**< Measured CO2 in parts per million (ppm) */
|
float CO2; /**< Measured CO2 in parts per million (ppm) */
|
||||||
float eCO2; /**< equivalent/estimated CO2 in parts per million (ppm
|
float eCO2; /**< equivalent/estimated CO2 in parts per million (ppm
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name=Adafruit Unified Sensor
|
name=Adafruit Unified Sensor
|
||||||
version=1.1.14
|
version=1.1.15
|
||||||
author=Adafruit <info@adafruit.com>
|
author=Adafruit <info@adafruit.com>
|
||||||
maintainer=Adafruit <info@adafruit.com>
|
maintainer=Adafruit <info@adafruit.com>
|
||||||
sentence=Required for all Adafruit Unified Sensor based libraries.
|
sentence=Required for all Adafruit Unified Sensor based libraries.
|
||||||
|
|||||||
@@ -227,7 +227,7 @@
|
|||||||
//#define TFT_RST 33 // Reset pin (could connect to Arduino RESET pin)
|
//#define TFT_RST 33 // Reset pin (could connect to Arduino RESET pin)
|
||||||
//#define TFT_BL 22 // LED back-light
|
//#define TFT_BL 22 // LED back-light
|
||||||
|
|
||||||
#define TOUCH_CS 21 // Chip select pin (T_CS) of touch screen
|
#define TOUCH_CS 4 // Chip select pin (T_CS) of touch screen
|
||||||
|
|
||||||
//#define TFT_WR 22 // Write strobe for modified Raspberry Pi TFT only
|
//#define TFT_WR 22 // Write strobe for modified Raspberry Pi TFT only
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
SET(SOURCES ui_Screen1.c
|
SET(SOURCES ui_Screen1.c
|
||||||
ui_Screen2.c
|
|
||||||
ui_Screen3.c
|
ui_Screen3.c
|
||||||
ui_Screen4.c
|
ui_Screen4.c
|
||||||
ui_Screen5.c
|
ui_Screen5.c
|
||||||
ui_Screen6.c
|
ui_Screen6.c
|
||||||
|
ui_Screen7.c
|
||||||
|
ui_Screen2.c
|
||||||
ui.c
|
ui.c
|
||||||
ui_comp_hook.c
|
ui_comp_hook.c
|
||||||
ui_helpers.c
|
ui_helpers.c
|
||||||
@@ -13,8 +14,8 @@ SET(SOURCES ui_Screen1.c
|
|||||||
ui_img_light_png.c
|
ui_img_light_png.c
|
||||||
ui_img_fan_png.c
|
ui_img_fan_png.c
|
||||||
ui_img_settings_png.c
|
ui_img_settings_png.c
|
||||||
ui_img_up_png.c
|
|
||||||
ui_img_down_png.c
|
ui_img_down_png.c
|
||||||
|
ui_img_up_png.c
|
||||||
ui_img_home_png.c
|
ui_img_home_png.c
|
||||||
ui_img_wifi_png.c
|
ui_img_wifi_png.c
|
||||||
ui_temporary_image.c)
|
ui_temporary_image.c)
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
ui_Screen1.c
|
ui_Screen1.c
|
||||||
ui_Screen2.c
|
|
||||||
ui_Screen3.c
|
ui_Screen3.c
|
||||||
ui_Screen4.c
|
ui_Screen4.c
|
||||||
ui_Screen5.c
|
ui_Screen5.c
|
||||||
ui_Screen6.c
|
ui_Screen6.c
|
||||||
|
ui_Screen7.c
|
||||||
|
ui_Screen2.c
|
||||||
ui.c
|
ui.c
|
||||||
ui_comp_hook.c
|
ui_comp_hook.c
|
||||||
ui_helpers.c
|
ui_helpers.c
|
||||||
@@ -13,8 +14,8 @@ ui_img_florist_png.c
|
|||||||
ui_img_light_png.c
|
ui_img_light_png.c
|
||||||
ui_img_fan_png.c
|
ui_img_fan_png.c
|
||||||
ui_img_settings_png.c
|
ui_img_settings_png.c
|
||||||
ui_img_up_png.c
|
|
||||||
ui_img_down_png.c
|
ui_img_down_png.c
|
||||||
|
ui_img_up_png.c
|
||||||
ui_img_home_png.c
|
ui_img_home_png.c
|
||||||
ui_img_wifi_png.c
|
ui_img_wifi_png.c
|
||||||
ui_temporary_image.c
|
ui_temporary_image.c
|
||||||
|
|||||||
@@ -29,26 +29,6 @@ lv_obj_t * ui_settings;
|
|||||||
lv_obj_t * ui_growmode;
|
lv_obj_t * ui_growmode;
|
||||||
|
|
||||||
|
|
||||||
// SCREEN: ui_Screen2
|
|
||||||
void ui_Screen2_screen_init(void);
|
|
||||||
lv_obj_t * ui_Screen2;
|
|
||||||
lv_obj_t * ui_Image3;
|
|
||||||
lv_obj_t * ui_Image4;
|
|
||||||
void ui_event_Label1(lv_event_t * e);
|
|
||||||
lv_obj_t * ui_Label1;
|
|
||||||
lv_obj_t * ui_Label2;
|
|
||||||
lv_obj_t * ui_light2statuslbl;
|
|
||||||
lv_obj_t * ui_light1statuslbl;
|
|
||||||
lv_obj_t * ui_light1switch;
|
|
||||||
lv_obj_t * ui_light2switch;
|
|
||||||
lv_obj_t * ui_light2percent;
|
|
||||||
lv_obj_t * ui_light1percent;
|
|
||||||
lv_obj_t * ui_light1up;
|
|
||||||
lv_obj_t * ui_light1down;
|
|
||||||
lv_obj_t * ui_light2up;
|
|
||||||
lv_obj_t * ui_light2down;
|
|
||||||
|
|
||||||
|
|
||||||
// SCREEN: ui_Screen3
|
// SCREEN: ui_Screen3
|
||||||
void ui_Screen3_screen_init(void);
|
void ui_Screen3_screen_init(void);
|
||||||
lv_obj_t * ui_Screen3;
|
lv_obj_t * ui_Screen3;
|
||||||
@@ -63,7 +43,6 @@ lv_obj_t * ui_Image6;
|
|||||||
void ui_event_btnfanhome(lv_event_t * e);
|
void ui_event_btnfanhome(lv_event_t * e);
|
||||||
lv_obj_t * ui_btnfanhome;
|
lv_obj_t * ui_btnfanhome;
|
||||||
lv_obj_t * ui_switchfanstatus;
|
lv_obj_t * ui_switchfanstatus;
|
||||||
lv_obj_t * ui_lblfanstatus;
|
|
||||||
|
|
||||||
|
|
||||||
// SCREEN: ui_Screen4
|
// SCREEN: ui_Screen4
|
||||||
@@ -109,6 +88,42 @@ lv_obj_t * ui_savemode;
|
|||||||
lv_obj_t * ui_lblsavemode;
|
lv_obj_t * ui_lblsavemode;
|
||||||
void ui_event_homebtngrow(lv_event_t * e);
|
void ui_event_homebtngrow(lv_event_t * e);
|
||||||
lv_obj_t * ui_homebtngrow;
|
lv_obj_t * ui_homebtngrow;
|
||||||
|
lv_obj_t * ui_led1check;
|
||||||
|
lv_obj_t * ui_led3check;
|
||||||
|
lv_obj_t * ui_led2check;
|
||||||
|
|
||||||
|
|
||||||
|
// SCREEN: ui_Screen7
|
||||||
|
void ui_Screen7_screen_init(void);
|
||||||
|
lv_obj_t * ui_Screen7;
|
||||||
|
lv_obj_t * ui_Label10;
|
||||||
|
lv_obj_t * ui_light3switch;
|
||||||
|
lv_obj_t * ui_light2switch;
|
||||||
|
lv_obj_t * ui_light1switch;
|
||||||
|
lv_obj_t * ui_light3percent;
|
||||||
|
lv_obj_t * ui_Label9;
|
||||||
|
lv_obj_t * ui_Label12;
|
||||||
|
lv_obj_t * ui_led3;
|
||||||
|
lv_obj_t * ui_led1;
|
||||||
|
lv_obj_t * ui_led2;
|
||||||
|
lv_obj_t * ui_light1percent;
|
||||||
|
lv_obj_t * ui_light2percent;
|
||||||
|
lv_obj_t * ui_lightup;
|
||||||
|
lv_obj_t * ui_lightdown;
|
||||||
|
void ui_event_ledhome(lv_event_t * e);
|
||||||
|
lv_obj_t * ui_ledhome;
|
||||||
|
|
||||||
|
|
||||||
|
// SCREEN: ui_Screen2
|
||||||
|
void ui_Screen2_screen_init(void);
|
||||||
|
lv_obj_t * ui_Screen2;
|
||||||
|
lv_obj_t * ui_sunsimspin;
|
||||||
|
lv_obj_t * ui_lblsunsim;
|
||||||
|
lv_obj_t * ui_endtime;
|
||||||
|
lv_obj_t * ui_starttime;
|
||||||
|
lv_obj_t * ui_clock;
|
||||||
|
void ui_event_simhome(lv_event_t * e);
|
||||||
|
lv_obj_t * ui_simhome;
|
||||||
lv_obj_t * ui____initial_actions0;
|
lv_obj_t * ui____initial_actions0;
|
||||||
|
|
||||||
///////////////////// TEST LVGL SETTINGS ////////////////////
|
///////////////////// TEST LVGL SETTINGS ////////////////////
|
||||||
@@ -124,7 +139,7 @@ void ui_event_btnlight(lv_event_t * e)
|
|||||||
lv_event_code_t event_code = lv_event_get_code(e);
|
lv_event_code_t event_code = lv_event_get_code(e);
|
||||||
lv_obj_t * target = lv_event_get_target(e);
|
lv_obj_t * target = lv_event_get_target(e);
|
||||||
if(event_code == LV_EVENT_CLICKED) {
|
if(event_code == LV_EVENT_CLICKED) {
|
||||||
_ui_screen_change(&ui_Screen2, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, &ui_Screen2_screen_init);
|
_ui_screen_change(&ui_Screen7, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, &ui_Screen7_screen_init);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ui_event_btnfan(lv_event_t * e)
|
void ui_event_btnfan(lv_event_t * e)
|
||||||
@@ -143,14 +158,6 @@ void ui_event_settings(lv_event_t * e)
|
|||||||
_ui_screen_change(&ui_Screen4, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, &ui_Screen4_screen_init);
|
_ui_screen_change(&ui_Screen4, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, &ui_Screen4_screen_init);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ui_event_Label1(lv_event_t * e)
|
|
||||||
{
|
|
||||||
lv_event_code_t event_code = lv_event_get_code(e);
|
|
||||||
lv_obj_t * target = lv_event_get_target(e);
|
|
||||||
if(event_code == LV_EVENT_CLICKED) {
|
|
||||||
_ui_screen_change(&ui_Screen1, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, &ui_Screen1_screen_init);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void ui_event_btnfanhome(lv_event_t * e)
|
void ui_event_btnfanhome(lv_event_t * e)
|
||||||
{
|
{
|
||||||
lv_event_code_t event_code = lv_event_get_code(e);
|
lv_event_code_t event_code = lv_event_get_code(e);
|
||||||
@@ -210,6 +217,23 @@ void ui_event_homebtngrow(lv_event_t * e)
|
|||||||
_ui_screen_change(&ui_Screen1, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, &ui_Screen1_screen_init);
|
_ui_screen_change(&ui_Screen1, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, &ui_Screen1_screen_init);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void ui_event_ledhome(lv_event_t * e)
|
||||||
|
{
|
||||||
|
lv_event_code_t event_code = lv_event_get_code(e);
|
||||||
|
lv_obj_t * target = lv_event_get_target(e);
|
||||||
|
if(event_code == LV_EVENT_CLICKED) {
|
||||||
|
_ui_screen_change(&ui_Screen1, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, &ui_Screen1_screen_init);
|
||||||
|
_ui_state_modify(ui_led1check, LV_STATE_CHECKED, _UI_MODIFY_STATE_REMOVE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ui_event_simhome(lv_event_t * e)
|
||||||
|
{
|
||||||
|
lv_event_code_t event_code = lv_event_get_code(e);
|
||||||
|
lv_obj_t * target = lv_event_get_target(e);
|
||||||
|
if(event_code == LV_EVENT_CLICKED) {
|
||||||
|
_ui_screen_change(&ui_Screen1, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, &ui_Screen1_screen_init);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////// SCREENS ////////////////////
|
///////////////////// SCREENS ////////////////////
|
||||||
|
|
||||||
@@ -220,11 +244,12 @@ void ui_init(void)
|
|||||||
false, LV_FONT_DEFAULT);
|
false, LV_FONT_DEFAULT);
|
||||||
lv_disp_set_theme(dispp, theme);
|
lv_disp_set_theme(dispp, theme);
|
||||||
ui_Screen1_screen_init();
|
ui_Screen1_screen_init();
|
||||||
ui_Screen2_screen_init();
|
|
||||||
ui_Screen3_screen_init();
|
ui_Screen3_screen_init();
|
||||||
ui_Screen4_screen_init();
|
ui_Screen4_screen_init();
|
||||||
ui_Screen5_screen_init();
|
ui_Screen5_screen_init();
|
||||||
ui_Screen6_screen_init();
|
ui_Screen6_screen_init();
|
||||||
|
ui_Screen7_screen_init();
|
||||||
|
ui_Screen2_screen_init();
|
||||||
ui____initial_actions0 = lv_obj_create(NULL);
|
ui____initial_actions0 = lv_obj_create(NULL);
|
||||||
lv_disp_load_scr(ui_Screen1);
|
lv_disp_load_scr(ui_Screen1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,24 +43,6 @@ extern lv_obj_t * ui_lblfanspeed;
|
|||||||
void ui_event_settings(lv_event_t * e);
|
void ui_event_settings(lv_event_t * e);
|
||||||
extern lv_obj_t * ui_settings;
|
extern lv_obj_t * ui_settings;
|
||||||
extern lv_obj_t * ui_growmode;
|
extern lv_obj_t * ui_growmode;
|
||||||
// SCREEN: ui_Screen2
|
|
||||||
void ui_Screen2_screen_init(void);
|
|
||||||
extern lv_obj_t * ui_Screen2;
|
|
||||||
extern lv_obj_t * ui_Image3;
|
|
||||||
extern lv_obj_t * ui_Image4;
|
|
||||||
void ui_event_Label1(lv_event_t * e);
|
|
||||||
extern lv_obj_t * ui_Label1;
|
|
||||||
extern lv_obj_t * ui_Label2;
|
|
||||||
extern lv_obj_t * ui_light2statuslbl;
|
|
||||||
extern lv_obj_t * ui_light1statuslbl;
|
|
||||||
extern lv_obj_t * ui_light1switch;
|
|
||||||
extern lv_obj_t * ui_light2switch;
|
|
||||||
extern lv_obj_t * ui_light2percent;
|
|
||||||
extern lv_obj_t * ui_light1percent;
|
|
||||||
extern lv_obj_t * ui_light1up;
|
|
||||||
extern lv_obj_t * ui_light1down;
|
|
||||||
extern lv_obj_t * ui_light2up;
|
|
||||||
extern lv_obj_t * ui_light2down;
|
|
||||||
// SCREEN: ui_Screen3
|
// SCREEN: ui_Screen3
|
||||||
void ui_Screen3_screen_init(void);
|
void ui_Screen3_screen_init(void);
|
||||||
extern lv_obj_t * ui_Screen3;
|
extern lv_obj_t * ui_Screen3;
|
||||||
@@ -75,7 +57,6 @@ extern lv_obj_t * ui_Image6;
|
|||||||
void ui_event_btnfanhome(lv_event_t * e);
|
void ui_event_btnfanhome(lv_event_t * e);
|
||||||
extern lv_obj_t * ui_btnfanhome;
|
extern lv_obj_t * ui_btnfanhome;
|
||||||
extern lv_obj_t * ui_switchfanstatus;
|
extern lv_obj_t * ui_switchfanstatus;
|
||||||
extern lv_obj_t * ui_lblfanstatus;
|
|
||||||
// SCREEN: ui_Screen4
|
// SCREEN: ui_Screen4
|
||||||
void ui_Screen4_screen_init(void);
|
void ui_Screen4_screen_init(void);
|
||||||
extern lv_obj_t * ui_Screen4;
|
extern lv_obj_t * ui_Screen4;
|
||||||
@@ -115,6 +96,38 @@ extern lv_obj_t * ui_savemode;
|
|||||||
extern lv_obj_t * ui_lblsavemode;
|
extern lv_obj_t * ui_lblsavemode;
|
||||||
void ui_event_homebtngrow(lv_event_t * e);
|
void ui_event_homebtngrow(lv_event_t * e);
|
||||||
extern lv_obj_t * ui_homebtngrow;
|
extern lv_obj_t * ui_homebtngrow;
|
||||||
|
extern lv_obj_t * ui_led1check;
|
||||||
|
extern lv_obj_t * ui_led3check;
|
||||||
|
extern lv_obj_t * ui_led2check;
|
||||||
|
// SCREEN: ui_Screen7
|
||||||
|
void ui_Screen7_screen_init(void);
|
||||||
|
extern lv_obj_t * ui_Screen7;
|
||||||
|
extern lv_obj_t * ui_Label10;
|
||||||
|
extern lv_obj_t * ui_light3switch;
|
||||||
|
extern lv_obj_t * ui_light2switch;
|
||||||
|
extern lv_obj_t * ui_light1switch;
|
||||||
|
extern lv_obj_t * ui_light3percent;
|
||||||
|
extern lv_obj_t * ui_Label9;
|
||||||
|
extern lv_obj_t * ui_Label12;
|
||||||
|
extern lv_obj_t * ui_led3;
|
||||||
|
extern lv_obj_t * ui_led1;
|
||||||
|
extern lv_obj_t * ui_led2;
|
||||||
|
extern lv_obj_t * ui_light1percent;
|
||||||
|
extern lv_obj_t * ui_light2percent;
|
||||||
|
extern lv_obj_t * ui_lightup;
|
||||||
|
extern lv_obj_t * ui_lightdown;
|
||||||
|
void ui_event_ledhome(lv_event_t * e);
|
||||||
|
extern lv_obj_t * ui_ledhome;
|
||||||
|
// SCREEN: ui_Screen2
|
||||||
|
void ui_Screen2_screen_init(void);
|
||||||
|
extern lv_obj_t * ui_Screen2;
|
||||||
|
extern lv_obj_t * ui_sunsimspin;
|
||||||
|
extern lv_obj_t * ui_lblsunsim;
|
||||||
|
extern lv_obj_t * ui_endtime;
|
||||||
|
extern lv_obj_t * ui_starttime;
|
||||||
|
extern lv_obj_t * ui_clock;
|
||||||
|
void ui_event_simhome(lv_event_t * e);
|
||||||
|
extern lv_obj_t * ui_simhome;
|
||||||
extern lv_obj_t * ui____initial_actions0;
|
extern lv_obj_t * ui____initial_actions0;
|
||||||
|
|
||||||
LV_IMG_DECLARE(ui__temporary_image);
|
LV_IMG_DECLARE(ui__temporary_image);
|
||||||
@@ -124,8 +137,8 @@ LV_IMG_DECLARE(ui_img_florist_png); // assets/florist.png
|
|||||||
LV_IMG_DECLARE(ui_img_light_png); // assets/light.png
|
LV_IMG_DECLARE(ui_img_light_png); // assets/light.png
|
||||||
LV_IMG_DECLARE(ui_img_fan_png); // assets/fan.png
|
LV_IMG_DECLARE(ui_img_fan_png); // assets/fan.png
|
||||||
LV_IMG_DECLARE(ui_img_settings_png); // assets/settings.png
|
LV_IMG_DECLARE(ui_img_settings_png); // assets/settings.png
|
||||||
LV_IMG_DECLARE(ui_img_up_png); // assets/up.png
|
|
||||||
LV_IMG_DECLARE(ui_img_down_png); // assets/down.png
|
LV_IMG_DECLARE(ui_img_down_png); // assets/down.png
|
||||||
|
LV_IMG_DECLARE(ui_img_up_png); // assets/up.png
|
||||||
LV_IMG_DECLARE(ui_img_home_png); // assets/home.png
|
LV_IMG_DECLARE(ui_img_home_png); // assets/home.png
|
||||||
LV_IMG_DECLARE(ui_img_wifi_png); // assets/wifi.png
|
LV_IMG_DECLARE(ui_img_wifi_png); // assets/wifi.png
|
||||||
|
|
||||||
|
|||||||
@@ -10,155 +10,58 @@ void ui_Screen2_screen_init(void)
|
|||||||
ui_Screen2 = lv_obj_create(NULL);
|
ui_Screen2 = lv_obj_create(NULL);
|
||||||
lv_obj_remove_flag(ui_Screen2, LV_OBJ_FLAG_SCROLLABLE); /// Flags
|
lv_obj_remove_flag(ui_Screen2, LV_OBJ_FLAG_SCROLLABLE); /// Flags
|
||||||
|
|
||||||
ui_Image3 = lv_image_create(ui_Screen2);
|
ui_sunsimspin = lv_spinner_create(ui_Screen2);
|
||||||
lv_image_set_src(ui_Image3, &ui_img_light_png);
|
//lv_spinner_set_anim_params(ui_sunsimspin, 1000, 90);
|
||||||
lv_obj_set_width(ui_Image3, LV_SIZE_CONTENT); /// 64
|
lv_obj_set_width(ui_sunsimspin, 95);
|
||||||
lv_obj_set_height(ui_Image3, LV_SIZE_CONTENT); /// 64
|
lv_obj_set_height(ui_sunsimspin, 97);
|
||||||
lv_obj_set_x(ui_Image3, 30);
|
lv_obj_set_x(ui_sunsimspin, 0);
|
||||||
lv_obj_set_y(ui_Image3, -40);
|
lv_obj_set_y(ui_sunsimspin, -10);
|
||||||
lv_obj_set_align(ui_Image3, LV_ALIGN_CENTER);
|
lv_obj_set_align(ui_sunsimspin, LV_ALIGN_CENTER);
|
||||||
lv_obj_add_flag(ui_Image3, LV_OBJ_FLAG_CLICKABLE); /// Flags
|
lv_obj_remove_flag(ui_sunsimspin, LV_OBJ_FLAG_CLICKABLE); /// Flags
|
||||||
lv_obj_remove_flag(ui_Image3, LV_OBJ_FLAG_SCROLLABLE); /// Flags
|
|
||||||
|
|
||||||
ui_Image4 = lv_image_create(ui_Screen2);
|
ui_lblsunsim = lv_label_create(ui_Screen2);
|
||||||
lv_image_set_src(ui_Image4, &ui_img_light_png);
|
lv_obj_set_width(ui_lblsunsim, LV_SIZE_CONTENT); /// 1
|
||||||
lv_obj_set_width(ui_Image4, LV_SIZE_CONTENT); /// 64
|
lv_obj_set_height(ui_lblsunsim, LV_SIZE_CONTENT); /// 1
|
||||||
lv_obj_set_height(ui_Image4, LV_SIZE_CONTENT); /// 64
|
lv_obj_set_x(ui_lblsunsim, 0);
|
||||||
lv_obj_set_x(ui_Image4, -120);
|
lv_obj_set_y(ui_lblsunsim, -90);
|
||||||
lv_obj_set_y(ui_Image4, -40);
|
lv_obj_set_align(ui_lblsunsim, LV_ALIGN_CENTER);
|
||||||
lv_obj_set_align(ui_Image4, LV_ALIGN_CENTER);
|
lv_label_set_text(ui_lblsunsim, "Sonnensimulation");
|
||||||
lv_obj_add_flag(ui_Image4, LV_OBJ_FLAG_CLICKABLE); /// Flags
|
lv_obj_set_style_text_font(ui_lblsunsim, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
lv_obj_remove_flag(ui_Image4, LV_OBJ_FLAG_SCROLLABLE); /// Flags
|
|
||||||
|
|
||||||
ui_Label1 = lv_label_create(ui_Screen2);
|
ui_endtime = lv_label_create(ui_Screen2);
|
||||||
lv_obj_set_width(ui_Label1, LV_SIZE_CONTENT); /// 1
|
lv_obj_set_width(ui_endtime, LV_SIZE_CONTENT); /// 1
|
||||||
lv_obj_set_height(ui_Label1, LV_SIZE_CONTENT); /// 1
|
lv_obj_set_height(ui_endtime, LV_SIZE_CONTENT); /// 1
|
||||||
lv_obj_set_x(ui_Label1, -85);
|
lv_obj_set_x(ui_endtime, 0);
|
||||||
lv_obj_set_y(ui_Label1, -90);
|
lv_obj_set_y(ui_endtime, 80);
|
||||||
lv_obj_set_align(ui_Label1, LV_ALIGN_CENTER);
|
lv_obj_set_align(ui_endtime, LV_ALIGN_CENTER);
|
||||||
lv_label_set_text(ui_Label1, "First");
|
lv_label_set_text(ui_endtime, "Sonnenuntergang: 12:00 Uhr");
|
||||||
lv_obj_add_flag(ui_Label1, LV_OBJ_FLAG_CLICKABLE); /// Flags
|
|
||||||
lv_obj_set_style_text_font(ui_Label1, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
|
||||||
|
|
||||||
ui_Label2 = lv_label_create(ui_Screen2);
|
ui_starttime = lv_label_create(ui_Screen2);
|
||||||
lv_obj_set_width(ui_Label2, LV_SIZE_CONTENT); /// 1
|
lv_obj_set_width(ui_starttime, LV_SIZE_CONTENT); /// 1
|
||||||
lv_obj_set_height(ui_Label2, LV_SIZE_CONTENT); /// 1
|
lv_obj_set_height(ui_starttime, LV_SIZE_CONTENT); /// 1
|
||||||
lv_obj_set_x(ui_Label2, 75);
|
lv_obj_set_x(ui_starttime, 0);
|
||||||
lv_obj_set_y(ui_Label2, -90);
|
lv_obj_set_y(ui_starttime, 60);
|
||||||
lv_obj_set_align(ui_Label2, LV_ALIGN_CENTER);
|
lv_obj_set_align(ui_starttime, LV_ALIGN_CENTER);
|
||||||
lv_label_set_text(ui_Label2, "Second");
|
lv_label_set_text(ui_starttime, "Sonnenaufgang: 18:00 Uhr");
|
||||||
lv_obj_set_style_text_font(ui_Label2, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
|
||||||
|
|
||||||
ui_light2statuslbl = lv_label_create(ui_Screen2);
|
ui_clock = lv_label_create(ui_Screen2);
|
||||||
lv_obj_set_width(ui_light2statuslbl, 60);
|
lv_obj_set_width(ui_clock, LV_SIZE_CONTENT); /// 1
|
||||||
lv_obj_set_height(ui_light2statuslbl, LV_SIZE_CONTENT); /// 1
|
lv_obj_set_height(ui_clock, LV_SIZE_CONTENT); /// 1
|
||||||
lv_obj_set_x(ui_light2statuslbl, 30);
|
lv_obj_set_x(ui_clock, 0);
|
||||||
lv_obj_set_y(ui_light2statuslbl, 15);
|
lv_obj_set_y(ui_clock, 101);
|
||||||
lv_obj_set_align(ui_light2statuslbl, LV_ALIGN_CENTER);
|
lv_obj_set_align(ui_clock, LV_ALIGN_CENTER);
|
||||||
lv_label_set_text(ui_light2statuslbl, "ON");
|
lv_label_set_text(ui_clock, "Uhrzeit: ");
|
||||||
lv_obj_set_style_text_align(ui_light2statuslbl, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT);
|
|
||||||
lv_obj_set_style_text_font(ui_light2statuslbl, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
|
||||||
|
|
||||||
ui_light1statuslbl = lv_label_create(ui_Screen2);
|
ui_simhome = lv_image_create(ui_Screen2);
|
||||||
lv_obj_set_width(ui_light1statuslbl, 60);
|
lv_image_set_src(ui_simhome, &ui_img_home_png);
|
||||||
lv_obj_set_height(ui_light1statuslbl, LV_SIZE_CONTENT); /// 1
|
lv_obj_set_width(ui_simhome, LV_SIZE_CONTENT); /// 64
|
||||||
lv_obj_set_x(ui_light1statuslbl, -120);
|
lv_obj_set_height(ui_simhome, LV_SIZE_CONTENT); /// 64
|
||||||
lv_obj_set_y(ui_light1statuslbl, 15);
|
lv_obj_set_x(ui_simhome, -120);
|
||||||
lv_obj_set_align(ui_light1statuslbl, LV_ALIGN_CENTER);
|
lv_obj_set_y(ui_simhome, -11);
|
||||||
lv_label_set_text(ui_light1statuslbl, "ON");
|
lv_obj_set_align(ui_simhome, LV_ALIGN_CENTER);
|
||||||
lv_obj_set_style_text_align(ui_light1statuslbl, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT);
|
lv_obj_add_flag(ui_simhome, LV_OBJ_FLAG_CLICKABLE); /// Flags
|
||||||
lv_obj_set_style_text_font(ui_light1statuslbl, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
lv_obj_remove_flag(ui_simhome, LV_OBJ_FLAG_SCROLLABLE); /// Flags
|
||||||
|
|
||||||
ui_light1switch = lv_switch_create(ui_Screen2);
|
lv_obj_add_event_cb(ui_simhome, ui_event_simhome, LV_EVENT_ALL, NULL);
|
||||||
lv_obj_set_width(ui_light1switch, 50);
|
|
||||||
lv_obj_set_height(ui_light1switch, 25);
|
|
||||||
lv_obj_set_x(ui_light1switch, -45);
|
|
||||||
lv_obj_set_y(ui_light1switch, 15);
|
|
||||||
lv_obj_set_align(ui_light1switch, LV_ALIGN_CENTER);
|
|
||||||
|
|
||||||
|
|
||||||
ui_light2switch = lv_switch_create(ui_Screen2);
|
|
||||||
lv_obj_set_width(ui_light2switch, 50);
|
|
||||||
lv_obj_set_height(ui_light2switch, 25);
|
|
||||||
lv_obj_set_x(ui_light2switch, 105);
|
|
||||||
lv_obj_set_y(ui_light2switch, 15);
|
|
||||||
lv_obj_set_align(ui_light2switch, LV_ALIGN_CENTER);
|
|
||||||
|
|
||||||
|
|
||||||
ui_light2percent = lv_label_create(ui_Screen2);
|
|
||||||
lv_obj_set_width(ui_light2percent, LV_SIZE_CONTENT); /// 1
|
|
||||||
lv_obj_set_height(ui_light2percent, LV_SIZE_CONTENT); /// 1
|
|
||||||
lv_obj_set_x(ui_light2percent, 105);
|
|
||||||
lv_obj_set_y(ui_light2percent, -40);
|
|
||||||
lv_obj_set_align(ui_light2percent, LV_ALIGN_CENTER);
|
|
||||||
lv_label_set_text(ui_light2percent, "0 %");
|
|
||||||
lv_obj_set_style_text_align(ui_light2percent, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT);
|
|
||||||
lv_obj_set_style_text_font(ui_light2percent, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
|
||||||
|
|
||||||
ui_light1percent = lv_label_create(ui_Screen2);
|
|
||||||
lv_obj_set_width(ui_light1percent, LV_SIZE_CONTENT); /// 1
|
|
||||||
lv_obj_set_height(ui_light1percent, LV_SIZE_CONTENT); /// 1
|
|
||||||
lv_obj_set_x(ui_light1percent, -45);
|
|
||||||
lv_obj_set_y(ui_light1percent, -40);
|
|
||||||
lv_obj_set_align(ui_light1percent, LV_ALIGN_CENTER);
|
|
||||||
lv_label_set_text(ui_light1percent, "0 %");
|
|
||||||
lv_obj_set_style_text_align(ui_light1percent, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT);
|
|
||||||
lv_obj_set_style_text_font(ui_light1percent, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
|
||||||
|
|
||||||
ui_light1up = lv_imagebutton_create(ui_Screen2);
|
|
||||||
lv_imagebutton_set_src(ui_light1up, LV_IMAGEBUTTON_STATE_RELEASED, NULL, &ui_img_up_png, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light1up, LV_IMAGEBUTTON_STATE_PRESSED, NULL, &ui_img_up_png, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light1up, LV_IMAGEBUTTON_STATE_DISABLED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light1up, LV_IMAGEBUTTON_STATE_CHECKED_PRESSED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light1up, LV_IMAGEBUTTON_STATE_CHECKED_RELEASED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light1up, LV_IMAGEBUTTON_STATE_CHECKED_DISABLED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_obj_set_height(ui_light1up, 64);
|
|
||||||
lv_obj_set_width(ui_light1up, LV_SIZE_CONTENT); /// 1
|
|
||||||
lv_obj_set_x(ui_light1up, -120);
|
|
||||||
lv_obj_set_y(ui_light1up, 75);
|
|
||||||
lv_obj_set_align(ui_light1up, LV_ALIGN_CENTER);
|
|
||||||
lv_obj_set_style_bg_color(ui_light1up, lv_color_hex(0x82ADF0), LV_PART_MAIN | LV_STATE_PRESSED);
|
|
||||||
lv_obj_set_style_bg_opa(ui_light1up, 255, LV_PART_MAIN | LV_STATE_PRESSED);
|
|
||||||
|
|
||||||
ui_light1down = lv_imagebutton_create(ui_Screen2);
|
|
||||||
lv_imagebutton_set_src(ui_light1down, LV_IMAGEBUTTON_STATE_RELEASED, NULL, &ui_img_down_png, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light1down, LV_IMAGEBUTTON_STATE_PRESSED, NULL, &ui_img_down_png, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light1down, LV_IMAGEBUTTON_STATE_DISABLED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light1down, LV_IMAGEBUTTON_STATE_CHECKED_PRESSED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light1down, LV_IMAGEBUTTON_STATE_CHECKED_RELEASED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light1down, LV_IMAGEBUTTON_STATE_CHECKED_DISABLED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_obj_set_height(ui_light1down, 64);
|
|
||||||
lv_obj_set_width(ui_light1down, LV_SIZE_CONTENT); /// 1
|
|
||||||
lv_obj_set_x(ui_light1down, -45);
|
|
||||||
lv_obj_set_y(ui_light1down, 75);
|
|
||||||
lv_obj_set_align(ui_light1down, LV_ALIGN_CENTER);
|
|
||||||
|
|
||||||
ui_light2up = lv_imagebutton_create(ui_Screen2);
|
|
||||||
lv_imagebutton_set_src(ui_light2up, LV_IMAGEBUTTON_STATE_RELEASED, NULL, &ui_img_up_png, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light2up, LV_IMAGEBUTTON_STATE_PRESSED, NULL, &ui_img_up_png, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light2up, LV_IMAGEBUTTON_STATE_DISABLED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light2up, LV_IMAGEBUTTON_STATE_CHECKED_PRESSED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light2up, LV_IMAGEBUTTON_STATE_CHECKED_RELEASED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light2up, LV_IMAGEBUTTON_STATE_CHECKED_DISABLED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_obj_set_height(ui_light2up, 64);
|
|
||||||
lv_obj_set_width(ui_light2up, LV_SIZE_CONTENT); /// 1
|
|
||||||
lv_obj_set_x(ui_light2up, 30);
|
|
||||||
lv_obj_set_y(ui_light2up, 75);
|
|
||||||
lv_obj_set_align(ui_light2up, LV_ALIGN_CENTER);
|
|
||||||
|
|
||||||
ui_light2down = lv_imagebutton_create(ui_Screen2);
|
|
||||||
lv_imagebutton_set_src(ui_light2down, LV_IMAGEBUTTON_STATE_RELEASED, NULL, &ui_img_down_png, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light2down, LV_IMAGEBUTTON_STATE_PRESSED, NULL, &ui_img_down_png, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light2down, LV_IMAGEBUTTON_STATE_DISABLED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light2down, LV_IMAGEBUTTON_STATE_CHECKED_PRESSED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light2down, LV_IMAGEBUTTON_STATE_CHECKED_RELEASED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_imagebutton_set_src(ui_light2down, LV_IMAGEBUTTON_STATE_CHECKED_DISABLED, NULL, &ui__temporary_image, NULL);
|
|
||||||
lv_obj_set_height(ui_light2down, 64);
|
|
||||||
lv_obj_set_width(ui_light2down, LV_SIZE_CONTENT); /// 1
|
|
||||||
lv_obj_set_x(ui_light2down, 105);
|
|
||||||
lv_obj_set_y(ui_light2down, 75);
|
|
||||||
lv_obj_set_align(ui_light2down, LV_ALIGN_CENTER);
|
|
||||||
|
|
||||||
lv_obj_add_event_cb(ui_Label1, ui_event_Label1, LV_EVENT_ALL, NULL);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,20 +115,11 @@ void ui_Screen3_screen_init(void)
|
|||||||
ui_switchfanstatus = lv_switch_create(ui_Screen3);
|
ui_switchfanstatus = lv_switch_create(ui_Screen3);
|
||||||
lv_obj_set_width(ui_switchfanstatus, 50);
|
lv_obj_set_width(ui_switchfanstatus, 50);
|
||||||
lv_obj_set_height(ui_switchfanstatus, 25);
|
lv_obj_set_height(ui_switchfanstatus, 25);
|
||||||
lv_obj_set_x(ui_switchfanstatus, 100);
|
lv_obj_set_x(ui_switchfanstatus, 40);
|
||||||
lv_obj_set_y(ui_switchfanstatus, 5);
|
lv_obj_set_y(ui_switchfanstatus, 5);
|
||||||
lv_obj_set_align(ui_switchfanstatus, LV_ALIGN_CENTER);
|
lv_obj_set_align(ui_switchfanstatus, LV_ALIGN_CENTER);
|
||||||
|
|
||||||
|
|
||||||
ui_lblfanstatus = lv_label_create(ui_Screen3);
|
|
||||||
lv_obj_set_width(ui_lblfanstatus, LV_SIZE_CONTENT); /// 1
|
|
||||||
lv_obj_set_height(ui_lblfanstatus, LV_SIZE_CONTENT); /// 1
|
|
||||||
lv_obj_set_x(ui_lblfanstatus, 30);
|
|
||||||
lv_obj_set_y(ui_lblfanstatus, 5);
|
|
||||||
lv_obj_set_align(ui_lblfanstatus, LV_ALIGN_CENTER);
|
|
||||||
lv_label_set_text(ui_lblfanstatus, "ON");
|
|
||||||
lv_obj_set_style_text_font(ui_lblfanstatus, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
|
||||||
|
|
||||||
lv_obj_add_event_cb(ui_btnfanhome, ui_event_btnfanhome, LV_EVENT_ALL, NULL);
|
lv_obj_add_event_cb(ui_btnfanhome, ui_event_btnfanhome, LV_EVENT_ALL, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,14 +100,14 @@ void ui_Screen6_screen_init(void)
|
|||||||
lv_label_set_text(ui_Label8, "Grow Mode");
|
lv_label_set_text(ui_Label8, "Grow Mode");
|
||||||
|
|
||||||
ui_sunsetcheck = lv_checkbox_create(ui_Screen6);
|
ui_sunsetcheck = lv_checkbox_create(ui_Screen6);
|
||||||
lv_checkbox_set_text(ui_sunsetcheck, "Sonne simulieren");
|
lv_checkbox_set_text(ui_sunsetcheck, "SIM");
|
||||||
lv_obj_set_width(ui_sunsetcheck, LV_SIZE_CONTENT); /// 1
|
lv_obj_set_width(ui_sunsetcheck, LV_SIZE_CONTENT); /// 1
|
||||||
lv_obj_set_height(ui_sunsetcheck, LV_SIZE_CONTENT); /// 1
|
lv_obj_set_height(ui_sunsetcheck, LV_SIZE_CONTENT); /// 1
|
||||||
lv_obj_set_x(ui_sunsetcheck, -35);
|
lv_obj_set_x(ui_sunsetcheck, 103);
|
||||||
lv_obj_set_y(ui_sunsetcheck, 40);
|
lv_obj_set_y(ui_sunsetcheck, 50);
|
||||||
lv_obj_set_align(ui_sunsetcheck, LV_ALIGN_CENTER);
|
lv_obj_set_align(ui_sunsetcheck, LV_ALIGN_CENTER);
|
||||||
lv_obj_add_flag(ui_sunsetcheck, LV_OBJ_FLAG_SCROLL_ON_FOCUS); /// Flags
|
lv_obj_add_flag(ui_sunsetcheck, LV_OBJ_FLAG_SCROLL_ON_FOCUS); /// Flags
|
||||||
lv_obj_set_style_text_font(ui_sunsetcheck, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
lv_obj_set_style_text_font(ui_sunsetcheck, &lv_font_montserrat_14, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
|
||||||
ui_setmode = lv_dropdown_create(ui_Screen6);
|
ui_setmode = lv_dropdown_create(ui_Screen6);
|
||||||
lv_dropdown_set_options(ui_setmode, "Veggie\nFlower");
|
lv_dropdown_set_options(ui_setmode, "Veggie\nFlower");
|
||||||
@@ -133,7 +133,7 @@ void ui_Screen6_screen_init(void)
|
|||||||
lv_obj_set_width(ui_lblsavemode, LV_SIZE_CONTENT); /// 1
|
lv_obj_set_width(ui_lblsavemode, LV_SIZE_CONTENT); /// 1
|
||||||
lv_obj_set_height(ui_lblsavemode, LV_SIZE_CONTENT); /// 1
|
lv_obj_set_height(ui_lblsavemode, LV_SIZE_CONTENT); /// 1
|
||||||
lv_obj_set_x(ui_lblsavemode, 61);
|
lv_obj_set_x(ui_lblsavemode, 61);
|
||||||
lv_obj_set_y(ui_lblsavemode, 90);
|
lv_obj_set_y(ui_lblsavemode, 91);
|
||||||
lv_obj_set_align(ui_lblsavemode, LV_ALIGN_CENTER);
|
lv_obj_set_align(ui_lblsavemode, LV_ALIGN_CENTER);
|
||||||
lv_label_set_text(ui_lblsavemode, "Speichern");
|
lv_label_set_text(ui_lblsavemode, "Speichern");
|
||||||
lv_obj_add_flag(ui_lblsavemode, LV_OBJ_FLAG_IGNORE_LAYOUT); /// Flags
|
lv_obj_add_flag(ui_lblsavemode, LV_OBJ_FLAG_IGNORE_LAYOUT); /// Flags
|
||||||
@@ -151,6 +151,35 @@ void ui_Screen6_screen_init(void)
|
|||||||
lv_obj_set_y(ui_homebtngrow, -83);
|
lv_obj_set_y(ui_homebtngrow, -83);
|
||||||
lv_obj_set_align(ui_homebtngrow, LV_ALIGN_CENTER);
|
lv_obj_set_align(ui_homebtngrow, LV_ALIGN_CENTER);
|
||||||
|
|
||||||
|
ui_led1check = lv_checkbox_create(ui_Screen6);
|
||||||
|
lv_checkbox_set_text(ui_led1check, "LED1");
|
||||||
|
lv_obj_set_width(ui_led1check, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_height(ui_led1check, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_x(ui_led1check, -120);
|
||||||
|
lv_obj_set_y(ui_led1check, 50);
|
||||||
|
lv_obj_set_align(ui_led1check, LV_ALIGN_CENTER);
|
||||||
|
lv_obj_add_flag(ui_led1check, LV_OBJ_FLAG_SCROLL_ON_FOCUS); /// Flags
|
||||||
|
lv_obj_set_style_text_font(ui_led1check, &lv_font_montserrat_14, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
|
||||||
|
ui_led3check = lv_checkbox_create(ui_Screen6);
|
||||||
|
lv_checkbox_set_text(ui_led3check, "LED3");
|
||||||
|
lv_obj_set_width(ui_led3check, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_height(ui_led3check, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_x(ui_led3check, 30);
|
||||||
|
lv_obj_set_y(ui_led3check, 50);
|
||||||
|
lv_obj_set_align(ui_led3check, LV_ALIGN_CENTER);
|
||||||
|
lv_obj_add_flag(ui_led3check, LV_OBJ_FLAG_SCROLL_ON_FOCUS); /// Flags
|
||||||
|
|
||||||
|
ui_led2check = lv_checkbox_create(ui_Screen6);
|
||||||
|
lv_checkbox_set_text(ui_led2check, "LED2");
|
||||||
|
lv_obj_set_width(ui_led2check, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_height(ui_led2check, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_x(ui_led2check, -45);
|
||||||
|
lv_obj_set_y(ui_led2check, 50);
|
||||||
|
lv_obj_set_align(ui_led2check, LV_ALIGN_CENTER);
|
||||||
|
lv_obj_add_flag(ui_led2check, LV_OBJ_FLAG_SCROLL_ON_FOCUS); /// Flags
|
||||||
|
lv_obj_set_style_text_font(ui_led2check, &lv_font_montserrat_14, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
|
||||||
lv_obj_add_event_cb(ui_homebtngrow, ui_event_homebtngrow, LV_EVENT_ALL, NULL);
|
lv_obj_add_event_cb(ui_homebtngrow, ui_event_homebtngrow, LV_EVENT_ALL, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
159
libraries/ui/src/ui_Screen7.c
Normal file
159
libraries/ui/src/ui_Screen7.c
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
// This file was generated by SquareLine Studio
|
||||||
|
// SquareLine Studio version: SquareLine Studio 1.4.2
|
||||||
|
// LVGL version: 9.1.0
|
||||||
|
// Project name: SmartGrow
|
||||||
|
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
|
void ui_Screen7_screen_init(void)
|
||||||
|
{
|
||||||
|
ui_Screen7 = lv_obj_create(NULL);
|
||||||
|
lv_obj_remove_flag(ui_Screen7, LV_OBJ_FLAG_SCROLLABLE); /// Flags
|
||||||
|
|
||||||
|
ui_Label10 = lv_label_create(ui_Screen7);
|
||||||
|
lv_obj_set_width(ui_Label10, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_height(ui_Label10, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_x(ui_Label10, -145);
|
||||||
|
lv_obj_set_y(ui_Label10, -80);
|
||||||
|
lv_obj_set_align(ui_Label10, LV_ALIGN_CENTER);
|
||||||
|
lv_label_set_text(ui_Label10, "1");
|
||||||
|
lv_obj_set_style_text_font(ui_Label10, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
|
||||||
|
ui_light3switch = lv_switch_create(ui_Screen7);
|
||||||
|
lv_obj_set_width(ui_light3switch, 50);
|
||||||
|
lv_obj_set_height(ui_light3switch, 25);
|
||||||
|
lv_obj_set_x(ui_light3switch, -50);
|
||||||
|
lv_obj_set_y(ui_light3switch, 60);
|
||||||
|
lv_obj_set_align(ui_light3switch, LV_ALIGN_CENTER);
|
||||||
|
|
||||||
|
|
||||||
|
ui_light2switch = lv_switch_create(ui_Screen7);
|
||||||
|
lv_obj_set_width(ui_light2switch, 50);
|
||||||
|
lv_obj_set_height(ui_light2switch, 25);
|
||||||
|
lv_obj_set_x(ui_light2switch, -50);
|
||||||
|
lv_obj_set_y(ui_light2switch, -10);
|
||||||
|
lv_obj_set_align(ui_light2switch, LV_ALIGN_CENTER);
|
||||||
|
|
||||||
|
|
||||||
|
ui_light1switch = lv_switch_create(ui_Screen7);
|
||||||
|
lv_obj_set_width(ui_light1switch, 50);
|
||||||
|
lv_obj_set_height(ui_light1switch, 25);
|
||||||
|
lv_obj_set_x(ui_light1switch, -50);
|
||||||
|
lv_obj_set_y(ui_light1switch, -80);
|
||||||
|
lv_obj_set_align(ui_light1switch, LV_ALIGN_CENTER);
|
||||||
|
|
||||||
|
|
||||||
|
ui_light3percent = lv_label_create(ui_Screen7);
|
||||||
|
lv_obj_set_width(ui_light3percent, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_height(ui_light3percent, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_x(ui_light3percent, 10);
|
||||||
|
lv_obj_set_y(ui_light3percent, 60);
|
||||||
|
lv_obj_set_align(ui_light3percent, LV_ALIGN_CENTER);
|
||||||
|
lv_label_set_text(ui_light3percent, "0 %");
|
||||||
|
lv_obj_set_style_text_font(ui_light3percent, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
|
||||||
|
ui_Label9 = lv_label_create(ui_Screen7);
|
||||||
|
lv_obj_set_width(ui_Label9, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_height(ui_Label9, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_x(ui_Label9, -145);
|
||||||
|
lv_obj_set_y(ui_Label9, -10);
|
||||||
|
lv_obj_set_align(ui_Label9, LV_ALIGN_CENTER);
|
||||||
|
lv_label_set_text(ui_Label9, "2");
|
||||||
|
lv_obj_set_style_text_font(ui_Label9, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
|
||||||
|
ui_Label12 = lv_label_create(ui_Screen7);
|
||||||
|
lv_obj_set_width(ui_Label12, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_height(ui_Label12, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_x(ui_Label12, -145);
|
||||||
|
lv_obj_set_y(ui_Label12, 60);
|
||||||
|
lv_obj_set_align(ui_Label12, LV_ALIGN_CENTER);
|
||||||
|
lv_label_set_text(ui_Label12, "3");
|
||||||
|
lv_obj_set_style_text_font(ui_Label12, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
|
||||||
|
ui_led3 = lv_image_create(ui_Screen7);
|
||||||
|
lv_image_set_src(ui_led3, &ui_img_light_png);
|
||||||
|
lv_obj_set_width(ui_led3, 56);
|
||||||
|
lv_obj_set_height(ui_led3, 56);
|
||||||
|
lv_obj_set_x(ui_led3, -110);
|
||||||
|
lv_obj_set_y(ui_led3, 60);
|
||||||
|
lv_obj_set_align(ui_led3, LV_ALIGN_CENTER);
|
||||||
|
lv_obj_add_flag(ui_led3, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_CHECKABLE); /// Flags
|
||||||
|
lv_obj_remove_flag(ui_led3, LV_OBJ_FLAG_SCROLLABLE); /// Flags
|
||||||
|
lv_obj_set_style_bg_color(ui_led3, lv_color_hex(0xEFF623), LV_PART_MAIN | LV_STATE_CHECKED);
|
||||||
|
lv_obj_set_style_bg_opa(ui_led3, 255, LV_PART_MAIN | LV_STATE_CHECKED);
|
||||||
|
|
||||||
|
ui_led1 = lv_image_create(ui_Screen7);
|
||||||
|
lv_image_set_src(ui_led1, &ui_img_light_png);
|
||||||
|
lv_obj_set_width(ui_led1, 56);
|
||||||
|
lv_obj_set_height(ui_led1, 56);
|
||||||
|
lv_obj_set_x(ui_led1, -110);
|
||||||
|
lv_obj_set_y(ui_led1, -80);
|
||||||
|
lv_obj_set_align(ui_led1, LV_ALIGN_CENTER);
|
||||||
|
lv_obj_add_flag(ui_led1, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_CHECKABLE); /// Flags
|
||||||
|
lv_obj_remove_flag(ui_led1, LV_OBJ_FLAG_SCROLLABLE); /// Flags
|
||||||
|
lv_obj_set_style_bg_color(ui_led1, lv_color_hex(0xEFF623), LV_PART_MAIN | LV_STATE_CHECKED);
|
||||||
|
lv_obj_set_style_bg_opa(ui_led1, 255, LV_PART_MAIN | LV_STATE_CHECKED);
|
||||||
|
|
||||||
|
ui_led2 = lv_image_create(ui_Screen7);
|
||||||
|
lv_image_set_src(ui_led2, &ui_img_light_png);
|
||||||
|
lv_obj_set_width(ui_led2, 56);
|
||||||
|
lv_obj_set_height(ui_led2, 56);
|
||||||
|
lv_obj_set_x(ui_led2, -110);
|
||||||
|
lv_obj_set_y(ui_led2, -10);
|
||||||
|
lv_obj_set_align(ui_led2, LV_ALIGN_CENTER);
|
||||||
|
lv_obj_add_flag(ui_led2, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_CHECKABLE); /// Flags
|
||||||
|
lv_obj_remove_flag(ui_led2, LV_OBJ_FLAG_SCROLLABLE); /// Flags
|
||||||
|
lv_obj_set_style_bg_color(ui_led2, lv_color_hex(0xEFF623), LV_PART_MAIN | LV_STATE_CHECKED);
|
||||||
|
lv_obj_set_style_bg_opa(ui_led2, 255, LV_PART_MAIN | LV_STATE_CHECKED);
|
||||||
|
|
||||||
|
ui_light1percent = lv_label_create(ui_Screen7);
|
||||||
|
lv_obj_set_width(ui_light1percent, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_height(ui_light1percent, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_x(ui_light1percent, 10);
|
||||||
|
lv_obj_set_y(ui_light1percent, -80);
|
||||||
|
lv_obj_set_align(ui_light1percent, LV_ALIGN_CENTER);
|
||||||
|
lv_label_set_text(ui_light1percent, "0 %");
|
||||||
|
lv_obj_set_style_text_font(ui_light1percent, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
|
||||||
|
ui_light2percent = lv_label_create(ui_Screen7);
|
||||||
|
lv_obj_set_width(ui_light2percent, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_height(ui_light2percent, LV_SIZE_CONTENT); /// 1
|
||||||
|
lv_obj_set_x(ui_light2percent, 10);
|
||||||
|
lv_obj_set_y(ui_light2percent, -10);
|
||||||
|
lv_obj_set_align(ui_light2percent, LV_ALIGN_CENTER);
|
||||||
|
lv_label_set_text(ui_light2percent, "0 %");
|
||||||
|
lv_obj_set_style_text_font(ui_light2percent, &lv_font_montserrat_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
|
||||||
|
ui_lightup = lv_image_create(ui_Screen7);
|
||||||
|
lv_image_set_src(ui_lightup, &ui_img_up_png);
|
||||||
|
lv_obj_set_width(ui_lightup, 56);
|
||||||
|
lv_obj_set_height(ui_lightup, 56);
|
||||||
|
lv_obj_set_x(ui_lightup, 125);
|
||||||
|
lv_obj_set_y(ui_lightup, 75);
|
||||||
|
lv_obj_set_align(ui_lightup, LV_ALIGN_CENTER);
|
||||||
|
lv_obj_add_flag(ui_lightup, LV_OBJ_FLAG_CLICKABLE); /// Flags
|
||||||
|
lv_obj_remove_flag(ui_lightup, LV_OBJ_FLAG_SCROLLABLE); /// Flags
|
||||||
|
|
||||||
|
ui_lightdown = lv_image_create(ui_Screen7);
|
||||||
|
lv_image_set_src(ui_lightdown, &ui_img_down_png);
|
||||||
|
lv_obj_set_width(ui_lightdown, 56);
|
||||||
|
lv_obj_set_height(ui_lightdown, 56);
|
||||||
|
lv_obj_set_x(ui_lightdown, 60);
|
||||||
|
lv_obj_set_y(ui_lightdown, 75);
|
||||||
|
lv_obj_set_align(ui_lightdown, LV_ALIGN_CENTER);
|
||||||
|
lv_obj_add_flag(ui_lightdown, LV_OBJ_FLAG_CLICKABLE); /// Flags
|
||||||
|
lv_obj_remove_flag(ui_lightdown, LV_OBJ_FLAG_SCROLLABLE); /// Flags
|
||||||
|
|
||||||
|
ui_ledhome = lv_image_create(ui_Screen7);
|
||||||
|
lv_image_set_src(ui_ledhome, &ui_img_home_png);
|
||||||
|
lv_obj_set_width(ui_ledhome, LV_SIZE_CONTENT); /// 64
|
||||||
|
lv_obj_set_height(ui_ledhome, LV_SIZE_CONTENT); /// 64
|
||||||
|
lv_obj_set_x(ui_ledhome, 125);
|
||||||
|
lv_obj_set_y(ui_ledhome, -80);
|
||||||
|
lv_obj_set_align(ui_ledhome, LV_ALIGN_CENTER);
|
||||||
|
lv_obj_add_flag(ui_ledhome, LV_OBJ_FLAG_CLICKABLE); /// Flags
|
||||||
|
lv_obj_remove_flag(ui_ledhome, LV_OBJ_FLAG_SCROLLABLE); /// Flags
|
||||||
|
|
||||||
|
lv_obj_add_event_cb(ui_ledhome, ui_event_ledhome, LV_EVENT_ALL, NULL);
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user