Da ka xi tong.

Dependencies:   libmDot mbed-rtos mbed

Fork of mDot_Connect_IoTClub_one_wire_4ch_8_24 by wireless sensor

main.cpp

Committer:
wang1tao
Date:
2017-02-16
Revision:
17:b60549bc8626
Parent:
16:847c028f4130

File content as of revision 17:b60549bc8626:

#include "mbed.h"
//#include "DataLoggerRS232.h"
#include "mbed.h"
#include "mDot.h"
#include "MTSLog.h"
#include <string>
#include <vector>
#include <algorithm>
#include <math.h>

#define RETURN_OK              0
#define RETURN_ERR            -1
//define baudrate
#define PC_BAUDRATE            115200
#define CARD_MACHINE_BAUDRATE  19200

#define COMMAND_LENGTH         7
#define RESPONSE_LENGTH        16
#define RINGBUFFER_SIZE        100

#define READ_PERIOD            1
#define SEND_PERIOD            5

const char readCmd[COMMAND_LENGTH] = {0x09,0x41,0x31,0x46,0x33,0x46,0x0d};

char readBuf[RESPONSE_LENGTH] = {0};
char ringBuffer[RINGBUFFER_SIZE][RESPONSE_LENGTH] = {0};

unsigned int inIndex  = 0;
unsigned int outIndex = 0;

/* functions prototype */
void readCardID(void);
void sendCardID(void);

void my_strcpy(char *dst, char *src);
void my_strclear(char *str, unsigned int len);

int configNetwork(void);
int joinNetwork(void);
int send_data(char *str);

/* Global variables */
Serial pc       (USBTX, USBRX);  // tx, rx
Serial cm_rs485 (PA_2,PA_3);     // tx, rx

mDot* dot;

static std::string config_network_name = "chinaiot";
static std::string config_network_pass = "password";
static uint8_t config_frequency_sub_band = 2; 

