티스토리 뷰

프로젝트/LCD1602

LCD1602 - ADC 출력

Just4Fun 2016. 7. 16. 09:14

이번에는 LCD1602를 실제 어떻게 활용할 수 있는지 간단한 프로젝트를 만들어 알아보기로 하겠다.

먼저 다음과 같은 회로를 구성한다.

LCD1602를 4비트 모드로 AVR과 연결시키고, AVR의 ADC0핀에 10K옴 가변 저항기를 연결하였다.  ADC 값을 읽어 오는 방법은 입문 과정중 ADC(Analog to Digital Converter)에서 다루어 보았으므로 참고하면 된다.

ADC 블럭을 통해서 읽어온 값을 LCD에 출력하는 코드를 만들어, ADC와 LCD가 정상적으로 동작되는지 확인해 본다.

이번 프로젝트에서는 LCD를 통하여 출력하고자 하는 글자들을 일단 lcd_buf라는 배열에 모두 저장한 후, 이 buf에서 한글자씩 순차적으로 LCD로 내 보내는 방법을 사용하게 만들었다.

clear_buf() 함수는 lcd_buf를 모두 space character(' ')로 채우는 기능을 수행한다.  이 때 주의할 점은 0으로 초기화하는 것이 아니라 ' '로 초기화 해야 하는것이다.  만일 0으로 초기화 하게 되면 LCD화면에는 CGRAM의 0번에 저장된 글자가 출력되기 때문이다.

convert_data() 함수는 ADC에서 읽어온 16비트 값을 lcd_buf의 특정 위치에 차례로 숫자형 문자로 저장하는 기능을 수행한다.  sprintf를 사용하지 않는 이유는 sprintf의 경우 문자열 마지막에 항상 '\0'이 들어가기 때문이다.  위에서 설명한대로 lcd_buf에 0의 값이 들어가면 CGRAM의 0번 글자가 출력되기 때문에 sprintf를 사용하지 않고 직접 lcd_buf에 숫자를 집어 넣는 코드를 만들어 주는 것이다.

setup() 함수는 lcd_buf를 초기화 하고, "ADC :"라는 문자열을 lcd_buf에 미리 입력 시켜놓는 과정을 수행하도록 한다.  "ADC :"문자열을 lcd_buf에 복사할 때에서 strcpy()를 사용하지 않고 memcpy()를 사용하는것에 유의하여야 한다. strcpy()를 사용하게 되면 문자열 마지막에 0이 들어가게 된다.

ADC 블럭과 LCD를 초기화 하는 과정이 뒤따른다.

loop() 함수는 ADC에서 현재 값을 읽어와서 lcd_buf의 특정 위치에 그 값을 집어 넣게 한 후, 일일이 한 글자씩 LCD 모듈로 내 보내는 과정을 수행한다.

코드를 완성한 후 빌드하여 LCD화면에 ADC값이 제대로 출력되는지 확인한다.

lcd1602_adc_simple.zip


정상적으로 ADC값이 출력되는 것을 확인 하였으면 다음 단계로 넘어가 보도록 하겠다.

ADC는 아날로그값을 디지털값으로 변환하는 것이므로 사람이 보기에는 숫자로만 표시되면 한눈에 현재 상태가 어느정도인지 인식하기가 쉽지않다.  따라서 ADC값을 그래프로 표현하게 되면 현재값이 어느정도의 수준인지 좀더 인식하기가 쉬울것이다.

따라서 이번에는 ADC에서 읽어 온 값을 막대 그래프로 표시하는 방법에 대해서 알아보도록 하겠다.

우선 코드에서 사용하는 상수 값들을 헤더 파일에 정의하는것으로 시작하겠다.

다음으로는 막대 그래프를 그리기 위하여 세로로 한줄씩 표시되는 글자를 CGRAM에 등록한다.

create_bar_pattern()은 세로로 한 줄씩 증가하는 다섯개의 글자 패턴을 CGRAM에 등록하는 코드이다.

위의 그림과 같은 다섯 글자가 등록된다.  LCD에 표시하기 위해서는 DDRAM 주소의 0,1,2,3,4번지를 지정해 주면 각각의 글자가 표시된다.

위에 보이는 update_bar_graph() 함수는 입력으로 들어온 ADC값을 막대 그래프로 표시하기 위하여 lcd_buf를 업데이트 하는 코드이다.

3번째 줄은 ADC 값을 표현하기 위해서 몇개의 수직선이 필요한 지 계산하는 것이다.

LCD1602의 한 줄에 표시할 수 있는 글자는 16자이고, 한 글자는 가로로 5개의 점으로 되어 있다.  그러므로 모두 80개의 세로선을 표시 할 수 있다는 얘기가 된다.  ADC는 10비트 값으로 표현 가능하므로 모두 1024개의 값을 표시할 수 있다. 따라서 하나의 세로선은 1024 / 80 = 12.8 단위가 된다.  소수점 값을 표현할 수 없으므로 분자, 분모에 10을 곱하여 계산하면 ADC 값을 표시하기 위하여 몇개의 세로선이 필요한 지 알수있게 된다.

4번줄의 코드는 하나의 글자로 출력할 수 있는 최대 세로선이 5개이므로 출력해야 하는 전체 세로선에서 5를 나눈값을 얻게 된다.

7~8번 라인의 코드는 LCD의 두번째줄만 clear하는 코드이다.

10~11번 라인의 코드는 5개 세로선 모두 출력되는 글자를 lcd_buf에 차례로 넣어주는 기능을 한다.

