×

基于涂鸦LZ201 Cat.1和MCU SDK的自动售货机

消耗积分:2 | 格式:zip | 大小:0.00 MB | 2023-06-15

分享资料个

描述

概述

得益于创新技术,我们的生活方式变得更加高效和智能。简单的自动售货机是现代的伟大发明之一。这是供应商使用的一种高效且低成本的方法,可以 24/7 全天候向最终用户交付产品。

本教程将向您展示如何基于涂鸦 LZ201 Cat.1 模块和 MCU SDK 以低代码方式制作自动售货机原型。

脚步

第 1 步:硬件设计

硬件由电源单元、单片机单元(MCU)、电机驱动与控制单元、电机到位检测单元、无线通信单元等外围单元组成。框图如下。

 
pYYBAGNoeV6ARWCpAAJA2CHOjGo852.png
 

供电单元

三台机组需要供电:

  • 主电源:24V直流电源。将其连接到 MOSFET 为自动售货机的电机供电。
  • 无线通讯单元:4V直流电源。使用LM2576 DC-DC稳压IC将24V降压至4V。LM2576 可以驱动 3A 负载,具有出色的线路和负载调整率。
  • 单片机:3.3V供电。使用 S-1206B33-U3T1G 低压差 (LDO) 稳压器 IC 将 4V 降压至 3.3V。

单片机

STM32F103RET6 是一款 32 位高密度性能 MCU。它采用 ARM Cortex-M3 架构,工作频率为 72 MHz。它具有 11 个定时器和一个内部复位电路、电压检测器、电压调节器和微调 RC 振荡器。有关产品和数据表的更多信息,请分别参见STM32F103RE 概述STM32F103RE 数据表

 
pYYBAGNoeWGAPz-VAACwxaokVT4850.png
 

电机驱动和控制单元

元器件74HC595是一个8位串行输入并行输出移位寄存器,用于向电机输出控制信号。( 74HC595 数据表)

 
poYBAGNoeWOAYtvcAABKsUuG7VA164.png
 

将电机的每个端子分别连接到 FDS9945 n 沟道 MOSFET(FDS9945 数据表)和 FDS9958 p 沟道 MOSFET(FDS9958 数据表)。连接方法如下:

  • 关于 FDS9945 MOSFET 的三个端子,源极接地,栅极连接信号线,漏极连接电机负极。
pYYBAGNoeWWAa7aWAAA1lJ_AGWY790.png
 
  • 关于FDS9958 MOSFET的三个端子,源极接24V电源,栅极接信号线,漏极接电机正极。
poYBAGNoeWiAAI5nAAA_YDm43PQ565.png
 

当 FDS9945 和 FDS9958 都处于导通状态时,电机可以旋转。

元件数量

  • 信号线:11根。我们设计了 10 个产品托盘,需要 10 个电机。通常,我们需要 20 根信号线。如果我们用一根信号线将 10 个电机的负极端子连接到 FDS9945 MOSFET 的漏极。只需要 11 根电线。
  • 74HC595移位寄存器:两片串联。我们有 11 位数据要输入和输出,但一个移位寄存器只支持 8 位数据。因此,我们将两个移位寄存器串联起来,最多支持 16 位数据。

电机到位检测单元

74HC165是一个8位并行输入和串行输出移位寄存器,用于确定电机旋转方向。( 74HC165 数据表)

 
poYBAGNoeWuAaqDJAAAiEXGVFg4388.png
 

当电机旋转到指定位置时,限位开关向74HC165移位寄存器上的并行输入引脚输出一个低电平信号。MCU 可以从 74HC165 上的串行输出引脚读取数据。当单片机检测到某个位的低电平时,会停止相应的电机。

由于我们没有足够的 I/O,10 个电机可以共享同一个限位开关。

无线通信单元

涂鸦专有的 LZ201-CN Cat.1 蜂窝模块可以在自动售货机和涂鸦 IoT Cloud 之间建立通信。有关详细信息,请参阅LZ201-CN Cat.1 模块数据表

 
poYBAGNoeW2AYyEYAABjV2tZKyQ057.png
 

该模块由高度集成的LTE Cat.1芯片UIS8910DM和外围电路组成。它的特点:

  • 内置LTE Cat.1网络通信协议栈和库函数。
  • 嵌入式 Cortex-A5 处理器和 Cat.1bis 调制解调器。
  • 高达 64 MB 的闪存和高达 128 MB 的 SRAM。
  • 支持的引脚包括 USB、UART、SDIO、SPI、I2C、I2S 和 ADC。
  • 支持的外设包括显示器、摄像头、键盘矩阵、麦克风、扬声器、充电器、microSD 卡和 USIM 卡。

只需移植涂鸦MCU SDK,即可实现自动售货机联网云端,通过APP实现设备控制。您还可以选择 WB3S Wi-Fi 模块或其他通信协议的模块。

其他外围设备

下面列出了一些可选外设:

  • LED 指示网络状态。
  • LED 指示电源状态。
  • 温度传感器检测自动售货机中的温度。
  • 跌落检测器检测产品跌落并返回操作结果。
  • 多通道按钮触发特定的按钮按下动作。
  • RS-485 接口用于在自动售货机和 RS-485 设备之间建立通信。
  • LCD 用于人机交互。

完成硬件设计后,即可进行 PCB 布局、焊接和测试。下图显示了我们完成的PCB。

 
pYYBAGNoeXCAC-ATAAJlx9dBLik496.png
 

第二步:在涂鸦IoT平台上创建产品

1.登录涂鸦物联网平台,点击创建

2.找到标准品类,点击户外出行>智能电动车

 
poYBAGNoeXKAQ6QWAABx_9n0xQ8894.png
 

3. 单击自定义解决方案选项卡上的智能电动汽车。

4.填写基本信息,协议选择LTE Cat.1 ,点击创建

 
poYBAGNoeXWAba_yAABPuC3vMgc496.png
 

5.根据需要添加标准功能。

 
pYYBAGNoeXmAXgrTAACMP2B_lBM608.png
 

6.(可选)如果没有找到需要的功能,找到自定义功能,点击+添加创建功能。我们创建两个功能:一个是Item ,从云端获取数据,另一个是Inventory ,发送数据到云端.

 
poYBAGNoeXyAXjUiAAAjL1koCAE417.png
 

7.单击设备面板选项卡并选择一个面板。为了方便测试,您可以选择调试面板,稍后再更改。

 
pYYBAGNoeX6AUAclAADSun3jHRI243.png
 

8.单击硬件开发选项卡。选择涂鸦标准模组MCU SDK ,然后选择LZ201-CN LTE Cat.1 Module

 
poYBAGNoeYKAY2v_AACjS285Wg0124.png
 

9.向下滚动页面并找到下载文档单击全部下载以获取嵌入式编程的所有文件。

第 3 步:嵌入式编程

将 SDK 中的文件添加到您的项目中,并根据错误消息更正您的代码。

您可能会使用不同的 MCU,因此以下驱动程序供您参考。完整示例代码见tuya-iotos-embeded-mcu-demo-4g-vending-machine

配置串口

/***********************************************************
*   Function:  USART3_Init
*   Input:     uint32_t pclk2,uint32_t bound
*   Output:    none
*   Return:    none
*   Notice:    USART initialization
***********************************************************/
void USART3_Init(uint32_t pclk2,uint32_t bound)
{
float temp;
uint16_t mantissa;
uint16_t fraction;
temp=(float)(pclk2*1000000)/(bound*16);// Get USARTDIV.
mantissa=temp;  			    // Get the integer part.
fraction=(temp-mantissa)*16; // Get the decimal part.
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<3;   // Enable the clock for PORTB.
RCC->APB1ENR|=1<<18;  // Enable the clock for USART3.
GPIOB->CRH&=~(0xf<<8|0xf<<12);
GPIOB->CRH|=0X0B<<8|8<<12;// // Configure GPIO state.
GPIOB->ODR|=1<<11;
RCC->APB1RSTR|=1<<18;   // Reset USART3.
RCC->APB1RSTR&=~(1<<18);// Stop reset.
// Set baud rate.
USART3->BRR=mantissa; // Set baud rate.
USART3->CR1|=0X200C;  // No parity, and 1 stop bit. 			USART3->CR1|=1<<8;    // Enable PE interrupt.
USART3->CR1|=1<<5;    // Enable the RXNE interrupt.
MY_NVIC_Init(1,2,USART3_IRQn,2);// Group 2
}

接收串行数据

/***********************************************************
*   Function:  USART3_IRQHandler
*   Input:     none
*   Output:    none
*   Return:    none
*   Notice:    USART interrupt handler function. Receive one byte of data in interrupt mode.
***********************************************************/
void USART3_IRQHandler(void)
{
if(USART3->SR&(1<<5))// Received data.
{
uart_receive_input((unsigned char)(USART3->DR));
}
}

