티스토리 뷰
반응형
다른 강의자료는 www.codingnow.co.kr/ 여기를 참고해주세요.!!
지난 실무 강의는 아두이노 LED를 파이썬으로 제어하기 였습니다.
이번에는 조이스틱을 사용하여 간단한 마우스를 만들어 보겠습니다.
자세한 사항은 첨부된 동영상을 참고해주세요.
1. C언어 - 아두이노
1) 회로구성
조이스틱 - A0, A1
버튼 - 2,3,4,5
조이스틱 모듈 구입처는 소스 코드내 주석으로 넣어 두었습니다.
2) 소스파일
-. Mouse.ino (아두이노 스케치 파일)
#include "src/global.h"
void setup()
{
setupMain();
}
void loop()
{
loopMain();
}
-.main.cpp
조이스틱 모듈의 키값을 read하여 분석 후 시리얼 통신으로 PC에 데이타를 전송합니다.
#include "global.h"
#define KEY_MAX 6
unsigned char keyMap[KEY_MAX] = {
A0, A1, /*6,*/ 3, 5, 2, 4
};
typedef struct{
unsigned char key;
unsigned char keyPre;
unsigned char keyResult[KEY_MAX + 2];
}KeyValtype;
KeyValtype val;
void getKey()
{
// int adc1, adc2, key1,key2, key3, key4;
// adc1 = analogRead(keyMap[0]);
// adc2 = analogRead(keyMap[1]);
// Serial.print(adc1);
// Serial.print(",");
// Serial.print(adc2);
// key1 = digitalRead(keyMap[2]);
// key2 = digitalRead(keyMap[3]);
// key3 = digitalRead(keyMap[4]);
// key4 = digitalRead(keyMap[5]);
// Serial.print(key1);
// Serial.print(",");
// Serial.print(key2);
// Serial.print(",");
// Serial.print(key3);
// Serial.print(",");
// Serial.println(key4);
unsigned char i, count = 0;
unsigned int adc;
memset(val.keyResult, 0x00, sizeof(val.keyResult));
for (i = 0; i < KEY_MAX; i++)
{
if (keyMap[i] >= A0)//아날로그 pin read
{
adc = analogRead(keyMap[i]);
if (adc > 530)
{
val.keyResult[count] = 1; //left, up
}else if(adc < 500)
{
val.keyResult[count + 1] = 1; //right, down
}
count++;
}else{//digital pin read
val.keyResult[count] = (~digitalRead(keyMap[i])) & 0x01;
}
count++;
}
}
void keyProcess(void)
{
unsigned char i,key = 0x00;
for (i = 0; i < sizeof(val.keyResult); i++)
{
key |= (val.keyResult[i] << i);
}
val.key = key;
}
void sendMsg()
{
char buf[64];
// unsigned char i,cnt=0;
// for(i=0; i<sizeof(val.keyResult);i++)
// {
// sprintf(&buf[cnt], "%02X,", val.keyResult[i]);
// cnt += 3;
// }
// sprintf(buf, "%02X,%02X,%02X,%02X,%02X,%02X,%02X"
// , val.keyResult[0], val.keyResult[1]
// , val.keyResult[2], val.keyResult[3]
// , val.keyResult[4], val.keyResult[5],
// val.keyResult[6]);
if (val.key == val.keyPre)
return;
val.keyPre = val.key;
sprintf(buf, "key=%02X", val.key);
Serial.println(buf);
}
void setupMain()
{
unsigned char i;
Serial.begin(9600);//시리얼 초기화
memset(&val, 0x00, sizeof(val));//변수 초기화
for (i = 0; i < KEY_MAX; i++) //포트 초기화
{
if(keyMap[i] >= A0)
{
pinMode(keyMap[i], INPUT);//Analog
}else{
pinMode(keyMap[i], INPUT_PULLUP);
}
}
}
void loopMain()
{
getKey();//key값을 read 한다.
keyProcess();//key값을 원하는 형태로 변환한다.
sendMsg();//시리얼 데이타를 전송한다.
}
2. 파이썬
1) 소스코드
.- main.py
쓰레드 2개를 생성하고
쓰레드1에서 시리얼 데이타를 받아 keybuffer에 저장
쓰레드2에서 keybuffer의 데이타에 따라 pyautogui를 사용하여 마우스를 제어 합니다.
import serial
import time
import threading
import pyautogui
import tkinter as tk
# pip install serial
# pip install pyserial
# pip uninstall serial
#https://www.devicemart.co.kr/goods/view?no=1279487
seri = serial.Serial(port='COM9',
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
###########################################
keybuffer = 0
def readSerial():
global isT1Run
global keybuffer
while isT1Run:
pass
try:
if seri.readable():
res = seri.readline()
res = res.decode()[:len(res)-1]
print(res)
if res.find('key') != -1:
res = res.replace("key=","")
key = int(res,16)
keybuffer = key
except:
pass
print('stop thread1')
def mouseProcess():
global isT2Run
global keybuffer
keybufferPre = 0
key = 0
moveOffset = 1
while isT2Run:
pass
try:
if keybuffer != keybufferPre:
key = keybuffer
keybufferPre = keybuffer
print(key)
#move
x, y = 0, 0
if key & 0x01:
x -= moveOffset
if key & 0x02:
x += moveOffset
if key & 0x04:
y -= moveOffset
if key & 0x08:
y += moveOffset
pyautogui.move(x,y)
if x or y:
if moveOffset < 100:
moveOffset *= 2
else:
moveOffset = 1
#click
if key&0x10:
pyautogui.leftClick()
if key&0x20:
pyautogui.rightClick()
if key&0x40:
pyautogui.scroll(200)
if key&0x80:
pyautogui.scroll(-200)
key &= (~0x30);#0xCF#bnt은 한번만 동작하도록 삭제
except:
pass
time.sleep(0.01)
print('stop thread2')
###########################################
isT1Run = True
t1 = threading.Thread(target=readSerial)
t1.start()
isT2Run = True
t2 = threading.Thread(target=mouseProcess)
t2.start()
###########################################
win = tk.Tk()
win.title('[파이선] 아두이노 제어')
win.mainloop()
###########################################
#GUI 종료 후
seri.close()
isT1Run = False
isT2Run = False
time.sleep(0.5)
print('Finish')
반응형
'아두이노' 카테고리의 다른 글
(프로그래밍 언어 실무편) #아두이노와 파이썬을 활용하여 LED Matrix 제어하기 두번째 (슬라이드 기능 추가하기) (0) | 2021.06.03 |
---|---|
(프로그래밍 언어 실무편) #아두이노와 파이썬을 활용하여 LED Matrix 제어하기 (0) | 2021.05.27 |
(프로그래밍 언어 실무편) #16진수와 bit 연산 왜 배우죠?? #python GUI를 활용하여#아두이노 #LED 제어하기 (0) | 2021.05.11 |
(프로그래밍 언어 실무편) #python GUI를 활용하여#아두이노 #LED 제어하기 (0) | 2021.05.04 |
아두이노 개발 환경 구축하기 (0) | 2021.05.03 |