[CZ] Firmware pro meteostanici - odesílání přes Sigfox

Dobrý den, snažím se zprovoznit jednoduché odesílání teploty a hodnoty osvětlení (mám lux tag) z core modulu přes sigfox. Pomocí příkladu, který byl na stránkách BigClown a používal Sigfox (už tam není), jsem si upravil kód na následující:

#include <application.h>

#define SIGFOX_COOLDOWN_SECONDS (15 * 60)

typedef enum
{
SIGFOX_HEADER_RESET = 0,
SIGFOX_HEADER_MOTION = 1,
} sigfox_header_t;

bc_led_t led;
bc_button_t button;
bc_tag_temperature_t temperature_tag;
bc_module_sigfox_t sigfox_module;

float temperature;

bool button_transmission_active = false;

void application_init(void)
{
bc_led_init(&led, BC_GPIO_LED, false, false);

bc_button_init(&button, BC_GPIO_BUTTON, BC_GPIO_PULL_DOWN, false);
bc_button_set_event_handler(&button, button_event_handler, NULL);

bc_tag_temperature_init(&temperature_tag, BC_I2C_I2C0, BC_TAG_TEMPERATURE_I2C_ADDRESS_ALTERNATE);
bc_tag_temperature_set_update_interval(&temperature_tag, 120000);

bc_module_sigfox_init(&sigfox_module, BC_MODULE_SIGFOX_REVISION_R2);
bc_module_sigfox_set_event_handler(&sigfox_module, sigfox_module_event_handler, NULL);

}

// Spustí funkci transmit_button_task při stisku tlačítka
void button_event_handler(bc_button_t *self, bc_button_event_t event, void *event_param)
{
(void) self;
(void) event_param;

if (event == BC_BUTTON_EVENT_PRESS)
{
    if (bc_module_sigfox_is_ready(&sigfox_module))
    {
        bc_tag_temperature_get_temperature_celsius(self, &temperature);

        uint8_t buffer[5];

        buffer[0] = 0x02;
        buffer[1] = (uint32_t) temperature;
        buffer[2] = (uint32_t) temperature >> 8;
        buffer[3] = (uint32_t) temperature >> 16;
        buffer[4] = (uint32_t) temperature >> 24;

        bc_module_sigfox_send_rf_frame(&sigfox_module, buffer, sizeof(buffer));
    }
}

}

void sigfox_module_event_handler(bc_module_sigfox_t *self, bc_module_sigfox_event_t event, void *event_param)
{
(void) self;
(void) event_param;

if (event == BC_MODULE_SIGFOX_EVENT_ERROR)
{
    bc_led_set_mode(&led, BC_LED_MODE_BLINK);
}
if (event == BC_MODULE_SIGFOX_EVENT_SEND_RF_FRAME_START)
{
    bc_led_set_mode(&led, BC_LED_MODE_BLINK_FAST);
}
else if (event == BC_MODULE_SIGFOX_EVENT_SEND_RF_FRAME_DONE)
{
    bc_led_set_mode(&led, BC_LED_MODE_OFF);
}

}

Nějaká data se mi v thingspeaku zobrazují:

thingspeak

Aktuálně se odeslání spouští stiskem tlačítka, já bych ale potřeboval, aby se data odesílala automaticky každých 12 minut. Jak program upravit?

Rád bych psaní kódu pro bigclown více porozuměl, ale žádný tutoriál, který by se tomu věnoval jsem nenašel, vše to je stylem stáhni si hotový firmware, nahraj a je to. Když chce ale člověk udělat v projektu nějaké úpravy, je to dost složité.

Zdravím,
vašemu případu bude asi nejbližší tento kód


Je tam i ukázka jak pracovat s data streamem, což je jednoduchá komponenta do které se vkládají naměřené vzorky a lze z něj lehce vytáhnout nějaké statistické informace, jako třeba průměr a medián.

Pro váš příklad bych navrhoval měřit dané veličiny třeba každou minutu a právě do data streamu ukládat, a každých 12 min si vytáhnout průměrné hodnoty a odeslat.

Odesílání dat co 12min, bude mít dopat na baterii, záleží který z batery modulů použijete a jaký typ baterií, jestli alkalické nebo lion. Velký battery modul s kvalitními alkalickými bateriemi zpráva po 12 minutách odhad 4-6měsíců.

Dobry den, pokud potrebujete odesilat zprumerovane vzorky, urcite se ridte radou vyse napsanou. Pokud potrebujete kazdych 12 minut odeslat pouze aktualni hodnotu, je to jeste jednodussi.

Udelal bych to treba tak, ze bych si vytvoril funkci, ktera zmeri co potrebuji a data odesle. Tuto funkci bych pomoci Scheduleru spustil kazdych dvanact minut (zbytek casu procesor spi). Podobny tutorial je v priprave a zverejnim jej hned jak bude hotovy. Mezitim se prosim zkuste podivat na:

Scheduler basics: https://www.bigclown.com/doc/firmware/timing-and-scheduler/
Scheduler SDK: http://sdk.bigclown.com/group__bc__scheduler.html

