Skip to content

Instantly share code, notes, and snippets.

@GOROman
Last active August 11, 2024 10:49
Show Gist options
  • Save GOROman/a64f592ac0180fa18875b5c647525c43 to your computer and use it in GitHub Desktop.
Save GOROman/a64f592ac0180fa18875b5c647525c43 to your computer and use it in GitHub Desktop.
M5 AtomJoyStick のジョイスティック情報を取得してみた。
#include <Arduino.h>
#include <Wire.h>
#include "driver_joy.h"
#define I2C_SDA_PIN 38 // M5 AtomS3 SDA
#define I2C_SCL_PIN 39 // M5 AtomS3 SCL
#define I2C_CLOCK 400000
#define ATOM_JOYSTICK_ADDR 0x59 // I2Cアドレス
#define JOY1_ADC_VALUE_12BITS_REG 0x00
#define JOY1_ADC_VALUE_8BITS_REG 0x10
#define JOY2_ADC_VALUE_12BITS_REG 0x20
#define JOY2_ADC_VALUE_8BITS_REG 0x30
#define BATTERY_ADC_12BITS_REG 0x40
#define BATTERY_ADC_8BITS_REG 0x50
#define BATTERY_VOLTAGE_REG 0x60
#define BUTTON_REG 0x70
#define BOOTLOADER_VERSION_REG 0xFC
#define FIRMWARE_VERSION_REG 0xFE
#define I2C_ADDRESS_REG 0xFF
// I2C通信で取得したジョイスティックの生データ
typedef struct {
struct {
uint16_t x; // 0-4095 (12bit)
uint16_t y; // 0-4095 (12bit)
} joy1; // 左スティック
struct {
uint16_t x; // 0-4095 (12bit)
uint16_t y; // 0-4095 (12bit)
} joy2; // 右スティック
struct {
uint8_t trigger_l; // 0:押されている, 1:押されていない
uint8_t trigger_r;
uint8_t stick_l;
uint8_t stick_r;
} button; // ボタン
} JOY_RAW_t;
// ジョイスティックの生データ
static JOY_RAW_t joy_raw;
// I2C通信の初期化
static void _I2C_init()
{
Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN, I2C_CLOCK);
}
// I2C通信で指定したレジスタからデータを読み込む
static void _I2C_read(uint8_t reg, uint8_t *data, int len)
{
Wire.beginTransmission(ATOM_JOYSTICK_ADDR);
Wire.write(reg);
Wire.endTransmission(false);
Wire.requestFrom(ATOM_JOYSTICK_ADDR, (int)len);
for (int i = 0; i < len; ++i)
{
data[i] = Wire.read();
}
}
// ジョイスティックの初期化
int Joy_init()
{
// I2C通信の初期化
_I2C_init();
return 0;
}
// ジョイスティックの更新
int Joy_update()
{
// 左スティック(JOY1)のX,Y座標を取得
_I2C_read(JOY1_ADC_VALUE_12BITS_REG, (uint8_t*)&joy_raw.joy1, sizeof(joy_raw.joy1));
// 右スティック(JOY2)のX,Y座標を取得
_I2C_read(JOY2_ADC_VALUE_12BITS_REG, (uint8_t*)&joy_raw.joy2, sizeof(joy_raw.joy2));
// ボタンの4個の状態を取得
_I2C_read(BUTTON_REG, (uint8_t*)&joy_raw.button, sizeof(joy_raw.button));
return 0;
}
// ジョイスティックの値を取得 (x: X軸の値, y: Y軸の値)
int Joy_getStick(int no, uint16_t *x, uint16_t *y)
{
switch (no)
{
case JOY_STICK_L:
*x = joy_raw.joy1.x; // 0-4095 (12bit)
*y = joy_raw.joy1.y;
break;
case JOY_STICK_R:
*x = joy_raw.joy2.x;
*y = joy_raw.joy2.y;
break;
default:
break;
}
return 0;
}
// ジョイスティックのボタンが押されたかどうかを取得
bool Joy_isPressed(int no)
{
// 生データは押されていると0になるので、反転して返す(負論理)
switch (no)
{
case JOY_BUTTON_TRIGGER_L:
return !joy_raw.button.trigger_l;
case JOY_BUTTON_TRIGGER_R:
return !joy_raw.button.trigger_r;
case JOY_BUTTON_STICK_L:
return !joy_raw.button.stick_l;
case JOY_BUTTON_STICK_R:
return !joy_raw.button.stick_r;
}
return false;
}
#pragma once
// ジョイスティックドライバ
#include <stdint.h>
enum {
JOY_STICK_L = 0, // 左のジョイスティック
JOY_STICK_R = 1, // 右のジョイスティック
JOY_STICK_MAX
};
enum {
JOY_BUTTON_TRIGGER_L = 0, // 左ボタン
JOY_BUTTON_TRIGGER_R = 1, // 右ボタン
JOY_BUTTON_STICK_L = 2, // 左スティック押し込み
JOY_BUTTON_STICK_R = 3, // 右スティック押し込み
JOY_BUTTON_MAX
};
// ジョイスティックの初期化
int Joy_init();
// ジョイスティックの更新
int Joy_update();
// ジョイスティックの値を取得 (x: X軸の値, y: Y軸の値)
int Joy_getStick(int no, uint16_t *x, uint16_t *y);
// ジョイスティックのボタンが押されているかどうかを取得
bool Joy_isPressed(int no);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment