野牛NBIOT 環境監測專案---裝置端篇(STM32L4+BC35)(五)
阿新 • • 發佈:2018-12-18
本章節主要介紹《01-基於NBIOT技術的環境監測與控制》工程例子 注意,該例程與野牛NBIOT 環境監測專案—華為OceanConnect雲平臺配置(四)中的profile是配套的,如果profile的相關資料格式發生變化,這裡需要同步調整程式碼,初學的同學們可以先把整個例程跑通,再一點一點消化,按照自己的專案需求修改Profile以及微控制器原始碼。 1、例程簡介 本微控制器例程STM32L4通過SHT20(I2C介面)感測器採集溫溼度、光敏電阻(ADC)獲取環境光照、OLED(SPI介面)顯示當前狀態、BC35 NBIOT模組(UART介面)上報/接收資料,實現對整個環境引數的週期性上報。 2、硬體設計
- 程式碼框架 針對各個模組,提供不同的介面,比如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中的各種介面即可。
- 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); }
- 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); }
- 主函式 主函式裡面,先初始化各個模組,包括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 淘寶店鋪(點選跳轉連結)