基于Linux C++多线程服务器 + Qt上位机开辟 + STM32 + 8266WIFI的聪明无人 ...

魏晓东  金牌会员 | 2024-6-28 21:51:05 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 497|帖子 497|积分 1491

前言

针对传统超市购物车结账列队时间长、付款效率低的问题,提出了一种更符合现代社会人们购物方式-基于RFID的自助收银体系。习惯了快节奏生活的人们都会选择自助收银机结账,理由显而易见:自助收银机结账很方便,几乎不消列队,也不消近距离和收银员接触,在防疫时期特别感觉安心。而且自助结账对每件物品的售价更是一次清楚地查对,最终需付出合计购物付出自己也更加清楚明了;这两年来,越来越多的智能装备应用在我们的生活范畴里,为我们的生活提供了很多智能和便利。自助收银机从几年前就连续涌入到各地阛阓、超市、便利店,自去年疫情发生后自助收银的需求比例更是呈直线上升趋势。自助收银机的启用,不仅节省了超市的人力开支本钱,也从根本上提升了超市的购物付出效率,在这个快节奏的社会里,智能自助收银机也从根本上提升了超市等
 
     基于Linux C++多线程服务器 + Qt上位机开辟 + STM32 + 8266WIFI的聪明无人超市项目
   
 
技术栈+硬件选型

Linux c++应用编程;
Linux socket编程,多线程编程,实时信号(线程通讯)
Qt/C++ 客户端开辟;
qml(QtLocation)与c++交互 安卓开辟;
Mysql 数据存储;
C语言下位机开辟;
stm32c8t6 下位机(自制,够用,市面价格10r);
RC522(RFID模块 SPI协议) 与白卡通讯 获取卡号;
DTH11 温湿度收罗模块(单总线协议,市面价格 4r);
sg90 舵机模块(PWM协议 市面价9r );
8226 01-s WIFI模块(uart协议 市面价格5r) 毗连 C++ 服务器;
蜂鸣器  是为了有白卡与RFID交互声音
GY-NEO6MV2 GPS模块(uart协议 市面价18)
 
 
总计划流程

本次计划的->基于RFID的自助收银体系->计划主要支持的功能和程序如下:
本项目一共有五个程序,Linux C++服务器,Qt管理员端,Qt客户结算端,qml安卓端,单片机下位机端,客户端程序都有服务器断开主动重连(单片机没有,有佬会的话,我想讨教一下)


Linux C++服务器:
       基于 socket 接口编写server服务端程序,监听8888端口,然后创建Mysql数据库毗连,开始监听。
     面向对象程序计划中最重要的一个概念是继续,所以我编写了一个基类mythread,他有一个纯虚函数,参数为一个界说的一个参数类,包罗了数据库封装好的对象,需要服务的客户端套接字,还有毗连的客户端网络的信息结构体,当socket客户端乐成接入时,取出该客户端套字和网络信息结构体和主函数的数据库对象来添补参数类,然后服务器端根据客户端发过来的第一个消息判断该客户端是上述哪个客户端,然后创建相应的派生类,填入该参数类,然后让mythread指针去指向这个子类对象,发生动多态,此时运行阶段时才确定函数的入口地址,实行派生类中的继续父类的已经实现的纯虚函数,此时派生类创建一个线程绑定线程处置惩罚函数去服务处置惩罚该socket套接字传过来的消息。绑定不同的线程处置惩罚函数服务不同的客户端程序。一共有四种线程处置惩罚函数服务上述四种客户端程序,由四个不同的基类去绑定。
    本项目的一个最大的特点,难点,单片机只负责发送卡号给服务器,本项目单片机传过来的卡号有以下走向,注册商品,注册会员,结账,商品入购物车,那么我该怎么知道该卡号是用来做什么呢,当时困扰了几天,然后想到Qt的信号与槽机制,联想到Linux 也有实时信号,还可携带参数,该信号是事件发生时对历程的关照机制,也可以把它称为软件中断,Linux 内核界说了 31 个不同的实时信号,信号编号范围为 34~64,我直接拿来做线程通讯,所以现在怎样把他们联系起来呢,当时我想到互斥啥的想法感觉不好实现,然后我就想到了一个方法,就是设置标志位,我设立了一个全局变量 int RES=34,让RES的默认值为34,34很熟悉吧,信号编号范围为 34~64,当单片机收到卡号发给服务器时,服务器直接调用信号发送函数,此时全局变量标志位为34,所以直接发送34这个实时信号,然后触发中断实行这个信号绑定处置惩罚函数。我们一共有四个地方需要用到卡号,资源只有一个,所以当需要实行某个用到卡号的操作时,我先判断该RES的值,如果该值即是34,代表该读卡器为空闲,我就更改RES为 35 ,然后下次单片机发过来卡号,我还是直接调用发送信号,此时标志位为35 所以此时实行 35 的信号处置惩罚函数,实行完函数,需要将RES 置为默认值 34,释放资源,如果当哀求资源时RES不即是 34 代表 读卡器正在被占用,此时回复客户端一个读卡器正忙,以此类推,绑定四个信号处置惩罚函数,处置惩罚这四个操作哀求,一定要释放改为34。我们添加商品到购物车,如果不停点击按钮获取来获取资源就会显得很笨拙,所以默认的 34 信号处置惩罚函数为添加商品入购物车,在没有人改变标志位的情况下,就是实行商品入购物车。
   本项目,由于多个线程对数据进行增编削查,存在竞争冒险,所以在实行数据库增编削操作时,我加入条 Mysql 事务操作语句,事务是一个原子操作,实行增编削操作前 开始事务,实行结束,提交事务。
   总结 : 单片机的所有数据全部转发给服务器,服务器跟据消息的种类,标志位,进行处置惩罚后,分发给指定客户端,完成一系列操作。
