IoT-Arduino

Java socket编程一次奇怪的bug

2018-07-16  本文已影响2人  Upstreamzy

近些天以来一直在写些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
这是出现问题的抓包情况

抓包1
微信截图_20180716142901.png
这是正常的抓包情况
![微信截图_20180716143128.png](https://upload-images.jianshu.io/upload_images/12687386-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;

果然不出问题了

上一篇下一篇

猜你喜欢

热点阅读