sterowanie ruchem c++

Tu możesz pisać o swoich problemach z pisaniem programów w języku C dla AVR.
robo1973
Posty: 11
Rejestracja: poniedziałek 06 mar 2017, 18:26

sterowanie ruchem c++

Postautor: robo1973 » środa 15 mar 2017, 14:41

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 {

   }

Awatar użytkownika
Antystatyczny
Geek
Geek
Posty: 1168
Rejestracja: czwartek 03 wrz 2015, 22:02

Re: sterowanie ruchem c++

Postautor: Antystatyczny » środa 15 mar 2017, 14:44

Ja bym wykorzystał kilka ifów.
"The true sign of intelligence is not knowledge but imagination" Albert Einstein.

robo1973
Posty: 11
Rejestracja: poniedziałek 06 mar 2017, 18:26

Re: sterowanie ruchem c++

Postautor: robo1973 » środa 15 mar 2017, 15:37

to że kilka to wiem

Awatar użytkownika
inż.wielki
User
User
Posty: 307
Rejestracja: niedziela 20 gru 2015, 23:11

Re: sterowanie ruchem c++

Postautor: inż.wielki » środa 15 mar 2017, 16:24

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ą"?

robo1973
Posty: 11
Rejestracja: poniedziałek 06 mar 2017, 18:26

Re: sterowanie ruchem c++

Postautor: robo1973 » środa 15 mar 2017, 16:43

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
}


Awatar użytkownika
inż.wielki
User
User
Posty: 307
Rejestracja: niedziela 20 gru 2015, 23:11

Re: sterowanie ruchem c++

Postautor: inż.wielki » środa 15 mar 2017, 18:42

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

robo1973
Posty: 11
Rejestracja: poniedziałek 06 mar 2017, 18:26

Re: sterowanie ruchem c++

Postautor: robo1973 » środa 15 mar 2017, 19:45

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/

Awatar użytkownika
inż.wielki
User
User
Posty: 307
Rejestracja: niedziela 20 gru 2015, 23:11

Re: sterowanie ruchem c++

Postautor: inż.wielki » czwartek 16 mar 2017, 09:42

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

robo1973
Posty: 11
Rejestracja: poniedziałek 06 mar 2017, 18:26

Re: sterowanie ruchem c++

Postautor: robo1973 » czwartek 16 mar 2017, 15:45

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ć ?

Awatar użytkownika
inż.wielki
User
User
Posty: 307
Rejestracja: niedziela 20 gru 2015, 23:11

Re: sterowanie ruchem c++

Postautor: inż.wielki » czwartek 16 mar 2017, 15:55

Przydałby się schemat w takim wypadku

robo1973
Posty: 11
Rejestracja: poniedziałek 06 mar 2017, 18:26

Re: sterowanie ruchem c++

Postautor: robo1973 » czwartek 16 mar 2017, 21:08

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/

Awatar użytkownika
mokrowski
User
User
Posty: 190
Rejestracja: czwartek 08 paź 2015, 20:50
Lokalizacja: Tam gdzie Centymetro

Re: sterowanie ruchem c++

Postautor: mokrowski » czwartek 16 mar 2017, 21:57

@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.
,,Myślenie nie jest łatwe, ale można się do niego przyzwyczaić" - Alan Alexander Milne: Kubuś Puchatek


Wróć do „Programowanie AVR w C”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 4 gości