Operácie

Implementácia funkcie map()

Zo stránky SensorWiki

Záverečný projekt predmetu MIPS / LS2026 - Dariia Svystak


Zadanie

Implementácia funkcie map()] V prostredí ArduinoIde máme možnosť použiť funkciu map(). Prepíšte túto funkciu tak, aby sme napätie merané v rozsahu 0 až 5V pomocou 10 b-ého A/D prevodníka vedeli zobraziť s presnosťou na „0,01V“. Použite celočíselnú aritmetiku. Výstup A/D prevodníkom filtrujte pomocou filtra kĺzavého priemeru – priemer s 8, resp. 16 vzoriek.

Vývojová doska ACROB.

Literatúra:


Analýza a opis riešenia

A/D prevodník je 10-bitový, preto vracia hodnoty v rozsahu 0 až 1023. Túto hodnotu program najprv filtruje pomocou kĺzavého priemeru z 8 alebo 16 vzoriek.

Následne sa hodnota prepočíta pomocou vlastnej funkcie map(). Funkcia prepočítava interval 0 až 1023 na interval 0 až 500. Hodnota 500 predstavuje 5,00 V, pretože napätie je v programe uložené v stotinách voltu. Vďaka tomu je možné vypísať napätie s presnosťou 0,01 V bez použitia typu float.

Potenciometer je zapojený ako delič napätia. Krajné vývody sú pripojené na VCC a GND, stredný vývod je pripojený na analógový vstup ADC4 mikrokontroléra ATmega328P.


Schéma zapojenia.

Na meranie napätia bol použitý laboratórny modul s potenciometrom, ktorý bol pripojený k vývojovej doske. V programe sa využíva iba výstup z potenciometra, preto je v schéme zapojenia znázornený len potenciometer. Ostatné prvky modulu použité neboli. Pri otáčaní potenciometra sa mení vstupná hodnota A/D prevodníka, ktorá sa v programe načítava z kanála ADC4.

Celkový pohľad na zariadenie.


Algoritmus a program

Algoritmus programu využíva toto a toto, základné funkcie sú takéto a voláma ich tuto... Výpis kódu je nižšie...


<tabs> <tab name="AVR C-code"><syntaxhighlight lang="c++" style="background: LightYellow;">

  1. include <avr/io.h>
  1. include <avr/io.h>
  2. include <stdio.h>
  3. include "uart.h"
  1. define LED1 PD6
  2. define POCET_VZORIEK 16

FILE uart_output = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);

void adc_init(void) {

   ADMUX = (1<<REFS0);                             
   ADCSRA = (1<<ADEN)                              
          | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);  

}

uint16_t adc_read(char channel)

{

    channel &= 0x0F;                  
    ADMUX = (ADMUX & 0xF0) | channel; 
   
   ADCSRA |= (1<<ADSC);              
   while(ADCSRA & (1<<ADSC))         
   { 
      
   }
   
   return (ADC);    

}


uint32_t map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min,uint16_t out_max) { return (uint32_t)(x - in_min)*(out_max - out_min)/(in_max - in_min) + out_min; }

uint16_t klzavy_priemer(uint8_t kanal)

{

uint32_t sucet = 0; for(uint8_t i=0; i < POCET_VZORIEK; i++) { sucet += 1023 - adc_read(kanal); } return sucet/POCET_VZORIEK; }


void pwm_init(void) { DDRD |= (1<<PD6);

TCCR0A = (1<<COM0A1) | (1<<WGM01) | (1<<WGM00); TCCR0B = (1<<CS01) | (1<<CS00); } int main(void) {

 uint16_t hodnota;
 uint32_t napatie;
 
 adc_init();
 uart_init();
 pwm_init();
 stdout = &uart_output;
 
 
 while (1)
 {
   hodnota = klzavy_priemer(4);

napatie = map(hodnota, 0, 1023, 0, 500);

if(hodnota>512) { PORTD |= (1<<PD6); } else{ PORTD &= ~(1<<PD6); }

   printf("ADC = %u, U = %lu.%02lu V\n", hodnota, napatie/100, napatie % 100);

OCR0A = hodnota/4;

 }
 return(0);

}



Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x zdrojaky.zip:

Zdrojový kód:Implementácia_funkcie_map()

Overenie

Ako ste overili funkciu, napríklad... Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia. Na konci uvádzame fotku hotového zariadenia.

Aplikácia.

Video:

Čo by som urobil inak

Zamyslite sa spätne nad problémom, ktorý ste riešili a napíšte, čo sa vám nepodarilo a nabudúce by ste spravili inak.


Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.