宠物喂食器的设计-基于涂鸦三明治三件套
本文章允许涂鸦智能转载使用
去年疫情突发,全国很多地区封城,封小区,让原本备受宠爱的主子与铲屎官异地分离。遇到有准备的铲屎官,主子们还能勉强度日,那些没有准备的主子只能靠吃猫砂,吃垃圾度日,甚至有些小可怜被活活饿死。
疫情缓解后,为了避免这样的事件再次发生,也为了解放懒惰的铲屎官,于是自动猫砂盆,自动喂食器,自动喂水器的需求不断提升。有数据显示,疫情后自动猫砂盆增长879%,自动喂水器增长120%,自动喂食器增长也超一倍。毕竟主子是家里的老大,要吃好喝好还要拉好。
此次DIY自动投食器由涂鸦智能开展的【宠物喂食器】实战营策划,并提供了涂鸦三明治开发套件,其中包括:
涂鸦三明治 Wi-Fi MCU 通信板1
涂鸦三明治H桥直流电机驱动功能板1
涂鸦三明治直流供电电源板*1。
除此之外,用户还需要自行准备MCU控制板和电机等组件,该WiFi模组出厂默认为透传模式,只负责数据转发,不负责数据处理,所以我们只需要准备MCU用于数据处理和外设控制。
涂鸦智能平台
1.前往涂鸦智能开发平台
(https://auth.tuya.com/register_source=7b811ac2e872ccb62376ba4dfe0568eb)注册开发者账号
2.在涂鸦loT平台创建产品
3.在小家电品类里面找到【宠物喂食器】
4.使用MCU SDK方案,完善产品信息
5.产品创建后添加标准功能
6.硬件开发选项
以上步骤更加具体配置可参考涂鸦IOT平台产品创建流程(https://shimo.im/docs/HvHRgTtjUDYIvLlA/read)产品创建完成后下载开发资料,建议全部下载,其中MCU SDK的内容会根据你所选择的标准功能不同而不同,为了方便可在选择功能时尽可能多的考虑到需要配置的功能,当然,即使你一个不选,SDK也开放了各个功能的函数,只是被屏蔽,可自行放开。
功能调试
MCU对接方案通信原理图
1.WIFI模组调试
打开上一步最终下载的文件如图,接着我们打开涂鸦调试助手
将WiFi的通信板的串口1接到usb-ttl上,接到电脑,一定是串口1,串口0是查看模组本身的logo的,打开涂鸦调试助手。选择MCU模拟,此时调试助手就相当于是MCU,可以与WiFi模组通信,可用此来调试WiFi模组。选择好串口,波特率默认9600.功能点调试文件选择之前下载的json文件。初始化配置保持默认,点击开始调试。如收到以下数据说明模组与助手连接正常,可以开始调试。
此时我们下载涂鸦智能APP,注册后选择添加设备,在小家电里面找到宠物喂食器,选择2.4G的WiFi网络。输入密码。点击下一步
此时在模组调试助手点击smart配网,手机点击下一步
配网成功后会在手机APP和调试助手同时看到相应信息。连接成功后会定时发送心跳包保持连接。
至此WiFi模组配网完成,改配网信息会保存在WiFi模组内部,下次上电会自动连接该网络。如果更换网络环境需要重置后再次配网。此时可在DP CMD里面测试相关DP点的数据上报,观察有无数据的上报下发。
2.MCU调试
WiFi模组调试完成之后我们需要调试我们的主控,也就是MCU,在我这里就是STM32F103ZET6。在进行MCU调试之前我们需要先进行SDK的移植,将之前下载的SDK移植到我们的STM32项目中。
1.工程搭建
本文实在串口驱动实验的基础上搭建的,因为后面需要用到串口;
usart.h
#ifndef __USART_H
#define __USART_H
#include "stdio.h"
#include "sys.h"
#define USART_REC_LEN 200 //定义最大接收字节数 200
#define EN_USART1_RX 1 //使能(1)/禁止(0)串口1接收
extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u16 USART_RX_STA; //接收状态标记
//如果想串口中断接收,请不要注释以下宏定义
void uart_init(u32 bound);
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch);
#endif
usart.c
#include "sys.h"
#include "usart.h"
#include "mcu_api.h"
#include "protocol.h"
#include "system.h"
#include "wifi.h"
//
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos 使用
#endif
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
#if EN_USART1_RX //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 USART_RX_STA=0; //接收状态标记
void uart_init(u32 bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitS