* 회로를 혼자 만들 수 있는 수준의 사람이라고 가정하고 써놓음
-서보 모터
서보는 지속적으로 회전하는 대신 어떤 위치로 이동하는 방식으로 작동되기 때문에 물리적인 이동을 정밀하게 제어하는 데 유용하다(특히 0도 ~ 180도 사이에서)
서보 모터 내부 구조 |
위치 피드백이 끊어져 있는 연속 회전 서보 모터를 사용하면 계속 회전할 수 있다.
// 모터 쉴드를 사용하지 않아도 된다.
서보 모터는 펄스의 지속 시간에 반응한다.
펄스의 지속 시간에 따른 회전방향
펄스의 지속 시간에 따른 회전방향
-----------------------ㅣ---------------------------ㅣ------------------------>
1ms 2ms
한쪽 끝으로 회전 펄스폭에 비례해서 회전 반대쪽으로 회전
-솔레노이드와 릴레이
솔레노이드는 전원이 공급되었을 때 선형 이동을 제공한다. 솔레노이드에는 전류가 코일을 통과할 때 생성되는 자기자에 의해 움직이는 금속 코어가 있다. 기계식 릴레이는 전기 접점을 연결하거나 끊어 주는 일종의 솔레노이드다.
-브러시드 및 브러시리스 모터
-스텝퍼 모터
스텝퍼는 제어 펄스에 반응해서 정해진 각도로 회전하는 모터다. 단계별 회전 각도는 모터에 따라 다르며, 단계당 1~2도부터 시작해서 30도 이상까지 다양하다.
*모터를 선택할 때 가장 중요하게 고려하는 특성은 토크다.
토크에 따라 모터의 최대 작업 용량이 결정된다. 일반적으로 토크가 높은 모터가 저토크 모터에 비해 크고 무거울 뿐만 아니라 전류도 많이 사용한다.
서보 모터 예제
#include <Servo.h>
Servo myservo; // 서보를 제어할 서보 오브젝트를 만든다.
int angle =0; // 서보 위치를 저장할 변수
void setup(){
myservo.attach(9); // 핀 9의 서보를 서보 오브젝트에 연결한다.
}
void loop(){
for(angle =0; angle<180; angle+=1){ // 0도에서 180도로 이동한다.
myservo.write(angle); // 'angle' 변수의 위치로 서보를 이동시킨다.
delay(20); // 서보 명령 간에 20ms를 기다린다.
}
for(angle = 180; angle >= 1; angle-=1){ // 180도에서 0도로 이동한다.
myservo.write(angle); // 서보를 반대 방향으로 이동한다.
delay(20); // 서보 명령 간에 20ms를 기다린다.
}
}
#include <Servo.h>
Servo myservo; // 서보를 제어할 서보 오브젝트를 만든다.
int angle =0; // 서보 위치를 저장할 변수
void setup(){
myservo.attach(9); // 핀 9의 서보를 서보 오브젝트에 연결한다.
}
void loop(){
for(angle =0; angle<180; angle+=1){ // 0도에서 180도로 이동한다.
myservo.write(angle); // 'angle' 변수의 위치로 서보를 이동시킨다.
delay(20); // 서보 명령 간에 20ms를 기다린다.
}
for(angle = 180; angle >= 1; angle-=1){ // 180도에서 0도로 이동한다.
myservo.write(angle); // 서보를 반대 방향으로 이동한다.
delay(20); // 서보 명령 간에 20ms를 기다린다.
}
}
myservo.attach(pin, min, max);
min: 서보의 최소 각도(0도)에 해당하는 펄스 폭이며, 기본값은 554이다.
max: 서보의 최대 각도(180도)에 해당하는 펄스 폭이며, 기본값은 2400이다.
2개 이하의 서보 제어하기(회전방향, 속도)
#include <Servo.h>
Servo myservo;
int potpin = 0; //포텐셔미터를 연결하는 데 사용되는 아날로그 핀
int val;
void setup(){
myservo.attach(9);
}
void loop(){
val = analogRead(potpin); // 포텐셔미터의 값을 읽는다.
val = map(val, 0, 1023, 0, 180);
myservo.write(val);
delay(15);
}
연속 회전 서보의 속도 제어하기
#include <Servo.h>
Servo myservo1;
Servo myservo2;
int angle=0;
void setup(){
myservo1.attach(9);
myservo2.attach(10);
}
void loop(){
for(angle=90;angle<180;angle+=1){
myservo1.write(angle);
myservo2.write(180-angle);
delay(20);
}
for(angle=180;angle>=90;angle-=1){
myservo1.write(angle);
myservo2.write(180-angle);
}
}
솔레노이드
int solenoidPin = 2;
void setup(){
pinMode(solenoidPin, OUTPUT);
}
void loop(){
long interval = 1000 * 60 * 60; // 1시간
digitalWrite(solenoidPin, HIGH);
delay(1000);
digitalWrite(solenoidPin, LOW);
delay(interval);
}
대부분의 솔레노이드는 아두이노 핀에서 제공해주는 것보다 많은 전원이 필요하므로 트랜지스터를 사용해서 솔레노이드를 활성화하는 데 필요한 전류를 공급한다.
센서 + 진동 모터
const int motorPin = 3;
const int sensorPin = 0;
int sensorAmbient = 0; // 초기 밝기
const in thresholdMargin = 100; // 진동 발생 조건에 해당하는 밝기 차이
void setup(){
pinMode(motorPin, OUTPUT);
sensorAmbient = analogRead(sensorPin);
}
void loop(){
int sensorValue = analogRead(sensorPin);
if( sensorValue > sensorAmbient + thresholdMargin){
digitalWrite(motorPin, HIGH);
}else{
digitalWrite(motorPin, LOW);
}
}
바이폴라 스텝퍼 모터 구동하기(아두이노 모터 실드가 필요하다)
#include <Stepper.h>
#define STEPS 24 //사용 중인 모터의 단계 수에 맞게 이 값을 변경한다.
Stepper stepper(STEPs, 2, 3, 4, 5);
// 스텝퍼 클래스의 인스턴스를 만들면서 모터의 단계 수와 모터를 연결할 핀을 지정한다.
int steps =0;
void setup(){
stepper.setSpeed(30); // 모터 속도를 30RPM으로 설정한다.
Serial.begin(9600);
}
void loop(){
if(Serial.available()){
char ch = Serial.read();
if(isDigit(ch)){
steps = steps * 10 + ch - '0';
}else if(ch =='+'){
stepper.step(steps);
steps = 0;
}else if(ch == '-'){
stepper.step(steps*-1);
steps = 0;
}
}
}
// 예를 들어 시리얼창에 3+, 7-로 입력한다.
바이폴라 스텝퍼 모터 구동하기
const int dirPin = 2;
const int stepPin = 3;
int speed = 100; //원하는 속도(초당 단계 수)
int steps = 0; // 단계 수
void setup(){
pinMode(dirPin, OUTPUT);
pinMode(stepPin, OUTPUT);
Serial.begin(9600);
}
void loop(){
if(Serial.available()){
char ch = Serial.read();
if(isDigit(ch)){ // ch가 숫자라면?
steps = steps * 10 + ch - '0'; // 값을 누적시킨다.
}else if(ch == '+'){
step(steps);
steps = 0;
}else if(ch == '-'){
step(-steps);
steps = 0;
}else if(ch == 's'){
speed = steps;
Serial.print("Setting speed to ");
Serial.println(steps);
steps = 0;
}
}
}
void step(int steps){
int stepDelay = 1000/speed;
int stepsLeft;
if(steps > 0){
digitalWrite(dirPin,HIGH);
stepsLeft = steps;
}
if(steps < 0){
digitalWrite(dirPin,LOW);
stepsLeft = -steps;
}
while(stepsLeft > 0){
digitalWrite(stepPin, HIGH);
delayMicroseconds(1);
digitalWrite(stepPin, LOW);
delay(stepDelay);
stepsLeft--;
}
}
min: 서보의 최소 각도(0도)에 해당하는 펄스 폭이며, 기본값은 554이다.
max: 서보의 최대 각도(180도)에 해당하는 펄스 폭이며, 기본값은 2400이다.
2개 이하의 서보 제어하기(회전방향, 속도)
#include <Servo.h>
Servo myservo;
int potpin = 0; //포텐셔미터를 연결하는 데 사용되는 아날로그 핀
int val;
void setup(){
myservo.attach(9);
}
void loop(){
val = analogRead(potpin); // 포텐셔미터의 값을 읽는다.
val = map(val, 0, 1023, 0, 180);
myservo.write(val);
delay(15);
}
연속 회전 서보의 속도 제어하기
#include <Servo.h>
Servo myservo1;
Servo myservo2;
int angle=0;
void setup(){
myservo1.attach(9);
myservo2.attach(10);
}
void loop(){
for(angle=90;angle<180;angle+=1){
myservo1.write(angle);
myservo2.write(180-angle);
delay(20);
}
for(angle=180;angle>=90;angle-=1){
myservo1.write(angle);
myservo2.write(180-angle);
}
}
컴퓨터 명령으로 서보 제어하기
#include<Servo.h>
#define SERVOS 4
int servoPins[SERVOS] = {7, 8, 9, 10}; // 핀 7부터 핀 10까지 서보를 연결한다.
Servo myservo[SERVOS];
void setup(){
Serial.begin(9600);
for(int i=0; i < SERVOS; i++)
myservo[i].attach(servoPins[i]);
}
void loop(){
serviceSerial();
}
// serviceSerial 함수는 시리얼 포트를 검사한 후 수신된 데이터를 사용하여 위치를 갱신한다.
// 이 함수에서는 다음 형식의 서보 데이터를 원한다.
//
// "180a"는 서보 a에 180을 기록한다.
// "90b"는 서보 b에 90을 기록한다.
//
void serviceSerial(){
static int pos = 0;
if(Serial.available()) {
char ch = Serial.read();
if(isDigit(ch)) // ch가 숫자라면:
pos = pos*10 + ch - '0'; // 값을 누적시킨다.
else if(ch >= 'a' && ch <= 'a'+SERVOS) // ch가 서보에 해당하는 문자라면:
myservo[ch - 'a'].write(pos); // 위치 배열에 위치를 저장한다.
}
}
솔레노이드
int solenoidPin = 2;
void setup(){
pinMode(solenoidPin, OUTPUT);
}
void loop(){
long interval = 1000 * 60 * 60; // 1시간
digitalWrite(solenoidPin, HIGH);
delay(1000);
digitalWrite(solenoidPin, LOW);
delay(interval);
}
대부분의 솔레노이드는 아두이노 핀에서 제공해주는 것보다 많은 전원이 필요하므로 트랜지스터를 사용해서 솔레노이드를 활성화하는 데 필요한 전류를 공급한다.
센서 + 진동 모터
const int motorPin = 3;
const int sensorPin = 0;
int sensorAmbient = 0; // 초기 밝기
const in thresholdMargin = 100; // 진동 발생 조건에 해당하는 밝기 차이
void setup(){
pinMode(motorPin, OUTPUT);
sensorAmbient = analogRead(sensorPin);
}
void loop(){
int sensorValue = analogRead(sensorPin);
if( sensorValue > sensorAmbient + thresholdMargin){
digitalWrite(motorPin, HIGH);
}else{
digitalWrite(motorPin, LOW);
}
}
바이폴라 스텝퍼 모터 구동하기(아두이노 모터 실드가 필요하다)
#include <Stepper.h>
#define STEPS 24 //사용 중인 모터의 단계 수에 맞게 이 값을 변경한다.
Stepper stepper(STEPs, 2, 3, 4, 5);
// 스텝퍼 클래스의 인스턴스를 만들면서 모터의 단계 수와 모터를 연결할 핀을 지정한다.
int steps =0;
void setup(){
stepper.setSpeed(30); // 모터 속도를 30RPM으로 설정한다.
Serial.begin(9600);
}
void loop(){
if(Serial.available()){
char ch = Serial.read();
if(isDigit(ch)){
steps = steps * 10 + ch - '0';
}else if(ch =='+'){
stepper.step(steps);
steps = 0;
}else if(ch == '-'){
stepper.step(steps*-1);
steps = 0;
}
}
}
// 예를 들어 시리얼창에 3+, 7-로 입력한다.
바이폴라 스텝퍼 모터 구동하기
const int dirPin = 2;
const int stepPin = 3;
int speed = 100; //원하는 속도(초당 단계 수)
int steps = 0; // 단계 수
void setup(){
pinMode(dirPin, OUTPUT);
pinMode(stepPin, OUTPUT);
Serial.begin(9600);
}
void loop(){
if(Serial.available()){
char ch = Serial.read();
if(isDigit(ch)){ // ch가 숫자라면?
steps = steps * 10 + ch - '0'; // 값을 누적시킨다.
}else if(ch == '+'){
step(steps);
steps = 0;
}else if(ch == '-'){
step(-steps);
steps = 0;
}else if(ch == 's'){
speed = steps;
Serial.print("Setting speed to ");
Serial.println(steps);
steps = 0;
}
}
}
void step(int steps){
int stepDelay = 1000/speed;
int stepsLeft;
if(steps > 0){
digitalWrite(dirPin,HIGH);
stepsLeft = steps;
}
if(steps < 0){
digitalWrite(dirPin,LOW);
stepsLeft = -steps;
}
while(stepsLeft > 0){
digitalWrite(stepPin, HIGH);
delayMicroseconds(1);
digitalWrite(stepPin, LOW);
delay(stepDelay);
stepsLeft--;
}
}
댓글 없음:
댓글 쓰기