“我们不做一锤子买卖,只做技术成长的长期伙伴!”
目录
一、视频展示
基于stm32的智能外卖柜系统-视频分享
二、项目简介
主控:STM32F103C8T6
显示:OLED显示屏
声光报警:蜂鸣器+led小灯
1、矩阵按键
2、GSM短信模块
3、继电器(柜门)+继电器(加热)
4、DS18B20温度传感器
功能:
1、 屏幕显示
用来显示发送取件码时的输入状态,和输入取件码的显示,包括模拟电子锁的状态。
2、短信发送自定义验证码
外卖员可打开电子锁并输入验证码并将验证码发送给自己输入的手机号。
3、用户通过短信验证码打开继电器
用户接收到验证码后,输入正确的验证码,会打开继电器(模拟电子锁)。
4、蜂鸣器提醒
当密码错误时,蜂鸣器会滴滴叫,提示密码错误。
5、自定义温度阈值
当温度低于所设阈值时,自动打开加热继电器
三、原理图设计
四、PCB硬件设计
五、程序设计
#include "stm32f10x.h" // Device header
#include "delay.h"
#include "lcd.h"
#include "IOput.h"
#include "sim900a.h"
#include "usart.h"
#include "ds18b20.h"
u8 mode,dec_wd=40;
#define mode_free 0
#define mode_courier 1
#define mode_user 2
u8 busy_flag;
#define busy 1
#define free 0
u8 KEY_ADD_flag;
#define finish 1
char phone_num[11],phone_place,phone_input_flag,packed_flag;
char English_message[]={"Pickup error!!"}; //英文短信内容
char phonenumber[]={"11111111111"}; //接受短信的号码
char pickup_code[6],pickup_code_place,pickup_input_flag;
char user_code[6],user_code_place,user_input_flag;
void show_free(void)
{
OLED_ShowCH(64,0,"阈值:"); //智能快递柜
OLED_ShowNum(104,0,dec_wd,2,16);
OLED_ShowCH(0,3,"送餐员请按");
OLED_ShowCH(0,6,"取餐请按");
OLED_ShowString(80,3,"SET",16);//快递员请按set
OLED_ShowString(64,6,"*",16);//取件请按*
}
void show_sending(void)
{
OLED_ShowCH(0,0," 送餐员模式 "); //快递员模式
OLED_ShowCH(0,2,"短信发送中");
OLED_ShowCH(0,4,"请稍后");
OLED_ShowString(48,4,"...",16);//请稍候...
}
void show_courier(void)
{
int i;
OLED_ShowCH(0,0," 送餐员模式 "); //快递员模式
OLED_ShowCH(0,2,"请输入取餐人号码");
// Display phone_num
for (i = 0; i <= 11; i++) {
if (i< phone_place) {
OLED_ShowChar(8 * i, 4, phone_num[i] + '0', 16);
} else {
OLED_ShowChar(8 * i, 4, ' ', 16);
}
}
OLED_ShowCH(0,6,"取餐号");
OLED_ShowChar(48,6,':',16);
// Display pickup_code
for (i = 0; i < 6; i++)
{
if (i < pickup_code_place)
{
OLED_ShowChar(8 * (i + 7), 6, pickup_code[i] + '0', 16);
}
else
{
OLED_ShowChar(8 * (i + 7), 6, '*', 16);
}
}
}
void show_user(void)
{
int i;
OLED_ShowCH(0,0," 取餐模式 "); //送餐员模式
OLED_ShowCH(0,3,"请输入取餐号");
OLED_ShowCH(0,6,"取餐号"); // 取件号
OLED_ShowChar(48,6,':',16);
// Display pickup_code
for (i = 0; i < 6; i++)
{
if (i < user_code_place)
OLED_ShowChar(8 * (i + 7), 6, user_code[i] + '0', 16);
else
OLED_ShowChar(8 * (i + 7), 6, '*', 16);
}
}
void code_right(void)
{
OLED_ShowCH(0,2,"取餐号正确"); //取件码正确
OLED_ShowCH(0,4,"请及时取走");
}
void code_error(void)
{
static int error_count = 0; // 静态变量,只会初始化一次,保留上一次的值
OLED_ShowCH(0,2,"取餐号错误");
OLED_ShowCH(0,4,"请重试");
OLED_ShowCH(0,6,"或联系管理员");
error_count++; // 每次输入错误,计数器加 1
if (error_count == 3)
{
sim900a_send_English_message(English_message, phonenumber); // 发送短信
//char English_message[]={"WARNING!!"}; //英文短信内容
//char phonenumber[]={"18101438049"};
error_count = 0; // 计数器清零
Usart_SendString2(USART1,"取餐异常 请管理员注意\r\n");
}
}
int main (void)
{
char i;
char phone_str[12],code_str[7]; // 为11位手机号码和空字符(null terminator)分配空间
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
output_init();
input_init();
Usart1_Init(9600); // 串口1,打印信息用
Usart3_Init(38400); // 串口3,驱动SIM900A用
OLED_Init();
delay_ms(1);
OLED_Clear();
DS18B20_Init();
Usart_SendString2(USART1,"送餐员请按set键 取件请按*键 \r\n");
while(1)
{
if(wd<=dec_wd)
JDQ1=0;
else
JDQ1=1;
temp_get();
key_num = key_scan(1);
if(key_num == KEY_SET && busy_flag == free && packed_flag == 0)
{
Usart_SendString2(USART1,"送餐员模式 请输入手机号码及取件码\r\n");
mode = mode_courier;
phone_input_flag = 0;
OLED_Clear();
}// 判断是否进入用户模式
if(key_num == KEY_Asterisk && busy_flag == free && packed_flag == 1)
{
Usart_SendString2(USART1,"取餐模式 请输入取件码\r\n");
mode = mode_user;
OLED_Clear();
}// 显示空闲模式
if(mode == mode_free)
{
show_free();
OLED_ShowCH(0,0,"温度:"); //智能快递柜
OLED_ShowNum(40,0,wd,2,16);
if(key_num==KEY_DEC)
{
dec_wd++;
if(dec_wd>=100)
dec_wd=0;
}
}
if(mode == mode_courier)
{
show_courier(); // 显示模式界面
busy_flag = busy; // 设置忙碌标志位
if(key_num <= 9 && phone_input_flag == 0)// 处理手机号输入
{
phone_num[phone_place] = key_num; // 存储输入的数字
phone_place++; // 移动到下一个位置
if(phone_place >= 11) // 检查是否输入了11位数字
{
phone_place = 11; // 防止数组越界
key_num = KEY_NONE; // 清除按键值
}
}
else if (key_num == KEY_Asterisk && phone_input_flag == 0 && phone_place > 0)// 处理退格键
{
phone_place--; // 移动到前一个位置
}
else if (key_num == KEY_Hashtag && phone_place == 11)// 处理手机号确认键
{
phone_input_flag = 1; // 设置已确认手机号标志位
for (i = 0; i < 11; i++)
{
phone_str[i] = phone_num[i] + '0';
}
phone_str[11] = '\0'; // 添加空字符表示字符串结束
}// 处理取件码输入
if(key_num <= 9 && phone_input_flag == 1 && pickup_input_flag == 0)
{
pickup_code[pickup_code_place] = key_num; // 存储输入的数字
pickup_code_place++; // 移动到下一个位置
if(pickup_code_place >= 6) // 检查是否输入了6位数字
{
pickup_code_place = 6; // 防止数组越界
key_num = KEY_NONE; // 清除按键值
}
}
else if (key_num == KEY_Asterisk && phone_input_flag == 1 && pickup_input_flag == 0 && pickup_code_place > 0)// 处理取件码退格键
{
pickup_code_place--; // 移动到前一个位置
}
else if (key_num == KEY_Hashtag && pickup_code_place == 6)// 处理取件码确认键
{
pickup_input_flag = 1; // 设置已确认取件码标志位
for (i = 0; i < 6; i++)
{
code_str[i] = pickup_code[i] + '0';
}
code_str[6] = '\0'; // 添加空字符表示字符串结束
}
if(phone_input_flag == 1 && pickup_input_flag == 1 && key_num == KEY_SAVE)// 处理保存键
{
OLED_Clear();
show_sending();
sim900a_send_English_message(code_str, phone_str); // 发送短信
Usart_SendString2(USART1,"短信已发送 \r\n");
phone_input_flag = 0;
pickup_input_flag = 0;
phone_place = 0;
pickup_code_place = 0;
busy_flag = free;
mode = mode_free;
Usart_SendString2(USART1,"送餐员请按set键 取件请按*键 \r\n");
packed_flag = 1;
Delay_50ms(100);
OLED_Clear();
}
}
if(mode == mode_user)
{
show_user(); // 显示用户模式界面
busy_flag = busy; // 设置忙碌标志位
if(key_num <= 9 && user_input_flag == 0)// 处理取件码输入
{
user_code[user_code_place] = key_num; // 存储输入的数字
user_code_place++; // 移动到下一个位置
if(user_code_place >= 6) // 检查是否输入了6位数字
{
user_code_place = 6; // 防止数组越界
key_num = KEY_NONE; // 清除按键值
}
}
else if (key_num == KEY_Asterisk && user_input_flag == 0 && user_code_place > 0)// 处理取件码退格键
{
user_code_place--; // 移动到前一个位置
}
else if (key_num == KEY_Hashtag && user_code_place == 6)// 处理取件码确认键
{
user_input_flag = 1; // 设置已确认取件码标志位
}
if(user_input_flag == 1 && key_num == KEY_SAVE)// 处理保存键
{
OLED_Clear();
user_input_flag = 0;
user_code_place = 0;
busy_flag = free;
// 检查输入的取件码是否正确
if(user_code[0] == pickup_code[0] && user_code[1] == pickup_code[1] && user_code[2] == pickup_code[2] && user_code[3] == pickup_code[3] && user_code[4] == pickup_code[4] && user_code[5] == pickup_code[5])
{
JDQ=0;
code_right(); // 取件码正确
Usart_SendString2(USART1,"取餐码输入正确,柜门已打开 \r\n");
Delay_50ms(6000);
packed_flag = 0;
JDQ=1;
}
else
{
code_error(); // 取件码错误
Usart_SendString2(USART1,"取餐码输入错误请重新输入 \r\n");
}
mode = mode_free;
Usart_SendString2(USART1,"送餐员请按set键 取件请按*键 \r\n");
Delay_50ms(6000);
OLED_Clear();
}
}
if(key_num == KEY_ADD)
{
sim900a_send_English_message(English_message, phonenumber); // 发送短信
}
}
}
六、资料分享
点击即可查看当前资料分享。