/* teplota_sht30.c
 * Měření teploty a relativní vlhkosti čidlem SHT30 
 * a zobrazení na OLED displeji ssd1306
 * 
 * (c) Jirka Chráska 2026, <jirka@lixis.cz>
 * BSD 3 clause licence.
 */

#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "ssd1306.h"
#include "font.h"
#include "pico_sensor_lib.h"
#include <stdio.h>
#include <string.h>

// pro OLED displej SSD1306
#define DISPLAY_WIDTH   128			// šířka displeje
#define DISPLAY_HEIGHT  32			// výška displeje
#define I2C_ADDRESS     0x3C		// i2c adresa
#define I2C_FREQ        1000000		// rychlost i2c sběrnice
#define SDA_PIN         4			// datový pin
#define SDC_PIN         5			// hodinový pin
#define I2C             i2c0		// i2c hardware

// struktura pro OLED displej včetně framebufferu
static ssd1306_t disp;

extern bitmapFONT font_spleen_6x12;

// čidlo SHT30
#define SHT30_I2C   i2c1
#define SHT30_ADDR  0x44
#define SHT30_SDA   14
#define SHT30_SCL   15

// nastavení I2C sběrnice
void setup_i2c(void)
{
    // displej na sběrnici i2c0 
    i2c_init(I2C, I2C_FREQ);
    gpio_set_function(SDA_PIN, GPIO_FUNC_I2C);
    gpio_set_function(SDC_PIN, GPIO_FUNC_I2C);
    gpio_pull_up(SDA_PIN);
    gpio_pull_up(SDC_PIN);
    // pauza 200ms je nutná kvůli displeji. Pokud není, displej se někdy nerozsvítí
    // pauza 100ms je málo
    sleep_ms(200);
    // čidlo SHT30 je na druhé sběrnici i2c1
    i2c_init(SHT30_I2C, I2C_FREQ);
    gpio_set_function(SHT30_SDA, GPIO_FUNC_I2C);
    gpio_set_function(SHT30_SCL, GPIO_FUNC_I2C);
    gpio_pull_up(SHT30_SDA);
    gpio_pull_up(SHT30_SCL);
    sleep_ms(200);
}

void zapnuti_displeje( void )
{
    ssd1306_init(&disp, DISPLAY_WIDTH, DISPLAY_HEIGHT, I2C_ADDRESS, I2C); // inicializace
    ssd1306_poweron(&disp); // zapnutí displeje
    ssd1306_clear(&disp);   // vymazání displeje
    ssd1306_contrast(&disp,0x10);
    ssd1306_draw_utf8_string(&disp, 0,  0, &font_spleen_6x12, "Teplota a rel. vlkost");
    ssd1306_draw_utf8_string(&disp, 0, 16, &font_spleen_6x12, "čidlo SHT30");
    ssd1306_show(&disp); // zobrazíme na displeji
}


int main()
{
char buf[128];
    stdio_init_all();
    sleep_ms(1500);
    printf("\n\nMěření teploty a relativní vlhkosti čidlem SHT30\n");
    //getchar();
    memset(buf,0,sizeof(buf));
	// nastavení displeje SSD1306
    setup_i2c();
    zapnuti_displeje();
    
    
	// Initialize sensor
    void *ctx = NULL;
    int res = i2c_init_sensor(get_i2c_sensor_type("SHT30"), SHT30_I2C, SHT30_ADDR, &ctx);
    if (res) {
        // nemohu nastavit čidlo...
        printf("Nemohu inicializovat sensor SHT30\n");
        ssd1306_draw_utf8_string(&disp, 0, 0, &font_spleen_6x12, "Nemohu nastavit SHT30");
        return -1;
    }
    
    int delay;
    float temp, pressure, humidity;

    while(1) {
        delay = i2c_start_measurement(ctx);
        // printf("Prodleva měření %d ms\n",delay);
        sleep_ms(delay+10);
        int res = i2c_read_measurement(ctx, &temp, &pressure, &humidity);
        memset(buf,0,sizeof(buf));
	    if (res) { // -1 je chcíplé čidlo, -2 je chyba CRC
            // failed to read measurements...
            printf("Nemohu přečíst naměřené hodnoty %d.\n", res);
            sprintf(buf,"Chyba čidla: %s.", res==-1?"neměří":"CRC");
            ssd1306_clear(&disp);   // vymazání displeje
            ssd1306_draw_utf8_string(&disp, 0, 0, &font_spleen_6x12, buf);
            ssd1306_show(&disp);
        } else {
            sprintf(buf,"Teplota: %5.1f °C", temp);
            printf("Teplota %5.1f °C, relativní vlkost %5.1f %%\r",temp,humidity);
            ssd1306_clear(&disp);   // vymazání displeje
            ssd1306_draw_utf8_string(&disp, 0, 0, &font_spleen_6x12, buf);
            sprintf(buf,"Rel. vlkost: %5.1f %%", humidity); 
            ssd1306_draw_utf8_string(&disp, 0, 16, &font_spleen_6x12, buf);
            ssd1306_show(&disp);
        }
        sleep_ms(1000);
    }

    ssd1306_poweroff(&disp);
    // ukončení práce s displejem (uvolnění paměti framebufferu)
    ssd1306_deinit(&disp);
}
