Hi,
Như tất cả chúng ta đều biết bàn phím touch không có sự chuyển động, tiếp xúc cơ khí nên có thể nói là siêu bền so với bàn phím cổ điển, mặt khác phím cảm biến điện dung có thể hoạt động cách xa điểm chạm khá lớn nên rất thuận tiện để bố trí và thiết kế mặt nạ bàn phím rất thuận tiện và đẹp mắt hơn. Nhược điểm là nó tốn kém chân VĐK hơn vì nó không làm kiểu ma trận được và mặt nạ bàn phím không thể bằng kim loại. Tuy vậy dùng cách lập trình khéo léo chúng ta có thể bắt được các sự kiện touch, slide, wheel. Đối với bàn phím touch kiểu cảm biến điện cảm thì nó cho phép mặt nạ phím là kim loại và có thể cảm nhận được touch mạnh hay yếu.
Hôm nay tranh thủ chút thời gian tui chia sẽ cho các bác một phương pháp làm bàn phím touch kiểu cảm biến điện dung sử dụng VĐK PIC. Để thực hiện cảm biến điện dung thì có 3 phương pháp: Đo tần số, đo giá trị tụ điện và đo điện áp trên tụ. Hai phương pháp đầu tiên thì có sử dụng bộ so sánh của VĐK để tạo thành mạch dao động để đo tần số và tụ điện để xác định được vị trí nào được touch. Trong phạm vi bài viết này, tui sẽ trình bày phương pháp thứ 3 đó là đo điện áp trên tụ điện sử dụng bộ ADC của PIC. Sở dĩ tui chọn phương pháp này là vì nó có thể áp dụng với hầu hết VĐK PIC, chỉ cần có ADC là có thể thực hiện được mặt khác nó có thể làm được bàn phím với nhiều phím (số phím bằng với số kênh ADC). Nếu dùng bộ so sánh để tạo dao động thì việc mở rộng số phím bấm rất phức tạp và khó thành công. Vì vậy tui chọn phương pháp dùng ADC để làm bàn phím cảm biến điện dung và muốn chia sẽ với các bác. Phương pháp này thì chẳng mới mẽ gì vì tui cũng học nó từ website của microchip nhưng tui search trên diễn đàn chưa thấy ai có bài hướng dẫn.
Nguyên tắc của phương pháp này là sử dụng bộ ADC của VĐK PIC để đo điện áp trên tụ C_hold (bất kỳ bộ ADC nào cũng phải có tụ này) đây là tụ điện để lấy mẫu điện áp để chuyển đổi AD. Chính vì nguyên tắc này mà cần tối thiểu 2 channel ADC mới thực hiện được cho dù là bác chỉ cần 1 phím touch mà thôi. Các bước thực hiện như sau:
- Nạp điện cho tụ C_hold bằng cách nối chân chưa dùng lên VCC, chân này phải là chân Analog của PIC. Chuyển kênh ADC nối với chân này để tụ C_hold nạp điện đến VCC
- Kéo chân cần quét xuống GND
- Chuyển chân cần quét thành ngõ vào
- Chuyển kênh ADC về chân cần quét, lúc này tụ điện C_hold sẽ nối song song với tụ điện C_touch được cấu thành bởi tấm pad và GND, giá trị của tụ điện C_touch này phụ thuộc vào nó có được chạm hay không chạm. Nếu chạm tay vào pad thì giá trị tụ điện sẽ lớn hơn không chạm.
- Bắt đầu thực hiện chuyển đổi ADC, lúc này kết quả chuyển đổi chính là điện áp trên cặp tụ C_hold và C_touch. Dựa vào độ chênh lệch của giá trị này ta xác định được phím có được touch hay không.
Rất đơn giản đúng không?
Nếu sự trình bày của tui khiến các bác khó hiểu các bác có thể tham khảo tài liệu: AN1298 từ Michrochip.
Tiếp theo là một chương trình mẫu:
File common.h
Chương trình này rất phổ biến trong các thiết bị điện tử, bình thường chương trình sẽ cho VĐK ngủ để tiết kiệm năng lượng. Khi tay người đưa gần đến thiết bị để chuẩn bị tương tác thì VĐK sẽ được đánh thức, cái này gọi là cảm biến tiệm cận (proximility sensor). Người dùng sẽ thực hiện các thao tác trên bàn phím bình thường, trong vòng 4 giây nếu người dùng không tương tác trên bàn phím thì VĐK sẽ tiếp tục đi ngủ. Hi vọng các bác có thể áp dụng được vào các sản phẩm của mình để tạo thêm độ bền và tính thẩm mỹ của nó.
Thân ái.
Như tất cả chúng ta đều biết bàn phím touch không có sự chuyển động, tiếp xúc cơ khí nên có thể nói là siêu bền so với bàn phím cổ điển, mặt khác phím cảm biến điện dung có thể hoạt động cách xa điểm chạm khá lớn nên rất thuận tiện để bố trí và thiết kế mặt nạ bàn phím rất thuận tiện và đẹp mắt hơn. Nhược điểm là nó tốn kém chân VĐK hơn vì nó không làm kiểu ma trận được và mặt nạ bàn phím không thể bằng kim loại. Tuy vậy dùng cách lập trình khéo léo chúng ta có thể bắt được các sự kiện touch, slide, wheel. Đối với bàn phím touch kiểu cảm biến điện cảm thì nó cho phép mặt nạ phím là kim loại và có thể cảm nhận được touch mạnh hay yếu.
Hôm nay tranh thủ chút thời gian tui chia sẽ cho các bác một phương pháp làm bàn phím touch kiểu cảm biến điện dung sử dụng VĐK PIC. Để thực hiện cảm biến điện dung thì có 3 phương pháp: Đo tần số, đo giá trị tụ điện và đo điện áp trên tụ. Hai phương pháp đầu tiên thì có sử dụng bộ so sánh của VĐK để tạo thành mạch dao động để đo tần số và tụ điện để xác định được vị trí nào được touch. Trong phạm vi bài viết này, tui sẽ trình bày phương pháp thứ 3 đó là đo điện áp trên tụ điện sử dụng bộ ADC của PIC. Sở dĩ tui chọn phương pháp này là vì nó có thể áp dụng với hầu hết VĐK PIC, chỉ cần có ADC là có thể thực hiện được mặt khác nó có thể làm được bàn phím với nhiều phím (số phím bằng với số kênh ADC). Nếu dùng bộ so sánh để tạo dao động thì việc mở rộng số phím bấm rất phức tạp và khó thành công. Vì vậy tui chọn phương pháp dùng ADC để làm bàn phím cảm biến điện dung và muốn chia sẽ với các bác. Phương pháp này thì chẳng mới mẽ gì vì tui cũng học nó từ website của microchip nhưng tui search trên diễn đàn chưa thấy ai có bài hướng dẫn.
Nguyên tắc của phương pháp này là sử dụng bộ ADC của VĐK PIC để đo điện áp trên tụ C_hold (bất kỳ bộ ADC nào cũng phải có tụ này) đây là tụ điện để lấy mẫu điện áp để chuyển đổi AD. Chính vì nguyên tắc này mà cần tối thiểu 2 channel ADC mới thực hiện được cho dù là bác chỉ cần 1 phím touch mà thôi. Các bước thực hiện như sau:
- Nạp điện cho tụ C_hold bằng cách nối chân chưa dùng lên VCC, chân này phải là chân Analog của PIC. Chuyển kênh ADC nối với chân này để tụ C_hold nạp điện đến VCC
- Kéo chân cần quét xuống GND
- Chuyển chân cần quét thành ngõ vào
- Chuyển kênh ADC về chân cần quét, lúc này tụ điện C_hold sẽ nối song song với tụ điện C_touch được cấu thành bởi tấm pad và GND, giá trị của tụ điện C_touch này phụ thuộc vào nó có được chạm hay không chạm. Nếu chạm tay vào pad thì giá trị tụ điện sẽ lớn hơn không chạm.
- Bắt đầu thực hiện chuyển đổi ADC, lúc này kết quả chuyển đổi chính là điện áp trên cặp tụ C_hold và C_touch. Dựa vào độ chênh lệch của giá trị này ta xác định được phím có được touch hay không.
Rất đơn giản đúng không?
Nếu sự trình bày của tui khiến các bác khó hiểu các bác có thể tham khảo tài liệu: AN1298 từ Michrochip.
Tiếp theo là một chương trình mẫu:
Code:
#include<16F684.h> #include "common.h" #device *=16 ADC=10 #fuses INTRC_IO, NOPROTECT, WDT #use fast_io(all) #use delay(internal = 8M) #byte PortADir = getenv("SFR:TRISA") #bit ProximilityDir = PortADir.0 #bit ButtonDir = PortADir.1 #byte AnalogPorts = getenv("SFR:ANSEL") #byte ADC_Config = getenv("SFR:ADCON0") #define BUTTON_THRES 120 #define PROXIMILITY_THRES 80 #define PROXIMILITY_SENSOR PIN_A0 #define BUTTON_SENSOR PIN_A1 #define PROXIMILITY_LED PIN_C0 #define LED PIN_C1 #define STANDBY_LED PIN_C2 #define PROXIMILITY 0 #define BUTTON 1 volatile unsigned long Difference; volatile unsigned long LastVolt[2] = {0, 0}; volatile unsigned int1 ProximilityEnable; void main (void) { volatile unsigned long capacitor_volt, sub; unsigned int i; set_tris_a(0x00); set_tris_c(0x00); setup_adc(ADC_CLOCK_DIV_16); ADC_Config = 0b10000001; AnalogPorts = BIT0 | BIT1; i = 0; setup_wdt(WDT_ON | WDT_144MS); ProximilityEnable = TRUE; Difference = PROXIMILITY_THRES; raise(PROXIMILITY_LED); while(1) { ProximilityDir = 0; // select output direction ButtonDir = 0; if(ProximilityEnable) // scan proximility { raise(BUTTON_SENSOR); set_adc_channel(BUTTON); // charge C hold ground(PROXIMILITY_SENSOR); delay_us(100); ProximilityDir = 1; // select input direction set_adc_channel(PROXIMILITY); read_adc(ADC_START_ONLY); while(!adc_done()); capacitor_volt = read_adc(ADC_READ_ONLY); if(LastVolt[PROXIMILITY] > capacitor_volt) { sub = LastVolt[PROXIMILITY] - capacitor_volt; if(sub > Difference) { ground(PROXIMILITY_LED); ProximilityEnable = FALSE; Difference = BUTTON_THRES; setup_wdt(WDT_2304MS | WDT_TIMES_2); } } LastVolt[PROXIMILITY] = capacitor_volt; } else // scan key { raise(PROXIMILITY_SENSOR); set_adc_channel(PROXIMILITY); // charge C hold ground(BUTTON_SENSOR); delay_us(100); ButtonDir = 1; set_adc_channel(BUTTON); read_adc(ADC_START_ONLY); while(!adc_done()); capacitor_volt = read_adc(ADC_READ_ONLY); if(LastVolt[BUTTON] > capacitor_volt) { sub = LastVolt[BUTTON] - capacitor_volt; if(sub > Difference) { blink(LED); restart_wdt(); delay_ms(50); } } LastVolt[BUTTON] = capacitor_volt; } if(ProximilityEnable)// && (restart_cause() == WDT_FROM_SLEEP)) { ground(STANDBY_LED); sleep(); } else raise(STANDBY_LED); } }
Code:
#define BIT0 0x01 #define BIT1 0x02 #define BIT2 0x04 #define BIT3 0x08 #define BIT4 0x10 #define BIT5 0x20 #define BIT6 0x40 #define BIT7 0x80 #define ground(x) output_low(x) #define raise(x) output_high(x) #define blink(x) output_toggle(x)
Thân ái.
Comment