Skocz do zawartości

malum

Użytkownicy
  • Zawartość

    75
  • Rejestracja

  • Ostatnio

Reputacja

0 Neutralna

O malum

  • Ranga
    4/10

Informacje

  • Płeć
    Mężczyzna
  • Lokalizacja
    Gdańsk
  1. Zdaję sobie z tego sprawę, ale nie bardzo wiem jak rozwiązać ten problem. Dokumentacja też nie wiele mi mówi, chyba że czegoś nie widzę. GP2D12-DATA-SHEET.PDF
  2. Witam! Przymierzam się do zastosowania czujnika Sharp GP2D12 w moim robocie. Podczepiłem go więc do miktokontrolera AtMega8 i napisałem prosty program mający za zadanie zapalić diodę LED, gdy czujnik coś zobaczy. Linijka odpowiedzialna za uruchomienie diody wygląda tak: if(PINB & _BV(6)) PORTC = 0x04; elsr PORTC = 0x00; Program działa, ale dioda zapala się dopiero, gdy czujnik zobaczy coś w odległości co najwyżej 18cm. Przy większej odległości dioda gaśnie. Teoretycznie czujnik powinien działać do 80cm. Postanowiłem więc utworzyć zmienną, która zmieni wartość z 0 na 1 gdy czujnik cokolwiek zobaczy. No i tu pojawił się problem. Nie mogę sobie poradzić z odczytaniem wartości z czujnika. Moją ostatnią wersją było: if(_BV(6)>63) PORTC = 0x04; Dioda świeci się jednak cały czas, a gdy zmieniam wartość na 64 to w ogóle się nie zapala. No i tu pojawia się moje pytanie. Jak za pomocą języka C odczytać wartość z tego czujnika?
  3. Schemat Hornera znam, ale nie spotkałem się nigdy z konstrukcją wynik <<= 1; i szczerze mówiąc nadal nie bardzo rozumiem jak to działa, no i dlaczego w linijce int na10(const char* liczba2) char'a deklarujemy jako stałą?
  4. Faktycznie, ja też przekleiłem mechanicznie bez przeanalizowania - teraz działa. [ Dodano: 04-11-2015, 23:32 ] Szczerze powiem, że tej konstrukcji nie znałem, możesz trochę dokładniej opisać zastosowane polecenia?
  5. Elvis, sprawdziłem działanie tego programu w DevC++ i nie bardzo działa. Po wykonaniu polecenia na10("00110011") otrzymałem 12291, a powinienem otrzymać 51. Czy kompilator C++ skompilował inaczej niż kompilator C?
  6. Założeniem programu jest sterowanie 6 diodami podpiętymi do portów D mikrokontrolera Atmega8, więc teoretycznie wystarczy mi 6 znaków liczby binarnej. Jednak dla lepszego zobrazowania całego portu D zdecydowałem się na użycie 8 znaków. Więcej mi nie potrzeba. Gdyby jednak zaszła taka konieczność to wystarczy sprawdzić wielkość tablicy char'ów i powtórzyć pętlę dokładnie tyle razy. Jeśli chodzi o mnożnik, to oczywiście można pokusić się o zastosowanie schematu Hornera czy choćby potęgowania, ale nie zmniejszy to ani złożoności obliczeniowej, ani pamięciowej tego algorytmu, ponieważ ilość operacji kluczowych będzie dokładnie taka sama. Zaintrygowałeś mnie jednak tym przesuwaniem bitowym - muszę trochę poczytać na ten temat. Na chwilę obecną zostanę przy tej wersji programu, sprawdziłem i działa, więc dla potrzeb testowych mi wystarczy. Jeszcze raz dziękuję bardzo za podsunięcie tego trefnego systemu ósemkowego, na to szybko bym nie wpadł Problem rozwiązany więc temat uważam za zamknięty.
  7. Czyli jak rozumiem proponujesz takie rozwiązanie: int na10(char liczba2[]) { int liczba10=0, mnoznik=1; for(int i=7;i>=0;i--) { liczba10 += (liczba2[i]-48) * mnoznik; mnoznik *= 2; } return liczba10; } Jutro sprawdzę czy to zadziała.
  8. To nie tylko standardowe zadanie na OIG, ale również jeden z podstawowych algorytmów ... i na pewno działa. Problem rozwiązany, a zwycięzcą jest Elvis! Dziękuję bardzo za podpowiedź i rozwiązanie, chociaż teraz mam jeszcze jeden problem Pierwotnym problemem było złe rozumienie liczby przez mikrokontroler. Gdy podawałem 00111111 niby w systemie dziesiętnym, to mikrokontroler rozpoznawał ją jako liczbę ósemkową a nie dziesiętną no i zamiana nie wychodziła. Wystarczyło usunąć te dwa zera na początku i wszystko działa. Drugi problem to sprzeczność z moim założeniem. Chciałem podawać kolejność ledów zawsze z wykorzystaniem całego ciągu 6 lub 8 zer i jedynek. Dla przykładu, jeśli miała się zapalić pierwsza i ostatnia dioda to do funkcji na10 miałem przekazać 00100001, czyli na10(00100001), a gdy miały się zapalić dwie ostatnie, to na10(00000011). Niestety te dwa początkowe zera psują całą koncepcję i wywołania muszą mieć postać na10(100001) oraz na10(11). W ostateczności nie ma tragedii, ale wolałbym jednak podawać całe 0 cyfr. Ma ktoś jakiś pomysł? Na początku myślałem o przekazaniu tablicy znaków string i odwoływaniu się do kolejnych komórek tej tablicy, ale mikrokontroler nie przyjmuje stringa lub brakuje mi jakiejś biblioteki - jakiej?
  9. Dlaczego pomysł jest zły? Teoretycznie podaję liczbę w postaci dziesiętnej, ale gdy obliczam reszty z dzielenia to otrzymuję liczby jednocyfrowe dziesiętne, czyli dokładnie takie jakich oczekuję. Wystarczy przemnożyć je przez kolejne czynniki tworzące rzędy systemu binarnego, czyli 1, 2, 4, 8, 16, 32, ...i otrzymuję wartość dziesiętną danego rzędu. Jest to jeden z klasycznych algorytmów. Bardziej obrazowo wygląda to tak: 00111111(2) = 0*2^7 + 0*2^6 + 1*2^5 + 1*2^4 + 1*2^3 + 1*2^2 + 1*2^1 + 1*2^0 = 0*128 + 0*64 + 1*32 + 1*16 + 1*8 + 1*4 + 1*2 + 1*1 = 0 + 0 + 32 + 16 + 8 + 4 + 2 + 1 = 63(10) Można oczywiście pobawić się w przesyłanie znaków i odejmowanie od każdego z nich wartości 48, czyli wartości zera z tablicy ASCII, ale efekt będzie dokładnie taki sam, a obciążenie pamięci większe. Jeśli chodzi o typ zmiennych to używam nie INT'a a LONG INT'a. Popatrz na zmienną, którą przekazuję do funkcji. Nazywa się LICZBA i jest typu LONG INT. Za pomocą INT'a przechowuję jedynie obliczoną wartość dziesiętną, która nigdy nie będzie większa od 255 więc spokojnie mieści się w typie INT. Czy istnieje jakiś symulator na PC, który pokazuje wartości zmiennych przy przetwarzaniu programu przez mikrokontroler, bo w standardowych kompilatorach jak DEV czy CODE:BLOCK wszystko działa, ale po wgraniu programu do mikrokontrolera już nie . [ Dodano: 03-11-2015, 17:03 ] Chcę uzyskać inny efekt, a mianowicie zamienić liczbę binarną 00111111 (najwyższa wartość, czyli zapalone wszystkie 6 diod) na wartość dziesiętną, czyli 63. Taka liczba binarna ma zaledwie 8 znaków, więc spokojnie mieści się w long int. Próbowałem nawet pracować na long long int, ale efekt był dokładnie taki sam [ Dodano: 03-11-2015, 17:10 ] Podczas doboru typu zmiennych korzystałem z tabelki z artykułu Kurs AVR-GCC cz.3
  10. Witam! Postanowiłem napisać funkcję zamieniającą liczbę podaną w systemie dwójkowym na liczbę zapisaną w systemie dziesiątkowym. Jest to klasyczny algorytm konwersji liczb i gdy kompiluje go w DevC++ to działa, ale gdy wrzucam go do AtMega8 to się sypie. Program testowałem na 6 diodach LED, które mają mrugać w kombinacjach opisanych za pomocą liczby binarnej. Gdy zamieniam tę liczbę na system heksadecymalny (szesnastkowy) lub decymalny (dziesiątkowy) to wszystko działa prawidłowo, ale gdy otrzymuję liczbę dziesiętną z funkcji to kolejność diod jest zupełnie inna. Poniżej funkcja - co jest nie tak? int na10(long int liczba2) { int liczba10=0, mnoznik=1; while(liczba2>0) { liczba10 += (liczba2 % 10) * mnoznik; liczba2 /= 10; mnoznik *= 2; } return liczba10; }
  11. Znasz to serwo czy oceniasz po zdjęciu? Szczerze mówiąc patrząc na zdjęcie to mam wątpliwości, ale jeśli jesteś pewny, to jeden problem jest rozwiązany. [ Dodano: 21-10-2015, 19:57 ] Jak je odróżnić? Czy serwo TowerPro MG996 jest RC czy smart?
  12. Witam! Przymierzam się do wykonania robota klasy minisumo no i oczywiście stanąłem przed problemem wyboru napędu. Zdecydowałem się na przerobione serwomechanizmy z metalowymi zębami. Rozważam poniższe serwa: - Emax ES08MAII (chyba jedne z najszybszych) - TowerPro MG90s (podobne do powyższego, ale nie wiem czy da się przerobić, ponieważ znalazłem jedno zdjęcie rozebranego serwa, gdzie na zębatce jest uskok - czy to takie dziwne zdjęcie czy faktycznie zębatka tak wygląda - uskok pokazany na załączonym zdjęciu?) - TowerPro MG996 (bardzo ciężkie i bardzo mocne, ale cyfrowe - czy da się takie przerobić?) Nie ukrywam, że jednym z ważniejszych składowych jest cena (te powyższe kosztują od 20 do 30zł), oczywiście w połączeniu z wytrzymałością. Czy polecacie te serwa, czy macie może jakieś inne sugestie, no i oczywiście czy da się je przerobić.
  13. Chyba doszedłem, chodzi o przekroczenie zakresu zmiennej Mam jednak inny problem, gdy zbudowałem program bazujący na czułości 128 robot spisywał się bardzo dobrze poruszając się po brązowym linoleum z białymi liniami. Gdy jednak wprowadziłem procedurę uśredniania wszystko diabli wzięli. już piszę o co chodzi. Średnią obliczam na podstawie czujnika 0 i 5. Czujniki mam ułożone w taki sposób: 5 2 1 3 0 4 Gdy po kalibracji na tej samej białej linii na brązowym linoleum zaczynam przesuwać robota na boli, to okazuje się, że czujniki głupieją. Gdy robot stoi z czujnikami 2 i 5 na linii jest wszystko OK, gdy przesunę go na pozycję 1 lub 3 też wszystko gra, ale gdy przesunę na 0 lub 5 zapalają się wszystkie diody. Gdy podniosę robota dzieje się podobnie. Jak sprawdzić jaką wartość ma czułość po wyliczeniu tej średniej, bo nie wiem czy obliczenia są poprawne - brakuje mi chyba monitora do śledzenia wartości zmiennych
  14. Z tym to strzeliłem gafę, chyba ślepy jestem, ale tego to nie rozumiem. Jak zrozumiałem mam obliczyć średnią z dwóch pomiarów, z linii i z tła. Średnia to suma wszystkich pomiarów podzielona przez ich ilość. Czemu więc moja wersja jest niepoprawna?Jeszcze jedno, co to za zmienna i czym różni się od ? Zmienne znalazłem, ale się trochę naszukałem Nazwa typu danych | Długość w bajtach | Zakres wartości int8_t | 1 | -128 ... 127 uint8_t | 1 | 0 ... 255 int16_t | 2 | -32768 ... 32767 uint16_t | 2 | 0 ... 65535 int32_t | 4 | -2147483648 ... 2147483647 uint32_t | 4 | 0 ... 4294967295 int64_t | 8 | -9,22*10^18 ... 9,22*10^18 uint64_t | 8 | 0 ... 1,844*10^19 Czyli uint8_t to odpowiednik zmiennej byte.
  15. No, i o to właśnie chodzi. Czyli mam wykorzystać Twój kod, zapisać w dwóch zmiennych pomiar z czujnika środkowego i bocznego, dodać podzielić przez 2 i wynik przypisać zmiennej czułość? Ale jak zmierzyć tą czułość? Czy wystarczy taki kod (przypominam, że czujniki mam przyczepione do bloku C)? int p1, p2, czulosc; //POCZĄTEK SPRAWDZANIA CZUJNIKA 0 PODŁĄCZONEGO DO PORTU C0 ADMUX = (PC0 + 96); //+96 aby ustawić ADLAR i REFS !!!!!WYBÓR CZUJNIKA ADCSRA |= (1<<ADSC); //start conversion while(bit_is_clear(ADCSRA,ADIF)); //czekaj na koniec pomiaru p1 = ADSC; //POCZĄTEK SPRAWDZANIA CZUJNIKA 1 PODŁĄCZONEGO DO PORTU C1 ADMUX = (PC1 + 96); //+96 aby ustawić ADLAR i REFS !!!!!WYBÓR CZUJNIKA ADCSRA |= (1<<ADSC); //start conversion while(bit_is_clear(ADCSRA,ADIF)); //czekaj na koniec pomiaru p2 = ADSC; czulosc = (p1+p2) / 2;
×
×
  • Utwórz nowe...