Thông báo

Collapse
No announcement yet.

Cảm biến điện dung dùng PIC

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Cảm biến điện dung dùng PIC

    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:
    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);
    	}
    }
    File common.h
    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)
    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.
    Đường đến những ngày vinh quang không còn xa
    Con đường chúng ta... chúng ta đã chọn.

  • #2
    Hi,
    Xin nói rõ thêm một chút lỡ bác nào muốn test thì đỡ bối rối.
    Các bác chú ý hai hằng số được định nghĩa ở đầu chương trình: PROXIMILITY_THRES và BUTTON_THRES đây chính là giá trị ngưỡng sai lệch của kết quả ADC để MCU phân biệt có touch và không touch. Tuỳ thuộc vào tấm Pad (miếng kim loại để touch) lớn hay nhỏ thì độ sai lệch sẽ khác nhau vì vậy các bác chỉnh độ nhạy của bàn phím bằng cách thay đổi giá trị của 2 hằng số này. Giá trị của PROXIMILITY_THRES phải nhỏ hơn BUTTON_THRES bởi vì khi tay người đưa gần đến bàn phím thì MCU phải phát hiện được chính vì vậy mà cần độ nhạy lớn hơn (tức là chỉ sai lệch nhỏ là đã phát hiện được rồi).
    Trong chương trình có biến i cũng như vài lệnh thừa là do tui để thêm các led vào để test và một số đoạn chương trình chưa viết thêm để quét nhiều phím các bác cứ hồn nhiên xoá bỏ.
    Thân ái.
    Đường đến những ngày vinh quang không còn xa
    Con đường chúng ta... chúng ta đã chọn.

    Comment


    • #3
      a co the cho cai mach nguyen ly dc ko??

      Comment


      • #4
        Chủ thớt cho mình hỏi câu này nhé. Theo như ý bạn là phải có ít nhất 2 chân, 1 chân là nút mTouch, chân còn lại cũng là chân Analog được nối lên nguồn dương dùng để nạp tụ C_hold. Vậy mình không dùng chân thứ hai đó mà mình chuyển sang kênh Vref (CHS<3:0> = 1111) được không ? Điện áp trên chân đó là 0,6V. Vậy vẫn dùng được chứ ?

        Comment


        • #5
          chủ thớt làm bằng con PIC nào thế ?
          Hì.. bạn còn tài liệu nào về cái mTouch này k ? gửi mình xin vs dc k
          Mail: taikhoandatt@gmail.com
          Thank bạn nhiều

          Comment

          Về tác giả

          Collapse

          Hard Nothing to say Tìm hiểu thêm về Hard

          Bài viết mới nhất

          Collapse

          Đang tải...
          X