Elektronická škrtiaca klapka: Rozdiel medzi revíziami
Zo stránky SensorWiki
Riadok 51: | Riadok 51: | ||
<tabs> | <tabs> | ||
<tab name=" | <tab name="semestralny-projekt"><source lang="c++" style="background: LightYellow;"> | ||
#include <avr/io.h> | #include <avr/io.h> | ||
#include <util/delay.h> | |||
#include <stdio.h> | |||
#include "uart.h" | #include "uart.h" | ||
volatile uint16_t distance = 0; //tu budeme ukladat vzdialenost, ako cele cislo o velkosti 16 bitov | |||
FILE mystdout = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE); | FILE mystdout = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE); | ||
void UART_Transmit(unsigned char data) { | |||
while (!(UCSR0A & (1<<UDRE0))); // Caka na prazdny buffer | |||
UDR0 = data; | |||
} | |||
void trigger_pulse() { | |||
PORTB |= (1 << PB1); // Nastavi Trig pin na vysoku uroven | |||
_delay_us(10); // Caka 10 mikrosekund | |||
PORTB &= ~(1 << PB1); // Nastavi Trig pin na nizku uroven | |||
} | |||
uint16_t measure_pulse_width() { | |||
uint16_t pulse_width = 0; | |||
uint16_t timeout = 50000; // Aby sme nesli donekonecna | |||
// Caka na Echo pin, kym bude na vysokej urovni | |||
while (!(PINB & (1 << PB2)) && timeout--) { | |||
_delay_us(1); | |||
} | |||
// Mera dlzku signalu | |||
while ((PINB & (1 << PB2)) && timeout--) { | |||
_delay_us(1); | |||
pulse_width++; | |||
} | |||
// Vypocitame vzdialenost v cm | |||
uint16_t distance = pulse_width / 41; | |||
return distance; | |||
} | |||
int main(void) { | |||
DDRB |= (1 << PB1); // Nastavi Trig pin ako vystup | |||
DDRB &= ~(1 << PB2); // Nastavi Echo pin ako vstup | |||
PORTB |= (1 << PB2); // Ovladanie pull-up rezistoru | |||
hw_init(); | |||
uart_init(); | |||
stdout= &mystdout; | |||
while (1) { | |||
trigger_pulse(); // Posle signal na senzor | |||
uint16_t distance = measure_pulse_width(); // Merame vzdialenost a vypocitame ju v cm | |||
printf("Vzdialenost: %d cm\n", distance); // Vypiseme vzdialenost cez napr. Putty | |||
_delay_ms(500); // Pockame pred dalsim meranim | |||
} | |||
return 0; | |||
} | } | ||
</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> | ||
Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]] | Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]] | ||
Verzia z 17:37, 26. 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
Témou mojej semestrálnej práce som si vybral 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:
Adaptér zapojený do siete konvertuje 230V AC na 9V DC,
V akej pozícií je pedál toľko energie sa vysiela na pohon škrtiacej klapky, preto 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 spatnovazobný regulátor aby Škrtiaca klapka presne kopírovala polohu pedálu.
Vizuálna reprezentácia PWM (Pulse width modulation), šírka impulzu sa mení podla 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 2 knižnice.
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include "uart.h"
volatile uint16_t distance = 0; //tu budeme ukladat vzdialenost, ako cele cislo o velkosti 16 bitov
FILE mystdout = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);
void UART_Transmit(unsigned char data) {
while (!(UCSR0A & (1<<UDRE0))); // Caka na prazdny buffer
UDR0 = data;
}
void trigger_pulse() {
PORTB |= (1 << PB1); // Nastavi Trig pin na vysoku uroven
_delay_us(10); // Caka 10 mikrosekund
PORTB &= ~(1 << PB1); // Nastavi Trig pin na nizku uroven
}
uint16_t measure_pulse_width() {
uint16_t pulse_width = 0;
uint16_t timeout = 50000; // Aby sme nesli donekonecna
// Caka na Echo pin, kym bude na vysokej urovni
while (!(PINB & (1 << PB2)) && timeout--) {
_delay_us(1);
}
// Mera dlzku signalu
while ((PINB & (1 << PB2)) && timeout--) {
_delay_us(1);
pulse_width++;
}
// Vypocitame vzdialenost v cm
uint16_t distance = pulse_width / 41;
return distance;
}
int main(void) {
DDRB |= (1 << PB1); // Nastavi Trig pin ako vystup
DDRB &= ~(1 << PB2); // Nastavi Echo pin ako vstup
PORTB |= (1 << PB2); // Ovladanie pull-up rezistoru
hw_init();
uart_init();
stdout= &mystdout;
while (1) {
trigger_pulse(); // Posle signal na senzor
uint16_t distance = measure_pulse_width(); // Merame vzdialenost a vypocitame ju v cm
printf("Vzdialenost: %d cm\n", distance); // Vypiseme vzdialenost cez napr. Putty
_delay_ms(500); // Pockame pred dalsim meranim
}
return 0;
}
/* ************************************************************************* */
/* 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);
}
Zdrojový kód: zdrojaky.zip
Overenie
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 záverečnej obrazovky pred resetom. Vypísaný je tu priemerný čas a najlepší čas.
Video:
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.