0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于STM32的无人售货机系统设计

DS小龙哥-嵌入式技术 来源:DS小龙哥-嵌入式技术 作者:DS小龙哥-嵌入式技 2023-05-17 16:29 次阅读

一、项目背景

随着科技的发展和生活水平的提高,人们对于购物体验的要求越来越高。传统的商场、超市购物方式已经无法满足消费者的需求,因此无人售货机应运而生。本文针对现有售货机存在的缺陷,设计了一款基于STM32的无人售货机系统。该系统采用STM32作为主控芯片,使用液晶屏显示各种商品库存与售价,用户按下对应按键选择购买指定商品,在矩阵键盘输入账号密码付款。若付款成功,对应电机旋转一定角度使商品出库,同时修改库存;若余额不足,则进行声光提示。手机端还可查看消费流水、商品库存情况,并进行补货和充值操作。

image-20230517113951921

二、系统设计

2.1 系统硬件设计

该系统的核心部件是STM32主控芯片,它负责整个售货机的控制和管理。液晶屏用于显示商品信息、价格等,矩阵键盘用于用户输入账号密码进行支付。电机控制板用于控制商品出库。

硬件组成:

主控芯片选:STM32F103ZET6 液晶屏选择:2.8寸TFT-LCD屏 WIFI选择:ESP8266-WIFI 与手机APP之间通信。模式配置为STA模块。连接服务器。 电机旋转角度:28BYJ48步进电机。 控制出货机出货物。 矩阵键盘:4X4的矩阵键盘。

2.2 系统软件设计

软件部分主要包括STM32程序和手机APP程序。STM32程序是售货机的核心程序,负责控制各个部件的工作,实现售货机的基本功能。APP程序可以通过与STM32通信来实现商品库存查看、补货、充值等功能。

STM32部分主要分为以下几个模块:

(1)初始化模块:初始化各个部件的工作状态和参数。 (2)商品选择模块:根据用户按下的按钮,选择相应的商品。 (3)支付模块:通过矩阵键盘输入账号密码进行支付,并根据支付结果控制电机的工作状态。 (4)库存管理模块:根据商品销售情况,实时更新商品库存信息。 (5)声光提示模块:在用户付款失败或余额不足时,通过蜂鸣器和LED灯进行声光提示。

手机APP程序主要分为以下几个模块:

(1)用户登录模块:用户可以通过输入账号密码登录APP。 (2)商品查看模块:用户可以查看售货机内商品库存情况。 (3)补货模块:商家可以通过APP进行补货操作,将商品补充至指定数量。 (4)充值模块:用户可以通过APP进行账户充值操作。 (5)消费流水模块:用户和商家可以查看售货机的消费记录。

以上各模块之间通过STM32和APP程序之间进行通信,实现整个系统的功能。

三、核心代码实现

【1】步进电机控制代码

以下是28BYJ48步进电机的代码:

(1)定义一些宏和变量以便于控制步进电机:

#define IN1 GPIO_Pin_0
#define IN2 GPIO_Pin_1
#define IN3 GPIO_Pin_2
#define IN4 GPIO_Pin_3
​
#define STEPS_PER_REVOLUTION 2048 //步数每圈
#define DELAY_MS 5 //控制转速的延迟时间
​
GPIO_InitTypeDef GPIO_InitStructure;
​
int step_count = 0;
uint16_t steps[] = {IN1 | IN2 | IN3 | IN4,
          IN2 | IN3 | IN4,
          IN1 | IN2 | IN3,
          IN3 | IN4,
          IN1 | IN3 | IN4,
          IN2 | IN4,
          IN1 | IN2,
          IN4};
​
void delay_ms(uint32_t ms) {
  uint32_t i, j;
  for (i = 0; i < ms; i++) {
         for (j = 0; j < 1141; j++);
     }
 }
 ​
 void setStep(int step) {
     GPIO_ResetBits(GPIOB, IN1 | IN2 | IN3 | IN4);
     GPIO_SetBits(GPIOB, steps[step]);
 }
 ​
 void forward(int steps_to_move) {
     int i;
     for (i = 0; i < steps_to_move; i++) {
         setStep(step_count % 8);
         step_count++;
         delay_ms(DELAY_MS);
     }
 }
 ​
 void backward(int steps_to_move) {
     int i;
     for (i = 0; i < steps_to_move; i++) {
         setStep(step_count % 8);
         step_count--;
         delay_ms(DELAY_MS);
     }
 }

在上面的代码中,定义了四个引脚来控制步进电机,然后定义了一些函数来实现正反转控制。

delay_ms函数用于延迟控制步进电机的转速。STEPS_PER_REVOLUTION宏定义了每圈的步数,DELAY_MS宏定义了控制转速的延迟时间。

setStep函数根据传入的步数设置引脚状态,接着forward和backward函数分别根据需要移动的步数控制步进电机的转动方向,并调用setStep函数控制步进电机的步数。

最后,将forward和backward函数封装成一个子函数来更方便地调用:

void control_stepper_motor(int steps_to_move, int direction) {
  if (direction == 1) {
    forward(steps_to_move);
   } else {
    backward(steps_to_move);
   }
}

这样,就可以通过调用control_stepper_motor函数来实现正反转控制28BYJ48步进电机了。

【2】矩阵键盘检测代码

以下是4x4电容矩阵键盘的示例代码:

(1)定义一些宏和变量以便于控制电容矩阵键盘:

#define ROW1 GPIO_Pin_0
#define ROW2 GPIO_Pin_1
#define ROW3 GPIO_Pin_2
#define ROW4 GPIO_Pin_3
​
#define COL1 GPIO_Pin_4
#define COL2 GPIO_Pin_5
#define COL3 GPIO_Pin_6
#define COL4 GPIO_Pin_7
​
GPIO_InitTypeDef GPIO_InitStructure;
​
const uint8_t keys[4][4] = {
   {'1', '2', '3', 'A'},
   {'4', '5', '6', 'B'},
   {'7', '8', '9', 'C'},
   {'*', '0', '#', 'D'}
};

在上面的代码中,定义了8个引脚来控制电容矩阵键盘,并使用一个二维数组来存储每个按键对应的字符。

(2)需要编写一个函数来检测电容矩阵键盘是否有按下。

该函数需要通过轮询扫描键盘来检测按键,如果有按键按下,则返回该按键对应的字符:

char scan_keypad() {
  GPIO_ResetBits(GPIOC, ROW1 | ROW2 | ROW3 | ROW4);
  GPIO_SetBits(GPIOC, COL1 | COL2 | COL3 | COL4);
​
  if (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0) {
    while (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0);
    return keys[0][0];
   } else if (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0) {
    while (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0);
    return keys[1][0];
   } else if (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0) {
    while (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0);
    return keys[2][0];
   } else if (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0) {
    while (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0);
    return keys[3][0];
   }
​
  GPIO_ResetBits(GPIOC, ROW1 | ROW2 | ROW3 | ROW4);
  GPIO_SetBits(GPIOC, COL1 | COL2 | COL3 | COL4);
​
  if (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0) {
    while (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0);
    return keys[0][1];
   } else if (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0) {
    while (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0);
    return keys[1][1];
   } else if (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0) {
    while (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0);
    return keys[2][1];
   } else if (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0) {
    while (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0);
    return keys[3][1];
   }
​
  GPIO_ResetBits(GPIOC, ROW1 | ROW2 | ROW3 | ROW4);
  GPIO_SetBits(GPIOC, COL1 | COL2 | COL3 | COL4);
​
  if (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0) {
    while (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0);
    return keys[0][2];
   } else if (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0) {
    while (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0);
    return keys[1][2];
   } else if (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0) {
    while (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0);
    return keys[2][2];
   } else if (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0) {
    while (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0);
      return keys[3][2];
}
GPIO_ResetBits(GPIOC, ROW1 | ROW2 | ROW3 | ROW4);
GPIO_SetBits(GPIOC, COL1 | COL2 | COL3 | COL4);
​
if (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0) {
  while (GPIO_ReadInputDataBit(GPIOC, ROW1) == 0);
  return keys[0][3];
} else if (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0) {
  while (GPIO_ReadInputDataBit(GPIOC, ROW2) == 0);
  return keys[1][3];
} else if (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0) {
  while (GPIO_ReadInputDataBit(GPIOC, ROW3) == 0);
  return keys[2][3];
} else if (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0) {
  while (GPIO_ReadInputDataBit(GPIOC, ROW4) == 0);
  return keys[3][3];
}
​
return '�';
 }

在上面的代码中,使用轮询的方式扫描键盘。首先将所有行引脚都设为低电平,所有列引脚都设为高电平,并检测是否有按键按下。如果有按键按下,则返回该按键对应的字符。 接下来,可以在主函数中循环调用scan_keypad函数来读取键值:

int main(void) {
  char key = '�';
​
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
​
  GPIO_InitStructure.GPIO_Pin = ROW1 | ROW2 | ROW3 | ROW4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
​
  GPIO_InitStructure.GPIO_Pin = COL1 | COL2 | COL3 | COL4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
​
  while (1) {
    key = scan_keypad();
​
    if (key != '�') {
      // 处理读取到的键值
     }
   }
}

在上面的代码中,首先初始化了8个引脚,并通过循环调用scan_keypad函数来读取键值。如果读取到键值,则可以进行相应的处理。

四、系统测试与验证

为了验证系统的可行性和稳定性,在硬件搭建完成后,进行了一系列测试。

(1)测试了系统的整体运行逻辑。通过模拟用户选择商品、支付、出货等情况,验证系统的基本功能。测试结果显示系统能够稳定运行,能够满足用户的购物需求。

(2)测试了系统的库存管理功能。通过模拟商品销售情况,验证系统的库存信息是否能够实时更新。测试结果表明系统能够准确地处理库存信息。

(3)测试了手机端APP程序的功能。通过模拟用户登录、查看商品库存、进行补货、充值和查看消费流水等操作,验证APP程序的功能。测试结果显示APP程序能够正常运行,并且与STM32主控芯片之间能够实现良好的通信。

审核编辑:汤梓红

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

    关注

    447

    文章

    47821

    浏览量

    409207
  • 单片机
    +关注

    关注

    6002

    文章

    43982

    浏览量

    620916
  • STM32
    +关注

    关注

    2240

    文章

    10675

    浏览量

    348866
  • APP
    APP
    +关注

    关注

    33

    文章

    1530

    浏览量

    71634
收藏 人收藏

    评论

    相关推荐

    LabVIEW售货机(人机交互实验版)

    售货机是基于NI的PXI控制器(LabVIEW软件实现)的人机交互性售货机。该售货机为试验版,正式版由于保密性不提供。本帖主要目的是给学习LabVIEW编程语言的朋友参考下,过程可能存在不合理或者有误的地方,希望学习的朋友可以
    发表于 09-21 15:26

    无线远程对自动售货机的管理

    现在很多支付商家都在推举1分钱购买自动售货机的饮料,那么这些自动售货机是怎么普及过来的呢? 随时随地可见的自动售货机俨然成为了我们的一种从商场转到小卖部,从小卖部转到个人的快捷交易平台。自动售卖机
    发表于 07-26 09:06

    被无线远程控制管理的自动售货机

    现在很多支付商家都在推举1分钱购买自动售货机的饮料,那么这些自动售货机是怎么普及过来的呢? 随时随地可见的自动售货机俨然成为了我们的一种从商场转到小卖部,从小卖部转到个人的快捷交易平台。自动售卖机
    发表于 07-28 09:23

    小体积4G工业路由器自助售货机无人值守断网自动修复联网

    方案需求自动售货机的应用日渐广泛,如城市街头、酒店、机场、居民社区、娱乐公共场所、办公大楼、商场、学校等场所,便捷式的服务和管理渐渐深入工作生活。自动售货机的管理逐步趋于无线管理方式,主要通过互联网
    发表于 02-07 13:52

    嵌入式自动售货机能实现什么功能?

    我们知道,智能设备的根本在于嵌入式系统的开发应用(嵌入式系统开发流程),随着电子技术不断的发展,很多智能化设备逐步取代了人工劳动,自动售货机就是其中一种基于嵌入式系统的智能化设备(什么
    发表于 04-17 08:14

    基于80C51单片机的自动售货机设计

    公司出品的80C51单片机为核心的自动售货机,并且着重详细地介绍了自动售货机的整体系统设计方案、硬件选择基础、软件使用方法及技巧。以80C51作为CPU处理单元连接各个功能模块;以4*4矩阵键盘
    发表于 12-02 07:30

    RK3399核心板在无人售货机的应用有哪些呢

    RK3399核心板具有哪些特性呢?RK3399核心板在无人售货机的应用有哪些呢?
    发表于 03-07 07:07

    自动售货机短信报警系统

    关键词 ZWG-03A 智能短信设备、自动售货机、短信报警摘 要 本文介绍 ZWG-03A 在自动售货机短信报警系统中的应用
    发表于 11-04 11:18 86次下载

    智能自动售货机售货

    英特尔打造核心技术智能自动售货机售货 .
    发表于 12-28 18:09 0次下载

    PLC售货机

    使用三菱PLC,拥有售货机简单功能,可用,无错误
    发表于 06-24 14:36 10次下载

    一种基于 PLC 的自动售货机系统的设计

    一种基于 PLC 的自动售货机系统的设计王晓丽摘要:设计一种可编程序控制器 PLC 控制的自动售货机控制系统
    的头像 发表于 03-29 10:12 1.3w次阅读

    基于Zigbee和物联网的自动售货机系统

    结合Zigbee技术、物联网技术和手机扫码支付技术,以STM32和Arduino为主控芯片,设计了一种自动售货机系统系统可实现购买商品的线上/线下支付,运营商通过短信可及时了解
    发表于 04-26 10:17 25次下载

    32-基于单片机的售货机系统

    基于单片机的售货机系统
    发表于 11-18 09:51 14次下载
    32-基于单片机的<b class='flag-5'>售货机</b><b class='flag-5'>系统</b>

    基于ARM硬件的智能售货机终端

    启扬智能为售货机行业提供了基于ARM架构搭载Android系统的智能售货机硬件解决方案。
    的头像 发表于 07-27 15:18 678次阅读
    基于ARM硬件的智能<b class='flag-5'>售货机</b>终端

    才茂智能售货机解决方案

    随着物联网技术的发展,移动支付和无人零售的流行,自动售货机创新新模式逐渐占据市场。据中商产业研究院的预测,我国在2023年将会拥有127.7万台自动售货机,销售额可达375亿人民币,自动售货机
    的头像 发表于 08-16 10:14 611次阅读
    才茂智能<b class='flag-5'>售货机</b>解决方案