From 65cb76457e892025bd6d31aeb515919f387c86c4 Mon Sep 17 00:00:00 2001 From: YunHorn Technology Date: Thu, 14 Dec 2023 19:21:14 +0800 Subject: [PATCH] refine upload data and format with position X, Y, spot cnt, spillage level --- Core/Inc/yunhorn_sts_sensors.h | 10 ++-- LoRaWAN/App/lora_app.c | 60 ++++++++++++++++------- mlx90640/mlx90640_lcd_display.c | 86 +++++++++++++++++++++++++++------ 3 files changed, 120 insertions(+), 36 deletions(-) diff --git a/Core/Inc/yunhorn_sts_sensors.h b/Core/Inc/yunhorn_sts_sensors.h index c130e7d..899256d 100644 --- a/Core/Inc/yunhorn_sts_sensors.h +++ b/Core/Inc/yunhorn_sts_sensors.h @@ -244,10 +244,14 @@ typedef struct float maxTemp; /* 0-120 C */ float minTemp; /* 0-120 C */ float centerTemp; /* 0-120 C */ - uint8_t v_water_cnt; /* 0-31 */ - uint8_t h_water_cnt; /* 0-63 */ + uint8_t spot_cnt; /* 0-20 max of v_water_cnt h_water_cnt */ + uint8_t spillage_level; /* 0-99%, out of 768 dots */ + uint8_t v_water_cnt; + uint8_t h_water_cnt; - uint8_t waterSpillMatrix[64][32]; /* temp matrix or mark */ + //uint8_t waterSpillMatrix[32][24]; /* temp matrix or mark */ + uint8_t upMask[80]; /* 0-80 origin value, 100-110, upload values */ + uint8_t order[80]; /* x, y of water in 10*8 matrix */ uint16_t battery_mV; /*mV, 1000mv-5000mv, regular 3300mV - 3600mV --4200mV */ uint8_t on_off_event; /* 1: liquid sensed, 0: no liquid sensed */ diff --git a/LoRaWAN/App/lora_app.c b/LoRaWAN/App/lora_app.c index 3ffd420..3a0e633 100644 --- a/LoRaWAN/App/lora_app.c +++ b/LoRaWAN/App/lora_app.c @@ -488,7 +488,7 @@ void LoRaWAN_Init(void) /* USER CODE END LoRaWAN_Init_LV */ /* USER CODE BEGIN LoRaWAN_Init_1 */ - APP_LOG(TS_OFF, VLEVEL_M, "\r\n\n\n##### YUNHORN_STS_FW:%d SWV%d HWV:%d MTM:%d.%d R:%d.%d.%d ####\r\n\n\n", + APP_LOG(TS_OFF, VLEVEL_H, "\r\n\n\n##### YUNHORN_STS_FW:%d SWV%d HWV:%d MTM:%d.%d R:%d.%d.%d ####\r\n\n\n", FirmwareVersion, sts_version, sts_hardware_ver, sts_mtmcode1,sts_mtmcode2, MajorVer, MinorVer, SubMinorVer); /* Get LoRaWAN APP version*/ @@ -808,7 +808,7 @@ static void SendTxData(void) #endif UTIL_TIMER_Time_t nextTxIn = 0; -// if (LmHandlerIsBusy() == false) + if (LmHandlerIsBusy() == false) { uint8_t i = 0; //MX_TOF_Process(); @@ -903,27 +903,31 @@ static void SendTxData(void) // AppData.Buffer[i++] = (uint8_t)(r0_data.battery_mV)&0xff; //#13 #endif #ifdef STS_TMG - AppData.Buffer[i++] = (uint8_t)(12)&0xff; //#length of following bytes - AppData.Buffer[i++] = (uint8_t)(m1a_data.waterSpillCount>>8)&0xff; //#01 - AppData.Buffer[i++] = (uint8_t)(m1a_data.waterSpillCount)&0xff; //#02 + AppData.Buffer[i++] = (uint8_t)(14)&0xff; //#length of following bytes + AppData.Buffer[i++] = (uint8_t)(m1a_data.waterSpillCount)&0xff; //#01 + AppData.Buffer[i++] = (uint8_t)(m1a_data.spillage_level)&0xff; //#02 - AppData.Buffer[i++] = (uint8_t)(m1a_data.v_water_cnt)&0xff; //#3 - AppData.Buffer[i++] = (uint8_t)(m1a_data.h_water_cnt)&0xff; //#4 + AppData.Buffer[i++] = (uint8_t)(m1a_data.order[0])&0xff; //#03 non zero value is valid + AppData.Buffer[i++] = (uint8_t)(m1a_data.order[1])&0xff; //#04 + AppData.Buffer[i++] = (uint8_t)(m1a_data.order[2])&0xff; //#05 + AppData.Buffer[i++] = (uint8_t)(m1a_data.order[3])&0xff; //#06 - AppData.Buffer[i++] = (uint8_t)((int)m1a_data.averageTemp)&0xff; //#5 - AppData.Buffer[i++] = (uint8_t)(((int)(m1a_data.averageTemp*100))%100)&0xff; //#6 + AppData.Buffer[i++] = (uint8_t)((int)m1a_data.minTemp)&0xff; //#7 + AppData.Buffer[i++] = (uint8_t)(((int)(m1a_data.minTemp*100))%100)&0xff; //#8 - AppData.Buffer[i++] = (uint8_t)((int)m1a_data.centerTemp)&0xff; //#7 - AppData.Buffer[i++] = (uint8_t)(((int)(m1a_data.centerTemp*100))%100)&0xff; //#8 + AppData.Buffer[i++] = (uint8_t)((int)m1a_data.averageTemp)&0xff; //#9 + AppData.Buffer[i++] = (uint8_t)(((int)(m1a_data.averageTemp*100))%100)&0xff; //#10 - AppData.Buffer[i++] = (uint8_t)((int)m1a_data.minTemp)&0xff; //#9 - AppData.Buffer[i++] = (uint8_t)(((int)(m1a_data.minTemp*100))%100)&0xff; //#10 - - AppData.Buffer[i++] = (uint8_t)((int)m1a_data.maxTemp)&0xff; //#11 + AppData.Buffer[i++] = (uint8_t)((int)m1a_data.maxTemp)&0xff; //#11 AppData.Buffer[i++] = (uint8_t)(((int)(m1a_data.maxTemp*100))%100)&0xff; //#12 + AppData.Buffer[i++] = (uint8_t)((int)m1a_data.centerTemp)&0xff; //#13 + AppData.Buffer[i++] = (uint8_t)(((int)(m1a_data.centerTemp*100))%100)&0xff; //#14 + + + #endif @@ -1059,7 +1063,22 @@ static void OnJoinRequest(LmHandlerJoinParams_t *joinParams) STS_LoRa_WAN_Joined = (uint8_t) joinParams->Mode; OnYunhornSTSHeartBeatPeriodicityChanged(HeartBeatPeriodicity); - OnTxPeriodicityChanged(TxPeriodicity); + + /* + uint32_t periodicity = (sts_cfg_nvm.periodicity); //TxPeriodicty interval + if ((char)sts_cfg_nvm.unit =='M') { + periodicity *= 60; + } else if ((char) sts_cfg_nvm.unit =='H') { + periodicity *= 3600; + } else if ((char) sts_cfg_nvm.unit =='S') { + periodicity *= 1; + } + + TxPeriodicity= periodicity*1000; // to ms + + OnTxPeriodicityChanged(TxPeriodicity); TO-DO XXXXX + */ + APP_LOG(TS_OFF, VLEVEL_H,"\r\n STS_LoRa_WAN_Joined = %s \r\n", (STS_LoRa_WAN_Joined == 1)?"ABP":"OTAA"); } else @@ -2094,13 +2113,18 @@ void OnRestoreSTSCFGContextProcess(void) samplingperiodicity *= 1; } + OnTxPeriodicityChanged(APP_TX_DUTYCYCLE); // in msec unit + if ((sts_cfg_nvm.ac[0] ==0x0 )&& (sts_cfg_nvm.ac[19]==0x0)) { - OnTxPeriodicityChanged(APP_TX_DUTYCYCLE); // in msec unit + //OnTxPeriodicityChanged(APP_TX_DUTYCYCLE); // in msec unit OnYunhornSTSHeartBeatPeriodicityChanged(HeartBeatPeriodicity); } else { // ensure it's not in production yet - OnTxPeriodicityChanged(TxPeriodicity); // in msec unit + if (STS_LoRa_WAN_Joined) + { + OnTxPeriodicityChanged(TxPeriodicity); // in msec unit + } //Heart-beat or Sampling interval samplingperiodicity = (samplingperiodicity > 0)? samplingperiodicity : 1; // in seconds unit HeartBeatPeriodicity = samplingperiodicity*1000; diff --git a/mlx90640/mlx90640_lcd_display.c b/mlx90640/mlx90640_lcd_display.c index 2dfea4b..86a3f43 100644 --- a/mlx90640/mlx90640_lcd_display.c +++ b/mlx90640/mlx90640_lcd_display.c @@ -20,7 +20,7 @@ paramsMLX90640 mlx90640; static uint16_t eeMLX90640[832]; int status; -volatile uint8_t draw_legend_once=0, normalPeopleTemp=32, blackOutTag=0, waterTempThreshold=20, normalWaterTemp=25, detectCycle=0, v_water_cnt=0,h_water_cnt=0; +volatile uint8_t draw_legend_once=0, normalPeopleTemp=32, blackOutTag=0, waterTempThreshold=20, normalWaterTemp=25, detectCycle=0, v_water_cnt=0,h_water_cnt=0, spot_cnt=0; // start with some initial colors volatile float minTemp = -20.0f; volatile float maxTemp = 120.0f; @@ -38,7 +38,7 @@ int x, y, i, j; // array for the 32 x 24 measured tempValues static float tempValues[32*24]; -volatile uint8_t zoneMask[32*24]={0x0}, edgeMask[32*24]={0x0}; +volatile uint8_t zoneMask[32*24]={0x0}, edgeMask[32*24]={0x0}, upMask[10*8]={0x0}; volatile STS_M1A_SensorDataTypeDef m1a_data; void blackOutFilter(void); static uint16_t TempToColor(float val); @@ -48,6 +48,8 @@ static void drawLegend(void); static void drawMeasurement(void); static void drawPicture(void); static void readTempValues(void); +static void bubbleSort(uint8_t arr[], uint8_t len, uint8_t order[]); + extern LCD_DrawPropTypeDef DrawProp; static uint16_t TempToColor(float val) { @@ -200,7 +202,6 @@ static void drawMeasurement(void ) { static void drawPicture(void) { uint8_t h_cnt[32]={0},v_cnt[24]={0}; //for horizon and vertical _water spill count - // start from 2, ignore edge of FOV for (y=2; y<23; y++) { @@ -212,6 +213,8 @@ static void drawPicture(void) if (zoneMask[y*32+x] > 3) { APP_LOG(TS_OFF,VLEVEL_L,"\r\n X=%d Y=%d Count=%d\r\n",x,y,zoneMask[y*32+x]); + + #if 0 BSP_LCD_FillRect(x*8, y*11+16, 4, 4, LCD_COLOR_GREEN); #endif @@ -258,6 +261,9 @@ static void drawPicture(void) } h_water_cnt = h_1 + h_2; + spot_cnt = max(h_water_cnt, v_water_cnt); + APP_LOG(TS_OFF, VLEVEL_L, " H cnt = %2u V cnt =%2u Spot Cnt=%2u \r\n", h_water_cnt, v_water_cnt, spot_cnt); + } // Read pixel data from MLX90640. @@ -284,7 +290,7 @@ static void readTempValues(void) void blackOutFilter(void) { float temp1=0.0, temph1=0.0, tempv1=0.0; - +/* if (maxTemp < normalPeopleTemp) { blackOutTag =0; @@ -292,7 +298,7 @@ void blackOutFilter(void) { blackOutTag =1; } - +*/ // ignore edge of FOV waterSpillCount =0; for (y=2; y<22; y++) @@ -321,6 +327,7 @@ void blackOutFilter(void) if (blackOutTag == 0) { zoneMask[y*32+x] ++; + upMask[(x/3+1)*(y/3+1)] ++; //translate to 10*8 matrix for upload waterSpillCount ++; } } @@ -333,6 +340,7 @@ void blackOutFilter(void) memset((void *)zoneMask,0,sizeof(zoneMask)); memset((void *)edgeMask, 0, sizeof(edgeMask)); + memset((void *)upMask, 0, sizeof(upMask)); } @@ -341,21 +349,46 @@ void blackOutFilter(void) void STS_M1A_SENSOR_Read(STS_M1A_SensorDataTypeDef *m1a_data) { - memset(tempBuffer,0,sizeof(tempBuffer)); - sprintf(tempBuffer,(char *)"Read Sensor M1A data %4d average=%2.2fC center=%2.2fC min=%2.2fC max=%2.2fC V_cnt=%2u H_cnt=%2u \r\n", - (int)waterSpillCount, (float)averageTemp, (float)centerTemp, (float)minTemp, (float)maxTemp, (uint8_t)v_water_cnt, (uint8_t)h_water_cnt); - - APP_LOG(TS_OFF, VLEVEL_M,(char *)tempBuffer); - - + uint8_t order[80]; m1a_data->waterSpillCount = waterSpillCount; + m1a_data->spillage_level = (uint8_t)((int)waterSpillCount*99/560)&0xff; // (24-4) * (32 -4) minus edge dots m1a_data->averageTemp = averageTemp; m1a_data->centerTemp = centerTemp; m1a_data->minTemp = minTemp; m1a_data->maxTemp = maxTemp; - m1a_data->v_water_cnt = v_water_cnt; m1a_data->h_water_cnt = h_water_cnt; + m1a_data->spot_cnt = max(v_water_cnt, h_water_cnt); + + + //memcpy((void *)m1a_data->waterSpillMatrix,(const void *) zoneMask,sizeof(zoneMask)); + + if (waterSpillCount != 0) { + bubbleSort((uint8_t*)upMask, 80, (uint8_t*)order); + for (uint8_t i= waterSpillCount; i<80;i++) { + order[i] = 0; + } + } + + memcpy((void *)m1a_data->order, (const void *)order, sizeof(order)); + + //memset(order + m1a_data->spot_cnt, 0x0, sizeof(tempBuffer)-m1a_data->spot_cnt); // fill non-spot position to zero + + memset(tempBuffer,0,sizeof(tempBuffer)); + + sprintf(tempBuffer,(char *)"Read Sensor Spot CNT=%4d V_cnt=%2d H_cnt=%2d Spillage Level =%2d average=%2.2fC center=%2.2fC min=%2.2fC max=%2.2fC \r\n", + m1a_data->waterSpillCount, v_water_cnt, h_water_cnt, m1a_data->spillage_level, (float)averageTemp, (float)centerTemp, (float)minTemp, (float)maxTemp); + APP_LOG(TS_OFF, VLEVEL_L,(char *)tempBuffer); + + + if (m1a_data->waterSpillCount !=0 ) + { + for (uint8_t i=0; i< 4; i++) { + memset(tempBuffer,0,sizeof(tempBuffer)); + sprintf(tempBuffer, (char *) " Top {%1d} =%1u:%1u \r\n", i, (uint8_t)(order[i]/10), (uint8_t)(order[i]%10)); + APP_LOG(TS_OFF, VLEVEL_L,(char *)tempBuffer); + } + } sensor_data_ready = 1; } @@ -365,8 +398,9 @@ void mlx90640_display_process(void) readTempValues(); setTempScale(); blackOutFilter(); + drawPicture(); -#if 1 +#if 0 if (blackOutTag == 0) { //BSP_LCD_DisplayOn(); @@ -383,7 +417,7 @@ void mlx90640_display_process(void) //BSP_LCD_DisplayOff(); } #endif - APP_LOG(TS_OFF, VLEVEL_M, "Water Spill Detected Level = %d of 600 \r\n", waterSpillCount); + APP_LOG(TS_OFF, VLEVEL_L, "Water Spill Detected Level = %d of 600 \r\n", waterSpillCount); } void mlx90640_display_init(void){ @@ -396,3 +430,25 @@ void mlx90640_display_init(void){ if (status != 0) APP_LOG(TS_OFF, VLEVEL_L, "\r\nParameter extraction failed with error code:%d\r\n",status); } + +static void bubbleSort(uint8_t arr[], uint8_t len, uint8_t order[]) +{ + uint8_t i, j, temp, t1; + for (j=0; j < len ; j++) { + order[j] = 1+j; + } + for (i = 0; i < len - 1; i++) { + for (j = 0; j < len - i - 1; j++) { + if (arr[j] < arr[j + 1]) { + temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + + t1 = order[j]; + order[j]=order[j+1]; + order[j+1]=t1; + } + } + } +} +