Operácie

Elektronická škrtiaca klapka: Rozdiel medzi revíziami

Z SensorWiki

(Algoritmus a program)
(Algoritmus a program)
 
(22 medziľahlých úprav od 2 ďalších používateľov nie je zobrazených)
Riadok 40: Riadok 40:
  
 
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.  
 
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|500px|thumb|center|ELEKTRONICKÁ SCHÉMA]]
+
[[Súbor:Photo_2024-05-19_23-52-06.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.
  
 +
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, jeden z nich je pripojeny k analógovému vstupu 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:
 +
  - 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.
 
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]]
 
[[Súbor:Osciloskopp.jpg|800px|thumb|center|ZÁZNAM Z OSCILOSKOPU]]
Riadok 54: Riadok 74:
 
#include <avr/io.h>
 
#include <avr/io.h>
 
#include "uart.h"
 
#include "uart.h"
#include "uarth.h"
 
 
#define F_CPU 16000000UL
 
#define F_CPU 16000000UL
#define BAUDRATE 9600
+
#define BAUDRATE       9600
 
#include <stdio.h>
 
#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)
 
int main(void)
 
{
 
{
Riadok 65: Riadok 84:
 
   hw_init();
 
   hw_init();
 
   uart_init();
 
   uart_init();
   stdout = &mystdout;        
+
   stdout = &mystdout;           // printf() works from now
 
   unsigned int measuredValue;
 
   unsigned int measuredValue;
  
   DDRD |= (1 << PD6); // PD6 as output (OC0A)
+
   DDRD|=(1<<PD6);       // Init PD5 and PD6 pins as output
  
  TCNT0 = 0; // initialize counter value
 
  
   OCR0A = 0; // initialize OCR0A value
+
  //Initialize Timer0
                             
+
 
   TCCR0A |= (1 << COM0A1) | (1 << COM0B1) | (1 << WGM01) | (1 << WGM00); // set fast PWM mode and non-inverting mode
+
  TCNT0=0;                        // Set Initial Timer value
   TCCR0B |= (1 << CS02) | (1 << CS00); // set prescaler to 1024
+
 
 +
   OCR0A=0;                       // Set Initial Pulse width
 +
 
 +
 
 +
                                //Set fast PWM mode + clear OC0A and set OC0B on compare match
 +
 
 +
   TCCR0A|=(1<<COM0A1)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
 +
 
 +
   TCCR0B|=(1<<CS02)|(1<<CS00);     // Set prescaller 1024 and start timer
 
    
 
    
 
   while(1)
 
   while(1)
 
   {
 
   {
    measuredValue = adc_read(4); // read ADC from channel 4
+
measuredValue = (adc_read(4)-150)/2;
    printf("hodnota: %04d \r", measuredValue);
+
// measuredValue = adc_read(4);
   
+
printf("hodnota: %04d \r",measuredValue);
    OCR0A = measuredValue / 4; // adjust PWM duty cycle
+
 +
 +
  OCR0A = measuredValue;
 +
     
 
   }
 
   }
 
    
 
    
   return 0;
+
   return(0);
 
}
 
}
 +
 +
 
</source></tab>
 
</source></tab>
 +
  
 
<tab name="adc.h"><source lang="c++" style="background: LightYellow;">
 
<tab name="adc.h"><source lang="c++" style="background: LightYellow;">
Riadok 115: Riadok 147:
  
 
<tab name="uart.h"><source lang="c++" style="background: LightYellow;">
 
<tab name="uart.h"><source lang="c++" style="background: LightYellow;">
#ifndef UART_H
+
/* ************************************************************************* */
#define UART_H
+
/* 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 );
  
#include <avr/io.h>
+
void delay(int delay);
  
void uart_init(void);
+
#endif /* UART_H_ */
int uart_putc(char c, FILE *stream);
 
  
#endif // UART_H
 
 
</source></tab>
 
</source></tab>
  
 
<tab name="uart.c"><source lang="c++" style="background: LightYellow;">
 
<tab name="uart.c"><source lang="c++" style="background: LightYellow;">
 +
/* ************************************************************************* */
 +
/* FileName:            uart.c                                              */
 +
/* ************************************************************************* */
 +
 +
#include <avr/io.h>
 +
#include <util/delay.h>
 
#include "uart.h"
 
#include "uart.h"
  
void uart_init(void) {
+
void hw_init( void )
   // Set baud rate
+
{  
   uint16_t baudrate = (F_CPU / (16UL * BAUDRATE)) - 1;
+
   DDRB |= (1<<LED);    // PORTB.5 kde je LED ma byt OUTPUT
  UBRR0H = (uint8_t)(baudrate >> 8);
+
   /* sem si mozete dopisat svoje vlastne inicializacne prikazy */
  UBRR0L = (uint8_t)baudrate;
+
}
  
  // Enable transmitter
+
void uart_init( void )
  UCSR0B = (1 << TXEN0);
+
{
 +
// 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
  
   // Set frame format: 8 data bits, 1 stop bit
+
 
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
+
    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;
 
}
 
}
  
int uart_putc(char c, FILE *stream) {
+
 
   if (c == '\n') {
+
void uart_puts(const char *s)
     uart_putc('\r', stream);
+
{
  }
+
   /* toto je vasa uloha */
  while (!(UCSR0A & (1 << UDRE0))); // Wait until the buffer is empty
+
}
  UDR0 = c;
+
 
  return 0;
+
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>
 +
 +
 +
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.
  
</source></tab>
+
3. uart.h a uart.c:
</tabs>
+
  - `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á:projektMenoPriezvisko.zip|zdrojaky.zip]]
+
Zdrojový kód: [[Médiá:MIPS1222.rar|zdrojaky.zip]]
  
 
=== Overenie ===
 
=== Overenie ===
  
 
Video reprezentácia funkčného zaraidenia.
 
Video reprezentácia funkčného zaraidenia.
[[Súbor:sklapka.jpg|550px|thumb|center|Aplikácia.]]
+
[[Súbor:Att.KX9vnEKu5l_coOQ2CEwbKsRA8lDHTEhfffUkBEqYaI8.jpg|550px|thumb|center|Aplikácia.]]
  
 
'''Video:'''
 
'''Video:'''
<center><youtube>_bB7sJQAfE8</youtube></center>
+
<center><youtube>=l0TCoHRCahY&ab</youtube></center>
  
  
  
 
[[Category:AVR]] [[Category:MIPS]]
 
[[Category:AVR]] [[Category:MIPS]]

Aktuálna revízia z 21:29, 1. jún 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

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.

ELEKTRONICKÁ SCHÉMA


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, jeden z nich je pripojeny k analógovému vstupu 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:

  - 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.

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 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;           // printf() works from now
  unsigned int measuredValue;

  DDRD|=(1<<PD6);        // Init PD5 and PD6 pins as output


  //Initialize Timer0

  TCNT0=0;                        // Set Initial Timer value

  OCR0A=0;                       // Set Initial Pulse width
  

                                 //Set fast PWM mode + clear OC0A and set OC0B on compare match

  TCCR0A|=(1<<COM0A1)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM00);

  TCCR0B|=(1<<CS02)|(1<<CS00);      // Set prescaller 1024 and start timer
  
  while(1)
  {
	measuredValue = (adc_read(4)-150)/2;
//	measuredValue = adc_read(4);
	printf("hodnota: %04d \r",measuredValue);
	
	
	   OCR0A = measuredValue;
	      
  }
  
  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.

Aplikácia.

Video: