Skip to content

Instantly share code, notes, and snippets.

@KeitetsuWorks
Last active April 3, 2021 03:20
Show Gist options
  • Select an option

  • Save KeitetsuWorks/ba816680d895039cc81496316ed55189 to your computer and use it in GitHub Desktop.

Select an option

Save KeitetsuWorks/ba816680d895039cc81496316ed55189 to your computer and use it in GitHub Desktop.
Arduino Mouse with Variable Resistor
/**
* @file arduino_mouse.ino
* @brief Arduino Mouse with Variable Resistor
* @author Keitetsu
* @date 2021/02/07
* @copyright Copyright (c) 2021 Keitetsu
* @par License
* This software is released under the MIT License.
*/
#define ADC_NUM 2 /**< A/D変換ピンの数 */
#define ADC_X 0 /**< X方向 */
#define ADC_Y 1 /**< Y方向 */
#define BUF_SIZE 13 /**< シリアル通信の送信バッファのサイズ */
#define INTERVAL_TIME 100 /**< 周期実行の間隔 */
/**
* @brief A/D変換ピンのリスト
*/
uint8_t adc_pins[ADC_NUM] = {0, 1};
unsigned long prev_time; /**< 周期実行の前回実行時刻 */
unsigned long interval_time; /**< 周期実行の間隔 */
/**
* @brief 入出力値のシリアル送信
*/
void sendData()
{
uint8_t i;
int adc_value[ADC_NUM];
char buf[BUF_SIZE];
// A/D変換ピンの値を取得する
for (i = 0; i < ADC_NUM; i++) {
adc_value[i] = analogRead(adc_pins[i]);
}
// A/D変換値にキーを付加して送信する
sprintf(buf, "X:%u,Y:%u", adc_value[ADC_X], adc_value[ADC_Y]);
Serial.println(buf);
}
/**
* @brief セットアップ関数
*/
void setup()
{
Serial.begin(9600);
prev_time = 0;
interval_time = INTERVAL_TIME;
}
/**
* @brief ループ関数
*/
void loop()
{
unsigned long curr_time;
// 現在時刻を取得する
curr_time = millis();
// 周期実行
if ((curr_time - prev_time) >= interval_time) {
prev_time += interval_time;
sendData();
}
}
#!/usr/bin/env python
# -*- coding: utf-8 -*-
##
## @file arduino_mouse.py
## @brief Arduino Mouse Receiver
## @author Keitetsu
## @date 2021/02/07
## @copyright Copyright (c) 2021 Keitetsu
## @par License
## This software is released under the MIT License.
##
import argparse
import pyautogui
import threading
import queue
import sys
import serial
class ArduinoMouseReceiver(threading.Thread):
def __init__(self, queue, port="/dev/ttyUSB0"):
super(ArduinoMouseReceiver, self).__init__()
self.port = port
self.queue = queue
self.received_data = {"X": 0, "Y": 0}
self.stop = False
# シリアルポートをオープン
try:
self.ser = serial.Serial(port=self.port, baudrate=9600)
except:
print("No Arduino found", file=sys.stderr)
raise
return
def run(self):
while (not self.stop):
# 1行受信する
line = self.ser.readline()
# 改行コードを削除し,文字列に変換する
line_string = line.strip().decode("utf-8")
# ","で文字列を分割する
line_elements = line_string.split(",")
# 分割結果が受信データを格納する辞書の要素数と一致するか確認する
if (len(line_elements) == len(self.received_data)):
# 分割結果の要素毎に処理する
for line_element in line_elements:
# ":"で文字列要素を分割する
received_datum = line_element.split(":")
# 文字列要素の分割結果が2であるか確認する
if (len(received_datum) == 2):
key, value_str = received_datum
# キーが受信データを格納する辞書にあれば,値を更新する
if (key in self.received_data):
self.received_data[key] = int(value_str)
# 受信データを格納した辞書をキューに格納する
self.queue.put(self.received_data)
# シリアルポートをクローズ
self.ser.close()
return
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description = "Arduino Mouse Receiver"
)
parser.add_argument(
"--port",
"-p",
type = str,
default = "/dev/ttyUSB0",
help = "Serial port (Arduino)"
)
args = parser.parse_args()
# 引数を変数に格納
port = args.port
# ディスプレイの解像度を取得する
screen_size = pyautogui.size()
# キューを作成
queue = queue.Queue()
# Arduino Mouseからのデータを受信するスレッドを作成
t = ArduinoMouseReceiver(queue, port)
# スレッドを実行
t.start()
# 受信データを格納する辞書をコピーする
prev_received_data = t.received_data.copy()
try:
print("Press Ctrl+C to quit")
while True:
# 現在の受信データをコピーする
curr_received_data = queue.get()
# 現在の受信データと以前の受信データが不一致であるか確認する
if (curr_received_data != prev_received_data):
# 受信データのキーを取得して,全てのキーと値を表示する
for i, key in enumerate(curr_received_data.keys()):
print("%s: %4d" % (key, curr_received_data[key]), end="")
if (i != (len(curr_received_data) - 1)):
print(", ", end="")
print("", end="\n")
# 受信データの変化量を計算する
delta_x = curr_received_data["X"] - prev_received_data["X"]
delta_y = curr_received_data["Y"] - prev_received_data["Y"]
# 現在のマウスカーソルの座標を取得する
mouse_pos = pyautogui.position()
# マウスカーソルの座標を受信データの変化量分だけ移動する
next_mouse_pos_x = max(min(mouse_pos[0] + delta_x, screen_size[0] - 1), 0)
next_mouse_pos_y = max(min(mouse_pos[1] + delta_y, screen_size[1] - 1), 0)
# マウスカーソルを移動する
pyautogui.moveTo(next_mouse_pos_x, next_mouse_pos_y)
# 以前の受信データを現在の受信データで更新する
prev_received_data = curr_received_data.copy()
except KeyboardInterrupt:
# Ctrl+Cが押下された場合はスレッドを終了する
t.stop = True
# スレッドの終了まで待機
t.join()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment