近些天以来一直在写些arduino,这个东西总是遭遇一些很奇怪的bug。
就在前几天我们的我们遭遇了一个这样的bug
我们是要用arduino和pc端通信采用的是TCP/IP协议,arduino做客户端pc做server端,arduino用它自己的语言那种类似于c++的语言,然后pc端用的是Java
这是arduino上面的代码
//这是arduino上的代码
#include "Keypad.h"
#include "PN532.h"
#include "TaskScheduler.h" //包含此头文件,才能使用调度器
#define box1 15
String correct_Box = "";
char customKey = ' ';//keypad
char c = ' ';
String padkey = "";
String comdata = "";//RFID
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
uint32_t id=0;//rfid
#define SCK 10
#define MOSI 11
#define SS 12
#define MISO 13
PN532 nfc(SCK, MISO, MOSI, SS);
void setup(){
pinMode(box1,OUTPUT);
digitalWrite(box1, HIGH);
Serial.begin(115200);
//RFID的代码部分
nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Serial.print("Didn't find PN53x board");
// while (1); // halt
}
//Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
//Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
//Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
//Serial.print("Supports "); Serial.println(versiondata & 0xFF, HEX);
}
void loop(){
while(Serial.read()>0){};
c = customKeypad.getKey();
// 根据映射后的值进行不同处理:
switch (c) {
case 'A'://rfid认证
Serial.print("A");
// Serial.flush();
get_rfid();
get_correct_Box();
open_box();
break;
case 'B'://密码认证
Serial.print("B");
// Serial.flush();
get_keyPad();
get_correct_Box();
open_box();
break;
case 'C':
break;
case 'D':
break;
}
}
void get_keyPad(){
// customKey = "";
// 根据映射后的值进行不同处理:
while(padkey.length() != 4){
customKey = customKeypad.getKey();
// Serial.print("hello");
switch (customKey) {
case '*':
// Serial.println("Start:");
break;
case '#':
// Serial.println("End:");
break;
case ' ':
// Serial.println("Empty");
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '0':
padkey += customKey;
break;
default:
break;
}
}
padkey="2222";
// Serial.println("End:");
Serial.print("#"+padkey);
// Serial.flush();
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
}
void get_rfid(){
while(id==0){
// configure board to read RFID tags and cards
nfc.SAMConfig();
// look for MiFare type cards
id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
if (id!=0) {
// Serial.print("rfid_ID:");
// Serial.println(id);
String str = "&";
str.concat(id);
// Serial.print(str);
// Serial.flush();
// str.remove(str.length() - 1);
Serial.print(str);
// Serial.flush();
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
// id = 0;
}
// id = 0;
}
id = 0;
}
// returns -1 if failed, otherwise returns ID #
void get_correct_Box(){
while(Serial.available() > 0) //??串口缓存区的问题???
{
char c = char(Serial.read());
if(c != 'e')
correct_Box += c;
// delay(2);
}
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
if(correct_Box != "")
Serial.print(correct_Box + "++");
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
// if(sizeof(correct_Box) > 0)
// Serial.println("#" + correct_Box);
// Serial.println("*");
}
void open_box(){
// Serial.println("*" + correct_Box);
// Serial.println("*");
// Serial.println(correct_Box.charAt(0));
if(correct_Box.charAt(0) == '1') {
Serial.println("box1,LOW");
delay(10);
Serial.println("box1,HIGH");
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
// Serial.flush();
digitalWrite(box1, LOW);
delay(50);
digitalWrite(box1, HIGH);
}
padkey = "";
correct_Box = "";
}
WiFi模块的代码
//这是WiFi模块上面的代码
#include <ESP8266WiFi.h>
#define relay1 2
const char *ssid = "root";//这里是我的wifi,你使用时修改为你要连接的wifi ssid
const char *password = "1234567890";//你要连接的wifi密码
const char *host = "192.168.43.230";//修改为手机的的tcpServer服务端的IP地址,即手机在路由器上的ip
WiFiClient client;
const int tcpPort = 9090;//修改为你建立的Server服务端的端口号
void setup()
{
pinMode(relay1,OUTPUT);
Serial.begin(115200);
delay(10);
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)//WiFi.status() ,这个函数是wifi连接状态,返回wifi链接状态
//这里就不一一赘述它返回的数据了,有兴趣的到ESP8266WiFi.cpp中查看
{
delay(500);
Serial.print("aaaaaaa");
}//如果没有连通向串口发送.....
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());//WiFi.localIP()返回8266获得的ip地址
}
void loop()
{
while (!client.connected())//几个非连接的异常处理
{
if (!client.connect(host, tcpPort))
{
Serial.println("connection....");
//client.stop();
delay(500);
}
}
while (client.available())//改动的就这里啦,无线读取到的数据转发到到串口
{
uint8_t c = client.read();
Serial.write(c);
}
if (Serial.available())//串口读取到的转发到wifi,因为串口是一位一位的发送所以在这里缓存完再发送
{
size_t counti = Serial.available();
uint8_t sbuf[counti];
Serial.readBytes(sbuf, counti);
client.write(sbuf, counti);
}
}
上面这个WiFi模块的代码很明显就是socket编程的操作,这个操作很简单就是读取网络中的数据然后在发给串口。
然后对于arduino上面的代码我们只关注它的
Serial.print();
因为arduino板子和WiFi模块就是通过rx和tx接口来和进行通信的,然后rx和tx就是IO嘛。
差不多arduino的IO流程是这样的:
arduino.jpg
Java代码
while(true){
// System.out.print("");
// System.out.print("");
int count = 0;
byte[] inDatas = null;
try {
while (count == 0) {
count = in.available();
}
inDatas = new byte[count];
System.out.print("");
in.read(inDatas);
msg = new String(inDatas, "gb2312");
System.out.println(msg);
// out.write("1".getBytes());
switch (msg.charAt(0)) {
case '#':
// System.out.println("*");
ResultSet queryResultSet = statement.executeQuery("SELECT * FROM cabinet WHERE keypassword=" + "'" + msg + "'");
System.out.println("SELECT * FROM cabinet WHERE keypassword=" + "'" + msg + "'");
if (queryResultSet.next()) {
String keypassword = queryResultSet.getString("keypassword");
String x = queryResultSet.getString("cabinet_id");
System.out.println(x);
out.write(x.getBytes());
list.remove((Integer) Integer.parseInt(x));
// System.out.println(Integer.getInteger(x));
// System.out.println(list);
statement.execute("DELETE FROM cabinet WHERE cabinet_id=" + "'" + x + "'");
} else {
ResultSet queryResultSetJudgeTable = statement.executeQuery("SELECT cabinet.cabinet_id FROM cabinet INNER JOIN student ON " +
"(cabinet.keypassword=student.keypassword OR \n" +
"cabinet.rfid=student.rfid OR cabinet.fingerprint=student.fingerprint) AND student.keypassword=" + "'" + msg + "'");
System.out.println("SELECT cabinet.cabinet_id FROM cabinet INNER JOIN student ON " +
"(cabinet.keypassword=student.keypassword OR \n" +
"cabinet.rfid=student.rfid OR cabinet.fingerprint=student.fingerprint) AND student.keypassword=" + "'" + msg + "'");
// System.out.println(queryResultSetJudgeTable.next());
// System.out.println(queryResultSetJudgeTable.getString("cabinet_id"));
if (queryResultSetJudgeTable.next()) {
String x = queryResultSetJudgeTable.getString("cabinet_id");
System.out.println(x);
statement.execute("UPDATE cabinet SET keypassword=" + "'" + msg + "'" + " WHERE cabinet_id=" + "'" +
x + "'");
System.out.println("UPDATE cabinet SET keypassword=" + "'" + msg + "'" + " WHERE cabinet_id=" + "'" +
x + "'");
} else {
Random rand = new Random();
int x = 0;
int i1 = 0;
while (true) {
x = rand.nextInt(1) + 1;
// System.out.println("x=" + x);
if (!list.contains(x) && x != 0) { // 2 3
// out.write(x);
// System.out.println("x=" + x);
// treeSetCabinet.add(x);
list.add(x);
// System.out.println(treeSetCabinet+"treeSetCabi");
break;
}
if (i1 > 5)
break;
i1++;
}
statement.execute("INSERT INTO cabinet(cabinet_id, keypassword) VALUES " + "('" + x + "','" + msg + "')");
out.write(((Integer)x).toString().getBytes());
Thread.sleep(1000);
out.write(((Integer)x).toString().getBytes());
for (int i = 0; i < 100; i++) {
out.write(((Integer)x).toString().getBytes());
}
for (int i = 0; i < 100; i++) {
out.write(((Integer)x).toString().getBytes());
}
for (int i = 0; i < 100; i++) {
out.write(((Integer)x).toString().getBytes());
}
for (int i = 0; i < 100; i++) {
out.write(((Integer)x).toString().getBytes());
}
for (int i = 0; i < 100; i++) {
out.write(((Integer)x).toString().getBytes());
}
}
}
break;
case '&':
ResultSet queryResultSet1 = statement.executeQuery("SELECT * FROM cabinet WHERE rfid=" + "'" + msg + "'");
System.out.println("SELECT * FROM cabinet WHERE rfid=" + "'" + msg + "'");
if (queryResultSet1.next()) {
// out.write(queryResultSet1.getString("cabinet_id").getBytes());
String rfid = queryResultSet1.getString("rfid");
String x = queryResultSet1.getString("cabinet_id");
System.out.println(x);
out.write(x.getBytes());
list.remove((Integer) Integer.parseInt(x));
System.out.println(x.equals("1") || x.equals("2"));
// System.out.println(Integer.getInteger(x));
// System.out.println(list);
statement.execute("DELETE FROM cabinet WHERE cabinet_id=" + "'" + x + "'");
// System.out.println("*");
System.out.println("DELETE FROM cabinet WHERE cabinet_id=" + "'" + x + "'");
} else {
ResultSet queryResultSetJudgeTable = statement.executeQuery("SELECT cabinet.cabinet_id FROM cabinet INNER JOIN student ON " +
"(cabinet.keypassword=student.keypassword OR \n" +
"cabinet.rfid=student.rfid OR cabinet.fingerprint=student.fingerprint) AND student.rfid=" + "'" + msg + "'");
System.out.println("SELECT cabinet.cabinet_id FROM cabinet INNER JOIN student ON " +
"(cabinet.keypassword=student.keypassword OR \n" +
"cabinet.rfid=student.keypassword OR cabinet.fingerprint=student.fingerprint) AND student.keypassword" + "'" + msg + "'");
if (queryResultSetJudgeTable.next()) {
String x = queryResultSetJudgeTable.getString("cabinet_id");
statement.execute("UPDATE cabinet SET rfid=" + "'" + msg + "'" + " WHERE cabinet_id=" + "'" +
x + "'");
System.out.println("UPDATE cabinet SET rfid=" + "'" + msg + "'" + " WHERE cabinet_id=" + "'" +
x + "'");
} else {
Random rand = new Random();
int x = 0;
int i1 = 0;
while (true) {
x = rand.nextInt(1) + 1;
// System.out.println("x=" + x);
if (!list.contains(x) && x != 0) { // 2 3
// out.write(x);
// System.out.println("x=" + x);
// treeSetCabinet.add(x);
list.add(x);
// System.out.println(treeSetCabinet+"treeSetCabi");
break;
}
if (i1 > 5)
break;
i1++;
}
statement.execute("INSERT INTO cabinet(cabinet_id, rfid) VALUES " + "('" + x + "','" + msg + "')");
// System.out.print("");
out.write(((Integer)x).toString().getBytes());
Thread.sleep(2000);
out.write(((Integer)x).toString().getBytes());
for (int i = 0; i < 100; i++) {
out.write(((Integer)x).toString().getBytes());
}
for (int i = 0; i < 100; i++) {
out.write(((Integer)x).toString().getBytes());
}
for (int i = 0; i < 100; i++) {
out.write(((Integer)x).toString().getBytes());
}
for (int i = 0; i < 100; i++) {
out.write(((Integer)x).toString().getBytes());
}
for (int i = 0; i < 100; i++) {
out.write(((Integer)x).toString().getBytes());
}
System.out.println(x);
System.out.println(((Integer) x).toString().getBytes());
System.out.println(((Integer)x).toString());
System.out.println(((Integer)x).toString().equals("1"));
System.out.println(((Integer)x).toString().equals("2"));
// out.write(((Integer) 1).toString().getBytes());
}
}
break;
case '*':
ResultSet queryResultSet2 = statement.executeQuery("SELECT * FROM cabinet WHERE fingerprint=" + "'" + msg + "'");
System.out.println("SELECT * FROM cabinet WHERE fingerprint=" + "'" + msg + "'");
if (queryResultSet2.next()) {
String rfid = queryResultSet2.getString("fingerprint");
String x = queryResultSet2.getString("cabinet_id");
out.write(x.getBytes());
list.remove((Integer) Integer.parseInt(x));
// System.out.println(Integer.getInteger(x));
// System.out.println(list);
statement.execute("DELETE FROM cabinet WHERE cabinet_id=" + "'" + x + "'");;
} else {
ResultSet queryResultSetJudgeTable = statement.executeQuery("SELECT cabinet.cabinet_id FROM cabinet INNER JOIN student ON " +
"(cabinet.keypassword=student.keypassword OR \n" +
"cabinet.rfid=student.rfid OR cabinet.fingerprint=student.fingerprint) AND student.fingerprint=" + "'" + msg + "'");
System.out.println("SELECT cabinet.cabinet_id FROM cabinet INNER JOIN student ON " +
"(cabinet.keypassword=student.keypassword OR \n" +
"cabinet.rfid=student.keypassword OR cabinet.fingerprint=student.fingerprint) AND student.fingerprint" + "'" + msg + "'");
if (queryResultSetJudgeTable.next()) {
String x = queryResultSetJudgeTable.getString("cabinet_id");
statement.execute("UPDATE cabinet SET fingerprint=" + "'" + msg + "'" + " WHERE cabinet_id=" + "'" +
x + "'");
System.out.println("UPDATE cabinet SET fingerprint=" + "'" + msg + "'" + " WHERE cabinet_id=" + "'" +
queryResultSetJudgeTable.getString("cabinet_id") + "'");
} else {
Random rand = new Random();
int x = 0;
while (true) {
x = rand.nextInt(1) + 1;
// System.out.println("x=" + x);
if (!list.contains(x) && x != 0) { // 2 3
// out.write(x);
// System.out.println("x=" + x);
// treeSetCabinet.add(x);
list.add(x);
// System.out.println(treeSetCabinet+"treeSetCabi");
break;
}
}
statement.execute("INSERT INTO cabinet(cabinet_id, fingerprint) VALUES " + "('" + x + "','" + msg + "')");
out.write(((Integer)x).toString().getBytes());
System.out.println(((Integer)x).toString().getBytes());
}
}
}
} catch (Exception e) {
// System.out.println(treeSetCabinet);
// System.out.println(e);
e.printStackTrace();
}
}
首先声明一点arduino会发送三种数据到pc端,但是这三种数据都是数字的字符串,我是通过arduino板子收集的时候在前面增加标识符来对他们进行区别。
Java代码的大概流程是这样的:
Java
再声明一下:在上面那个arduino代码中的Serial.print(str)就是发送的以&开头的数据
发现错误
在arduino端的操作是先按A,发送str,之后得到server端响应的数据也就是1,之后arduino再发送box1 LOW和box1 HIGH
然后就是有一个很奇怪的现象就是第二次box1 LOW box1 HIGH 可以发送成功第一次就不能成功
好吧出了问题那就疯狂调试呗,我的调试技巧就是打log
先确定是不是Java这边出了问题
一开始是我认为我代码的问题,然后我用这种方法做的测试:
System.out.println(x.equals(1));
然后事实证明不是Java这边的问题是
不是Java这边那就是arduino那边喽!
arduino这边由两部分组成一是它本身二是它的外接WiFi模块
是不是arduino它本身出了问题
不可能的第二次能成功就说明它从WiFi模块获取数据还是问题不大的
那就应该是WiFi模块本身的问题了
WiFi是用的TCP/IP协议来传输数据的那如何查看数据传输的情况呢?
当然是一言不合就抓包了
打开Wireshark
这是出现问题的抓包情况
微信截图_20180716142901.png
这是正常的抓包情况
![微信截图_20180716143128.png](https://img.haomeiwen.com/i12687386/b00113c34f848 微信截图_20180716143202.png
e92.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
微信截图_20180716143303.png
从这几张截图中可以看出好像网络传输也没问题
这怎末办?我好像束手无策啊?
后来我又想了想网卡是插在主板上的,而那个外接的WiFi模块是通过IO来进行通信的,会不会是因为IO是有缓存的,这个是会消耗时间的
解决问题成功
我把代码这么改了下
get_rfid();
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
delay(10);
get_correct_Box();
open_box();
break;
果然不出问题了
网友评论