Giỏ hàng
DANH MỤC

SYHNC and Atmega8

Đăng bởi Cửa hàng linh kiện điện tử KME ngày 0 bình luận

ỨNG DỤNG SENSOR SYH ĐO ĐỘ ẨM BẰNG ATMEGA8

Khang Dang Minh

http://kme.com.vn

  1. Tổng quan

Trên thị trường có rất nhiều loại cảm biến độ ẩm với những phương pháp đo khác nhau. Với những ứng dụng không yêu cầu độ chính xác cao và thời gian đáp ứng chậm, việc lựa chọn cảm biến hướng tới giá thành cảm biến và phương pháp sử dụng sensor sao cho đơn giản với giá cạnh tranh nhất.

Bài viết này hướng dẫn cách đo độ ẩm bằng sensor SYH, biến trở theo độ ẩm

Cảm biến SYH:

- Dải đo: 20%-90%

- Dải tần số làm việc: 100Hz-10kHz

- Điện áp tối đa: 5VAC

  1. Phương pháp đo

Cảm biến độ ẩm SYH bản chất là một biến trở, giá trị điện trở sẽ thay đổi theo độ ẩm. Để đo giá trị điện trở của cảm biến, ta mắc cảm biến vào 1 bộ trở chia, từ giá trị điện áp đo được rơi trên cảm biến ta có thể tính ra được giá trị của điện trở tại thời điểm và vị trí đo. Do đặc tính chế tạo cảm biến của nhà sản xuất, đưa trực tiếp tín hiệu DC qua cảm biến có thể gây hư hại hoặc kết quả đo không chính xác. Thay vào đó, tín hiệu đưa qua sensor là 1 xung AC (xung sine). Ở đây ta đưa 1 xung vuông vào đầu mạng trở chia, đo biên độ đầu vào và biên độ tín hiệu ở đầu cảm biến cho phép tính ra được giá trị của diện trở và tra ngược ra được độ ẩm.

III. Mạch nguyên lý

Vi điều khiển hoạt động ở tần số 16MHz

R1: 22K, 1%

RV1: Biến trở, mô  phỏng thay thế SYH

D1: Zenner (Optional), 2.2V. (Trong code mẫu không sử dụng D1). D1 có tác dụng giới hạn áp tránh gây hỏng sensor.

Mô tả hoạt động:

Tín hiệu xung đầu vào được đưa qua trở R2 tới bộ trở chia R1 và RV1. Tần số tín hiệu đầu vào là 100Hz. Sử dụng 2 đầu ADC của Atmega8 thực hiện đo tại 2 điểm, đầu R1 và đầu RV1, thời gian lớn nhất để Atmega8 chuyển đổi ADC là 260uS. Vi điều khiển thực hiện đo biên độ của tín hiệu đo tại 2 điểm trên sau đó tính ra giá trị RV1 từ công thức phân áp.

RV1= R1/(AVIN/AVOUT-1) (kOhm)

III. Sơ đồ thuật toán và Code mẫu

Main code:

/*****************************************************

This program was produced by the

CodeWizardAVR V1.25.9 Professional

Automatic Program Generator

© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.

http://www.hpinfotech.com


Project :

Version :

Date : 12/9/2009

Author  : Dang Minh Khang

Company : KME

Comments:



Chip type        : ATmega8

Program type     : Application

Clock frequency : 16.000000 MHz

Memory model     : Small

External SRAM size  : 0

Data Stack size : 256

*****************************************************/

#include <includes.h>


unsigned int valmin, valmax, vpkpkin, vpkpkout;

float rrh=0;


#ifndef RXB8

#define RXB8 1

#endif


#ifndef TXB8

#define TXB8 0

#endif


#ifndef UPE

#define UPE 2

#endif


#ifndef DOR

#define DOR 3

#endif


#ifndef FE

#define FE 4

#endif


#ifndef UDRE

#define UDRE 5

#endif


#ifndef RXC

#define RXC 7

#endif


#define FRAMING_ERROR (1<<FE)

#define PARITY_ERROR (1<<UPE)

#define DATA_OVERRUN (1<<DOR)

#define DATA_REGISTER_EMPTY (1<<UDRE)

#define RX_COMPLETE (1<<RXC)


// USART Receiver buffer

#define RX_BUFFER_SIZE 8

char rx_buffer[RX_BUFFER_SIZE];


#if RX_BUFFER_SIZE <= 256

unsigned char rx_wr_index,rx_rd_index,rx_counter;

#else

unsigned int rx_wr_index,rx_rd_index,rx_counter;

#endif


// This flag is set on USART Receiver buffer overflow

bit rx_buffer_overflow;


// USART Receiver interrupt service routine

interrupt [USART_RXC] void usart_rx_isr(void)

