Last active
April 3, 2021 03:20
-
-
Save KeitetsuWorks/ba816680d895039cc81496316ed55189 to your computer and use it in GitHub Desktop.
Arduino Mouse with Variable Resistor
This file contains hidden or 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
| /** | |
| * @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(); | |
| } | |
| } |
This file contains hidden or 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
| #!/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