Strona 1 z 1
sterowanie ruchem c++
: środa 15 mar 2017, 14:41
autor: robo1973
Cześć!!!
Napisałem program , którym struję za pomocą drążków apartaury RC jazdę to tyłu, przodu w prawo i lewo łazika.
W zależności od położenia drążka zmienia się wartość licznika od 2000 do 4000
Funkcje załączają kierunki silników
Jak zrobić że jak łazik jedzie do przodu to nie załączy jady w lewo i jak na skręca w lewo to nie załączy jady w tył
Może coś za pomocą funkcji case
Kod: Zaznacz cały
void jazda_tyl() //funkcja jazdy do tylu
{ }
void jazda_przódl() //funkcja jazdy do tylu
{}
void jazda_prawo() //funkcja jazdy do tylu
{}
void jazda_lewo() //funkcja jazdy do tylu
{}
//PRZÓD TYŁ /kierunek/>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
if (kierunek>=3060 && kierunek<=4100) {
jazda_przod(); }
else if (kierunek >2000 && kierunek <=3010 ) {
jazda_tyl(); }
else {
}
//PRZÓD TYŁ /kierunek/>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//PRWAO LEWO /orientacja/>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
if (orientacja>=3060 && orientacja<=4100) {
skret_prawo(); }
else if (orientacja >2000 && orientacja <=3010 ) {
skret_lewo(); }
else {
}
Re: sterowanie ruchem c++
: środa 15 mar 2017, 14:44
autor: Antystatyczny
Ja bym wykorzystał kilka ifów.
Re: sterowanie ruchem c++
: środa 15 mar 2017, 15:37
autor: robo1973
to że kilka to wiem
Re: sterowanie ruchem c++
: środa 15 mar 2017, 16:24
autor: inż.wielki
Jak byś pokazał cały kod programu, możliwe że ktoś by rzucił na niego okiem i poprawił lub zaproponował Ci jakieś rozwiązanie. W obecnym momencie niestety nie wiemy jak kod wygląda oraz jak wygląda logika sterująca.
Czy ruch robota jest realizowany podczas trzymania drążka w daną stronę czy po jego jednokrotnym przesunięciu
Czy, jeżeli ruch robota jest sterowany poprzez jednokrotne przesunięcie drążka w daną stronę, nie lepiej sterować go poprzez trzymanie tegoż drążka w danym kierunku?
Czy korzystasz z czegoś jeszcze, czy proc obecnie tylko decyduje o ruchu silników.
Czy masz jakiś sterownik silników? Jeżeli nie i jeżeli są to silniki krokowe, czy używasz mechanizmów potocznie zwanych "rampą"?
Re: sterowanie ruchem c++
: środa 15 mar 2017, 16:43
autor: robo1973
jest 6 silników prądu stałego Każdy sterowany 2 sygnałami PWM i kirunek obrotu Drążek do przodu zmiana prędkości Dwa lewe drążki to kierunek i skręt
Kod: Zaznacz cały
* LazikV1.c
*
* Created: 2017-03-07 19:00:47
* Author: Robo
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "hd44780.h"
#include<stdio.h>
#include<math.h>
#define skala_predkosci 2 ;
int predkosc, kierunek, orientacja, start;
void lcd_float(float val) //funkcja zamienia liczbę na znak
{
char bufor[17]; //bufor na dane
sprintf(bufor,"t=%.6f [s]",val); //zmieniasz float na string - 4 miejsca po przecinku % . 6f lub %1. 6f jedna przed przecinkiem
LcdWrite(bufor); //wyświetlasz string z liczbą np. "12,345"
}
void jazda_przod() //funkcja jazdy do przodu
{
PORTA.OUTCLR = PIN7_bm; // ustawienie pinu A2=0
PORTF.OUTCLR = PIN4_bm |PIN5_bm |PIN6_bm;// silniki prawe do przodu
PORTD.OUTCLR = PIN5_bm; //// silniki prawe do przodu
PORTE.OUTCLR = PIN4_bm |PIN5_bm |PIN6_bm | PIN7_bm;// silniki lewe do przodu
TCF0.CCA = predkosc; // prędkość_silnik_P_1
TCF0.CCB = predkosc; // prędkość_silnik_P_2
TCF0.CCC = predkosc; // prędkość_silnik_P_3
TCE0.CCA = predkosc; // prędkość_silnik_L_1
TCE0.CCB = predkosc; // prędkość_silnik_L_2
TCE0.CCC = predkosc; // prędkość_silnik_L_3
return;
//PORTA.OUTCLR = PIN2_bm; // ustawienie pinu A2=0
}
void jazda_tyl() //funkcja jazdy do tylu
{
PORTA.OUTSET = PIN7_bm; // ustawienie pinu A1=1
PORTF.OUTSET = PIN4_bm |PIN5_bm |PIN6_bm;// silniki prawe do tyłu
PORTD.OUTSET = PIN5_bm; //// silniki prawe do tyłu
PORTE.OUTSET = PIN4_bm |PIN5_bm |PIN6_bm | PIN7_bm;// silniki lewe do tyłu
TCF0.CCA = predkosc; // prędkość_silnik_P_1
TCF0.CCB = predkosc; // prędkość_silnik_P_2
TCF0.CCC = predkosc; // prędkość_silnik_P_3
TCE0.CCA = predkosc; // prędkość_silnik_L_1
TCE0.CCB = predkosc; // prędkość_silnik_L_2
TCE0.CCC = predkosc; // prędkość_silnik_L_3
return;
}
void skret_prawo() //funkcja skretu w prawo
{
PORTF.OUTSET = PIN4_bm |PIN5_bm |PIN6_bm;// silniki prawe do tyłu
PORTD.OUTSET = PIN5_bm; //// silniki prawe do tyłu
PORTE.OUTCLR = PIN4_bm |PIN5_bm |PIN6_bm | PIN7_bm;// silniki lewe do przodu
TCF0.CCA = predkosc; // prędkość_silnik_P_1
TCF0.CCB = predkosc; // prędkość_silnik_P_2
TCF0.CCC = predkosc; // prędkość_silnik_P_3
TCE0.CCA = predkosc; // prędkość_silnik_L_1
TCE0.CCB = predkosc; // prędkość_silnik_L_2
TCE0.CCC = predkosc; // prędkość_silnik_L_3
return;
}
void skret_lewo() //funkcja skretu w lewo
{
return;
}
int main(void) {
// konfiguracja przycisku FLIP
PORTE.DIRCLR = PIN5_bm; // pin E5 jako wejście
PORTE.PIN5CTRL = PORT_OPC_PULLUP_gc; // podciągnięcie do zasilania
//wyjście
PORTA.DIRSET = PIN7_bm; // pin A7 jako wyjście
// wyscie PWM dla silników
PORTF.DIRSET = 0b11111111; // piny F0,F1,F2,F3 jako wyjście PWM dla silników 1,2,3 prawych
PORTE.DIRSET = 0b11111111; // piny E0,E1,E2,E3 jako wyjście PWMdla silników 1,2,3 lewych
PORTD.DIRSET = 0b00100000; //kierunek silnik 3 prawy
// KONFIGURACJA WEJSC PWM Z ELSERA TCDO <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
PORTD.DIRCLR = PIN0_bm |PIN1_bm |PIN2_bm |PIN3_bm; // 1-ch D0, 2-ch D1, 3-ch D2, 4-ch D3 jako wejscie sygnalu PWM
PORTD_PIN0CTRL=PORT_ISC_BOTHEDGES_gc | PORT_OPC_PULLDOWN_gc;// D0 zdarzenie na każdym zboczu impulsu, podciągnięcie do zera sterujemy 3,3 V
PORTD_PIN1CTRL=PORT_ISC_BOTHEDGES_gc | PORT_OPC_PULLDOWN_gc;// D1
PORTD_PIN2CTRL=PORT_ISC_BOTHEDGES_gc | PORT_OPC_PULLDOWN_gc;// D2
PORTD_PIN3CTRL=PORT_ISC_BOTHEDGES_gc | PORT_OPC_PULLDOWN_gc;// D3
// konfiguracja timera czytanie PWM
TCD0.CTRLB = TC_WGMODE_SS_gc
|TC0_CCAEN_bm
|TC0_CCBEN_bm
|TC0_CCCEN_bm
|TC0_CCDEN_bm; // tryb single slope PWM (może być normalny) TC0_CCBEN_bm;
TCD0.CTRLD = TC_EVACT_PW_gc | TC_EVSEL_CH0_gc; // pomiar szerokosci impulsu na kanale CH0
TCD0.CTRLA = TC_CLKSEL_DIV1_gc; // ustawienie preskalera i uruchomienie timera TCC0
// konfiguracja systemu zdarzeń
EVSYS.CH0MUX = EVSYS_CHMUX_PORTD_PIN0_gc;// pin E0 wywołuje zdarzenie CH 0 - kanal NADAJNIKA CCA
EVSYS.CH0CTRL = EVSYS_DIGFILT_8SAMPLES_gc; // filtr cyfrowy
EVSYS.CH1MUX = EVSYS_CHMUX_PORTD_PIN1_gc;// pin E1 wywołuje zdarzenie CH 1 - kanal NADAJNIKA CCB
EVSYS.CH1CTRL = EVSYS_DIGFILT_8SAMPLES_gc; // filtr cyfrowy
EVSYS.CH2MUX = EVSYS_CHMUX_PORTD_PIN2_gc;// pin E2 wywołuje zdarzenie CH 2 - kanal NADAJNIKA CCC
EVSYS.CH2CTRL = EVSYS_DIGFILT_8SAMPLES_gc; // filtr cyfrowy
EVSYS.CH3MUX = EVSYS_CHMUX_PORTD_PIN3_gc;// pin E2 wywołuje zdarzenie CH 3 - kanal NADAJNIKA CCC
EVSYS.CH3CTRL = EVSYS_DIGFILT_8SAMPLES_gc; // filtr cyfrowy
// konfiguracja przerwań
TCD0.INTCTRLB = TC_OVFINTLVL_LO_gc
|TC_CCAINTLVL_LO_gc
|TC_CCBINTLVL_LO_gc
|TC_CCCINTLVL_LO_gc
|TC_CCDINTLVL_LO_gc; //odblokowanie przewrań CAPTRURE dla CCA, CCB, CCD, CCD
PMIC.CTRL = PMIC_LOLVLEN_bm; // odblokowanie przerwań o priorytecie LO
sei();
// konfiguracja timera PWM port F >>>>>>>>>>
TCF0.CTRLB = TC_WGMODE_DSBOTH_gc| // tryb normalny
TC0_CCAEN_bm|
TC0_CCBEN_bm|
TC0_CCCEN_bm|
TC0_CCDEN_bm;
TCF0.PER = 39999;
//TCF0.CTRLA = TC_CLKSEL_DIV1_gc; // ustawienie preskalera i uruchomienie timera
// konfiguracja timera PWM port E >>>>>>>>>>
TCE0.CTRLB = TC_WGMODE_DSBOTH_gc| // tryb normalny
TC0_CCAEN_bm|
TC0_CCBEN_bm|
TC0_CCCEN_bm|
TC0_CCDEN_bm;
TCE0.PER = 39999;
//TCE0.CTRLA = TC_CLKSEL_DIV1_gc; // ustawienie preskalera i uruchomienie tim
// globalne odblokowanie przerwań
// wyświetlacz
LcdInit();
while(1) {
//START STOP
if (start>=2600 && start<=3000) {
TCF0.CTRLA = TC_CLKSEL_DIV1_gc; // załacza PWM na F0
TCE0.CTRLA = TC_CLKSEL_DIV1_gc; // załacza PWM na E0
}
else {
TCF0.CTRLA = TC_CLKSEL_OFF_gc; //wylacza PWM na F0
TCE0.CTRLA = TC_CLKSEL_OFF_gc; //wylacza PWM na E0
}
//START STOP
//PRZÓD TYŁ /kierunek/>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
if (kierunek>=3060 && kierunek<=4100) {
jazda_przod(); }
else if (kierunek >2000 && kierunek <=3010 ) {
jazda_tyl(); }
else {
}
//PRZÓD TYŁ /kierunek/>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//PRWAO LEWO /orientacja/>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
if (orientacja>=3060 && orientacja<=4100) {
skret_prawo(); }
else if (orientacja >2000 && orientacja <=3010 ) {
skret_lewo(); }
else {
}
//PRAWO LEWO /orientacja/>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//wyswietlacz kontrolny>>>>
LcdClear();
Lcd("CH1:");
LcdDec(predkosc);
Lcd("CH2:");
LcdDec(orientacja);
Lcd2;
Lcd("CH3:");
LcdDec(kierunek);
Lcd("CH4:");
LcdDec(start);
_delay_ms(100);
//wyswietlacz kontrolny>>>>
}
}
//ISR(TCF0_CCA_vect) { // przerwanie przepełnienia TCF0 PWM
//PORTF.OUTTGL = PIN0_bm; // zamiana stanu diody
//_delay_ms(100);
//}
ISR(TCD0_CCA_vect) { // przerwanie przepełnienia TCD0 1- CH ELSERA D0
//buforowanie CCA
predkosc = (TCD0.CCA*3)-4000; //drazek pionowy lewy 1- ch, D0 funkcja obliczenia predkosci
//buForowanie CCA+++++++++++++++++++++++++++++++++++++++PWM
}
ISR(TCD0_CCB_vect) { // przerwanie przepełnienia TCD0 2- CH ELSERA D1
//buforowanie CCB
orientacja = TCD0.CCB; //drazek poziomy lewy 2- ch, D1
//TCF0.CCB = orientacja;
//bugorowanie CCB+++++++++++++++++++++++++++++++++++++++PWM
}
ISR(TCD0_CCC_vect) { // przerwanie przepełnienia TCD0 3- CH ELSERA D2
//buforowanie CCC
kierunek = TCD0.CCC; //drążek pionowy prawy 3 -ch , D2
//TCF0.CCC = kierunek;
//bugorowanie CCC+++++++++++++++++++++++++++++++++++++++PWM
}
ISR(TCD0_CCD_vect) { // przerwanie przepełnienia TCD0 5- CH ELSERA D3
//buforowanie CCD
start = TCD0.CCD; //drążek pionowy prawy 3 -ch , D2
//TCF0.CCD = start;//uruchom zatrzyma !!!
//bugorowanie CCD+++++++++++++++++++++++++++++++++++++++PWM
}
Re: sterowanie ruchem c++
: środa 15 mar 2017, 18:42
autor: inż.wielki
Czyli, jeżeli dobrze rozumiem, to silniki ciągle jadą. Nie rozumiem tylko troszkę logiki bo skoro:
Silniki ciągle jadą.
Skręcasz w lewo i cały czas skręcają.
Następnie chcesz je wyprostować czy skręcić w prawo?
Musisz sobie dorobić mechanizm stanów czyli, zmienna, która trzyma ustawienia kierunku. To znaczy, jeżeli w zmiennej jest kierunek w lewo, to funkcja w prawo nie może się odpalić ponieważ silniki jadą w lewo, jak już przestają, to powinieneś zmienić status flagi na jazda prosto i wtedy można wejść w funkcje w prawo

