ver. 1

Dependencies:   mbed OneWireCRC_LoRa_Node

main.cpp

Committer:
lukas_formanek
Date:
2021-05-08
Revision:
2:e731b7dba32b
Parent:
1:8a60d7a33fa5

File content as of revision 2:e731b7dba32b:

#include "stm32f4xx_hal.h"
#include "stm32f4xx.h"
#include "hal_tick.h"
#include "mbed.h"
//#include "stdio.h"
//#include <sstream>
//#include <iostream>
//#include <string>
#include "DS18B20.h"
#include "OneWireDefs.h"


#ifndef DEBUG_CONSOLE
    #define DEBUG_CONSOLE 0
#endif

#define USB_TX          PA_9
#define USB_RX          PA_10
#define LORA_TX         PA_11
#define LORA_RX         PA_12
#define THERM_PIN       PB_8
#define LED_PIN         PB_0
#define FOTO_PIN        PA_1
#define BATTERY_PIN     PA_3

#define BUF_SIZE        256
#define V_BATT_REFF     8.20                                            // max napatie baterii

volatile int measurePeriod = 60;                                        // in seconds

const double voltage_divider_ref = V_BATT_REFF * (1.00/(1.00+1.60));    // max uroven napatia na delici
const char *delimiter=":";                                              // delimiter na prijatie spravy
volatile uint32_t timeCounter = 0;

DS18B20 thermometer(true, true, false,THERM_PIN);
AnalogIn foto(FOTO_PIN);
AnalogIn battery(BATTERY_PIN);
DigitalOut led(LED_PIN);
Ticker secondTicker;

Serial lora(LORA_TX, LORA_RX,115200);

#if DEBUG_CONSOLE
    Serial usb(USB_TX, USB_RX,115200);
#endif


char buffer[BUF_SIZE];
char hexBuffer[BUF_SIZE];
char rxBuffer[BUF_SIZE];
char rxMessage[BUF_SIZE];
char message[BUF_SIZE];

volatile int8_t rxPtr = 0;
volatile uint8_t numOfERR = 0;
volatile float batteryValue = 0.00;
volatile float temperature = 0.00;
volatile uint16_t fotoValue = 0;


volatile bool measure = true;
volatile bool rxDone = false;
volatile bool receiveOK=false;
volatile bool receiveACK=false;
volatile bool receiveJOIN=false;
volatile bool receiveERR=false;

// -----------------------------------------------------------------------------
void onSecondTick();
void rxLoraInterrupt();
void clearRxBuffer();
void resetModule();
void init();
void onMeasure();
void onReceive();
// -----------------------------------------------------------------------------


int main()
{
    #if DEBUG_CONSOLE
        usb.printf("\r\n ------------ START APPLICATION ------------ \r\n");
        usb.printf("HCLK frequency : %d \r\n",HAL_RCC_GetHCLKFreq());
        usb.printf("System clock : %d \r\n", SystemCoreClock);
    #endif
    init();
    while(true) {
        if(measure) {
            onMeasure();
        }

        if(receiveACK) {
            onReceive();
        }

        if(receiveERR) {
            receiveERR = false;
        }

        if(receiveOK) {
            receiveOK = false;
        }
        hal_sleep();
    }
}


void clearRxBuffer()
{
    memset(rxBuffer, '\0', sizeof(rxBuffer));
    rxPtr = 0;
};

void resetModule()
{
    numOfERR = 0;
    lora.printf("at+set_config=device:sleep:0\r\n");
    wait(0.2);
    receiveJOIN = false;
    lora.printf("at+set_config=device:restart\r\n");
    #if DEBUG_CONSOLE
        usb.printf("Joining to network... \r\n");
    #endif

    Timer timer;
    timer.reset();
    timer.start();
    while(1) 
    {
        if(receiveJOIN) 
        {
            #if DEBUG_CONSOLE
                usb.printf("Join OK \r\n");
            #endif
            timer.stop();
            receiveJOIN=false;
            break;
        }
        if(timer.read_ms() > 30000) 
        {
            timer.stop();
            timer.reset();
            timer.start();
            lora.printf("at+join\r\n");
            #if DEBUG_CONSOLE
                usb.printf("Joining...\r\n");
            #endif
        }
    }
    timer.stop();
}


void rxLoraInterrupt()
{
    while (lora.readable()) 
    {
        char c = lora.getc();
//        usb.putc(c);
        if(rxPtr >= sizeof(rxBuffer) - 1)
            clearRxBuffer();
        rxBuffer[rxPtr++] = c;

        if(c =='\n') 
        {
            rxDone = true;

            if( strncmp( ( const char* )rxBuffer, "at+recv", 7) == 0) 
            {
                receiveACK = true;
                snprintf((char *)rxMessage, BUF_SIZE, "%s", rxBuffer);
                clearRxBuffer();
                return;
            }

            if(strncmp( ( const char* )rxBuffer, "OK", 2) == 0) 
            {
                receiveOK = true;
                clearRxBuffer();
                return;
            }

            if(strncmp( ( const char* )rxBuffer, "ERROR", 5) == 0) 
            {
                receiveERR = true;
                numOfERR++;
                clearRxBuffer();
                return;
            }

            if( strncmp( ( const char* )rxBuffer, "[LoRa]:Join Success", 19) == 0) 
            {
                receiveJOIN = true;
                clearRxBuffer();
                return;
            }
            clearRxBuffer();
        }
    }
}

void onSecondTick()
{
    timeCounter++;
    if(timeCounter >= measurePeriod) 
    {
        timeCounter = 0;
        measure = true;
        return;
    }
}

void init()
{
    led = 1;                                        // led OFF
    timeCounter = 0;
    secondTicker.detach();
    clearRxBuffer();
    lora.attach(&rxLoraInterrupt, Serial::RxIrq);
    resetModule();
    thermometer.initialize();
    thermometer.setResolution(twelveBit);
    memset(buffer, '\0', sizeof(buffer));
    memset(hexBuffer, '\0', sizeof(hexBuffer));
    memset(rxBuffer, '\0', sizeof(rxBuffer));
    memset(rxMessage, '\0', sizeof(rxMessage));
    memset(message, '\0', sizeof(message));
    sprintf(hexBuffer,"at+send=lora:1:");
    secondTicker.attach(&onSecondTick, 1.0);
}

void onMeasure()
{
    fotoValue = foto.read_u16();
    batteryValue = (((battery.read_u16()/65535.0)*3.30)/voltage_divider_ref)*V_BATT_REFF;
    lora.printf("at+set_config=device:sleep:0\r\n");
    temperature = thermometer.readTemperature();
    sprintf(buffer, "%.2f;%.2f;%d", batteryValue, temperature, fotoValue);
    for(int i=0; i < sizeof(buffer); i++) 
    {
        if(buffer[i] == '\0')
            break;
        sprintf(hexBuffer + strlen(hexBuffer), "%02x",buffer[i]);
    }
    #if DEBUG_CONSOLE
        usb.printf("Buffer : %s\r\n", buffer);
    #endif
    lora.printf("%s\r\n", hexBuffer);
    memset(buffer, '\0', sizeof(buffer));
    memset(hexBuffer, '\0', sizeof(hexBuffer));
    sprintf(hexBuffer,"at+send=lora:1:");
    measure=false;
}

void onReceive()
{
    #if DEBUG_CONSOLE
        usb.printf("%s",rxMessage);
    #endif
    if(rxMessage[8] != '0') 
    {
        char *e;
        int idx;
        e = strchr(rxMessage, ':');
        idx = (int)(e - rxMessage);
        char str[3];
        str[2]='\0';
        int8_t j = 0;
        memset(message, '\0', sizeof(message));

        for(int i=idx+1; i<sizeof(rxMessage); i+=2) 
        {
            if((rxMessage[i] == '\r') || (rxMessage[i] == '\n'))
                break;
            str[0]=rxMessage[i];
            str[1]=rxMessage[i+1];
            char chr = (char)(int)strtol((const char *)str, NULL, 16);
            message[j++] = chr;
        }

        if(rxMessage[8] == '1') 
        {               // nastavenie intervalu merania v sekundach
            timeCounter = 0;
            measurePeriod = atoi((const char*)(message));
            #if DEBUG_CONSOLE
                usb.printf("Converted number : %d \r\n", measurePeriod);
            #endif
        } 
        else if(rxMessage[8] == '2') 
        {
            if( strncmp( ( const char* )message, "reset", 5) == 0) 
            {
                #if DEBUG_CONSOLE
                    usb.printf("Received message : %s \r\n", message);
                    usb.printf("\r\n ------------ SOFTWARE RESET ------------ \r\n");
                #endif
                NVIC_SystemReset();
            }
            lora.printf("at+set_config=device:sleep:0\r\n");
            wait(0.1);
            lora.printf("%s\r\n", message);
            wait(0.2);
        }
        #if DEBUG_CONSOLE
            usb.printf("Received message : %s \r\n", message);
        #endif
    }
    memset(rxMessage, '\0', sizeof(rxMessage));
    lora.printf("at+set_config=device:sleep:1\r\n");
    receiveACK = false;
}