@@ -471,6 +471,154 @@ uint8_t Baro_update() { // first UT conversion is started in i
471
471
}
472
472
#endif
473
473
474
+ // ************************************************************************************************************
475
+ // I2C Barometer BOSCH BMP280
476
+ // ************************************************************************************************************
477
+ // I2C adress: 0x76 or 0x77 !!!Please make sure you set the correct address (BMP280_ADDR)
478
+ // ************************************************************************************************************
479
+
480
+ #if defined(BMP280)
481
+
482
+ #define BMP280_ADDR 0x76
483
+ #define i2c_read (ack ) (ack) ? i2c_readAck() : i2c_readNak();
484
+
485
+ #define BMP280_CAL_REG_FIRST 0x88
486
+ #define BMP280_CAL_REG_LAST 0xA1
487
+ #define BMP280_CAL_DATA_SIZE (BMP280_CAL_REG_LAST+1 - BMP280_CAL_REG_FIRST)
488
+
489
+ #define BMP280_STATUS_REG 0xF3
490
+ #define BMP280_CONTROL_REG 0xF4
491
+ #define BMP280_CONFIG_REG 0xF5
492
+
493
+ #define BMP280_PRES_REG 0xF7
494
+ #define BMP280_TEMP_REG 0xFA
495
+ #define BMP280_RAWDATA_BYTES 6 // 3 bytes pressure, 3 bytes temperature
496
+
497
+ int64_t p; // temp variable for calculating pressure
498
+ uint32_t deadline;
499
+
500
+ static union _bmp280_cal_union {
501
+ uint8_t bytes[BMP280_CAL_DATA_SIZE];
502
+ struct {
503
+ uint16_t dig_t1;
504
+ int16_t dig_t2;
505
+ int16_t dig_t3;
506
+ uint16_t dig_p1;
507
+ int16_t dig_p2;
508
+ int16_t dig_p3;
509
+ int16_t dig_p4;
510
+ int16_t dig_p5;
511
+ int16_t dig_p6;
512
+ int16_t dig_p7;
513
+ int16_t dig_p8;
514
+ int16_t dig_p9;
515
+ };
516
+ } bmp280_cal;
517
+
518
+ /*
519
+ * read calibration registers
520
+ */
521
+ static void bmp280_getcalibration (void )
522
+ {
523
+ memset (bmp280_cal.bytes , 0 , sizeof (bmp280_cal));
524
+
525
+ i2c_read_reg_to_buf (BMP280_ADDR,
526
+ BMP280_CAL_REG_FIRST,
527
+ bmp280_cal.bytes ,
528
+ BMP280_CAL_DATA_SIZE
529
+ );
530
+ }
531
+
532
+ void bmp280_set_ctrl (uint8_t osrs_t , uint8_t osrs_p, uint8_t mode)
533
+ {
534
+ i2c_writeReg (BMP280_ADDR, BMP280_CONTROL_REG,
535
+ ((osrs_t & 0x7 ) << 5 ) | ((osrs_p & 0x7 ) << 2 ) | (mode & 0x3 ));
536
+ }
537
+
538
+ void bmp280_set_config (uint8_t t_sb, uint8_t filter, uint8_t spi3w_en)
539
+ {
540
+ i2c_writeReg (BMP280_ADDR, BMP280_CONFIG_REG,
541
+ ((t_sb & 0x7 ) << 5 ) | ((filter & 0x7 ) << 2 ) | (spi3w_en & 1 ));
542
+ }
543
+
544
+ #define bmp280_24bit_reg (b1, b2, b3 ) ( \
545
+ ((int32_t )(b1) << 16 ) \
546
+ | ((int32_t )(b2) << 8 ) \
547
+ | ((int32_t )(b3) ) \
548
+ )
549
+
550
+ /* Measures and calculates pressure and temperature
551
+ *
552
+ * This function updates global variables baroPressure and baroTemperature
553
+ *
554
+ * baroTemperature unit is 0.01 deg C
555
+ * baroPressure unit is Pa
556
+ *
557
+ */
558
+
559
+ void bmp280_measure (void )
560
+ {
561
+ uint8_t data[BMP280_RAWDATA_BYTES];
562
+ int32_t temp_raw, pres_raw, var1, var2, t_fine;
563
+
564
+ i2c_read_reg_to_buf (BMP280_ADDR, BMP280_PRES_REG, data, BMP280_RAWDATA_BYTES);
565
+ pres_raw = bmp280_24bit_reg (data[0 ], data[1 ], data[2 ]);
566
+ temp_raw = bmp280_24bit_reg (data[3 ], data[4 ], data[5 ]);
567
+
568
+ temp_raw >>= 4 ;
569
+ pres_raw >>= 4 ;
570
+
571
+ var1 = ((((temp_raw >> 3 ) - ((int32_t )bmp280_cal.dig_t1 << 1 ))) *
572
+ ((int32_t )bmp280_cal.dig_t2 )) >> 11 ;
573
+
574
+ var2 = (((((temp_raw >> 4 ) - ((int32_t )bmp280_cal.dig_t1 )) *
575
+ ((temp_raw >> 4 ) - ((int32_t )bmp280_cal.dig_t1 ))) >>12 ) *
576
+ ((int32_t )bmp280_cal.dig_t3 )) >> 14 ;
577
+
578
+ t_fine = var1 + var2;
579
+
580
+ baroTemperature = (t_fine * 5 + 128 ) >> 8 ;
581
+
582
+ var1 = ((int64_t )t_fine) - 128000 ;
583
+ var2 = var1 * var1 * (int64_t )bmp280_cal.dig_p6 ;
584
+ var2 = var2 + ((var1 * (int64_t )bmp280_cal.dig_p5 ) << 17 );
585
+ var2 = var2 + (((int64_t )bmp280_cal.dig_p4 ) << 35 );
586
+ var1 = ((var1 * var1 * (int64_t )bmp280_cal.dig_p3 ) >> 8 ) +
587
+ ((var1 * (int64_t )bmp280_cal.dig_p2 ) << 12 );
588
+ var1 = (((((int64_t )1 ) << 47 ) + var1)) * ((int64_t )bmp280_cal.dig_p1 ) >> 33 ;
589
+
590
+ if (var1 == 0 ) {
591
+ return 0 ; // avoid exception caused by division by zero
592
+ }
593
+ p = 1048576 - pres_raw;
594
+ p = (((p << 31 ) - var2) * 3125 ) / var1;
595
+ var1 = (((int64_t )bmp280_cal.dig_p9 ) * (p >> 13 ) * (p >> 13 )) >> 25 ;
596
+ var2 = (((int64_t )bmp280_cal.dig_p8 ) * p) >> 19 ;
597
+
598
+ p = ((p + var1 + var2) >> 8 ) + (((int64_t )bmp280_cal.dig_p7 ) << 4 );
599
+ baroPressure = p >> 8 ; // baroPressure in Pa
600
+
601
+ }
602
+
603
+ void Baro_init () {
604
+ bmp280_getcalibration ();
605
+ bmp280_set_config (0 , 4 , 0 ); // 0.5 ms standby time, 16x filter, no 3-wire SPI
606
+ bmp280_set_ctrl (2 , 5 , 3 ); // T oversample x2, P over sample x16, normal mode
607
+ deadline = currentTime+5000 ;
608
+ }
609
+
610
+ // return 0: no data available, no computation ; 1: new value available and computation ;
611
+ uint8_t Baro_update () {
612
+ if (currentTime < deadline) return 0 ;
613
+ deadline = currentTime+3000 ;
614
+
615
+ Baro_Common ();
616
+ bmp280_measure ();
617
+
618
+ return 1 ;
619
+ }
620
+ #endif
621
+
474
622
// ************************************************************************************************************
475
623
// I2C Barometer MS561101BA
476
624
// ************************************************************************************************************
@@ -1536,4 +1684,4 @@ void initSensors() {
1536
1684
initS ();
1537
1685
if (i2c_errors_count == 0 ) break ; // no error during init => init ok
1538
1686
}
1539
- }
1687
+ }
0 commit comments