Elektronická škrtiaca klapka: Rozdiel medzi revíziami
Z SensorWiki
(→Zadanie) |
(→Algoritmus a program) |
||
(65 medziľahlých úprav od jedného ďalšieho používateľa nie je zobrazených) | |||
Riadok 1: | Riadok 1: | ||
− | Záverečný projekt predmetu MIPS / LS2024 - ''' | + | Záverečný projekt predmetu MIPS / LS2024 - '''Peter Szovics''' |
Riadok 9: | Riadok 9: | ||
− | [[Obrázok: UNO_schema_na_zaciatok_stranky.jpg| | + | [[Obrázok: UNO_schema_na_zaciatok_stranky.jpg|400px|thumb|center|Vývojová doska Arduino UNO R3]] |
'''Literatúra:''' | '''Literatúra:''' | ||
* [http://ap.urpi.fei.stuba.sk/sensorwiki/index.php/Acrob_technical_description Dokumentácia k doske Acrob] | * [http://ap.urpi.fei.stuba.sk/sensorwiki/index.php/Acrob_technical_description Dokumentácia k doske Acrob] | ||
− | + | ||
Riadok 20: | Riadok 20: | ||
== Analýza a opis riešenia == | == Analýza a opis riešenia == | ||
− | + | Mojou témou semestrálnej práce je ovládanie škrtiacej klapky pomocou plynového pedálu. Zapojenie a vypracovanie projektu je inšpirované cvičením 8: (http://senzor.robotika.sk/sensorwiki/index.php/A/D_prevodn%C3%ADk).<p> | |
+ | <br> | ||
+ | Súčiastky a diely ktoré boli použité na zostrojenie projektu:<br> | ||
+ | <br> | ||
+ | • elektronický plynový pedál (1K2 721 503 AJ) <br> | ||
+ | • elektronická škrtiaca klapka (047 133 062) <br> | ||
+ | • sacie potrubie (047 129 743 G) <br> | ||
+ | • arduino r3 doska (Microchip ATmega328P) <br> | ||
+ | • adaptér 230V/9V (ASSA107E-090100) <br> | ||
+ | • napatovy stabilizator (7805) <br> | ||
+ | • mosfet transistor (IRF540N) <br> | ||
+ | • rezistory 1kΩ, 220Ω <br> | ||
+ | • breadboard (MB-102 830/400) <br> | ||
+ | • duPont káble M-M - 40x, 40 cm <br> | ||
+ | <br> | ||
+ | Presný opis fungovania elektrického obvodu: <br> | ||
− | + | <br> | |
− | + | V akej pozícií je pedál toľko energie sa vysiela na pohon škrtiacej klapky, v našom prípade s aktuálnym zapojením sa klapka začne hýbať až po prekročení 40% zatlačenia pedálu, aby sme predišli tomuto neefektívnemu ovládaniu a chceliť docieliť identický pohyb klapky a pedálu tak som pre budúce vylepšovanie do projektu zakomponoval aj predprípravu (arduino výstup A3, A1 a A2) na spätnoväzobný regulátor aby klapka presne kopírovala polohu pedálu. | |
+ | [[Súbor:schemap.jpg|450px|thumb|left|ELEKTRONICKÁ SCHÉMA]] | ||
+ | <br> | ||
+ | Na obrázku je vyobrazená schéma zapojenia elektronického plynového pedála pre Arduino. Popis jednotlivých častí: | ||
+ | <br> | ||
+ | 1. Napájanie: | ||
+ | - Sieťový adaptér (230V/9V) je pripojený k stabilizátoru napätia 7805, ktorý redukuje napätie na 5V pre Arduino. | ||
− | [[Súbor: | + | 2. Ovládanie motora: |
+ | - Motor (škrtacia klapka) sú pripojené k Mosfet tranzistoru IRF540N, ktorý slúži ako spínač pre ovládanie motora. | ||
+ | - Gate (G) tranzistora je riadený z pinu D6 Arduina cez rezistor R1 (1kΩ). | ||
+ | |||
+ | 3. Snímanie polohy pedála: | ||
+ | - Elektronický plynový pedál má v sebe dva potenciometre pripojené k analógovým vstupom Arduina (A4). | ||
+ | - Posuvné kontakty potenciometrov sú napájané 5V a zemou, poskytujúce variabilný výstupný signál podľa stlačenia pedála. | ||
+ | |||
+ | 4. Ochranné prvky: | ||
+ | - Dióda D1 je chránená rezistorom R2. | ||
+ | - Rezistor R1 je pridaný pre ochranu pinu D6 Arduina pred nadmerným prúdom. | ||
+ | |||
+ | |||
+ | <br> | ||
+ | <br> | ||
+ | <br> | ||
+ | Vizuálna reprezentácia PWM (Pulse width modulation), šírka impulzu sa mení podľa závislosti zatlačenia pedálu. | ||
+ | [[Súbor:Osciloskopp.jpg|800px|thumb|center|ZÁZNAM Z OSCILOSKOPU]] | ||
=== Algoritmus a program === | === Algoritmus a program === | ||
− | + | Celý kód som použil z 8 cvičenia, kde sme sa mohli naučiť ovládať ledku pomocou PWM, kód je napísaný v jednom .c súbore – na spustenie treba 4 knižnice. | |
− | |||
<tabs> | <tabs> | ||
− | <tab name=" | + | <tab name="main.c"><source lang="c++" style="background: LightYellow;"> |
#include <avr/io.h> | #include <avr/io.h> | ||
− | + | #include "uart.h" | |
+ | #define F_CPU 16000000UL | ||
+ | #define BAUDRATE 9600 | ||
+ | #include <stdio.h> | ||
+ | FILE mystdout = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE); | ||
+ | |||
int main(void) | int main(void) | ||
{ | { | ||
+ | adc_init(); | ||
+ | hw_init(); | ||
+ | uart_init(); | ||
+ | stdout = &mystdout; | ||
unsigned int measuredValue; | unsigned int measuredValue; | ||
− | while (1) | + | DDRD|=(1<<PD6); |
+ | |||
+ | |||
+ | TCNT0=0; | ||
+ | |||
+ | OCR0A=0; | ||
+ | |||
+ | |||
+ | TCCR0A|=(1<<COM0A1)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM00); | ||
+ | |||
+ | TCCR0B|=(1<<CS02)|(1<<CS00); | ||
+ | |||
+ | while(1) | ||
{ | { | ||
− | + | measuredValue = adc_read(4); | |
+ | printf("hodnota: %04d \r",measuredValue); | ||
+ | |||
+ | OCR0A=measuredValue/4; | ||
} | } | ||
+ | |||
+ | return(0); | ||
+ | } | ||
+ | |||
+ | </source></tab> | ||
+ | |||
+ | |||
+ | <tab name="adc.h"><source lang="c++" style="background: LightYellow;"> | ||
+ | #include <avr/io.h> | ||
− | + | void adc_init(void); | |
+ | unsigned int adc_read(char a_pin); | ||
+ | </source></tab> | ||
+ | |||
+ | <tab name="adc.c"><source lang="c++" style="background: LightYellow;"> | ||
+ | #include <stdio.h> | ||
+ | #include "adc.h" | ||
+ | |||
+ | void adc_init(void) { | ||
+ | ADMUX = (1 << REFS0); // reference voltage set to AVcc | ||
+ | ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // enable ADC and set prescaler to 128 | ||
+ | } | ||
+ | |||
+ | unsigned int adc_read(char a_pin) { | ||
+ | a_pin &= 0x07; // limit input to 0-7 | ||
+ | ADMUX = (ADMUX & 0xF8) | a_pin; // select ADC channel with safety mask | ||
+ | ADCSRA |= (1 << ADSC); // start conversion | ||
+ | while (ADCSRA & (1 << ADSC)); // wait for conversion to complete | ||
+ | return ADC; // return the ADC value | ||
} | } | ||
+ | </source></tab> | ||
+ | |||
+ | <tab name="uart.h"><source lang="c++" style="background: LightYellow;"> | ||
+ | /* ************************************************************************* */ | ||
+ | /* FileName: uart.h */ | ||
+ | /* ************************************************************************* */ | ||
+ | |||
+ | #define LED PB5 // internal on-board LED | ||
+ | |||
+ | /* na testovanie su uz zadefinovane */ | ||
+ | // bit_is_set(PINB, SW1) | ||
+ | // bit_is_clear(PINB, SW1) | ||
+ | |||
+ | /* na cakanie su preddefinovane slucky */ | ||
+ | // loop_until_bit_is_set(PINB, SW1); // cakanie na uvolnenie tlacitka | ||
+ | // loop_until_bit_is_clear(PINB, SW1); // cakanie na stlacenie tlacitka | ||
+ | |||
+ | |||
+ | #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 * 16UL))) - 1) // vzor?ek z datasheetu | ||
+ | |||
+ | void hw_init( void ); | ||
+ | void uart_init( void ); | ||
+ | |||
+ | /* Following definition is compatible with STDIO.H, for more | ||
+ | * information see https://www.appelsiini.net/2011/simple-usart-with-avr-libc/ | ||
+ | */ | ||
+ | |||
+ | int uart_putc( char c, FILE *stream ); | ||
+ | void uart_puts( const char *s ); | ||
+ | |||
+ | char uart_getc( void ); | ||
+ | |||
+ | void delay(int delay); | ||
+ | |||
+ | #endif /* UART_H_ */ | ||
</source></tab> | </source></tab> | ||
− | <tab name=" | + | |
+ | <tab name="uart.c"><source lang="c++" style="background: LightYellow;"> | ||
+ | /* ************************************************************************* */ | ||
+ | /* FileName: uart.c */ | ||
+ | /* ************************************************************************* */ | ||
+ | |||
#include <avr/io.h> | #include <avr/io.h> | ||
+ | #include <util/delay.h> | ||
+ | #include "uart.h" | ||
+ | |||
+ | void hw_init( void ) | ||
+ | { | ||
+ | DDRB |= (1<<LED); // PORTB.5 kde je LED ma byt OUTPUT | ||
+ | /* sem si mozete dopisat svoje vlastne inicializacne prikazy */ | ||
+ | } | ||
+ | |||
+ | void uart_init( void ) | ||
+ | { | ||
+ | // for different BAUD rate change the project settings, or uncomment | ||
+ | // following two lines: | ||
+ | // #undef BAUD // avoid compiler warning | ||
+ | // #define BAUD 115200 | ||
+ | |||
+ | #include <util/setbaud.h> // requires defined BAUD | ||
+ | |||
+ | UBRR0H = UBRRH_VALUE; | ||
+ | UBRR0L = UBRRL_VALUE; | ||
+ | #if USE_2X // defined in setbaud.h | ||
+ | UCSR0A |= (1 << U2X0); | ||
+ | #else | ||
+ | UCSR0A &= ~(1 << U2X0); | ||
+ | #endif | ||
+ | |||
+ | |||
+ | UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */ | ||
+ | UCSR0B = _BV(RXEN0) | _BV(TXEN0); /* Enable RX and TX */ | ||
+ | } | ||
+ | |||
+ | |||
+ | int uart_putc( char c, FILE *stream ) | ||
+ | { | ||
+ | if (c == '\n') | ||
+ | uart_putc('\r',stream); | ||
+ | |||
+ | loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */ | ||
+ | UDR0 = c; | ||
+ | return 0; | ||
+ | } | ||
− | |||
− | + | void uart_puts(const char *s) | |
+ | { | ||
+ | /* toto je vasa uloha */ | ||
+ | } | ||
+ | |||
+ | char uart_getc(void) | ||
+ | { | ||
+ | loop_until_bit_is_set(UCSR0A, RXC0); /* Wait until data exists. */ | ||
+ | return UDR0; | ||
+ | } | ||
+ | |||
+ | void delay(int delay) // vlastna funkcia pre dlhsie casy | ||
+ | { | ||
+ | for (int i=1; i<=delay; i++) | ||
+ | _delay_ms(1); | ||
+ | } | ||
</source></tab> | </source></tab> | ||
+ | |||
+ | |||
+ | |||
</tabs> | </tabs> | ||
− | |||
− | + | 1. main.c: | |
+ | - Inicializuje ADC, hardware a UART. | ||
+ | - Nastaví PWM na pin PD6. | ||
+ | - V nekonečnej slučke číta hodnotu z ADC, tlačí ju cez UART a nastavuje PWM podľa tejto hodnoty. | ||
+ | |||
+ | 2. adc.h a adc.c: | ||
+ | - `adc_init()` nastaví ADC. | ||
+ | - `adc_read(char a_pin)` číta hodnotu z daného ADC kanála. | ||
+ | |||
+ | 3. uart.h a uart.c: | ||
+ | - `uart_init()` nastaví UART pre komunikáciu. | ||
+ | - `uart_putc(char c, FILE *stream)` posiela znak cez UART. | ||
+ | - `uart_getc()` prijíma znak cez UART. | ||
+ | Zdrojový kód: [[Médiá:PeterSzovics.zip|zdrojaky.zip]] | ||
=== Overenie === | === Overenie === | ||
− | + | Video reprezentácia funkčného zaraidenia. | |
− | + | [[Súbor:sklapka.jpg|550px|thumb|center|Aplikácia.]] | |
− | |||
− | [[Súbor: | ||
'''Video:''' | '''Video:''' | ||
<center><youtube>_bB7sJQAfE8</youtube></center> | <center><youtube>_bB7sJQAfE8</youtube></center> | ||
− | + | ||
[[Category:AVR]] [[Category:MIPS]] | [[Category:AVR]] [[Category:MIPS]] |
Aktuálna revízia z 10:40, 29. máj 2024
Záverečný projekt predmetu MIPS / LS2024 - Peter Szovics
Zadanie
Zostrojte a naprogramujte ovladanie škrtiacej klapky pomocou plynového pedálu.
Literatúra:
Analýza a opis riešenia
Mojou témou semestrálnej práce je ovládanie škrtiacej klapky pomocou plynového pedálu. Zapojenie a vypracovanie projektu je inšpirované cvičením 8: (http://senzor.robotika.sk/sensorwiki/index.php/A/D_prevodn%C3%ADk).
Súčiastky a diely ktoré boli použité na zostrojenie projektu:
• elektronický plynový pedál (1K2 721 503 AJ)
• elektronická škrtiaca klapka (047 133 062)
• sacie potrubie (047 129 743 G)
• arduino r3 doska (Microchip ATmega328P)
• adaptér 230V/9V (ASSA107E-090100)
• napatovy stabilizator (7805)
• mosfet transistor (IRF540N)
• rezistory 1kΩ, 220Ω
• breadboard (MB-102 830/400)
• duPont káble M-M - 40x, 40 cm
Presný opis fungovania elektrického obvodu:
V akej pozícií je pedál toľko energie sa vysiela na pohon škrtiacej klapky, v našom prípade s aktuálnym zapojením sa klapka začne hýbať až po prekročení 40% zatlačenia pedálu, aby sme predišli tomuto neefektívnemu ovládaniu a chceliť docieliť identický pohyb klapky a pedálu tak som pre budúce vylepšovanie do projektu zakomponoval aj predprípravu (arduino výstup A3, A1 a A2) na spätnoväzobný regulátor aby klapka presne kopírovala polohu pedálu.
Na obrázku je vyobrazená schéma zapojenia elektronického plynového pedála pre Arduino. Popis jednotlivých častí:
1. Napájanie:
- Sieťový adaptér (230V/9V) je pripojený k stabilizátoru napätia 7805, ktorý redukuje napätie na 5V pre Arduino.
2. Ovládanie motora:
- Motor (škrtacia klapka) sú pripojené k Mosfet tranzistoru IRF540N, ktorý slúži ako spínač pre ovládanie motora. - Gate (G) tranzistora je riadený z pinu D6 Arduina cez rezistor R1 (1kΩ).
3. Snímanie polohy pedála:
- Elektronický plynový pedál má v sebe dva potenciometre pripojené k analógovým vstupom Arduina (A4). - Posuvné kontakty potenciometrov sú napájané 5V a zemou, poskytujúce variabilný výstupný signál podľa stlačenia pedála.
4. Ochranné prvky:
- Dióda D1 je chránená rezistorom R2. - Rezistor R1 je pridaný pre ochranu pinu D6 Arduina pred nadmerným prúdom.
Vizuálna reprezentácia PWM (Pulse width modulation), šírka impulzu sa mení podľa závislosti zatlačenia pedálu.
Algoritmus a program
Celý kód som použil z 8 cvičenia, kde sme sa mohli naučiť ovládať ledku pomocou PWM, kód je napísaný v jednom .c súbore – na spustenie treba 4 knižnice.
#include <avr/io.h>
#include "uart.h"
#define F_CPU 16000000UL
#define BAUDRATE 9600
#include <stdio.h>
FILE mystdout = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);
int main(void)
{
adc_init();
hw_init();
uart_init();
stdout = &mystdout;
unsigned int measuredValue;
DDRD|=(1<<PD6);
TCNT0=0;
OCR0A=0;
TCCR0A|=(1<<COM0A1)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
TCCR0B|=(1<<CS02)|(1<<CS00);
while(1)
{
measuredValue = adc_read(4);
printf("hodnota: %04d \r",measuredValue);
OCR0A=measuredValue/4;
}
return(0);
}
#include <avr/io.h>
void adc_init(void);
unsigned int adc_read(char a_pin);
#include <stdio.h>
#include "adc.h"
void adc_init(void) {
ADMUX = (1 << REFS0); // reference voltage set to AVcc
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // enable ADC and set prescaler to 128
}
unsigned int adc_read(char a_pin) {
a_pin &= 0x07; // limit input to 0-7
ADMUX = (ADMUX & 0xF8) | a_pin; // select ADC channel with safety mask
ADCSRA |= (1 << ADSC); // start conversion
while (ADCSRA & (1 << ADSC)); // wait for conversion to complete
return ADC; // return the ADC value
}
/* ************************************************************************* */
/* FileName: uart.h */
/* ************************************************************************* */
#define LED PB5 // internal on-board LED
/* na testovanie su uz zadefinovane */
// bit_is_set(PINB, SW1)
// bit_is_clear(PINB, SW1)
/* na cakanie su preddefinovane slucky */
// loop_until_bit_is_set(PINB, SW1); // cakanie na uvolnenie tlacitka
// loop_until_bit_is_clear(PINB, SW1); // cakanie na stlacenie tlacitka
#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 * 16UL))) - 1) // vzor?ek z datasheetu
void hw_init( void );
void uart_init( void );
/* Following definition is compatible with STDIO.H, for more
* information see https://www.appelsiini.net/2011/simple-usart-with-avr-libc/
*/
int uart_putc( char c, FILE *stream );
void uart_puts( const char *s );
char uart_getc( void );
void delay(int delay);
#endif /* UART_H_ */
/* ************************************************************************* */
/* FileName: uart.c */
/* ************************************************************************* */
#include <avr/io.h>
#include <util/delay.h>
#include "uart.h"
void hw_init( void )
{
DDRB |= (1<<LED); // PORTB.5 kde je LED ma byt OUTPUT
/* sem si mozete dopisat svoje vlastne inicializacne prikazy */
}
void uart_init( void )
{
// for different BAUD rate change the project settings, or uncomment
// following two lines:
// #undef BAUD // avoid compiler warning
// #define BAUD 115200
#include <util/setbaud.h> // requires defined BAUD
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
#if USE_2X // defined in setbaud.h
UCSR0A |= (1 << U2X0);
#else
UCSR0A &= ~(1 << U2X0);
#endif
UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */
UCSR0B = _BV(RXEN0) | _BV(TXEN0); /* Enable RX and TX */
}
int uart_putc( char c, FILE *stream )
{
if (c == '\n')
uart_putc('\r',stream);
loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
UDR0 = c;
return 0;
}
void uart_puts(const char *s)
{
/* toto je vasa uloha */
}
char uart_getc(void)
{
loop_until_bit_is_set(UCSR0A, RXC0); /* Wait until data exists. */
return UDR0;
}
void delay(int delay) // vlastna funkcia pre dlhsie casy
{
for (int i=1; i<=delay; i++)
_delay_ms(1);
}
1. main.c:
- Inicializuje ADC, hardware a UART. - Nastaví PWM na pin PD6. - V nekonečnej slučke číta hodnotu z ADC, tlačí ju cez UART a nastavuje PWM podľa tejto hodnoty.
2. adc.h a adc.c:
- `adc_init()` nastaví ADC. - `adc_read(char a_pin)` číta hodnotu z daného ADC kanála.
3. uart.h a uart.c:
- `uart_init()` nastaví UART pre komunikáciu. - `uart_putc(char c, FILE *stream)` posiela znak cez UART. - `uart_getc()` prijíma znak cez UART.
Zdrojový kód: zdrojaky.zip
Overenie
Video reprezentácia funkčného zaraidenia.
Video: