セットアップや使用方法 967
TinyGoとRKJXV122400Rを利用したマウスの製作実験
今回の内容
今回はTinyGoを使用してADCからジョイスティックの状態を取り出し、制御をしたいと思います。また、TiinyGoは簡単にHIDのライブラリを標準で準備されているので、今回はジョイステックの情報を利用してマウスを作成したいと思います。
使用部品
使用部品 | 購入先 | 備考 |
---|---|---|
Seed Xiao RP2040 | 秋月電子 | RP2040 |
RKJXV122400R | 秋月電子 | アナログジョイスティック |
アナログジョイスティック用変換基板 | 秋月電子 | ブレッドボードで使用するため |
回路図
回路としてはX軸のAD値をA0、Y軸のAD値をA1、スイッチをD3に接続しています。
プログラムについて
今回もTinyGoを使用してプログラムを作成しています。TinyGOがUSBHIDのライブラリを持っているのでインポートして使用すれば簡単にUSB機器を製作できます。処理的には、アナログジョイスティックのアナログデータをA/Dポートで読み込み、その値から移動方向と移動量を計算し、マウスカーソルを移動させています。
RKJXV122400.go
package joystick
import (
"machine"
)
// Joystick アナログジョイスティック制御用 構造体
type Joystick struct {
xStick machine.ADC
yStick machine.ADC
sw machine.Pin
}
// New 初期化
func New(xStick machine.Pin, yStick machine.Pin, sw machine.Pin) (Joystick, error) {
var err error
joystick := Joystick{}
joystick.xStick = machine.ADC{Pin: xStick}
joystick.yStick = machine.ADC{Pin: yStick}
joystick.sw = sw
err = joystick.xStick.Configure(machine.ADCConfig{})
if err != nil {
return Joystick{}, err
}
err = joystick.yStick.Configure(machine.ADCConfig{})
if err != nil {
return Joystick{}, err
}
joystick.sw.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
return joystick, nil
}
// GetDataX X軸のアナログ値を取得
func (j Joystick) GetDataX() uint16 {
return j.xStick.Get() >> 12 // 16bit -> 12bit 変換
}
// GetDataY Y軸のアナログ値を取得
func (j Joystick) GetDataY() uint16 {
return j.yStick.Get() >> 12 // 16bit -> 12bit 変換
}
// GetDataSw スイッチの状態を取得
func (j Joystick) GetDataSw() bool {
return j.sw.Get()
}
main.go
#define LED_PIN 13
package main
import (
"JoyMouse/RKJXV122400R"
"machine"
"machine/usb/hid/keyboard"
"machine/usb/hid/mouse"
"time"
)
// スティックの値格納用構造体
type switchState struct {
xValue uint16
yValue uint16
swState bool
}
func getData(ch chan<- switchState) {
var s switchState
// ジョイスティックで使用するのポート初期化
j, err := joystick.New(machine.A0, machine.A1, machine.D2)
if err != nil {
panic(err)
}
for {
// 取得データから移動量を計算
s.xValue = j.GetDataX() >> 12 // 16bit -> 4bit 変換
s.yValue = j.GetDataY() >> 12 // 16bit -> 4bit 変換
// スイッチの状態を取得
if j.GetDataSw() == false {
time.Sleep(100 * time.Millisecond)
if j.GetDataSw() == false {
s.swState = false
} else {
s.swState = true
}
} else {
s.swState = true
}
ch <- s
time.Sleep(5 * time.Millisecond)
}
}
// LED点灯制御用
func ledCtrl(ch chan<- bool) {
ledR := machine.LED_RED
ledG := machine.LED_GREEN
ledB := machine.LED_BLUE
ledR.Configure(machine.PinConfig{Mode: machine.PinOutput})
ledG.Configure(machine.PinConfig{Mode: machine.PinOutput})
ledB.Configure(machine.PinConfig{Mode: machine.PinOutput})
ledG.High()
ledB.High()
for {
ledR.High()
time.Sleep(100 * time.Millisecond)
ledR.Low()
time.Sleep(100 * time.Millisecond)
ch <- true
}
}
// 初期化ルーチン
func init() {
// ADC初期化
machine.InitADC()
}
// メインルーチン
func main() {
var s switchState
ch1 := make(chan switchState, 1)
ch2 := make(chan bool, 1)
m := mouse.Port()
kb := keyboard.Port()
go getData(ch1)
go ledCtrl(ch2)
for {
// Receive channel data from Goroutine
select {
// Control of ADC
case s = <-ch1:
m.Move(int(s.yValue)-8, int(s.xValue)-8)
if s.swState == false {
_, err := kb.Write([]byte("Hello !!"))
if err != nil {
panic(err)
}
time.Sleep(200 * time.Millisecond)
}
// Control of LED
case <-ch2:
}
}
}
最後に
今回のプログラムでは、TinyGoを使用してADコンバータの取得、USBを利用した例を紹介しました。TinyGoは日々バージョンアップが行われ、使用できるマイコンの種類や使用できる機能が増えてきています。今までの紹介した記事を参考にして、少しでもTinyGoに興味を持ってもらえたらと思います。
投稿者の人気記事
-
keiske-hongyo
さんが
2023/10/21
に
編集
をしました。
(メッセージ: 初版)
ログインしてコメントを投稿する