Ovladanie krokoveho motora joystickom + uvod displej: Rozdiel medzi revíziami
Z SensorWiki
(→Zadanie) |
|||
(36 medziľahlých úprav od rovnakého používateľa nie je zobrazených.) | |||
Riadok 2: | Riadok 2: | ||
== Zadanie == | == Zadanie == | ||
− | *1. | + | *1. Preštudovanie datasheetov k daným komponentom |
− | *2. | + | # Joystick |
+ | # LCD/I2C | ||
+ | # Krokový motor + driver | ||
+ | |||
+ | *2.Návrh zapojenia a funkčnosti komponentov | ||
+ | |||
*3. Zapojenie | *3. Zapojenie | ||
− | *4. | + | |
− | + | *4. Návrh programového riešenia | |
− | + | # Čítanie hodnôt z joysticku a vhodná interpretácia pre ďalšie použitie | |
− | + | # Pohyb krokového motora v oboch smeroch | |
− | + | # Rýchlosť krokového motora | |
− | + | # Prepojenie joystick - motor | |
− | + | ## Ovládanie joystickom smer/rychlosť otáčania | |
− | *5. | + | # Úvodná obrazovka |
− | [[Obrázok: | + | ## Výpis privítania a čo robí daný projekt na LCD |
+ | # Výpis smeru otáčania na LCD | ||
+ | |||
+ | *5. Otestovanie funkčnosti (videodokumentácia) | ||
+ | |||
+ | |||
+ | '''Hardware:''' | ||
+ | *1.Arduino uno R3 | ||
+ | |||
+ | [[Obrázok:Ledecky Mips arduino-uno.png|400px|thumb|left|Arduino UNO R3]] | ||
+ | <br style="clear: both;"/> | ||
+ | |||
+ | *2.Joystick | ||
+ | |||
+ | [[Obrázok:Ledecky Mips joystick.jpg|400px|thumb|left|Joystick]] | ||
+ | [[Obrázok:Ledecky mips Shcema joystick.png|400px|thumb|center|Schéma zapojenia]] | ||
+ | <br style="clear: both;"/> | ||
+ | |||
+ | *3.LED display 16×2 I2C | ||
+ | |||
+ | [[Obrázok:Ledecky Mips LED-display-16×2-modre-podsvietenie-spajkovany-I2C-modul.jpg|400px|thumb|left|LCD displej]] | ||
+ | [[Obrázok:Ledecky mips Shcema LCD.png|400px|thumb|center|Schéma zapojenia]] | ||
+ | <br style="clear: both;"/> | ||
+ | |||
+ | |||
+ | |||
+ | *4.Krokový motor 28BYJ-48 modul ULN2003 | ||
+ | |||
+ | [[Obrázok:Ledecky Mips Krokovy-motor-28BYJ-48-modul-ULN2003.jpg|400px|thumb|left|Krokovy motor + driver]] | ||
+ | [[Obrázok:Ledecky mips Schema motor.png|400px|thumb|center|Schéma zapojenia]] | ||
+ | <br style="clear: both;"/> | ||
+ | |||
+ | |||
+ | '''Schéma zapojenia zariadenia:''' | ||
+ | |||
+ | |||
+ | [[Obrázok:Ledecky mips Schema zar.png|400px|thumb|left|Schéma zapojenia zariadenia]] | ||
+ | |||
+ | <br style="clear: both;"/> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
'''Literatúra:''' | '''Literatúra:''' | ||
− | * [ | + | * [https://docs.arduino.cc/resources/datasheets/A000066-datasheet.pdf Dokumentácia Arduino uno R3] |
− | + | ||
− | |||
__TOC__ | __TOC__ | ||
== Analýza a opis riešenia == | == Analýza a opis riešenia == | ||
− | + | *1.Najprv som pripojil joystick a vyhotovil jeho programové riešenie. Joystick je súčiastka, ktorá funguje štandardne na báze potenciometra, variabilného rezistora, ktorý mení odpor pri zmene polohy. Tento konkrétny joystick má dve osi pohybu (x a y) a tlačidlo. Na toto zariadenie použijeme jednu os pohybu, ktorú pripojíme na A/D prevodník s použitím knižnice, ktorú sme používali na cvičeniach. | |
+ | |||
+ | *2.Ďalej som zapojil krokový motor spolu s driverom a vyhotovil programový systém, pri ktorom je možné motorom otáčať a aj meniť jeho rýchlosť. Krokový motor 28BYJ-48 s modulom ULN2003 funguje na princípe rozdelenia celého otáčania na kroky. Každý krok zodpovedá určitému uhlu otáčania. ULN2003 je ovládač, ktorý prijíma signály z mikrokontroléra a riadi cievky motora. Postupným napájaním cievok v správnom poradí sa motor pohybuje o jeden krok. Tento spôsob umožňuje presné riadenie pozície a rýchlosti motora. Jednoducho povedané, motor sa otáča v malých krokoch riadených elektrickými impulzmi z ovládača ULN2003. | ||
+ | |||
+ | *3.Pokračoval som prepojením týchto dvoch funkcií s výsledným cieľom, aby som vedel podľa smeru otočenia páčky (buď vľavo alebo vpravo) riadiť smer krokového motora a intenzitou ohybu v danom smere riadiť rýchlosť. Smer je riešený podľa výstupných parametrov systému: pri hodnotách v nižšej polovici možných výstupných hodnôt je jeden smer a pri vyššej druhý, pričom program ráta aj s takzvaným mŕtvym stredom (stav, kedy sa nič nedeje). Funkcia rýchlosti vychádza z úpravy delayu medzi jednotlivými krokmi motora, pričom hodnota pre úpravu vychádza z hodnoty výstupu joysticka. | ||
+ | |||
+ | *4.V poslednom programovom kroku som vyhotovil jednoduchú úvodnú obrazovku (info k zariadeniu vid video) spolu s výpisom smeru otáčania. Realizácia spočívala v pripojení LCD LED displeja 16×2 s I2C modulom, s ktorým sa pracuje podobne ako na cvičení, s rozdielom, že tu sa používa aj I2C, s ktorým sme sa stretli tiež na cvičení. | ||
+ | |||
+ | *5.Na záver som všetko odskúšal a po overení funkčnosti vyhotovil jednoduchú inštalačnú dosku pre dané zariadenie, ktorá bola z dreva a mosadzných úchytov, a vytvorila celistvé zariadenie s jednoduchým ovládaním. | ||
=== Algoritmus a program === | === Algoritmus a program === | ||
− | |||
<tabs> | <tabs> | ||
<tab name="AVR C-code"><source lang="c++"> | <tab name="AVR C-code"><source lang="c++"> | ||
− | #include < | + | #include "main.h" // vlozenie potrebnych includeov prepojeni |
+ | |||
+ | #define X_PIN 0 //definovanie pinov joysticku | ||
+ | #define Y_PIN 1 | ||
+ | |||
+ | void delay(int delay) // klasicky delay | ||
+ | { | ||
+ | for (int i=1; i<=delay; i++) | ||
+ | _delay_ms(1); | ||
+ | } | ||
+ | |||
+ | void delayus(int delay) //us delay pre pozitie v rotacii ako regulacia rychlosti | ||
+ | { | ||
+ | for (int i=1; i<=delay; i++) | ||
+ | _delay_us(1); | ||
+ | } | ||
+ | |||
+ | void left(char Pole[],int Speed){ //tocenie doprava | ||
+ | for (int L=0;L<10;L++) | ||
+ | for(int i = 0; i < 4; i++){ | ||
+ | PORTD = Pole[i]; | ||
+ | delayus(4250 - Speed*20); | ||
+ | } | ||
+ | PORTD = 0b00000000; | ||
+ | |||
+ | } | ||
+ | |||
+ | void right(char Pole[], int Speed){ // tocenie dolava | ||
+ | for (int L=0;L<10;L++) | ||
+ | for(int i = 3; i >= 0; i--){ | ||
+ | PORTD = Pole[i]; | ||
+ | delayus(4000 - Speed*20); | ||
+ | } | ||
+ | PORTD = 0b00000000; | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
int main(void) | int main(void) | ||
{ | { | ||
− | unsigned int | + | |
− | while (1) | + | MCUCR &= ~(1<<PUD); |
− | { /* | + | |
− | return(0); | + | DDRD |= 0b00111100; //paramatre pre otacanie |
+ | char Pole[] = {0b00100000, 0b00010000, 0b00001000, 0b00000100}; | ||
+ | |||
+ | int Speed = 0; | ||
+ | |||
+ | unsigned int Valuex; // premenne pre nacitanie s AD prevodnika | ||
+ | unsigned int Valuey; | ||
+ | unsigned int Value; | ||
+ | |||
+ | int x = 0b00001110; // premenna pre mod LCD cursor on/OFF | ||
+ | int y = 0b00001100; | ||
+ | |||
+ | |||
+ | char *num; | ||
+ | |||
+ | TWI_Init(); //inicializacie TWI LCD ADC + uvodne texty | ||
+ | delay(500); | ||
+ | |||
+ | LCD_Init(y); | ||
+ | delay(500); | ||
+ | LCD_clear(); | ||
+ | delay(500); | ||
+ | LCD_sendString("Vitajte"); | ||
+ | delay(2000); | ||
+ | LCD_clear(); | ||
+ | delay(500); | ||
+ | |||
+ | LCD_sendString("Riadenie Motora "); | ||
+ | LCD_setPosition(0,1); | ||
+ | LCD_sendString("Joystickom"); | ||
+ | delay(2000); | ||
+ | LCD_clear(); | ||
+ | delay(500); | ||
+ | |||
+ | LCD_sendString("Smer otacania"); | ||
+ | LCD_setPosition(0,1); | ||
+ | delay(500); | ||
+ | |||
+ | adc_init(); | ||
+ | delay(500); | ||
+ | |||
+ | while(1){ | ||
+ | |||
+ | Valuex = adc_read(X_PIN)/4; //Citanie s AD do valuex | ||
+ | if(Valuex > 125){ //pobyb packy po osi x dolava | ||
+ | Speed=Valuex-123; //vypocet konstatny rychlosti | ||
+ | left(Pole,Speed); // rotacia dolava | ||
+ | LCD_setPosition(0,1); // pozicia kurzora LCD | ||
+ | LCD_sendString("<--"); // vypis na LCD | ||
+ | |||
+ | } | ||
+ | else if(Valuex < 124){ //to iste len do druhej strany s mensimi upravami kvoli rozdielnym hodnotam s AD | ||
+ | Speed=127-Valuex; | ||
+ | right(Pole, Speed); | ||
+ | LCD_setPosition(0,1); | ||
+ | LCD_sendString("-->"); | ||
+ | } | ||
+ | else{ | ||
+ | LCD_setPosition(0,1); // KED nic | ||
+ | LCD_sendString("<->"); | ||
+ | } | ||
+ | /* num = (char *)malloc(snprintf(NULL, 0, "%d", o) + 1); | ||
+ | LCD_sendString(num); | ||
+ | free(num); */ | ||
+ | |||
+ | |||
+ | } | ||
+ | return(0); | ||
+ | |||
+ | } | ||
+ | |||
+ | </source></tab> | ||
+ | <tab name="main.h"><source lang="c++"> | ||
+ | |||
+ | #ifndef MAIN_H_ | ||
+ | #define MAIN_H_ | ||
+ | |||
+ | #define BAUD 9600 | ||
+ | #define F_CPU 16000000UL | ||
+ | |||
+ | #include <avr/io.h> | ||
+ | #include <avr/interrupt.h> | ||
+ | #include <stdio.h> | ||
+ | #include <util/delay.h> | ||
+ | |||
+ | #include "adc.h" | ||
+ | #include "twi.h" | ||
+ | #include "lcd.h" | ||
+ | |||
+ | #endif /* MAIN_H_ */ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | </source></tab> | ||
+ | <tab name="lcd.h"><source lang="c++"> | ||
+ | |||
+ | #ifndef LCD_H_ | ||
+ | #define LCD_H_ | ||
+ | |||
+ | void LCD_Init(int); | ||
+ | void sendHalfByte(unsigned char); | ||
+ | void sendByte(unsigned char, unsigned char); | ||
+ | void LCD_setPosition(unsigned char, unsigned char); | ||
+ | void LCD_sendString(char[]); | ||
+ | void LCD_clear(void); | ||
+ | void LCD_BackLight(unsigned char); | ||
+ | |||
+ | #endif /* LCD_H_ */ | ||
+ | |||
+ | |||
+ | |||
+ | </source></tab> | ||
+ | <tab name="lcd.c"><source lang="c++"> | ||
+ | |||
+ | |||
+ | #include "main.h" | ||
+ | |||
+ | |||
+ | unsigned char portlcd = 0; | ||
+ | |||
+ | void LCD_Init(int X) { | ||
+ | sendHalfByte(0b00000011); | ||
+ | _delay_ms(5); | ||
+ | sendHalfByte(0b00000011); | ||
+ | _delay_us(100); | ||
+ | sendHalfByte(0b00000011); | ||
+ | _delay_ms(1); | ||
+ | sendHalfByte(0b00000010); | ||
+ | _delay_ms(1); | ||
+ | sendByte(0b00101000, 0); // Data 4bit, Line 2, Font 5x8 | ||
+ | _delay_ms(1); | ||
+ | sendByte(X, 0); //Display ON, Blink OFF CUrsor ON/OFF vramci premennej | ||
+ | _delay_ms(1); | ||
+ | |||
+ | TWI_TransmitByAddr(portlcd |= 0x08, 0x4E); //BackLight ON | ||
+ | |||
+ | TWI_TransmitByAddr(portlcd &= ~0x02, 0x4E); //LCD Write ON | ||
+ | } | ||
+ | |||
+ | void LCD_BackLight(unsigned char mode) { | ||
+ | switch(mode) { | ||
+ | case 0: | ||
+ | TWI_TransmitByAddr(portlcd &= ~0x08, 0x4E); //BackLight OFF | ||
+ | break; | ||
+ | case 1: | ||
+ | TWI_TransmitByAddr(portlcd |= 0x08, 0x4E); //BackLight ON | ||
+ | break; | ||
+ | } | ||
} | } | ||
+ | |||
+ | void sendHalfByte(unsigned char c) { | ||
+ | c <<= 4; | ||
+ | |||
+ | TWI_TransmitByAddr(portlcd |= 0x04, 0x4E); // Enable E | ||
+ | _delay_us(50); | ||
+ | |||
+ | TWI_TransmitByAddr(portlcd | c, 0x4E); | ||
+ | |||
+ | TWI_TransmitByAddr(portlcd &= ~0x04, 0x4E); // Disable E | ||
+ | _delay_us(50); | ||
+ | |||
+ | } | ||
+ | |||
+ | void sendByte(unsigned char c, unsigned char mode) { | ||
+ | if(mode == 0) TWI_TransmitByAddr(portlcd &= ~0x01, 0x4E); | ||
+ | else TWI_TransmitByAddr(portlcd |= 0x01, 0x4E); | ||
+ | unsigned char hc = 0; | ||
+ | hc = c >> 4; | ||
+ | sendHalfByte(hc); | ||
+ | sendHalfByte(c); | ||
+ | } | ||
+ | |||
+ | void LCD_sendString(char s[]) { | ||
+ | char n; | ||
+ | for(n=0; s[n]!='\0'; n++) | ||
+ | sendByte(s[n], 1); | ||
+ | } | ||
+ | |||
+ | void LCD_setPosition(unsigned char x, unsigned char y) { | ||
+ | switch(y) { | ||
+ | case 0: | ||
+ | sendByte(x | 0x80, 0); | ||
+ | break; | ||
+ | case 1: | ||
+ | sendByte((0x40+ x) | 0x80, 0); | ||
+ | break; | ||
+ | case 2: | ||
+ | sendByte((0x10+ x) | 0x80, 0); | ||
+ | break; | ||
+ | case 3: | ||
+ | sendByte((0x50+ x) | 0x80, 0); | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void LCD_clear(void) { | ||
+ | sendByte(0x01, 0); | ||
+ | _delay_ms(5); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
</source></tab> | </source></tab> | ||
− | <tab name=" | + | <tab name="adc.h"><source lang="c++"> |
+ | |||
#include <avr/io.h> | #include <avr/io.h> | ||
− | void adc_init(void); | + | |
+ | #ifndef ADC_H_ | ||
+ | #define ADC_H_ | ||
+ | |||
+ | |||
+ | |||
+ | void adc_init(void); // A/D converter initialization | ||
+ | |||
unsigned int adc_read(char a_pin); | unsigned int adc_read(char a_pin); | ||
+ | |||
+ | #endif /* ADC_H_ */ | ||
+ | |||
+ | |||
+ | |||
+ | </source></tab> | ||
+ | <tab name="adc.c"><source lang="c++"> | ||
+ | |||
+ | #include "main.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); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | </source></tab> | ||
+ | <tab name="twi.h"><source lang="c++"> | ||
+ | |||
+ | #ifndef TWI_H_ | ||
+ | #define TWI_H_ | ||
+ | |||
+ | void TWI_Start(void); | ||
+ | void TWI_Init(void); | ||
+ | void TWI_Stop(void); | ||
+ | void TWI_Transmit(unsigned char); | ||
+ | void TWI_TransmitByAddr(unsigned char, unsigned char); | ||
+ | |||
+ | #endif /* TWI_H_ */ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | </source></tab> | ||
+ | <tab name="twi.c"><source lang="c++"> | ||
+ | |||
+ | #include "main.h" | ||
+ | |||
+ | void TWI_Init(void) { | ||
+ | |||
+ | TWBR = 0x48; | ||
+ | } | ||
+ | |||
+ | void TWI_Start(void) { | ||
+ | TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); | ||
+ | while(!(TWCR & (1<<TWINT))); | ||
+ | } | ||
+ | |||
+ | void TWI_Transmit(unsigned char data) { | ||
+ | TWDR = data; | ||
+ | TWCR = (1<<TWINT) | (1<<TWEN); | ||
+ | while(!(TWCR & (1<<TWINT))); | ||
+ | } | ||
+ | |||
+ | void TWI_TransmitByAddr(unsigned char data, unsigned char addr) { | ||
+ | TWI_Start(); | ||
+ | TWI_Transmit(addr); | ||
+ | TWI_Transmit(data); | ||
+ | TWI_Stop(); | ||
+ | } | ||
+ | |||
+ | void TWI_Stop(void) { | ||
+ | TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN); | ||
+ | } | ||
+ | |||
</source></tab> | </source></tab> | ||
</tabs> | </tabs> | ||
− | == | + | == Zdrojovy kod == |
− | + | Zdrojový kód: [[Médiá:Ledecky_zdroj.7z|zdrojaky.zip]] | |
− | + | ||
− | + | == Ukážka zariadenia == | |
− | [[ | + | Video s prezentáciou funkcie |
− | + | <center><youtube>pz4nsYvfYTA</youtube></center> | |
− |
Aktuálna revízia z 16:52, 11. jún 2024
Záverečný projekt predmetu MIPS / LS2023 - Matej Ledecky
Zadanie
- 1. Preštudovanie datasheetov k daným komponentom
- Joystick
- LCD/I2C
- Krokový motor + driver
- 2.Návrh zapojenia a funkčnosti komponentov
- 3. Zapojenie
- 4. Návrh programového riešenia
- Čítanie hodnôt z joysticku a vhodná interpretácia pre ďalšie použitie
- Pohyb krokového motora v oboch smeroch
- Rýchlosť krokového motora
- Prepojenie joystick - motor
- Ovládanie joystickom smer/rychlosť otáčania
- Úvodná obrazovka
- Výpis privítania a čo robí daný projekt na LCD
- Výpis smeru otáčania na LCD
- 5. Otestovanie funkčnosti (videodokumentácia)
Hardware:
- 1.Arduino uno R3
- 2.Joystick
- 3.LED display 16×2 I2C
- 4.Krokový motor 28BYJ-48 modul ULN2003
Schéma zapojenia zariadenia:
Literatúra:
Obsah
Analýza a opis riešenia
- 1.Najprv som pripojil joystick a vyhotovil jeho programové riešenie. Joystick je súčiastka, ktorá funguje štandardne na báze potenciometra, variabilného rezistora, ktorý mení odpor pri zmene polohy. Tento konkrétny joystick má dve osi pohybu (x a y) a tlačidlo. Na toto zariadenie použijeme jednu os pohybu, ktorú pripojíme na A/D prevodník s použitím knižnice, ktorú sme používali na cvičeniach.
- 2.Ďalej som zapojil krokový motor spolu s driverom a vyhotovil programový systém, pri ktorom je možné motorom otáčať a aj meniť jeho rýchlosť. Krokový motor 28BYJ-48 s modulom ULN2003 funguje na princípe rozdelenia celého otáčania na kroky. Každý krok zodpovedá určitému uhlu otáčania. ULN2003 je ovládač, ktorý prijíma signály z mikrokontroléra a riadi cievky motora. Postupným napájaním cievok v správnom poradí sa motor pohybuje o jeden krok. Tento spôsob umožňuje presné riadenie pozície a rýchlosti motora. Jednoducho povedané, motor sa otáča v malých krokoch riadených elektrickými impulzmi z ovládača ULN2003.
- 3.Pokračoval som prepojením týchto dvoch funkcií s výsledným cieľom, aby som vedel podľa smeru otočenia páčky (buď vľavo alebo vpravo) riadiť smer krokového motora a intenzitou ohybu v danom smere riadiť rýchlosť. Smer je riešený podľa výstupných parametrov systému: pri hodnotách v nižšej polovici možných výstupných hodnôt je jeden smer a pri vyššej druhý, pričom program ráta aj s takzvaným mŕtvym stredom (stav, kedy sa nič nedeje). Funkcia rýchlosti vychádza z úpravy delayu medzi jednotlivými krokmi motora, pričom hodnota pre úpravu vychádza z hodnoty výstupu joysticka.
- 4.V poslednom programovom kroku som vyhotovil jednoduchú úvodnú obrazovku (info k zariadeniu vid video) spolu s výpisom smeru otáčania. Realizácia spočívala v pripojení LCD LED displeja 16×2 s I2C modulom, s ktorým sa pracuje podobne ako na cvičení, s rozdielom, že tu sa používa aj I2C, s ktorým sme sa stretli tiež na cvičení.
- 5.Na záver som všetko odskúšal a po overení funkčnosti vyhotovil jednoduchú inštalačnú dosku pre dané zariadenie, ktorá bola z dreva a mosadzných úchytov, a vytvorila celistvé zariadenie s jednoduchým ovládaním.
Algoritmus a program
#include "main.h" // vlozenie potrebnych includeov prepojeni
#define X_PIN 0 //definovanie pinov joysticku
#define Y_PIN 1
void delay(int delay) // klasicky delay
{
for (int i=1; i<=delay; i++)
_delay_ms(1);
}
void delayus(int delay) //us delay pre pozitie v rotacii ako regulacia rychlosti
{
for (int i=1; i<=delay; i++)
_delay_us(1);
}
void left(char Pole[],int Speed){ //tocenie doprava
for (int L=0;L<10;L++)
for(int i = 0; i < 4; i++){
PORTD = Pole[i];
delayus(4250 - Speed*20);
}
PORTD = 0b00000000;
}
void right(char Pole[], int Speed){ // tocenie dolava
for (int L=0;L<10;L++)
for(int i = 3; i >= 0; i--){
PORTD = Pole[i];
delayus(4000 - Speed*20);
}
PORTD = 0b00000000;
}
int main(void)
{
MCUCR &= ~(1<<PUD);
DDRD |= 0b00111100; //paramatre pre otacanie
char Pole[] = {0b00100000, 0b00010000, 0b00001000, 0b00000100};
int Speed = 0;
unsigned int Valuex; // premenne pre nacitanie s AD prevodnika
unsigned int Valuey;
unsigned int Value;
int x = 0b00001110; // premenna pre mod LCD cursor on/OFF
int y = 0b00001100;
char *num;
TWI_Init(); //inicializacie TWI LCD ADC + uvodne texty
delay(500);
LCD_Init(y);
delay(500);
LCD_clear();
delay(500);
LCD_sendString("Vitajte");
delay(2000);
LCD_clear();
delay(500);
LCD_sendString("Riadenie Motora ");
LCD_setPosition(0,1);
LCD_sendString("Joystickom");
delay(2000);
LCD_clear();
delay(500);
LCD_sendString("Smer otacania");
LCD_setPosition(0,1);
delay(500);
adc_init();
delay(500);
while(1){
Valuex = adc_read(X_PIN)/4; //Citanie s AD do valuex
if(Valuex > 125){ //pobyb packy po osi x dolava
Speed=Valuex-123; //vypocet konstatny rychlosti
left(Pole,Speed); // rotacia dolava
LCD_setPosition(0,1); // pozicia kurzora LCD
LCD_sendString("<--"); // vypis na LCD
}
else if(Valuex < 124){ //to iste len do druhej strany s mensimi upravami kvoli rozdielnym hodnotam s AD
Speed=127-Valuex;
right(Pole, Speed);
LCD_setPosition(0,1);
LCD_sendString("-->");
}
else{
LCD_setPosition(0,1); // KED nic
LCD_sendString("<->");
}
/* num = (char *)malloc(snprintf(NULL, 0, "%d", o) + 1);
LCD_sendString(num);
free(num); */
}
return(0);
}
#ifndef MAIN_H_
#define MAIN_H_
#define BAUD 9600
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <util/delay.h>
#include "adc.h"
#include "twi.h"
#include "lcd.h"
#endif /* MAIN_H_ */
#ifndef LCD_H_
#define LCD_H_
void LCD_Init(int);
void sendHalfByte(unsigned char);
void sendByte(unsigned char, unsigned char);
void LCD_setPosition(unsigned char, unsigned char);
void LCD_sendString(char[]);
void LCD_clear(void);
void LCD_BackLight(unsigned char);
#endif /* LCD_H_ */
#include "main.h"
unsigned char portlcd = 0;
void LCD_Init(int X) {
sendHalfByte(0b00000011);
_delay_ms(5);
sendHalfByte(0b00000011);
_delay_us(100);
sendHalfByte(0b00000011);
_delay_ms(1);
sendHalfByte(0b00000010);
_delay_ms(1);
sendByte(0b00101000, 0); // Data 4bit, Line 2, Font 5x8
_delay_ms(1);
sendByte(X, 0); //Display ON, Blink OFF CUrsor ON/OFF vramci premennej
_delay_ms(1);
TWI_TransmitByAddr(portlcd |= 0x08, 0x4E); //BackLight ON
TWI_TransmitByAddr(portlcd &= ~0x02, 0x4E); //LCD Write ON
}
void LCD_BackLight(unsigned char mode) {
switch(mode) {
case 0:
TWI_TransmitByAddr(portlcd &= ~0x08, 0x4E); //BackLight OFF
break;
case 1:
TWI_TransmitByAddr(portlcd |= 0x08, 0x4E); //BackLight ON
break;
}
}
void sendHalfByte(unsigned char c) {
c <<= 4;
TWI_TransmitByAddr(portlcd |= 0x04, 0x4E); // Enable E
_delay_us(50);
TWI_TransmitByAddr(portlcd | c, 0x4E);
TWI_TransmitByAddr(portlcd &= ~0x04, 0x4E); // Disable E
_delay_us(50);
}
void sendByte(unsigned char c, unsigned char mode) {
if(mode == 0) TWI_TransmitByAddr(portlcd &= ~0x01, 0x4E);
else TWI_TransmitByAddr(portlcd |= 0x01, 0x4E);
unsigned char hc = 0;
hc = c >> 4;
sendHalfByte(hc);
sendHalfByte(c);
}
void LCD_sendString(char s[]) {
char n;
for(n=0; s[n]!='\0'; n++)
sendByte(s[n], 1);
}
void LCD_setPosition(unsigned char x, unsigned char y) {
switch(y) {
case 0:
sendByte(x | 0x80, 0);
break;
case 1:
sendByte((0x40+ x) | 0x80, 0);
break;
case 2:
sendByte((0x10+ x) | 0x80, 0);
break;
case 3:
sendByte((0x50+ x) | 0x80, 0);
break;
}
}
void LCD_clear(void) {
sendByte(0x01, 0);
_delay_ms(5);
}
#include <avr/io.h>
#ifndef ADC_H_
#define ADC_H_
void adc_init(void); // A/D converter initialization
unsigned int adc_read(char a_pin);
#endif /* ADC_H_ */
#include "main.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 TWI_H_
#define TWI_H_
void TWI_Start(void);
void TWI_Init(void);
void TWI_Stop(void);
void TWI_Transmit(unsigned char);
void TWI_TransmitByAddr(unsigned char, unsigned char);
#endif /* TWI_H_ */
#include "main.h"
void TWI_Init(void) {
TWBR = 0x48;
}
void TWI_Start(void) {
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
while(!(TWCR & (1<<TWINT)));
}
void TWI_Transmit(unsigned char data) {
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT)));
}
void TWI_TransmitByAddr(unsigned char data, unsigned char addr) {
TWI_Start();
TWI_Transmit(addr);
TWI_Transmit(data);
TWI_Stop();
}
void TWI_Stop(void) {
TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
}
Zdrojovy kod
Zdrojový kód: zdrojaky.zip
Ukážka zariadenia
Video s prezentáciou funkcie