Zaroven se zeptam - jaky tutorial by se vam libil ohledne psani kodu? Obecne pochopeni koncepce, vice prikladu, vice komentaru v hotovem firmwaru,…? Diky :slight_smile:

Dobrý den,

základy scheduleru jsem díky tutoriálu pochopil a zaimplementoval do programu, nicméně není mi jasné, jak tasku přidělím ID, v ukázkovém příkladu jsem toto nenašel.

Aktuálně můj program vypadá takto:

#include <application.h>

bc_led_t led;
bc_button_t button;
bc_module_sigfox_t sigfox;
bc_tmp112_t temp;

static void disableLCD(void* param)
{
    (void) param;
    bc_led_set_mode(&led, BC_LED_MODE_OFF);
}

static void start_sending(void* param)
{
    if (bc_module_sigfox_is_ready(&sigfox)) {
        uint8_t buffer[4];
        float value = 0.0;
        bc_tmp112_get_temperature_celsius(&temp, &value);

        memcpy(buffer, &value, 4);

        if (bc_module_sigfox_send_rf_frame(&sigfox, buffer, sizeof(buffer))) {
            bc_led_set_mode(&led, BC_LED_MODE_ON);
            bc_scheduler_register(disableLCD, NULL, bc_tick_get() + 3000);
        } else {
            bc_led_set_mode(&led, BC_LED_MODE_BLINK);
            bc_scheduler_register(disableLCD, NULL, bc_tick_get() + 2000);
        }
    } else {
        bc_led_set_mode(&led, BC_LED_MODE_BLINK);
        bc_scheduler_register(disableLCD, NULL, bc_tick_get() + 2000);
    }
    bc_scheduler_plan_current_from_now(60000);
}

void application_init(void)
{
    bc_led_init(&led, BC_GPIO_LED, false, false);
    bc_led_set_mode(&led, BC_LED_MODE_OFF);

    bc_module_sigfox_init(&sigfox, BC_MODULE_SIGFOX_REVISION_R2);

    bc_scheduler_register(start_sending, NULL, bc_tick_get() + 1000);
}

Každou minutu se odešle zpráva (na Thingspeaku to vidím), ale data jsou 0. To znamená, že tam je někde problém s vyčítáním teploty nebo převodem na uint8_t, co s tím? Převodník na UART nemám a USB dongle taky ne, takže mám trochu problém s debuggováním a nevím, kde přesně je chyba.

Co se týče tutoriálu, tak mám problémy s pochopením koncepce, třeba když se používají event funkce např. void button_event_handler(bc_button_t *self, bc_button_event_t event, void *event_param), tak nerozumím jednotlivým parametrům, prostě to jenom opíšu.

Díky,
Jakub

Dobry vecer, tasku ID nepridelujete - to prideli SDK samo. Vy jej muzete jednoduse zjistit pomoci
bc_scheduler_task_id_t bc_scheduler_get_current_task_id (void )

http://sdk.bigclown.com/group__bc__scheduler.html#gad1104a0ca62626127ff7425c78e2f118

Co se tyce cetnosti odesilani - pozor na limity. Dle legislativy jsou pro pasmo 868MHz nejaka omezeni na 1% vysilaciho casu, takze by vysilani melo byt maximalne 140x za den (kazdych 6-7 minut tusim).

UART prevodnik - nejsem si uplne jisty na co ho potrebujete, kdyz Core ma usb - takze je mozne treba printovat data z bufferu do konzole, nejak takto:

  • #include <bc_usb_cdc.h>
  • v app_init() spustit bc_usb_cdc_init();
  • odeslat data pomoci bc_usb_cdc_write(buffer, strlen(buffer))

–> Priklad v dokumentaci: https://www.bigclown.com/doc/firmware/how-to-usb-console/

Pomuze tohle aspon trochu v debuggingu?

Koncepce
Chapu, v dokumentaci se to pokusime nejak rozumne vysvetlit. Kazdopadne Handlery funguji takto:

  • prvni parametr je asi jasny, pointer na instanci tlacitka
  • druhy - typ eventu, ktery se stal - v pripade tlacitka je to press, release, click a hold… Pomoci jednoducheho IFu muzete napriklad zajistit, ze handler zareaguje pouze v pripade, ze tlacitko budete drzet alespon 3 sekundy, jinak ne.
  • treti parametr - (void *) je “genericky” pointer a slouzi k tomu, ze autori SDK nevi, jake vlastni hodnoty budete chtit do handleru poslat formou parametru - floaty, chary, inty… (void *) je mozne pretypovat na libovolny typ a pouzit jej tak pro libovolne typy hodnot. Tady je hezky popis:
    https://stackoverflow.com/questions/11626786/what-does-void-mean-and-how-to-use-it

Pokud je problemu vice, cemu neni rozumet na prvni pohled, muzeme se treba potkat na par minut v chatu a probrat to? GHangouts, Jabber, FB… kdyztak mi poslete SZ :slight_smile:

Samotny kod - tipoval bych, ze chyba je nekde mezi konverzi float -> uint8 a odesilanim… Hned jak budu mit pristup k nutnemu vybaveni, pokusim se otestovat… Treba ale bude nekdo rychlejsi