지금까지 여러번 C++로 객체 지향 프로그램 개발을 시도 하였으나 번번이 조금하다 말고는 포기하게 되었다. 워낙 C프로그램 개발이 익숙하다보니 C++의 새로운 개념을 받아 들이기가 쉽지 않았고, C로 안되는게 없는데 굳이 C++로 개발할 필요성을 못느끼게 되었기 때문이다. 그러다가 자바와 파이썬으로 객체 지향 프로그램을 할 기회가 있어서 몇개의 프로젝트를 진행하였고 자연히 객체 지향 프로그램의 특징과 장점을 알게되었다. 그래서 다시한번 C++ 프로그램에 도전하게 되었고, 그냥 목적없이 배우다보면 또다시 중간에 그만둘것 같아 임베디드 시스템 개발을 C++로 해보자는 확실한 목표를 세우고 진행해 보기로 하였다. 하드웨어 성능과 메모리 자원이 극히 제한적인 시절에는 어셈블리 언어 외에는 선택의 여지가 없었지만..
Tiny Clock을 만드는데 필요한 개별 기능들에 대한 구현과 확인 절차를 모두 끝냈으면, 마지막으로 개별 기능들을 모두 합쳐 하나의 프로젝트에서 원활하게 각자의 기능을 수행하도록 만들어야 한다.먼저, 시계처럼 보이도록 시간과 분을 표시해 주고 초단위 값을 표시하기 위한 함수를 만든다.void disp_clock(uint8_t h, uint8_t m, uint8_t s) { if (h < 10) send_data(0, 0); else send_data(0, digits[h/10]); if (s & 1) send_data(1, digits[h%10] | 0x80); else send_data(1, digits[h%10]); send_data(2, digits[m/10]); send_data(3, digi..
이번 글에서는 프로그램이 시작되는 시점의 현재 시간을 맞춰 주거나 시간 경과에 따라 시간 오차가 발생할 때, 이를 보정해주기 위하여 사용자가 푸쉬버튼을 눌러 주어 시간과 분에 해당되는 값을 조정하는 방법에 대해서 구현해 보도록 하겠다.시간 단위 조정을 위하여 푸쉬버튼 하나를 이용하고, 분단위 값을 조정하기 위하여 푸쉬버튼을 하나 더 이용하기로 한다.시간을 조정하기 위하여 사용자가 언제 푸쉬버튼을 누를지 알 수 없기 때문에, 버튼을 누르는 순간 즉각 이를 알아내기 위하여 external interrupt를 사용하여야 한다. AVR에는 두가지 종류의 external interrupt를 제공하는데, 하나는 위의 그림에서 초록색 박스로 표시된 INT# 라고 되어 있는 각 핀별로 인터럽트를 발생할 수 있는 방법과..
이번 글에서는 빛의 세기에 따라 저항값이 달라지는 Cds(Photo cell)을 이용하여 빛의 밝기를 측정하는 방법에 대해서 설명하도록 하겠다.회로 구성을 보면 ATtiny85의 7번 핀에 Cds가 연결되어 있는것을 볼 수 있다. Cds의 한쪽은 VCC에 연결되어 있고, 다른 쪽은 10K옴 저항을 통하여 GND에 연결되게 된다.Cds는 빛이 세기가 강해 질 수록 저항값이 감소하게 된다. 당연히 어두워지면 저항값이 증가한다. 빛이 밝아지면 Cds의 저항값이 감소하게 된다는 의미는 10K 저항에 걸리는 전압이 증가한다는 것이고, 이를 ATtiny85의 ADC로 측정하게 되면 큰 값이 읽히게 된다. 반대로 주위가 어두워지면 Cds의 저항값이 증가하고 10K 저항에 걸리는 전압은 상대적으로 낮아지게 된다. 결과..
이번 글에서는 디지털 시계 만들기 프로젝트의 핵심이라고 할 수 있는 타이머 설정에 대해서 설명하도록 하겠다.ATtiny85의 Timer/Counter0을 이용하여 일정한 시간 간격으로 타이머를 동작 시키도록 할 것이다.입문 과정에서 설명하였던 타이머/카운터 - PWM(CTC Mode)을 참고하여 원하는 시간에 인터럽트가 발생되도록 설정해준다. 하드웨어 타이머를 사용하면 CPU 동작과 무관하게 일정한 시간 간격으로 이벤트를 제공하므로 비교적 정확한 시계로 동작될 수 있게된다.enum timer_mode { NORMAL, PHASE, CTC, FAST }; enum timer_prescaler { DIV_NO, DIV_0, DIV_8, DIV_64, DIV_256, DIV_1024, EXT_FALLING, ..
이번 글에서는 TM1637을 제어하여 4자리 숫자를 표시해 보도록 하겠다. 이전 글에서 간단하게 언급하였지만 MCU와 TM1637간의 연결은 CLK, DIO 이렇게 2개의 시그널을 이용한다. 동작 원리는 I2C와 비슷하다는것도 앞에서 설명하였다.TM1637 datasheet에 설명되어 있는 방법중 "Write SRAM data in a fixed address mode"라는 동작을 이용하여 숫자를 표시하게 된다.CLK, DIO가 high 상태에서 DIO가 low가 되면 start 된다는 것을 의미한다. CLK 신호가 low에서 high 상태로 변경되는 시점의 DIO 값이 TM1637로 전달된다. 데이터가 나가는 순서는 LSB부터 나가도록 되어있는데 datasheet에는 이 부분이 정확히 설명되어 있지 않..
이번 프로젝트는 ATtiny85를 사용하여 아주 간단한 디지털 시계를 만들어 보는 것이다.ATtiny85는 위의 그림에서 보는것처럼 외부로 나오는 핀이 모두 8개인 아주 작은 MCU이다.ATtiny85의 핀 구성은 위의 그림과 같다. 이번 프로젝트에서는 VCC, GND, /RESET 핀을 제외한 5개의 핀 모두를 사용하도록 하겠다.이번에 만들어 보는것이 디지털 시계이므로 시간을 숫자로 표시해 주기위하여 7-세그먼트 디스플레이 모듈을 사용하겠지만, MCU의 I/O 핀을 직접 7세그먼트에 연결하는 것이 아니고 TM1637 칩이 들어있는 4핀짜리 디스플레이 모듈을 이용할 것이다. 위의 그림을 자세히 보면 TM1637칩이 실장되어 있고 CLK, DIO, GND, 5V 이렇게 4개의 핀이 연결될 수 있다는 것을 ..
앞의 글에서 설명한 대로 송신 기능을 구현하여 동작시켜 놓은 상태이므로, 송신기에서는 주기적으로 16비트 카운트 값을 내 보내주고 있다.이번에는 이 데이터를 수신하여 콘솔창에 출력함으로써 데이터 송신과 수신 과정이 정상적으로 수행되고 있음을 확인해 보도록 하겠다. static uint8_t tranceiver_addr[ADDR_WIDTH] = {0x12, 0x34, 0x56, 0x78, 0x90}; void nrf24_init(void) { ce_low(); cs_high(); _delay_ms(10); nrf24_close_pipe(NRF_ALL); nrf24_open_pipe(NRF_PIPE0); nrf24_crc_mode(NRF_CRC_16BIT); nrf24_auto_retr(15, 500); n..
nRF24L01을 이용한 무선 통신nRF24L01 register 읽어보기 nRF24L01의 내부 레지스터들을 정상적으로 읽어 오는 것을 확인하였으면 다음 과정으로 송신 기능을 구현해 보도록 하겠다.static uint8_t tranceiver_addr[ADDR_WIDTH] = {0x12, 0x34, 0x56, 0x78, 0x90}; void nrf24_init(void) { ce_low(); cs_high(); _delay_ms(10); nrf24_close_pipe(NRF_ALL); nrf24_open_pipe(NRF_PIPE0); nrf24_crc_mode(NRF_CRC_16BIT); nrf24_auto_retr(15, 500); nrf24_addr_width(NRF_AW_5BYTES); nrf24..
지금까지는 OLED 디스플레이 모듈과의 통신을 위하여 SPI버스를 이용하였지만, 이번에는 I2C 버스를 이용하여 원하는 데이터를 출력하는 방법에 대해서 설명하도록 하겠다.SPI 버스 방식은 모두 7개의 연결이 필요하였지만, I2C버스의 경우 전원 포함 4개의 연결만 필요하므로 훨씬 단순한 연결방식이라고 할 수 있겠다.SSD1306 datasheet 문서에서 I2C 버스의 경우에 어떻게 데이터를 보내야하는지는 위의 그림과 같이 설명되어 있다.I2C의 경우 device address가 필요한데 SSD1306의 경우에는 0x3C의 값을 가진다. 필요한 경우 칩의 D/C# 핀을 1로 연결하면 device address가 0x3D로 변경할 수 있다. 이번 프로젝트에서 사용하는 모듈은 0x3C의 주소를 가지고 있다..