int main() 
{    
    int32_t ret;

    pc.baud(PC_BAUDRATE);
    pc.printf("\n\r\n\r\n\r");
    pc.printf("============================================\n\r");
    pc.printf("SiFOX remote card read system!\n\r");
    pc.printf("============================================\n\r");
    pc.printf("PC COM RS232 baudrate: %d \n\r", PC_BAUDRATE);
    cm_rs485.baud(CARD_MACHINE_BAUDRATE);
    cm_rs485.format(9,SerialBase::Even,1);
    pc.printf("Card Machine RS485 baudrate: %d!\n\r", CARD_MACHINE_BAUDRATE);

    //*******************************************
    // Configurate Network
    //*******************************************
    ret = configNetwork();
    if(ret != RETURN_OK)         
        dot->sleep(5, mDot::RTC_ALARM); //sleep a while and restart
    
    //*******************************************
    // Join Network
    //*******************************************
    ret = joinNetwork();
    if(ret != RETURN_OK)         
        dot->sleep(5, mDot::RTC_ALARM); //sleep a while and restart
   
    pc.printf("Wait 15S or card machine booting...\n\r");
    wait(15); 
    
    while(1) {
        /* Read Card ID */
        readCardID();
        
        /* Send Card ID to gateway */
        sendCardID();
        
        /* wait a while */
        wait(1);          
    }
}

    
int configNetwork(void)
{
    int32_t ret; 
    
    dot = mDot::getInstance();
    
    // print library version information
    pc.printf("version: %s\n\r", dot->getId().c_str());
    
    //*******************************************
    // configuration
    //*******************************************
    // reset to default config so we know what state we're in
    dot->resetConfig();

    dot->setLogLevel(mts::MTSLog::INFO_LEVEL);

    // set up the mDot with our network information: frequency sub band, network name, and network password
    // these can all be saved in NVM so they don't need to be set every time - see mDot::saveConfig()

    // frequency sub band is only applicable in the 915 (US) frequency band
    // if using a MultiTech Conduit gateway, use the same sub band as your Conduit (1-8) - the mDot will use the 8 channels in that sub band
    // if using a gateway that supports all 64 channels, use sub band 0 - the mDot will use all 64 channels
    pc.printf("Setting frequency sub band\n\r");
    if ((ret = dot->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) {
        pc.printf("Error:failed to set frequency sub band %d:%s\n\r", ret, mDot::getReturnCodeString(ret).c_str());
        return RETURN_ERR;
    }

    pc.printf("Setting network name\n\r");
    if ((ret = dot->setNetworkName(config_network_name)) != mDot::MDOT_OK) {
        pc.printf("Error:failed to set network name %d:%s\n\r", ret, mDot::getReturnCodeString(ret).c_str());
        return RETURN_ERR;
    }

    pc.printf("Setting network password\n\r");
    if ((ret = dot->setNetworkPassphrase(config_network_pass)) != mDot::MDOT_OK) {
        pc.printf("Error:failed to set network password %d:%s\n\r", ret, mDot::getReturnCodeString(ret).c_str());
        return RETURN_ERR;
    }
    
    // a higher spreading factor allows for longer range but lower throughput
    // in the 915 (US) frequency band, spreading factors 7 - 10 are available
    // in the 868 (EU) frequency band, spreading factors 7 - 12 are available
    pc.printf("Setting TX spreading factor\n\r");
    if ((ret = dot->setTxDataRate(mDot::SF_10)) != mDot::MDOT_OK) {
        pc.printf("Error:failed to set TX datarate %d:%s\n\r", ret, mDot::getReturnCodeString(ret).c_str());
        return RETURN_ERR;
    }

    // request receive confirmation of packets from the gateway
    pc.printf("Enabling ACKs\n\r");
    if ((ret = dot->setAck(1)) != mDot::MDOT_OK) {
        pc.printf("Error:failed to enable ACKs %d:%s\n\r", ret, mDot::getReturnCodeString(ret).c_str());
        return RETURN_OK;
    }

    // save this configuration to the mDot's NVM
    pc.printf("Saving config\n\r");
    if (! dot->saveConfig()) {
        pc.printf("Error:failed to save configuration\n\r");
    }
    
    return RETURN_OK;
}   // end of configuration


int joinNetwork(void)
{    
    int32_t ret,i; 
    std::vector<uint8_t> sendData;
    char _header[] = "ChongQi!";
    
    // attempt to join the network
    pc.printf("Joining network...\n\r");
    
    while ((ret = dot->joinNetwork()) != mDot::MDOT_OK) {
        pc.printf("Error: failed to join network %d:%s\n\r", ret, mDot::getReturnCodeString(ret).c_str());
        // in the 868 (EU) frequency band, we need to wait until another channel is available before transmitting again
        return RETURN_ERR;
    }

    sendData.clear(); 
    // format data for sending to the gateway
    for( i=0; i< strlen(_header); i++ )
               sendData.push_back( _header[i] );
               
    // send the data to the gateway
    pc.printf("Send header to the gateway\n\r");

    if ((ret = dot->send(sendData)) != mDot::MDOT_OK) {
        pc.printf("Error: failed to send %d:%s\n\r", ret, mDot::getReturnCodeString(ret).c_str());
        return RETURN_ERR;
    } else {
        pc.printf("Successfully sent data to gateway\n\r");
    } 
    
    return RETURN_OK;
}

int send_data(char *str)
{
    int32_t i, ret;
    std::vector<uint8_t> sendData;
    
    //Send the data to Gateway
    sendData.clear();   
    // probably not the most efficent way to do this
    for(i=0; i< strlen(str); i++ )
        sendData.push_back(str[i] );
        
    // send the data to the gateway
    pc.printf("Send %s to Gateway \n\r", str); 
    
    if ((ret = dot->send(sendData)) != mDot::MDOT_OK) {
        pc.printf("Error:failed to send\n\r", ret, mDot::getReturnCodeString(ret).c_str());
        return RETURN_ERR;
    } else {            
        pc.printf("Sent data to gateway successfully!\n\r");
    }
    return RETURN_OK;
}


void my_strcpy(char *dst, char *src)
{
    int j=0;
    
    while(src[j] != 0)
    {
        dst[j] = src[j];
        j++;
    }       
}


void my_strclear(char *str, unsigned int len)
{
    unsigned int j;
    for(j=0; j<len; j++)str[j]=0;  
}

unsigned int get_F_position(char *str)
{
    unsigned int i=0;
    while(str[i] != 'F')
    {
        i++;
        if( i >6)break;
    }
    return i;
}


void readCardID(void)
{
      unsigned int i, p;
      char chr;
      
      /* clear the read buffer */
      my_strclear(readBuf, RESPONSE_LENGTH);
        
      pc.printf("Send the READ command!\n\r");//, &readCmd[1]);
      if(cm_rs485.writeable()){
            for(i=0; i<COMMAND_LENGTH; i++){
               cm_rs485.putc(readCmd[i]);
            }            
      }
      
      /* read the response */
      chr = cm_rs485.getc();
      i = 0;
      while(chr != 0x0d)
      {
            readBuf[i] = chr;
            i++;
            chr = cm_rs485.getc();
      }  
        
      /* print the response for debug */
      pc.printf("Response[ASCII]:");
        
      for(i=0; i< RESPONSE_LENGTH; i++){
           pc.printf("%0X ", readBuf[i]);
           if (readBuf[i] == 0) break;
      } 
       
      p = get_F_position(readBuf);
      pc.printf("P=%d\n\r", p);
      pc.printf("Response[Text]:%s\n\r", &readBuf[p+1]);
      /* add to ringBuffer if valid */ 
      if((p != 0) && (readBuf[p+1] != '3') && (readBuf[p+2] !='C')) //valid response
      {
          my_strcpy(ringBuffer[inIndex], &readBuf[p+1]); //strim the 3 bytes prehead
          //pc.printf("addr = 0x%0X, inIndex = %d\n\r", &ringBuffer[inIndex],inIndex);
          inIndex++;
          if(inIndex >= RINGBUFFER_SIZE) inIndex = 0;
          if(ringBuffer[inIndex][0] != 0)  //is not empty
          {
              pc.printf("Warning! Ringbuffer overflow at [%d]!\n\r", inIndex);
              pc.printf("Please have a check of the network!\n\r");
              pc.printf("Data in ring buffer:\n\r");
              for(i=0; i<RINGBUFFER_SIZE; i++)
              {
                  pc.printf("Data[%d]: %s \n\r", i, ringBuffer[i]);
              }
              
              wait(10); //in seconds
          }
     }
}

void sendCardID(void)
{
    int32_t ret;
    
    //pc.printf("Send Tick!\n\r");
    /*send the data */
    if(ringBuffer[outIndex][0] != 0) //not empty
    {
        pc.printf("Send dada[%s] to Gateway!\n\r", ringBuffer[outIndex]);
      #ifndef NO_MULTITECH_GATEWAY  
        /* t.b.d : send data though LoRA */
        if(send_data(ringBuffer[outIndex]) != RETURN_OK)
        {
           pc.printf("Failed to send data to netwotk!\n\r");
           pc.printf("Rejoin network and try one more time!\n\r");
                       // attempt to rejoin the network
           pc.printf("Attemp to rejoin network....\n\r");
           if ((ret = dot->joinNetworkOnce()) != mDot::MDOT_OK) {
                pc.printf("Failed to rejoin network! %d:%s \n\r", ret, mDot::getReturnCodeString(ret).c_str());
                return;
           }else{
                pc.printf("Rejoin network successfully!");
                if(send_data(ringBuffer[outIndex]) != RETURN_OK) return;  //abort to send       
           } 
        }
       #endif 
        //clear the buffer
        my_strclear(ringBuffer[outIndex], RESPONSE_LENGTH);
        outIndex++;
        if(outIndex >= RINGBUFFER_SIZE)outIndex = 0;
    }else{ //empty
        pc.printf("Nothing to send!\n\r");
        //wait(10);
    }
    
}