Updates along with SDK1.3.0 release (#181)
Bug fixes and new examples Co-authored-by: Paulo Marques <pm@quant-insight.com> Co-authored-by: martin <admin@crossleys.biz> Co-authored-by: matiasilva <matias.silva@raspberrypi.com> Co-authored-by: Uri Shaked <uri@urishaked.com> Co-authored-by: Diego Solano <diegosolano@gmail.com> Co-authored-by: Andrew Scheller <andrew.scheller@raspberrypi.com> Co-authored-by: Adrian Hesketh <a-h@users.noreply.github.com> Co-authored-by: Emircan Gündoğdu <58917386+emircangun@users.noreply.github.com> Co-authored-by: Josef Wegner <80200012+josefwegner@users.noreply.github.com> Co-authored-by: pmarques-dev <72901351+pmarques-dev@users.noreply.github.com> Co-authored-by: Paulo Marques <pm@quant-insight.com> Co-authored-by: mjcross <mjcross@users.noreply.github.com> Co-authored-by: martin <admin@crossleys.biz>
This commit is contained in:
147
i2c/mcp9808_i2c/mcp9808_i2c.c
Normal file
147
i2c/mcp9808_i2c/mcp9808_i2c.c
Normal file
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/binary_info.h"
|
||||
#include "hardware/i2c.h"
|
||||
|
||||
/* Example code to talk to a MCP9808 ±0.5°C Digital temperature Sensor
|
||||
|
||||
This reads and writes to registers on the board.
|
||||
|
||||
Connections on Raspberry Pi Pico board, other boards may vary.
|
||||
|
||||
GPIO PICO_DEFAULT_I2C_SDA_PIN (On Pico this is GP4 (physical pin 6)) -> SDA on MCP9808 board
|
||||
GPIO PICO_DEFAULT_I2C_SCK_PIN (On Pico this is GP5 (physcial pin 7)) -> SCL on MCP9808 board
|
||||
Vsys (physical pin 39) -> VDD on MCP9808 board
|
||||
GND (physical pin 38) -> GND on MCP9808 board
|
||||
|
||||
*/
|
||||
//The bus address is determined by the state of pins A0, A1 and A2 on the MCP9808 board
|
||||
static uint8_t ADDRESS = 0x18;
|
||||
|
||||
//hardware registers
|
||||
|
||||
const uint8_t REG_POINTER = 0x00;
|
||||
const uint8_t REG_CONFIG = 0x01;
|
||||
const uint8_t REG_TEMP_UPPER = 0x02;
|
||||
const uint8_t REG_TEMP_LOWER = 0x03;
|
||||
const uint8_t REG_TEMP_CRIT = 0x04;
|
||||
const uint8_t REG_TEMP_AMB = 0x05;
|
||||
const uint8_t REG_RESOLUTION = 0x08;
|
||||
|
||||
|
||||
void mcp9808_check_limits(uint8_t upper_byte) {
|
||||
|
||||
// Check flags and raise alerts accordingly
|
||||
if ((upper_byte & 0x40) == 0x40) { //TA > TUPPER
|
||||
printf("Temperature is above the upper temperature limit.\n");
|
||||
}
|
||||
if ((upper_byte & 0x20) == 0x20) { //TA < TLOWER
|
||||
printf("Temperature is below the lower temperature limit.\n");
|
||||
}
|
||||
if ((upper_byte & 0x80) == 0x80) { //TA > TCRIT
|
||||
printf("Temperature is above the critical temperature limit.\n");
|
||||
}
|
||||
}
|
||||
|
||||
float mcp9808_convert_temp(uint8_t upper_byte, uint8_t lower_byte) {
|
||||
|
||||
float temperature;
|
||||
|
||||
|
||||
//Check if TA <= 0°C and convert to denary accordingly
|
||||
if ((upper_byte & 0x10) == 0x10) {
|
||||
upper_byte = upper_byte & 0x0F;
|
||||
temperature = 256 - (((float) upper_byte * 16) + ((float) lower_byte / 16));
|
||||
} else {
|
||||
temperature = (((float) upper_byte * 16) + ((float) lower_byte / 16));
|
||||
|
||||
}
|
||||
return temperature;
|
||||
}
|
||||
|
||||
#ifdef i2c_default
|
||||
void mcp9808_set_limits() {
|
||||
|
||||
//Set an upper limit of 30°C for the temperature
|
||||
uint8_t upper_temp_msb = 0x01;
|
||||
uint8_t upper_temp_lsb = 0xE0;
|
||||
|
||||
//Set a lower limit of 20°C for the temperature
|
||||
uint8_t lower_temp_msb = 0x01;
|
||||
uint8_t lower_temp_lsb = 0x40;
|
||||
|
||||
//Set a critical limit of 40°C for the temperature
|
||||
uint8_t crit_temp_msb = 0x02;
|
||||
uint8_t crit_temp_lsb = 0x80;
|
||||
|
||||
uint8_t buf[3];
|
||||
buf[0] = REG_TEMP_UPPER;
|
||||
buf[1] = upper_temp_msb;
|
||||
buf[2] = upper_temp_lsb;
|
||||
i2c_write_blocking(i2c_default, ADDRESS, buf, 3, false);
|
||||
|
||||
buf[0] = REG_TEMP_LOWER;
|
||||
buf[1] = lower_temp_msb;
|
||||
buf[2] = lower_temp_lsb;
|
||||
i2c_write_blocking(i2c_default, ADDRESS, buf, 3, false);
|
||||
|
||||
buf[0] = REG_TEMP_CRIT;
|
||||
buf[1] = crit_temp_msb;
|
||||
buf[2] = crit_temp_lsb;;
|
||||
i2c_write_blocking(i2c_default, ADDRESS, buf, 3, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
|
||||
stdio_init_all();
|
||||
|
||||
#if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN)
|
||||
#warning i2c/mcp9808_i2c example requires a board with I2C pins
|
||||
puts("Default I2C pins were not defined");
|
||||
#else
|
||||
printf("Hello, MCP9808! Reading raw data from registers...\n");
|
||||
|
||||
// This example will use I2C0 on the default SDA and SCL pins (4, 5 on a Pico)
|
||||
i2c_init(i2c_default, 400 * 1000);
|
||||
gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C);
|
||||
gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C);
|
||||
gpio_pull_up(PICO_DEFAULT_I2C_SDA_PIN);
|
||||
gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);
|
||||
// Make the I2C pins available to picotool
|
||||
bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C));
|
||||
|
||||
mcp9808_set_limits();
|
||||
|
||||
uint8_t buf[2];
|
||||
uint16_t upper_byte;
|
||||
uint16_t lower_byte;
|
||||
|
||||
float temperature;
|
||||
|
||||
while (1) {
|
||||
// Start reading ambient temperature register for 2 bytes
|
||||
i2c_write_blocking(i2c_default, ADDRESS, ®_TEMP_AMB, 1, true);
|
||||
i2c_read_blocking(i2c_default, ADDRESS, buf, 2, false);
|
||||
|
||||
upper_byte = buf[0];
|
||||
lower_byte = buf[1];
|
||||
|
||||
//isolates limit flags in upper byte
|
||||
mcp9808_check_limits(upper_byte & 0xE0);
|
||||
|
||||
//clears flag bits in upper byte
|
||||
temperature = mcp9808_convert_temp(upper_byte & 0x1F, lower_byte);
|
||||
printf("Ambient temperature: %.4f°C\n", temperature);
|
||||
|
||||
sleep_ms(1000);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user