3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

M5StackAdvent Calendar 2021

Day 7

M5Stackでxeyesしてみたら意外に便利

Last updated at Posted at 2021-12-09

1639046047865.jpg

 ディスプレイの数が増えてくると(液タブとかも)マウス・ポインタの迷子が多発します.
そんなときに便利なのが,ご存じxeyesです.
 でも,画面の一部を占有されるのはうれしくないし,ディスプレイ自体が複数あるので,どこに置くのがよいか決めるのも難しい...
 と,いうわけでM5Stackを使って幸せになってみます.

全体構成

m5.png

PC側のプログラム

 Windows上でマウスの現在座標値を受け取って,UDPソケットで通信します.
Pythonで実装しました.
 送るデータは(X座標値,Y座標値)のみです.

xpyes.py
import socket
import time
import pyautogui


host = '192.168.0.6'
port = 8080
m5stack = (host, port)

sock = socket.socket(socket.AF_INET, type=socket.SOCK_DGRAM)
sock.connect(m5stack)


while True:
    x, y = pyautogui.position()
#    x = (int)((x / 1980) * 240)
#    y = (int)((y / 1200) * 200)
    pos = "(" + str(x) + "," + str(y) + ")"
    try :
#        print(pos)

        time.sleep(0.1)
        sock.sendto(pos.encode(encoding='utf-8'), m5stack)

    except KeyboardInterrupt:
        sock.close()
        break

マイコン(M5Stack)側のプログラム

UDPソケットでX・Y座標値を受け取って目玉を描くだけです.
Arduinoフレームワークを使っています.

#include <WiFi.h>
#include <WiFiUDP.h>
#include <M5Stack.h>

void drawEyes();

const char ssid[] = "pi"; //WifiのSSID
const char pass[] = "raspberry"; //Wifiの password

WiFiUDP wifiUdp; 
const int my_port = 8080;  //自身のポート

int16_t drawLeftEyeX=100;
int16_t drawLeftEyeY=120;
int16_t drawRightEyeX=210;
int16_t drawRightEyeY=120;

void setup() {
  M5.begin();
//  M5.Power.begin();
//  M5.Lcd.setTextSize(2);

  WiFi.begin(ssid, pass);
  while( WiFi.status() != WL_CONNECTED) {
    delay(500); 
    M5.Lcd.print("."); 
  }  
  M5.Lcd.println("WiFi connected");
  M5.Lcd.print("IP address = ");
  M5.Lcd.println(WiFi.localIP());
  Serial.println(WiFi.localIP());
  
  wifiUdp.begin(my_port);
  M5.Lcd.fillScreen(TFT_WHITE);
  drawEyes();
  M5.Lcd.fillEllipse(drawLeftEyeX, drawLeftEyeY, 14,18,TFT_BLACK);
  M5.Lcd.fillEllipse(drawRightEyeX, drawRightEyeY, 14,18,TFT_BLACK);
}


void loop(){
  String message;
  
  int16_t pointX=0;
  int16_t pointY=0;

  int num_packet = wifiUdp.parsePacket();
  char packetBuffer[100];
  if (num_packet){
    int len = wifiUdp.read(packetBuffer, num_packet);
    if (len > 0){ packetBuffer[len] = '\0'; }
    //M5.Lcd.println(packetBuffer);
    message = (String)((char*)packetBuffer);
    uint8_t firstSep = message.indexOf(',');
    uint8_t secondSep = message.indexOf(')');
    String a = message.substring(1,firstSep);
    String b = message.substring(firstSep+2, secondSep);
    M5.Lcd.fillEllipse(drawLeftEyeX, drawLeftEyeY, 14,18,TFT_WHITE);
    M5.Lcd.fillEllipse(drawRightEyeX, drawRightEyeY, 14,18,TFT_WHITE);
    pointX = a.toInt();
    pointY = b.toInt();
//    pointX = message.substring(1,firstSep).toInt();
//    pointY = message.substring(firstSep+1, secondSep).toInt();
    drawLeftEyeX = (int16_t)(pointX/12-pointY/50+25);  //1920/(320/2) = 6
    drawLeftEyeY = (int16_t)(pointY/10+120);  //1200/240 = 5
    if(drawLeftEyeX < 40) drawLeftEyeX = 40;
    if(drawLeftEyeX > 120) drawLeftEyeX = 120;
    if(drawLeftEyeY < 40) drawLeftEyeY = 40;
    if(drawLeftEyeY > 175) drawLeftEyeY = 175;

    drawRightEyeX = (int16_t)(pointX/12+pointY/50+160-25);  //1920/(320/2) = 6
    drawRightEyeY = (int16_t)(pointY/10+120);  //1200/240 = 5
    if(drawRightEyeX < 200) drawRightEyeX = 200;
    if(drawRightEyeX > 280) drawRightEyeX = 280;
    if(drawRightEyeY < 40) drawRightEyeY = 40;
    if(drawRightEyeY > 175) drawRightEyeY = 175;

    M5.Lcd.fillEllipse(drawLeftEyeX, drawLeftEyeY, 14,18,TFT_BLACK);
    M5.Lcd.fillEllipse(drawRightEyeX, drawRightEyeY, 14,18,TFT_BLACK);
    Serial.println("message: " + message);
    
    Serial.println("pointX: " + String(pointX));
    Serial.println("pointY: " + String(pointY));
    //M5.Lcd.drawString("pointX: " + String(pointX), 100, 60);
    //M5.Lcd.drawString("pointY: " + String(pointY), 100, 80);
    
  }
  M5.update();
  delay(20);
}

void drawEyes(){
  M5.Lcd.fillEllipse(75,115,75,110, TFT_BLACK);
  M5.Lcd.fillEllipse(75,115,63,94, TFT_WHITE);
  M5.Lcd.fillEllipse(245,115,75,110, TFT_BLACK);
  M5.Lcd.fillEllipse(245,115,63,94, TFT_WHITE);
}

完成

IMAGE ALT TEXT HERE

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?