티스토리 뷰
반응형
다른 강의자료는 www.codingnow.co.kr/ 여기를 참고해주세요.!!
C언어와 파이썬을 같이 사용하여 간단한 프로젝트를 진행 합니다.
아두이노의 LED를 시리얼 통신을 사용하여 파이썬 GUI로 제어합니다.
자세한 설명은 첨부 동영상을 참고해주세요.
1. C언어 - 아두이노
1) 회로 구성
4개의 LED를 13~10 번 포트에 연결합니다.
2) 소스파일
-. Blink.ino
아두이노 스케치 파일입니다. main.cpp에서 처리하도록 변경하였습니다.
#include "src/global.h"
void setup()
{
setupMain();
}
void loop()
{
loopMain();
}
-. src/main.cpp
아두이노 초기화와 시리얼 통신으로 받은 데이타 처리를 합니다.
#include "global.h"
//https://www.arduino.cc/reference/ko/language/variables/data-types/stringobject/
#define MAX_LED_CNT 4
unsigned char LEDS[MAX_LED_CNT] = {13,12,11,10};
void responseLedState(unsigned char state)
{
unsigned char i,led;
String hex;
//digitalRead가 안되는 경우가 있어서 state를 가지고 처리함.
led = state;
// led = 0x00;
// for(i=0; i<MAX_LED_CNT; i++)
// {
// if(digitalRead(LEDS[i]))
// {
// led |= 0x01 << i;
// }
// }
Serial.print("Arduino LED : ");
hex = String((led>>4)&0x0F, HEX);
hex += String(led&0x0F, HEX);
Serial.println(hex);
}
void setupMain()
{
unsigned char i;
Serial.begin(9600);
for(i=0; i<MAX_LED_CNT; i++){
pinMode(LEDS[i], OUTPUT);
}
}
void loopMain()
{
unsigned char state = 0, i;
state = serialGet();
if (state != 0xFF)
{
for(i=0; i<MAX_LED_CNT; i++)
{
if (state & (0x01 << i))
{
digitalWrite(LEDS[i], HIGH);
}else{
digitalWrite(LEDS[i], LOW);
}
}
responseLedState(state);
}
}
-. src/processSerial.cpp
시리얼 데이타를 받아 문자열을 정수로 변환하여 리턴합니다.
#include "processSerial.h"
/* String Data Types
https://www.arduino.cc/reference/ko/language/variables/data-types/stringobject/
*/
String str = "";
unsigned char AsciiToHex(unsigned char val)
{
if(val >= '0' && val <= '9')
{
return val-'0';
}
if(val >= 'A' && val <= 'F')
{
return (val-'A')+10;
}
return 0;
}
unsigned char strToHex(String val)
{
unsigned char ret = 0;
ret = AsciiToHex(val[0]) << 4;
ret += AsciiToHex(val[1]);
return ret;
}
unsigned char serialGet(void)
{
unsigned char cmd = 0xFF;
while (Serial.available())
{
str += (char)Serial.read();
if (str.indexOf('\n') > -1 )
{
str.replace("\n","");//enter 삭제
str.replace(" ","");//space 삭제
str.toUpperCase();//대문자변환
if(str.indexOf("LED")>-1)
{
str.replace("LED","");//LED 삭제
if(str.length()==2)
{
cmd = strToHex(str);
// Serial.print(cmd);
}
}
str = "";
}
}
return cmd;
}
2. 파이썬(GUI)
gui를 생성하고 아두이노와 시리얼 통신으로 명령을 주고 받습니다.
1) 소스코드
-.main.py
시리얼 통신을 초기화 하고 데이타를 주고 받습니다.
GUI를 통해 명령을 제어합니다.
import serial
import tkinter as tk
import time
import threading
# pip install serial
# pip install pyserial
# pip uninstall serial
seri = serial.Serial(port='COM9',
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
ledState = 0x00
def sendToAruino(led):
global ledState
if ledState & led:
ledState &= (~led)
else:
ledState |= led
comm = "{:02x}".format(ledState)
# comm = "{:02x}".format(led)#01
comm = 'LED'+comm
print('Send : ', comm)
comm += '\n'
seri.write(bytes(comm, encoding='ascii'))
####################################################
## GUI 생성하기
####################################################
class LedControl():
commands = ['0', '1', '2','3','auto']
def __init__(self):
self.win = tk.Tk()
self.win.title('[파이선] 아두이노 LED 제어')
self.isAuto = False
self.btn = [None for i in range(len(self.commands))]
for i, comm in enumerate(self.commands):##버튼을 만든다.
self.btn[i] = tk.Button(self.win,text=comm,
width=10, height=5,
bg='gray', fg='black',
command=lambda cmd=comm: self.button_click(cmd)
)
self.btn[i].grid(column=i, row=0)
def button_click(self, value):
if value == 'auto':
self.isAuto = True
else:
self.isAuto = False
led = 0x01<< int(value)
print(led)
sendToAruino(led)
#thread 1 함수
def TH_readSerial():
global isT1Run
while isT1Run:
if seri.readable():
res = seri.readline()
res = res.decode()[:len(res)-1]
print(' Response :', res,'\n')
if res.find('Arduino LED') != -1:
res = res.replace("Arduino LED : ", "")
led = int(res, 16)
for i in range(len(tool.btn)):
if led & (0x01 << i):
tool.btn[i].configure(bg="yellow")
else:
tool.btn[i].configure(bg="gray")
print('stop1 thread')
# #thread 2 함수
def TH_sendCmdAuto():
global isT2Run
index = 0
while isT2Run:
if tool.isAuto:
led = 0x01 << index
sendToAruino(led)
index = (index+1) % 4
time.sleep(0.4)
print('stop2 thread')
#GUI class 생성
tool = LedControl()
#쓰레드 생성
isT1Run = True
t1 = threading.Thread(target=TH_readSerial)
t1.start()
isT2Run = True
t2 = threading.Thread(target=TH_sendCmdAuto)
t2.start()
#GUI 실행
tool.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 |
(프로그래밍 언어 실무편) #아두이노와 파이썬을 활용하여 조이스틱 마우스 만들기 (0) | 2021.05.20 |
(프로그래밍 언어 실무편) #python GUI를 활용하여#아두이노 #LED 제어하기 (0) | 2021.05.04 |
아두이노 개발 환경 구축하기 (0) | 2021.05.03 |