Version FC

Dependencies:   DmTftLibrary eeprom SX1280Lib filesystem mbed

Fork of MSNV2-Terminal_V1-5 by Francis CHATAIN

main.cpp

Committer:
FCH_31
Date:
2017-08-20
Revision:
7:1d890cab51bd
Parent:
6:784bb5247f0b
Child:
8:cd489b7c49a0

File content as of revision 7:1d890cab51bd:

#include "mbed.h"
#include "radio.h"
#include "sx1280-hal.h"
#include "stdio.h"
#include "XNucleoIKS01A2.h"

#include "DmTftHX8353C.h" 
#include "DmTftS6D0164.h"
#include "DmTftIli9325.h"
#include "DmTftIli9341.h"
#include "DmTftSsd2119.h"
#include "DmTftRa8875.h"

#define FIRMWARE_VERSION ( ( char* )"Firmware Version: 1.0" )   // display firmware version on RS232
#define MODE_LORA                                               // Lora modulation 
#define RF_FREQUENCY     2400000000UL                           // HzNominal frequency
#define TX_OUTPUT_POWER  -18                                    // Output power in dBm [-18..+13] dBm

typedef enum         // States of the application
{
    APP_LOWPOWER,
    APP_RX,
    APP_RX_TIMEOUT,
    APP_RX_ERROR,
    APP_TX,
    APP_TX_TIMEOUT,
}AppStates_t;

#define ID_TERMINAL1     '1' 
#define ID_TERMINAL2     '2'
#define ID_GATEWAY       '1'

float temperature = 0.0 ; 
float humidite    = 0.0 ; 

float etalonTemp1 = 6.3F ; 
float etalonTemp2 = 8.7F ; 


#define log(...) printf(__VA_ARGS__)

#define MESSAGESIZE     34                  // Defines the size of the token defining message type in the payload
char Message[MESSAGESIZE] = "MSG DATA IOT TERMINAL";

int cptr = 0 ; 

#define BUFFER_SIZE     34                  // Payload size
uint8_t BufferSize      =   BUFFER_SIZE;    // Size of the buffer
uint8_t Buffer[BUFFER_SIZE];                // Buffer 

AppStates_t AppState = APP_LOWPOWER;        // State of the application

int8_t RssiValue    = 0;
int8_t SnrValue     = 0;

void OnTxDone       ( void );               // Function to be executed on Radio Tx Done event
void OnRxDone       ( void );               // Function to be executed on Radio Rx Done event
void OnTxTimeout    ( void );               // Function executed on Radio Tx Timeout event
void OnRxTimeout    ( void );               // Function executed on Radio Rx Timeout event
void OnRxError      ( IrqErrorCode_t );     // Function executed on Radio Rx Error event

RadioCallbacks_t callbacks =                // All the callbacks are stored in a structure
{
    &OnTxDone,        // txDone
    &OnRxDone,        // rxDone
    NULL,             // syncWordDone
    NULL,             // headerDone
    &OnTxTimeout,     // txTimeout
    &OnRxTimeout,     // rxTimeout
    &OnRxError,       // rxError
    NULL,             // rangingDone
    NULL,             // cadDone
};

//                    mosi, miso, sclk, nss, busy, dio1, dio2, dio3, rst, callbacks...
SX1280Hal Radio     ( D11 , D12 , D13 , D7 , D3  , D5  , NC  , NC  , A0 , &callbacks );

DigitalOut ANT_SW   ( A3 )  ;
DigitalOut TxLed    ( A4 )  ;
DigitalOut RxLed    ( A5 )  ;
DigitalOut F_CS     ( D6 )  ;     // MBED description of pin
DigitalOut SD_CS    ( D8 )  ;     // MBED description of pin

#define TX_TIMEOUT_VALUE        100         // ms   Number of tick size steps for tx timeout
#define RX_TIMEOUT_VALUE        100         // ms   Number of tick size steps for rx timeout
#define RX_TIMEOUT_TICK_SIZE    RADIO_TICK_SIZE_1000_US   // Size of ticks (used for Tx and Rx timeout)

uint16_t RxIrqMask = IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT;       // Mask of IRQs to listen to in rx mode
uint16_t TxIrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;       // Mask of IRQs to listen to in tx mode

PacketParams_t PacketParams;        // Locals parameters and status for radio API
PacketStatus_t PacketStatus;        // NEED TO BE OPTIMIZED, COPY OF STUCTURE ALREADY EXISTING

ModulationParams_t modulationParams;


/* Instantiate the expansion board */
static XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(D14, D15, D4, D5);

/* Retrieve the composing elements of the expansion board */
static LSM303AGRMagSensor   *magnetometer = mems_expansion_board->magnetometer;
static HTS221Sensor         *hum_temp = mems_expansion_board->ht_sensor;
static LPS22HBSensor        *press_temp = mems_expansion_board->pt_sensor;
static LSM6DSLSensor        *acc_gyro = mems_expansion_board->acc_gyro;
static LSM303AGRAccSensor   *accelerometer = mems_expansion_board->accelerometer;

uint8_t     id1, id2, id3, id4, id5, id6, id7;
float       valueTH1, valueTH2, valueTP1, valueTP2;
float       OldvalueTH1, OldvalueTH2, OldvalueTP1, OldvalueTP2;
char        buffer1[32], buffer2[32], buffer3[32], buffer4[32];
int32_t     axesA[3], axesM[3], axesG1[3], axesG2[3];
int32_t     OldaxesA[3], OldaxesM[3], OldaxesG1[3], OldaxesG2[3];

static char *print_double   ( char* str, double v, int decimalDigits=2) ; 
void        baud            ( int baudrate ) ; 
void        sendRadio       ( char TERMINAL, char GATEWAY, float value1, float value2) ; 
 
 
DmTftIli9341 tft(D10, D9, D11, D12, D13);  /* DmTftIli9341(PinName cs, PinName dc, PinName mosi, PinName miso, PinName clk)  DM_TFT28_105 */

int bmpWidth, bmpHeight;
uint8_t bmpImageoffset;

/******************************************************************************
 * Global variables
 *****************************************************************************/

extern uint8_t dmlogo[];

/******************************************************************************
 * Local functions
 *****************************************************************************/

// LITTLE ENDIAN!
uint16_t read16(uint8_t *src)
{
  uint16_t d;
  uint8_t b;
  b = *src;
  d = *(src+1);
  d <<= 8;
  d |= b;
  return d;
}

// LITTLE ENDIAN!
uint32_t read32(uint8_t *src)
{
  uint32_t d;
  uint16_t b;

  b = read16(src);
  d = read16(src+2);
  d <<= 16;
  d |= b;
  return d;
}

void drawBmpFromFlash(int x, int y)
{
  uint16_t pos = bmpImageoffset;

  uint16_t p;  // pixel
  uint8_t g, b;
  int i, j; // line, column

  for(i=bmpHeight; i>0; i--) {
    for(j=0; j<bmpWidth; j++) {
      b = *(dmlogo+pos++);
      g = *(dmlogo+pos++);
      p = *(dmlogo+pos++);

      p >>= 3;
      p <<= 6;

      g >>= 2;
      p |= g;
      p <<= 5;

      b >>= 3;
      p |= b;

      // write out the 16 bits of color
      tft.setPixel(j, i+y, p);
    }
  }
}


int bmpReadHeader() {
  uint32_t fileSize;
  uint32_t headerSize;
  uint16_t bmpDepth;
  uint16_t pos = 0;
  log("reading bmp header\r\n");
  log("Magic byte is: %d \r\n", read16(dmlogo));


  if (read16(dmlogo) !=0x4D42){ // read magic byte
    log("Magic byte not found\r\n");
    return false;
  }

  pos += 2;

  // read file size
  fileSize = read32(dmlogo+pos);
  log("filesize is: %d \r\n", fileSize);
  log("");
  pos += 4;

  pos += 4; // Skip creator bytes

  bmpImageoffset = read32(dmlogo+pos);
  pos += 4;

  // read DIB header
  headerSize = read32(dmlogo+pos);
  pos +=4;
  bmpWidth = read32(dmlogo+pos);
  pos += 4;
  bmpHeight = read32(dmlogo+pos);
  pos += 4;

  //if (bmpHeight == -40) bmpHeight = 40 ; 


  log("Image size:        %d\r\n", fileSize);
  log("Image offset:      %d\r\n", bmpImageoffset);
  log("Header size:       %d\r\n", headerSize);
  log("Image width:       %d\r\n", bmpWidth );
  log("Image height:      %d\r\n", bmpHeight );
  

  if (read16(dmlogo+pos) != 1){
    // number of color planes must be 1
    return false;
  }

  pos += 2;

  bmpDepth = read16(dmlogo+pos);
  pos +=2;
  log("Bitdepth:          %d\r\n", bmpDepth);


  if (read16(dmlogo+pos) != 0) {
    // compression not supported!
    return false;
  }

  pos += 2; // Should really be 2??

  return true;
}


void updateDisplay (float temp1, float hum, float temp2, float press, int cptr1, int cptr2) ; 
void updateLed (bool led1, bool led2) ; 

/* Specify serial datarate for UART debug output */
void baud   ( int baudrate )    { Serial s( USBTX, USBRX ); s.baud( baudrate );}

  char bufferDisplay[50] ;  
 
  int IDTerminal = 1 ; 
  int IDGateway  = 1 ; 
  float temp1 = 20.0F ; 
  float temp2 = 20.0F ; 
  float hum = 50.0F ; 
  int press = 1000 ; 

void setup () {
    baud    (115200); 
    printf( "\n\n\r SX1280 Terminal IoT LORA MODULATION 2.4GHz (%s)\n\n\r", FIRMWARE_VERSION );

    F_CS   = 1  ;
    SD_CS  = 1  ;
    ANT_SW = 1  ;

    wait_ms( 500 ); // wait for on board DC/DC start-up time

    Radio.Init              ( );
    Radio.SetRegulatorMode  ( USE_DCDC ); // Can also be set in LDO mode but consume more power

    memset  ( &Buffer, 0x00, BufferSize );
 
    RxLed = 0;
    TxLed = 0;
    
    modulationParams.PacketType                     =   PACKET_TYPE_LORA        ;
    modulationParams.Params.LoRa.SpreadingFactor    =   LORA_SF7                ;
    modulationParams.Params.LoRa.Bandwidth          =   LORA_BW_0400            ;
    modulationParams.Params.LoRa.CodingRate         =   LORA_CR_4_5             ;

    PacketParams.PacketType                         =   PACKET_TYPE_LORA        ;
    PacketParams.Params.LoRa.PreambleLength         =   0x08                    ;
    PacketParams.Params.LoRa.HeaderType             =   LORA_PACKET_VARIABLE_LENGTH;
    PacketParams.Params.LoRa.PayloadLength          =   34                      ;
    PacketParams.Params.LoRa.CrcMode                =   LORA_CRC_ON             ;
    PacketParams.Params.LoRa.InvertIQ               =   LORA_IQ_INVERTED        ;

    Radio.SetStandby                ( STDBY_RC );
    Radio.SetPacketType             ( modulationParams.PacketType );
    Radio.SetModulationParams       ( &modulationParams );
    Radio.SetPacketParams           ( &PacketParams );
    Radio.SetRfFrequency            ( RF_FREQUENCY );
    Radio.SetBufferBaseAddresses    ( 0x00, 0x00 );
    Radio.SetTxParams               ( TX_OUTPUT_POWER, RADIO_RAMP_20_US );
    Radio.SetDioIrqParams           ( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
    Radio.SetRx                     ( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );

    AppState = APP_LOWPOWER;    
    
    /* Enable all sensors */
    hum_temp->enable        ();
    press_temp->enable      ();
    magnetometer->enable    ();
    accelerometer->enable   ();
    acc_gyro->enable_x      ();
    acc_gyro->enable_g      ();
  
    printf("\r\n--- Starting new run ---\r\n");

    hum_temp->read_id       (&id1);
    printf("HTS221  humidity & temperature    = 0x%X\r\n", id1);
    press_temp->read_id     (&id2);
    printf("LPS22HB  pressure & temperature   = 0x%X\r\n", id2);
    magnetometer->read_id   (&id3);
    printf("LSM303AGR magnetometer            = 0x%X\r\n", id3);
    accelerometer->read_id  (&id4);
    printf("LSM303AGR accelerometer           = 0x%X\r\n", id4);
    acc_gyro->read_id       (&id5);
    printf("LSM6DSL accelerometer & gyroscope = 0x%X\r\n", id5);
    
      tft.init();

  //tft.drawString(0,32,"www.");
  //tft.drawString(12,48,"displaymodule");
  //tft.drawString(88,64,".com");
  
  tft.drawString (20,80,"TERMINAL IoT MISNet V1.0");

  tft.drawRectangle (05, 70 , 230, 105, GREEN);
  tft.drawRectangle (05, 125, 230, 175, RED);
  tft.drawRectangle (05, 185, 230, 270, BLUE);
  tft.drawRectangle (05, 280, 230, 310, YELLOW); 

  sprintf (bufferDisplay, "ID Terminal  : %1d ", IDTerminal); 
  tft.drawString (40,130,bufferDisplay);
  sprintf (bufferDisplay, "ID Gateway   : %1d ", IDGateway); 
  tft.drawString (40,150,bufferDisplay);
  
  updateDisplay ( 0.0, 0.0, 0.0, 0.0, 0, 0 ) ; 
  updateLed     (false, false) ; 

  if (! bmpReadHeader()) {
    log("bad bmp\r\n");
    //return -1;
  }
  drawBmpFromFlash(20, 10);
}

  int cpt1, cpt2 = 0 ; 
  bool led1, led2 ; 


void loop () {   

    TxLed   = 0     ;     
    RxLed   = 0     ; 
    wait    (1)     ;
    F_CS    = 1     ;
    SD_CS   = 1     ;
    ANT_SW  = 1     ;
    led1 = led2 = false ; 
    
    /* Enable all sensors */
    hum_temp->enable        ();
    press_temp->enable      ();
    magnetometer->enable    ();
    accelerometer->enable   ();
    acc_gyro->enable_x      ();
    acc_gyro->enable_g      ();

    printf("============================================================== \r\n");
    hum_temp->get_temperature   (&valueTH1)   ;   
    hum_temp->get_humidity      (&valueTH2)   ;   
    printf("HTS221    : [temp] %7s C, [hum]   %s%%\r\n"    , print_double(buffer1, valueTH1), print_double(buffer2, valueTH2));
    press_temp->get_temperature (&valueTP1)   ;    
    press_temp->get_pressure    (&valueTP2)   ;    
    printf("LPS22HB   : [temp] %7s C, [press] %s mbar\r\n" , print_double(buffer3, valueTP1), print_double(buffer4, valueTP2));
    magnetometer->get_m_axes    (axesM)       ;   
    printf("LSM303AGR : [mag/mgauss]  %6ld, %6ld, %6ld\r\n", axesM[0], axesM[1], axesM[2]);  
    accelerometer->get_x_axes   (axesA)       ;   
    printf("LSM303AGR : [acc/mg]      %6ld, %6ld, %6ld\r\n", axesA[0], axesA[1], axesA[2]);
    acc_gyro->get_x_axes        (axesG1)      ;    
    printf("LSM6DSL   : [acc/mg]      %6ld, %6ld, %6ld\r\n", axesG1[0], axesG1[1], axesG1[2]);
    acc_gyro->get_g_axes        (axesG2)      ;        
    printf("LSM6DSL   : [gyro/mdps]   %6ld, %6ld, %6ld\r\n", axesG2[0], axesG2[1], axesG2[2]);
    printf("============================================================== \r\n");
     
    
    valueTH1 = valueTH1 - etalonTemp1 ; 
    valueTP1 = valueTP1 - etalonTemp2 ; 
 
    /* Disable all sensors */
    hum_temp->disable        ();
    press_temp->disable      ();
    magnetometer->disable    ();
    accelerometer->disable   ();
    acc_gyro->disable_x      ();
    acc_gyro->disable_g      ();
    
    if (    abs(OldvalueTH1 - valueTH1) > 0.25F  || 
            abs(OldvalueTH2 - valueTH2) > 0.25F  ||
            abs(OldaxesA[0] - axesA[0]) > 20 ) {
            OldvalueTH1 = valueTH1 ;   
            OldvalueTH2 = valueTH2 ;
            OldaxesA[0] = axesA[0] ; 
            led1 = true ; 
            updateLed (led1, led2) ; 
            sendRadio (ID_TERMINAL1, ID_GATEWAY, valueTH1, valueTH2) ;   
            cpt1++ ; 

     }
    if (    abs(OldvalueTP1 - valueTP1) > 0.25F  || 
            abs(OldvalueTP2 - valueTP2) > 0.25F  ||
            abs(OldaxesM[0] - axesM[0]) > 20 ) {
            OldvalueTP1 = valueTP1 ;   
            OldvalueTP2 = valueTP2 ;
            OldaxesM[0] = axesM[0] ; 
            led2 = true ; 
            updateLed (led1, led2) ; 
            sendRadio (ID_TERMINAL2, ID_GATEWAY, valueTP1, valueTP2) ; 
            cpt2++ ;  

     }    

    updateDisplay(valueTH1, valueTH2, valueTP1, valueTP2, cpt1, cpt2) ; 
    wait (0.8) ; 
    if (led1 ||led2) 
        updateLed (false, false) ; 

}
  

int main( )  { setup () ; while (1) loop () ; }

void OnTxDone       ( void )                            { /*printf( "*** TERM ***  OnTxDone      \r\n" ); */ AppState = APP_TX         ;   }
void OnRxDone       ( void )                            { printf( "*** TERM ***  OnRxDone      \r\n" ); AppState = APP_RX         ;   }
void OnTxTimeout    ( void )                            { printf( "*** TERM ***  OnTxTimeout   \r\n" ); AppState = APP_TX_TIMEOUT ;   }
void OnRxTimeout    ( void )                            { printf( "*** TERM ***  OnRxTimeout   \r\n" ); AppState = APP_RX_TIMEOUT ;   } 
void OnRxError      ( IrqErrorCode_t errorCode )        { printf( "*** TERM ***  OnRxError     \r\n" ); AppState = APP_RX_ERROR   ;   }
void OnRangingDone  ( IrqRangingCode_t val )            { printf( "*** TERM ***  OnRangingDone \r\n" ); }
void OnCadDone      ( bool channelActivityDetected )    { printf( "*** TERM ***  OnCadDone     \r\n" ); }

void updateDisplay (float temp1, float hum, float temp2, float press, int cptr1, int cptr2) {
    sprintf (bufferDisplay, "Temperature1 : %02.2f C", temp1);
    tft.drawString (20,190,bufferDisplay) ; 
    sprintf (bufferDisplay, "Humidite     : %02.2f % ", hum);
    tft.drawString (20,210,bufferDisplay);
    sprintf (bufferDisplay, "Temperature2 : %02.2f C", temp2);
    tft.drawString (20,230,bufferDisplay);
    sprintf (bufferDisplay, "Pression     : %05.1f mb", press);
    tft.drawString (20,250,bufferDisplay);   
    sprintf (bufferDisplay, "Tx #1:%04d", cptr1);
    tft.drawString (20,286,bufferDisplay);     
    sprintf (bufferDisplay, "#2:%04d", cptr2);
    tft.drawString (140,286,bufferDisplay); 
}

void updateLed (bool led1, bool led2) {
    if (led1)
        tft.fillCircle (115, 295, 8, RED) ; 
    else
        tft.fillCircle (115, 295, 8, BLACK) ;
        
    if (led2) 
        tft.fillCircle (210, 295, 8, RED) ; 
    else
        tft.fillCircle (210, 295, 8, BLACK) ;
           
    tft.drawCircle (115, 295, 8, WHITE) ; 
    tft.drawCircle (210, 295, 8, WHITE) ; 
    
}

   /*
    Radio.GetPacketStatus(&packetStatus);
    RssiValue = packetStatus.Lr24.RssiPkt;
    SnrValue = packetStatus.Lr24.SnrPkt;
    printf("rssi: %d; snr: %d\n\r", RssiValue, SnrValue );
    */
    
void sendRadio (char TERMINAL, char GATEWAY, float value1, float value2) {  
    TxLed = 1 ; 
    memset  ( &Buffer , 0x00, BufferSize );
    memset  ( &Message, 0x00, BufferSize );
    int n = sprintf             ( Message, "%c%c%5s%5s",  
                                    TERMINAL, 
                                    GATEWAY,
                                    print_double(buffer1, value1), 
                                    print_double(buffer2, value2) );                              
    memcpy                      ( Buffer    , Message   , MESSAGESIZE );
    printf                      ( "*** TERM ***  Message = %s \r\n", Buffer );
    Radio.SetDioIrqParams       ( TxIrqMask , TxIrqMask , IRQ_RADIO_NONE, IRQ_RADIO_NONE );
    Radio.SendPayload           ( Buffer    , BufferSize,( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
    TxLed = 0 ; 
 }   
    
    
    
/* Helper function for printing floats & doubles */
static char *print_double(char* str, double v, int decimalDigits)
{
  int i = 1;
  int intPart, fractPart;
  int len;
  char *ptr;

  /* prepare decimal digits multiplicator */
  for (;decimalDigits!=0; i*=10, decimalDigits--);

  /* calculate integer & fractinal parts */
  intPart = (int)v;
  fractPart = (int)((v-(double)(int)v)*i);

  /* fill in integer part */
  sprintf(str, "%i.", intPart);

  /* prepare fill in of fractional part */
  len = strlen(str);
  ptr = &str[len];

  /* fill in leading fractional zeros */
  for (i/=10;i>1; i/=10, ptr++) {
    if (fractPart >= i) {
      break;
    }
    *ptr = '0';
  }

  /* fill in (rest of) fractional part */
  sprintf(ptr, "%i", fractPart);

  return str;
}