发送串口数据

/***********************************************************
*   Function:  Uart3_PutChar
*   Input:     uint8_t
*   Output:    none
*   Return:    uint8_t
*   Notice:    Send one byte of data to check whether a timeout has happened.
***********************************************************/
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)// Wait until the transmission is completed.
{
timeout--;
if( 0 == timeout )
{
ret = 1;
break;
}
}
if( 0 != timeout )
{
ret = 0;
}
return ret;
}
/**
* @brief  Send serial data
* @param[in] {value}  The one byte of data to be sent by UART.
* @return Null
*/
void uart_transmit_output(u8 value)
{
//#error "Specify the UART transmission function and delete this line"
Uart3_PutChar(value);
/*
// Example:
extern void Uart_PutChar(u8 value);
Uart_PutChar(value);                                    // UART transmission function
*/
}

通过74HC165移位寄存器读取数据

/***********************************************************
*   Function:  HC165In
*   Input:     none
*   Output:    none
*   Return:    uint8_t
*   Notice:    Read values of the eight pins of 74HC165 and return 8-bit data.
***********************************************************/
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沟道MOSFET和p沟道MOSFET输出不同电平的信号。这样,我们可以控制电机旋转。

/***********************************************************
*   Function:  HC595Send
*   Input:     uint16_t
*   Output:    none
*   Return:    none
*   Notice:    Output 16-bit data through pins of the two 74HC595 shift registers.
***********************************************************/
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<1||<<10);

1<表示高电平信号输出到第 X 个 p 沟道 MOSFET。<>

注意:电路中的所有 n 沟道 MOSFET 使用相同的信号引脚,因此1<<10是固定的。

要停止电机旋转,我们可以调用

HC595Send(0);

该功能的参数因电路设计而异。根据您的硬件调整它们。

处理来自云端的命令

来自云端的数据长度为 6 个字节。我们可以指定位 0 为产品托盘编号,位 1 为产品编号,位 2 至位 5 为订单编号。

您可以根据需要指定通信协议。以下程序供您参考。

/*****************************************************************************
Function name: dp_download_m_num_handle
Feature description: a processing function for DPID_M_NUM.
Input parameters: value indicates the data source
: length: the length of the data
Return parameters: Return SUCCESS on success, and ERROR on failure
Instruction: For the send-only data point, the results must be sent to the cloud after the operation is completed.
*****************************************************************************/
static unsigned char dp_download_m_num_handle(const unsigned char value[], unsigned short length)
{
// Example: This is a data point of raw type.
unsigned char ret;
const unsigned char error[6]={"ERROR1"};
/*
// Process data of raw type.

*/
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);
}
// Return the result of the operation.
ret = mcu_dp_raw_update(DPID_M_NUM,value,length);
if(ret == SUCCESS)
return SUCCESS;
else
return ERROR;
}

编译下载

编程完成后,如果出现任何错误,请单击构建并更正您的代码。

然后,将程序下载到开发板上进行测试。

STM32 支持 ST-Link 和 J-Link 等调试器。建议使用 ST-Link。下表概述了要连接的引脚:

pYYBAGNoeYSADW2eAAAi3_pn84Y444.png
 

将 ST-Link 连接到您的开发板后,单击下载

第 4 步:演示

打开涂鸦智能应用,点击您为自动售货机选择的面板。找到创建的数据点Item ,输入XXYYZZZZZZZZ格式的值进行测试。

  • XX表示第 X 个产品托盘。
  • YY表示托盘上的剩余产品。
  • ZZZZZZZZ表示订单号。它可以是任何值。

例如输入0104aabbccdd,表示第一个托盘现在有四个产品,订单号是aabbccdd

数据发送后,您会发现电机开始转动,产品掉落后停止。

注意:库存值必须与项目匹配。例如,如果第一个托盘有四个产品,则有效值为0104无效值如01050103不能使电机旋转。
 
poYBAGNoeYeABlINAAD6JLhjfNQ572.jpg
 

概括

涂鸦物联网平台提供便捷物联网开发工具和服务,旨在让您的物联网项目更轻松、更高效。查看并发现更多很棒的想法。

 


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.lene-v.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'基于涂鸦LZ201 Cat.1和MCU SDK的自动售货机',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.lene-v.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);