https://m.blog.naver.com/dev4unet/221209677083
버섯돌이의 정보 공유 Arduino Robot Car with Speed Sensors - Using Arduino Interrupts - 해외 영상
|
아두이노의 인터럽트를 이용한 스피드 센서 사용법에 대한 꽤 상세한 해외 강좌입니다.
ㅎㅎㅎ.. 비슷한 강좌도 쓰려고 관련 부품들을 구매한 지도 어느덧 몇 년이 훨씬 지나갔네요^^;;
본업을 손 놓고 이쪽을 자주 접할 때에는 그러려니 했었지만...
그동안 손 놓았던 본업의 기초를 다시 쌓느라고 비수면으로 너무 바쁘게 보냈더니
이제는 이쪽 분야는 Hello World도 기억이 안 나는 관계로 시간 될 때 기초부터 정독해야겠네요^^
Arduino Robot Car with Speed Sensors - Using Arduino Interrupts
1만 원 이하로 구매 가능한 차량 KIT를 이용합니다.
부품 구성을 보면 모터에 연결하는 인코더(검은색 동그라미)가 있지만 전자 부품은 포함되어 있지 않은 제품입니다.
그래서 인코더를 이용하시려면 H206 같은 광 인터럽트 센서나 기타 다른 센서 부품이 필요합니다.
하지만 H206 만으로는 오차가 있어서 보정을 위한 Comparator를 함께 사용해야 합니다.
비교기는 두 개의 입력과 1개의 출력을 갖는 장치로서
하나의 입력은 기준 전압이고 다른 하나의 입력은 포토트랜지스터의 출력을 연결합니다.
열쇠는 기준 전압으로서 포토 트랜지스터의 입력이 기준 전압보다 낮 으면 비교기의 디지털 출력은 로우로 유지되고
입력이 기준 전압과 동일하거나 초과하면 출력은 높아지게 됩니다.
센서는 이런 형태로 장착하면 됩니다.
아두이노와 L298N 모터 드라이버를 비롯하여 스피드 센서를 연결합니다.
아두이노 모델에 따라 디지털 인터럽트 핀 번호가 다릅니다.
간단한 센서 테스트를 위한 결선도입니다.
실제로는 이런 형태가 되겠지요?
테스트 코드이며 시리얼 모니터에 RPM이 출력됩니다.
/*
Optical Sensor Two Motor Demonstration
DualMotorSpeedDemo.ino
Demonstrates use of Hardware Interrupts
to measure speed from two motors
DroneBot Workshop 2017
*/
// Include the TimerOne Library from Paul Stoffregen
#include "TimerOne.h"
// Constants for Interrupt Pins
// Change values if not using Arduino Uno
const byte MOTOR1 = 2; // Motor 1 Interrupt Pin - INT 0
const byte MOTOR2 = 3; // Motor 2 Interrupt Pin - INT 1
// Integers for pulse counters
unsigned int counter1 = 0;
unsigned int counter2 = 0;
// Float for number of slots in encoder disk
float diskslots = 20; // Change to match value of encoder disk
// Interrupt Service Routines
// Motor 1 pulse count ISR
void ISR_count1()
{
counter1++; // increment Motor 1 counter value
}
// Motor 2 pulse count ISR
void ISR_count2()
{
counter2++; // increment Motor 2 counter value
}
// TimerOne ISR
void ISR_timerone()
{
Timer1.detachInterrupt(); // Stop the timer
Serial.print("Motor Speed 1: ");
float rotation1 = (counter1 / diskslots) * 60.00; // calculate RPM for Motor 1
Serial.print(rotation1);
Serial.print(" RPM - ");
counter1 = 0; // reset counter to zero
Serial.print("Motor Speed 2: ");
float rotation2 = (counter2 / diskslots) * 60.00; // calculate RPM for Motor 2
Serial.print(rotation2);
Serial.println(" RPM");
counter2 = 0; // reset counter to zero
Timer1.attachInterrupt( ISR_timerone ); // Enable the timer
}
void setup()
{
Serial.begin(9600);
Timer1.initialize(1000000); // set timer for 1sec
attachInterrupt(digitalPinToInterrupt (MOTOR1), ISR_count1, RISING); // Increase counter 1 when speed sensor pin goes High
attachInterrupt(digitalPinToInterrupt (MOTOR2), ISR_count2, RISING); // Increase counter 2 when speed sensor pin goes High
Timer1.attachInterrupt( ISR_timerone ); // Enable the timer
}
void loop()
{
// Nothing in the loop!
// You can place code here
}
|
최종 차량의 소스입니다.
/* Robot Car with Speed Sensor Demonstration
RobotCarSpeedSensorDemo.ino
Demonstrates use of Hardware Interrupts
to control motors on Robot Car
DroneBot Workshop 2017
*/
// Constants for Interrupt Pins
// Change values if not using Arduino Uno
const byte MOTOR_A = 3; // Motor 2 Interrupt Pin - INT 1 - Right Motor
const byte MOTOR_B = 2; // Motor 1 Interrupt Pin - INT 0 - Left Motor
// Constant for steps in disk
const float stepcount = 20.00; // 20 Slots in disk, change if different
// Constant for wheel diameter
const float wheeldiameter = 66.10; // Wheel diameter in millimeters, change if different
// Integers for pulse counters
volatile int counter_A = 0;
volatile int counter_B = 0;
// Motor A
int enA = 10;
int in1 = 9;
int in2 = 8;
// Motor B
int enB = 5;
int in3 = 7;
int in4 = 6;
// Interrupt Service Routines
// Motor A pulse count ISR
void ISR_countA()
{
counter_A++; // increment Motor A counter value
}
// Motor B pulse count ISR
void ISR_countB()
{
counter_B++; // increment Motor B counter value
}
// Function to convert from centimeters to steps
int CMtoSteps(float cm) {
int result; // Final calculation result
float circumference = (wheeldiameter * 3.14) / 10; // Calculate wheel circumference in cm
float cm_step = circumference / stepcount; // CM per Step
float f_result = cm / cm_step; // Calculate result as a float
result = (int) f_result; // Convert to an integer (note this is NOT rounded)
return result; // End and return result
}
// Function to Move Forward
void MoveForward(int steps, int mspeed)
{
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
// Set Motor A forward
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// Set Motor B forward
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// Go forward until step value is reached
while (steps > counter_A && steps > counter_B) {
if (steps > counter_A) {
analogWrite(enA, mspeed);
} else {
analogWrite(enA, 0);
}
if (steps > counter_B) {
analogWrite(enB, mspeed);
} else {
analogWrite(enB, 0);
}
}
// Stop when done
analogWrite(enA, 0);
analogWrite(enB, 0);
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
}
// Function to Move in Reverse
void MoveReverse(int steps, int mspeed)
{
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
// Set Motor A reverse
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
// Set Motor B reverse
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
// Go in reverse until step value is reached
while (steps > counter_A && steps > counter_B) {
if (steps > counter_A) {
analogWrite(enA, mspeed);
} else {
analogWrite(enA, 0);
}
if (steps > counter_B) {
analogWrite(enB, mspeed);
} else {
analogWrite(enB, 0);
}
}
// Stop when done
analogWrite(enA, 0);
analogWrite(enB, 0);
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
}
// Function to Spin Right
void SpinRight(int steps, int mspeed)
{
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
// Set Motor A reverse
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
// Set Motor B forward
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// Go until step value is reached
while (steps > counter_A && steps > counter_B) {
if (steps > counter_A) {
analogWrite(enA, mspeed);
} else {
analogWrite(enA, 0);
}
if (steps > counter_B) {
analogWrite(enB, mspeed);
} else {
analogWrite(enB, 0);
}
}
// Stop when done
analogWrite(enA, 0);
analogWrite(enB, 0);
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
}
// Function to Spin Left
void SpinLeft(int steps, int mspeed)
{
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
// Set Motor A forward
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// Set Motor B reverse
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
// Go until step value is reached
while (steps > counter_A && steps > counter_B) {
if (steps > counter_A) {
analogWrite(enA, mspeed);
} else {
analogWrite(enA, 0);
}
if (steps > counter_B) {
analogWrite(enB, mspeed);
} else {
analogWrite(enB, 0);
}
}
// Stop when done
analogWrite(enA, 0);
analogWrite(enB, 0);
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
}
void setup()
{
// Attach the Interrupts to their ISR's
attachInterrupt(digitalPinToInterrupt (MOTOR_A), ISR_countA, RISING); // Increase counter A when speed sensor pin goes High
attachInterrupt(digitalPinToInterrupt (MOTOR_B), ISR_countB, RISING); // Increase counter B when speed sensor pin goes High
// Test Motor Movement - Experiment with your own sequences here
MoveForward(CMtoSteps(50), 255); // Forward half a metre at 255 speed
delay(1000); // Wait one second
MoveReverse(10, 255); // Reverse 10 steps at 255 speed
delay(1000); // Wait one second
MoveForward(10, 150); // Forward 10 steps at 150 speed
delay(1000); // Wait one second
MoveReverse(CMtoSteps(25.4), 200); // Reverse 25.4 cm at 200 speed
delay(1000); // Wait one second
SpinRight(20, 255); // Spin right 20 steps at 255 speed
delay(1000); // Wait one second
SpinLeft(60, 175); // Spin left 60 steps at 175 speed
delay(1000); // Wait one second
MoveForward(1, 255); // Forward 1 step at 255 speed
}
void loop()
{
// Put whatever you want here!
}
|
보다 자세한 내용은 원본 영상을 참고하시기 바랍니다.
출처 : https://youtu.be/oQQpAACa3ac
아래 블로그에 조립을 비롯하여 아두이노 코드 등 설명이 꽤 자세히 나와 있으니 가급적 참고하시기 바랍니다.
Build a Robot Car with Speed Sensors
https://dronebotworkshop.com/robot-car-with-speed-sensors/
참고 자료..
얼핏 봤을 때 대부분은 예전에 포스팅했었던 부품과 강좌들 같으니 별도로 찾지는 않겠습니다.
예전에 포스팅했었던 2륜이나 4륜 차량 KIT 정보와 센서 정보 및 부품 구매 글들을 참고하시면 도움이 되리라 봅니다.
'프로세싱+아두이노+안드로이드' 카테고리의 다른 글
아두이노 인터럽트의 이해 (interrupt) (0) | 2022.05.14 |
---|---|
무언가 반복해서 지나가는 속도를 측정할때는 IR(적외선) 기반 Tachometer를 사용하세요 (0) | 2022.05.13 |
Arduino 포토 인터럽터 사용하기 (0) | 2022.05.13 |
Adding External I2C EEPROM to Arduino (24LC256) (0) | 2022.05.13 |
How to Control a 4-digit 7-segment LED Display with a Max7219 Chip (0) | 2022.05.12 |
댓글