MarcinTe Napisano Lipiec 6, 2019 Udostępnij Napisano Lipiec 6, 2019 Czesc, Robie wozek inwalidzki oparty na 2 silnikach, joystick porusza wozek, przycisk obraca go w miejscu, wszystko dziala. Problem w tym ze joystick jest maly i silniki bardzo agresywnie reaguja, chcialbym zeby po natychmiastowym wychyleniu do przodu predkosc nie skoczyla od razu do wartosci maksymalnej tylko chwile plynnie do niej dochodzila. Bede wdzieczny za pomoc. Dzieki. // FINAL Z 1 PRZYCISKIEM ENDER 3 // Button const int switchPin = 2; int switchValue; // Motor A int enA = 9; int in1 = 8; int in2 = 7; // Motor B int enB = 3; int in3 = 5; int in4 = 4; // Joystick Input int joyVert = A0; // Vertical int joyHorz = A1; // Horizontal // Motor Speed Values - Start at zero int MotorSpeed1 = 0; int MotorSpeed2 = 0; // Joystick Values - Start at 512 (middle position) int joyposVert = 512; int joyposHorz = 512; void setup() { Serial.begin(9600); //button pinMode(switchPin, INPUT_PULLUP); // Set all the motor control pins to outputs pinMode(enA, OUTPUT); pinMode(enB, OUTPUT); pinMode(in1, OUTPUT); pinMode(in2, OUTPUT); pinMode(in3, OUTPUT); pinMode(in4, OUTPUT); // Start with motors disabled and direction forward // Motor A digitalWrite(enA, LOW); digitalWrite(in1, HIGH); digitalWrite(in2, LOW); // Motor B digitalWrite(enB, LOW); digitalWrite(in3, HIGH); digitalWrite(in4, LOW); } void loop() { // button state switchValue = digitalRead(switchPin); if (switchValue==1) { // Read the Joystick X and Y positions joyposVert = analogRead(joyVert); joyposHorz = analogRead(joyHorz); // Determine if this is a forward or backward motion // Do this by reading the Verticle Value // Apply results to MotorSpeed and to Direction if (joyposVert < 460) { // This is Backward // Set Motor A backward digitalWrite(in1, LOW); digitalWrite(in2, HIGH); // Set Motor B backward digitalWrite(in3, LOW); digitalWrite(in4, HIGH); //Determine Motor Speeds // As we are going backwards we need to reverse readings joyposVert = joyposVert - 460; // This produces a negative number joyposVert = joyposVert * -1; // Make the number positive MotorSpeed1 = map(joyposVert, 0, 460, 0, 255); MotorSpeed2 = map(joyposVert, 0, 460, 0, 255); } else if (joyposVert > 564) { // This is Forward // Set Motor A forward digitalWrite(in1, HIGH); digitalWrite(in2, LOW); // Set Motor B forward digitalWrite(in3, HIGH); digitalWrite(in4, LOW); //Determine Motor Speeds MotorSpeed1 = map(joyposVert, 564, 1023, 0, 255); MotorSpeed2 = map(joyposVert, 564, 1023, 0, 255); } else { // This is Stopped MotorSpeed1 = 0; MotorSpeed2 = 0; } // Now do the steering // The Horizontal position will "weigh" the motor speed // Values for each motor if (joyposHorz < 460) { // Move Left // As we are going left we need to reverse readings joyposHorz = joyposHorz - 460; // This produces a negative number joyposHorz = joyposHorz * -1; // Make the number positive // Map the number to a value of 255 maximum joyposHorz = map(joyposHorz, 0, 460, 0, 255); MotorSpeed1 = MotorSpeed1 - joyposHorz; MotorSpeed2 = MotorSpeed2 + joyposHorz; // Don't exceed range of 0-255 for motor speeds if (MotorSpeed1 < 0)MotorSpeed1 = 0; if (MotorSpeed2 > 255)MotorSpeed2 = 255; } else if (joyposHorz > 564) { // Move Right // Map the number to a value of 255 maximum joyposHorz = map(joyposHorz, 564, 1023, 0, 255); MotorSpeed1 = MotorSpeed1 + joyposHorz; MotorSpeed2 = MotorSpeed2 - joyposHorz; // Don't exceed range of 0-255 for motor speeds if (MotorSpeed1 > 255)MotorSpeed1 = 255; if (MotorSpeed2 < 0)MotorSpeed2 = 0; } // Adjust to prevent "buzzing" at very low speed if (MotorSpeed1 < 10)MotorSpeed1 = 0; if (MotorSpeed2 < 10)MotorSpeed2 = 0; } else if (switchValue==0) { digitalWrite(in1, HIGH); digitalWrite(in2, LOW); MotorSpeed1=150; // Motor B digitalWrite(in3, LOW); digitalWrite(in4, HIGH); MotorSpeed2=150; } // Set the motor speeds analogWrite(enA, MotorSpeed1); analogWrite(enB, MotorSpeed2); Serial.print("X: "); Serial.print(MotorSpeed1); Serial.print(" Y: "); Serial.print(MotorSpeed2); Serial.print(" Button: "); Serial.println(switchValue); } Link do komentarza Share on other sites More sharing options...
deshipu Lipiec 6, 2019 Udostępnij Lipiec 6, 2019 To może dodaj zmienną, w której będziesz trzymać docelową prędkość danego silnika, osobną od aktualnej jego prędkości, i w każdym obrocie pętli, jeśli docelowa prędkość jest większa od aktualnej, to zwiększaj aktualną o jakąś ograniczoną od góry wartość, a jak jest mniejsza, to zmniejszaj, analogicznie. Link do komentarza Share on other sites More sharing options...
InspektorGadzet Lipiec 7, 2019 Udostępnij Lipiec 7, 2019 (edytowany) 15 godzin temu, MarcinTe napisał: chcialbym zeby po natychmiastowym wychyleniu do przodu predkosc nie skoczyla od razu do wartosci maksymalnej tylko chwile plynnie do niej dochodzila. Prędkość zwiększaj w przerwaniu od timera. Jak chcesz zrobić rampę to mam gdzieś kod źródłowy. Edytowano Lipiec 7, 2019 przez InspektorGadzet Link do komentarza Share on other sites More sharing options...
MarcinTe Lipiec 7, 2019 Autor tematu Udostępnij Lipiec 7, 2019 Dzieki za popdowiedzi, sprobuje potestowac z ograniczeniem predkosci o stala czasowa.. Nie wiem o co chodzi z ta rampa ale i tak poprosze o ten kod 🙂 Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
InspektorGadzet Lipiec 7, 2019 Udostępnij Lipiec 7, 2019 30 minut temu, MarcinTe napisał: Nie wiem o co chodzi z ta rampa ale i tak poprosze o ten kod Nie wiesz a chcesz? Mam odczucie, że kod się nie przyda. Jest w dużym projekcie, wyciąłem istotne fragmenty, jak potrzebne coś jeszcze to napisz co konkretnie. void Przesow( uint8_t stan ) { if ( stan ) { AktualnaMoc = 1; fazaRozpedu = ROZBIEG; KrokPrzyrostukMocy = (float)Cfg.silnik / Cfg.tRozpedzania; // przyrost mocy na 1ms = (Vmax-Vmin / 500ms) uint8_t mocMin = 30; // Procentowa moc, do ktorej zwalniamy if( mocMin > Cfg.silnik ) mocMin = Cfg.silnik; KrokZmniejszaniaMocy = (float)(Cfg.silnik-mocMin) / Cfg.lHamowania; // spadek predkosci w % na 0,1mm (Pmax-Pmin) / DYSTANS mm UstawMoc( AktualnaMoc ); HAL_TIM_Base_Start_IT( &htim4 );// Start przerwan od timera TimEnkoder = DEF_TIMENKODER; FL_tstEnkoder = true; // Wlaczenie kontroli enkodera } else { HAL_TIM_Base_Stop_IT( &htim4 ); // Stop timera HAL_GPIO_WritePin( STEP_GPIO_Port, STEP_Pin, GPIO_PIN_RESET ); // STEP (PWM) Konczymy zawsze poziomem niskim FL_koniecPrzesowu = true; FL_tstEnkoder = false; // Wylaczenie kontroli enkodera FL_Enkoder = false; // hamulec( 0 ); // TimHamucec==1 zalatwia sprawe } } void TIM4_IRQHandler(void) { /* USER CODE BEGIN TIM4_IRQn 0 */ HAL_GPIO_TogglePin( STEP_GPIO_Port, STEP_Pin ); /* USER CODE END TIM4_IRQn 0 */ HAL_TIM_IRQHandler(&htim4); /* USER CODE BEGIN TIM4_IRQn 1 */ /* USER CODE END TIM4_IRQn 1 */ } //------------------------------------------------------------ char volatile FL_wykrytoZnacznik = false; //------------------------------------------------------------ void wykrytyZnacznik() // Zadzialala fotokomorka. Wykryte przez EXTI lub 1ms { if( FL_wykrytoZnacznik ) return; // Jesli znacznik byl juz wykryty wyjdz FL_wykrytoZnacznik = true; // Przesow( false ); // Natychmiastowe zatrzymanie fazaRozpedu = HAMOWANIE; // soft-stop TimSoftStop = CZAS_ZATRZYMANIA_Z_FOTO; } //------------------------------------------------------------ void ZwalnianieFoto() // Wywolywane w przerwaniu 1ms { if( (!TimSoftStop && FL_wykrytoZnacznik && Cfg.TrybPracy==1) || (!TimSoftStop && FL_wykrytoZnacznik && Cfg.TrybPracy==2) ) { TimSoftStop = 0xFFFF; Przesow( false ); } } void PracaSilnika1ms() // Wywolywane co 1ms w przerwaniu { int static volatile dobieg=0; switch( fazaRozpedu ) { case ROZBIEG: if( AktualnaMoc <= (float)Cfg.silnik ) // Jesli moc mniejsza od minimalnej { AktualnaMoc += KrokPrzyrostukMocy; UstawMoc( AktualnaMoc ); } else{ fazaRozpedu = BIEG; __NOP(); } break; case BIEG: if( lenZmierzone/1000 > Cfg.len-Cfg.lHamowania ){ // Jesli zblizamy sie do konca materialu fazaRozpedu = HAMOWANIE; hamulec( Cfg.tHamulec ); // INFO: hamulec zwalniany przez "Przesow(" INFO: przez TimHamulec __asm{ NOP }; } break; case HAMOWANIE: if( AktualnaMoc > 1 ) { AktualnaMoc -= KrokPrzyrostukMocy; UstawMoc( AktualnaMoc ); } break; } } Link do komentarza Share on other sites More sharing options...
MarcinTe Lipiec 7, 2019 Autor tematu Udostępnij Lipiec 7, 2019 InspektorGadzet, faktycznie niewiele z tego rozumiem, wroce do tego kodu na pewno jak sie troche poducze, dziekuje za poswiecony czas i przepraszam za zaklocenia. Pozdrawiam Link do komentarza Share on other sites More sharing options...
InspektorGadzet Lipiec 8, 2019 Udostępnij Lipiec 8, 2019 8 godzin temu, MarcinTe napisał: faktycznie niewiele z tego rozumiem Spodziewałem się tego. Nawet nie zauważyłeś, że kod jest dla STM32 i używa HAL. Możesz pokazać fotografie jak rozwiązałeś napęd i jak zabezpieczyłeś sterownik przez wpływami atmosferycznymi? W wózku to chyba IP 67 musi być? Zgadza się? Link do komentarza Share on other sites More sharing options...
MarcinTe Lipiec 8, 2019 Autor tematu Udostępnij Lipiec 8, 2019 InspektorGadzet, dzieki za zainteresowanie ale za rada kolegi na innym forum chyba sobie odpuszcze to przedsiewziecie, widze ze mnie zdecydowanie przerasta. Pozdrawiam Link do komentarza Share on other sites More sharing options...
InspektorGadzet Lipiec 8, 2019 Udostępnij Lipiec 8, 2019 1 godzinę temu, MarcinTe napisał: odpuszcze to przedsiewziecie, widze ze mnie zdecydowanie przerasta. Jest powiedzenie (przysłowie?) "Mierz siły na zamiary". Jesteś początkujący, co widać po problemie, który masz a wybrałeś sobie ambitne, jak na swoje możliwości zadanie. Zacznij od czegoś prostszego, może samochód zdalnie sterowany? Dzięki temu zapoznasz się z problemami jakie występują przy sterowaniu silników. Link do komentarza Share on other sites More sharing options...
MarcinTe Lipiec 8, 2019 Autor tematu Udostępnij Lipiec 8, 2019 To moze jeszcze tylko dopytam na czym docelowo realizuje sie takie projekty, bo rozumiem ze nie na Arduino? Link do komentarza Share on other sites More sharing options...
ethanak Lipiec 8, 2019 Udostępnij Lipiec 8, 2019 Moc obliczeniowa Arduino spokojnie wystarczy do sterowania wózkiem. Znam bardziej skomplikowane projekty ,(sterowanie głosem) oparte na RPi. Tu jednak najważniejsze jest bezpieczeństwo. Pomyśl, co się stanie jeśli jakiś drucik wsadzony w gniazdo w Arduino uzna za stosowne wysunąć się np. w trakcie wjazdu na krawężnik... Link do komentarza Share on other sites More sharing options...
MarcinTe Lipiec 8, 2019 Autor tematu Udostępnij Lipiec 8, 2019 Jasne. Dzieki za odpowiedz. Link do komentarza Share on other sites More sharing options...
InspektorGadzet Lipiec 8, 2019 Udostępnij Lipiec 8, 2019 (edytowany) 1 godzinę temu, ethanak napisał: Moc obliczeniowa Arduino spokojnie wystarczy do sterowania wózkiem Pod warunkiem, że użyje się sprzętu a nie, jak to mówią (piszą) "machanie pinem" a w tym kodzie tak prawdopodobnie jest. Autor nie dołączył kodu bibliotek, ale one dają możliwość generowania sygnału na dowolnym pinie. To oznacza, że nie korzystają ze sprzętu, a to oznacza, że są ułomne. Edytowano Lipiec 8, 2019 przez InspektorGadzet Link do komentarza Share on other sites More sharing options...
ethanak Lipiec 8, 2019 Udostępnij Lipiec 8, 2019 Możesz jakoś rozwinąć owo niewątpliwie twórcze stwierdzenie? Szczególnie interesujące jest tu owo "niekorzystanie ze sprzętu"... Link do komentarza Share on other sites More sharing options...
InspektorGadzet Lipiec 8, 2019 Udostępnij Lipiec 8, 2019 (edytowany) 19 minut temu, ethanak napisał: Możesz jakoś rozwinąć owo niewątpliwie twórcze stwierdzenie? Szczególnie interesujące jest tu owo "niekorzystanie ze sprzętu"... Nie analizuję każdej biblioteki Arduino (używam ARM, głównie STM32 często LPC od NXP), bo te co analizowałem (jest ich dziesiątki tysięcy), używają millis, programowych SPI, I2C, UART. Jakiej użył autor tego wątku? Nie wiadomo? Przykładowo pod nazwą "onewire" są biblioteki akceptowalne i nieakceptowalne. Takich, które używają rozwiązań zalecanych przez producenta (Dallas, teraz Dallas-Maxim) nie widziałem. Nie oznacza to, że takich nie ma, ale na forach widzę tylko "machanie pinem". Analizowałem biblioteki graficzne U8 (coś tam dalej w nazwie). Tragedia! Moja kostka wyświetlałaby obrazek poi kilku sekundach! Co gorsza, byłoby widać jego rysowanie! Próbowałem te biblioteki z 320x240 SPI. Szkoda pisać, to trzeba zobaczyć. Wczytanie i wyświetlenie BMP to 2,5 sekundy. Dopiero na ARM, do LCD DMA, do karty SDIO (4-bit), daje zadowalające efekty. Edytowano Lipiec 8, 2019 przez InspektorGadzet Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »