Sandwich IoT
Published © GPL3+

Prototype NB-IoT Smart Contact Sensors (MCU Control)

This demo describes how to prototype an NB-IoT module based smart contact sensor with Tuya Sandwich development board, implementing two basi

BeginnerFull instructions provided12 hours144
Prototype NB-IoT Smart Contact Sensors (MCU Control)

Things used in this project

Hardware components

Tuya Sandwich NB-IoT communication board (NM1)
Provide pairing capability in collaboration with the MCU.
×1
Tuya Sandwich function board of contact sensor
Determine the open and closed status by the logic levels generated by moving the magnet close to or away from the reed switch.
×1
NUCLEO-G71RB
×1

Story

Read more

Code

Code snippet #1

Plain text
// Sensor report flag 
typedef enum
{ 
STATE_IDLE = 0,
STATE_DOOR_NEED_UP = 1  
}

sensor_state_t;
// Open and closed status 
typedef enum
{
STATE_CLOSE = 0,
STATE_OPEN = 1  
}

door_state_t;
typedef struct
{ 
door_state_t door_state;         
sensor_state_t sensor_state;
unsigned char door_up_lock;      
// Status reporting lock unsigned char remaining_power;   
// Remaining battery level in percentage 
}
device_status_t;

Code snippet #10

Plain text
void enter_lowpower_mode()
{  
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_SET);
lowpower_gpio_init();
HAL_ADC_Stop(&hadc1);
HAL_ADC_DeInit(&hadc1);
HAL_UART_DeInit(&huart3);
// HAL_TIM_Base_DeInit(&htim3);

// Turn off the clock 
__HAL_RCC_DMA1_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();          
__HAL_RCC_GPIOD_CLK_DISABLE();
__HAL_RCC_GPIOF_CLK_DISABLE();
HAL_SuspendTick();

// Enter STOP mode 
HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_STOPENTRY_WFI);
}

void leave_lowpower_mode()
{
SystemClock_Config();
MX_GPIO_Init();

// MX_TIM3_Init();
MX_USART3_UART_Init();
__HAL_UART_ENABLE_IT(&huart3, UART_IT_RXNE);
MX_ADC1_Init();
HAL_ADC_Start(&hadc1);

// Pull down the pin to wake up NB-IoT module 
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_RESET);

// The sensor needs to report the door status 
device_status_s.sensor_state = STATE_DOOR_NEED_UP;
}

Code snippet #11

Plain text
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) 
{   
leave_lowpower_mode();  
device_status_s.door_state = STATE_OPEN;  
}

void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{  
leave_lowpower_mode();  
device_status_s.door_state = STATE_CLOSE;  
}

Code snippet #12

Plain text
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) 
{   
leave_lowpower_mode();  
device_status_s.door_state = STATE_OPEN;  
}

void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{  
leave_lowpower_mode();  
device_status_s.door_state = STATE_CLOSE;  
}

Code snippet #13

Plain text
// Working status 
case NBIOT_STATE_CMD:
nbiot_work_state = nbiot_uart_rx_buf[offset + DATA_START];
nbiot_uart_write_frame(NBIOT_STATE_CMD,0);

if (STATE_DOOR_NEED_UP == mcu_get_nbiot_work_state()) 
   {  
   mcu_dp_bool_update(DPID_DOORCONTACT_STATE, device_status_s.door_state);
   device_status_s.sensor_state = STATE_IDLE; 
   }   
break;

Code snippet #14

Plain text
// Working status 
case NBIOT_STATE_CMD:
nbiot_work_state = nbiot_uart_rx_buf[offset + DATA_START];
nbiot_uart_write_frame(NBIOT_STATE_CMD,0);

if (STATE_DOOR_NEED_UP == mcu_get_nbiot_work_state()) 
   {  
   mcu_dp_bool_update(DPID_DOORCONTACT_STATE, device_status_s.door_state);
   device_status_s.sensor_state = STATE_IDLE; 
   }   
break;

Code snippet #15

Plain text
case STATE_UPLOAD_CMD: 

// Evaluate the result value. Enable the door status reporting lock and prepare for the next report after the information returned by the module is received. 
device_status_s.door_up_lock=1;
break;

Code snippet #16

Plain text
case STATE_UPLOAD_CMD: 

// Evaluate the result value. Enable the door status reporting lock and prepare for the next report after the information returned by the module is received. 
device_status_s.door_up_lock=1;
break;

Code snippet #2

Plain text
// Sensor report flag 
typedef enum
{ 
STATE_IDLE = 0,
STATE_DOOR_NEED_UP = 1  
}

sensor_state_t;
// Open and closed status 
typedef enum
{
STATE_CLOSE = 0,
STATE_OPEN = 1  
}

door_state_t;
typedef struct
{ 
door_state_t door_state;         
sensor_state_t sensor_state;
unsigned char door_up_lock;      
// Status reporting lock unsigned char remaining_power;   
// Remaining battery level in percentage 
}
device_status_t;

Code snippet #3

Plain text
nbiot_protocol_init();

// Enable low power mode clock 
__HAL_RCC_PWR_CLK_ENABLE();

// Initialize wake-up pin level of the NB-IoT module 
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_SET);

Code snippet #4

Plain text
nbiot_protocol_init();

// Enable low power mode clock 
__HAL_RCC_PWR_CLK_ENABLE();

// Initialize wake-up pin level of the NB-IoT module 
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_SET);

Code snippet #5

Plain text
while (1)
{
nbiot_uart_service();
power_detect_poll();
user_sensor_up_poll();
}

Code snippet #6

Plain text
while (1)
{
nbiot_uart_service();
power_detect_poll();
user_sensor_up_poll();
}

Code snippet #7

Plain text
 void user_sensor_up_poll(void)
{  
// When the module is bound and connected, and the door status reporting lock is enabled. After receiving the successful return code by the module, the door status reporting lock will be enabled. 
if ((NB_STATE_DEVICE_BINDED == mcu_get_nbiot_work_state()) && (device_status_s.door_up_lock)) 
   {
   // Interpret that there is an unprocessed door status reporting task, and start reporting data to the NB-IoT module. 
   if (STATE_DOOR_NEED_UP == device_status_s.sensor_state) 
      {
      device_status_s.sensor_state = STATE_IDLE;
      mcu_dp_bool_update(DPID_DOORCONTACT_STATE, device_status_s.door_state);
      device_status_s.door_up_lock = 0;     
      } 
   else 
      {
      // Determine whether the remaining battery level is below the power reporting threshold,  send power reporting data, and lower the threshold. 
      if (device_status_s.remaining_power <= power_threshold) 
         {
         mcu_dp_value_update(DPID_BATTERY_PERCENTAGE, device_status_s.remaining_power);
         if(power_threshold >= 25) 
            {     
            power_threshold -= 25;  
            }  
         }
      // Enable the PSM sleep lock of the NB-IoT module 
      mcu_set_nbiot_sleeplock(0);
      // The MCU enters low power mode 
      enter_lowpower_mode();        
      }

   }
}

Code snippet #8

Plain text
 void user_sensor_up_poll(void)
{  
// When the module is bound and connected, and the door status reporting lock is enabled. After receiving the successful return code by the module, the door status reporting lock will be enabled. 
if ((NB_STATE_DEVICE_BINDED == mcu_get_nbiot_work_state()) && (device_status_s.door_up_lock)) 
   {
   // Interpret that there is an unprocessed door status reporting task, and start reporting data to the NB-IoT module. 
   if (STATE_DOOR_NEED_UP == device_status_s.sensor_state) 
      {
      device_status_s.sensor_state = STATE_IDLE;
      mcu_dp_bool_update(DPID_DOORCONTACT_STATE, device_status_s.door_state);
      device_status_s.door_up_lock = 0;     
      } 
   else 
      {
      // Determine whether the remaining battery level is below the power reporting threshold,  send power reporting data, and lower the threshold. 
      if (device_status_s.remaining_power <= power_threshold) 
         {
         mcu_dp_value_update(DPID_BATTERY_PERCENTAGE, device_status_s.remaining_power);
         if(power_threshold >= 25) 
            {     
            power_threshold -= 25;  
            }  
         }
      // Enable the PSM sleep lock of the NB-IoT module 
      mcu_set_nbiot_sleeplock(0);
      // The MCU enters low power mode 
      enter_lowpower_mode();        
      }

   }
}

Code snippet #9

Plain text
void enter_lowpower_mode()
{  
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_SET);
lowpower_gpio_init();
HAL_ADC_Stop(&hadc1);
HAL_ADC_DeInit(&hadc1);
HAL_UART_DeInit(&huart3);
// HAL_TIM_Base_DeInit(&htim3);

// Turn off the clock 
__HAL_RCC_DMA1_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();          
__HAL_RCC_GPIOD_CLK_DISABLE();
__HAL_RCC_GPIOF_CLK_DISABLE();
HAL_SuspendTick();

// Enter STOP mode 
HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_STOPENTRY_WFI);
}

void leave_lowpower_mode()
{
SystemClock_Config();
MX_GPIO_Init();

// MX_TIM3_Init();
MX_USART3_UART_Init();
__HAL_UART_ENABLE_IT(&huart3, UART_IT_RXNE);
MX_ADC1_Init();
HAL_ADC_Start(&hadc1);

// Pull down the pin to wake up NB-IoT module 
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_RESET);

// The sensor needs to report the door status 
device_status_s.sensor_state = STATE_DOOR_NEED_UP;
}

Credits

Sandwich IoT
40 projects • 5 followers

Comments