웹에서 서보모터 제어하기
목차
개발환경#
웹 : MS Windows Server 2003. ASP.NET 2.0 Framework2.0
하드웨어 : IAR 4.0 Ponyprog2000
하드웨어 구성 : MCU Atmega128, Servo motor HS-311
웹 프로그램#
포함된 파일#
Default.aspx - 웹 첫 페이지
Default.aspx.vb - vb로 작성된 코드.
web.config
rs232.vb - 시리얼 통신 COM port 제어를 위한 클래스 파일
기본 인터페이스#
실행#
2 번의 텍스트 상자에 서보 모터의 제어 하고 싶은 각도를 넣고 좌우 방향 버튼을 누르게 되면 서보 모터가 움직이게 된다. 텍스트 상자에 적게 되는 각도는 상대적인 각도이다. -90에 서보모터가 위치 해 있을 때 45 값을 넣고 우측 버튼을 눌렀을 때 -45도에 위치하게 된다.
소스 코드 - Default.aspx.vb#
1 번 버튼을 클릭 했을 때 Left.Click 호출 실행. 2번 클릭 했을 때. Right.Click 호출 실행. 버튼을 한 번 누를 때 마다 COM Port를 열고 패킷을 보낸 다음 다시 Port를 닫는 방법을 택했다. 각도 값을 0보다 작거나 180보다 크면 90으로 전송 하도록 하였다.
- '// Servo-morot Control in the webpage
'// Progaming by duwon
'// 2007. 10. 19.
Partial Class _Default
Inherits System.Web.UI.Page- '//Private miAngle As Integer = 8
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Right.Click - If textbox_angle.Text > 180 Or textbox_angle.Text < 0 Then
textbox_angle.Text = 90
End If - Dim moRS232 As New Rs232()
With moRS232
.Port = 1 '// Uses COM1
.BaudRate = 9600 '// 9600 baud rate
.DataBit = 8 '// 8 data bits
.StopBit = Rs232.DataStopBit.StopBit_1 '// 1 Stop bit
.Parity = Rs232.DataParity.Parity_None '// No Parity
.Timeout = 500 '// 500 ms of timeout admitted to get all required bytes
End With
'// Initializes and Open
moRS232.Open()
'//You can, optionally control the state of DTR/RTS lines after the Port is open
'// Set state of RTS / DTS
moRS232.Dtr = True
moRS232.Rts = True - Dim aAngle() As Byte = {textbox_angle.Text}
moRS232.Write("r")
moRS232.Write(aAngle)
moRS232.Close()
End Sub - Protected Sub Button1_Click1(ByVal sender As Object, ByVal e As System.EventArgs) Handles Left.Click
If textbox_angle.Text > 180 Or textbox_angle.Text < 0 Then
textbox_angle.Text = 90
End If
Dim moRS232 As New Rs232()
With moRS232
.Port = 1 '// Uses COM1
.BaudRate = 9600 ' // 9600 baud rate
.DataBit = 8 '// 8 data bits
.StopBit = Rs232.DataStopBit.StopBit_1 '// 1 Stop bit
.Parity = Rs232.DataParity.Parity_None '// No Parity
.Timeout = 500 '// 500 ms of timeout admitted to get all required bytes
End With
'// Initializes and Open
moRS232.Open()
'//You can, optionally control the state of DTR/RTS lines after the Port is open
'// Set state of RTS / DTS
moRS232.Dtr = True
moRS232.Rts = True - Dim aAngle() As Byte = {textbox_angle.Text}
moRS232.Write("l")
moRS232.Write(aAngle)
moRS232.Close()
End Sub
End Class
패킷 구조#
패킷 손실 위험이 없으므로 헤더와 CRC 체크 비트는 추가 하지 않았고 방향과 각도 만으로 패킷을 구성.
|
방향(8비트) |
각도(8비트) |
방향 구분
r (ASCII 0x72) - 우측 방향
l (ASCII 0x6C) - 좌측 방향
각도 - ASCII값으로 0-180을 보냄.
아래 그림은 컴퓨터 COM port를 통해 패킷이 오가는 모습을 캡쳐한 것이다. 각도를 50으로 놓고 1번과 2번을 눌렀을 때 패킷이 COM port를 통해 나가는 것을 확인 할 수 있다.
웹 프로그램 다운로드 WebToServo_webprogram.zip#
하드웨어#
사진#
회로도#
동작방식#
시리얼 통신으로 컴퓨터에서 넘어온 데이터를 받아서 첫 번째 패킷으로 좌측인지 우측인지 구분한다. 첫 패킷이 좌측이나 우측 명령어 아니라면 그 패킷을 버린다. 다음 패킷으로 각도가 넘어 오는데 오른쪽이면 +, 왼쪽이면 - 값을 붙여 ConvertAngle 함수에 넘겨준다. ConvertAngle 함수는 컴퓨터에서 받은 각도 값을 지금 서보모터의 위치 각도도 값을 더해서 서보모터 제어 할 수 있는 값으로 변경하여 준다. 가운데가 0도 좌우측 -90, 90도로 정했고 컴퓨터에서 들어 오는 각도가 그 이상을 넘어가면 -90, 90 으로 예외처리하였다.
현재 모터의 각도가 30도에 있고 웹에서 60도 각도에 좌측 버튼을 눌렀을 경우 최종 서보모터의 각도는 -30도로 결정된다.
소스코드 - WebToServo.cpp#
- #include <iom128.h> // MCU 128 각종 레지스터 정의
#include <ina90.h> // 인터럽트 관련 구문 - #define LEFT_ANGLE -90
- #define RIGHT_ANGLE 90
- int flag = 0;
int Sv_angle = 42; // mim15 mid 42 max69 - int fromServerAngle = 0;
int holdedServoAngle = 0; - void ConvertAngle(int fromServerAngle) // 절대각도 -> 상대각도 변환 구문
{
holdedServoAngle = holdedServoAngle + fromServerAngle;
if( holdedServoAngle > RIGHT_ANGLE){ holdedServoAngle = RIGHT_ANGLE;} // 절대각도가 오른쪽 상한선 이상시 예외구문
if( holdedServoAngle < LEFT_ANGLE){ holdedServoAngle = LEFT_ANGLE;} // 절대각도가 왼쪽 상한선 이상시 예외구문
Sv_angle = (int)((((float)holdedServoAngle) / 1.63) + 92); // 사용자 입력 각도 -> 서보모터 제어값 ( 0~255) 변환
} - void Timer_Initialization()
{
TCCR0 = 0x06; //분주비 256로 설정
TCNT0 = 0x00; //
TIMSK = 0x01; //오버플로우 발생하면 인터럽트 발생
}
void UART_Initialization()
{
UCSR1A = 0x00; // 0000 0000
UCSR1B = 0x98; // 1001 1000 Receive enable, Transmitte enable
UCSR1C = 0x06; // 0000 0100 비동기 방식, Parity bit Disable , 1 stop bit
UBRR1H = 0x00; // 0000 0000
UBRR1L = 0x67; // 0100 0111 16MHz 에서 9600 bps (10진수 103)
}- char getch(void) // PC -> MCU 데이터 1byte 전송 UART1 사용
{
unsigned char data; - while(!(UCSR1A & 0x80));
data = UDR1; // MCU 버퍼에서 데이터 수신 - UCSR1A |= 0x80; // 클리어 RXC0
return(data);
} - void putch(unsigned char data) // MCU -> PC 데이터 1byte 전송 UART1 사용
{
while(!(UCSR1A & 0x20));
UDR1 = data; // MCU 버퍼에 데이터 입력
UCSR1A |= 0x20;
} - int main()
{
DDRF = 0xff; //포트 입출력 설정
DDRB = 0xff;
DDRD = 0xfb;
PORTF = 0x00; //포트 초기화
Timer_Initialization();
UART_Initialization();
__enable_interrupt(); // 인터럽트를 걸어주는 함수
while(1)
{
unsigned char text;
int fromServerAngle = 0;
text = getch(); // 1byte 수신 ( Right or Left 구분)
putch(text); // PC에서 모니터링 프로그램을 통해 에코데이터를 통해 전송여부 확인
if(text == 'l')
{
fromServerAngle = 0 - getch(); // 1byte 수신 ( Left의 경우 각도 수신)
ConvertAngle(fromServerAngle); // 각도 변환 함수 호출
}
if(text == 'r')
{
fromServerAngle = getch(); // 1byte 수신 ( Right 의 경우 각도 수신)
ConvertAngle(fromServerAngle); // 각도 변환 함수 호출
}
} - }
- #pragma vector = TIMER0_OVF_vect
__interrupt void TIMER0_OVF_interrupt(void) //오버플로우가 발생하면 인터럽트벡터로 들어옴 - {
if(flag ==1)
{
PORTB = 0xff;
TCNT0 = 0xff-Sv_angle;
flag = 0;
}
else
{
PORTB = 0x00;
TCNT0 = 0x00;
flag = 1;
}
}
하드웨어 소스코드 다운로드 - WebToServo_hardware.zip#
작동 동영상#
추가 하드웨어 제작
Clonix 아르바이트 할 때 만들었던 테스트 보드를 가지고 간단하게 하드웨어 제작을 했습니다.
다양한 테스트 기능이 들어 가 있는 보드이기 때문에 여러 핀들이 많이 있습니다만 사용된건 두개. UART1, PORTB
UART1번을 보면 원래 보는 VTRG 형태의 핀을 꼽게 되어 있는데 대부분 RTVG형태의 핀을 꼽기 때문에 변환하여 사용하였습니다.
소스코드는 위에서 제작했던 것과 같습니다.
작동동영상
History
Last edited on 01/03/2008 03:34 by duwon
Comments (0)