-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from Crow314/develop
v0.1.0
- Loading branch information
Showing
8 changed files
with
359 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"github.com/Crow314/im920s-controller/pkg/connector" | ||
"github.com/Crow314/im920s-controller/pkg/module" | ||
"os" | ||
) | ||
|
||
func main() { | ||
scanner := bufio.NewScanner(os.Stdin) | ||
|
||
fmt.Print("Please input COM port path/name: ") | ||
var portName string | ||
if scanner.Scan() { | ||
portName = scanner.Text() | ||
} | ||
|
||
conn := connector.NewConnector(portName) | ||
im920s := module.NewIm920s(conn.TransmitChannel(), conn.ReceiveChannel()) | ||
|
||
go func() { | ||
for { | ||
data := <-im920s.DataReceiver() | ||
fmt.Printf("node: %d\n", data.Node()) | ||
fmt.Printf("RSSI: %ddb\n", data.Rssi()) | ||
|
||
for _, v := range data.Data() { | ||
fmt.Printf("%X, ", v) | ||
} | ||
fmt.Println() | ||
} | ||
}() | ||
|
||
for { | ||
var msg string | ||
if scanner.Scan() { | ||
msg = scanner.Text() | ||
} | ||
|
||
res, err := im920s.SendCommand(msg) | ||
if err != nil { | ||
_, _ = fmt.Fprintf(os.Stderr, "%v\n", err) | ||
} else { | ||
fmt.Println(res) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module github.com/Crow314/im920s-controller | ||
|
||
go 1.17 | ||
|
||
require github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 | ||
|
||
require golang.org/x/sys v0.0.0-20210903071746-97244b99971b // indirect |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07 h1:UyzmZLoiDWMRywV4DUYb9Fbt8uiOSooupjTq10vpvnU= | ||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= | ||
golang.org/x/sys v0.0.0-20210903071746-97244b99971b h1:3Dq0eVHn0uaQJmPO+/aYPI/fRMqdrVDbu7MQcku54gg= | ||
golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package connector | ||
|
||
import ( | ||
"github.com/tarm/serial" | ||
"log" | ||
) | ||
|
||
type Connector struct { | ||
portName string | ||
port *serial.Port | ||
txChan chan string | ||
rxChan chan string | ||
} | ||
|
||
func NewConnector(portName string) *Connector { | ||
conn := new(Connector) | ||
conn.portName = portName | ||
|
||
conf := &serial.Config{Name: portName, Baud: 19200} | ||
|
||
p, err := serial.OpenPort(conf) | ||
if err != nil { | ||
log.Fatalf("Failed to open COM port\n%v", err) | ||
} | ||
conn.port = p | ||
|
||
conn.txChan = make(chan string) | ||
conn.rxChan = make(chan string, 5) // 損失対策 / RTSを受け取ってくれないので | ||
|
||
go conn.transmit() | ||
go conn.receive() | ||
|
||
return conn | ||
} | ||
|
||
func (conn *Connector) transmit() { | ||
for { | ||
msg := <-conn.txChan | ||
|
||
_, err := conn.port.Write([]byte(msg)) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
} | ||
} | ||
|
||
func (conn *Connector) receive() { | ||
dataBuf := make([]byte, 128) | ||
msgBuf := make([]byte, 0, 128) | ||
|
||
for { | ||
n, err := conn.port.Read(dataBuf) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
// 1回での受信データ (!= 1行) | ||
for _, v := range dataBuf[:n] { | ||
msgBuf = append(msgBuf, v) | ||
|
||
if v == '\n' { // LFで一区切り | ||
msg := string(msgBuf) | ||
msgBuf = msgBuf[:0] // 要素を全て削除 | ||
|
||
conn.rxChan <- msg | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Getter | ||
|
||
func (conn Connector) TransmitChannel() chan<- string { | ||
return conn.txChan | ||
} | ||
|
||
func (conn Connector) ReceiveChannel() <-chan string { | ||
return conn.rxChan | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package module | ||
|
||
import ( | ||
"errors" | ||
"strings" | ||
"time" | ||
) | ||
|
||
type Im920s struct { | ||
uartChannel uartChannel | ||
dataReceiver chan ReceivedData | ||
responseReceiver chan string | ||
} | ||
|
||
type uartChannel struct { | ||
transmitter chan<- string | ||
receiver <-chan string | ||
} | ||
|
||
func NewIm920s(transmitter chan<- string, receiver <-chan string) *Im920s { | ||
im920s := new(Im920s) | ||
|
||
im920s.uartChannel.transmitter = transmitter | ||
im920s.uartChannel.receiver = receiver | ||
|
||
im920s.dataReceiver = make(chan ReceivedData) | ||
|
||
go im920s.receiver() | ||
|
||
return im920s | ||
} | ||
|
||
func (im920s *Im920s) SendCommand(msg string) (string, error) { | ||
if !strings.HasSuffix(msg, "\r\n") { // 末尾がCRLFでない場合 | ||
msg += "\r\n" | ||
} | ||
|
||
im920s.responseReceiver = make(chan string) | ||
im920s.uartChannel.transmitter <- msg | ||
|
||
res := "" | ||
var err error | ||
|
||
select { | ||
case res = <-im920s.responseReceiver: | ||
if res == "NG\r\n" { | ||
err = errors.New("returned \"NG\" response") | ||
} | ||
|
||
if msg == "RPRM\r\n" || msg == "rprm\r\n" { | ||
loop: | ||
for { // 2行目以降に対応 | ||
select { | ||
case res2 := <-im920s.responseReceiver: | ||
res += res2 | ||
case <-time.After(1 * time.Second): | ||
break loop | ||
} | ||
} | ||
} | ||
case <-time.After(10 * time.Second): | ||
err = errors.New("returned no response") | ||
} | ||
|
||
close(im920s.responseReceiver) | ||
|
||
return res, err | ||
} | ||
|
||
// Getter | ||
|
||
func (im920s Im920s) DataReceiver() <-chan ReceivedData { | ||
return im920s.dataReceiver | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package module | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"os" | ||
"regexp" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
type ReceivedData struct { | ||
node uint16 | ||
rssi int8 | ||
data []byte | ||
} | ||
|
||
var receiveDataFormat *regexp.Regexp | ||
|
||
func (im920s *Im920s) receiver() { | ||
for { | ||
str := <-im920s.uartChannel.receiver | ||
|
||
// onReceived的なsomething | ||
|
||
if isReceivedData(str) { // データ受信 | ||
data, err := parseData(str) | ||
if err != nil { | ||
_, _ = fmt.Fprintf(os.Stderr, "Error: Failed to parse data\n%v\n", err) | ||
continue | ||
} | ||
|
||
im920s.dataReceiver <- *data | ||
} else { | ||
if str == "GRNOREGD\r\n" { // STGNコマンド実行後 グループ番号設定パケット受信時 | ||
// TODO config struct | ||
println("Info: Group number has been registered") | ||
} else { // コマンドに対するレスポンス | ||
im920s.responseReceiver <- str | ||
} | ||
} | ||
} | ||
} | ||
|
||
func isReceivedData(receivedStr string) bool { | ||
// 正規表現定義 | ||
if receiveDataFormat == nil { | ||
receiveDataFormat = regexp.MustCompile("^00,[0-9A-F]{4},[0-9A-F]{2}:.+\r\n$") | ||
} | ||
|
||
return receiveDataFormat.MatchString(receivedStr) | ||
} | ||
|
||
func parseData(dataStr string) (*ReceivedData, error) { | ||
// 末尾CRLF除去 | ||
if strings.HasSuffix(dataStr, "\r\n") { | ||
dataStr = dataStr[:len(dataStr)-2] | ||
} | ||
|
||
data := new(ReceivedData) | ||
|
||
tmpStrs := strings.Split(dataStr, ":") | ||
|
||
if len(tmpStrs) != 2 { | ||
return nil, errors.New("invalid format\nCan't separate header and body.") | ||
} | ||
|
||
header := strings.Split(tmpStrs[0], ",") | ||
// TODO ECIO | ||
body := strings.Split(tmpStrs[1], ",") // Only DCIO mode | ||
|
||
if header[0] != "00" { | ||
return nil, errors.New("invalid format\nDummy is not 0x00.") | ||
} | ||
|
||
// Node | ||
hex, err := strconv.ParseInt(header[1], 16, 16) | ||
if err != nil { | ||
return nil, err | ||
} | ||
data.node = uint16(hex) | ||
|
||
// RSSI | ||
tmpByte, err := parseByteHex(header[2]) | ||
if err != nil { | ||
return nil, err | ||
} | ||
data.rssi = int8(tmpByte) | ||
|
||
// Data | ||
data.data = make([]byte, len(body)) | ||
for i, v := range body { | ||
res, err := parseByteHex(v) | ||
if err != nil { | ||
return nil, err | ||
} | ||
data.data[i] = res | ||
} | ||
|
||
return data, nil | ||
} | ||
|
||
// Getter | ||
|
||
func (data *ReceivedData) Node() uint16 { | ||
return data.node | ||
} | ||
|
||
func (data *ReceivedData) Rssi() int8 { | ||
return data.rssi | ||
} | ||
|
||
func (data *ReceivedData) Data() []byte { | ||
return data.data | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package module | ||
|
||
import ( | ||
"encoding/hex" | ||
"errors" | ||
) | ||
|
||
func (im920s *Im920s) Broadcast(data []byte) error { | ||
size := len(data) | ||
if size < 1 || size > 32 { | ||
return errors.New("invalid data size") | ||
} | ||
|
||
_, err := im920s.SendCommand("TXDA " + hex.EncodeToString(data)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package module | ||
|
||
import "strconv" | ||
|
||
func parseByteHex(rssi string) (byte, error) { | ||
hex, err := strconv.ParseUint(rssi, 16, 8) | ||
if err != nil { | ||
return 0, err | ||
} | ||
return byte(hex), nil | ||
} |