This is an example application based on Mbed-OS LoRaWAN protocol APIs. The Mbed-OS LoRaWAN stack implementation is compliant with LoRaWAN v1.0.2 specification.

Dependencies:   Lorawan_Version_0_1

Dependents:   Lorawan_Version_0_1

main.cpp

Committer:
jacktractive
Date:
2020-02-04
Revision:
74:b05ae4efbd12
Parent:
73:974c1df98553

File content as of revision 74:b05ae4efbd12:

#include <stdio.h>
#include "Watchdog.h"
#include "events/EventQueue.h"
#include "trace_helper.h"
#include <mbed.h>
#include "mbed_stats.h"
#include "Light.h"
#include "GPS.h"
#include "Lora.h"

#define MAX_NUMBER_OF_EVENTS            20
static EventQueue ev_queue(MAX_NUMBER_OF_EVENTS *EVENTS_EVENT_SIZE);

int TickID,LoraTickID;
uint32_t TickCounter;
uint32_t TickTime=3000;
uint32_t LoraTickCounter;
uint32_t LoraTickTime=15000; //15000
uint32_t LoraTickTimeSleep=21600000; // in sleep mode only every 6 hours to receive commandos


int mode;

bool IsLoading;
AnalogIn LadeSpannung(PB_0); // 1/11 der gleichgerichteten Spannung am Dynamo

//Light
DigitalOut LichtAus(PC_12);
DigitalOut LichtHell(PC_9);
Light light(&ev_queue,&LichtAus,&LichtHell);

//Userbutton
DigitalIn USERButton(PB_15);

//GPS
DigitalOut GPSdisable(PC_6);
GPS GPS_modul(PC_4, PC_5, 9600,&GPSdisable);
uint32_t TimeWithoutMoving;

//Lora
Lora lora(&ev_queue, &light, &GPS_modul);

// function for changing the mode 
void change_mode(int modeid);

//LoraTicker Send information
static void LoraTicker()
{   
//Lora Lifetick
    LoraTickCounter=LoraTickCounter+1;
    printf("\n\n[LoraTick] --- [%i]", LoraTickCounter);
    
//GPS read
    GPS_modul.get_Position();   
    
//LORA 
    lora.send_Position_to_Lora(0x01, GPS_modul.time,GPS_modul.longitude,GPS_modul.latitude);           
}


//LifeTicker - Check if bike is moving
static void LifeTicker()
{   

//Lifetick
    TickCounter=TickCounter+1;
    printf("\n[LiveTick] --- [%i] ", TickCounter);
    
//Watchdog
    Watchdog &watchdog = Watchdog::get_instance();    
    Watchdog::get_instance().kick(); // kick the Watchdog before the timeout
    
//Sleep statistics
   mbed_stats_cpu_t stats;
   mbed_stats_cpu_get(&stats);
   printf("\n[SYSTEM] Uptime: %llu Idle: %llu Sleep: %llu Deep: %llu", stats.uptime / 1000 , stats.idle_time / 1000, stats.sleep_time / 1000,stats.deep_sleep_time / 1000);
        
//Dynamo - bike in motion - adjust light
   if(LadeSpannung.read()*3.3f*11 > 2) {   
        TimeWithoutMoving =0 ;
        printf("\n[SYSTEM] Bike moving: %fV", LadeSpannung.read()*3.3f*11);

//GPS , Lora wake up communication when moving
        if (GPS_modul.mode==2 && GPS_modul.is_idle){
            GPS_modul.idle(false); 
            printf("\n[GPS] Wake up due to Moving");
        }
        if (GPS_modul.mode==3){
            change_mode(2); // eco mode after moving
        }
    }else {        
        TimeWithoutMoving=TimeWithoutMoving+TickTime;
        printf("\n[SYSTEM] Bike still for: %is", TimeWithoutMoving/1000);
        
//GPS turn off when bike is not moved for a while (3min)
        if (GPS_modul.mode==2 && TimeWithoutMoving>180000){ 
        GPS_modul.idle(true); //GPS to sleep, Lora needs to stay active for blinkrequests
        printf("\n[GPS] Sleep due to Standing still");
        }       
     }        
     
// Adjust the light according to the movement of the bike
    light.adjust(TimeWithoutMoving);


// change Mode 
if (GPS_modul.mode!= mode) change_mode(GPS_modul.mode);
if (!USERButton) change_mode(mode+1);
}

  
/**
 * Entry point for application
 */
int main(void)
{ 
    Watchdog &watchdog = Watchdog::get_instance();    
    watchdog.start(30000); //30s ohne kick im Ticker wird die CPU neu gestartet    
    uint32_t watchdog_timeout = watchdog.get_timeout();
    printf("Watchdog initialized to %iu ms.\r\n", watchdog_timeout);
           
    TickID = ev_queue.call_every(TickTime,LifeTicker); //Zyklus um Dynamoaktivitäten zu prüfen
    LoraTickID = ev_queue.call_every(LoraTickTime,LoraTicker); //Zyklus zum senden über Lora     
    
    setup_trace(); // setup tracing für mehr Infos im log über lora    
    
    lora.Lora_init(); // Lora initialisieren
    
    mode=1; // always starting in normal mode
    GPS_modul.mode = mode;
    
    ev_queue.dispatch_forever();// make your event queue dispatching events forever
    return 0;
}

void change_mode(int modeid){
    
 //Stop current LoraTick         
          if (LoraTickID>0)  { 
                 ev_queue.cancel(LoraTickID);
                 LoraTickID=0;
                 }        
                 
 //1 = normal , 2 = Eco-mode GPS only while moving , 3 = sleep Lora only every few hours for remote accessibility
         mode=modeid;
         if (mode>3) mode=1; 
         GPS_modul.mode=mode;           
    
 //Init new LoraTick         
 
         if (mode == 1){
             GPS_modul.idle(false); 
             LoraTickID = ev_queue.call_every(LoraTickTime,LoraTicker); //Zyklus zum senden über Lora    
             light.Blinken_ein(500); //blink 1x
             printf("\n[MODE][1][Normal-Mode]");
             }
         if (mode == 2) {    
             LoraTickID = ev_queue.call_every(LoraTickTime,LoraTicker); //Zyklus zum senden über Lora, GPS only when moving       
             light.Blinken_ein(1000);//blink 2x
             printf("\n[MODE][2][Eco-Mode]");
             }             
         if (mode == 3) {    
             LoraTickID = ev_queue.call_every(LoraTickTimeSleep,LoraTicker); // Lora Ticker every few hours te receive messages   
             GPS_modul.idle(true);  
             light.Blinken_ein(1500);//blink 3x
             printf("\n[MODE][3][Sleep-Mode]");
             }
     }              
    
// EOF