简介
智能家居是在互联网影响之下物联化的体现。智能家居通过物联网技术将家中的各种设备连接到一起,提供家电控制、照明控制、电话远程控制、室内外遥控、防盗报警、暖通控制、红外转发以及可编程定时控制等多种功能和手段。
智能电动床属于智能家具产品的一类,反映了当前智能家居领域发展趋势和全新的产品概念。智能床能通过床板调节,可以开启休闲、阅读、观影、止鼾、零重力等模式,以满足用户睡眠、休闲、健康三大核心需求。
智能床对智慧生活的助推作用不容小觑,随着城镇化水平提高和居民可支配收入增长,智能家居在人们家庭中越来越普及,智能床反映了当前智能家居领域发展趋势和全新的产品概念。
本教程使用STM32F405实现智能电动床的控制,基本功能如下:
语音控制模块:LD3320,提供基于 " 关键词语列表 " 的语音识别,可以使用语音命令控制智能电动床进行相关操作,例如床头抬起,床位抬起,还原设备默认设置及指定智能电动床当前模式。
BLE蓝牙:低功耗蓝牙,用来连接蓝牙遥控器及微信小程序,微信小程序提供WIFI配网及本地遥控操作
物联网模块:EMW3080, 提供阿里云物联网平台访问,属性上报,远程状态查看及远程控制等操作
马达控制板:使用SPI协议最多同时控制4个马达,实现正反转控制,可用于双人电动床。
其他:压力传感器(上离床,体征监测),温度传感器及鼾声传感器在本版本并未体现。
项目架构
CubeMAX配置
通讯协议
SPI1 访问W25Q16Flash存储芯片,用于保存设备状态,
软SPI(PA5,PA6,PA7) 访问马达控制板
USAERT2 LD3320语音模块
USAERT3 EMW3080阿里物联网模块
USAERT6 BLE蓝牙
硬件选型
STM32F405开发板:主频168M,192K内存,1M Flash。支持SWD调试接口,支持USB一键下载,W25Q16 Flash数据存储芯片,全IO引出。
LD3320:可实现中文/英文识别,不需要训练,官方宣传具有95%以上识别率,实测应该小于这个识别率。最多识别50条候选词。
EMW3080:阿里云物联网低功耗无线模组,本系统使用的为阿里云单独开发版本,支持AT设置,直接对接阿里云物联网(非阿里飞燕)。
蓝牙:微信小程序可以访问的蓝牙设备,需支持低功耗蓝牙。
马达控制板:实现马达正反转控制,单模块可控制两个推杆电机独立运动,输出性能可达24V8A,可使用arduino,c51,stm32等微处理器直接驱动。
该模块是易于实施及DIY推杆类设备的关键,一般低电压推杆电机应用场景都可以使用,模块在设计上使用两种不同的继电器用来防止继电器损坏造成短路对相关设备造成的伤害。以下为继电器部分原理图。
核心代码
既然是马达控制系统,自然以马达运动控制作为核心部分。项目采用嵌入式实时操作系统(FREERTOS)更合理、更有效地利用CPU的资源。在main函数的MX_FREERTOS_Init中调用以下代码。
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* definition and creation of reportTask */
osThreadDef(reportTask, StartReportTask, osPriorityHigh, 0, 1024);
reportTaskHandle = osThreadCreate(osThread(reportTask), NULL);
/* definition and creation of bedTask */
osThreadDef(bedTask, StartBedTask, osPriorityHigh, 0, 1024);
bedTaskHandle = osThreadCreate(osThread(bedTask), NULL);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
}
StartReportTask是设备属性定时上报任务,负责定时上报设备属性到阿里云物联网。以下为report task具体实现
void attr_report_task()
{
static portTickType xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
const portTickType xFrequency = pdMS_TO_TICKS(300000);
osDelay(1000);
attr_report();
for(;;)
{
vTaskDelayUntil(&xLastWakeTime,xFrequency);
attr_report();
}
}
void attr_report()
{
char * json = bed_status_dumps();
memset(wifi_tx_buf,0,RECV_BUFFER_SIZE);
sprintf(wifi_tx_buf,"AT+IDMPP=0,\"%s\"\r\n",json);
free(json);
memset(wifi_rx_buf,0,RECV_BUFFER_SIZE);
int cmdlen = strlen(wifi_tx_buf);
int ret = at_send_wait_reply(wifi_tx_buf,cmdlen,NULL,NULL,0,wifi_rx_buf,256,&atcmd_report_config);
}
StartBedTask是马达运动检测任务,负责根据运动命令,控制电机正反转及通电时长。
void bed_action_task()
{
static portTickType xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
const portTickType xFrequency = pdMS_TO_TICKS(100);
RunBedAction();
for(;;)
{
vTaskDelayUntil(&xLastWakeTime,xFrequency);
RunBedAction();
}
}
void RunBedAction()
{
uint32_t tick = HAL_GetTick();
uint8_t action = 0x00;
for(uint8_t i = 0;i < 8; i+=2)
{
uint8_t mu = 0;
bed_positon_save_t *currentDevice = i < 4 ? &device_save_0 : &device_save_1 ;
if(action_remain[i].endTick > tick) // up action
{
action |= action_remain[i].action;
SaveCurrentPosition(currentDevice,action_remain[i].action);
mu = 1;
}
else
{
if(action_remain[i].endTick > 0)
{
action &= ~action_remain[i].action;
action_remain[i].endTick = 0;
}
}
if(mu == 0) //down action
{
if(action_remain[i+1].endTick > tick)
{
action |= action_remain[i+1].action;
SaveCurrentPosition(currentDevice,action_remain[i+1].action);
}
else
{
if(action_remain[i+1].endTick > 0)
{
action &= ~action_remain[i+1].action;
action_remain[i+1].endTick = 0;
}
}
}
}
SetBedAction(action);
dirty_count++;
if(save_dirty && (dirty_count % (3000000)) == 0) // save device position every 5 min
{
SaveDevicePostion();
}
}
uint8_t SetBedAction(uint8_t action)
{
HAL_GPIO_WritePin(GPIOA,MOTOR_ST_Pin,GPIO_PIN_RESET);
//uint8_t act = ~action;
for(uint8_t i = 0; i < 8; i++){
HAL_GPIO_WritePin(GPIOA,MOTOR_SCK_Pin,GPIO_PIN_RESET);
uint8_t bit = action >> (7-i) & 0x01;
HAL_GPIO_WritePin(GPIOA,MOTOR_MOSI_Pin,bit);
HAL_GPIO_WritePin(GPIOA,MOTOR_SCK_Pin,GPIO_PIN_SET);
}
HAL_GPIO_WritePin(GPIOA,MOTOR_ST_Pin,GPIO_PIN_SET);
return 0;
}
蓝牙遥控器
微信小程序控制面板
蓝牙控制器面板
项目地址:https://gitee.com/zhupingqi/SmartBedAli
来源:oschina
链接:https://my.oschina.net/u/4398987/blog/4318704