Skip to content
This repository was archived by the owner on Feb 3, 2025. It is now read-only.

Commit 59f310b

Browse files
committed
🎉 separate files to avoid confusing
1 parent 94d5a71 commit 59f310b

7 files changed

Lines changed: 845 additions & 799 deletions

File tree

api.go

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"net"
7+
"strconv"
8+
"strings"
9+
"time"
10+
)
11+
12+
func RunApi(chapi chan bool, MyID uint32) {
13+
//ポートを開く
14+
listener, err := net.Listen("tcp", PORT)
15+
if err != nil {
16+
log.Fatal(err)
17+
}
18+
defer listener.Close()
19+
20+
//接続を待つ
21+
for {
22+
conn, err := listener.Accept()
23+
if err != nil {
24+
log.Fatal(err)
25+
}
26+
// log
27+
log.Println("Remote API Connected by ", conn.RemoteAddr())
28+
//接続があったら処理を行う
29+
go HandleRequest(conn)
30+
}
31+
}
32+
33+
// 接続があったときの処理
34+
func HandleRequest(conn net.Conn) {
35+
defer conn.Close()
36+
37+
//リクエストを解析
38+
buf := make([]byte, 1024)
39+
_, err := conn.Read(buf)
40+
if err != nil {
41+
log.Println(err)
42+
return
43+
}
44+
45+
// リクエストを解析
46+
// リクエストヘッダーの1行目を取得
47+
request := string(buf)
48+
// リクエストヘッダーの1行目をスペースで区切る
49+
requests := strings.Split(request, " ")
50+
// リクエストヘッダーの1行目からリクエストの種類を取得
51+
requestType := requests[0]
52+
53+
// リクエストの種類がGETでなければエラーを返す
54+
if requestType != "GET" {
55+
fmt.Fprintf(conn, "HTTP/1.1 400 Bad Request\r\n")
56+
fmt.Fprintf(conn, "Content-Type: text/plain; charset=utf-8\r\n\r\n")
57+
fmt.Fprintf(conn, "400 Bad Request\r\n")
58+
return
59+
}
60+
61+
// リクエストのパスが"/buzzer"の場合
62+
if strings.Split(requests[1], "/")[1] == "buzzer" {
63+
// tone が指定されていない場合
64+
if len(requests) < 3 {
65+
fmt.Fprintf(conn, "HTTP/1.1 400 Bad Request\r\n")
66+
fmt.Fprintf(conn, "Content-Type: text/plain; charset=utf-8\r\n\r\n")
67+
fmt.Fprintf(conn, "400 Bad Request\r\n")
68+
return
69+
}
70+
// buzzer/ の後に tone が指定されている場合
71+
log.Println(strings.Split(requests[1], "/")[1])
72+
tone, err := strconv.Atoi(strings.Split(requests[1], "/")[3])
73+
if err != nil {
74+
fmt.Fprintf(conn, "HTTP/1.1 400 Bad Request\r\n")
75+
fmt.Fprintf(conn, "Content-Type: text/plain; charset=utf-8\r\n\r\n")
76+
fmt.Fprintf(conn, "400 Bad Request\r\n")
77+
return
78+
}
79+
duration, err := strconv.Atoi(strings.Split(requests[1], "/")[4])
80+
if err != nil {
81+
fmt.Fprintf(conn, "HTTP/1.1 400 Bad Request\r\n")
82+
fmt.Fprintf(conn, "Content-Type: text/plain; charset=utf-8\r\n\r\n")
83+
fmt.Fprintf(conn, "400 Bad Request\r\n")
84+
return
85+
}
86+
// tone が 0 から 12 でない場合
87+
if tone < 0 || tone > 15 {
88+
fmt.Fprintf(conn, "HTTP/1.1 400 Bad Request\r\n")
89+
fmt.Fprintf(conn, "Content-Type: text/plain; charset=utf-8\r\n\r\n")
90+
fmt.Fprintf(conn, "400 Bad Request\r\n")
91+
return
92+
}
93+
// duration が 50 から 3000 でない場合
94+
if duration < 50 || duration > 3000 {
95+
fmt.Fprintf(conn, "HTTP/1.1 400 Bad Request\r\n")
96+
fmt.Fprintf(conn, "Content-Type: text/plain; charset=utf-8\r\n\r\n")
97+
fmt.Fprintf(conn, "400 Bad Request\r\n")
98+
return
99+
}
100+
101+
// OK と表示
102+
fmt.Fprintf(conn, "HTTP/1.1 200 OK\r\n")
103+
fmt.Fprintf(conn, "Content-Type: text/plain; charset=utf-8\r\n\r\n")
104+
fmt.Fprintf(conn, "BUZZER OK\r\n")
105+
//ブザーを1秒鳴らす
106+
doBuzzer = true
107+
buzzerTone = tone
108+
buzzerTime = time.Duration(duration) * time.Millisecond
109+
return
110+
}
111+
112+
if strings.Split(requests[1], "/")[1] == "ignorebatterylow" {
113+
// OK と表示
114+
fmt.Fprintf(conn, "HTTP/1.1 200 OK\r\n")
115+
fmt.Fprintf(conn, "Content-Type: text/plain; charset=utf-8\r\n\r\n")
116+
fmt.Fprintf(conn, "IGNORE BATTERY LOW OK\r\n")
117+
//アラーム無視をセットする
118+
alarmIgnore = true
119+
return
120+
}
121+
122+
// 200 OKを返す
123+
fmt.Fprintf(conn, "HTTP/1.1 200 OK\r\n")
124+
// UTF-8指定
125+
fmt.Fprintf(conn, "Content-Type: application/json; charset=utf-8\r\n\r\n")
126+
127+
// JSON形式で返す
128+
response := fmt.Sprintf(`{
129+
"VOLT": %f,
130+
"PHOTOSENSOR": %d,
131+
"ISHOLDBALL": %t,
132+
"IMUDIR": %d,
133+
"ERROR": %t,
134+
"ERRORCODE": %d,
135+
"ERRORMESSAGE": "%s"
136+
}`, float32(recvdata.Volt)/10.0, recvdata.PhotoSensor, recvdata.IsHoldBall, recvdata.ImuDir, isRobotError, RobotErrorCode, RobotErrorMessage)
137+
138+
fmt.Fprint(conn, response)
139+
140+
}

gpio.go

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"math"
7+
"time"
8+
9+
"github.com/stianeikeland/go-rpio/v4"
10+
)
11+
12+
// GPIO処理部分
13+
func RunGPIO(chgpio chan bool) {
14+
15+
//ラズパイのGPIOのメモリを確保
16+
err := rpio.Open()
17+
CheckError(err)
18+
19+
//GPIO18をLED1に設定。出力
20+
led := rpio.Pin(18)
21+
led.Output()
22+
23+
//GPIO27をLED2に設定。出力
24+
led2 := rpio.Pin(27)
25+
led.Output()
26+
27+
//GPIO22をbutton1に設定。入力(S2)
28+
button1 := rpio.Pin(22)
29+
button1.Input()
30+
button1.PullUp()
31+
32+
//GPIO 24をbutton2に設定。入力(S3)
33+
button2 := rpio.Pin(24)
34+
button2.Input()
35+
button2.PullUp()
36+
37+
//GPIO12をブザーPWMに設定。出力
38+
buzzer := rpio.Pin(12)
39+
buzzer.Mode(rpio.Pwm)
40+
buzzer.Freq(64000)
41+
buzzer.DutyCycle(0, 32)
42+
43+
// ここで音楽を鳴らす
44+
buzzer.Freq(1244 * 64)
45+
buzzer.DutyCycle(16, 32)
46+
time.Sleep(time.Millisecond * 100)
47+
buzzer.Freq(1108 * 64)
48+
time.Sleep(time.Millisecond * 100)
49+
buzzer.Freq(739 * 64)
50+
time.Sleep(time.Millisecond * 150)
51+
buzzer.DutyCycle(0, 32)
52+
time.Sleep(time.Millisecond * 100)
53+
buzzer.Freq(1479 * 64)
54+
buzzer.DutyCycle(16, 32)
55+
time.Sleep(time.Millisecond * 100)
56+
buzzer.DutyCycle(0, 32)
57+
time.Sleep(time.Millisecond * 100)
58+
buzzer.DutyCycle(16, 32)
59+
time.Sleep(time.Millisecond * 100)
60+
buzzer.DutyCycle(0, 32)
61+
62+
//GPIO 6, 25, 4, 5 を DIP 1, 2, 3, 4 に設定。入力
63+
dip1 := rpio.Pin(6)
64+
dip1.Input()
65+
dip1.PullUp()
66+
dip2 := rpio.Pin(25)
67+
dip2.Input()
68+
dip2.PullUp()
69+
dip3 := rpio.Pin(4)
70+
dip3.Input()
71+
dip3.PullUp()
72+
dip4 := rpio.Pin(5)
73+
dip4.Input()
74+
dip4.PullUp()
75+
76+
// DIP1, 2, 3 ,4 の状態を出力
77+
fmt.Println("DIP1:", dip1.Read()^1)
78+
fmt.Println("DIP2:", dip2.Read()^1)
79+
fmt.Println("DIP3:", dip3.Read()^1)
80+
fmt.Println("DIP4:", dip4.Read()^1)
81+
82+
//DIP 1, 2, 3, 4からhexを作成
83+
hex := dip1.Read() ^ 1 + (dip2.Read()^1)*2 + (dip3.Read()^1)*4 + (dip4.Read()^1)*8
84+
85+
//hexを表示
86+
fmt.Println("HEX:", int(hex))
87+
88+
//Lチカ速度
89+
ledsec := 500 * time.Millisecond
90+
alarmVoltage := BATTERY_LOW_THRESHOULD
91+
for {
92+
//電圧降下検知
93+
if recvdata.Volt <= uint8(alarmVoltage) {
94+
for {
95+
buzzer.Freq(1200 * 64)
96+
buzzer.DutyCycle(16, 32)
97+
98+
//高速チカチカ
99+
led2.High()
100+
time.Sleep(100 * time.Millisecond)
101+
102+
buzzer.Freq(760 * 64)
103+
led2.Low()
104+
time.Sleep(150 * time.Millisecond)
105+
106+
if button1.Read()^1 == rpio.High || alarmIgnore {
107+
//一時的にアラーム解除する
108+
log.Println("BATTERY ALARM IGNORED")
109+
alarmVoltage = BATTERY_CRITICAL_THRESHOULD
110+
break
111+
}
112+
}
113+
} else {
114+
//通常チカチカ。ボタンが押されたら高速チカチカ
115+
//ボタンが押されたら、imuをリセットする
116+
buzzer.Freq(1479 * 64)
117+
time.Sleep(ledsec)
118+
led.Write(rpio.High)
119+
if button1.Read()^1 == rpio.High {
120+
imuReset = true
121+
ledsec = 100 * time.Millisecond
122+
buzzer.DutyCycle(16, 32)
123+
} else {
124+
imuReset = false
125+
ledsec = 500 * time.Millisecond
126+
}
127+
if button2.Read()^1 == rpio.High {
128+
//kickする
129+
buzzer.DutyCycle(16, 32)
130+
time.Sleep(500 * time.Millisecond)
131+
buzzer.DutyCycle(0, 32)
132+
kicker_enable = true
133+
kicker_val = 100
134+
}
135+
time.Sleep(ledsec)
136+
led.Write(rpio.Low)
137+
buzzer.DutyCycle(0, 32)
138+
139+
if doBuzzer {
140+
buzzer.Freq(int(440*math.Pow(1.0595, float64(buzzerTone))) * 64)
141+
buzzer.DutyCycle(16, 32)
142+
time.Sleep(buzzerTime)
143+
buzzer.DutyCycle(0, 32)
144+
doBuzzer = false
145+
}
146+
}
147+
}
148+
}

0 commit comments

Comments
 (0)