본문 바로가기
aCodingTo

Arduino Uno - LM35 온도센서 이용하기 - 1

by redi 2018. 11. 21.
반응형

온도센서를 이용하기 위해서 코딩을 해 본다.
근데 한 방에 이상한 점을 발견.. 기초지식이 없는 탓일거야...

센서가 연결된 핀을 지정하는데 누구는 int를 쓰고 누구는 const int를 쓰길래 찾아보니 이런 내용이 있더라


이 아날로그 핀은 입력 전용이니까 나도 일단 const int를 쓰기로 하고
대강 만들어봤다. LM35dz 소자는 mV단위로 값이 나온다니 정수로 지정하면 되겠고  이건 틀렸네..
그 이유는 아래 설명을 보면 되겠다.
그리고 아래 코드 중에서 tempsensor=2는 잘못된 것.. 아날로그 입력이니까 A0정도를 썼어야 했다.
아날로그 단자는 입력 전용이니 pinMode로 지정할 필요는 없고!

별 생각없이 한 번만 돌아가는 부분에다 변수를 선언했더니 이렇게 에러 메시지를 보내준다. 변수는 미리 잡아줘야 하나보다. 근데 loop 안에서 변수를 선언해도 잘 되는데....??

LM35 data sheet 를 뒤져보니

이렇게 섭씨 1도 상승에 10.0mV 증가라는데... 근데 저 구성이 아두이노 보드에 연결하는 것과 같은 구성인데 2~150도를 측정할 수 있다고? 그럼 영하는 안된다는 말인데?
이건 좀 찾아봐야겠다.

센서에서 읽어낸 값에다 5*100을 곱한 다음 1024로 나누는데 이거 왜 이렇게 하는걸까..

일단 아두이노의 아날로그 단자는 입력 전용이고, 0부터 1023까지 1024단계를 입력할 수 있다고 하고
아두이노의 출력단자는 기본적으로 디지털인데 ~표시가 붙은 단자는 PWM방식으로 0~5V를 0~255로 나타내 준단다. 즉 입력값이 출력값보다 4배 더 정교하다는 말이 되겠네

이걸 좀 더 생각해보면 아날로그 입력단은 0V~5V의 입력값을 그대로 갖고 오는 것이 아니라 0~1023에 대응하는 값으로 변환해서 읽어들인다는 말이 되겠네. 그리고 입력된 아날로그 값을 바로 PMW단자로 출력하려면 그 값을 4로 나눠줘야 한다는 것일테고

그러니까 실제 10mV가 LM35의 출력단에 걸리게 되면 실제 아두이노가 아날로그 단자를 통해 읽어오는 값은 10mVx1024/5000mV가 된다는 말

그러니 실제 출력값이 10mV를 갖고오려면 다시 5000을 곱하고 1024를 나눠야 하는데... 왜 500만 곱하는걸까?
LM35가 섭씨 1도에 10mV 증가하니까 온도에 대응시키려면 다시 10으로 나눠야 하니까..
아예 처음부터 500만 곱하면 되겠네..
우씨 이걸 딱히 설명해 놓은 곳을 못찾아서 (빌려온 책도 그냥 공식!이라고 하고 넘어가버림) 이거 이해하느라 한참을 고민했다. 이런 과정은 아날로그 입력을 이용할 때마다 생각해야 할 문제일테고..


그리고 전원 공급에 대해서... 전압이 불안정하면 캐패시터를 하나 추가하라고 나와있더라.

여튼 LM35를 이용해서 온도를 측정하는 방법은 확인했으니까 이제 LCD에 출력하는 방법을 알아내야 하는데..

빌려온 책을 읽다가 다시 멘붕..
분명 아날로그 입력 단자는 입력 전용이라고 해놓고 이번에는 당당하게 LCD를 구동할 때 아날로그 입력단자를 이용한다고 나와있다.... 이거 뭐니??

원래 16x2 LCD를 구동하려면 16개의 핀을 써야 하는데 이랬다가는 아두이노 보드로는 아무 것도 못하게 되니까..
여기에 I2C LCD 모듈을 연결해서 전원 포함 4개 단자로 구동할 수 있단다. 대신 Wire.h, LiquidCrystal_I2C.h 라이브러리를 포함시켜야 한다고..

그리고 아날로그 입력 단자는 입력 전용이라고 생각하지 말고 주 용도는 입력이지만 특수한 상황에선 출력으로 쓰일 수도 있다... 정도로 정리하도록 하자

내가 쓸 16x2 LCD는 왼쪽 상단 모서리 좌표를 (0,0)이라고 잡고 아랫줄은 (0,1)이라고 생각하면 되겠다
그래서  첫번째 줄 첫 자리에 들어갈 문자는 

lcd.setCursor(0,0);

lcd.print("temp");

라고 입력하면 되고, 

temp: 25 라고 출력하려면

lcd.setCursor(0,0);

lcd.print("temp:");

lcd.setCursor(6,0);

lcd.print(temp);

라고 하면 되겠네!

"temp"와 temp는 다르다는 것


LCD 출력 참고 페이지


여기까지 잘 해놓고 이제 직접 온도센서를 연결해서 값을 불러와봤는데.... 망했다!!!

온도에 따라 LED 하나를 켜거나 끄게 하겠다고 작업을 시작했는데...
온도센서에서 읽어온 값이 이상하다...
하도 이상해서 시리얼 입력값과 계산한 온도를 같이 출력하게 해봤더니....

이 모양이다.. 

그래서 싸그리 지우고 아날로그 포트로 값을 읽어오는 것에만 집중해보자고 다시 코딩을 해서 읽었는데..

이러고 있다.. 아 이거 뭐냐 -__-;;
혹시 센서 연결을 잘못했나 싶어서 센서를 분리했는데도 비슷한 값을 읽어댄다 -_-;;;;;;
그 다음엔 계산식의 연산 순서가 영향을 미치나 싶어서 확인해봤는데...

이건 별 차이가 없는 모양이다

좌절하고... 그래도 온도 범위에 따라 LED가 켜지게나 해보자 싶어서 if문을 집어넣었는데..
처음엔 설정값 이하가 되어도 계속 켜져있더라..
그래서 찾아보니.. 200이 아니면 꺼지도록 해주지 않으면 계속 켜져 있을 수 밖에 없는 구조였다..
그래서 다시 else를 추가했다

이렇게 해서 이상하게 읽어낸 온도가 220도를 넘으면 LED가 켜지게 하는 데에는 성공.

근데 왜 온도가 저 모양일까????????????


일단 아날로그 입력값의 레퍼런스를 설정해봐야 할 것 같다. 

analogReference(INTERNAL); // use 1.1volt Aref

그래도 안되면 정말 GND 라인에 캐패시터를 하나 물려줘야하나??

728x90
반응형