This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| et:examples:sensor:ntc [2009/03/25 11:33] – raivo.sell | et:examples:sensor:ntc [2009/11/05 13:30] (current) – eemaldatud mikk.leini | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ===== Temperatuuri andur ===== | ||
| - | |||
| - | MS Exceli fail, mis võimaldab lihtsalt arvutada termistori väärtusi ka karakteristikut. | ||
| - | {{examples: | ||
| - | |||
| - | Sõltuvalt termistorist ja tema parameetritest on koefitsiendid erinevad. | ||
| - | Samuti tuleb tähelepanu pöörata pingejaguri takisti väärtustele ja ühendusskeemile. | ||
| - | |||
| - | {{examples: | ||
| - | |||
| - | Temperatuuri andur on plaadil ühendatud ühelt poolt toitega +5V ja teiselt polt porti PF2. | ||
| - | |||
| - | {{: | ||
| - | |||
| - | ===== Näide Temperatuuri kuvamisest LCD-le ===== | ||
| - | |||
| - | PS Temperatuuri koefitsendid on siin näites suvalised. | ||
| - | |||
| - | <code c> | ||
| - | // Antud kood kuvab LCD-l ADC väärtuse, analoog pinge, loenduri ja temperatuuri | ||
| - | |||
| - | #define RREF 10000 // termistori nimitakistus 25 kraadi juures | ||
| - | #define BVALUE 3977 // B väärtus termistori andmelehelt | ||
| - | |||
| - | #include < | ||
| - | #include < | ||
| - | #include < | ||
| - | #include " | ||
| - | |||
| - | |||
| - | #define SET(x) |= (1<< | ||
| - | #define CLR(x) & | ||
| - | #define INV(x) ^=(1<< | ||
| - | #define bit_get(p, | ||
| - | #define BIT(x) (0x01 << (x)) | ||
| - | #define MAX(a, b) ((a) > (b)) ? (a):(b) | ||
| - | |||
| - | unsigned char echo[10]; | ||
| - | unsigned int ntc=0; | ||
| - | unsigned int adc=0; | ||
| - | unsigned int num=0; | ||
| - | |||
| - | |||
| - | const int TEMP_pos[] PROGMEM = // Positive Celcius temperatures (ADC-value) | ||
| - | { // from 0 to 60 degrees | ||
| - | 806, | ||
| - | 636, | ||
| - | 452, | ||
| - | 297, | ||
| - | 187, | ||
| - | }; | ||
| - | |||
| - | int TEMP_neg[] = // Negative Celcius temperatures (ADC-value) | ||
| - | { // from -1 to -15 degrees | ||
| - | 815, | ||
| - | }; | ||
| - | |||
| - | |||
| - | void init_lcd(void){ // initialize display, cursor off | ||
| - | | ||
| - | lcd_clrscr(); | ||
| - | } | ||
| - | |||
| - | void write_echo(void){ | ||
| - | |||
| - | lcd_clrscr (); | ||
| - | |||
| - | itoa(num, | ||
| - | lcd_gotoxy(8, | ||
| - | lcd_puts(echo); | ||
| - | |||
| - | itoa(ntc, | ||
| - | lcd_gotoxy(8, | ||
| - | lcd_puts(echo); | ||
| - | } | ||
| - | |||
| - | void lcd(int arv,int pos, int rida){ | ||
| - | |||
| - | itoa(arv, | ||
| - | lcd_gotoxy(pos, | ||
| - | lcd_puts(echo); | ||
| - | } | ||
| - | |||
| - | void temp_read(){ | ||
| - | int ADCresult = 0; | ||
| - | int i=0; | ||
| - | |||
| - | ADCresult = ADC_read(2); | ||
| - | adc=ADCresult; | ||
| - | for (i=0; | ||
| - | if (ADCresult > pgm_read_word(& | ||
| - | } | ||
| - | |||
| - | ntc=i; | ||
| - | |||
| - | } | ||
| - | |||
| - | |||
| - | int main (void) { | ||
| - | |||
| - | char buffer[7]; | ||
| - | uint16_t volt; | ||
| - | |||
| - | init_lcd(); | ||
| - | // | ||
| - | |||
| - | while(1) | ||
| - | { | ||
| - | |||
| - | // | ||
| - | temp_read(); | ||
| - | num++; | ||
| - | |||
| - | lcd(ntc, | ||
| - | lcd(adc, | ||
| - | |||
| - | volt=50*adc/ | ||
| - | |||
| - | lcd(volt, | ||
| - | lcd(num, | ||
| - | |||
| - | _delay_ms(500); | ||
| - | lcd_clrscr (); | ||
| - | // | ||
| - | |||
| - | } | ||
| - | } | ||
| - | |||
| - | </ | ||
| - | |||
| - | |||
| - | ===== Automaatse mõõtepiirkonnaga mõõtmine ===== | ||
| - | |||
| - | Et ühe numbri-indikaatoriga adekvaatseid väärtusi kuvada, võib kasutusele võtta automaatse mõõtepiirkonna. See tähendab, et programm peab pidevalt arvet minimaalse ja maksimaalse mõõdetud väärtuse üle ja number mis kuvatakse näitab mõõdetud väärtuse suhtarvu minimaalsest maksimaalseni skaalas 0 kuni 9. Näiteks termomeetri näitu mõõtes saab anduri panna külma vette (0 kraadi) ning keevasse vette (100 kraadi) ja kui siis 0-st 100-kraadini mõõtmisi teha, kuvatakse indikaatoril näite kümnete kraadide kaupa. | ||
| - | |||
| - | <code c> | ||
| - | // | ||
| - | // ADC sampling and integrating in automatic measuring region | ||
| - | // | ||
| - | // Mikk Leini | ||
| - | // | ||
| - | // 2009 | ||
| - | // | ||
| - | |||
| - | // Include avrlibc | ||
| - | #include < | ||
| - | #include < | ||
| - | |||
| - | // Include common library | ||
| - | #include " | ||
| - | |||
| - | // Math operations | ||
| - | #define MIN(a, b) ((a) < (b) ? (a) : (b)) | ||
| - | #define MAX(a, b) ((a) > (b) ? (a) : (b)) | ||
| - | #define INTEGRATE(value, | ||
| - | |||
| - | // Configure pins | ||
| - | #define SEGMENT_DISPLAY_LATCH | ||
| - | #define SEGMENT_DISPLAY_DATA_OUT | ||
| - | #define SEGMENT_DISPLAY_CLOCK | ||
| - | |||
| - | // | ||
| - | // 7 segment display initialization | ||
| - | // | ||
| - | void segment_diplay_init(void) | ||
| - | { | ||
| - | // Set latch, data out and clock pins as output | ||
| - | setup_output_pin(SEGMENT_DISPLAY_LATCH); | ||
| - | setup_output_pin(SEGMENT_DISPLAY_DATA_OUT); | ||
| - | setup_output_pin(SEGMENT_DISPLAY_CLOCK); | ||
| - | } | ||
| - | |||
| - | // | ||
| - | // Digit writing to 7 segment display | ||
| - | // | ||
| - | void segment_display_write(unsigned char digit) | ||
| - | { | ||
| - | unsigned char map; | ||
| - | |||
| - | // Decimal to segment map | ||
| - | switch (digit) | ||
| - | { | ||
| - | case 0 : map = 0b00111111; break; // Every bit corresponds to one segment | ||
| - | case 1 : map = 0b00000110; break; // " | ||
| - | case 2 : map = 0b01011011; break; // " | ||
| - | case 3 : map = 0b01001111; break; // " | ||
| - | case 4 : map = 0b01100110; break; | ||
| - | case 5 : map = 0b01101101; break; | ||
| - | case 6 : map = 0b01111100; break; | ||
| - | case 7 : map = 0b00000111; break; | ||
| - | case 8 : map = 0b01111111; break; | ||
| - | case 9 : map = 0b01100111; break; | ||
| - | default: map = 0b01111001; | ||
| - | } | ||
| - | |||
| - | // Latch low | ||
| - | clear_pin(SEGMENT_DISPLAY_LATCH); | ||
| - | |||
| - | // Send every bit in the byte. MSB (most significant bit) first. | ||
| - | for (signed char i = 7; i >= 0; i--) | ||
| - | { | ||
| - | // If bit is set, sets the data out pin, otherwise not | ||
| - | set_pin_to(SEGMENT_DISPLAY_DATA_OUT, | ||
| - | |||
| - | // Clock high for certain period | ||
| - | set_pin(SEGMENT_DISPLAY_CLOCK) | ||
| - | _delay_us(1); | ||
| - | |||
| - | // Clock low for certain period | ||
| - | clear_pin(SEGMENT_DISPLAY_CLOCK) | ||
| - | _delay_us(1); | ||
| - | } | ||
| - | |||
| - | // Latch high | ||
| - | set_pin(SEGMENT_DISPLAY_LATCH); | ||
| - | } | ||
| - | |||
| - | // | ||
| - | // ADC conversion waiting | ||
| - | // | ||
| - | void adc_wait_until_done(void) | ||
| - | { | ||
| - | while (IS_BIT_SET(ADCSRA, | ||
| - | { | ||
| - | asm volatile (" | ||
| - | } | ||
| - | } | ||
| - | |||
| - | // | ||
| - | // ADC channel value sampling | ||
| - | // | ||
| - | unsigned short adc_sample_value(unsigned char channel, unsigned char num_samples) | ||
| - | { | ||
| - | unsigned short result = 0; | ||
| - | |||
| - | // ADC setup - prescaler 8 | ||
| - | ADCSRA = BIT(ADEN) | BIT(ADPS1) | BIT(ADPS0); | ||
| - | |||
| - | // Specify channel | ||
| - | ADMUX = channel & 0x0F; | ||
| - | |||
| - | // Reference voltage to external | ||
| - | ADMUX |= BIT(REFS0); | ||
| - | |||
| - | // Take test sample to "warm up" converter | ||
| - | // Usually the first sample is discarded | ||
| - | SET_BIT(ADCSRA, | ||
| - | adc_wait_until_done(); | ||
| - | |||
| - | // Real sampling, sum up specifed number of samples | ||
| - | for (unsigned char i = 0; i < num_samples; | ||
| - | { | ||
| - | SET_BIT(ADCSRA, | ||
| - | adc_wait_until_done(); | ||
| - | |||
| - | // Sum-up | ||
| - | result += ADCW; | ||
| - | } | ||
| - | |||
| - | // De-activate ADC | ||
| - | CLEAR_BIT(ADCSRA, | ||
| - | |||
| - | // Return averaged result | ||
| - | return (result / num_samples); | ||
| - | } | ||
| - | |||
| - | // | ||
| - | // Program entrance function | ||
| - | // | ||
| - | int main(void) | ||
| - | { | ||
| - | unsigned short lowValue | ||
| - | unsigned short highValue = 0x0000; | ||
| - | unsigned short value; | ||
| - | unsigned char relativeValue; | ||
| - | |||
| - | // 7 segment display initialization | ||
| - | segment_diplay_init(); | ||
| - | |||
| - | // To not get wrong lowValue we should set get the initial integrated value | ||
| - | value = adc_sample_value(2, | ||
| - | |||
| - | // Endless loop | ||
| - | while (1) | ||
| - | { | ||
| - | // Sample ADC channel 2 four times | ||
| - | // Integrate value over 25 steps (50 ms each) | ||
| - | INTEGRATE(value, | ||
| - | |||
| - | // Check for new lower limit | ||
| - | lowValue = MIN(lowValue, | ||
| - | |||
| - | // Check for new higher limit | ||
| - | highValue = MAX(highValue, | ||
| - | |||
| - | // Calculate relative value | ||
| - | // Range from lowValue to highValue is converted to 0 to 9 | ||
| - | relativeValue = 9 * (value - lowValue) / (highValue - lowValue); | ||
| - | |||
| - | // Write digit | ||
| - | segment_display_write(relativeValue); | ||
| - | |||
| - | // Wait 50 ms | ||
| - | _delay_ms(50); | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | ===== Viited ===== | ||
| - | |||
| - | * [[http:// | ||