1. 程式人生 > >野牛NBIOT 環境監測專案---裝置端篇(STM32L4+BC35)(五)

野牛NBIOT 環境監測專案---裝置端篇(STM32L4+BC35)(五)

本章節主要介紹《01-基於NBIOT技術的環境監測與控制》工程例子 注意,該例程與野牛NBIOT 環境監測專案—華為OceanConnect雲平臺配置(四)中的profile是配套的,如果profile的相關資料格式發生變化,這裡需要同步調整程式碼,初學的同學們可以先把整個例程跑通,再一點一點消化,按照自己的專案需求修改Profile以及微控制器原始碼。 1、例程簡介 本微控制器例程STM32L4通過SHT20(I2C介面)感測器採集溫溼度、光敏電阻(ADC)獲取環境光照、OLED(SPI介面)顯示當前狀態、BC35 NBIOT模組(UART介面)上報/接收資料,實現對整個環境引數的週期性上報。 2、硬體設計

在這裡插入圖片描述在這裡插入圖片描述 3、軟體設計

  1. 程式碼框架 針對各個模組,提供不同的介面,比如NBIOT BC35/95模組,分為nb_bc95.c、nb_at.c兩個板塊,nb_at.c主要提供NB模組的AT指令底層,包括AT命令收發、UART驅動程式碼;nb_bc95.c提供各個AT指令介面,如獲取訊號強度、獲取IMEI號、CoAP傳送資料等,同時解析AT指令的返回值,擷取有用資訊返回上一層;使用者只要呼叫nb_bc95.c中的各種介面即可。
  2. NBIOT BC35/95程式碼(片段)
uint8_t NBBCxx_getNBAND( void )
{
   uint8_t res = 0;
   res = NBAT_sendCmd( "AT+NBAND?\r\n", "OK", 100, atRxBuf );
   if ( res == 0 )
   {
       printf( "[INFO]GETNBAND RESPONSE SUCCESS\r\n" );
       printf( "[INFO]RESPONSE IS %s\r\n", atRxBuf );
   }
   return (res);
}

uint8_t NBBCxx_getCSQ( u8* csq )
{
   uint8_t res = 0;
   res = NBAT_sendCmd( "AT+CSQ\r\n", "OK", 100, atRxBuf );
   if ( res == 0 )
   {
       /*獲取CSQ */
       uint8_t csqTmp = (atRxBuf[7] - 0x30) * 10 + (atRxBuf[8] - 0x30);
       if ( csqTmp == 99 )
       {
           printf( "[ERROR]GETCSQ Fail\n" );
           return (3);
       }
       if ( csq != NULL )
           *csq = csqTmp;
   }
   else
   {
       printf( "[INFO]AT RESPONSE FAIL\r\n" );
   }
   return (res);
}

/*通過COPA協議傳送資料 */
uint8_t NBBCxx_setNMGS_char( char *inData )
{
   uint8_t res = 0;
   sprintf( atTxBuf, "AT+NMGS=%d,%s\r\n", strlen( inData ) / 2, inData );
   res = NBAT_sendCmd( atTxBuf, "OK", 2000, atRxBuf );
   if ( res == 0 )
   {
       printf( "[INFO]SETNMGS RESPONSE SUCCESS\r\n" );
   }
   return (res);
}

  1. SHT20感測器程式碼(片段) 程式碼中提供兩個介面,分別是float SHT20_getTemp( void );float SHT20_getHumidity( void );使用者只需要初始化SHT20感測器之後,呼叫這兩個介面,即可獲取到溫溼度資料。