Pozdrawiam
Re: sterowanie ruchem c++
: środa 15 mar 2017, 19:45
autor: robo1973
dzięki za radę Silnik cały czas nie jadą tylko załączane są drążkiem prędkości. Tu się z Tobą zgodzę że jak jadę prosto to nie mogę skręcać silnikami. Więc skręcam prędkością - już to poprawiłem i jutro przetestuję
PS jak sprawdzić If jazda_przódl() /jeżeli funkcja aktywna to wykonaj/
Chodzi i jazda_przódl() jak ją zapisać w warunku że jest 1 /aktywna/
Re: sterowanie ruchem c++
: czwartek 16 mar 2017, 09:42
autor: inż.wielki
Możesz wykorzystać albo timer, tzn. ustawiasz sobie flagę że obecnie jest wykonywany ruch. Po zakończeniu tego ruchu, timer czyści Ci tą flagę. Ewentualnie, robisz funkcję, która blokuje wykonywanie innego kodu, do póki ruch nie zostanie zakończony, wtedy czyścisz flagę.
Pozdrawiam
Re: sterowanie ruchem c++
: czwartek 16 mar 2017, 15:45
autor: robo1973
ok coś pokombinuję Na razie to mam problem z samym skręcaniem Jest 6 silników a kołami. Trzy z lewej i 3 z prawej Jak uruchomię je w przeciwnych kierunkach to nie skręca Kombinuję jak to zrobić ?
Re: sterowanie ruchem c++
: czwartek 16 mar 2017, 15:55
autor: inż.wielki
Przydałby się schemat w takim wypadku
Re: sterowanie ruchem c++
: czwartek 16 mar 2017, 21:08
autor: robo1973
nie kumam po co Ci schemat ? 6 silników każdy ma dwa sygnały sterowania PWM- prędkość i kierunek/1 lewo, 0 prawo/
Re: sterowanie ruchem c++
: czwartek 16 mar 2017, 21:57
autor: mokrowski
@robo1973 to czego szukasz, nazywane jest maszyną stanów. Zapoznaj się z tą koncepcją a Twój kod będzie i czytelny i łatwy do opanowania. Jak rozpoczniesz "zabawę" ze stadem if'ów i (oby nie) instrukcjami switch/case, to powstanie Ci bardzo nieuporządkowany kod który zapomnisz jak działa po 1 tyg.