Elektronická škrtiaca klapka: Rozdiel medzi revíziami
Z SensorWiki
(→Algoritmus a program) |
(→Algoritmus a program) |
||
Riadok 54: | Riadok 54: | ||
#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 | + | #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 67: | Riadok 68: | ||
unsigned int measuredValue; | unsigned int measuredValue; | ||
− | DDRD|=(1<<PD6); | + | DDRD |= (1 << PD6); // PD6 as output (OC0A) |
− | TCNT0=0; | + | TCNT0 = 0; // initialize counter value |
− | OCR0A=0; | + | OCR0A = 0; // initialize OCR0A value |
− | TCCR0A|=(1<<COM0A1)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM00); | + | TCCR0A |= (1 << COM0A1) | (1 << COM0B1) | (1 << WGM01) | (1 << WGM00); // set fast PWM mode and non-inverting mode |
− | + | TCCR0B |= (1 << CS02) | (1 << CS00); // set prescaler to 1024 | |
− | TCCR0B|=(1<<CS02)|(1<<CS00); | ||
while(1) | while(1) | ||
{ | { | ||
− | + | measuredValue = adc_read(4); // read ADC from channel 4 | |
− | + | printf("hodnota: %04d \r", measuredValue); | |
− | + | ||
− | + | OCR0A = measuredValue / 4; // adjust PWM duty cycle | |
} | } | ||
− | return | + | return 0; |
} | } | ||
+ | </source></tab> | ||
− | |||
− | |||
<tab name="adc.h"><source lang="c++" style="background: LightYellow;"> | <tab name="adc.h"><source lang="c++" style="background: LightYellow;"> | ||
#include <avr/io.h> | #include <avr/io.h> | ||
void adc_init(void); | void adc_init(void); | ||
− | |||
unsigned int adc_read(char a_pin); | unsigned int adc_read(char a_pin); | ||
</source></tab> | </source></tab> | ||
+ | |||
<tab name="adc.c"><source lang="c++" style="background: LightYellow;"> | <tab name="adc.c"><source lang="c++" style="background: LightYellow;"> | ||
#include <stdio.h> | #include <stdio.h> | ||
#include "adc.h" | #include "adc.h" | ||
− | void adc_init(void){ | + | 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){ | + | 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;"> | ||
+ | #ifndef UART_H | ||
+ | #define UART_H | ||
+ | |||
+ | #include <avr/io.h> | ||
+ | |||
+ | void uart_init(void); | ||
+ | int uart_putc(char c, FILE *stream); | ||
+ | |||
+ | #endif // UART_H | ||
+ | </source></tab> | ||
+ | |||
+ | <tab name="uart.c"><source lang="c++" style="background: LightYellow;"> | ||
+ | #include "uart.h" | ||
+ | |||
+ | void uart_init(void) { | ||
+ | // Set baud rate | ||
+ | uint16_t baudrate = (F_CPU / (16UL * BAUDRATE)) - 1; | ||
+ | UBRR0H = (uint8_t)(baudrate >> 8); | ||
+ | UBRR0L = (uint8_t)baudrate; | ||
+ | |||
+ | // Enable transmitter | ||
+ | UCSR0B = (1 << TXEN0); | ||
+ | |||
+ | // Set frame format: 8 data bits, 1 stop bit | ||
+ | UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); | ||
+ | } | ||
+ | |||
+ | int uart_putc(char c, FILE *stream) { | ||
+ | if (c == '\n') { | ||
+ | uart_putc('\r', stream); | ||
+ | } | ||
+ | while (!(UCSR0A & (1 << UDRE0))); // Wait until the buffer is empty | ||
+ | UDR0 = c; | ||
+ | return 0; | ||
+ | } | ||
+ | </source></tab> | ||
+ | |||
+ | <tab name="uarth.h"><source lang="c++" style="background: LightYellow;"> | ||
+ | #ifndef UARTH_H | ||
+ | #define UARTH_H | ||
+ | |||
+ | #include <avr/io.h> | ||
+ | |||
+ | void uart_init(void); | ||
+ | int uart_putc(char c, FILE *stream); | ||
+ | int uart_getc(FILE *stream); | ||
+ | |||
+ | #endif // UARTH_H | ||
+ | </source></tab> | ||
+ | |||
</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 zo dňa a času 18:30, 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
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.
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"
#include "uarth.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); // PD6 as output (OC0A)
TCNT0 = 0; // initialize counter value
OCR0A = 0; // initialize OCR0A value
TCCR0A |= (1 << COM0A1) | (1 << COM0B1) | (1 << WGM01) | (1 << WGM00); // set fast PWM mode and non-inverting mode
TCCR0B |= (1 << CS02) | (1 << CS00); // set prescaler to 1024
while(1)
{
measuredValue = adc_read(4); // read ADC from channel 4
printf("hodnota: %04d \r", measuredValue);
OCR0A = measuredValue / 4; // adjust PWM duty cycle
}
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
}
#ifndef UART_H
#define UART_H
#include <avr/io.h>
void uart_init(void);
int uart_putc(char c, FILE *stream);
#endif // UART_H
#include "uart.h"
void uart_init(void) {
// Set baud rate
uint16_t baudrate = (F_CPU / (16UL * BAUDRATE)) - 1;
UBRR0H = (uint8_t)(baudrate >> 8);
UBRR0L = (uint8_t)baudrate;
// Enable transmitter
UCSR0B = (1 << TXEN0);
// Set frame format: 8 data bits, 1 stop bit
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
}
int uart_putc(char c, FILE *stream) {
if (c == '\n') {
uart_putc('\r', stream);
}
while (!(UCSR0A & (1 << UDRE0))); // Wait until the buffer is empty
UDR0 = c;
return 0;
}
#ifndef UARTH_H
#define UARTH_H
#include <avr/io.h>
void uart_init(void);
int uart_putc(char c, FILE *stream);
int uart_getc(FILE *stream);
#endif // UARTH_H
</source></tab>
Zdrojový kód: zdrojaky.zip
Overenie
Video reprezentácia funkčného zaraidenia.
Video: