BASIC4MCU | 질문게시판 | ATmega128 진동센서 코딩 질문입니다.
페이지 정보
작성자 444222a 작성일2022-05-20 17:27 조회653회 댓글5건본문
ATmega128과 SW18010P 진동센서를 이용하여 진동이 감지되면 LCD에 A=1을 표시하고 감지되지 않으면 A=0을 표시하는 코드를 작성하고 있습니다.
문제는 진동과 관계없이 LCD에 A=0과 A=1이 번갈아가면서 출력됩니다. 진동 센서를 뽑고 실행해도 동일한 증상이 나타납니다.
코드가 길어서 진동센서 입력과 LCD 출력에 직접 관련된 C파일만 올렸습니다. (lcd.c와 lcd.h는 정상 작동을 확인하였습니다)
코드에 문제가 있는 부분을 알려주시면 감사하겠습니다.
#include <stdio.h>
#include <avr/io.h>
#define F_CPU 8000000
#include <util/delay.h>
#include "lcd.h"
long a = 0;
int main(void)
{
DDRA=0b11111101; // PA1 진동센서 입력 설정
char lcd_string[2][MAX_LCD_STRING];
LCD_init();
while(1){
if((PINA&2)==0){ // 센서에 진동이 감지되면 0, 감지되지 않으면 1이므로 PA1 값이 0이면 a = 1 실행, 0이 아니면 a = 0 실행
a = 1;}
else{
a = 0;}
sprintf(lcd_string[0], "A=%-5ld", a);
LCD_str_write(0, 0, lcd_string[0]);
_delay_ms(500);
}
return 0;
}
댓글 5
조회수 653master님의 댓글
master 작성일
#include <stdio.h>
#include <avr/io.h>
#define F_CPU 8000000UL // <-- 큰 숫자는 뒤에 UL을 붙여줘서 데이터형을 구분해주는 것이 좋습니다.
#include <util/delay.h>
#include "lcd.h"
//
int main(void){
int a=0;
char lcd_string[2][MAX_LCD_STRING];
// DDRA=0b11111101; // PA1 진동센서 입력 설정
PORTA=2; // <----------- PA1 내부 풀업저항 사용
LCD_init();
while(1){
if((PINA&2)==0)a=1; // 진동이 감지되면 0 / 감지되지 않으면 1
else a=0;
sprintf(lcd_string[0],"A=%5d",a);
LCD_str_write(0,0,lcd_string[0]);
_delay_ms(500);
}
return 0;
}
여기서
// DDRA=0b11111101; // PA1 진동센서 입력 설정
리셋 디폴트 값이 입력이라서 따로 입력을 지정해줄 필요가 없으며
위 코드는 PA1을 제외한 나머지 7개의 핀을 출력으로 설정하고 있으므로 고장위험이 있습니다.
DDRA&=~2; // PA1 진동센서 입력 설정
이런식으로 비트 마스크 연산을 해야지 다른핀 영향없이 PA1만 입력으로 처리 됩니다.
PORTA=2; // <----------- PA1 내부 풀업저항 사용
지금 증상은 외부에 풀업저항을 사용하지 않아서 발생하는 문제인데
내부 풀업저항을 사용하면 됩니다.
444222a님의 댓글
444222a 작성일
답변해주셔서 감사합니다. 풀업저항을 사용하고 나니 A=0과 A=1이 저절로 바뀌는 문제가 해결되었습니다.
그런데 진동센서에 진동을 가해도 계속 A=0 으로만 표시되는데 혹시 이유를 알 수 있을까요?
진동센서에 달린 LED는 진동을 가할 때만 켜지는 걸 보면 진동센서는 문제가 없는 것 같습니다.
master님의 댓글
master
실행 시간을 체크 해보세요
while(1){
if((PINA&2)==0)a=1; else a=0; // 수us도 안걸리고
sprintf(lcd_string[0],"A=%5d",a); // 이 시간도 오래 걸리지는 않는데
LCD_str_write(0,0,lcd_string[0]); // 여긴 제법 걸립니다. 길어도 수ms 이내
_delay_ms(500); // 그래도 이 시간이 가장 길죠
}
이번에는 진동 센서를 살펴보죠
센서 원통 길이가 1.5cm라고 가정하고
원통안의 볼이 한쪽 끝에 닿았을 때 연결이 됩니다. a=1
나머지 시간은 떨어져있죠 a=0
시간으로 봐서도 떨어져 있는 시간이 더 깁니다.
master님의 댓글
master 작성일
#include <stdio.h>
#include <avr/io.h>
#define F_CPU 8000000UL // <-- 큰 숫자는 뒤에 UL을 붙여줘서 데이터형을 구분해주는 것이 좋습니다.
#include <util/delay.h>
#include "lcd.h"
//
int main(void){
int a=0,b=0; char str[30];
PORTA=2;
LCD_init();
while(1){
if((PINA&2)==0){
if(a==0){ a=1; b++; sprintf(str,"A=%5d",b); LCD_str_write(0,0,str); _delay_ms(50); }
else{
if(a==1){ a=0; _delay_ms(50); }
}
}
return 0;
}
PA1에 연결되어 있는 센서에 병렬로 0.1uF(100nF) 커패시터를 연결하면 채터링이 줄어듭니다.
진동센서를 흔들었을 때 몇번 흔들었는지 LCD에 표시하는 코드이니 체크해보세요
444222a님의 댓글
444222a 작성일
진동센서를 사용 시 고려해야할 것들이 생각보다 많은 것 같네요.
조금 더 코딩해보고 다시 질문 드리겠습니다.
알려주셔서 감사합니다.