이후 재부팅
1. 안드로이드
2. 아이폰
AttributeError: partially initialized module 'serial' has no attribute 'Serial' (most likely due to a circular import)
한 글자씩 받기 (ser.py)
# 한 글자씩 받기
import serial
se = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=1.0)
# baudrate = 통신 속도
# timeout = 1.0초 동안 데이터가 입려되지 않으면 timeout 이벤트 발생
try:
while True:
data = se.read()
print(data)
except KeyboardInterrupt:
pass
se.close()
한 line 씩 받기 (ser2.py)
import serial
se = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=1.0)
try:
while True:
data = se.readline()
data = data.decode() # \r\n 과 같은 정규표현식을 decode 하여 출력한다.
print(data)
except KeyboardInterrupt:
pass
se.close()
해당 시리얼 통신으로 스마트폰 - 라즈베리파이가 연결되었으며 이를 putty를 통해 개발자의 pc 모니터로 확인할 수 있다.
시리얼 통신 코드의 작성 (ser3.py)
import serial
import time
ser = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=1.0)
try:
while True:
data = "Hello world \r\n"
ser.write(data.encode())
time.sleep(1.0)
except KeyboardInterrupt:
pass
ser.close()
통신 받은 data에서 문자열 확인하기 (ser4.py)
import serial
ser = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=1.0)
try:
while True:
data = bleSerial.readline()
data = data.decode()
if data.find("go") >= 0: # find() 함수는 문자열 중 원하는 문자열을 찾으면 0, 그렇지 못했다면 -1을 반환한다.
print("gogo")
elif data.find("back") >= 0:
print("back")
elif data.find("left") >= 0:
print("left")
elif data.find("right") >= 0:
print("right")
elif data.find("stop") >= 0:
print("stop")
except KeyboardInterrupt:
pass
ser.close()
쓰레드 : 프로그램을 실행하는 일꾼을 추가하여 둘 이상의 코드를 동시에 실행시키는 기능
달리기로 예를 들어보자
import threading
import time
def hello():
for i in range(10):
print("hello")
time.sleep(0.2)
def main():
for i in range(10):
print("main code")
time.sleep(0.2)
# 스레드를 사용하지 않았을 시에
hello()
main()
# 스레드를 사용할 시에
task1 = threading.Thread(target=hello)
task1.start()
main()
쓰레드가 필요 할 만한 코드 (thr1.py)
import serial
import time
se = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=1.0)
try:
while True:
data = se.readline()
data = data.decode() # \r\n 과 같은 정규표현식을 decode 하여 출력한다.
print(data)
for i in range(10):
print(i)
time.sleep(0.15)
except KeyboardInterrupt:
pass
se.close()
쓰레드를 사용한 코드 (thr2.py)
import serial
import time
import threading
se = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=1.0)
def serial():
while True:
data = se.readline()
data = data.decode()
print("serial : ", data)
def main():
try:
while True:
print("hello")
time.sleep(1.0)
except KeyboardInterrupt:
pass
if __name__ == '__main__':
task1 = threading.Thread(target=serial)
task1.start()
main()
se.close()
작업관리자 - 프로세스 목록 : 단독으로 실행되는 하나의 일
- 멀티 프로세스 : 홍길동 분신 같은거
- 하나의 CPU에 다양한 프로세스 사용하기
멀티 쓰레드 : 하나의 프로세스를 나누어서 데이터 영역을 공유하면서 프로세스를 운영함.
프로세스 큰 개념 -> 쓰레드 작은 개념.
1단계. 틀 만들기 (car1.py)
import threading
import serial
import time
ser = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=1.0)
ser_data = "" # 시리얼 통신으로 데이터를 입력 받을 변수
def serial():
global ser_data
while True:
data = ser.readline()
data = data.decode()
ser_data = data
def main():
global ser_data
try:
while True:
if ser_data.find("go") >= 0:
print(ser_data)
ser_data = ""
elif ser_data.find("back") >= 0:
print(ser_data)
ser_data = ""
elif ser_data.find("left") >= 0:
print(ser_data)
ser_data = ""
elif ser_data.find("right") >= 0:
print(ser_data)
ser_data = ""
elif ser_data.find("stop") >= 0:
print(ser_data)
ser_data = ""
except KeyboardInterrupt:
pass
if __name__ == '__main__':
task1 = threading.Thread(target=serial)
task1.start()
main()
ser.close()
2단계. 기능 구현 (car2.py)
import RPi.GPIO as gpio
import threading
import serial
import time
ser = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=1.0)
ser_data = "" # 시리얼 통신으로 데이터를 입력 받을 변수
L_M = [18, 22, 27] #PWMA, AIN1, AIN2
R_M = [23, 25, 24] #PWMB, BIN1, BIN2
gpio.setmode(gpio.BCM)
for i in L_M:
gpio.setup(i, gpio.OUT)
for i in R_M:
gpio.setup(i, gpio.OUT)
L_Motor = gpio.PWM(L_M[0], 500)
L_Motor.start(0)
R_Motor = gpio.PWM(R_M[0], 500)
R_Motor.start(0)
def serial():
global ser_data
while True:
data = ser.readline()
data = data.decode()
ser_data = data
def drive(speed, left, right):
# 좌측 모터 드라이버
gpio.output(L_M[1], left)
if left <= 0 :
left2 = 1
else:
left2 = 0
gpio.output(L_M[2], left2)
L_Motor.ChangeDutyCycle(speed)
# 우측 모터 드라이버
gpio.output(R_M[1], right)
if right <= 0:
right2 = 1
else:
right2 = 0
gpio.output(R_M[2], right2)
R_Motor.ChangeDutyCycle(speed)
def main():
global ser_data
try:
while True:
if ser_data.find("go") >= 0:
print(ser_data)
drive(50, 0, 0)
ser_data = ""
elif ser_data.find("back") >= 0:
print(ser_data)
drive(50, 1, 1)
ser_data = ""
elif ser_data.find("left") >= 0:
print(ser_data)
drive(50, 1, 0)
ser_data = ""
elif ser_data.find("right") >= 0:
print(ser_data)
drive(50, 0, 1)
ser_data = ""
elif ser_data.find("stop") >= 0:
print(ser_data)
drive(0, 0, 0)
ser_data = ""
except KeyboardInterrupt:
pass
if __name__ == '__main__':
task1 = threading.Thread(target=serial)
task1.start()
main()
gpio.cleanup()
ser.close()
스위치를 이용한 비상 정지 기능 (car3.py)
import RPi.GPIO as gpio
import threading
import serial
import time
ser = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=1.0)
ser_data = "" # 시리얼 통신으로 데이터를 입력 받을 변수
SW = [5,6,13,19] # sw1 , 2, 3, 4
L_M = [18, 22, 27] #PWMA, AIN1, AIN2
R_M = [23, 25, 24] #PWMB, BIN1, BIN2
gpio.setmode(gpio.BCM)
for i in SW:
gpio.setup(i, gpio.IN, pull_up_down=gpio.PUD_DOWN)
for i in L_M:
gpio.setup(i, gpio.OUT)
for i in R_M:
gpio.setup(i, gpio.OUT)
L_Motor = gpio.PWM(L_M[0], 500)
L_Motor.start(0)
R_Motor = gpio.PWM(R_M[0], 500)
R_Motor.start(0)
def serial():
global ser_data
while True:
data = ser.readline()
data = data.decode()
ser_data = data
def drive(speed, left, right):
# 좌측 모터 드라이버
gpio.output(L_M[1], left)
if left <= 0 :
left2 = 1
else:
left2 = 0
gpio.output(L_M[2], left2)
L_Motor.ChangeDutyCycle(speed)
# 우측 모터 드라이버
gpio.output(R_M[1], right)
if right <= 0:
right2 = 1
else:
right2 = 0
gpio.output(R_M[2], right2)
R_Motor.ChangeDutyCycle(speed)
def main():
global ser_data
try:
while True:
if ser_data.find("go") >= 0:
print(ser_data)
drive(50, 0, 0)
ser_data = ""
elif ser_data.find("back") >= 0:
print(ser_data)
drive(50, 1, 1)
ser_data = ""
elif ser_data.find("left") >= 0:
print(ser_data)
drive(50, 1, 0)
ser_data = ""
elif ser_data.find("right") >= 0:
print(ser_data)
drive(50, 0, 1)
ser_data = ""
elif ser_data.find("stop") >= 0:
print(ser_data)
drive(0, 0, 0)
ser_data = ""
# gpio.HIGH == 0
if gpio.input(SW[0]) == gpio.HIGH or gpio.input(SW[1]) == gpio.HIGH or gpio.input(SW[2]) == gpio.HIGH or gpio.input(SW[3]) == gpio.HIGH:
drive(0,0,0)
except KeyboardInterrupt:
pass
if __name__ == '__main__':
task1 = threading.Thread(target=serial)
task1.start()
main()
gpio.cleanup()
ser.close()
이동방향 LED로 표시하기 (carAdd1.py)
import threading
import serial
import time
import RPi.GPIO as gpio
ser = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=1.0)
ser_data = "" # 시리얼 통신으로 데이터를 입력 받을 변수
SW = [5,6,13,19] # sw1 , 2, 3, 4
L_M = [18, 22, 27] #PWMA, AIN1, AIN2
R_M = [23, 25, 24] #PWMB, BIN1, BIN2
LED = [26, 16, 20, 21] #전좌, 전우, 후좌, 후우
gpio.setmode(gpio.BCM)
for i in LED:
gpio.setup(i, gpio.OUT)
# gpio.setup(i, gpio.OUT, initial=gpio.LOW) # 프로그램 시작과 동시에 gpio 상태를 셋팅함, LOW 해두면 프로그램을 시작하면서 LED가 꺼진상태로 시작.
for i in SW:
gpio.setup(i, gpio.IN, pull_up_down=gpio.PUD_DOWN)
for i in L_M:
gpio.setup(i, gpio.OUT)
for i in R_M:
gpio.setup(i, gpio.OUT)
L_Motor = gpio.PWM(L_M[0], 500)
L_Motor.start(0)
R_Motor = gpio.PWM(R_M[0], 500)
R_Motor.start(0)
def serial():
global ser_data
while True:
data = ser.readline()
data = data.decode()
ser_data = data
def drive(speed, left, right):
# 좌측 모터 드라이버
gpio.output(L_M[1], left)
if left <= 0 :
left2 = 1
else:
left2 = 0
gpio.output(L_M[2], left2)
L_Motor.ChangeDutyCycle(speed)
# 우측 모터 드라이버
gpio.output(R_M[1], right)
if right <= 0:
right2 = 1
else:
right2 = 0
gpio.output(R_M[2], right2)
R_Motor.ChangeDutyCycle(speed)
def led_func(front_L, front_R, back_L, back_R):
gpio.output(LED[0], front_L)
gpio.output(LED[1], front_R)
gpio.output(LED[2], back_L)
gpio.output(LED[3], back_R)
def main():
global ser_data
try:
while True:
if ser_data.find("go") >= 0:
print(ser_data)
led_func(1,1,0,0)
drive(50, 0, 0)
ser_data = ""
elif ser_data.find("back") >= 0:
print(ser_data)
led_func(0,0,1,1)
drive(50, 1, 1)
ser_data = ""
elif ser_data.find("left") >= 0:
print(ser_data)
led_func(1,0,1,0)
drive(50, 1, 0)
ser_data = ""
elif ser_data.find("right") >= 0:
print(ser_data)
led_func(0,1,0,1)
drive(50, 0, 1)
ser_data = ""
elif ser_data.find("stop") >= 0:
print(ser_data)
led_func(0,0,0,0)
drive(0, 0, 0)
ser_data = ""
# gpio.HIGH == 0
if gpio.input(SW[0]) == gpio.HIGH or gpio.input(SW[1]) == gpio.HIGH or gpio.input(SW[2]) == gpio.HIGH or gpio.input(SW[3]) == gpio.HIGH:
led_func(0,0,0,0)
drive(0,0,0)
except KeyboardInterrupt:
pass
if __name__ == '__main__':
task1 = threading.Thread(target=serial)
task1.start()
main()
gpio.cleanup()
ser.close()
경적기능 추가 (carAdd2.py)
import threading
import serial
import time
import RPi.GPIO as gpio
import RPi.GPIO as gpio
import threading
import serial
import time
ser = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=1.0)
ser_data = "" # 시리얼 통신으로 데이터를 입력 받을 변수
SW = [5,6,13,19] # sw1 , 2, 3, 4
L_M = [18, 22, 27] #PWMA, AIN1, AIN2
R_M = [23, 25, 24] #PWMB, BIN1, BIN2
LED = [26, 16, 20, 21] #전좌, 전우, 후좌, 후우
BUZZER = 12
gpio.setmode(gpio.BCM)
for i in LED:
gpio.setup(i, gpio.OUT)
# gpio.setup(i, gpio.OUT, initial=gpio.LOW) # 프로그램 시작과 동시에 gpio 상태를 셋팅함, LOW 해두면 프로그램을 시작하면서 LED가 꺼진상태로 시작.
for i in SW:
gpio.setup(i, gpio.IN, pull_up_down=gpio.PUD_DOWN)
for i in L_M:
gpio.setup(i, gpio.OUT)
for i in R_M:
gpio.setup(i, gpio.OUT)
gpio.setup(BUZZER, gpio.OUT)
p = gpio.PWM(BUZZER, 391)
p.stop()
L_Motor = gpio.PWM(L_M[0], 500)
L_Motor.start(0)
R_Motor = gpio.PWM(R_M[0], 500)
R_Motor.start(0)
def serial():
global ser_data
while True:
data = ser.readline()
data = data.decode()
ser_data = data
def drive(speed, left, right):
# 좌측 모터 드라이버
gpio.output(L_M[1], left)
if left <= 0 :
left2 = 1
else:
left2 = 0
gpio.output(L_M[2], left2)
L_Motor.ChangeDutyCycle(speed)
# 우측 모터 드라이버
gpio.output(R_M[1], right)
if right <= 0:
right2 = 1
else:
right2 = 0
gpio.output(R_M[2], right2)
R_Motor.ChangeDutyCycle(speed)
def led_func(front_L, front_R, back_L, back_R):
gpio.output(LED[0], front_L)
gpio.output(LED[1], front_R)
gpio.output(LED[2], back_L)
gpio.output(LED[3], back_R)
def main():
global ser_data
try:
while True:
if ser_data.find("go") >= 0:
print(ser_data)
led_func(1,1,0,0)
drive(50, 0, 0)
ser_data = ""
elif ser_data.find("back") >= 0:
print(ser_data)
led_func(0,0,1,1)
drive(50, 1, 1)
ser_data = ""
elif ser_data.find("left") >= 0:
print(ser_data)
led_func(1,0,1,0)
drive(50, 1, 0)
ser_data = ""
elif ser_data.find("right") >= 0:
print(ser_data)
led_func(0,1,0,1)
drive(50, 0, 1)
ser_data = ""
elif ser_data.find("stop") >= 0:
print(ser_data)
led_func(0,0,0,0)
drive(0, 0, 0)
ser_data = ""
elif ser_data.find("bz_on") >= 0:
print("bz_on")
p.start(50)
p.ChangeFrequency(391)
ser_data = ""
elif ser_data.find("bz_off") >= 0:
print("bz_off")
p.stop()
ser_data = ""
# gpio.HIGH == 0
if gpio.input(SW[0]) == gpio.HIGH or gpio.input(SW[1]) == gpio.HIGH or gpio.input(SW[2]) == gpio.HIGH or gpio.input(SW[3]) == gpio.HIGH:
led_func(0,0,0,0)
drive(0,0,0)
p.stop()
except KeyboardInterrupt:
pass
if __name__ == '__main__':
task1 = threading.Thread(target=serial)
task1.start()
main()
gpio.cleanup()
ser.close()
putty 터미널