一、项目介绍

1.课题意义

当今时代,国内信息化步伐逐渐加快,随着互联网和电子商务的迅速发展和普及,网络购物已成为人们生活中不可缺少的一部分。现在快递服务业已发展到一定规模,但是快递服务效率却停滞不前。一个好的物流公司想要在这个社会站稳脚跟,需要的不仅仅是传输速度,更重要的是用合理的方法来加快精简各个步骤所需要花费的时间和精力,而快递网点系统是物流这个大模块中一个重要的子系统。单纯的人工取货费时费力,本设计以取件码为依据来实现快递的货物识别,取快递时出示取件码,扫码之后,对应的货物自动发声或发光提示其所在位置,据此想法,从而设计本系统。

2.实现要求

本课题是设计一个基于单片机的快递网点货物识别系统,以扫码模块、基于单片机的货物识别等关键技术为重点研究对象设计系统,研究设计的目标是在快递网点取货时更加方便,让客户在取货时出示取件码,扫码之后,对应的货物自动发声或者发光提示其所在位置,便于客户快速取件成功。同时需要了解系统原理、原理、特点、控制方式、应用情况、工作流程等,实现系统货物识别、声光控制等基本功能要求。


二、原件清单

  • Stc89c52Rc*1
  • 单片机最小系统*1
  • QX1100扫码器*1
  • 有源蜂鸣器*3
  • LED发光二极管*3
  • 1k电阻*12
  • 330Ω电阻*3
  • npn三极管*3
  • 杜邦线 若干
  • 排针 若干

三、原理框图

快递信息二维码生成软件流程图
软件

快递信息二维码读取硬件流程图
硬件

三、电路连接

protues仿真连接(仅供参考)
图中1、2、3为三个子端设备,即贴在快递上用来声光报警的设备。仿真图仅供连接参考,我本身是在草稿纸上画的线路因此这个仿真只体现大体思路。

注意:实际连接时P2口需接1k的上拉电阻来稳压,发光二极管串联330欧姆电阻,三极管基极接1k电阻。


四、实物展示

1.软件展示

软件界面

  • 在最上方生成二维码。
  • 中间填入快递货架号,格式为xxx(排、行、个,如:123,代表第一排第二行第三个)。
  • 点击录入会自动生成二维码并记录进快递列表。
  • 点击快递列表即可查看存入快递。
  • 点击“关闭”关闭应用。
  • 在qq邮箱栏,输入qq邮箱点击发送会将二维码以邮件附件的形式发送给用户。
  • 最下方是信息提示栏。

2.硬件展示

背面
背面(三个子端)
正面
正面(扫码器)


五、程序代码

1.软件程序

软件是基于unity进行开发的,之所以不选用VS开发是因为对我个人来说unity的ui设计更加直观明了。两者都是用的C#语言,因此在代码方面实际上差别并不很大。以下贴一下关键代码:
(1)QQ邮件发送代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
using UnityEngine;
using System.Collections;
using System;
using System.Net;
using System.Net.Mail;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using UnityEngine.UI;
public class Mail : MonoBehaviour
{
public GameObject Text_02,send;
public Vector2 creatPosition;

public void Update()
{
if (GameObject.Find("QQMileAdress").GetComponent<Text>().text.Length <= 14)
{
send.GetComponent<Button>().interactable = false;
}
else
{
send.GetComponent<Button>().interactable = true;
}
}

public void SendEmail()
{
MailMessage mail = new MailMessage();

mail.From = new MailAddress("xxx@qq.com");//发件人
mail.To.Add(GameObject.Find("QQMileAdress").GetComponent<Text>().text);//收件人
mail.Subject = "Test Mail";//标题
mail.Body = "This is for Me";//内容
mail.Attachments.Add(new Attachment(Application.dataPath + "/" + "QR.png"));//附件

SmtpClient smtpServer = new SmtpClient("smtp.qq.com");
smtpServer.Credentials = new System.Net.NetworkCredential("xxx@qq.com", "xxxxxxxxxxxxxx") as ICredentialsByHost;
//Credentials证书 NetworkCredential网络证书 xxxxxxxxxxxxxx邮箱授权密码!
smtpServer.EnableSsl = true;
ServicePointManager.ServerCertificateValidationCallback =
delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{ return true; };

smtpServer.Send(mail);
Instantiate(Text_02, creatPosition, Quaternion.identity, GameObject.Find("Canvas").transform);
}
}

(2)QR码生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using ZXing;
using ZXing.QrCode;
using System.IO;

public class QR_Code : MonoBehaviour
{
public string QrCodeStr;
public List<string> Mylist;
public GameObject Text, createPosition;
//在屏幕上显示二维码
public RawImage image;
public Text Items;
//存放二维码
Texture2D encoded;
int Nmuber = 0;


void Start()
{
encoded = new Texture2D(256, 256);
}


void Update()
{
if (Input.GetKeyDown(KeyCode.Return))
{
Sign();
}
}


/// 定义方法生成二维码
private static Color32[] Encode(string textForEncoding, int width, int height)
{
var writer = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new QrCodeEncodingOptions
{
Height = height,
Width = width
}
};
return writer.Write(textForEncoding);
}


/// 生成二维码
public void Btn_CreatQr()
{

if (QrCodeStr==null || GameObject.Find("number").GetComponent<Text>().text.Length>0)
{
QrCodeStr = GameObject.Find("number").GetComponent<Text>().text;
Mylist.Add(QrCodeStr+"\n");
//二维码写入图片
var color32 = Encode(QrCodeStr, encoded.width, encoded.height);
encoded.SetPixels32(color32);
encoded.Apply();
//生成的二维码图片附给RawImage
image.texture = encoded;
}
else
{
Instantiate(Text, createPosition.transform.position, Quaternion.identity,transform);
}
}

public void Sign()
{
Btn_CreatQr();
SaveTextureToFile();
Nmuber++;
if (Nmuber >= QrCodeStr.Length)
{
Nmuber = 0;
}
}
public void list()
{
Items.text = null;
foreach (var item in Mylist)
{
Items.text += item;
}
}
public void Quit()
{
Application.Quit();
}

void SaveTextureToFile()
{
var bytes = encoded.EncodeToPNG();
File.WriteAllBytes(Application.dataPath + "/" + "QR.png", bytes);
}
}

(3)52单片机程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include "reg52.h"
#include <stdio.h>

typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
typedef unsigned long u32;

void delay_10us(u16 ten_us);
void delay_ms(u16 ms);


unsigned char num[][10]={"0","1","2","3","4","5","6","7","8","9"};
u8 led[9]={0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
u8 n;
//****************************************************************************************

void delay_10us(u16 ten_us)
{
while(ten_us--);
}
void delay_ms(u16 ms)
{
u16 i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}

//****************************************************************************************
void uart_init(u8 baud)
{
TMOD|=0X20; //设置计数器工作方式2
SCON=0X50; //设置为工作方式1
PCON=0X80; //波特率加倍
TH1=baud; //计数器初始值设置
TL1=baud;
ES=1; //打开接收中断
EA=1; //打开总中断
TR1=1; //打开计数器
}
void main()
{
int r;
uart_init(0XFA);//波特率为9600

while(1)
{
if(n >= '0' && n <= '9')
r=n-'0';
P2=led[r];
//lcd1602_init();//LCD1602初始化
//lcd1602_show_string(0,0,num[r]);//第一行显示
delay_ms(10);
}
}

void uart() interrupt 4 //串口通信中断函数
{
u8 rec_data;

RI = 0; //清除接收中断标志位
rec_data=SBUF; //存储接收到的数据
n=rec_data;
SBUF=rec_data; //将接收到的数据放入到发送寄存器
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
}

有一些用来控制ui动画的小代码就不放出来了,大家根据自己的需要去修改就好。


六、设备运行结果

视频我已上传百度云,需要看设备运行的可以下载来看
链接:百度云
提取码:k2w6