Porting arduino, i2c registers give different values in squirrel

I’m trying to port the BME280 library from Arduino to Squirrel. One of the main functions is:
function readTemperature() { local var1, var2; local adc_T = read16(BME280_REGISTER_TEMPDATA); adc_T = adc_T << 8; adc_T = adc_T | read8(BME280_REGISTER_TEMPDATA+2); adc_T = adc_T >> 4; var1 = ((((adc_T>>3) - (cal_t1 <<1)))); * (cal_t2)) >> 11; var2 = (((((adc_T>>4) - (cal_t1)) * ((adc_T>>4) - (cal_t1))) >> 12) * (cal_t3)) >> 14; local t_fine = var1 + var2; local T = (t_fine * 5 + 128) >> 8; return T/100; }

I went through this code line by line on both arduino and eimp inserting server.logs and they work identically up until cal_t1 .

cal_t1 is a calibration register from
`function readCoefficients(){

cal_t1 <- read16(BME280_REGISTER_DIG_T1);` BME280_REGISTER_DIG_T1 has already been assigned in the beginning of my code

const BME280_REGISTER_DIG_T1 = "\\x88";

and read16 is function read16(REG_ADDR) { local word = i2c.read(i2cAddr, REG_ADDR, 2); local REG_VAL = (word[0] << 8) + word[1]; server.log(REG_VAL); return REG_VAL; }

Also the arduino code seems to cast the register value to 32 bit (int32_t)bme280_calib.dig_T1 <<1).

The imp returns 63085 and the arduino returns 21852.00 . I don’t understand why Arduino prints the .00 as the type of the read16_LE there (.cpp in the arduino library) is

uint16_t Adafruit_BME280::read16_LE(byte reg) {
uint16_t temp = read16(reg);
return (temp >> 8) | (temp << 8);
}

Sorry a code tag didn’t work for my last snippet

Note that there’s a rogue ; in your var1 calculation.

I would double-check your calibration on the two versions. I don’t know the BME280, but I see that the Arduino code makes use of signed 16-bit values, and these will need converting to signed 32-bit values for use in Squirrel, ie. you need to make sure bit 15 in the int_16t value matches bit 31 in the Squirrel integer.

PS. Looking at the BME280 datasheet, I see the compensation calculations use (in part) unsigned 32-bit integers, which are not supported by Squirrel. Eg. if the BME280 generates a value of 2147483649, Squirrel reads this as -2147483647.

So you’re going to have to do some work with the value’s two 16-bit components to get the right numbers out

@fmurray one obvious thing here is that you’re swapping the bytes…

The BME280 datasheet says the lower register number has the LSBs, and that’s also why the Arduino lib says “read16_LE” (little endian).

Read16 should be:
function read16(REG_ADDR) { local word = i2c.read(i2cAddr, REG_ADDR, 2); local REG_VAL = (word[1] << 8) + word[0]; server.log(REG_VAL); return REG_VAL; }

guys, would you mind sharing your code?

I have a BME280 and wanted to use it. The code on GH is not fully ported…