Skocz do zawartości

klimek4765

Użytkownicy
  • Zawartość

    28
  • Rejestracja

  • Ostatnio

  • Wygrane dni

    1

klimek4765 wygrał w ostatnim dniu 7 lipca 2015

klimek4765 ma najbardziej lubianą zawartość!

Reputacja

1 Neutralna

O klimek4765

  • Ranga
    3/10

Informacje

  • Płeć
    Mężczyzna
  • Lokalizacja
    Gdańsk
  1. asdpii0, Czy mozesz wrzucic obsluge i2c tego zyroskopu? mam caly czas problem z odczytami, ciagle odczytuje ze zyro daje 0 we wszystkich osiach, accel 26728 i ze niby w kazdym rejestrze jest wartosc 104 :| o co tu moze chodzic? pomozesz?
  2. Mega kawal dobrej roboty^^! Czy bylo to wykonywane w ramach pracy inz/mgr? w jakim jezyku bylo pisane oprogramowanie mikrokontrolera? Czy kolega bylby taki mily i udostepnil tu badz na privie biblioteke obslugujaca modul MPU 6050? Sam mecze sie z tym modulem od jakiegos czasu ale porzadnych bibliotek w C w internecie jak na lekarstwo a przerabianie bibliotek z arduino po 3000 linijek kodu troche mnie jeszcze przerasta.
  3. Juz spiesze z pomoca, w moim przypadku czujnik zaczynal wariowac a procek sie zawieszac kiedy zasilanie i GND HC-SR04 bylo podlaczone blisko zasilania i GND procka. Zaczalem wiec odsuwac czujnik od mikroprocka i bylo coraz lepiej ale dopiero zawieszenia procka ustaly gdy zaczalem zasilac czujnik napieciem sprzed stabilizatora a gnd bylo tuz obok gnd od baterii. Druga smocza zasada jest to ze wszystkie delaye w przypadku pomiarow tak krotkich sygnalow bez udzialu przetwornika ADC poprostu zabijaja cala konstrukcje, musisz je ograniczyc do minimum, a w szczegolnosci ten wyzwalajacy pomiar to juz MAKSYMALNIE 15us, sproboj tez taktowac procesor jak najwieksza czestotliwoscia zeby zadne stany ci nie umknely, u mnie jest to 8 MHZ. A no i oczywiscie najlepiej to by bylo generowac przerwania od stanu wysokiego/niskiego na pinie ECHO. W zalaczniku dorzucam ci moj kod uzbrojony w pomiar medianowy czyli skladajacy sie z kilku pomiarow i sredniej z nich wyciagnietej. Oczywiscie kod moznaby usprawnic dodaniem jeszcze jednego timera ktory by odliczal superokladnie czas sygnalu ECHO, ale w sumie to co jest daje wystarczajace rezultaty. W zalaczniku masz kompletny kod (bez biblioteki HD44780) W algorytmie znajduje sie rowniez prototyp funkcji ktora w przypadku wystapienia w krotkiej chwili 1 do 2 bardzo rozniacych sie pomiarow odrzuca je i kaze wykonac te pomiary od nowa az do skutku, jednak jest niedopracowana i w sumie pomiar medianowy dal juz wystarczajace wyniki. Pozostaje rowniez kwestia tego ze ten czujnik nie jest idealny, przy malych przedmiotach i rownoczesnej odleglosci >50 cm wystarczy niewielki kat odchylenia przedmiotu (tak ze fala ultradzwiekowa nie odbija sie od prostopadlej przeszkody) i masz po pomiarze i tego sie juz nie da raczej naprawic. Ew rozwiazaniem byloby zastosowanie 2 takich czujnikow w kooperacji i dzialalyby one jak uklad stereofoniczny, jednak to juz wyzsza szkola jazdy a moj projekt mial slozyc jedynie do nauki i nic wiecej. addons.h addons.c serwo+odleglosc.c
  4. Witam, Chcialem zrobic robota w oparciu o ultradzwiekowy czujnik odleglosci HC SR04 zamontowany na serwie w taki sposob aby robot mogl sie "rozgladac" w razie napotkania przeszkody. Wszystko nawet dziala, jednak przy okreslaniu kierunku robot uparcie wskazuje na skrajne prawo (chyba sugeruje zeby glosowac na korwina ) wiec cos tam w srodku nie dziala, tylko pytanie co? Czy ma ktos jakis pomysl? Glowna petla programu (w ktorej na 99,99% znajduje sie blad prezentuje sie tak: #define F_CPU 8000000L //wewnetrzy oscylator #include <avr/io.h> #include <util/delay.h> #include <stdlib.h> #define PWM OCR1B #include "addons.h" #include "HD44780.h" #include <avr/interrupt.h> volatile int flaga=0; //flaga przerwania pomiaru odleglosci unsigned int odleglosc=300; //doyslna wartosc odleglosci ( volatile int flaga_przerwania=0; //flaga przerwania wywolania calej procedury pomiaru unsigned int najdalej=0; //wartosc najwiekszej odleglosci pomiaru int kierunek=0; //zmienna do przechowywania wartosci kierunku jazdy int main(void) { char wynik[4]; //do przechowywania wyniku wyswietlacza alfanumerycznego LCD_Initalize(); //inicjalizacja LCD LCD_GoTo(0, 0); //Ustawienie kursora w pozycji (0,0) LCD_WriteText(" "); //wyczyszczenie wyswietlacza LCD_WriteText("SRV1"); _delay_ms(500); //odczekanie init(); //inicjalizacja wszystkiego while(1) //glowna petla { if(flaga==1) //jesli rozpoczal sie pomiar { odleglosc=0; //zerowanie odleglosci } while(flaga==1) //podczas pomiaru { odleglosc++; //zwiekszaj licznik odleglosci } if(odleglosc<300) //jesli podczas jazdy odleglosc od przeszkody mniejsza niz 300 { najdalej=0; //zerujemy najdalsza odleglosc int i; //zmienna pomocnicza TIMSK &=~(1<<TOIE0); //wylaczanie glownego timera zeby nie przeszkadzal PWM=7000; //obrot czujnika w prawo (pozycja startowa pomiaru) _delay_ms(400); //odczekanie az sie ustabilizuje for(i=0;i<=100;i++) //rozpoczecie jednoczesnego obracania i serii pomiarow { PWM=7000+i*100; //wartosc PWM potrzebna do obrotu _delay_ms(5); //odczekanie na stabilizacje uruchom_pomiar(); //wyzwolenie pomiaru if(flaga==1) //jezeli rozpoczal sie pomiar { odleglosc=0; //zerujemy odleglosc } while(flaga==1) //podczas pomiaru { odleglosc++; //zwiekszamy licznik odleglosci } if(odleglosc>najdalej) //jezeli wykryta odleglosc jest najwyzsza z dotychczas zmierzonych { najdalej=odleglosc; //najdalsza zmierzona odlegloscia zostaje ta spelniajaca powyzszy warunek kierunek=i; //zostaje przypisany kierunek w ktorym robot ma podazac } } TIMSK |=(1<<TOIE0); //po wykonaniu petli przywracamy timer0 PWM=11600; //ustawiamy glowe do pozycji startowej _delay_ms(200); //odczekujemy na ustabilizowanie sie odleglosc=301; //ustawiamy na wszelki wypadek odleglosc na wieksza niz prog zeby sie nie zapetlil przypadkiem } LCD_GoTo(1, 1); //Ustawienie kursora w pozycji (1,1) LCD_WriteText(" "); //czyszczenie poprzednij wartości itoa(odleglosc,wynik,10); //konwersja wyniku do tablicy char LCD_WriteText(wynik); //Wyświetlenie wyniku /*if(flaga_przerwania%5==0) //2 razy na jedno glowne przerwanie aktualizujemy stan toru jazdy(na wszelki wypadek) { if((kierunek>40)&&(kierunek<60)){ prosto();} if(kierunek<=40){ prawo();} if(kierunek>=60){ lewo();} } */ if(flaga_przerwania>=10) //glowne przerwanie { flaga_przerwania=0; //zerujemy flage przerwania uruchom_pomiar(); //wyzwalamy pomiar } } } ISR(INT1_vect) { if(flaga==0) //jesli poza czasem pomiaru { flaga=1; //flaga rozpoczecia pomiaru MCUCR &=~(1<<ISC10); //przerwanie wyzwalane zboczem opadajacym } else if(flaga==1) //jesli w trakcie pomiaru { MCUCR |= (1<<ISC10); //przerwanie wzwalane zboczem narastajacym flaga=0; //zerowanie flagi pomiaru } } ISR(TIMER0_OVF_vect) //glowne przerwanie, zwieksza licznik { flaga_przerwania++; } Prosze o sugestie, na kod mozna smialo narzekac bo jest to wersja robocza, jeszcze przed liftingiem PS odnosnie tego czujnika odleglosci, przy czestych pomiarach podczas obracania serwem czesto zdarza mu sie wykonac zly pomiar, ma ktos jakis pomysl?
  5. Witam, jakis czas temu udalo mi sie zrobic linefollowera, ogolnie projekt powstawal na bazie kodu z artykulu: https://forbot.pl/blog/artykuly/podstawy/algorytm-linefollowera-c-poczatkujacych-id2722 Dziekuje bardzo autorowi tekstu, bez niego robot powstawalby o wiele dluzej. Generalnie uklad pracuje na Atmedze328P taktowanym przez wewnetrzny oscylator 8Mhz, 5 transoptorach CNY70, napedzie roznicowym, motku H sterowanym przez PWM, oraz przetworniku ADC. Na uwage zasluguje tutaj proces kalibracji czujnikow ktore najprawdopodobniej mialy bardzo duze rozrzuty parametrow i powstawaly ciagle problemy z lapaniem przez nie blednych odczytow. W moim procesie kalibracji prog pomiedzy bialym/czarnym jest ustalany osobno dla kazdego z czujnikow co pozwala na zniwelowanie wiekszosci pomylek. W miare powstawania ukladu i dobierania elementow pod katem "byle pasowalo" stawal sie on coraz ciezszy, stad jego mala predkosc. Robot powstawal w celach edukacyjnych, i jak sie potem okazalo pomogl w zaliczeniu przedmiotu na uczelni. Tutaj filmik z dzialania: init.c init.h LinefollowerPierwszy.c
  6. Gratuluje super konstrukcji. Mam jednak pytanie, nie do konca rozumiem w jaki sposob jednostka dowiaduje sie ktory czujnik wykryl linie? czy pojedynczy komparator porownoje odczyty z 2 czujnikow, czy jeden odczyt czujnika porownoje z jakims napieciem odniesienia ? Nie do konca rozumiem to rozwiazanie a wydaje sie byc szalenie dokladne i chcialbym wiedziec jak ono dziala, wiec w miare mozliwosci prosilbym o opis
  7. dzieki, meczylo mnie to od jakiegos czasu a nie oglem nigdzie znalezc zwiezlej odpowiedzi
  8. btw, czy moze ktos mi to wyjasni: PWML = abs(lewy) PWMP = abs(prawy) czy abs() ma za zadanie tutaj przeksztalcac lewy i prawy na wartosc bezwzgledna??
  9. wiem wiem, robi sie wtedy takie PWM z wspolczynikiem wypelnienia kolo 40%(akurat w tym przypadku), ale w tym przypadku to nie jest problemem, chcialem miec poprostu jakiekolwiek informacje o tym czy petla sie wykonuje
  10. ok, dzieki, juz widze czemu nie dzialalo, CNY70 byly podlaczone kolejno do wejsc ADC1...ADC5. ADC0 byl nieuzywany, w sumie to nie patrzylem na schemat, tylko po swojemu kombinowalem, stad ta roznica. Tez sie martwilem nad szybkoscia wykonywania kodu, wlaczylem sobie nawet jednego LEDa zmieniajacego stan jak XOR przy kazdym wykonaniu petli i nie widac nawet momentu gaszenia i zapalania, nawet przy 8 Mhz wiec chyba jest ok, co innego jak zmienilem typ zmiennej progi z int na float - wtedy wyraznie widac bylo zapalanie i gaszenie leda
  11. Witam, Chcialbym odkopac temat, mianowicie u mnie przy uzyciu tego algorytmu powstawal problem z blednymi odczytami z transoptorow CNY70, czasami okazywalo sie ze jeden wykrywal linie a nie powinien itd. Podejrzewam ze wynika to z niejednolitego wykonania transoptorow i innych elementow jak rezystory, straty w stykach itp ktore zaklocaja pomiary, w zwiazku z czym na sztywno ustalany prog pomiedzy czarnym kolorem a bialym moze nie pasowac do wszystkich odczytow z roznych transoptorow cny70. Pomyslalem ze fajnym rozwiazaniem byloby wykorzystanie komparatora,tak aby za kazdym razem robot wybieral najwyzszy odczyt, bez wzgledu na prog itp. Zeby sie nie meczyc postanowilem zaimplementowac komparator programowo. zalozenie bylo takie aby czujniki szukaly najwiekszego odczytu z ADC i wybieraly go jako ten z linia. W efekcie przeksztalcilem funkcje czytad_adc() autora artykulu(ktoremu gratuluje i dziekuje za ciezka prace, wiele sie z niej nauczylem) i usunalem kalibracje. void czytaj_adc() { int i; max=tab_czujnikow[0]; min=tab_czujnikow[0]; for(i=0; i<5; i++) { ADMUX &= 0b11100000; // zerujemy bity MUX odpowiedzialne za wybór kanału (s. 255 w DS) ADMUX |= tab_czujnikow[i]; // wybieramy kanał przetwornika ADCSRA |= _BV(ADSC); // uruchamiamy pomiar while(ADCSRA & _BV(ADSC)) {}; // czekamy aż skończy się pomiar czujniki[i]=ADCH; if(czujniki[i]>max) max=czujniki[i]; //szukamy czujnika z najwyzszym odczytem if(czujniki[i]<min) min=czujniki[i]; //szukamy czujnika z najnizszym odczytem (czysto dydaktycznie) } for(i=0;i<5;i++){ if(czujniki[i]>=max) czujniki[i] = 1; //jezeli odczyt jest rowny badz wiekszy od max to dostaje 1 else czujniki[i] = 0; } Czekam na wasze komentarze odnosnie kodu. BTW czy tylko mi nie dzialal ten algorytm do momentu kiedy zmienilem wartosci int tab_czujnikow[7] = {5,4,3,2,1,0,7}; na int tab_czujnikow[7] = {7,6,5,1,2,3,4}; jak dla mnie powodowalo to bledy przy wybieraniu kanalu ADC (algorytm probowal wybrac kanal 0) Mial ktos podobny problem? [ Dodano: 05-09-2015, 00:44 ] mam ostatnio chyba pecha, wyglada na to ze trafilem jakies trefne CNY70, kazdy ma inne odczyty na wzglednie ta sama powierzchnie. Nie mam innych pod reka wiec pomyslalem ze dobrym sposobem byloby ustawianie progu miedzy czarnym a bialym dla kazdego transoptora z osobna, kalibracja jest 2-etapowa, najpierw wszystkie czujki sa nad czarna linia, a potem wszystkie nad biala. Sprawdza sie to bardzo dobrze, nawet z pewna tolerancja co do wysokosci i faktury podloza. teraz kod wyglada tak: void kalibracja() { int i; for(i=0;i<5;i++){ czarne[i] = 0; ADMUX &= 0b11100000; // zerujemy bity MUX odpowiedzialne za wybór kanału (s. 255 w DS) ADMUX |= tab_czujnikow[i]; // wybieramy kanał przetwornika ADCSRA |= _BV(ADSC); // uruchamiamy pomiar while(ADCSRA & _BV(ADSC)) {}; // czekamy aż skończy się pomiar czarne[i] = ADCH; } // odczyt z czujnika nad białym polem { PORTD |=(1<<LED0)|(1<<LED1)|(1<<LED2)|(1<<LED3)|(1<<LED4); _delay_ms(2000); PORTD &=(1<<LED0)&(1<<LED1)&(1<<LED2)&(1<<LED3)&(1<<LED4); _delay_ms(100); } for(i=0;i<5;i++){ biale[i] = 0; ADMUX &= 0b11100000; // zerujemy bity MUX odpowiedzialne za wybór kanału (s. 255 w DS) ADMUX |= tab_czujnikow[i]; // wybieramy kanał przetwornika ADCSRA |= _BV(ADSC); // uruchamiamy pomiar while(ADCSRA & _BV(ADSC)) {}; // czekamy aż skończy się pomiar biale[i] = ADCH; } for(i=0;i<5;i++){ progi[i]=0; progi[i]=biale[i]+(czarne[i]-biale[i])/2; } PORTD |=(1<<LED0)|(1<<LED1)|(1<<LED2)|(1<<LED3)|(1<<LED4); _delay_ms(200); PORTD &=(1<<LED0)&(1<<LED1)&(1<<LED2)&(1<<LED3)&(1<<LED4); _delay_ms(100); } void czytaj_adc() { int i; min=czujniki[0]; for(i=0; i<5; i++) { ADMUX &= 0b11100000; // zerujemy bity MUX odpowiedzialne za wybór kanału (s. 255 w DS) ADMUX |= tab_czujnikow[i]; // wybieramy kanał przetwornika ADCSRA |= _BV(ADSC); // uruchamiamy pomiar while(ADCSRA & _BV(ADSC)) {}; // czekamy aż skończy się pomiar czujniki[i]=ADCH; if(czujniki[i]>=progi[i]) czujniki[i] = 1; else czujniki[i] = 0; } for(i=0; i<5; i++){ if(czujniki[i]==1) PORTD |=LEDY[i]; _delay_ms(50); PORTD &=~LEDY[i]; _delay_ms(50); } } zrezygnowalem z programowego komparatora ze wzgledu na problem pojawiajacy sie gdy linie wykrywal wiecej niz 1 czujnik. Kod w dalszym ciagu jest jedynie zmodyfikowana wersja autora tematu! moze komus sie przyda moja koncepcja
  12. 1. sprawdz czy w robocie masz poprawnie podlaczony pin RESET do uc oraz GND 2. sprawdz czy masz dobrze przylaczone GND mikrokontrolera 3. ew zwarcia, przerwy w obwodach
  13. no tez mi sie wydawalo ze chodzi o srednia wazona dzieki za wszystkie porady. BTW super forum, a sam blog - majstersztyx
  14. oooo dzieki za artykul. widze ze lata swietlne przede mna do przebycia zabieram sie do roboty
  15. to sie musze sporo douczyc bo nie wiem wogole o co chodzi. mozesz zaprezentowac jakis przyklad?
×
×
  • Utwórz nowe...