2023 과학전시관 ai메이커 직무연수 자료 업데이트
작성자 : 경기기계공업고 교사 성원경
메인 강의 자료 (canva ppt)
- 목차.
1. 아두이노 서보모터 제어하기
2. 로봇팔 프로토 타입 모델링하기
3. 파이썬 음성 인식하기
4. 파이썬 음성인식 코드와 아두이노 서보모터 제어 연결하기
사전 작업 : 프로그램 설치
1. 아두이노 프로그램 설치
2. vs코드 설치
3. 아나콘다 설치
참고자료.
1. 아두이노 서보모터 제어하기
실습 1. 서보모터 1개 제어하기
- 회로
- 코드 설명
- 코드 원본
#include <Servo.h>
Servo servo;
int value = 0;
void setup() {
servo.attach(7);
}
void loop() {
value = 0;
servo.write(value);
delay(500);
value = 90;
servo.write(value);
delay(500);
value = 179;
servo.write(value);
delay(500);
}
실습 2. 시리얼 통신으로 서보모터 제어하기
(이론적 배경) 시리얼통신이란?
- 회로
- 코드 1 - 시리얼 통신 테스트
- 코드 1 원본
void setup() {
Serial.begin(9600); // Serial 통신을 설정합니다.
}
void loop() {
Serial.println("hello World"); //Serial 모니터에 a에 저장된 값을 타이핑 합니다.
delay(500);
}
코드 2 - 시리얼 통신으로 서보모터 제어하기
코드2 원본
#include <Servo.h>
Servo servo;
int value = 0;
void setup() {
servo.attach(7);
Serial.begin(9600); // Serial 통신을 설정합니다.
while(!Serial);
Serial.println("Servor Mortor");
}
void loop() {
if(Serial.available()){ //Serial 모니터창에 어떤 값이 들어오면 실행을 합니다.
value = Serial.parseInt(); //Serial 모니터창에서 받은 값을 a라는 변수로 넘겨줍니다.
Serial.print("각도 : ");
Serial.println(value);
servo.write(value);
delay(15);
}
}
실습3. 서보모터 2개 시리얼 통신으로 제어하기.
- 회로
- 코드 설명
- 코드(2축 서보모터 시리얼 통신 제어)
#include <Servo.h> //헤더파일 포함
Servo servo1; //servo1 변수 선언
Servo servo2; //servo2 변수 선언
int motor1 = 3; //motor1을 입출력 3번 핀에 연결
int motor2 = 5; //motor2을 입출력 5번 핀에 연결
int angle1 = 90; //초기 각도값 설정
int angle2 = 90; //초기 각도값 설정
void setup() {
servo1.attach(motor1); //servo1에 입출력 3번 핀을 지정
servo2.attach(motor2); //servo2에 입출력 5번 핀을 지정
Serial.begin(9600); //시리얼 모니터 사용
Serial.println("Enter the w,a,s,d ");
}
void loop() {
if(Serial.available()) //시리얼 통신이 가능할 경우
{
char input = Serial.read(); //시리얼 모니터 입력 값을 읽어옴
if(input =='w') //입력값이 W일 경우
{
Serial.print("+30");
for(int i = 0; i <30; i++) // 30번 반복
{
angle1 = angle1 + 1; // angle1의 값에 1씩 30번을 더함
if(angle1 >=180) // angle1이 180보다 커지거나 같아질 경우
angle1 = 180; // angle1을 180으로 고정
servo1.write(angle1); // servo1을 angle1 값에 맞추어 동작
delay(10);
}
Serial.print("\t\t");
Serial.println(angle1);
}
else if(input =='a') //입력값이 a일 경우
{
Serial.print("+30");
for(int j = 0; j <30; j++)
{
angle2 = angle2 + 1;
if(angle2 >=180)
angle2 = 180;
servo2.write(angle2);
delay(10);
}
Serial.print("\t\t");
Serial.println(angle2);
}
else if(input == 's') //입력값이 s일 경우
{
Serial.print("\t-30\t");
for(int i = 0; i <30; i++) // 30번 반복
{
angle1 = angle1 -1; // angle1의 값에 1씩 30번을 빼기
if(angle1 <= 0) // angle1이 0보다 작아지거나 같을 경우
angle1 = 0; // angle1을 0으로 고정
servo1.write(angle1); // servo1을 angle 값에 맞추어 동작
delay(10);
}
Serial.println(angle1);
}
else if(input == 'd') //입력값이 d일 경우
{
Serial.print("\t-30\t");
for(int j = 0; j <30; j++)
{
angle2 = angle2 -1;
if(angle2 <= 0)
angle2 = 0;
servo2.write(angle2);
delay(10);
}
Serial.println(angle2);
}
}
}
- 코드(3축 서보모터 시리얼 통신 제어)
#include <Servo.h> //헤더파일 포함
Servo servo0; //servo0 변수 선언
Servo servo1; //servo1 변수 선언
Servo servo2; //servo2 변수 선언
int motor0 = 6; //motor1을 입출력 3번 핀에 연결
int motor1 = 3; //motor1을 입출력 3번 핀에 연결
int motor2 = 5; //motor2을 입출력 5번 핀에 연결
int angle0 = 90; //초기 각도값 설정
int angle1 = 90; //초기 각도값 설정
int angle2 = 90; //초기 각도값 설정
void setup() {
servo0.attach(motor0); //servo0에 입출력 3번 핀을 지정
servo1.attach(motor1); //servo1에 입출력 3번 핀을 지정
servo2.attach(motor2); //servo2에 입출력 5번 핀을 지정
Serial.begin(9600); //시리얼 모니터 사용
Serial.println("Enter the w,a,s,d,z,c");
}
void loop() {
if(Serial.available()) //시리얼 통신이 가능할 경우
{
char input = Serial.read(); //시리얼 모니터 입력 값을 읽어옴
if(input =='w') //입력값이 W일 경우
{
Serial.print("+30");
for(int i = 0; i <30; i++) // 30번 반복
{
angle1 = angle1 + 1; // angle1의 값에 1씩 30번을 더함
if(angle1 >=180) // angle1이 180보다 커지거나 같아질 경우
angle1 = 180; // angle1을 180으로 고정
servo1.write(angle1); // servo1을 angle1 값에 맞추어 동작
delay(10);
}
Serial.print("\t\t");
Serial.println(angle1);
}
else if(input =='a') //입력값이 a일 경우
{
Serial.print("+30");
for(int j = 0; j <30; j++)
{
angle2 = angle2 + 1;
if(angle2 >=180)
angle2 = 180;
servo2.write(angle2);
delay(10);
}
Serial.print("\t\t");
Serial.println(angle2);
}
else if(input == 's') //입력값이 s일 경우
{
Serial.print("\t-30\t");
for(int i = 0; i <30; i++) // 30번 반복
{
angle1 = angle1 -1; // angle1의 값에 1씩 30번을 빼기
if(angle1 <= 0) // angle1이 0보다 작아지거나 같을 경우
angle1 = 0; // angle1을 0으로 고정
servo1.write(angle1); // servo1을 angle 값에 맞추어 동작
delay(10);
}
Serial.println(angle1);
}
else if(input == 'd') //입력값이 d일 경우
{
Serial.print("\t-30\t");
for(int j = 0; j <30; j++)
{
angle2 = angle2 -1;
if(angle2 <= 0)
angle2 = 0;
servo2.write(angle2);
delay(10);
}
Serial.println(angle2);
}
else if(input == 'z') //입력값이 d일 경우
{
Serial.print("\t-30\t");
for(int j = 0; j <30; j++)
{
angle0 = angle0 +1;
if(angle0 >= 180)
angle0 = 180;
servo0.write(angle0);
delay(10);
}
Serial.println(angle0);
}
else if(input == 'c') //입력값이 d일 경우
{
Serial.print("\t-30\t");
for(int j = 0; j <30; j++)
{
angle0 = angle0 -1;
if(angle0 <= 0)
angle0 = 0;
servo0.write(angle0);
delay(10);
}
Serial.println(angle0);
}
}
}
- 코드(4축 서보모터 시리얼 통신 제어)
#include <Servo.h> //헤더파일 포함
Servo servo0; //servo0 변수 선언
Servo servo1; //servo1 변수 선언
Servo servo2; //servo2 변수 선언
Servo servo3; //servo3 변수 선언
int motor[4]={6, 3, 5, 9}; //servo motor와 연결된 digital pin 값을 설정
int angle[4]={90, 90, 90, 90}; //초기 각도값 설정
void setup() {
servo0.attach(motor[0]); //servo0에 입출력 6번 핀을 지정_베이스 서보
servo1.attach(motor[1]); //servo1에 입출력 3번 핀을 지정_상하1 서보
servo2.attach(motor[2]); //servo2에 입출력 5번 핀을 지정_상하2 서보
servo3.attach(motor[3]); //servo2에 입출력 9번 핀을 지정_그리퍼 서보
Serial.begin(9600); //시리얼 모니터 사용
Serial.println("Enter the w,a,s,d,z,c");
}
int delayTime(int i){ //지연값 변경
return int(sq(abs(15-i))*0.1)+10;
//return 10;
}
void move(int smotor, int dir){
if(dir==1){
Serial.print("+30");
}else{
Serial.print("-30");
}
for(int i = 0; i <30; i++) // 30번 반복
{
angle[smotor] = angle[smotor] + dir; // angle1의 값에 +-1씩 30번을 더함
if(angle[smotor] >=180) // angle1이 180보다 커지거나 같아질 경우
angle[smotor] = 180; // angle1을 180으로 고정
if(angle[smotor] <=0) // angle1이 180보다 커지거나 같아질 경우
angle[smotor] = 0; // angle1을 180으로 고정
servo0.write(angle[0]); // servo1을 angle[0] 값에 맞추어 동작
servo1.write(angle[1]); // servo2을 angle[1] 값에 맞추어 동작
servo2.write(angle[2]); // servo3을 angle[2] 값에 맞추어 동작
servo3.write(angle[3]); // servo4을 angle[3] 값에 맞추어 동작
delay(delayTime(i));
}
Serial.print("\t\t");
Serial.println(angle[smotor]);
}
void loop() {
if(Serial.available()) //시리얼 통신이 가능할 경우
{
char input = Serial.read(); //시리얼 모니터 입력 값을 읽어옴
if(input =='w') //입력값이 W일 경우
{
move(1, 1);
}
else if(input == 's') //입력값이 s일 경우
{
move(1, -1);
}
else if(input =='a') //입력값이 a일 경우
{
move(2, 1);
}
else if(input == 'd') //입력값이 d일 경우
{
move(2, -1);
}
else if(input == 'z') //입력값이 z일 경우
{
move(0, 1);
}
else if(input == 'c') //입력값이 c일 경우
{
move(0, -1);
}
else if(input == 'q') //입력값이 q일 경우
{
move(3, 1);
}
else if(input == 'e') //입력값이 e일 경우
{
move(3, -1);
}
}
2. 로봇팔 프로토 타입 제작
- 로봇팔 모델링 참고자료
https://www.tinkercad.com/dashboard
- 제작 예시
3. 파이썬 음성 인식하기
1) 시작하며 : VS 코드 사용해 보기
2) 파이썬 음성인식 환경 구성 및 코드 작성
- 음성인식 코드
import speech_recognition as sr
# 인스턴스 생성
r = sr.Recognizer()
# 마이크 설정
microphone = sr.Microphone(sample_rate=16000)
# 마이크 소음 수치 반영
with microphone as source:
r.adjust_for_ambient_noise(source)
print("주변 소음 수치 {}".format(r.energy_threshold))
# 음성 수집해서 텍스트로 변환
with microphone as source:
print("말씀하세요.")
result = r.listen(source)
text = r.recognize_google(result, language='ko')
#변환된 텍스트 출력
print(text)
4. 로봇팔 음성제어
- 코드
import speech_recognition as sr
import time
import serial
ser = serial.Serial('COM4',9600)
r = sr.Recognizer()
microphone = sr.Microphone(sample_rate=16000)
try:
while True:
with microphone as source:
r.adjust_for_ambient_noise(source)
print("소음수치 {}".format(r.energy_threshold))
with microphone as source:
print("말씀하세요.")
result = r.listen(source)
text = r.recognize_google(result, language='ko')
if '위' in text:
ser.write(b'w')
print('로봇팔을 올립니다.')
elif '아래' in text: ser.write(b's')
elif '좌' in text: ser.write(b'a')
elif '우' in text: ser.write(b'd')
except KeyboardInterrupt:
print('ctrl + c 중지 메세지 출력')
print('프로그램을 종료합니다')
- 코드2
import speech_recognition as sr
import time
import serial
ser = serial.Serial('COM4',9600)
r = sr.Recognizer()
microphone = sr.Microphone(sample_rate=16000)
try:
while True:
with microphone as source:
r.adjust_for_ambient_noise(source)
print("소음수치 {}".format(r.energy_threshold))
with microphone as source:
print("말씀하세요.")
result = r.listen(source)
text = r.recognize_google(result, language='ko')
print(text)
if '왼' in text:
ser.write(b'a')
print('왼쪽으로.')
elif '오' in text:
ser.write(b'd')
print('오른쪽으로.')
elif '불' or 'led' in text:
ser.write(b's')
print('led ON/OFFd')
except KeyboardInterrupt:
print('ctrl + c 중지 메세지 출력')
print('프로그램을 종료합니다')
방법 : 기존 아두이노 로봇팔 프로토타입 회로를 윈도우 PC에 연결해서 시리얼통신으로 제어한다.
import speech_recognition as sr
import time
import serial
ser = serial.Serial('COM7',9600)
r = sr.Recognizer()
microphone = sr.Microphone(sample_rate=16000)
try:
while True:
with microphone as source:
r.adjust_for_ambient_noise(source)
print("소음수치 {}".format(r.energy_threshold))
with microphone as source:
text=None
print("말씀하세요.")
result = r.listen(source)
try: #음성 인식이 잘 안될 경우 UnknownValueError 예외가 발생, 예외 처리 추가(시작)
text = r.recognize_google(result, language='ko') #UnknownValueError 발생 코드
print(text)
if '왼' in text:
ser.write(b'z')
print('왼쪽으로.')
elif '오' in text:
ser.write(b'c')
print('오른쪽으로.')
elif '위' in text:
ser.write(b'w')
print('위로')
elif '아래' in text:
ser.write(b's')
print('아래로')
elif '올려'in text:
ser.write(b'd')
print('더 위로')
elif '내려'in text:
ser.write(b'a')
print('더 아래로')
elif '잡아' in text or '자' in text or '바' in text:
ser.write(b'e')
print('물건 잡아')
elif '풀어'in text or '놔' in text:
ser.write(b'q')
print('물건 풀어')
except sr.UnknownValueError: #UnknownValueError 예외 발생할 경우 메시지 출력
print("다시 말씀하세요")
except KeyboardInterrupt:
print('ctrl + c 중지 메세지 출력')
print('프로그램을 종료합니다')
- 동작영상(4축)
끝.
'메이커 프로젝트' 카테고리의 다른 글
[AI 메이커 특강] 경기기계공업고등학교 미니 로봇 음성제어 프로젝트 자료 (0) | 2022.11.02 |
---|---|
라즈베리파이 설치 안내 및 스마트 액자 만들기 강의자료 (0) | 2022.09.29 |
픽스호크 자율비행 드론 제작 - 미션플래너 세팅 2부(조종기 세팅, esc 캘리브레이션, 모터테스트) (11) | 2022.01.20 |
자율비행 드론 하드웨어 제작 2부 (1) | 2022.01.18 |
자율비행 드론 미션플래너 세팅 1부 (0) | 2022.01.18 |