{

char status,data;

status=UCSRA;

data=UDR;



if (data=='1')

{

lcd_putchar(data);

printf("IDone\r\n");

}


if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)

  {

  rx_buffer[rx_wr_index++]=data;

#if RX_BUFFER_SIZE == 256

  // special case for receiver buffer size=256

  if (++rx_counter == 0)

  {

#else

  if (rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;

  if (++rx_counter == RX_BUFFER_SIZE)

  {

  rx_counter=0;

#endif

  rx_buffer_overflow=1;

  }

  }

}


//// Read the AD conversion result

//unsigned int read_adc(unsigned char adc_input)

//{

//ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);

//// Delay needed for the stabilization of the ADC input voltage

//delay_us(10);

//// Start the AD conversion

//ADCSRA|=0x40;

//// Wait for the AD conversion to complete

//while ((ADCSRA & 0x10)==0);

//ADCSRA|=0x10;

//return ADCW;

//}


// Declare your global variables here


void main(void)

{

unsigned int val;

float value,rh,rhold;

char str[10];

unsigned char i;

// Declare your local variables here


// Input/Output Ports initialization

// Port B initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTB=0x00;

DDRB=0x00;


// Port C initialization

// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTC=0x00;

DDRC=0x00;


// Port D initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTD=0x00;

DDRD=0x00;


// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: Timer 0 Stopped

TCCR0=0x00;

TCNT0=0x00;


// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: Timer 1 Stopped

// Mode: Normal top=FFFFh

// OC1A output: Discon.

// OC1B output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

// Timer 1 Overflow Interrupt: Off

// Input Capture Interrupt: Off

// Compare A Match Interrupt: Off

// Compare B Match Interrupt: Off

TCCR1A=0x00;

TCCR1B=0x00;

TCNT1H=0x00;

TCNT1L=0x00;

ICR1H=0x00;

ICR1L=0x00;

OCR1AH=0x00;

OCR1AL=0x00;

OCR1BH=0x00;

OCR1BL=0x00;


// Timer/Counter 2 initialization

// Clock source: System Clock

// Clock value: Timer 2 Stopped

// Mode: Normal top=FFh

// OC2 output: Disconnected

ASSR=0x00;

TCCR2=0x00;

TCNT2=0x00;

OCR2=0x00;


// External Interrupt(s) initialization

// INT0: Off

// INT1: Off

MCUCR=0x00;


// Timer(s)/Counter(s) Interrupt(s) initialization

TIMSK=0x00;


// USART initialization

// Communication Parameters: 8 Data, 1 Stop, No Parity

// USART Receiver: On

// USART Transmitter: On

// USART Mode: Asynchronous

// USART Baud Rate: 9600

//UCSRA=0x00;

//UCSRB=0x98;

//UCSRC=0x86;

//UBRRH=0x00;

//UBRRL=0x67;


UCSRA=0x00;

UCSRB=0x00;

UCSRC=0x00;

UBRRH=0x00;

UBRRL=0x00;


// Analog Comparator initialization

// Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0x80;

SFIOR=0x00;


// ADC initialization

// ADC Clock frequency: 62.500 kHz

// ADC Voltage Reference: AVCC pin

ADMUX=ADC_VREF_TYPE & 0xff;

ADCSRA=0x87;


// Global enable interrupts

#asm("sei")


// LCD module initialization

lcd_init(16);

lcd_putsf("Hello World!");

delay_ms(300);


read_scan_adc(0,&valmin, &valmax);


//printf("Hello World\r\n");


//valmin = valarr[0];

//valmax = valarr[0];

//for (i=0; i<5; i++)

//     {

//         scan_min(&valmin, valarr[i]);

//         scan_max(&valmax, valarr[i]);

//     }

//

    lcd_clear();

    lcd_gotoxy(0,0);

    sprintf(str,"%i",valmin);

    lcd_puts(str);


    lcd_gotoxy(0,1);

    sprintf(str,"%i",valmax);

    lcd_puts(str);




while (1)

  {

//   // Place your code here

//   val = read_adc(0);

//   value = val;

//   value = value/1024*5;

//

//   lcd_clear();

//

//   lcd_gotoxy(0,0);

//   sprintf(str,"%2.3f",value);

//   lcd_puts(str);

//   lcd_putsf("V");

//

    delay_ms(2000);


    read_scan_adc(0,&valmin, &valmax);

    lcd_clear();

    lcd_gotoxy(0,0);

    vpkpkin = get_Vpkpk(valmin, valmax);

    sprintf(str,"%i",vpkpkin);

    lcd_puts(str);


    read_scan_adc(1,&valmin, &valmax);

    lcd_gotoxy(4,0);

    vpkpkout = get_Vpkpk(valmin, valmax);

    sprintf(str,"%i",vpkpkout);

    lcd_puts(str);


    get_Rrh(vpkpkin, vpkpkout, &rrh);

    lcd_gotoxy(0,1);

    ftoa(rrh,2,str);

    lcd_puts(str);


  };

}


Hàm con:

float VREF  = 5;


// Read the AD conversion result

unsigned int read_adc(unsigned char adc_input)

{

ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);

// Delay needed for the stabilization of the ADC input voltage

delay_us(10);

// Start the AD conversion

ADCSRA|=0x40;

// Wait for the AD conversion to complete

while ((ADCSRA & 0x10)==0);

ADCSRA|=0x10;

return ADCW;

}


void read_scan_adc(unsigned char adc_input, unsigned int *valmin, unsigned int *valmax)

{


unsigned int i, temp;


    *valmin = *valmax = read_adc(adc_input);

    for (i=0; i<MAX_SAMPLE; i++)

    {

        temp = read_adc(adc_input);

        scan_min(&*valmin, temp);

        scan_max(&*valmax, temp);

    }

}


void scan_max(unsigned int *max, unsigned int value)

{

if (value > *max)

    *max = value;


}


void scan_min(unsigned int *min, unsigned int value)

{

if (value< *min)

    *min = value;

}


unsigned int get_Vpkpk(unsigned int valmin, unsigned int valmax)

{

return (valmax-valmin);

}


void get_Rrh(unsigned int adcin, unsigned int adcout, float *result)

{

//vout=vin*Rrh/(R1+Rrh)-->(R1+Rrh)/Rrh=Vin/Vout

//--->R1/Rrh+1 = Vin/Vout-->Rrh=R1/(Vin/Vout-1)

*result = (float) adcin/adcout -1 ;

*result = RESISTOR_H/ *result; //RESITOR=22k


}



0 bình luận


Bình luận

Lưu ý: Các bình luận phải được duyệt trước khi được hiển thị.


Cũ hơn Mới hơn