bugst / go-serial

A cross-platform serial library for go-lang.
BSD 3-Clause "New" or "Revised" License
620 stars 189 forks source link

Can't get data using win10 #72

Closed kerwin612 closed 4 years ago

kerwin612 commented 4 years ago
package main

import (
    "log"
    "time"
    "go.bug.st/serial"
)

func main() {
    mode := &serial.Mode{
        BaudRate: 115200,
    }
    port, err := serial.Open("COM4", mode)
    if err != nil {
        log.Fatal(err)
    }

    go func() {
        for {
            _, err := port.Write([]byte("get_down"))
            log.Println("send: ", "get_down")
            if err != nil {
                log.Fatal(err)
            }
            time.Sleep(time.Millisecond * 200)
        }
    }()

    go func() {
        for {
            buf := make([]byte, 128)
            log.Print("read...")
            n, err := port.Read(buf)
            log.Printf("read count[%d]\n", n)
            if err != nil {
                log.Fatal(err)
            }
            if n != 0 {
                log.Printf("recv: %s\n", string(buf[:n]))
            }
        }
    }()

    time.Sleep(time.Hour * 1)
}

this is my code,the results are as follows:

2020/01/14 11:17:52 read...
2020/01/14 11:17:52 send:  get_down
2020/01/14 11:17:52 send:  get_down
2020/01/14 11:17:52 send:  get_down
2020/01/14 11:17:52 send:  get_down
2020/01/14 11:17:53 send:  get_down
2020/01/14 11:17:53 send:  get_down
2020/01/14 11:17:53 send:  get_down
2020/01/14 11:17:53 send:  get_down
2020/01/14 11:17:53 send:  get_down
2020/01/14 11:17:54 send:  get_down
2020/01/14 11:17:54 send:  get_down
2020/01/14 11:17:54 send:  get_down
2020/01/14 11:17:54 send:  get_down
2020/01/14 11:17:54 send:  get_down
2020/01/14 11:17:55 send:  get_down
2020/01/14 11:17:55 send:  get_down
..........................................

The normal situation is that every get_down will respond to down done:

send:  get_down
read...
read count[9]
recv: down done
send:  get_down
read...
read count[9]
recv: down done
send:  get_down
read...
read count[9]
recv: down done
send:  get_down
read...
read count[9]
recv: down done
.........

In the same operating environment (system, serial port, serial device), can get correct results by sending get_down with java.

cmaglie commented 4 years ago

Some questions to understand what's happening:

Is get_down received by the device? Can you add some debugging to see it?

Is the device sending back the response?

Can you share the firmware of the device?

kerwin612 commented 4 years ago

get_down is printed in the demo code above.
The device will respond down done, but this serial library read is blocked, and the device response cannot be read.

kerwin612 commented 4 years ago

Sorry, I can’t get the device firmware; but for the same device and the same PC environment, I can use a serial tool such as SecureCRT to receive the device response normally.

kerwin612 commented 4 years ago

The connection parameter I use in SecureCRT is 8N1 115200

cmaglie commented 4 years ago

Can you share the java example?

kerwin612 commented 4 years ago

sure.

import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortDataListener;
import com.fazecast.jSerialComm.SerialPortEvent;

public class Demo {

    private static SerialPort comPort;
    private static boolean sessionEnd = true;
    private static StringBuffer recdBuffer = new StringBuffer();

    public static void main(String[] args) {
        comPort = SerialPort.getCommPort("COM4");
        comPort.setComPortParameters(115200, 8, 1, 0);
        comPort.openPort();

        comPort.addDataListener(new SerialPortDataListener() {
            @Override
            public int getListeningEvents() {
                return SerialPort.LISTENING_EVENT_DATA_RECEIVED;
            }

            @Override
            public void serialEvent(SerialPortEvent event) {
                try {
                    recd(new String(event.getReceivedData(), "utf-8"));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        if (sessionEnd) {
                            send("get_down");
                        }
                        Thread.sleep(200);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

    }

    private static synchronized void recd(String recd) {
        char[] chars = recd.toCharArray();
        for (char c : chars) {
            if (c == '\r') {
                String cmd = recdBuffer.toString();
                System.out.println("recd: " + cmd);
                if (cmd.startsWith("down")) {
                    down(cmd);
                }
                recdBuffer.setLength(0);
            } else {
                recdBuffer.append(c);
            }
        }
    }

    private static synchronized void down(String down) {
        sessionEnd = false;
        try {
            if (down.endsWith("none")) {
                return;
            }
            send("result 2 1 0 " + (Math.random() * 10 > 5 ? "1" : "0"));
        } finally {
            sessionEnd = true;
        }
    }

    private static synchronized void send(String send) {
        String cmd = send + "\r";
        System.out.println("send: " + cmd);
        comPort.writeBytes(cmd.getBytes(), cmd.getBytes().length);
    }

}

pom.xml(dependency)

<dependency>
            <groupId>com.fazecast</groupId>
            <artifactId>jSerialComm</artifactId>
            <version>[2.0.0,3.0.0)</version>
</dependency>
cmaglie commented 4 years ago

In the send command you add a \r to the end of the string:

    private static synchronized void send(String send) {
        String cmd = send + "\r";
        System.out.println("send: " + cmd);
        comPort.writeBytes(cmd.getBytes(), cmd.getBytes().length);
    }

but on the golang example you send the string without it:

            _, err := port.Write([]byte("get_down"))

you should change the line above to:

            _, err := port.Write([]byte("get_down\r"))
kerwin612 commented 4 years ago

thank you, you are right. this is my own carelessness.