티스토리 뷰
반응형
다른 강의자료는 www.codingnow.co.kr/ 여기를 참고해주세요.!!
MCU의 제한된 포트 수로 인한 LED 제어 가능 수가 제한됩니다.
이런 점을 극복하기 위해 matrix 형태로 LED를 구성하게 됩니다.
이번시간에는 matirix를 어떻게 제어하는지 또한 어떻게 활용하는지 강의해 보았습니다.
자세한 사항은 첨부된 동영상을 참고해주세요.
1. C언어 - 아두이노
1-1) 회로구성 (led matrix : 1088BS)
1-2) 스케메틱
2) 소스코드
-.main.cpp : 주요 제어 코드
#include "global.h"
#include <MsTimer2.h>
/*
Arduino Uno Board 메인 컨트롤러 : Atmega328
Atmega328를 3개의 타이머가 있고 PWM 출력 및 시간 관련 함수들을 제공
Timer0 - 8Bit : PWM 5/6핀, 시간 관련 함수 (delay(), millis() 등)
Timer1 - 16Bit : PWM 9/10핀 (외부 라이브러리 Servo.h 와 함께 사용 불가)
Timer2 - 8Bit : PWM 3/11핀 (외부 라이브러리 MsTimer2.h 와 함께 사용 불가)
*/
#define _CONTROL_PYTHON_EN
// #define _TEST_0_EN
// #define _DEMO_EN
unsigned char ledMap[2][COLUMN_MAX] = {
/*ROW*/ {A5, 3, 13, A2, 6, 12, 7, 10},
/*COL*/ {2, 8, 9, A4, 11, A3, 4, 5},
};
typedef struct{
unsigned char dispBuffer[ROW_MAX];//display data buffer
unsigned char rxBuffer[ROW_MAX];//serial data buffer
unsigned char currRow;
#if defined(_DEMO_EN) || defined(_TEST_0_EN)
unsigned long timeCurr;
unsigned long timeDealy;
#ifdef _TEST_0_EN
unsigned char idexRow;
unsigned char idexCol;
#endif
#ifdef _DEMO_EN
unsigned char imageIdex;
#endif
#endif
}valType;
valType val;
unsigned char const heart[ROW_MAX] = {
0b00000000,//0x00
0b01100110,//0x66
0b10011001,//0x99
0b10000001,//0x81
0b10000001,//0x81
0b01000010,//0x42
0b00100100,//0x24
0b00011000,//0x18
};
#ifdef _DEMO_EN
#define IMAGE_MAX 4
unsigned char const images[IMAGE_MAX][ROW_MAX] = {
{0x00, 0x42, 0xA5, 0x00, 0x00, 0x00, 0x42, 0x3C},
{0x00, 0x42, 0xA5, 0x42, 0x00, 0x00, 0x42, 0x3C},
{0x00, 0x42, 0xA5, 0x00, 0x00, 0x00, 0x3C, 0x42},
{0x00, 0x66, 0x99, 0x81, 0x81, 0x42, 0x24, 0x18},
};
#endif
void Timer2Interrupt()
{
unsigned char i, col;
digitalWrite(ledMap[ROW][val.currRow], LOW); //row port 초기화
val.currRow = (val.currRow + 1) % ROW_MAX;
col = val.dispBuffer[val.currRow]; //row의 column을 가져온다.
for (i = 0; i < COLUMN_MAX; i++)
{
if (col & (0x01<<i))
digitalWrite(ledMap[COL][i], LOW);//column on
else
digitalWrite(ledMap[COL][i], HIGH);//column off
}
digitalWrite(ledMap[ROW][val.currRow], HIGH); //row port enable
}
void setupMain()
{
unsigned char i;
Serial.begin(9600);//시리얼 초기화
memset(&val, 0x00, sizeof(val));//변수초기화
for (i = 0; i < COLUMN_MAX; i++) //포트 초기화
{
pinMode(ledMap[ROW][i], OUTPUT); //row
pinMode(ledMap[COL][i], OUTPUT); //col
}
memcpy(val.dispBuffer, heart, sizeof(val.dispBuffer));//heart image 넣기
// val.dispBuffer[1] = 0x01;
// memset(val.dispBuffer,0xff, sizeof(val.dispBuffer));
MsTimer2::set(1, Timer2Interrupt);//timer2 interrupt
MsTimer2::start();
#if defined(_DEMO_EN) || defined(_TEST_0_EN)
val.timeCurr = millis();
val.timeDealy = 1000;
#endif
}
void loopMain()
{
#ifdef _CONTROL_PYTHON_EN
if (serialGet(val.rxBuffer))
{
memcpy(val.dispBuffer, val.rxBuffer, sizeof(val.dispBuffer));
}
#endif
#if defined(_DEMO_EN) || defined(_TEST_0_EN)
if ((millis() - val.timeCurr) > val.timeDealy)
{
val.timeCurr = millis();
#ifdef _DEMO_EN
val.timeDealy = 500;
memcpy(val.dispBuffer, &images[val.imageIdex], sizeof(val.dispBuffer));
val.imageIdex = (val.imageIdex + 1) % IMAGE_MAX;
#endif
#ifdef _TEST_0_EN
val.timeDealy = 100;
memset(val.dispBuffer, 0x00, sizeof(val.dispBuffer));
val.dispBuffer[val.idexRow] = 0x01 << val.idexCol;
val.idexCol = (val.idexCol + 1) % COLUMN_MAX;
if (val.idexCol == 0)
{
val.idexRow = (val.idexRow + 1) % ROW_MAX;
}
#endif
}
#endif
}
-.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(unsigned char* buffer)
{
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 삭제
Serial.println(str);
if (str.length() == (2 * ROW_MAX))
{
unsigned char i,cnt=0;
for(i=0; i<ROW_MAX; i++)
{
buffer[i] = strToHex(str.substring(cnt,cnt+2));
cnt += 2;
}
str = "";
return 1;
}
}
str = "";
}
}
return 0;
}
2.파이썬
1) 소스코드
-.main.py : led 제어 GUI
import serial
import tkinter as tk
import time
import threading
# pip install serial
# pip install pyserial
# pip uninstall serial
images = ['0042A5000000423C',
'0042A5420000423C',
'0042A50000003C42',
'0066998181422418']
seri = serial.Serial(port='COM8',
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
def sendToAruino(img):
comm = 'LED'+images[img]
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('[파이선] 아두이노 Matrix 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
sendToAruino(int(value))
# #thread 2 함수
def TH_sendCmdAuto():
global isT1Run
index = 0
while isT1Run:
if tool.isAuto:
sendToAruino(index)
index = (index+1) % len(images)
time.sleep(0.5)
print('stop2 thread')
#GUI class 생성
tool = LedControl()
isT1Run = True
t2 = threading.Thread(target=TH_sendCmdAuto)
t2.start()
#GUI 실행
tool.win.mainloop()
#GUI 종료 후
isT1Run = False
time.sleep(0.5)
seri.close()
print('Finish')
반응형
'아두이노' 카테고리의 다른 글
(프로그래밍 언어 실무편) #아두이노, 스테핑 모터, 서보 모터, 조이스틱을 활용한 초간단 #로봇팔 만들기 (비트연산) (0) | 2021.06.23 |
---|---|
(프로그래밍 언어 실무편) #아두이노와 파이썬을 활용하여 LED Matrix 제어하기 두번째 (슬라이드 기능 추가하기) (0) | 2021.06.03 |
(프로그래밍 언어 실무편) #아두이노와 파이썬을 활용하여 조이스틱 마우스 만들기 (0) | 2021.05.20 |
(프로그래밍 언어 실무편) #16진수와 bit 연산 왜 배우죠?? #python GUI를 활용하여#아두이노 #LED 제어하기 (0) | 2021.05.11 |
(프로그래밍 언어 실무편) #python GUI를 활용하여#아두이노 #LED 제어하기 (0) | 2021.05.04 |