Riadenie polohy klapky klimatizácie: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
Bez shrnutí editace |
||
(20 medziľahlých úprav od rovnakého používateľa nie je zobrazených.) | |||
Riadok 4: | Riadok 4: | ||
== Zadanie == | == Zadanie == | ||
Úlohou tohto zadania je riadenie polohy klapky klimatizácie, ktorá sa bežne používa v dnešných automobiloch. | Úlohou tohto zadania je riadenie polohy klapky klimatizácie, ktorá sa bežne používa v dnešných automobiloch. Zariadenie nie je tak celkom klapka, ale mechanizmus, ktorý klapku ovláda. Ten sa skladá z viacerých častí. Budeme ho používať v spolupráci s vývojovou doskou Acrob s mikroprocesorom ATmega328P. | ||
[[Obrázok: | [[Obrázok:klapka.jpg|400px|thumb|center|Mechanizmus ovládania klapky klimatizácie, ktorý budem používať.]] | ||
'''Literatúra:''' | '''Literatúra:''' | ||
* [ | * [https://datasheetspdf.com/pdf-down/R/F/-/RF-370CB-Mabuchi.pdf] - datasheet k motorčeku, ktorý je použitý v klapke | ||
Riadok 17: | Riadok 17: | ||
== Analýza a opis riešenia == | == Analýza a opis riešenia == | ||
Mechanizmus ovládania klapky klimatizácie je zložený z DC motorčeka, potenciometra a súkolia na prevod. My budeme ovládať daný systém jedným potenciometrom, ale ako? Chceme zostrojiť kód na ovládanie polohy DC motora s použitím dvoch potenciometrov: jeden na nastavenie želanej polohy a druhý na snímanie aktuálnej polohy motora. | |||
Takto vyzerá mechanizmus ovládania klapky vnútri. Môžeme tam vidieť obyčajný jednosmerný motor s filmovým kondenzátorom, šnekový prevod(na zabránenie voči samovoľnému pohybu klapky) so súkolím, na ktorého poslednom koliečku je snímací potenciometer. Tento obvod funguje sám o sebe ako regulačný obvod. | |||
[[Súbor:vnutro.jpg|400px|thumb|center|Vnútro ovládacieho mechanizmu Mahle.]] | |||
Schéma zapojenia je zobrazená na obrázku nižšie: | |||
[[Súbor:schma.jpg|400px|thumb|center|Schéma zapojenia celého obvodu.]] | |||
'''Inicializácia:''' | |||
Na začiatku programu si zavoláme všetky potrebné knižnice, ktoré budeme využívať, definujeme a nastavíme piny a inicializujeme všetky potrebné periférie, teda A/D prevodník. | |||
'''A/D prevod:''' | |||
Princíp riešenia je vskutku jednoduchý. Budem používať A/D prevodník na prevod analógového signálu z potenciometrov na digitálny signál, vhodný pre spracovanie. Takže prvý princíp je cez A/D prevod spracovať informáciu z oboch potenciometrov a uložiť ich do nejakej premennej. S touto informáciou môžeme ďalej pracovať. | |||
'''Rozdiel polôh:''' | |||
Ďalším krokom je tieto dve hodnoty od seba odčítať, čím získame rozdiel polôh. Vzhľadom na tento rozdiel definujeme stavy, ak bude rozdiel kladný, tak premenná nadobudne hodnotu 1, záporný = -1 alebo nulový/minimálny = 0. Následne budeme túto hodnotu potrebovať pri podmienkach pre smer otáčania motora. | |||
'''Smer otáčania:''' | |||
Hodnotu, ktorú získame z porovnávania použijeme v princípe smeru otáčania motora. Pre jednotlivé hodnoty definujeme smer, teda ak bude premenná rozdielu polohy kladná, motor sa bude otáčať do jednej strany, ak záporná tak do opačnej, a ak 0, tak bude stáť. Celý tento program beží v cykle while, takže mikropočítač neustále porovnáva hodnoty potenciometrov a snaží sa dosiahnuť ustálený stav motora. | |||
'''Úprava kódu:''' | |||
Pre úhľadnosť a jednoduchosť kódu jednotlivé procesy ako A/D prevod a smer otáčania motora napíšem do vedľajších súborov, pripíšem knižnice a budem jednotlivé funkcie jednoducho volať z hlavného programu. | |||
=== Algoritmus a program === | === Algoritmus a program === | ||
Celý program pozostáva s viacerých súborov/knižníc. Pre funkciu motora som si vytvoril osobitný kód, ktorý budem volať funkciou v hlavnej slučke. Rovnako s funkciou A/D prevodníka. | |||
<tabs> | <tabs> | ||
<tab name=" | <tab name="main"><source lang="c++" style="background: LightYellow;"> | ||
#include <avr/io.h> | #include <avr/io.h> | ||
#include <util/delay.h> | |||
#include "adc.h" | |||
#include "motor.h" | |||
// Nastavenie pinov | |||
#define nastav_poten 0 | |||
#define snim_poten 1 | |||
#define motor_pin1 PB4 | |||
#define motor_pin2 PB5 | |||
int main(void) { | |||
// Inicializácia ADC | |||
adc_init(); | |||
// Nastavenie pinov motora ako výstup | |||
DDRB |= (1 << motor_pin1) | (1 << motor_pin2); | |||
while (1) { | |||
// Želaná poloha z nastavovacieho potenciometra | |||
uint16_t pozicia_nastav = adc_read(nastav_poten); | |||
// Aktuálna poloha z potenciometra pre spätnú väzbu | |||
uint16_t pozicia_snim = adc_read(snim_poten); | |||
// Rozdiel medzi želanou a aktuálnou polohou | |||
int rozdiel_pozicie = pozicia_snim-pozicia_nastav; | |||
// Ak je rozdiel velký, otácaj motorom | |||
if (rozdiel_pozicie > 10) { | |||
smer_otacania(1); // Otácaj v jednom smere | |||
} else if (rozdiel_pozicie < -10) { | |||
smer_otacania(-1); // Otácaj v opacnom smere | |||
} else { | |||
smer_otacania(0); // Zastav motor | |||
} | |||
// Krátka pauza pre stabilitu | |||
_delay_ms(100); | |||
} | |||
} | } | ||
</source></tab> | </source></tab> | ||
<tab name=" | <tab name="adc.c"><source lang="c++" style="background: LightYellow;"> | ||
#include <avr/io.h> | #include <avr/io.h> | ||
void adc_init(void); | void adc_init(void){ | ||
ADMUX = (1<<REFS0); | |||
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); | |||
} | |||
unsigned int adc_read(char a_pin){ | |||
a_pin &= 0x07; | |||
ADMUX = (ADMUX & 0xF8) | a_pin; | |||
ADCSRA |= (1<<ADSC); | |||
while(ADCSRA & (1<<ADSC)); | |||
return(ADC); | |||
} | |||
</source></tab> | |||
<tab name="adc.h"><source lang="c++" style="background: LightYellow;"> | |||
#ifndef INCFILE1_H_ | |||
#define INCFILE1_H_ | |||
#endif /* INCFILE1_H_ */ | |||
void adc_init(void); | |||
unsigned int adc_read(char a_pin); | unsigned int adc_read(char a_pin); | ||
</source></tab> | |||
<tab name="motor.c"><source lang="c++" style="background: LightYellow;"> | |||
#include <avr/io.h> | |||
// Nastavenie pinov pre motor | |||
#define motor_pin1 PB4 | |||
#define motor_pin2 PB5 | |||
// Nastavenie smeru otacania motora | |||
void smer_otacania(int smer) { | |||
if (smer == 1) { | |||
PORTB |= (1 << motor_pin1); | |||
PORTB &= ~(1 << motor_pin2); | |||
} else if (smer == -1) { | |||
PORTB |= (1 << motor_pin2); | |||
PORTB &= ~(1 << motor_pin1); | |||
} else { | |||
PORTB &= ~(1 << motor_pin1); | |||
PORTB &= ~(1 << motor_pin2); | |||
} | |||
} | |||
</source></tab> | |||
<tab name="motor.h"><source lang="c++" style="background: LightYellow;"> | |||
#ifndef INCFILE1_H_ | |||
#define INCFILE1_H_ | |||
#endif /* INCFILE1_H_ */ | |||
void smer_otacania(int smer); | |||
</source></tab> | </source></tab> | ||
</tabs> | </tabs> | ||
Zdrojový kód: [[Médiá: | Zdrojový kód je možné stiahnuť kliknutím na odkaz nižšie: | ||
Zdrojový kód: [[Médiá:projektPeterFedor.zip|zdrojovykod.zip]] | |||
=== Overenie === | === Overenie === | ||
Na | Na koniec nahráme kód do mikroprocesora a môžeme testovať! Ako vidíme na videu, všetko funguje a klapka reaguje na zmenu polohy potenciometra. | ||
[[Súbor: | [[Súbor:mahleklapka.jpg|400px|thumb|center|Vývojová doska Acrob s potenciometrom a mechanizmom ovládania klapky Mahle]] | ||
'''Video:''' | '''Video:''' | ||
<center><youtube> | <center><youtube>aYvNehqQK18</youtube></center> | ||
Vypracoval: Peter Fedor 17.5.2024 :) | |||
[[Category:AVR]] [[Category:MIPS]] | [[Category:AVR]] [[Category:MIPS]] |
Aktuálna revízia z 22:13, 16. máj 2024
Záverečný projekt predmetu MIPS / LS2024 - Peter Fedor
Zadanie
Úlohou tohto zadania je riadenie polohy klapky klimatizácie, ktorá sa bežne používa v dnešných automobiloch. Zariadenie nie je tak celkom klapka, ale mechanizmus, ktorý klapku ovláda. Ten sa skladá z viacerých častí. Budeme ho používať v spolupráci s vývojovou doskou Acrob s mikroprocesorom ATmega328P.
Literatúra:
- [1] - datasheet k motorčeku, ktorý je použitý v klapke
Analýza a opis riešenia
Mechanizmus ovládania klapky klimatizácie je zložený z DC motorčeka, potenciometra a súkolia na prevod. My budeme ovládať daný systém jedným potenciometrom, ale ako? Chceme zostrojiť kód na ovládanie polohy DC motora s použitím dvoch potenciometrov: jeden na nastavenie želanej polohy a druhý na snímanie aktuálnej polohy motora.
Takto vyzerá mechanizmus ovládania klapky vnútri. Môžeme tam vidieť obyčajný jednosmerný motor s filmovým kondenzátorom, šnekový prevod(na zabránenie voči samovoľnému pohybu klapky) so súkolím, na ktorého poslednom koliečku je snímací potenciometer. Tento obvod funguje sám o sebe ako regulačný obvod.
Schéma zapojenia je zobrazená na obrázku nižšie:
Inicializácia: Na začiatku programu si zavoláme všetky potrebné knižnice, ktoré budeme využívať, definujeme a nastavíme piny a inicializujeme všetky potrebné periférie, teda A/D prevodník.
A/D prevod: Princíp riešenia je vskutku jednoduchý. Budem používať A/D prevodník na prevod analógového signálu z potenciometrov na digitálny signál, vhodný pre spracovanie. Takže prvý princíp je cez A/D prevod spracovať informáciu z oboch potenciometrov a uložiť ich do nejakej premennej. S touto informáciou môžeme ďalej pracovať.
Rozdiel polôh: Ďalším krokom je tieto dve hodnoty od seba odčítať, čím získame rozdiel polôh. Vzhľadom na tento rozdiel definujeme stavy, ak bude rozdiel kladný, tak premenná nadobudne hodnotu 1, záporný = -1 alebo nulový/minimálny = 0. Následne budeme túto hodnotu potrebovať pri podmienkach pre smer otáčania motora.
Smer otáčania: Hodnotu, ktorú získame z porovnávania použijeme v princípe smeru otáčania motora. Pre jednotlivé hodnoty definujeme smer, teda ak bude premenná rozdielu polohy kladná, motor sa bude otáčať do jednej strany, ak záporná tak do opačnej, a ak 0, tak bude stáť. Celý tento program beží v cykle while, takže mikropočítač neustále porovnáva hodnoty potenciometrov a snaží sa dosiahnuť ustálený stav motora.
Úprava kódu: Pre úhľadnosť a jednoduchosť kódu jednotlivé procesy ako A/D prevod a smer otáčania motora napíšem do vedľajších súborov, pripíšem knižnice a budem jednotlivé funkcie jednoducho volať z hlavného programu.
Algoritmus a program
Celý program pozostáva s viacerých súborov/knižníc. Pre funkciu motora som si vytvoril osobitný kód, ktorý budem volať funkciou v hlavnej slučke. Rovnako s funkciou A/D prevodníka.
#include <avr/io.h>
#include <util/delay.h>
#include "adc.h"
#include "motor.h"
// Nastavenie pinov
#define nastav_poten 0
#define snim_poten 1
#define motor_pin1 PB4
#define motor_pin2 PB5
int main(void) {
// Inicializácia ADC
adc_init();
// Nastavenie pinov motora ako výstup
DDRB |= (1 << motor_pin1) | (1 << motor_pin2);
while (1) {
// Želaná poloha z nastavovacieho potenciometra
uint16_t pozicia_nastav = adc_read(nastav_poten);
// Aktuálna poloha z potenciometra pre spätnú väzbu
uint16_t pozicia_snim = adc_read(snim_poten);
// Rozdiel medzi želanou a aktuálnou polohou
int rozdiel_pozicie = pozicia_snim-pozicia_nastav;
// Ak je rozdiel velký, otácaj motorom
if (rozdiel_pozicie > 10) {
smer_otacania(1); // Otácaj v jednom smere
} else if (rozdiel_pozicie < -10) {
smer_otacania(-1); // Otácaj v opacnom smere
} else {
smer_otacania(0); // Zastav motor
}
// Krátka pauza pre stabilitu
_delay_ms(100);
}
}
#include <avr/io.h>
void adc_init(void){
ADMUX = (1<<REFS0);
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
}
unsigned int adc_read(char a_pin){
a_pin &= 0x07;
ADMUX = (ADMUX & 0xF8) | a_pin;
ADCSRA |= (1<<ADSC);
while(ADCSRA & (1<<ADSC));
return(ADC);
}
#ifndef INCFILE1_H_
#define INCFILE1_H_
#endif /* INCFILE1_H_ */
void adc_init(void);
unsigned int adc_read(char a_pin);
#include <avr/io.h>
// Nastavenie pinov pre motor
#define motor_pin1 PB4
#define motor_pin2 PB5
// Nastavenie smeru otacania motora
void smer_otacania(int smer) {
if (smer == 1) {
PORTB |= (1 << motor_pin1);
PORTB &= ~(1 << motor_pin2);
} else if (smer == -1) {
PORTB |= (1 << motor_pin2);
PORTB &= ~(1 << motor_pin1);
} else {
PORTB &= ~(1 << motor_pin1);
PORTB &= ~(1 << motor_pin2);
}
}
#ifndef INCFILE1_H_
#define INCFILE1_H_
#endif /* INCFILE1_H_ */
void smer_otacania(int smer);
Zdrojový kód je možné stiahnuť kliknutím na odkaz nižšie:
Zdrojový kód: zdrojovykod.zip
Overenie
Na koniec nahráme kód do mikroprocesora a môžeme testovať! Ako vidíme na videu, všetko funguje a klapka reaguje na zmenu polohy potenciometra.
Video:
Vypracoval: Peter Fedor 17.5.2024 :)