Can I use the SPIFFS on the M5StackCore2, or do I need to install something in advance? I use #include "SPIFFS.h.
Cheers,
Jan
Can I use the SPIFFS on the M5StackCore2, or do I need to install something in advance? I use #include "SPIFFS.h.
Cheers,
Jan
Make an improvement in the main call routine. The return value of getBME280 is a boolean.
now it is possible to check whether a BME280 is connected correctly.
bool getBME280(TwoWire *theWire, double *t, double *p, double *h)
{
_i2c = theWire;
/* check of BME280 is avilable */
uint8_t value = read8(0xD0);
if (value == 0x60) // BME280 detected
{
reset_BME280(); // Reset BME280
write8(BME280_REGISTER_CONTROLHUMID,(uint8_t)0x01); // Select control humidity register
write8(BME280_REGISTER_CONTROL, (uint8_t)0x27); // Select control measurement register
write8(BME280_REGISTER_CONFIG, (uint8_t)0xA0); // Select config register
readCoefficients(); // Read coefficients from BME280
*t = get_Temperature(); // Get temperature
*p = get_Pressure()/100.0; // Get pressure
*h = get_Humidity(); // Get Humidity
return true;
}
else
{
return false; // No BME280 detected
}
}
Cheers,
Jan
Because the BME280 library didn't want to work with the M5Paper Wire1 I2c connection, I changed the routines so that they now work.
The adjustment now works for M5Stack, the M5Paper and for the Core2.
I post the complete code here, because I cannot upload a zip file.
he whole consists of:
1. M5Paper_BME280.uno
/*
* BME280 Sensor (Temperature,Pressure, and Humidity)
* Is working now also for M5Paper, and testest on all M5Stack devices
* Rewritten by J.Kromhout (NL)
* Version 1.0
* Date : 24-02-2021
*
* Todo: Beter input for smapling etc.
* Making the routine universal for BME280 and BMP280
*/
#include <M5EPD.h>
#include <Wire.h>
#include "BME280.h" /* definition file */
double p,t,h; /* pressure,temperature and humidity */
void setup() {
M5.begin();
Wire1.begin(25,32); /* start Wire1 on M5Paper */
getBME280(&Wire1, &t, &p, &h); /* get messurment*/
Serial.println("-------------------------");
Serial.printf("Temperature : %6.1f °C\n", t);
Serial.printf("Barometer : %6.1f hPa\n", p);
Serial.printf("Humidity : %6.1f %%\n", h);
Serial.println("-------------------------");
}
void loop() {
// put your main code here, to run repeatedly:
}
void getBME280(TwoWire *theWire, double *t, double *p, double *h)
{
_i2c = theWire;
/* check of BME280 is avilable */
uint8_t value = read8(0xD0);
if (value == 0x60)
Serial.println("BME280 found");
else
{
Serial.println("No BME280 found! Check your device........");
while(true);
}
reset_BME280(); // Reset BME280
write8(BME280_REGISTER_CONTROLHUMID,(uint8_t)0x01); // Select control humidity register
write8(BME280_REGISTER_CONTROL, (uint8_t)0x27); // Select control measurement register
write8(BME280_REGISTER_CONFIG, (uint8_t)0xA0); // Select config register
readCoefficients(); // Read coefficients from BME280
*t = get_Temperature(); // Get temperature
*p = get_Pressure()/100.0; // Get pressure
*h = get_Humidity(); // Get Humidity
}
2. BME280.h
#define BME280_ADDRESS 0x77 /* Primary I2C Address */
TwoWire *_i2c;
uint8_t _i2caddr = BME280_ADDRESS;
int32_t t_fine; /* tempory variable */
/* calibration data, need for calculation */
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
uint8_t dig_H1;
int16_t dig_H2;
uint8_t dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t dig_H6;
/* Calibrate registers addresses */
#define BME280_REGISTER_DIG_T1 0x88
#define BME280_REGISTER_DIG_T2 0x8A
#define BME280_REGISTER_DIG_T3 0x8C
#define BME280_REGISTER_DIG_P1 0x8E
#define BME280_REGISTER_DIG_P2 0x90
#define BME280_REGISTER_DIG_P3 0x92
#define BME280_REGISTER_DIG_P4 0x94
#define BME280_REGISTER_DIG_P5 0x96
#define BME280_REGISTER_DIG_P6 0x98
#define BME280_REGISTER_DIG_P7 0x9A
#define BME280_REGISTER_DIG_P8 0x9C
#define BME280_REGISTER_DIG_P9 0x9E
#define BME280_REGISTER_DIG_H1 0xA1
#define BME280_REGISTER_DIG_H2 0xE1
#define BME280_REGISTER_DIG_H3 0xE3
#define BME280_REGISTER_DIG_H4 0xE4
#define BME280_REGISTER_DIG_H5 0xE5
#define BME280_REGISTER_DIG_H6 0xE7
/* ontrol registers */
#define BME280_REGISTER_CHIPID 0xD0
#define BME280_REGISTER_VERSION 0xD1
#define BME280_REGISTER_SOFTRESET 0xE0
#define BME280_REGISTER_CAL26 0xE1
#define BME280_REGISTER_CONTROLHUMID 0xF2
#define BME280_REGISTER_STATUS 0xF3
#define BME280_REGISTER_CONTROL 0xF4
#define BME280_REGISTER_CONFIG 0xF5
#define BME280_REGISTER_PRESSUREDATA 0xF7
#define BME280_REGISTER_TEMPDATA 0xFA
#define BME280_REGISTER_HUMIDDATA 0xFD
3. BME280_routines
uint8_t read8(byte reg)
{
uint8_t value;
_i2c->beginTransmission((uint8_t)BME280_ADDRESS);
_i2c->write((uint8_t)reg);
_i2c->endTransmission();
_i2c->requestFrom((uint8_t)BME280_ADDRESS,(uint8_t)1);
value = _i2c->read();
return value;
}
void write8(byte reg , byte value)
{
_i2c->beginTransmission((uint8_t)BME280_ADDRESS);
_i2c->write((uint8_t)reg);
_i2c->write((uint8_t)value);
_i2c->endTransmission();
}
uint16_t read16(byte reg)
{
uint16_t value;
_i2c->beginTransmission((uint8_t) BME280_ADDRESS);
_i2c->write((uint8_t)reg);
_i2c->endTransmission();
_i2c->requestFrom((uint8_t)BME280_ADDRESS,(uint8_t)2);
value = (_i2c->read() << 8) | _i2c->read();
return value;
}
uint32_t read24(byte reg)
{
uint32_t value;
_i2c->beginTransmission((uint8_t)BME280_ADDRESS);
_i2c->write((uint8_t)reg);
_i2c->endTransmission();
_i2c->requestFrom((uint8_t)BME280_ADDRESS,(uint8_t)3);
value = _i2c->read();
value <<= 8;
value |= _i2c->read();
value <<= 8;
value |= _i2c->read();
return value;
}
uint16_t read16_LE(byte reg)
{
uint16_t temp = read16(reg);
return (temp >> 8) | (temp << 8);
}
int16_t readS16(byte reg)
{
return (int16_t) read16(reg);
}
int16_t readS16_LE(byte reg)
{
return (int16_t) read16_LE(reg);
}
void readCoefficients()
{
dig_T1 = read16_LE(BME280_REGISTER_DIG_T1);
dig_T2 = readS16_LE(BME280_REGISTER_DIG_T2);
dig_T3 = readS16_LE(BME280_REGISTER_DIG_T3);
dig_P1 = read16_LE(BME280_REGISTER_DIG_P1);
dig_P2 = readS16_LE(BME280_REGISTER_DIG_P2);
dig_P3 = readS16_LE(BME280_REGISTER_DIG_P3);
dig_P4 = readS16_LE(BME280_REGISTER_DIG_P4);
dig_P5 = readS16_LE(BME280_REGISTER_DIG_P5);
dig_P6 = readS16_LE(BME280_REGISTER_DIG_P6);
dig_P7 = readS16_LE(BME280_REGISTER_DIG_P7);
dig_P8 = readS16_LE(BME280_REGISTER_DIG_P8);
dig_P9 = readS16_LE(BME280_REGISTER_DIG_P9);
dig_H1 = read8(BME280_REGISTER_DIG_H1);
dig_H2 = readS16_LE(BME280_REGISTER_DIG_H2);
dig_H3 = read8(BME280_REGISTER_DIG_H3);
dig_H4 = ((int8_t)read8(BME280_REGISTER_DIG_H4) << 4) | (read8(BME280_REGISTER_DIG_H4 + 1) & 0xF);
dig_H5 = ((int8_t)read8(BME280_REGISTER_DIG_H5 + 1) << 4) | (read8(BME280_REGISTER_DIG_H5) >> 4);
dig_H6 = (int8_t)read8(BME280_REGISTER_DIG_H6);
}
double get_Temperature() {
int32_t var1, var2;
int32_t adc_T = read24(BME280_REGISTER_TEMPDATA);
adc_T >>= 4;
var1 = ((((adc_T >> 3) - ((int32_t)dig_T1 << 1))) *
((int32_t)dig_T2)) >> 11;
var2 = (((((adc_T >> 4) - ((int32_t)dig_T1)) *
((adc_T >> 4) - ((int32_t)dig_T1))) >> 12) *
((int32_t)dig_T3)) >> 14;
t_fine = var1 + var2;
double T = (t_fine * 5 + 128) >> 8;
return T / 100;
}
double get_Pressure() {
int64_t var1, var2, p;
// Must be done first to get the t_fine variable set up
get_Temperature();
int32_t adc_P = read24(BME280_REGISTER_PRESSUREDATA);
adc_P >>= 4;
var1 = ((int64_t)t_fine) - 128000;
var2 = var1 * var1 * (int64_t)dig_P6;
var2 = var2 + ((var1 * (int64_t)dig_P5) << 17);
var2 = var2 + (((int64_t)dig_P4) << 35);
var1 = ((var1 * var1 * (int64_t)dig_P3) >> 8) +
((var1 * (int64_t)dig_P2) << 12);
var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)dig_P1) >> 33;
if (var1 == 0) {
return 0; // avoid exception caused by division by zero
}
p = 1048576 - adc_P;
p = (((p << 31) - var2) * 3125) / var1;
var1 = (((int64_t)dig_P9) * (p >> 13) * (p >> 13)) >> 25;
var2 = (((int64_t)dig_P8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((int64_t)dig_P7) << 4);
return (double)p / 256;
}
double get_Humidity(void) {
get_Temperature(); // 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;
int32_t v_x1_u32r;
v_x1_u32r = (t_fine - ((int32_t)76800));
v_x1_u32r = (((((adc_H << 14) - (((int32_t)dig_H4) << 20) -
(((int32_t)dig_H5) * v_x1_u32r)) +
((int32_t)16384)) >>
15) * (((((((v_x1_u32r * ((int32_t)dig_H6)) >> 10) *
(((v_x1_u32r * ((int32_t)dig_H3)) >> 11) + ((int32_t)32768))) >>
10) + ((int32_t)2097152)) * ((int32_t)dig_H2) + 8192) >> 14));
v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)dig_H1)) >> 4));
v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r;
v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r;
double h = (v_x1_u32r >> 12);
return h / 1024.0;
}
void reset_BME280()
{
write8(BME280_REGISTER_SOFTRESET , (uint8_t)0xB6);
}
Have fun with it. Let us know when there are improvements.
Cheers,
Jan
Thank you for this. I was looking for this!
Cheers,
Jan
Today I rewrote the routines for the BMP280 and BME280 for a single device.
Simple include the source into the main program, and call it.
This is now working as I wont. It takes a afternoon of work!
Now put the finishing touches on the BMP280/BME280.
Would it make sense to post them on the forum when they are ready?
Cheers
Jan
I will stop to interface I2C devices to the M5Paper.
Tried to make a connection with various devices, no positive results so far. It is a pity that they have taken this path. Now a number of devices are no longer usable for me on the M5Paper.
@felmue
Is there a principal difference in the I2C approach between the M5Paper and the CORE2?
Felix, I've tried it and for this device it is working. But when I try it with a BMP280 it is not working. I think it is depending on the header of the program.
I will investigate this further.
Cheers,
Jan
Felix,
Sorry, I made a mistake. The address the scanner sees is 0x58, which is correct. The address of the SGP30 is also 0x58.
Still, the test program will not run!
#include <M5EPD.h>
#include <Wire.h>
#include "Adafruit_SGP30.h"
Adafruit_SGP30 sgp;
void setup() {
M5.begin();
Serial.println("\n\n=====SGP30 test====");
if (! sgp.begin()){
Serial.println("Sensor not found ...........");
while (1);
}
Serial.print("Found SGP30 serial #");
Serial.print(sgp.serialnumber[0], HEX);
Serial.print(sgp.serialnumber[1], HEX);
Serial.println(sgp.serialnumber[2], HEX);
}
void loop()
{
}
This is my message now:
21:20:51.388 ->
21:20:51.388 ->
21:20:51.388 -> =====SGP30 test====
21:20:51.388 -> Sensor not found ...........
Hope you can help me out, because this is for me a general problem.
Wont connect several I2C devices to the M5Paper.
Cheers,
Jan
@felmue Thank you Felix. What strikes me now is that the original I2C address 0x30 has been changed to 0x58. Does this mean that I have to edit the original LIB of Adafruit?
Or is there a trick to keep using the address 0x30?
Cheers
Jan