|
|
View previous topic :: View next topic |
Author |
Message |
pekka1234
Joined: 28 May 2017 Posts: 83
|
BMP280 humidity doesn't work |
Posted: Sun Sep 10, 2023 1:11 am |
|
|
Hey, I have a small problem.
I tried to use CCS BMP280 library with my new BMP280.
It doesn't work anything. I tried to change I2C address to right.
I found from https://simple-circuit.com/ BMP280_lib.c file.
I does work, but then there was not humidity sensor at this time, when it was done.
I try to ask help there, but do not get any answer.
I ask from here to help.
It works from outside http://probyte.fi/Sunday.jpg
But humidity doesn't work.
The device is using RDY-41 2.4GHz radio module. It works well.
I have two I2C pull up resistors to 3.3V 1.7kohms.
The PIC18F2620 works with 3.3 volt.
I have CCS compiler v5.092
Code: |
/*
* sender.c for PIC18F2620 BME280 temperature, humidity and pressure sensor.
* C Code for CCS C compiler.
* Temperature, humidity and pressure values a
* File d:\pic\2023\radio\sender.c
* Pekka Ritamaki, Probyte Oy, Tampere Finland
* Include BMP280 library BMP280_lib.c
* Thus has older BMP280 library, It will work, but not humidity
*/
// define device I2C address: 0xEC or 0xEE (0xEE is library default address)
#define BME280_I2C_ADDRESS 0xEC
#include <18F2620.h>
#DEVICE ADC=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgoming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOMCLR //Master Clear pin not enabled
#FUSES NOWRT
#use delay(internal = 8MHz)
#use rs232(baud=9600, parity=N, UART1, errors, bits=8, BRGH1OK) // RS232 settings
#use I2C(MASTER, I2C1, FAST = 400000)
#define LEDON output_high(PIN_C5); //redLED
#include "BMP280_Lib.c"
signed int32 temperature;// this was BME280 temperature
unsigned int32 pressure, humidity=0;
unsigned int16 temp1 ;
void main()
{
int8 ok,i;
LEDON ;
delay_ms(1000); // wait 1 second
BMP280_Configure(MODE_NORMAL,SAMPLING_X1,
SAMPLING_X1, 1,STANDBY_62_5) ;
BMP280_begin(MODE_NORMAL,
SAMPLING_X1,
SAMPLING_X1,
FILTER_OFF,
STANDBY_0_5);
ok= BMP280_ForcedMeasurement();
printf("\rBME280 sender %s\r", __DATE__ );
while(TRUE)
{
temp1=0;
for( i=0;i<10;i++) {
BMP280_readTemperature(&temperature);
temp1 += temperature;
}
temperature = temp1/10 ;
BMP280_readTemperature(&temperature);
BMP280_readPressure(&pressure);// read pressure
temperature -= 240; // calibrate -2.c
printf("#TT15"); // # starts data string
temperature -= 1.94; // caibrate
if(temperature < 0)
{
temperature = abs(temperature); // abs: absolute value
printf("-%02Lu.%02Lu,", temperature / 100, temperature % 100);
}
else {
printf("+%02Lu.%02Lu,", temperature / 100, temperature % 100);
}
printf("%04Lu.%02Lu,", pressure/100, pressure % 100);
printf("%02Lu.%02Lu$\r", humidity / 1024, ((humidity * 100)/1024) % 100);
delay_ms(10000); // wait 10 seconds
}
}
// end of code.¯
///////////////////////////////////////////////////////////////////////////
//// BMP280_Lib.c ////
//// Driver for CCS C compiler ////
//// Driver for Bosch BMP280 sensor. This sensor can read temperature ////
//// and pressure. ////
//// This driver only supports I2C mode, it doesn't support SPI mode. ////
//// https://simple-circuit.com/ ////
///////////////////////////////////////////////////////////////////////////
#include <stdint.h>
#ifndef BMP280_I2C_ADDRESS
#define BMP280_I2C_ADDRESS 0xEC // was 0xEE
#endif
#define BMP280_CHIP_ID 0x58
#define BMP280_REG_DIG_T1 0x88
#define BMP280_REG_DIG_T2 0x8A
#define BMP280_REG_DIG_T3 0x8C
#define BMP280_REG_DIG_P1 0x8E
#define BMP280_REG_DIG_P2 0x90
#define BMP280_REG_DIG_P3 0x92
#define BMP280_REG_DIG_P4 0x94
#define BMP280_REG_DIG_P5 0x96
#define BMP280_REG_DIG_P6 0x98
#define BMP280_REG_DIG_P7 0x9A
#define BMP280_REG_DIG_P8 0x9C
#define BMP280_REG_DIG_P9 0x9E
#define BMP280_REG_CHIPID 0xD0
#define BMP280_REG_SOFTRESET 0xE0
#define BMP280_REG_STATUS 0xF3
#define BMP280_REG_CONTROL 0xF4
#define BMP280_REG_CONFIG 0xF5
#define BMP280_REG_PRESS_MSB 0xF7
int32_t adc_T, adc_P, t_fine;
// BMP280 sensor modes, register ctrl_meas mode[1:0]
enum BMP280_mode
{
MODE_SLEEP = 0x00, // sleep mode
MODE_FORCED = 0x01, // forced mode
MODE_NORMAL = 0x03 // normal mode
} ;
// oversampling setting. osrs_t[2:0], osrs_p[2:0]
enum BMP280_sampling
{
SAMPLING_SKIPPED = 0x00, //skipped, output set to 0x80000
SAMPLING_X1 = 0x01, // oversampling x1
SAMPLING_X2 = 0x02, // oversampling x2
SAMPLING_X4 = 0x03, // oversampling x4
SAMPLING_X8 = 0x04, // oversampling x8
SAMPLING_X16 = 0x05 // oversampling x16
} ;
// filter setting filter[2:0]
enum BMP280_filter
{
FILTER_OFF = 0x00, // filter off
FILTER_2 = 0x01, // filter coefficient = 2
FILTER_4 = 0x02, // filter coefficient = 4
FILTER_8 = 0x03, // filter coefficient = 8
FILTER_16 = 0x04 // filter coefficient = 16
} ;
// standby (inactive) time in ms (used in normal mode), t_sb[2:0]
enum standby_time
{
STANDBY_0_5 = 0x00, // standby time = 0.5 ms
STANDBY_62_5 = 0x01, // standby time = 62.5 ms
STANDBY_125 = 0x02, // standby time = 125 ms
STANDBY_250 = 0x03, // standby time = 250 ms
STANDBY_500 = 0x04, // standby time = 500 ms
STANDBY_1000 = 0x05, // standby time = 1000 ms
STANDBY_2000 = 0x06, // standby time = 2000 ms
STANDBY_4000 = 0x07 // standby time = 4000 ms
} ;
struct
{
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;
} BMP280_calib;
// writes 1 byte '_data' to register 'reg_addr'
void BMP280_Write(uint8_t reg_addr, uint8_t _data)
{
I2C_Start();
I2C_Write( BMP280_I2C_ADDRESS);
I2C_Write( reg_addr);
I2C_Write( _data);
I2C_Stop();
}
// reads 8 bits from register 'reg_addr'
uint8_t BMP280_Read8(uint8_t reg_addr)
{
uint8_t ret;
I2C_Start();
I2C_Write( BMP280_I2C_ADDRESS);
I2C_Write( reg_addr);
I2C_Start();
I2C_Write( BMP280_I2C_ADDRESS | 1);
ret = I2C_Read( 0);
I2C_Stop();
return ret;
}
// reads 16 bits from register 'reg_addr'
uint16_t BMP280_Read16(uint8_t reg_addr)
{
union
{
uint8_t b[2];
uint16_t w;
} ret;
I2C_Start();
I2C_Write( BMP280_I2C_ADDRESS);
I2C_Write( reg_addr);
I2C_Start();
I2C_Write( BMP280_I2C_ADDRESS | 1);
ret.b[0] = I2C_Read( 1);
ret.b[1] = I2C_Read( 0);
I2C_Stop();
return(ret.w);
}
// BMP280 sensor configuration function
void BMP280_Configure(BMP280_mode mode, BMP280_sampling T_sampling,
BMP280_sampling P_sampling, BMP280_filter filter, standby_time standby)
{
uint8_t _ctrl_meas, _config;
_config = ((standby << 5) | (filter << 2)) & 0xFC;
_ctrl_meas = (T_sampling << 5) | (P_sampling << 2) | mode;
BMP280_Write(BMP280_REG_CONFIG, _config);
BMP280_Write(BMP280_REG_CONTROL, _ctrl_meas);
}
// initializes the BMP280 sensor, returns 1 if OK and 0 if error
int1 BMP280_begin(BMP280_mode mode,
BMP280_sampling T_sampling = SAMPLING_X1,
BMP280_sampling P_sampling = SAMPLING_X1,
BMP280_filter filter = FILTER_OFF,
standby_time standby = STANDBY_0_5)
{
if(BMP280_Read8(BMP280_REG_CHIPID) != BMP280_CHIP_ID)
return 0;
// reset the BMP280 with soft reset
BMP280_Write(BMP280_REG_SOFTRESET, 0xB6);
delay_ms(100);
// if NVM data are being copied to image registers, wait 100 ms
while ( (BMP280_Read8(BMP280_REG_STATUS) & 0x01) == 0x01 )
delay_ms(100);
BMP280_calib.dig_T1 = BMP280_Read16(BMP280_REG_DIG_T1);
BMP280_calib.dig_T2 = BMP280_Read16(BMP280_REG_DIG_T2);
BMP280_calib.dig_T3 = BMP280_Read16(BMP280_REG_DIG_T3);
BMP280_calib.dig_P1 = BMP280_Read16(BMP280_REG_DIG_P1);
BMP280_calib.dig_P2 = BMP280_Read16(BMP280_REG_DIG_P2);
BMP280_calib.dig_P3 = BMP280_Read16(BMP280_REG_DIG_P3);
BMP280_calib.dig_P4 = BMP280_Read16(BMP280_REG_DIG_P4);
BMP280_calib.dig_P5 = BMP280_Read16(BMP280_REG_DIG_P5);
BMP280_calib.dig_P6 = BMP280_Read16(BMP280_REG_DIG_P6);
BMP280_calib.dig_P7 = BMP280_Read16(BMP280_REG_DIG_P7);
BMP280_calib.dig_P8 = BMP280_Read16(BMP280_REG_DIG_P8);
BMP280_calib.dig_P9 = BMP280_Read16(BMP280_REG_DIG_P9);
BMP280_Configure(mode, T_sampling, P_sampling, filter, standby);
return 1;
}
// Takes a new measurement, for forced mode only!
// Returns 1 if ok and 0 if error (sensor is not in sleep mode)
int1 BMP280_ForcedMeasurement()
{
uint8_t ctrl_meas_reg = BMP280_Read8(BMP280_REG_CONTROL);
if ( (ctrl_meas_reg & 0x03) != 0x00 )
return 0; // sensor is not in sleep mode
// set sensor to forced mode
BMP280_Write(BMP280_REG_CONTROL, ctrl_meas_reg | 1);
// wait for conversion complete
while (BMP280_Read8(BMP280_REG_STATUS) & 0x08)
delay_ms(1);
return 1;
}
// read (updates) adc_P, adc_T and adc_H from BMP280 sensor
void BMP280_Update()
{
union
{
uint8_t b[4];
uint32_t dw;
} ret;
ret.b[3] = 0x00;
I2C_Start();
I2C_Write( BMP280_I2C_ADDRESS);
I2C_Write( BMP280_REG_PRESS_MSB);
I2C_Start();
I2C_Write( BMP280_I2C_ADDRESS | 1);
ret.b[2] = I2C_Read( 1);
ret.b[1] = I2C_Read( 1);
ret.b[0] = I2C_Read( 1);
adc_P = (ret.dw >> 4) & 0xFFFFF;
ret.b[2] = I2C_Read( 1);
ret.b[1] = I2C_Read( 1);
ret.b[0] = I2C_Read( 0);
I2C_Stop();
adc_T = (ret.dw >> 4) & 0xFFFFF;
}
// Reads temperature from BMP280 sensor.
// Temperature is stored in hundredths C (output value of "5123" equals 51.23 DegC).
// Temperature value is saved to *temp, returns 1 if OK and 0 if error.
int1 BMP280_readTemperature(int32_t *temp)
{
int32_t var1, var2;
BMP280_Update();
// calculate temperature
var1 = ((((adc_T / 8) - ((int32_t)BMP280_calib.dig_T1 * 2))) *
((int32_t)BMP280_calib.dig_T2)) / 2048;
var2 = (((((adc_T / 16) - ((int32_t)BMP280_calib.dig_T1)) *
((adc_T / 16) - ((int32_t)BMP280_calib.dig_T1))) / 4096) *
((int32_t)BMP280_calib.dig_T3)) / 16384;
t_fine = var1 + var2;
*temp = (t_fine * 5 + 128) / 256;
return 1;
}
// Reads pressure from BMP280 sensor.
// Pressure is stored in Pa (output value of "96386" equals 96386 Pa = 963.86 hPa).
// Pressure value is saved to *pres, returns 1 if OK and 0 if error.
int1 BMP280_readPressure(uint32_t *pres)
{
int32_t var1, var2;
uint32_t p;
// calculate pressure
var1 = (((int32_t)t_fine) / 2) - (int32_t)64000;
var2 = (((var1/4) * (var1/4)) / 2048 ) * ((int32_t)BMP280_calib.dig_P6);
var2 = var2 + ((var1 * ((int32_t)BMP280_calib.dig_P5)) * 2);
var2 = (var2/4) + (((int32_t)BMP280_calib.dig_P4) * 65536);
var1 = ((((int32_t)BMP280_calib.dig_P3 * (((var1/4) * (var1/4)) / 8192 )) / 8) +
((((int32_t)BMP280_calib.dig_P2) * var1)/2)) / 262144;
var1 =((((32768 + var1)) * ((int32_t)BMP280_calib.dig_P1)) / 32768);
if (var1 == 0)
return 0; // avoid exception caused by division by zero
p = (((uint32_t)(((int32_t)1048576) - adc_P) - (var2 / 4096))) * 3125;
if (p < 0x80000000)
p = (p * 2) / ((uint32_t)var1);
else
p = (p / (uint32_t)var1) * 2;
var1 = (((int32_t)BMP280_calib.dig_P9) * ((int32_t)(((p/8) * (p/8)) / 8192))) / 4096;
var2 = (((int32_t)(p/4)) * ((int32_t)BMP280_calib.dig_P8)) / 8192;
p = (uint32_t)((int32_t)p + ((var1 + var2 + (int32_t)BMP280_calib.dig_P7) / 16));
*pres = p;
return 1;
}
// tästä alkaa humidity
/*
typedef union
{
struct
{
unsigned int mode:2;
unsigned int osrs_p:3;
unsigned int osrs_t:3;
};
unsigned int8 val;
} _bme280_ctrl_meas_t;
struct
{
unsigned int8 isInit;
_bme280_ctrl_meas_t ctrlMeas;
struct
{
unsigned int16 dig_T1; //0x88,0x89
signed int16 dig_T2; //0x8a,0x8b
signed int16 dig_T3; //0x8c,0x8d
unsigned int16 dig_P1; //0x8e,0x8f
signed int16 dig_P2; //0x90,0x91
signed int16 dig_P3; //0x92,0x93
signed int16 dig_P4; //0x94,0x95
signed int16 dig_P5; //0x96,0x97
signed int16 dig_P6; //0x98,0x99
signed int16 dig_P7; //0x9a,0x9b
signed int16 dig_P8; //0x9c,0x9d
signed int16 dig_P9; //0x9e,0x9f
unsigned int8 dig_H1; //0xa1
signed int16 dig_H2; //0xe1,0xe2
unsigned int8 dig_H3; //0xe3
signed int16 dig_H4; //0xe4,0xe5[3:0]
signed int16 dig_H5; //0xe5[7:4],0xe6
signed int8 dig_H6; //0xe7
signed int32 t_fine;
} comps;
} _g_Bme280 = {0};
// THIS FUNCTION MOSTLY WRITTEN BY BOSCH, PROVIDED IN THEIR DATASHEETS.
// Returns pressure in Pa as unsigned 32 bit integer. Output value of "96386" equals 96386 Pa = 963.86 hPa
static unsigned int32 _bme280_compensate_P_int32(signed int32 adc_P)
{
signed int32 var1, var2;
unsigned int32 p;
var1 = (((signed int32)_g_Bme280.comps.t_fine)/2) - (signed int32)64000;
var2 = (((var1/4) * (var1/4)) / 2048 ) * ((signed int32)_g_Bme280.comps.dig_P6);
printf( "P STEP1 %ld %ld\r\n", var1, var2);
var2 = var2 + ((var1*((signed int32)_g_Bme280.comps.dig_P5))*2);
printf( "P STEP2a %ld %ld\r\n", var1, var2);
#if 0
var2 = (var2/4)+(((signed int32)_g_Bme280.comps.dig_P4)*65536);
printf( "P STEP2b %ld %ld %ld\r\n", var1, var2, (((signed int32)_g_Bme280.comps.dig_P4)*65536));
#else
var2 /= 4;
printf( "P STEP2- %ld\r\n", var2);
var2 += ((signed int32)_g_Bme280.comps.dig_P4) * 65536;
printf( "P STEP2b %ld\r\n", var2);
#endif
var1 = ((((signed int32)_g_Bme280.comps.dig_P3 * (((var1/4) * (var1/4)) / 8192 )) / 8) + ((((signed int32)_g_Bme280.comps.dig_P2) * var1)/2))/262144;
printf( "P STEP3a %ld %ld\r\n", var1, var2);
var1 =((((32768+var1))*((signed int32)_g_Bme280.comps.dig_P1))/32768);
printf( "P STEP3b %ld %ld\r\n", var1, var2);
if (var1 == 0)
{
return 0; // avoid exception caused by division by zero
}
p = (((unsigned int32)(((signed int32)1048576)-adc_P)-(var2/4096)))*3125;
printf( "P STEP4 %lu\r\n", p);
if (p < 0x80000000)
{
p = (p * 2) / ((unsigned int32)var1);
}
else
{
p = (p / (unsigned int32)var1) * 2;
}
printf( "P STEP5 %lu\r\n", p);
var1 = (((signed int32)_g_Bme280.comps.dig_P9) * ((signed int32)(((p/8) * (p/8))/8192)))/4096;
var2 = (((signed int32)(p/4)) * ((signed int32)_g_Bme280.comps.dig_P8))/8192;
p = (unsigned int32)((signed int32)p + ((var1 + var2 + (signed int32)_g_Bme280.comps.dig_P7) / 16));
printf( "P STEP6 %ld %ld %lu\r\n", var1, var2, p);
printf( "\r_bme280_compensate_P_int32(%ld) %ld\r\n", adc_P, p);
return p;
}
static signed int32 _bme280_compensate_T_int32(signed int32 adc_T)
{
signed int32 var1, var2, T;
var1 = ((((adc_T/8) - ((signed int32)_g_Bme280.comps.dig_T1*2))) * ((signed int32)_g_Bme280.comps.dig_T2)) / 2048;
#if 0
var2 = (((((adc_T/16) - ((signed int32)_g_Bme280.comps.dig_T1)) * ((adc_T/16) - ((signed int32)_g_Bme280.comps.dig_T1))) / 4096) * ((signed int32)_g_Bme280.comps.dig_T3)) / 16384;
#else
signed int32 var3, var4, var5, var6;
var3 = ((adc_T/16) - ((signed int32)_g_Bme280.comps.dig_T1));
var4 = 0;
var5 = ((var3 * var3) / 4096);
var6 = (var5 * ((signed int32)_g_Bme280.comps.dig_T3));
var2 = var6 / 16384;
printf( "_\rcomp_t %ld %ld %ld %ld\r\n", var3, var4, var5, var6);
#endif
_g_Bme280.comps.t_fine = var1 + var2;
T = (_g_Bme280.comps.t_fine * 5 + 128) / 256;
printf( "\r_bme280_compensate_T_int32(%ld) %ld %ld %ld %ld\r\n", adc_T, T, _g_Bme280.comps.t_fine, var1, var2);
return T;
}
static unsigned int32 _bme280_get20bits(char *p)
{
unsigned int32 ret = 0;
char c;
ret += *p++;
ret *= 256;
ret += *p++;
ret *= 16;
c = *p;
c >>= 4;
c &= 0xF;
ret += c;
return(ret);
}
static unsigned int32 _bme280_compensate_H_int32(signed int32 adc_H)
{
signed int32 v_x1_u32r;
unsigned int32 H;
v_x1_u32r = (_g_Bme280.comps.t_fine - ((signed int32)76800));
v_x1_u32r = (((((adc_H * 16384) - (((signed int32)_g_Bme280.comps.dig_H4) * 1048576) - (((signed int32)_g_Bme280.comps.dig_H5) * v_x1_u32r)) +
((signed int32)16384)) / 32768) * (((((((v_x1_u32r * ((signed int32)_g_Bme280.comps.dig_H6)) / 1024) * (((v_x1_u32r *
((signed int32)_g_Bme280.comps.dig_H3)) / 2048) + ((signed int32)32768))) / 1024) + ((signed int32)2097152)) *
((signed int32)_g_Bme280.comps.dig_H2) + 8192) / 16384));
v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r / 32768) * (v_x1_u32r / 32768)) / 128) * ((signed int32)_g_Bme280.comps.dig_H1)) / 16));
v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
H = (unsigned int32)(v_x1_u32r/4096);
printf("_bme280_compensate_H_int32(%ld) %ld\r\n", adc_H, H);
return H;
}
int1 bme280_get_humidity(signed int32 *pTemp, unsigned int32 *pPress, unsigned int32 *pHum)
{
unsigned int8 read[8];
unsigned int32 scr32;
printf( "\r bme280_get_humidity ");
if (!bme280_ok())
{
debug_bme280(debug_putc, "NOT_INIT\r\n");
return(FALSE);
}
if (!_bme280_read_bytes(read, 0xF7, sizeof(read)))
{
printf( "\rREAD_FAIL\r\n");
return(FALSE);
}
// #if defined(__DO_DEBUG2_BME280)
// _DEBUG_BME280_DISPLAY_TRIMS();
// #endif
printf( "\r%X %X %X %X %X %X %X %X\r\n", read[0], read[1], read[2], read[3], read[4], read[5], read[6], read[7]);
scr32 = _bme280_get20bits(&read[3]); //raw temp adc value
//#warning !! DEBUG VALUE BEING USED
//scr32 = 532560;
scr32 = _bme280_compensate_T_int32(scr32);
if (pTemp != 0) *pTemp = scr32;
if (pPress != 0)
{
scr32 = _bme280_get20bits(read); //raw press adc value
//#warning !! DEBUG VALUE BEING USED
//scr32 = 329712;
scr32 = _bme280_compensate_P_int32(scr32);
*pPress = scr32;
}
if (pHum != 0)
{
scr32 = 0;
scr32 = make16(read[6], read[7]);
//#warning !! DEBUG VALUE BEING USED
//scr32 = 27227;
scr32 = _bme280_compensate_H_int32(scr32);
*pHum = scr32;
}
return(TRUE);
}
*/
// end of code.
|
Reagars Pekka Ritamaki Finland |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sun Sep 10, 2023 5:02 am |
|
|
curious, I downloaded the Bosch BMP280 datasheet. The 'register map' of the device is NOT the same as what is in the code you post ! It may be you have a different variation of the sensor than whomever coded the driver you're using.
I suggest you copy the I2C SCANNER program from the 'code library' here,compile and run. It will tell you what addresses ARE valid for your device.
With every I2C device I use, I run the scanner.It's great at telling me I've wrongly configured I2C addresses ! |
|
|
pekka1234
Joined: 28 May 2017 Posts: 83
|
Temtonic. |
Posted: Sun Sep 10, 2023 5:32 am |
|
|
I have just right I2C address, 0xEC. Ift it is not right, I test it with my program http://remotesmart.wikidot.com/i2c-converter
All other things like pressure and temperature works well.
I showed the results in http://probyte.fi/Sunday.jpg
It is from yesterday and today.
After I put the question to you place, I got the answer from https://simple-circuit.com/
Maybe they have forgot to send it to me?
They say that there are two different model BMP280 and BME280.
I had said that I have BME280 model.
http://probyte.fi/BME280.jpg
They were asking what model I have?
Anyway, I found in simple-circuit.com a new(?) library BME280.
It has a humidity program.
I have just trying how it will work.
I will inform to here.
Regards Pekka |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sun Sep 10, 2023 6:25 am |
|
|
First thing. You say the 2620 works at 3.3v.
No it doesn't......
To run at 3.3v, you need the LF2640, not the F2620. Classic things that
fail when you run the 5v chip at 3.3v, are peripherals like the I2C....
You need to get the 3.3v version of your chip.
Even if it seems to work, it will be unreliable.
The BMP280, and the BME280 are relatives. The code for a BMP will run
with the BME. The difference is the BMP does not read humidity, so is
cheaper.
0xEC is correct if the SDO pin is pulled to ground. 0xEE is if SDO is pulled
up.
There are some significant problems with your code. You have temperature
as an int32, then subtract 1.94 from this. Not going to work.... |
|
|
pekka1234
Joined: 28 May 2017 Posts: 83
|
|
Posted: Sun Sep 10, 2023 6:29 am |
|
|
I tested the I2C address, it was 0xEC
Here what I got with BME280 :
Probyte BME280 sender,LDR,NTC 10-Sep-23
Connection error!
Forced 1
BME280 sender 10-Sep-23
Probyte BME280 sender,LDR,NTC 10-Sep-23
102400#TT15+24.94,-06.41,024,0903.07,100.00$
102400#TT15+24.93,-06.41,079,0903.07,100.00$
==
The Temperature +24.94 was my NTC temp.
The BME280 gives the temperature -06.41. Not right.
The LDR gives right 079.
The air pressure gives 903.07 mmBar, it should give about 100.1 mmBar
The air humidity was 100.00 %, it should give about 55-64 %
Hmm, I got something, but not right,
I have test it more.
Why the address is not right, although I tested it?
Pekka |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sun Sep 10, 2023 10:05 am |
|
|
The big problem is that your chip _will not work properly at 3.3v_ The
minimum rated voltage for the F2620, is 4.2v. Historically one of the
first peripherals that goes wrong when you try to operate below the
rated voltage is the I2C..... |
|
|
pekka1234
Joined: 28 May 2017 Posts: 83
|
|
Posted: Sun Sep 10, 2023 11:02 am |
|
|
Ttelmah.
You may be right, but I have used 18F2620 for 15 years and most of time with 3.3V peripherals.
As long it will work well, I an not worried.
The BME280 is 3.3V device, so I thing it will work with 3.3V
I know that there are PIC18LF2620, but what is the highest voltage of PIC18LF2620. Is it 5.5V? Why everybody doesn't use LF models?
In the sensor reads BME280, but Aliexpress is not very reliable.
I am very satisfied the cheap sensor., although it doesn't give me a humidity value.
==
I just return a GSM SIM800L V2 to Aliexpress.
They require a post following number.
It will costs 30 e and the 2 modems costs 8.5e
Pekka |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sun Sep 10, 2023 11:27 am |
|
|
Other thing though is that the maths you have is fundamentally flawed.
I suspect you have changed the types used, or the values used for
the values. Subtracting a FP number from an integer, just gives an integer
subtraction. Not going to give the result required.
You need to step back and use the right types where needed.... |
|
|
pekka1234
Joined: 28 May 2017 Posts: 83
|
|
Posted: Sun Sep 10, 2023 11:45 am |
|
|
Well, I do like is said
It is show in https://simple-circuit.com/pic16f877a-bme280-sensor-ccs-c/
Here is Humidity function.
I read humidity and dive it with 1024
=====
// Reads humidity from BME280 sensor.
// Humidity is stored in relative humidity percent in 1024 steps
// (output value of "47445" represents 47445/1024 = 46.333 %RH).
// Humidity value is saved to *humi, returns 1 if OK and 0 if error.
int1 BME280_readHumidity(uint32_t *humi)
{
int32_t v_x1_u32r;
uint32_t H;
v_x1_u32r = (t_fine - ((int32_t)76800));
v_x1_u32r = (((((adc_H * 16384) - (((int32_t)BME280_calib.dig_H4) * 1048576) - (((int32_t)BME280_calib.dig_H5) * v_x1_u32r)) +
((int32_t)16384)) / 32768) * (((((((v_x1_u32r * ((int32_t)BME280_calib.dig_H6)) / 1024) * (((v_x1_u32r *
((int32_t)BME280_calib.dig_H3)) / 2048) + ((int32_t)32768))) / 1024) + ((int32_t)2097152)) *
((int32_t)BME280_calib.dig_H2) + 8192) / 16384));
v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r / 32768) * (v_x1_u32r / 32768)) / 128) * ((int32_t)BME280_calib.dig_H1)) / 16));
v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
H = (uint32_t)(v_x1_u32r / 4096);
*humi = H;
return 1;
}
Hopefully you found my error
Pekka |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sun Sep 10, 2023 4:23 pm |
|
|
re: Why everybody doesn't use LF models?
Some of us are old enough to have only had 5 volt PICs to play with !!! That comes from TTL where 5 volt WAS the power source.
Today I use the 18F46K22 as it happily works at 5 or 3 volts. |
|
|
pekka1234
Joined: 28 May 2017 Posts: 83
|
|
Posted: Sun Sep 10, 2023 11:09 pm |
|
|
Thank you Temtronic !
So I use LF models from this day ( or when I got them)
Pekka |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Mon Sep 11, 2023 2:21 am |
|
|
It is not the function there that is faulty. It is what you are doing with it in your
main. Understand, the functions do not return floating point values, they
return integers, _Scaled_. So the temperature function returns 100, for
one degree. The pressure function 100000 for 1000mBar. You try to scale
the values, but using floating point values, not correctly scaled.... |
|
|
pekka1234
Joined: 28 May 2017 Posts: 83
|
|
Posted: Mon Sep 11, 2023 2:59 am |
|
|
I do not understand what you mean?
Here is my main program.
Code: |
#define LEDON output_high(PIN_C5); //Red LED
#include "BME280_Lib.c" // This is a new
signed int32 temperature;// this was BME280 temperature
unsigned int32 pressure, humidity=0;
unsigned int16 temp1 ;
void main()
{
int8 ok,i;
LEDON ;
delay_ms(1000); // wait 1 second
//BME280_Configure(MODE_NORMAL,SAMPLING_X1,
// SAMPLING_X1, 1,STANDBY_62_5) ;
if(BME280_begin(MODE_NORMAL) == 0)
{ // connection error or device address wrong!
printf("\rConnection error!");
}
/*
BME280_begin(MODE_NORMAL,
SAMPLING_X1,
SAMPLING_X1,
FILTER_OFF,
STANDBY_0_5);
*/
ok= BME280_ForcedMeasurement();
printf("\rBME280 sender %s\r", __DATE__ );
while(TRUE)
{
temp1=0;
for( i=0;i<10;i++) {
BME280_readTemperature(&temperature);
temp1 += temperature;
}
temperature = temp1/10 ;
BME280_readTemperature(&temperature);
BME280_readPressure(&pressure);// read pressure
BME280_readHumidity(&humidity);
temperature -= 240; // calibrate -2.c
printf("#TT15"); // # starts data string
temperature -= 1.94; // caibrate
if(temperature < 0)
{
temperature = abs(temperature); // abs: absolute value
printf("-%02Lu.%02Lu,", temperature / 100, temperature % 100);
}
else {
printf("+%02Lu.%02Lu,", temperature / 100, temperature % 100);
}
printf("%04Lu.%02Lu,", pressure/100, pressure % 100);
printf("%02Lu.%02Lu$\r", humidity / 1024, ((humidity * 100)/1024) % 100);
delay_ms(10000); // wait 10 seconds
}
}
// end of code.¯
|
The library return also unsigned int16 parameters.
What I have done wrong ?
Pekka |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Mon Sep 11, 2023 7:40 am |
|
|
I have to ask why you are fiddling around using this third party code?.
There is a driver for the BME280 included _with_ the compiler.
Use it. |
|
|
pekka1234
Joined: 28 May 2017 Posts: 83
|
|
Posted: Mon Sep 11, 2023 7:44 am |
|
|
If you mean CCS driver, I have tried to use it, but it doesn't work at all.
It is BMP280.c
Have tried it?
Pekka |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|