技术发明一直在改变人们的生活方式。自动售货机便是其中之一,在不需要工作人员或人工协助的情况下,它可以 24 小时向客户分发产品。整个售货过程都由机器自动完成,使人们在购买物品和交易方面更加便利。
使用涂鸦 LZ201 CAT1 模组,借助涂鸦 MCU SDK 低代码开发方式,开发者可以跟随本教程在涂鸦 IoT 平台上快速开发一款自动售货机产品原型。
整体硬件由供电单元、主控单元、电机驱控控制单元、电机到位检测单元、无线通讯单元和其他外设单元组成。具体如下图所示:
本款自动售货机主要包含以下几个部件的供电:
该单元采用 STM32F103RET6 作为主控芯片。该芯片是一款基于 ARM 架构的高密度性能 32 位微处理器,主频最大可支持 72MHZ,多达 11 个定时器,内部集成了复位电路、低电压检测、调压器和精确的 RC 振荡器电路。更多关于该芯片的信息,请参考 STM32F103RE 芯片介绍;更多关于该芯片的数据规格,请参考 STM32F103RE 数据规格书。
控制单元组成
该单元采用 74HC595 (74HC595 数据规格书)八位串行输入、并行输出的移位寄存器用于提供输出各个电机的控制信号。
每个电机的两端各接一个 FDS9945 N 沟道 MOS 管(FDS9945 数据规格书)和一个 FDS9958 P 沟道 MOS 管(FDS9958 数据规格书),其中
组件数量
该单元采用 74HC165 (74HC165 数据规格书)八位并行输入,串行输出的移位寄存器用于检测电机转动位置情况。
当电机转动到一定位置时,到位开关输出低电平信号给 74HC165 并行输入脚。主控单元读取 74HC165 串行输出脚,检测到某一位低电平时,将对应位的电机停转,避免多次掉落物品。
由于 I/O 口资源有限,开发者可以让 10 个电机共用一个到位开关。
无线通信单元
该单元主要用于售货机和云平台的信息交互,可以采用涂鸦 LZ201-CN CAT1 模组。这是由涂鸦智能开发的一款 LTE Cat.1 蜂窝网络模组。关于该模组的数据规格,请参考 LZ201-CN CAT1 模组规格书。
模组主要由一个高集成度的 LTE Cat.1 芯片 UIS8910DM 及其外围电路构成,其中:
开发者只需要通过移植涂鸦 MCU SDK,即可以实现对 App、云、售货机三者的通信控制。当然,这部分也可以用 WB3S Wi-Fi 模组或者其他通信模组来代替。
其他外设单元
该单元的外设,可以根据开发者自身需求自行设计添加,比如
完成以上硬件的设计后,可以根据结构尺寸,设计对应的 PCB,并且完成焊接,测试等工作。下图为参考示例:
登录 涂鸦IoT平台,单击 创建产品。
在 标准类目 导航栏中,选择 户外出行 > 智能电动车。
选择 自定义方案 中的 智能电动车 方案。
输入产品名称,产品型号(可选),选择通信协议为 LTE Cat1,并单击 创建产品。
在功能定义选项中,根据自身需要选择功能。
(可选)若标准功能中缺少您需要的功能,可在 自定义功能 区域单击 添加功能,根据实际需求进行配置。
例如,本次可以添加两个 DP 点,一个用于指示平台下发的数据,一个用于指示自动售货机上报的数据。
在 设备面板 页签中选择想要的面板,开始调试时可选择开发调试面板,后面可根据自身需要自由配置面板。
在 硬件开发 页签中,选择 涂鸦标准模组MCU SDK开发,并选择 LZ201-CN LTE Cat.1模组。
上述操作完成之后,单击 下载全部 下载所有开发需要用到的资料,开始嵌入式程序的开发。
开发者在获取了 MCU SDK 开发包之后,需要将 SDK 文件添加到自己的工程中,根据编译中的错误信息提示逐个修改。
由于 MCU 和选择的 PIN 脚不一定相同,以下为一些驱动程序,仅供参考。完整示例程序请参考 tuya-iotos-embeded-mcu-demo-4g-vending-machine。
串口配置
/*********************************************************** * Function: USART3_Init * Input: uint32_t pclk2,uint32_t bound * Output: none * Return: none * Notice: 串口初始化 ***********************************************************/ void USART3_Init(uint32_t pclk2,uint32_t bound) { float temp; uint16_t mantissa; uint16_t fraction; temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV mantissa=temp; //得到整数部分 fraction=(temp-mantissa)*16; //得到小数部分 mantissa<<=4; mantissa+=fraction; RCC->APB2ENR|=1<<3; //使能PORTB口时钟 RCC->APB1ENR|=1<<18; //使能串口3时钟 GPIOB->CRH&=~(0xf<<8|0xf<<12); GPIOB->CRH|=0X0B<<8|8<<12;//IO状态设置 GPIOB->ODR|=1<<11; RCC->APB1RSTR|=1<<18; //复位串口3 RCC->APB1RSTR&=~(1<<18);//停止复位 //波特率设置 USART3->BRR=mantissa; // 波特率设置 USART3->CR1|=0X200C; //1位停止,无校验位. USART3->CR1|=1<<8; //PE中断使能 USART3->CR1|=1<<5; //接收缓冲区非空中断使能 MY_NVIC_Init(1,2,USART3_IRQn,2);//组2 }
串口接收数据
/*********************************************************** * Function: USART3_IRQHandler * Input: none * Output: none * Return: none * Notice: 串口中断服务函数,接收一个字节数据 ***********************************************************/ void USART3_IRQHandler(void) { if(USART3->SR&(1<<5))//接收到数据 { uart_receive_input((unsigned char)(USART3->DR)); } }
串口发送数据
/*********************************************************** * Function: Uart3_PutChar * Input: uint8_t * Output: none * Return: uint8_t * Notice: 发送一个字节数据,并返回发送是否超时的状态 ***********************************************************/ uint8_t Uart3_PutChar(uint8_t data) { uint8_t ret=1; uint16_t timeout=0x8000; USART3->DR = data; while((USART3->SR&1<<6)!=1<<6)//等待发送完毕 { timeout--; if( 0 == timeout ) { ret = 1; break; } } if( 0 != timeout ) { ret = 0; } return ret; } /** * @brief 串口发送数据 * @param[in] {value} 串口要发送的1字节数据 * @return Null */ void uart_transmit_output(u8 value) { //#error "请将MCU串口发送函数填入该函数,并删除该行" Uart3_PutChar(value); /* //Example: extern void Uart_PutChar(u8 value); Uart_PutChar(value); //串口发送函数 */ }
读取 74HC165 数据
/*********************************************************** * Function: HC165In * Input: none * Output: none * Return: uint8_t * Notice: 读取 74HC165 的八个引脚状态,并返回对应的八位数据 ***********************************************************/ uint8_t HC165In(void) { uint8_t i,dat=0; CP_SET; PL_RESET; delay_us(10); PL_SET; delay_us(10); for(i=0;i<8;i++) { dat=dat<<1; if(ODATA==1) { dat=dat+1; } CP_RESET; delay_us(10); CP_SET; delay_us(10); } CP_RESET; return dat; }
发送 74HC595 数据
本函数通过 74HC595 输出不同的电平信号给 N 沟道 MOS 管和 P 沟道 MOS 管,由此实现电机转动控制。
/*********************************************************** * Function: HC595Send * Input: uint16_t * Output: none * Return: none * Notice: 将 16 位的数据通过两个 74HC595 引脚输出 ***********************************************************/ void HC595Send(uint16_t data) { uint8_t j; LOCK_RESET; delay_us(10); for (j = 16; j > 0; j--) { SHIFT_RESET; delay_us(10); if(data & 0x8000) { INDATA_SET; } else { INDATA_RESET; } delay_us(10); data <<= 1; SHIFT_SET; delay_us(10); } LOCK_SET; delay_us(10); }
例如,我们想让第 X 个(0≤X≤9)电机转动使物品掉落,只要调用
HC595Send(1<<X||1<<10);
其中 1<<X
表示给第 X 个 P 沟道 MOS 管高电平信号;1<<10
表示给 N 沟道 MOS 管高电平信号。
说明:由于电路中所有的 N 沟道 MOS 管共用了一个信号口,所以调用时固定为 1<<10。
同理,我们想让电机停止转动,只需要调用
HC595Send(0);
由于不同电路设计差异,函数中的实际参数会有所不同,需要根据实际硬件来处理。
下发的串口事件处理
下发数据的长度为 6 个字节,可以约定第 0 位为货道号,第 1 位为物品序号,后面 4 位为订单号。
开发者也可以根据自己的需要,规定通讯协议。以下程序,仅供参考。
/***************************************************************************** 函数名称 : dp_download_m_num_handle 功能描述 : 针对DPID_M_NUM的处理函数 输入参数 : value:数据源数据 : length:数据长度 返回参数 : 成功返回:SUCCESS/失败返回:ERROR 使用说明 : 只下发类型,需要在处理完数据后上报处理结果至app *****************************************************************************/ static unsigned char dp_download_m_num_handle(const unsigned char value[], unsigned short length) { //示例:当前 DP 类型为 RAW unsigned char ret; const unsigned char error[6]={"ERROR1"}; /* //RAW类型数据处理 */ if((length==6)&&(value[0]<11)&&(value[1]<10)) { IoT_receive[Q_U3.rear].data[0]=value[0]; IoT_receive[Q_U3.rear].data[1]=value[1]; IoT_receive[Q_U3.rear].data[2]=value[2]; IoT_receive[Q_U3.rear].data[3]=value[3]; IoT_receive[Q_U3.rear].data[4]=value[4]; IoT_receive[Q_U3.rear].data[5]=value[5]; F_TASK_MOTOR_OPEN++; rear_inc(&Q_U3); } else { mcu_dp_raw_update(DPID_R_NUM,error,6); } //处理完 DP 数据后应有反馈 ret = mcu_dp_raw_update(DPID_M_NUM,value,length); if(ret == SUCCESS) return SUCCESS; else return ERROR; }
编译与下载
程序编写完成之后,单击 Build 并根据软件提示修改相关错误或者警告信息。
待程序编译通过之后,就可以下载到开发板中进行调试和测试。
STM32 支持 ST-Link ,J-Link 等工具下载,这里推荐 ST-Link,引脚连接方式如下:
ST-Link | STM32F103 |
---|---|
SWCLK | SWCLK |
SWDIO | SWDIO |
NRST | NRST |
VDD | VDD |
GND | GND |
连接无误后,单击 Download 把程序下载到开发板中。
打开涂鸦智能 App,在 Item 输入栏中输入 XXYYZZZZZZZZ,其中
XX
表示第 X 个货道;YY
表示货道上剩余的物品数量;ZZZZZZZZ
为订单号(可以为任意值)。如,输入0104aabbccdd,表示第 1 个货道剩余 4 个物品,订单号为 aabbccdd。
数据发送成功后,可以看到电机开始转动,当物品掉落后,电机停止转动。
注意:当前货道的物品剩余量务必要和输入物品号相同,比如第 1 个货道有4个物品时,只有输入 0104 才会有效,输入 0105 或 0103 等其他值,电机都是不会转动的。
涂鸦物联网开发平台为开发者提供了便捷的 IoT 开发工具与服务,助力开发者更高效的完成设备接入,并为开发者提供物联网应用开发及场景服务能力。
该内容对您有帮助吗?
是我要提建议更进一步