Compare commits

...

3 Commits

Author SHA1 Message Date
a54f29e21e Sonnensimulation auf Kern 0 2025-03-13 09:54:30 +01:00
ca8f70a887 LED3 still missing SUNSIM still missing 2025-03-04 15:52:17 +01:00
ae617cade4 save all 2025-02-28 14:30:08 +01:00
46 changed files with 5235 additions and 521 deletions

Binary file not shown.

View 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;
}

View 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

View 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.

View File

@@ -0,0 +1,54 @@
# Adafruit BME280 Library [![Build Status](https://github.com/adafruit/Adafruit_BME280_Library/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_BME280_Library/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](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

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 KiB

View File

@@ -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();
}

View File

@@ -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);
}

View File

@@ -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();
}

View 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

View 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

View 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

View 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);
}

View 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

View 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
}

View 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

View 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

View 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;
}

View 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

View 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)

View 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.

View File

@@ -0,0 +1,8 @@
# Adafruit Bus IO Library [![Build Status](https://github.com/adafruit/Adafruit_BusIO/workflows/Arduino%20Library%20CI/badge.svg)](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

View File

@@ -0,0 +1 @@
COMPONENT_ADD_INCLUDEDIRS = .

View File

@@ -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); }

View File

@@ -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); }

View File

@@ -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() {}

View File

@@ -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() {}

View File

@@ -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() {}

View File

@@ -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() {}

View File

@@ -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);
}
}

View File

@@ -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() {}

View File

@@ -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;
}

View File

@@ -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() {}

View 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=*

View File

@@ -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

View File

@@ -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.

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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);
} }

View File

@@ -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

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View 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);
}

1204
ui/ui.ino

File diff suppressed because it is too large Load Diff