MarJanPol Napisano Luty 17, 2018 Udostępnij Napisano Luty 17, 2018 Witam, napisałem program do kontroli pojazdu-robota za pomocą akcelerometru w smartphonie. Wszystko dzialalo jak należy. Jednak gdy dodalem serwo z funkcją sterowania suwakiem na telefonie nagle prawe koła przestały się kręcić. Po odłączeniu serwa i wgraniu poprzedniego kodu wszystko działa. Czy może ktoś domyśla się co jest przyczyną? Serwo mam zasilone z L298N //Napisany pod UNO i RoboRemo. //Przed wgraniem wyjąć moduł BT z Arduino i włożyć dopiero po zakońćzeniu wgrywania żeby nie było konfliktu z UART //W aplikacji RoboRemo ustawić akcelerometr i tylko dane x i y. ID: X, lub Y, czyli X lub Y pisane dużą literą i zaraz potem przecinek. gain=1,0. output int od 0 do 255 //zaznaczyć limit to [min, max].NIE WYSYŁAĆ SPACJI #include <Servo.h> //Biblioteka odpowiedzialna za serwa Servo serwomechanizm; //Tworzymy obiekt, dzięki któremu możemy odwołać się do serwa int ENA=10; //adjusting speed - prawe koła int ENB=5; //adjusting speed - lewe koła int IN1=2; // defining pin2 left rear int IN2=4; // defining pin4 left front int IN3=7; // defining pin7 right rear int IN4=8; // defining pin8 right front int PWM_A=0; //prędkość prawych int PWM_B=0; //prędkość lewych int factor; //współczynnik pomocniczy służący do procentowej zmiany prędkości w przód kół prawych lub lewych w zależoności od wyhylenia komórki na boki int Iwart; //potrzebne do konwersji z tablicy znaków na wartość integer char* znak; //potrzebne do zapisania pierwszego znaku - X lub Y po parsowaniu char* Twart; //potrzebne do zapisania znaków liczbowych w tablicy po parsowaniu int iX; //służy do przypisania wartości Iwart pochodząych z akcelerometra dla ruchów prawo-lewo int iY; //służy do przypisania wartości Iwart pochodząych z akcelerometra dla ruchów przód-tył int iS; const byte numChars = 6; //określa ilość bajtów (znaków) w tablicy receivedChars. Potrzebnych jest: jeden znak na X lub Y, drugi znak na przecinek, trzy znaki na cyfry //i ostatni znak na znak zakończenia linii którego nie widać ale który jest wysyłany przez acclerometr char receivedChars[numChars]; // an array to store the received data boolean newData = false; //flaga - operator void setup() { serwomechanizm.attach(3); //Serwomechanizm podłączony do pinu 3 pinMode(ENA,OUTPUT); // pin10 (PWM) pinMode(ENB,OUTPUT); // pin11 (PWM) pinMode(IN1,OUTPUT); // pin2 pinMode(IN2,OUTPUT); // pin4 pinMode(IN3,OUTPUT); // pin7 pinMode(IN4,OUTPUT); // pin8 Serial.begin(9600); //Serial1.begin(9600); // while (!Serial); //gdyby miało pracować z Leonardo } void loop() { recvWithEndMarker(); //idź do funkcji odpowiedzialnej za przyjęcie danych przychodzących po UART z akcelerometra if (newData == true) //działaj poniżej tylko jeśli flaga ustawiona na true {parseData(); //idź do funkcji parsowania - czyli wydzielenia z przychodzących danych tego co nas interesuje i przypisania wartości odpowiednim zmiennym // showParsedData(); //funkcja testowa wyświetlania wartości sparsowanych na monitorze portu szeregowego sprawdzenie(); //sprawdzenie jakie wartości przyszły z akcelerometra i w zależności od tych wartości przejście do odpowiedniej funkcji ruchu newData = false;} //po przerobieniu nowych danych można już "podnieść" flagę "false" } void recvWithEndMarker() //funkcja odpowiedzialna za przejęcie danych przychodzących po UART (czyli w tym wypadku przez Bluetooth z accelerometru) do tabicy receivedChars { static byte ndx = 0; char endMarker = '\n'; //określa jaki znak kończy daną porcję znaków przychodzących po UART. //W tym wypadku jest to znak nowej linii bo w monitorze portu szeregowego można było zobaczyć, //że każda porcja informacji przychodząca z akcelerometru - czyli koljeno wartości przypsane do X lub Y - zaczynają się od nowej linii char rc; /*gdy pojawiły się jakieś dane z UART w buforze pamięci mikroprocesora i flaga jest ustawiona na false to działaj. Przypisuj kolejno pojedyncze znaki z bufora pamięci do zmiennej rc a następnie do kolejnych komórek tablicy receivedChars dotąd aż nie pojawi się znak kończący '\n'. Gdyby znaków było więcej niż komórek w tablicy to cały czas nadpisuj ostatnią komórkę tej tablicy nowym znakiem Jeśli w końcu pojawi się znak kończący '\n' to przypisz ostatniej komórce znak '\0' oznaczający dla komputera koniec łańcucha znaków. Zmień flagę na true i na chwilę przestań zajmować się znakami w buforze pamięci nawet gdyby tam były. W razie czego poczekają one tam chwilę ale raczej ich jeszcze nie będzie bo dane z UART przychodzą wolniej niż wykonywane są kolejne operacje przez mikroprocesor. Wróć do funkcji loop */ while (Serial.available() > 0 && newData == false) //Serial1 - gdyby miało pracować z Leonardo { rc = Serial.read();//Serial1 - gdyby miało pracować z Leonardo if (rc != endMarker) { receivedChars[ndx] = rc; ndx++; if (ndx >= numChars) { ndx = numChars - 1; } } else { receivedChars[ndx] = '\0'; // terminate the string ndx = 0; newData = true; } } } void parseData() //parsowanie czyli podział danych zapisanych w tablicy na części. Elementem rozdzielającym jest przecinek { znak = strtok(receivedChars,","); // get the first part - the string Twart = strtok(NULL, ","); // this continues where the previous call left off Iwart = atoi(Twart); // convert this part to an integer if (znak[0]=='X') iX = Iwart; if (znak[0]=='Y') iY = Iwart; if (znak[0]=='S') iS = Iwart; } void sprawdzenie() { if (znak[0]=='S') { serwomechanizm.write(iS); //Wykonaj ruch } if (iY<118 && iX>117 && iX<139) //PRZÓD PROSTO { PWM_A = map(iY,117,0,50,255); PWM_B = map(iY,117,0,50,255); przod(); } if (iY>138 && iX>117 && iX<139) //TYŁ PROSTO { PWM_A = map(iY,139,255,50,255); PWM_B = map(iY,139,255,50,255); tyl(); } if (iY>117 && iY<139 && iX>117 && iX<139) //ZATRZYMANIE { PWM_A = 0; PWM_B = 0; zatrz(); } if (iY<118 && iX<118) //PRZÓD PRAWO { factor = map(iX,117,0,100,0); PWM_A = (map(iY,117,0,50,255))*factor/100; PWM_B = map(iY,117,0,50,255); przod(); } if (iY<118 && iX>138) //PRZÓD LEWO { factor = map(iX,139,255,100,0); PWM_A = map(iY,117,0,50,255); PWM_B = (map(iY,117,0,50,255))*factor/100; przod(); } if (iY>138 && iX<118) //TYL PRAWO { factor = map(iX,117,0,100,0); PWM_A = (map(iY,139,255,50,255))*factor/100; PWM_B = map(iY,139,255,50,255); tyl(); } if (iY>138 && iX>138) //TYL LEWO { factor = map(iX,139,255,100,0); PWM_A = map(iY,139,255,50,255); PWM_B = (map(iY,139,255,50,255))*factor/100; tyl(); } /* if (iY>117 && iY<139 && iX<118) //DOOKOŁA PRAWO { PWM_A = map(iX,117,0,50,255); PWM_B = map(iX,117,0,50,255); prawo(); } if (iY>117 && iY<139 && iX>138) //DOOKOŁA LEWO { PWM_A = map(iX,117,0,50,255); PWM_B = map(iX,117,0,50,255); lewo(); } */ } /* void showParsedData() { Serial.print("znak: "); Serial.println(znak); Serial.print("wartosc: "); Serial.println(Iwart); } */ void przod() { analogWrite(ENA,PWM_A); analogWrite(ENB,PWM_B); digitalWrite(IN1,0); digitalWrite(IN2,1); digitalWrite(IN3,0); digitalWrite(IN4,1); } void tyl() { analogWrite(ENA,PWM_A); analogWrite(ENB,PWM_B); digitalWrite(IN1,1); digitalWrite(IN2,0); digitalWrite(IN3,1); digitalWrite(IN4,0); } void prawo() { analogWrite(ENA,PWM_A); analogWrite(ENB,PWM_B); digitalWrite(IN1,1); digitalWrite(IN2,0); digitalWrite(IN3,0); digitalWrite(IN4,1); } void lewo() { analogWrite(ENA,PWM_A); analogWrite(ENB,PWM_B); digitalWrite(IN1,0); digitalWrite(IN2,1); digitalWrite(IN3,1); digitalWrite(IN4,0); } void zatrz() { analogWrite(ENA,PWM_A); analogWrite(ENB,PWM_B); digitalWrite(IN1,1); digitalWrite(IN2,1); digitalWrite(IN3,1); digitalWrite(IN4,1); } the Cytuj Link do komentarza Share on other sites More sharing options...
marek1707 Luty 17, 2018 Udostępnij Luty 17, 2018 Serwo nie potrzebuje L298. Cytuj Link do komentarza Share on other sites More sharing options...
MarJanPol Luty 18, 2018 Autor tematu Udostępnij Luty 18, 2018 Wcześniej serwo podłączyłem bezpośrednio do UNO ale ponieważ prawe kola zaczely wariować to znaczy przestały się obracać więc pomysłami że może serwo wprowadza jakieś zakłócenia. Dlatego zasilanie serwa przeniosłem na L298N (na stabilizowane wyjście 5v) zeby wykorzystać zewnętrzne zasilanie. Nic to jednak nie pomogło - działa tak samo wadliwie 🙁 Cytuj Link do komentarza Share on other sites More sharing options...
marek1707 Luty 18, 2018 Udostępnij Luty 18, 2018 Nie mamy schematu tego Twojego cuda więc tylko możemy się domyślać z tłumaczeń trochę naokoło, że masz jakiś stabilizator i to on zasila L298 (tylko 5V dla tego mostka? to bez sensu) i teraz serwo. Oczywiście napisałeś prosty kod testowy włączający oba silniki na różne PWM i jednocześnie kręcący serwem bez żadnych zdalnych sterowań i akcelerometrów żeby sprawdzić poprawność działania sprzętu - i on też zawiódł. A z czego zasila się ten robot? Co jest przed stabilizatorem 5V, jakie silniki tam masz i jaki stabilizator? I po co on w ogóle gdy masz mostek do silników? Czy próbowałeś serwo podpiąć na inny pin Arduino? Może są jakieś interakcje między generacją sygnału dla serwa a PWM-ami silników lub innymi wyjściami np. sterującymi kierunkiem? Mierzyłeś jakieś napięcia? To główne, zasilające wszystko i te 5V podczas problemów. Cytuj 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
MarJanPol Luty 18, 2018 Autor tematu Udostępnij Luty 18, 2018 marek17017, dziękuję Ci za pochylenie się nad moim problemem. Owe "cudo" jak to ładnie nazwałeś wygląda tak: CUDO Jest i schemat cuda: SCHEMAT Załączyłem schemat z zaznaczeniem skąd ciągnę 5V. Program stworzyłem samemu wykorzystując czyjś fragment dot. buforowania danych i parsowania. Program zbiera dane z akcelerometru telefonu i kręci kołami w zależności od ruchu komórki. TA CZĘŚĆ DZIAŁA WYŚMIENICIE. Następnie dodałem parę linijek kodu obsługujących serwo. Dane z suwaka na telefonie (0-180st) są na identycznej zasadzie przekazywane z telefonu do Arduino. TA CZĘŚĆ TEŻ DZIAŁA tak jak powinna. Niestety po dodaniu serwa z jakiegoś powodu prawe koła zaczęły fiksować - obracają się tylko przy maksymalnym nachyleniu komórki. Program w wersji bez serwa działa jak należy. Cytuj Link do komentarza Share on other sites More sharing options...
MarJanPol Luty 20, 2018 Autor tematu Udostępnij Luty 20, 2018 Już znam przyczynę mojego problemu! Dzielę się tu, bo może komuś też się przyda: https://forum.arduino.cc/index.php?topic=530504.0 Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!