static uint8_t SHT2x_MeasureHM( etSHT2xMeasureType eSHT2xMeasureType, nt16 *pMeasurand )
{
   uint8_t		checksum;                   /*checksum */
   uint8_t		data[2];                    /*data array for checksum verification */
   uint8_t		error = 0;                  /*error variable */
   uint16_t	i;                          /*counting variable */

   I2c_startCondition();
   error |= I2C_writeByte( I2C_ADR_W );    /* I2C Adr */
   switch ( eSHT2xMeasureType )
   {
   case HUMIDITY:
       error |= I2C_writeByte( TRIG_RH_MEASUREMENT_HM );
       break;
   case TEMP:
       error |= I2C_writeByte( TRIG_T_MEASUREMENT_HM );
       break;
   default:
       return (6);
   }
   I2c_stopCondition();

   I2c_startCondition();
   error |= I2C_writeByte( I2C_ADR_R );
   SHT20_SCL( 1 );             /* set SCL I/O port as input */
   for ( i = 0; i < 100; i++ ) /* wait until master hold is released or */
   {
       DELAY_us( 1000 );       /* a timeout (~1s) is reached */
       if ( SHT20_SCL_Read )
           break;
   }
   if ( SHT20_SCL_Read == 0 )
       error |= TIME_OUT_ERROR;


   pMeasurand->s16.u8H = data[0] = I2C_readByte( ACK );
   pMeasurand->s16.u8L = data[1] = I2C_readByte( ACK );
   checksum			= I2C_readByte( NO_ACK );

   /*-- verify checksum -- */
   error |= SHT2x_checkCrc( data, 2, checksum );
   I2c_stopCondition();
   DELAY_us( 1000 );
   return (error);
}

/*獲取溼度 */
float SHT20_getHumidity( void )
{
   uint8_t error = 0;
   nt16	sRH;
   float	humidityRH;

   error		|= SHT2x_MeasureHM( HUMIDITY, &sRH );
   humidityRH	= SHT2x_calcRH( sRH.u16 );
   return (humidityRH);
}

/*獲取溫度 */
float SHT20_getTemp( void )
{
   uint8_t error = 0;

   float	temperatureC;
   nt16	sT;
   error			|= SHT2x_MeasureHM( TEMP, &sT );
   temperatureC	= SHT2x_calcTemperatureC( sT.u16 );
   return (temperatureC);
}
  1. 主函式 主函式裡面,先初始化各個模組,包括LED、SHT20感測器、光敏感測器、NBIOT BC35模組、OLED模組、TIME6定時器。通過TIME6來設定迴圈週期,預設是5秒,獲取訊號強度、採集溫溼度、光照感測器資料、更新OLED資料、、檢查是否接收到命令、上報資料。具體程式碼如下:
int main( void )
{
    HAL_Init();
    SystemClock_Config();
    DELAY_init( 80 );
    MX_GPIO_Init();
    MX_USART1_UART_Init();
    LED_init();
    printf( "**********************Welcome Nbiot**********************\r\n" );
    printf( "**********************BC35   demo************************\r\n" );
    DELAY_ms( 100 );

    uint8_t stup	= 0;
    uint8_t res		= 0;
    uint8_t cnt		= 0;
    uint8_t csq		= 0;
    float	lightLx = 0;
    char	tmpBuf1[512];
    char	tmpBuf2[512];

    float	humidityRH		= 0.0;
    float	temperatureC	= 0.0;

    u8g2_t			u8g2;
    OLEDInfoTypeDef showInfo;

    /*init */
    DEBUG_init();
    DEBUG_switch( DEBUG_INDEX_1, DEBUG_STATE_TOGGLE, 10 );

    LED_init();
    ADC_init();
    SHT20_init();
    NBBCxx_init();
    TIM6_init();
    /*ADC LIGHT */
    ADC_addChannel( ADC_DEVICE_BAT );
    ADC_addChannel( ADC_DEVICE_LIGHT );
    HAL_TIM_Base_Start( &htim6 );

    /*U8G2 */
    showInfo.cnt		= 1;
    showInfo.humidity	= 57.2;
    showInfo.temp		= 27.5;
    showInfo.lx			= 57;
    showInfo.vbat		= 34.2;
    showInfo.csq		= 11;
    u8g2_init( &u8g2 );
    u8g2_updata( &u8g2, &showInfo );

    DELAY_ms( 100 );

    /*NBIOT start */
    cnt = 10;
    do
    {
        res = NBBCxx_checkModel();
    }
    while ( (cnt--) != 0 && (res != 0) );
    REQUIRE_noErr( res != 0x00, error, stup = 1 );

    res = NBBCxx_setCMEE();
    REQUIRE_noErr( res != 0x00, error, stup = 2 );

    res = NBBCxx_getNBAND();
    REQUIRE_noErr( res != 0x00, error, stup = 3 );

    res = NBBCxx_getCIMI();
    REQUIRE_noErr( res != 0x00, error, stup = 4 );

    res = NBBCxx_setCGATT();
    REQUIRE_noErr( res != 0x00, error, stup = 5 );

    res = NBBCxx_getCSQ( NULL );
    REQUIRE_noErr( res != 0x00, error, stup = 6 );

    cnt = 10;
    do
    {
        res = NBBCxx_getCEREG();
    }
    while ( (cnt--) != 0 && (res != 0) );
    REQUIRE_noErr( res != 0x00, error, stup = 7 );

    res = NBBCxx_setCEREG();
    REQUIRE_noErr( res != 0x00, error, stup = 8 );

    res = NBBCxx_getCOPS();
    REQUIRE_noErr( res != 0x00, error, stup = 9 );

    /*pdpact */
    res = NBBCxx_setCGDCONT();
    REQUIRE_noErr( res != 0x00, error, stup = 10 );

    res = NBBCxx_setCGATT();
    REQUIRE_noErr( res != 0x00, error, stup = 11 );

    res = NBBCxx_getCGATT();
    REQUIRE_noErr( res != 0x00, error, stup = 12 );

    res = NBBCxx_getCSCON();
    REQUIRE_noErr( res != 0x00, error, stup = 13 );

    /*coap */
    res = NBBCxx_setNCDP( HUAWEI_COAP_IP );
    REQUIRE_noErr( res != 0x00, error, stup = 14 );
    cnt = 0;
    HAL_TIM_Base_Start( &htim6 );
    while ( 1 )
    {
        memset( tmpBuf1, 0x00, sizeof(tmpBuf1) );
        memset( tmpBuf2, 0x00, sizeof(tmpBuf2) );

        printf( "\r\n**********************************************\r\n" );
        printf( "[INFO]NBIOT DEMO %d\r\n", cnt );

        /*開啟LED燈 */
        LED_set( LED_INDEX_1, LED_STATE_ON );

        /*獲取光照強度 */
        lightLx = ADC_getLightLx();

        /*獲取溫度 */
        humidityRH		= SHT20_getHumidity();
        temperatureC	= SHT20_getTemp();

        bc95B5_recvCmdHandling();

        /*獲取NB訊號強度 */
        res = NBBCxx_getCSQ( &csq );
        REQUIRE_noErr( res != 0x00, error, stup = 15 );

        /*更新OLED */
        showInfo.cnt		= cnt;
        showInfo.humidity	= humidityRH;
        showInfo.temp		= temperatureC;
        showInfo.lx			= lightLx;
        showInfo.vbat		= 00.0;
        showInfo.csq		= csq;
        u8g2_updata( &u8g2, &showInfo );

        bc95B5_recvCmdHandling();

        printf( "[INFO]SEND DATA IS %2.1f %2.1f %2.1f\r\n", temperatureC, humidityRH, lightLx );

        sprintf( tmpBuf1, "%2.1f%2.1f%2.1f", temperatureC, humidityRH, lightLx );
        memset( tmpBuf2, 0x00, sizeof(tmpBuf2) );
        hexToStr( tmpBuf1, tmpBuf2 );

        /*COAP資料上傳 */
        res = NBBCxx_setNMGS_char( tmpBuf2 );
        REQUIRE_noErr( res != 0x00, error, stup = 15 );

        /*關閉LED燈 */
        LED_set( LED_INDEX_1, LED_STATE_OFF );
        memset( tmpBuf1, 0x00, sizeof(tmpBuf1) );

        if ( cnt > 50 )
        {
            break;
        }
        cnt++;

        res = 0;
        while ( timeOutFlage == 0 )
        {
            bc95B5_recvCmdHandling();
        }
        timeOutFlage = 0;
    }
    printf( "[INFO]BC95 TEST SUCCESS\r\n" );
    return (0);
error:
    printf( "[ERROR]BC95 TEST ERROR STUP IS %d\r\n", stup );
    return (1);
}

有問題可以加入QQ群或者淘寶店鋪旺旺聯絡: 野牛物聯網 QQ交流群:897268542 淘寶店鋪(點選跳轉連結)