Operácie

Elektronická škrtiaca klapka: Rozdiel medzi revíziami

Z SensorWiki

(Algoritmus a program)
(Algoritmus a program)
Riadok 51: Riadok 51:
  
 
<tabs>
 
<tabs>
<tab name="AVR C-code"><source lang="c++" style="background: LightYellow;">
+
<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"
#define F_CPU 16000000UL
+
volatile uint16_t distance = 0; //tu budeme ukladat vzdialenost, ako cele cislo o velkosti 16 bitov
#define BAUDRATE      9600
 
#include <stdio.h>
 
 
FILE mystdout = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);
 
FILE mystdout = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);
                             
 
int main(void)
 
{
 
  adc_init();
 
  hw_init();
 
  uart_init();
 
  stdout = &mystdout;          // printf() works from now
 
  unsigned int measuredValue;
 
  
  DDRD|=(1<<PD6);       // Init PD5 and PD6 pins as output
+
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
 +
}
  
  //Initialize Timer0
+
uint16_t measure_pulse_width() {
 +
    uint16_t pulse_width = 0;
 +
    uint16_t timeout = 50000; // Aby sme nesli donekonecna
  
  TCNT0=0;                        // Set Initial Timer value
+
    // Caka na Echo pin, kym bude na vysokej urovni
 +
    while (!(PINB & (1 << PB2)) && timeout--) {
 +
        _delay_us(1);
 +
    }
  
  OCR0A=0;                      // Set Initial Pulse width
+
    // Mera dlzku signalu
 
+
    while ((PINB & (1 << PB2)) && timeout--) {
 +
        _delay_us(1);
 +
        pulse_width++;
 +
    }
  
                                //Set fast PWM mode + clear OC0A and set OC0B on compare match
+
    // Vypocitame vzdialenost v cm
 +
    uint16_t distance = pulse_width / 41;
 +
    return distance;
 +
}
  
  TCCR0A|=(1<<COM0A1)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
+
int main(void) {
 
+
    DDRB |= (1 << PB1); // Nastavi Trig pin ako vystup
  TCCR0B|=(1<<CS02)|(1<<CS00);     // Set prescaller 1024 and start timer
+
    DDRB &= ~(1 << PB2); // Nastavi Echo pin ako vstup
 
+
PORTB |= (1 << PB2); // Ovladanie pull-up rezistoru
  while(1)
+
  {
+
hw_init();
measuredValue = adc_read(4);
+
    uart_init();
printf("hodnota: %04d \r",measuredValue);
+
    stdout= &mystdout;
 
 
OCR0A=measuredValue/4;
+
    while (1) {
  }
+
        trigger_pulse(); // Posle signal na senzor
 
+
uint16_t distance = measure_pulse_width(); // Merame vzdialenost a vypocitame ju v cm
  return(0);
+
        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="filename.h"><source lang="c++" style="background: LightYellow;">
+
<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);
 +
}
  
void adc_init(void);                                  // A/D converter initialization
 
  
unsigned int adc_read(char a_pin);
 
 
</source></tab>
 
</source></tab>
 
</tabs>
 
</tabs>
 
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: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]]
 
Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]]
  

Verzia zo dňa a času 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.



Vývojová doska Arduino UNO R3

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.

ELEKTRONICKÁ SCHÉMA

Vizuálna reprezentácia PWM (Pulse width modulation), šírka impulzu sa mení podla závislosti zatlačenia pedálu.

ZÁZNAM Z OSCILOSKOPU


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.

Aplikácia.

Video:

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