Operácie

Pripojenie viacero tlačidiel cez A/D prevodník: Rozdiel medzi revíziami

Zo stránky SensorWiki

StudentMIPS (diskusia | príspevky)
Bez shrnutí editace
StudentMIPS (diskusia | príspevky)
Bez shrnutí editace
Riadok 171: Riadok 171:


</syntaxhighlight ></tab>
</syntaxhighlight ></tab>
<tab name="filename.h"><syntaxhighlight  lang="c++" style="background: LightYellow;">
<tab name="uart.h"><syntaxhighlight  lang="c++" style="background: LightYellow;">
#include <avr/io.h>
#include <avr/io.h>
#define set_bit(ADDRESS, BIT)(ADDRESS |= (1 << BIT))
#define clear_bit(ADDRESS, BIT)(ADDRESS &= ~(1 << BIT))


void adc_init(void);                                  // A/D converter initialization
#ifndef UART_H_
#define UART_H_


unsigned int adc_read(char a_pin);
#include <stdio.h>
 
#define BAUD_PRESCALE(((F_CPU / (BAUDRATE * 16 UL))) - 1)
 
void uart_init(void);
int uart_putc(char c, FILE * stream);
void uart_puts(const char * s);
char uart_getc(void);
void delay(int delay);
 
#endif /* UART_H_ */
</syntaxhighlight ></tab>
</syntaxhighlight ></tab>
</tabs>
</tabs>

Verzia z 15:22, 12. máj 2026

Záverečný projekt predmetu MIPS / LS2026 - Kristian Rostupytskyi


Zadanie

Cieľom projektu bolo pripojiť viacero tlačidiel k mikrokontroléru Arduino s čipom ATmega328P pomocou jedného analógového vstupu a A/D prevodníka. Projekt demonštruje možnosť rozlišovania viacerých stavov tlačidiel podľa rôznych hodnôt napätia získaných cez rezistorovú sieť.

Úlohou bolo:

  • pripojiť 5 tlačidiel cez rezistory,
  • využiť iba jeden analógový vstup mikrokontroléra,
  • merať hodnotu napätia pomocou A/D prevodníka,
  • zobrazovať zmeny hodnôt v konzole programu AVR Studio.
Vývojová doska ACROB.

Literatúra:


Analýza a opis riešenia

Teoretický úvod

Mikrokontrolér ATmega328P obsahuje vstavaný 10-bitový A/D prevodník (ADC – Analog to Digital Converter), ktorý prevádza analógové napätie na digitálnu hodnotu v rozsahu 0 – 1023.

Každé tlačidlo bolo pripojené cez rezistor s odlišnou hodnotou. Po stlačení konkrétneho tlačidla vznikne na analógovom vstupe iné napätie, ktoré ADC prevedie na inú digitálnu hodnotu.

Vďaka tomu je možné pomocou jediného analógového vstupu rozlišovať viacero tlačidiel.

Výhody riešenia:

  • úspora vstupných pinov mikrokontroléra,
  • jednoduché zapojenie,
  • možnosť rozšírenia o ďalšie tlačidlá.

Nevýhody:

  • menšia presnosť pri väčšom počte tlačidiel,
  • citlivosť na toleranciu rezistorov,
  • možnosť nepresných hodnôt pri súčasnom stlačení viacerých tlačidiel.

Použité komponenty

  • Arduino / ATmega328P
  • 5 tlačidiel
  • rezistory
  • prepojovacie vodiče
  • AVR Studio

Schéma zapojenia

Tlačidlá boli pripojené cez rezistorový delič na jeden analógový vstup mikrokontroléra. Každé tlačidlo malo vlastný rezistor, čím vznikla jedinečná hodnota napätia pre každé tlačidlo.

Princíp zapojenia:

  • bez stlačenia tlačidla je na vstupe základná hodnota,
  • po stlačení tlačidla sa zmení napätie,
  • ADC prevedie napätie na digitálnu hodnotu,
  • program vyhodnotí rozsah hodnoty a určí stlačené tlačidlo.
Celkový pohľad na zariadenie.


Algoritmus a program

Hlavné časti programu:

1. Inicializácia A/D prevodníka

  • nastavenie referenčného napätia,
  • nastavenie prescalera,
  • povolenie ADC.

2. Čítanie analógovej hodnoty

  • spustenie konverzie,
  • čakanie na dokončenie prevodu,
  • načítanie hodnoty z registra ADC.

3. Vyhodnotenie tlačidiel

  • porovnanie načítanej hodnoty s intervalmi,
  • určenie stlačeného tlačidla.

4. Výpis do konzoly

  • zobrazenie aktuálnej hodnoty ADC,
  • zobrazenie informácie o stlačenom tlačidle.


#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#include "hardware.h"
#include "uart.h"

#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define toggle_bit(ADDRESS,BIT) (ADDRESS ^= (1<<BIT))

FILE uart_stream = FDEV_SETUP_STREAM(uart_putc, uart_getc, _FDEV_SETUP_RW);

volatile unsigned int oldICR = 0;
volatile unsigned int Ton = 0;
volatile unsigned int Toff = 0;
volatile unsigned char edge = 0;   // 0=rising, 1=falling

void timer1_init(void)
{
    TCCR1A = 0x00;                          // normal mode
    TCCR1B = (1<<CS12) | (1<<CS10);         // prescaler 1024
    TCCR1B |= (1<<ICES1);                   // rising edge first

    TCNT1 = 0;

    TIMSK1 = (1<<ICIE1);
}

ISR(TIMER1_CAPT_vect)
{
    unsigned int diff = ICR1 - oldICR;
    oldICR = ICR1;

    if(edge == 0)
    {
        Toff = diff;

        TCCR1B &= ~(1<<ICES1);
        edge = 1;
    }
    else
    {
        Ton = diff;

        TCCR1B |= (1<<ICES1);
        edge = 0;

        unsigned long Ton_us  = (unsigned long)Ton * 64;
        unsigned long Toff_us = (unsigned long)Toff * 64;

        unsigned long Ttotal = Ton_us + Toff_us;

        unsigned long period_ms = Ttotal / 1000;

        unsigned long duty = (Ton_us * 100) / Ttotal;

        printf("Period: %lu ms | Duty: %lu %%\n", period_ms, duty);
    }
}

int main(void)
{
    hw_init();
    hw_init1();

    uart_init();
    stdout = &uart_stream;

    timer1_init();

    sei();

    printf("Ready to measure...\n");

    while(1)
    {
    }

    return 0;
}
#include <avr/io.h>
#define set_bit(ADDRESS, BIT)(ADDRESS |= (1 << BIT))
#define clear_bit(ADDRESS, BIT)(ADDRESS &= ~(1 << BIT))

#ifndef UART_H_
#define UART_H_

#include <stdio.h>

#define BAUD_PRESCALE(((F_CPU / (BAUDRATE * 16 UL))) - 1)

void uart_init(void);
int uart_putc(char c, FILE * stream);
void uart_puts(const char * s);
char uart_getc(void);
void delay(int delay);

#endif /* UART_H_ */

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: zdrojaky.zip

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.