티스토리 뷰
반응형
다른 강의자료는 www.codingnow.co.kr/ 여기를 참고해주세요.!!
코딩나우
프로그래밍 교육및 개발의뢰 받습니다.
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 |