野牛NBIOT 环境监测项目---设备端篇(STM32L4+BC35)(五)

本章节主要介绍《01-基于NBIOT技术的环境监测与控制》工程例子
注意,该例程与野牛NBIOT 环境监测项目—华为OceanConnect云平台配置(四)中的profile是配套的,如果profile的相关数据格式发生变化,这里需要同步调整代码,初学的同学们可以先把整个例程跑通,再一点一点消化,按照自己的项目需求修改Profile以及单片机源码。
1、例程简介
本单片机例程STM32L4通过SHT20(I2C接口)传感器采集温湿度、光敏电阻(ADC)获取环境光照、OLED(SPI接口)显示当前状态、BC35 NBIOT模块(UART接口)上报/接收数据,实现对整个环境参数的周期性上报。
2、硬件设计
野牛NBIOT 环境监测项目---设备端篇(STM32L4+BC35)(五)_第1张图片野牛NBIOT 环境监测项目---设备端篇(STM32L4+BC35)(五)_第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
淘宝店铺(点击跳转链接)

你可能感兴趣的:(野牛NBIOT 环境监测项目---设备端篇(STM32L4+BC35)(五))