#include <stdio.h> //provides printf function
#include <string.h> //provides memset etc
#include "pico/stdlib.h" //provides standard library for the pico
#include "hardware/gpio.h" //configure gpio
#include "hardware/i2c.h" //configure i2c
#include "shtc3.h"
#include "ssd1306.h"
#include "raspberry26x32.h"
#define I2C_INSTANCE i2c0
#define PICO_I2C_SDA_PIN 16
#define PICO_I2C_SCL_PIN 17
// I2C peripheral adapted from https://wokwi.com/projects/333375908055351891
// I2C reserves some addresses for special purposes. We exclude these from the scan.
// These are any addresses of the form 000 0xxx or 111 1xxx
bool reserved_addr(uint8_t addr) {
return (addr & 0x78) == 0 || (addr & 0x78) == 0x78;
}
int main()
{
stdio_init_all();
// This example will use I2C0 on the selected SDA and SCL pins
i2c_init(I2C_INSTANCE, 100 * 1000);
gpio_set_function(PICO_I2C_SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(PICO_I2C_SCL_PIN, GPIO_FUNC_I2C);
//the pico has a board with hardware pullups attached
//gpio_pull_up(PICO_I2C_SDA_PIN);
//gpio_pull_up(PICO_I2C_SCL_PIN);
printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n");
for (int addr = 0; addr < (1 << 7); ++addr) {
if (addr % 16 == 0) {
printf("%02x ", addr);
}
// Perform a 1-byte dummy read from the probe address. If a slave
// acknowledges this address, the function returns the number of bytes
// transferred. If the address byte is ignored, the function returns
// -1.
// Skip over any reserved addresses.
int ret;
uint8_t rxdata;
if (reserved_addr(addr))
ret = PICO_ERROR_GENERIC;
else
ret = i2c_read_blocking(I2C_INSTANCE, addr, &rxdata, 1, false);
printf(ret < 0 ? "." : "@");
printf(addr % 16 == 15 ? "\n" : " ");
}
printf("\n");
// Initialize render area for entire frame (SSD1306_WIDTH pixels by SSD1306_NUM_PAGES pages)
struct render_area frame_area = {
start_col: 0,
end_col : SSD1306_WIDTH - 1,
start_page : 0,
end_page : SSD1306_NUM_PAGES - 1
};
calc_render_area_buflen(&frame_area);
// zero the entire display
uint8_t buf[SSD1306_BUF_LEN];
memset(buf, 0, SSD1306_BUF_LEN);
render(buf, &frame_area);
// intro sequence: flash the screen 3 times
for (int i = 0; i < 3; i++) {
SSD1306_send_cmd(SSD1306_SET_ALL_ON); // Set all pixels on
sleep_ms(500);
SSD1306_send_cmd(SSD1306_SET_ENTIRE_ON); // go back to following RAM for pixel state
sleep_ms(500);
}
// render 3 cute little raspberries
struct render_area area = {
start_page : 0,
end_page : (IMG_HEIGHT / SSD1306_PAGE_HEIGHT) - 1
};
area.start_col = 0;
area.end_col = IMG_WIDTH - 1;
calc_render_area_buflen(&area);
uint8_t offset = 5 + IMG_WIDTH; // 5px padding
for (int i = 0; i < 3; i++) {
render(raspberry26x32, &area);
area.start_col += offset;
area.end_col += offset;
}
while (true) {
uint16_t sht3c_id = shtc3_read_id();
uint32_t res;
float temp, hum;
printf("Read SHT3C chip ID: %x\n", sht3c_id);
res = shtc3_perform_measurements(&temp, &hum);
printf("Read SHT3C I2C read res: %x\n", res);
printf("Temperature: %.1f\n", temp);
printf("Humidity: %.1f\n", hum);
sleep_ms(1000);
}
}