主循环如下:
  1. while (1)
  2.    {
  3.       myret=server.client_socket();
  4.       myret.my_sql=sql_typ;
  5.       std::cout<<"new connect !!"<<endl;
  6.       std::string str=server.readbuf();
  7.       int num;
  8.       istringstream a(str);
  9.       a >> num;
  10.    
  11.      switch (num)
  12.   {
  13.      {
  14.      case 100001:   
  15.    
  16.          Mythread *android_thread=new androidthread;
  17.          android_thread->thread_start(myret);
  18.          std::cout<<"安卓客户端连接成功"<<std::endl;
  19.      }
  20.          break;
  21.      case 100101:
  22.      {
  23.           Mythread  *admin_thread=new adminthread;   
  24.           admin_thread->thread_start(myret);
  25.           std::cout<<"PC客户端连接成功"<<std::endl;
  26.      }
  27.          break;
  28.      case 100111:
  29.      {
  30.           Mythread  *cust_thread=new custthread;   
  31.           cust_thread->thread_start(myret);
  32.           std::cout<<"ARM客户端连接成功"<<std::endl;
  33.      }
  34.          break;
  35.      case 101001:
  36.      {
  37.           Mythread   *mcu_thread=new mcuthread;   
  38.           mcu_thread->thread_start(myret);
  39.           std::cout<<"STM32客户端连接成功"<<std::endl;
  40.      }  
  41.          break;
  42.      default:
  43.          std::cout<<"未知的错误"<<std::endl;   
  44.          break;
  45.      }
  46.         
  47.    }
  48.    
复制代码

 
Qt管理员端:
Qt管理员端具有的功能,注册商品,注册会员,充值,检察销售记录,日志。
起首毗连服务器乐成,主动发指令给服务器,服务器从数据库取出数据发给客户端,初始化,商品,会员,服务器上有一个文本文件记录销售记录,我给服务器文本巨细做了一个限制,如果巨细大于1M清空文件,清除销售记录,客户端可以通过点击按钮发送一个指令,获取文本内容表现销售记录,日志的话就是从服务器运行阶段开始,对会员充值,会员烧毁,商品添加,商品删除,都会直接记录,服务器退出主动烧毁。
Qt客户结算端:
Qt客户结算端具有的功能:添加商品入购物车,结算,表现从服务器端获取的温湿度数据。
商品入库取出价格,然后相加,点击结算按钮将总价格发给服务器,然后服务器判断标志位,如果读卡器被占用则取消结账,反之。此时标志位改变,下次刷的卡将充当会员卡进行数据比对,余额不足则返回数据给客户端,反之。实行完毕释放资源置为34。
qml安卓端:
qml安卓端具有的功能:地图表现当前手机与MCU的位置和距离,在售商品查询,购买记录查询,姓名号码登录。
这个安卓端实在有点多此一举的意思,我就是想夸耀一下我的GPS模块,然后地图表现当前手机GPS数据与MCU的GPS模块的距离和位置,功能太单调了,我就加了一个在售商品检察功能,然后给Mysql添加了1000巨细的varcahr字段,存储当前用户购买记录,加了一个登录界面。
   qml的教程挺少,之前学过一遍,没有实时巩固,当时写这个qml真的炸裂,很多坑。想入门qml也简朴,学一下qml与C++交互,信号与槽,函数互调。qml界面的话让gpt去写,百度CV。
STM32单片机开辟:
stm32具体的功能:stm32c8t6主控芯片,DTH11温湿度收罗发送给服务器客户端表现,sg90舵机模仿开门,GY-NEO6MV2 GPS 获取GPS,8226 01-s 与tcp 服务器数据交互,RC522与白卡交互,蜂鸣器提示刷卡乐成。
32这调试是最恶心的,一般调试是直接通过串口打印到电脑,但是串口用来初始化8266了,问题就是这个8266,当时毗连服务器不停毗连不上,我就去找缘故原由,有供电缘故原由,还有at指令的缘故原由,供电最好直接从32vcc上引出来,由于我是根据客户端程序毗连乐成后根据发过来的第一条数据来创建对应线程服务,不知道为啥这个32程序按复位键的话8266没有从第一条指令开始运行,然后就创建不了对应线程服务,只能断电,然后在重新烧录一次,调试巨麻烦。
GPS的话也是串口通讯,重新初始化一个串口资源就好了,这个信号很差必须在阳台上,有条件的还是买好一点的吧我收罗数据还有抱着一大堆线接个充电宝在阳台调试。gps数据有个NMEA协议,需要对数据分析出经纬度,有很多范例数据,最重要的一条就是包罗经纬度的 
  1.  
复制代码
"$GPGLL,2547.35222,N,11306.12283,E,111129.00,A,A*6D";
这是当时当时在阳台调试出来的,这里我偷了个小懒,由于c语言字符串处置惩罚很鸡肋,所以我直接在32这里过滤出这条消息,一整条发给服务器,然后服务器发给Qt客户端,让Qt的QString去解分割分析处置惩罚,分分钟的事情,封装好的库就是简朴
 

很简朴吧!
8266的话我初始化很随意,快准狠,直接配置tcp,毗连WiFi然毗连服务器,哈哈。

温湿度舵机什么的没什么好讲,一个单总线写按时序拉低拉高电平就行了,一个设置指定占空比。RC522的话,驱动很复杂,我程度不太行,写不出来,直接调厂家的库了。
主循环就这样了

 

 

末了留言:

本项目一共写了半个月,遇到很多坑,当时地图传的坐标经纬度传犯了,调试了一下战书才发现了这个问题,还有Linux 实时信号 是一个软件中断嘛,然后当时server的while循环的accept直接导通解除阻塞了,程序直接崩溃。查了很多资料才知道了,末了加一个goto语句哈哈就解决了。
  1. ret_client  Myserver::client_socket()
  2. {
  3. reboot:
  4.      ret_client ret;
  5.   
  6.      m_client_socket= accept(m_socket,(struct sockaddr *)&ret.client_struct,&len);
  7.      if(m_client_socket==-1)
  8.      {
  9.        goto reboot;
  10.      }
  11.     ret.client_socket=m_client_socket;
  12.     return ret;
  13. }
复制代码
这是sql语句啊,本人挺懒的,全用varchar了。
  1. CREATE DATABASE shopping;
  2. CREATE TABLE users(
  3. id VARCHAR(20) unique key,
  4. name VARCHAR(50),
  5. phone VARCHAR(15) unique key,
  6. balance VARCHAR(25),
  7. text VARCHAR(1000)
  8. )
  9. CREATE TABLE me(
  10. pid VARCHAR(20) unique key,
  11. pname VARCHAR(50),
  12. price VARCHAR(15),
  13. brand VARCHAR(25)
  14. )
复制代码
需要源码的哥们三连加批评邮箱,直接发邮箱
 
 

 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

魏晓东

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表