12번 라인은 다섯개의 선으로 표현될 수 있는 양을 제외한 나머지 세로선이 몇개인지 계산하여 해당하는 글자로 출력될 수 있도록 하는 것이다.

이제 코드를 완성하여 실행 시키면 다음과 같은 결과를 볼 수 있다.

lcd1602_adc_bargraph.zip


여기까지 구현한 것만으로도 충분히 쓸만하다고 할 수 있겠지만 한가지 기능을 추가해 보도록 하겠다.

바 그래프로 어느정도의 크기인지는 한눈에 알아볼 수 있겠지만 정확하게 몇 %정도의 값인지 알려주면 더 좋을것 같은 생각이 든다.

그래서 이번 프로젝트의 마지막 기능으로 바 그래프 중앙에 몇 %인지 알려주는 기능을 구현해 보도록 하겠다.

바 그래프 중앙에 표시될 숫자의 패턴을 만들어 둔다.

calc_percent()는 ADC 값이 몇 %인지 계산하여 그 결과를 바그래프 중앙부분에 들어가도록 만들어 준다.

3번 라인의 코드가 실제적인 %값을 구하는 코드이다.  일반적으로 %를 구하기 위해서는 분자에 100을 곱해 주는것이 일반적이지만 ADC에서 읽어 오는 최대값이 1023이므로 여기에 100을 곱하면 102300이 된다.  이 값은 16비트 변수가 담을수 있는 범위를 벗어나기 때문에 오류가 발생하게 된다.  이런 이유로 분자값에 50을 곱하고, 분모에는 1024의 절반인 512를 사용하도록 하였다.

7번 라인에서 구한 %값을 100으로 나눈값이 참인지 거짓인지 비교하는 코드이다.  %의 최대값은 100이므로 100%인지 그 보다 작은값인지를 비교하는 것이다.  만약 if문이 참이라면 무조건 LCD에 출력되는 %값은 100이 될 수밖에 없다.  그리고 100이 출력되는 위치의 바 그래프는 무조건 다섯개의 세로줄이 모두 출력될 수 밖에 없다.

10번 라인은 바 그래프에 출력될 숫자 '1'에 해당되는 패턴과 다섯줄모두 출력되는 바 그래프를 exclusive-OR 하여 그 결과를 CGRAM 5번 주소에 넣어준다.  이렇게 하면 바그래프에 숫자 1의 역상이 출력된다.

13번 라인은 숫자 '0'을 역상으로 출력하는 패턴을 만드는 코드이다.  이렇게 생성된 패턴을 CGRAM 6번 주소에 넣는다.

15~17번 라인은 역상으로 생성된 '1','0','0' 패턴을 바 그래프 중앙에 넣어주는 역할을 수행한다.

19번 라인의 else 문으로 들어간다는 것은 무조건 100보다 작은 값을 처리하는 코드가 들어 간다는 것을 의미한다.  즉 두자리 수만 표시하면 된다는 뜻이다.

21, 22는 십의 자리수와 1의 자리수에 표시될 숫자를 분리해 내는 코드이다.

24번 라인은 십의 자리수가 들어갈 위치까지 바 그래프가 도달했는지 체크해 보는 코드이다.  그 값이 ' '이라는 뜻은 십의 자리수를 굳이 역상으로 만들 필요 없이 정상적인 숫자를 표시해 주면 된다.  만일 십의 자리수가 들어갈 위치에 이미 바 그래프를 출력하기 위한 패턴이 쓰여져 있다면 십의 자리수에 들어갈 숫자 패턴과 바 그래프의 패턴을 exclusive-OR 시켜 주는 것이다.  이렇게 하면 바 그래프 패턴과 중첩되지 않는 영역은 정상적으로 숫자가 출력이 되고, 만일 바 그래프 패턴과 숫자 패턴이 중첩되는 영역이 있으면 그 부분의 숫자는 역상으로 표시된다.

만들어진 패턴을 CGRAM 5번 주소에 넣어준다.

35~44번 라인은 앞의 방법과 동일하게 일의 자리수에 대한 패턴을 계산하여 CGRAM 6번 주소에 넣어주는 코드이다.

46번 라인은 100의 자리수에 들어갈 내용을 이미 lcd_buf에 들어있는 값을 그대로 사용하겠다는 의미이다.  어차피 100의 자리수는 필요없기 때문이다.

47번 라인은 십의 자리수가 0이 아닌 값을 가질때는 CGRAM 5번 주소의 패턴을 사용하고, 만약 그 값이 0일 경우에는 lcd_buf[]에 있는 값을 사용하겠다는 의미이다.

48번 라인은 마지막 일의 자리 숫자를 CGRAM 6번 주소에 있는 패턴을 사용하겠다는 것을 의미한다.

최종적으로 ADC값을 읽어 화면에 출력하는 코드를 만든다.

바 그래프 패턴을 먼저 구한 후 %데이터 처리를 하여야 하는 점에 유의 하여야 한다.

최종 결과화면은 위의 영상과 같다.  바 그래프 안에 표시되어지는 숫자는 5x8의 크기로 표현하기에는 다소 어색하지만, 원하는 대로 출력되는 것을 확인할 수 있다.


lcd1602_adc_complete.zip




'프로젝트 > LCD1602' 카테고리의 다른 글

LCD1602 - Spectrum Analyzer  (0) 2016.07.17
LCD1602 - VU meter  (0) 2016.07.17
LCD1602 드라이버 코드 - CGRAM  (1) 2016.07.15
LCD1602 드라이버 코드 - 4비트 모드(2)  (0) 2016.07.14
LCD1602 드라이버 코드 - 4비트 모드  (4) 2016.07.14
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함