Järgnev näide ei kasuta Kodulabori teegi alalisvoolu mootorite kiiruse juhtimise teeki, vaid on tehtud riistvaralise PWM väljundi peale, mis on Mootori moodulil ühendatud servo pistikutesse.
Lihtsustatud näide suunab UH anduri lugemi otse mootori kiiruseks.
//***************************************************************************** // Vajalik riistvara: // 1. Kodulabori kontrollermoodul ATmega2561 // 3. Kodulabori mootorite moodul ja andurite moodul või Kombo moodul // 4. UH andur // 5. Alalisvoolumootor // // Kirjeldus: // Programm seadistab riistvaralise PWM-i kasutama servopistikuid. Ultraheli anduri näit antakse otse // mootori kiiruseks. Kiiruse vahemik 0-255 // // Kasutamine: // Ühenda moodulid kokku. Ühenda UH andur Viiku ADC3 / PF3 // Ühenda mootori maa Servo pistiku GND viiguga ja mootori juhtkaabel servo pistiku signaali viiguga. // Servo pistiku keskmine viik (+5 V) jääb ühendamata. // // Autor: Heiko Pikner, Raivo Sell // // Compiler: AVR-GCC // Chip type: Atmega2561 //***************************************************************************** //#include <stdio.h> #include "homelab/pin.h" #include "homelab/delay.h" #include <homelab/module/sensors.h> #define PWM_PERIOD (F_CPU / 8 / 5000) // Kasutusel servopistik. Protsessori viigud PB5 ja PB6 static pin servo_pins[2] = { PIN(B, 5), PIN(B, 6) }; void hv_pwm_init(unsigned char index) { // Seadista PWM viik väljundiks. pin_setup_output(servo_pins[index]); // Seadista timeri kontrollregister // Clear OUTA and OUTB on compare match // Fast PWM mode with ICR = TOP // Prescaler 8 timer1_init_fast_pwm( TIMER1_PRESCALE_8, TIMER1_FAST_PWM_TOP_ICR, TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH, TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH, TIMER1_FAST_PWM_OUTPUT_DISABLE); // TOP period timer1_set_input_capture_value(PWM_PERIOD); } // // PWM väärtuse muutmine // index - Servo pins 0-1. // position 0-255. PWM value. // void hv_pwm_value(unsigned char index, unsigned int value) { switch (index) { case 0: timer1_set_compare_match_unitA_value(value); if(OCR1A == 0) { DDRB &= ~(1 << DDB5); } else { DDRB |= (1 << DDB5); } break; case 1: timer1_set_compare_match_unitB_value(value); if(OCR1B == 0) { DDRB &= ~(1 << DDB6); } else { DDRB |= (1 << DDB6); } break; } } // // Põhiprogramm // int main(void) { // UH anduri viik pin pin_trigger_echo = PIN(F, 3); // Anduriplaadi väliste andurite viik pin sensors = PIN(G, 0); pin_setup_output(sensors); pin_set(sensors); // Mootori seadistamine hv_pwm_init(0); // Lõputu tsükkel while (true) { // UH anduri mõõtetulemuse (cm) suunamine mootori kiiruseks (0-255) //Väärtus on korrutatud läbi 10-ga, seegamax kiirusele vastab 2,55 m hv_pwm_value(0, ultrasonic_measure_srf05(pin_trigger_echo)*10); } }
Failid pakituna projektiks:
//***************************************************************************** // Vajalik riistvara: // 1. Kodulabori kontrollermoodul ATmega2561 // 3. Kodulabori mootorite moodul // 4. Kodulabori kasutajaliidese moodul // 5. UH andur // 6. Akudrelli mootor või LED, mille kiirust või heledust saaks juhtida. // // Kirjeldus: // Programm seadistab riistvaralise PWM-i kasutama servopistikuid. Selle // töötsüklit on võimalik nuppudest muuta. Lisaks toimub samal ajal mõõtmine // UH anduriga. // // Kasutamine: // Ühenda moodulid kokku. Ühenda UH andur ja PWM-i kasutav seade. // Vajutades nupule S1 mootori kiirus või LEDi heledus suureneb. Nupp S2 vähendab // töötsüklit. Ekraanil kuvatakse kiirus (töötsükkel) 0 - 255. Lisaks UH anduri // näit cm. // // Autor: Heiko Pikner // // Compiler: AVR-GCC // Chip type: Atmega2561 //***************************************************************************** #include <stdio.h> #include "homelab/pin.h" #include "homelab/delay.h" #include <homelab/module/lcd_gfx.h> #include <homelab/module/sensors.h> #include "HvPWM.h" // UH anduri viik pin pin_trigger_echo = PIN(F, 2); pin sensors = PIN(G, 0); // LEDide viigud pin led_red = PIN(C, 5); pin led_yellow = PIN(C, 4); pin led_green = PIN(C, 3); // Nuppude viigud pin button1 = PIN(C, 0); pin button2 = PIN(C, 1); pin button3 = PIN(C, 2); // // Põhiprogramm // int main(void) { unsigned int speed = 0; char text[16]; unsigned short distance; unsigned char new_value1, old_value1 = 0; // Seab LEDid töökorda pin_setup_output(led_red); pin_setup_output(led_yellow); pin_setup_output(led_green); // Anduriplaat välistele anduritele pin_setup_output(sensors); pin_set(sensors); // Seab nupud töökorda pin_setup_input_with_pullup(button1); pin_setup_input_with_pullup(button2); pin_setup_input_with_pullup(button3); // Lülitab LEDid välja pin_set(led_green); pin_set(led_yellow); pin_set(led_red); // Ekraani seadistamine lcd_gfx_init(); // LCD ekraani puhastamine lcd_gfx_clear(); lcd_gfx_backlight(true); // Kursori (nähtamatu) ekraani keskele viimine lcd_gfx_goto_char_xy(2, 2); // Teksti kuvamine lcd_gfx_write_string("UHandHVPWM"); // Mootori seadistamine hv_pwm_init(0); hv_pwm_init(1); // Lõputu tsükkel while (true) { // Loeb nupu S3 väärtuse new_value1 = pin_get_debounced_value(button3); // Nupp S1 alla vajutatud if(!pin_get_debounced_value(button1)) { // Suurendab kiirust if(speed < 255) { speed++; } pin_clear(led_green); } // Nupp S2 alla vajutatud if(!pin_get_debounced_value(button2)) { // Vähendab kiirust if(speed > 0) { speed--; } pin_clear(led_yellow); } // Jätab eelmise nupu S3 väärtuse meelde old_value1 = new_value1; // Töötsükli ehk kiiruse muutmine mõlemal viigul. hv_pwm_value(0, speed); hv_pwm_value(1, speed); // Kiiruse teisendamine stringiks. sprintf(text, "%d kiirus", speed); // Kiiruse kuvamine ekraanil. lcd_gfx_goto_char_xy(3, 4); lcd_gfx_write_string(text); // Viide. sw_delay_ms(2); // LEDide kustutamine pin_set(led_green); pin_set(led_yellow); // Mõõtmine UH anduriga distance = ultrasonic_measure_srf05(pin_trigger_echo); // Mõõtmine õnnestus ? if (distance > 0) { // Kauguse tekstiks teisendamine sprintf(text, "%d cm ", distance); } // Mõõtmisel tekkis viga ? else { // Vea tekst sprintf(text, "Viga "); } // Kauguse kuvamine LCD viienda rea alguses lcd_gfx_goto_char_xy(3, 5); lcd_gfx_write_string(text); } }
//***************************************************************************** // Riistvaraline PWM kasutamiseks Kodulabori servoviikude juhtimiseks. // // Kirjeldus: // Funktsioonid võimaldavad kasutada kodulabori servo viike (PB5 ja PB7) PWM // väljunditena. // // Kasutamine: // // Lisa oma projektile HvPWM.c ja HvPWM.h failid. Edasi lingi need // eelprotsessorikäsuga #include "HvPWM.h" // // Edasi saad initsialiseerida PWM-i, kasutades käsku "hv_pwm_init(unsigned // char index)". Kus "index" on servo number, ehk kas 0 või 1. // // Autor: Heiko Pikner // // Compiler :AVR-GCC // Chip type :Atmega2561 //***************************************************************************** #include "HvPWM.h" // // PWMi periood (5000ms) // #define PWM_PERIOD (F_CPU / 8 / 5000) // // Kasutusel servopistik. Protsessori viigud PB5 ja PB6 // static pin servo_pins[2] = { PIN(B, 5), PIN(B, 6) }; // // Seadistamine. Ette anda 0 või 1 olenevalt valitud pistikust. // void hv_pwm_init(unsigned char index) { // Seadista PWM viik väljundiks. pin_setup_output(servo_pins[index]); // Seadista timeri kontrollregister // Clear OUTA and OUTB on compare match // Fast PWM mode with ICR = TOP // Prescaler 8 timer1_init_fast_pwm( TIMER1_PRESCALE_8, TIMER1_FAST_PWM_TOP_ICR, TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH, TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH, TIMER1_FAST_PWM_OUTPUT_DISABLE); // TOP period timer1_set_input_capture_value(PWM_PERIOD); } // // PWM väärtuse muutmine // index - Servo pins 0-1. // position 0-255. PWM value. // void hv_pwm_value(unsigned char index, unsigned int value) { switch (index) { case 0: timer1_set_compare_match_unitA_value(value); if(OCR1A == 0) { DDRB &= ~(1 << DDB5); } else { DDRB |= (1 << DDB5); } break; case 1: timer1_set_compare_match_unitB_value(value); if(OCR1B == 0) { DDRB &= ~(1 << DDB6); } else { DDRB |= (1 << DDB6); } break; } }
#ifndef HVPWM_H #define HVPWM_H #include <stdio.h> #include <avr/interrupt.h> #include "homelab/pin.h" #include "homelab/timer2561.h" // prototypes void hv_pwm_init(unsigned char index); void hv_pwm_value(unsigned char index, unsigned int position); #endif