微信小程序+UDP+wifi8266+l293d扩展板+Arduino uno遥控小车

序言

前面突然看到自己已经落灰的Arduino板子,感觉自己必须做点什么。正好手上有个8266的模块、有个焊接接好的小车、有个落灰的Arduino板子,好巧。正好前几天上过一篇8266模块和微信小程序进行UDP通信的博文,一切都正好,那开搞吧。

前置知识需要的不多
至少要去看看微信小程序关于UDP通信的文档,当然你看我上面的文章也行,感觉还挺详细的,有电脑就行(滑稽~),下面的代码我都只贴最核心的代码,基本上都会覆盖到,如果需要所有项目的源码请一键三连留下邮箱,接下来直接正题

主要涉及的一些东西
wifi8266:

 3V3 3.3V供电,避免使用5V供电RX    UART_RXD,异步串口接受端RST  外部复位引脚,低电平有效,默认高电平IO0 GPIO 0引脚;状态:1.悬空:Flash下载模式和工作模式;2.下拉:串口下载模式EN    使能端口,高电平工作,低电平模块不工作IO2    GPIO2引脚,开机上电时禁止下拉,默认高电平UTXD   UART_TXD,异步串口发送端GND  GND接地引脚


烧录工具

广告请忽略,我买的就是这一套,挺方便的

L293d扩展板

这个没啥好说的,直接插Arduino板子上,下面是太极创客官网的板子介绍,感兴趣可以去看看,别急着吐槽,需要注意的地方我都会在这里说的。比如这里的2号引脚就很重要,没有焊接,这个很关键,esp-01和Arduino串口通信需要用到,板子上的A0-A5也可以作为软串口通信,但是接上esp-01后它无法正常工作(这个可以自己去验证一下,l293d扩展板其实真没什么东西只是为了扩展Arduino的功能,单块l293d最多只能控制两个电机,如果是两轮驱动完全没必要买这个板子,但是转向你需要搞一个舵机,供电建议使用9v电源同时为Arduino和l293d供电,电压不足会导致很多奇怪的行为)

Arduino uno

这也没啥好说的,感兴趣就自己去太极创客官网看看介绍,主要的硬件差不多就这几个,后面我会贴一个我自己焊接的图,不急


微信小程序

这个是我自己开发的,因为有的页面空着,发布小程序还被微信驳回了,只能测试玩玩了,不想自己写的话可以扫码体验一把,虽然瑕疵有点多,但是测试还是可以的,后面做新的东西我也会在这个上面继续开发,有需求也可以提,等成熟了可以把代码放github


小程序wifi功能核心代码以及运行界面

背景是一个video标签,不要在意内容,这里准备接入Esp32-cam摄像头


代码 html css js


<video class="video-bg" autoplay controls="{{false}}" src="https://vd4.bdstatic.com/mda-kewsvi1w9u7bv42w/v1-cae/mda-kewsvi1w9u7bv42w.mp4?v_from_s=hkapp-haokan-hnb&auth_key=1669192668-0-0-aefa5c11bf88aacc22c048084a76aadb&bcevod_channel=searchbox_feed&pd=1&cd=0&pt=3&logid=0468789483&vid=1260358254659161368&abtest=&klogid=0468789483"></video>
<view class="wificontainer"><van-row><van-col span="12"><view class="direction" catchtouchmove="move" catchtouchstart="movestart" catchtouchend="moveend" ><view class="point" style="left:{{left+'px'}};top:{{top+'px'}}">+</view></view></van-col><van-col span="12"><view class="option"><view class="btnFore" bindtap="instructions" data-message="accelerate">加速</view><view class="btnBack" bindtap="instructions" data-message="decelerate">减速</view><view class="btnStop" bindtap="instructions" data-message="stop">停止</view></view></van-col></van-row></view>
.video-bg{width:100vw;height:100vh;position:absolute;z-index:-100;
}
//这里这个style标签只是为了当前显示,在微信小程序中使单个文件
<style>
.wificontainer{height: 100vh;width:100vw;position: relative;z-index:100;background: transparent;position:absolute;/* background-position: left top;background-repeat: no-repeat;background-position: center;background-size: cover;background-image: url('https://pic.rmb.bdstatic.com/c614c350d47179742c388cf996c3b23d.jpeg'); *//* https://pic.rmb.bdstatic.com/c614c350d47179742c388cf996c3b23d.jpeg */
}
.van-row{height:100%;text-align: center;vertical-align: middle;/* margin:10px; */
}
.van-col{height:100%;display: grid;grid-template-columns:100%;grid-template-rows: 100%;justify-items: center;align-items: center;/* border:1px solid red; */
}
.direction{height:140px;width:140px;line-height:140px;border-radius: 50%;color:#fff;border:1px solid #ccc;background-color: rgba(66, 65, 57, 0.2);box-shadow: 0 0 14px #fff inset;position: relative;/* border: 1px solid red; */
}
.point{width:50px;height:50px;line-height: 50px;display: inline-block;background-color: rgba(0,0,0,0.4);box-shadow: 0 0 14px #fff inset;border-radius: 50%;position: relative;/* left:00px; *//* vertical-align: center; */color:#fff;/* position: absolute; */
}
/* 操作按钮容器 */
.option{height:100%;width:100%;display: grid;align-items: center;justify-items: center;grid-template-rows: repeat(4,25%);grid-template-columns: repeat(4,25%);}
.btnFore{/* border:1px solid red; */display: inline-block;width:60px;height:60px;line-height:60px;grid-row-start: 2;grid-row-end:3;grid-column-start:3;grid-column-end:4;color:#fff;/* margin:auto; */border:1px solid #ccc;background-color: rgba(66, 65, 57, 0.2);box-shadow: 0 0 14px #fff inset;border-radius: 50%;}
.btnBack{display: inline-block;width:60px;height:60px;line-height:60px;grid-row-start: 3;grid-row-end:4;grid-column-start:3;grid-column-end:4;color:#fff;/* margin:auto; */border:1px solid #ccc;background-color: rgba(66, 65, 57, 0.2);box-shadow: 0 0 14px #fff inset;border-radius: 50%;/* vertical-align: center; */
}
.btnStop{display: inline-block;width:60px;height:60px;line-height:60px;grid-row-start: 2;grid-row-end:3;grid-column-start:2;grid-column-end:3;color:#fff;/* margin:auto; */border:1px solid #ccc;background-color: rgba(192, 17, 66, 0.8);box-shadow: 0 0 14px #fff inset;border-radius: 50%;/* vertical-align: center; */
}
</style>

这里讲一下,因为微信的渲染规则,导致movetouch等方法的触发会有卡顿的情况,所以做了节流处理,有博主说wxs可以解决,可以去试试

// pages/controls/wifi/wifi.js
import Dialog from '@vant/weapp/dialog/dialog';
// import Notify from '@vant/weapp/notify/notify';
Page({/*** 页面的初始数据*/data: {//wifi列表equipmentList:[],//需要发送的数据message:"",udpScoket:{},//记录起点的相对位置originPageX:0,originPageY:0,left:0,top:0,operating:true,address:'192.168.43.3',port:"7788"},arrayBufferToString(arr){var dataview=new DataView(arr);var ints=new Uint8Array(arr.byteLength);for(var i=0;i<ints.length;i++){ints[i]=dataview.getUint8(i);}// console.log(ints)arr=ints;var str = '',  _arr = arr;  for(var i = 0; i < _arr.length; i++) {  var one = _arr[i].toString(2),  v = one.match(/^1+?(?=0)/);  if(v && one.length == 8) {  var bytesLength = v[0].length;  var store = _arr[i].toString(2).slice(7 - bytesLength);  for(var st = 1; st < bytesLength; st++) {  store += _arr[st + i].toString(2).slice(2);  }  str += String.fromCharCode(parseInt(store, 2));  i += bytesLength - 1;  } else {  str += String.fromCharCode(_arr[i]);  }  }  return str; },/*** 生命周期函数--监听页面加载*/onLoad(options) {let that=this;let is = wx.canIUse('createUDPSocket');if(is){//开启UDP监听this.data.udpScoket =  wx.createUDPSocket();this.data.udpScoket.bind(4321) this.data.udpScoket.onListening(function (res) {console.log('监听中.....');console.log(res);})this.data.udpScoket.onError(function(err) {wx.showToast({title: err.message,})})this.data.udpScoket.onMessage(function(res) {console.log(res);let mess=that.arrayBufferToString(res.message);console.log(mess)})}else{this.showToast({title:"当前基础库版本不支持createUDPSocket"})}},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {// wx.startLocalServiceDiscovery({//     serviceType: '_http._tcp.',//     success: (res)=> {//     console.log(res)//     }//   })//   wx.onLocalServiceResolveFail((res)=>{//     console.log(res);// })//   wx.onLocalServiceFound((resp)=>{//     console.log(resp);// })},//向wifi模块发送数据instructions(e){let message=e.currentTarget.dataset.message;console.log(message)this.data.udpScoket.send({address: this.data.address,port: this.data.port,message: message,})},/*** 生命周期函数--监听页面显示*/onShow() {},/*** 生命周期函数--监听页面隐藏*/onHide() {},//防抖操作 只执行最后一次debounce(fn, delay){let timer = null;return function(){clearTimeout(timer);timer = setTimeout(()=> {fn.apply(this, arguments);}, delay)}},//节流操作 间隔执行throttle(fn, delay){let that=this;return function(){if(that.data.operating) {that.data.operating = false;setTimeout(()=> {fn.apply(this, arguments);that.data.operating = true;}, delay)}}},//计算斜边maxBorder(l,t){let leftAbs=Math.abs(l);let topAbs=Math.abs(t);let hypotenuse=Math.pow(leftAbs,2)+Math.pow(topAbs,2)// console.log()let sqrthy=Math.sqrt(hypotenuse).toFixed()return sqrthy;},//节流方式向wifi模块投递命令intervalCall(intervalTime,instruction){this.throttle(()=>{console.log(instruction)this.data.udpScoket.send({address:this.data.address,port:this.data.port,message:instruction})},intervalTime)(); },//记录事件触发movestart(e){//固定坐标中心点// console.log("========开始移动给定相对盒子的位置=======")this.setData({originPageX:165.30,originPageY:187.95,left:0,top:0})
},move(e){let tempT=e.changedTouches[0].pageY-this.data.originPageY;let tempL=e.changedTouches[0].pageX-this.data.originPageX;let sqrt=this.maxBorder(tempL,tempT);// console.log(sqrt);if(sqrt<=70){this.setData({left:tempL,top:tempT })}else{// console.log("========移动中的坐标=======")let calcLeft= (70*((tempL/sqrt).toFixed(2)));let calcTop=(70*((tempT/sqrt).toFixed(2)));this.setData({left:calcLeft,top:calcTop})// console.log(calcLeft,calcTop)if(calcLeft>0&&calcTop>0){if(Math.abs(calcLeft)>=Math.abs(calcTop)){//节流方式发布方向指令    this.intervalCall(50,"right");}else{this.intervalCall(50,"backward");}}else if(calcLeft<0&&calcTop>0){if(Math.abs(calcLeft)>=Math.abs(calcTop)){this.intervalCall(50,"left");}else{this.intervalCall(50,"backward");}}else if(calcLeft<0&&calcTop<0){if(Math.abs(calcLeft)>=Math.abs(calcTop)){this.intervalCall(50,"left");}else{this.intervalCall(50,"forward");} }else if(calcLeft>0&&calcTop<0){if(Math.abs(calcLeft)>=Math.abs(calcTop)){this.intervalCall(50,"right");}else{this.intervalCall(50,"forward");}       }}},moveend(e){// console.log("========移动终止置位置到起点=======")// console.log(Object.defineProperty(this.data,"oprating",{value:false}))// console.log(this.data.oprating)this.setData({originPageX:165.30,originPageY:187.95,left:0,top:0})},//udp通信,需要wifi模块与手机接入同一个网段UDPComunicate(){const UDP= wx.createUDPSocket();UDP.bind();UDP.send({address:this.address,port:this.part,message:this.message})},onUnload() {if(this.data.udpScoket){this.data.udpScoket.close();}//  wx.stopLocalServiceDiscovery({//     success:(res)=>{//         console.log(res);//     },//     fail:(err)=>{//         console.log(err)//     }// })},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh() {},/*** 页面上拉触底事件的处理函数*/onReachBottom() {},/*** 用户点击右上角分享*/onShareAppMessage() {}
})

wifi8266代码

因为微信mDNS没有接入成功所以我把wifi和密码写死的,个人手机热点先改成这样吧,用这个小程序的都通用(滑稽~)

 //程序如下:
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266WiFi.h>
#define ssid      "wifi8266"       //WIFI名字最好别包含特殊符号 不然连接不上
#define password  "987654321"     //WIFI密码
unsigned int localUDPPort = 7788;  //本地监听端口
unsigned int remoteUDPPort = 8877;  //远程监听端口
char incomingPacket[255];  // 保存Udp工具发过来的消息WiFiUDP UDPInstance;//实例化WiFiUDPvoid setup()
{Serial.begin(115200);delay(10);Serial.printf("正在连接 %s ", ssid);WiFi.begin(ssid, password);//连接到wifiSerial.println();while (WiFi.status() != WL_CONNECTED)//等待连接{delay(600);Serial.print(".");}Serial.println("wifi连接成功");//启动mdns功能if(WiFi.status() == WL_CONNECTED) //wifi连接成功后{if (UDPInstance.begin(localUDPPort)) { //启动Udp监听服务Serial.println("监听成功");Serial.printf("现在收听IP:%s, UDP端口:%d\n", WiFi.localIP().toString().c_str(), localUDPPort); //wifi模块的ip地址在这里获取} else {Serial.println("监听失败");}}}
void loop()
{if (UDPInstance.parsePacket()) //解析包不为空{// 读取Udp数据包并存放在incomingPacketint len = UDPInstance.read(incomingPacket, 255);//返回数据包字节数if (len > 0){incomingPacket[len] = 0;//清空缓存//strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数。//基本形式为strcmp(str1,str2),若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数。if (strcmp(incomingPacket, "forward") == 0){Serial.println                                                                                                                                                                                                                                    (incomingPacket);}else if(strcmp(incomingPacket, "backward") == 0){Serial.printf(incomingPacket);}else if(strcmp(incomingPacket, "left") == 0){Serial.printf(incomingPacket);}else if(strcmp(incomingPacket, "right") == 0){Serial.printf(incomingPacket);}else if(strcmp(incomingPacket, "accelerate") == 0){Serial.printf(incomingPacket);}else if(strcmp(incomingPacket, "decelerate") == 0){Serial.printf(incomingPacket);}else if(strcmp(incomingPacket, "stop") == 0){Serial.printf(incomingPacket);}else{Serial.printf("无效命令");} }}
}//向udp工具发送消息
void sendCallBack(const char *buffer)
{UDPInstance.beginPacket(UDPInstance.remoteIP(), remoteUDPPort);//配置远端ip地址和端口UDPInstance.write(buffer); //把数据写入发送缓冲区UDPInstance.endPacket(); //发送数据
}

L293D代码(叫Arduino代码我感觉更合适)

速度数值可以自己调整,电压推荐9v,6v看起来病秧秧的,模块四个端子默认的频率输出并不相同,介意的可以自己调平

··#include <AFMotor.h>
#include<SoftwareSerial.h>
SoftwareSerial softSerial(2,3);//软串口,用于接收命令//常量
#define MAX_SPEED 255 //变量
String incomingPacket="";
String directionW="fore";
int speedSet = 0;
int currentSpend=120;AF_DCMotor motor1(1); // 这4条语句的作用是建立4个直流电机对象,它们的名称分别是:motor1/2/3/4.AF_DCMotor motor2(2); AF_DCMotor motor3(3); AF_DCMotor motor4(4); void setup() {delay(100);//读取wifi模块参数作为指令softSerial.begin(115200);Serial.begin(115200);softSerial.listen();motor1.setSpeed(120); motor2.setSpeed(120);motor3.setSpeed(120); motor4.setSpeed(120); motor1.run(RELEASE); // 这4条语句的作用是让4个电机在启动时停止转动motor2.run(RELEASE); motor3.run(RELEASE); motor4.run(RELEASE);
}//执行流程  指令->微信小程序UDP->wifi8266->Arduino->驱动电机动作void loop() {//循环接收指令   if(softSerial.available()>0){incomingPacket=softSerial.readString();Serial.println(incomingPacket);if (incomingPacket== "forward"){moveForward();}else if(incomingPacket== "backward"){moveBackward();}else if(incomingPacket=="left"){turnLeft();}else if(incomingPacket=="right"){turnRight();}else if(incomingPacket== "accelerate"){accelerate();}else if(incomingPacket== "decelerate"){decelerate();}else if(incomingPacket== "stop"){moveStop();}else{//        Serial.print("未匹配到该指令"); } }}//以下为对应操作指令执行的函数
//加速
void accelerate(){//这里不修改运动的方向,只做加速if(currentSpend<=MAX_SPEED-50){currentSpend+=50;motor1.setSpeed(currentSpend);         motor2.setSpeed(currentSpend);         motor3.setSpeed(currentSpend);          motor4.setSpeed(currentSpend);              }else{currentSpend=255;motor1.setSpeed(currentSpend);         motor2.setSpeed(currentSpend);          motor3.setSpeed(currentSpend);         motor4.setSpeed(currentSpend);          }  }
//减速
void decelerate(){if(currentSpend>=50){currentSpend-=50;motor1.setSpeed(currentSpend);          motor2.setSpeed(currentSpend); motor3.setSpeed(currentSpend); motor4.setSpeed(currentSpend); }else{currentSpend=0;motor1.setSpeed(currentSpend);motor2.setSpeed(currentSpend);motor3.setSpeed(currentSpend);motor4.setSpeed(currentSpend);}}
//停止
void moveStop() {motor1.run(RELEASE); motor2.run(RELEASE); motor3.run(RELEASE); motor4.run(RELEASE); currentSpend=120;}
//向前
void moveForward() {delay(100);//防止电压值过低无法工作currentSpend=120;motor1.run(FORWARD);      motor2.run(FORWARD);motor3.run(FORWARD); motor4.run(FORWARD); motor1.setSpeed(currentSpend);          motor2.setSpeed(currentSpend);          motor3.setSpeed(currentSpend);          motor4.setSpeed(currentSpend);          //记录当前的方向,用于转向后的方向保持 directionW=="fore" ;
}
//后退
void moveBackward() {//防止电压值过低无法工作currentSpend=120;//方向motor1.run(BACKWARD);      motor2.run(BACKWARD);motor3.run(BACKWARD);motor4.run(BACKWARD);   //速度motor1.setSpeed(currentSpend);         motor2.setSpeed(currentSpend);         motor3.setSpeed(currentSpend);         motor4.setSpeed(currentSpend);          //记录当前的方向,用于转向后的方向保持directionW=="back";}
//右转
void turnRight() {if(directionW=="back"){motor1.run(BACKWARD);motor2.run(BACKWARD);motor3.run(FORWARD);motor4.run(FORWARD);     delay(300);motor1.run(BACKWARD);      motor2.run(BACKWARD);motor3.run(BACKWARD);motor4.run(BACKWARD); }else if(directionW=="fore"){motor1.run(FORWARD);motor2.run(FORWARD);motor3.run(BACKWARD);motor4.run(BACKWARD);     delay(300);motor1.run(FORWARD);      motor2.run(FORWARD);motor3.run(FORWARD);motor4.run(FORWARD); }else{}motor1.setSpeed(120); motor2.setSpeed(120);motor3.setSpeed(120); motor4.setSpeed(120);
}
//左转
void turnLeft() {if(directionW=="back"){motor1.run(FORWARD);motor2.run(FORWARD);motor3.run(BACKWARD);motor4.run(BACKWARD);     delay(300);motor1.run(BACKWARD);      motor2.run(BACKWARD);motor3.run(BACKWARD);motor4.run(BACKWARD); }else if(directionW=="fore"){motor1.run(BACKWARD);motor2.run(BACKWARD);motor3.run(FORWARD);motor4.run(FORWARD);     delay(300);motor1.run(FORWARD);      motor2.run(FORWARD);motor3.run(FORWARD);motor4.run(FORWARD); }else{}motor1.setSpeed(120); motor2.setSpeed(120);motor3.setSpeed(120); motor4.setSpeed(120);
}

核心的东西差不多就这些,讲一下需要注意的一些地方,烧录的时候记得把9v去掉或者把跳线拔掉二选一,否则烧板子,还有就是wifi模块工作电压3.3v,这个是真坑啊,扩展板唯一输出3.3v的就是跳线针脚那里,5v降压或者9v降压不推荐,太费劲,我直接接的5v,工作时会有wifi模块发烫的问题,希望它能坚持一段时间,还有就是接线,wifi模块的TX引脚接l293d上那个空的针脚,也就是2号,作为串口通信使用,3号针脚要是要向wifi模块回送数据也可以接(但是真的难焊,毕竟封死了,滑稽~),关于wifi8266模块(也就是esp-01)烧录相关的问题,可以看我开头说的那篇文章,最后上个整机图,快乐就是这么朴实无华

微信小程序+UDP+wifi8266+l293d扩展板+Arduino uno遥控小车相关推荐

  1. 微信小程序UDP通信

    微信小程序UDP通信及编码转换 import Encoder from '../../util/Encoder.js' onLoad() {this.udp = wx.createUDPSocket( ...

  2. 微信小程序udp通信连接硬件设备配网

    == 注意:UDP连接只能在局域网才能连接成功 == 设备配网,首先获取当前WIFI 页面加载之后自动获取当前手机连接的WiFi名字 点击获取更多网络,获取附近可以搜到的WiFi列表 选择一个WiFi ...

  3. 微信小程序基于udp协议与esp8266进行通信

    1.概述 微信小程序有关于UDP协议的API,具体内容可前往官网查看:整体实现的思路就是利用路由组一个局域网,手机.路由器和esp8266,手机和esp8266连接路由器,登录路由器查看esp8266 ...

  4. VR场景切换-微信小程序

    VR场景切换-微信小程序 业务需求 开发软件 技术方案 技术文档 微信小程序项目关键代码 app.json app.js index.json index.js index.wxml index.wx ...

  5. 8266模块和微信小程序进行UDP通信

    记录一下微信小程序接入esp8266过程中的一些问题 太久没写了,你知道时间是遗忘一个人最好的东西,请记得我一直在 微信小程序接入vant 会不会有人问为什么引入vant?不会,好那不讲了,直接讲引入 ...

  6. 扫码进入微信小程序使用WIFI进行UDP通信发送消息

    项目前提:液晶屏不可操作无网络但是有热点,需要通过扫液晶屏上的二维码进入微信小程序配置连接WIFI 业务逻辑:手机扫码进入微信小程序,登录页面输入登录密码进入配置WIFI页面,配置WIFI页面输入当前 ...

  7. ESP8266 web配网微信小程序配网 全平台配网库 arduino 傻瓜式通用库

    wifi_link_tool esp8266通用配网库 (arduino) 库地址:点击进入GitHub 这是一个为esp8266设计的通用配网库 该库免费提供 使用请注明出处 允许毕业设计使用本库 ...

  8. arduino获取TDS数据再由ESP01发送到服务器,微信小程序显示

    我在各大网站苦苦搜寻,没有一个好的资料来叙述一下关于arduino发送数据给ESP01的通信案例,发现没有一个完整的,单片机给单片机做辅助是很常见的,于是我自己在不断探索之后,总结出了以下经验. 先说 ...

  9. 微信小程序用udp协议与服务器通信(一):连接服务器,将数据传输给服务器

    在微信小程序中udp通信传送的message支持两种格式: ArrayBuffer和string,可按服务器要接受的格式传送 ArrayBuffer格式传送 要使用ArrayBuffer格式传送,就需 ...

最新文章

  1. springboot怎么写上传头像接口?
  2. AES加密,加签验签
  3. 十二.激光SLAM框架学习之livox-loam框架安装和跑数据集
  4. Django报错NameError: name ‘ListView‘ is not defined
  5. Linux(1) 目录结构
  6. Win10如何关闭管理员权限运行
  7. hbuilderx的快捷键整理pdf_47个电脑快捷键大全,让你工作提升100倍,一般人我不告诉他...
  8. TMS320C55x的硬件结构
  9. Java制作验证码的完整代码
  10. 云编程那些事1 - 把开发过程彻底云化
  11. 北大新任校长王恩哥的10句话
  12. 华为云耀服务器与弹性云服务器的区别
  13. word粘贴 默认html,如何更改Microsoft Word中的默认粘贴设置 | MOS86
  14. SAP ABAP DUMP GETWA_NOT_ASSIGNED 指针未分配错误
  15. spark 不在 sudoers 文件中。此事将被报告。
  16. (附源码)ssm+mysql+基于ssm技术的校自助阅览室的设计与实现 毕业设计242326
  17. java计算机毕业设计基于ssm的基于android的家庭理财系统
  18. 关于Debian10的网络配置
  19. CryEngine 3引擎Forest Demo画质初窥
  20. yolov5实现水稻病虫害识别

热门文章

  1. 一个屌丝程序猿的人生(一百零六)
  2. sigmoid函数原理及饱和后梯度消失的问题
  3. 程序员放松的8个好网站推荐
  4. Win10+OpenCV4.5 无法正常读取USB摄像头数据解决方案
  5. Python 爬虫 | 获取股票基本面数据
  6. 在word中快速查找所有图片
  7. SSM框架:SpringMVC
  8. java绕过加密密码_Java实现简单密码加密功能
  9. 难道真的忘记放洗衣粉了??
  10. 学会VBA,菜鸟也高飞!