Skocz do zawartości

Robot unikający kolizji


mati 6

Pomocna odpowiedź

Podoba Ci się ten projekt? Zostaw pozytywny komentarz i daj znać autorowi, że zbudował coś fajnego!

Masz uwagi? Napisz kulturalnie co warto zmienić. Doceń pracę autora nad konstrukcją oraz opisem.

Pomysłowa konstrukcja 🙂 Pytanie tylko, czy machanie serwem nie odbywa się zbyt szybko? SHARPy znane są z dość dużych stałych czasowych. Dobierałeś jakoś doświadczalnie prędkość skanowania?

Link do komentarza
Share on other sites

Zgadza się. Z tego powodu ograniczona jest prędkość całego robota. Machanie dobierałem doświadczalnie ( ciekawa zabawa, by dodatkowo połączyć to z odpowiednim zapalaniem i gaszeniem diod by wprowadzić efekt synchronizacji). W chwili obecnej wygląda to tak:

->komenda, by serwo przesunęło się o jedną jednostkę ( ok. 10-11 stopni)

-> odczekaj 20ms

-> zgaś diodę, pod którą wcześniej był czujnik

-> odczekaj kolejne 15ms

-> zapal kolejną diodę

-> sprawdź stan czujnika na nowej pozycji

Nie omieszkam pobawić się jeszcze tymi parametrami, by uzyskać jeszcze lepszą synchronizację.

Link do komentarza
Share on other sites

Ciekawa konstrukcja, gratuluję! 🙂

W kwestii programu, nie przekazuj do delay'ów zmiennych, bo będą one rzutowane na typ zmiennoprzecinkowy i program urośnie ci w kobyłę. Sam popełniłem już ten błąd i program, który powinien zajmować 300B, zajmował 4kB 😋

Druga sprawa - nie twórz funkcji z możliwością zwrotu danych wyjściowych, skoro tego nie wykorzystujesz. Wykorzystaj wówczas typ "void". We wszystkich funkcjach masz argumenty typu "int", a wcale nie wykorzystujesz całej długości tych zmiennych. Np. timer od PWM'a masz 16-bitowy, to do OCRx przekazuj argumenty typu "uint16_t" (przecież i tak nie używasz liczb ujemnych 😉 ).

Dobrym nawykiem jest używanie dyrektyw "#define" zamiast wpisywania wszędzie wartości binarnych/heksadecymalnych. Za jakiś czas po prostu będzie ci się trudno odnaleźć w kodzie, który sam napisałeś. Twój kod można bardzo łatwo zoptymalizować, więc może warto się tym zająć 🙂

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

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

Gratuluję konstrukcji, a przede wszystkim tego rysunku ze Sketchupa 🙂

No właśnie, piotreks-89, mnie ubiegł, najpierw przeanalizowałem kod, później przeczytałem komentarze 😉 .

To:

_delay_ms(czas); 
 _delay_ms(z);

Dobrze by było zamienić na:

void czekaj_ms(uint8_t ms)
{
for (uint8_t i=0; i<ms ; i++) _delay_ms(1);
}

i w programie zamiast:

_delay_ms(czas); 
_delay_ms(z);

używać:

czekaj_ms(czas);
czekaj_ms(z);

Za pomocą zmiennych int LEDx zapychasz niepotrzebnie ram, a skoro i tak nie zmieniasz wartości tych zmiennych możesz to zrobić inaczej, omijając zapychanie ramu:

int LED1=0xFE; 
#define LED1 0xFE

Jestem ciekaw ile to by dało oszczędności RAMu i flasha.

Ale oczywiście ilu programistów, tyle rozwiązań 😉

Link do komentarza
Share on other sites

Już nie mówiąc o tym, że cały wielki kawał kodu - poprzez użycie tablicy - zamienia się w kilka prostych operacji:

uint16_t led_bits[] =
   {
       0x0000, 0x0200, 0x0400, 0x0800, 0x1000, 0x0100, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001
   };

void zapal_diode(uint8_t numer_diody)
{
   uint16_t
       mask = (numer_diody < sizeof(led_bits)) ? led_bits[numer_diody] : 0x0000;

   PORTD &= ~(mask >> 8);
   PORTC &= ~mask;
}

Pamiętaj, że programy piszesz dla siebie, nie dla procesora. Inaczej wstukiwałbyś binarne kody instrukcji. Jeżeli diodki są na pewnych bitach portów, w tablicy używaj jedynek na tej pozycji bo to jest dużo bardziej czytelne. Niech procesor sobie to odwróci, szybki jest. Po co odwalasz robotę za niego?

Moja tablica ma słowa 16-bitowe i pobieram maskę od razu dla dwóch portów. Przekazanie argumentu numer_diody=0 powoduje pobranie z indeksu [0] i brak jakiejkolwiek zmiany. Przy zbyt dużym numerku diody ograniczeniem jest porównanie z wielkością tablicy. Wtedy także mask dostaje wartość 0x0000.

Jeżeli chcesz oszczędzić RAM i przechowywać tablicę w pamięci FLASH, przy deklaracji musisz użyć atrybutu PROGMEM a odczyt wykonywać przy pomocy funkcji pgm_read_word().

Link do komentarza
Share on other sites

A ja bym się programu nie czepiał. Najważniejsze że działa, a z czasem można go udoskonalać na wiele sposobów.

Natomiast oszczędzanie pamięci, czy sprytne tablice to nie najlepszy pomysł dla kogoś kto zaczyna. Po pierwsze, to co zaoszczędzimy i tak nie będzie używane... Po drugie łatwo o błąd.

Kod który podał marek1707, zawiera poważny błąd.

sizeof() w języku C zwraca liczbę bajtów zajmowaną przez dany typ lub zmienną. Więc wyrażenie

sizeof(led_bits)

zwróci ile bajtów zajmuje ta tablica. Nie jest to liczba elementów, ale w przypadku typu uint16_t dokładnie dwa razy więcej. Mamy więc przykład programu, w którym nawet ktoś z doświadczeniem może łatwo zrobić błąd.

Przy okazji, kod powinien wyglądać:

    uint16_t 
       mask = (numer_diody < (sizeof(led_bits)/sizeof(led_bits[0])) ? led_bits[numer_diody] : 0x0000; 
Link do komentarza
Share on other sites

Dzięki wszystkim. Nie spodziewałem się aż takiego odzewu.

Niezaprzeczalne, że kod jest do poprawy. Jutro na pewno do tego przysiądę.

Niemniej jednak pierwszorzędną sprawą było dla mnie dostarczenie w pierwszej kolejności działającego kodu, który ( w chwili jego pisania 😃 ) rozumiałem i mogłem łatwo modyfikować. Przypominam, to moje pierwsze połączenie Uc i C.

Za niektóre " błędy " jest mi wstyd już teraz , z niektórych będę się śmiał jutro, a część pewnie będę jeszcze przez długi czas popełniał.

Na tym etapie mikrokontroler jeszcze wiele wybacza, ale macie rację, że to nie powód by robić to byle jak.

Tak czy inaczej nie żałuję, że wstawiłem ten kod. Byłem gotowy na konstruktywną krytykę i jeszcze raz wielkie dzięki za nią.

Jeśli jacyś inni początkujący chcieliby coś zaczerpnąć z takiej konstrukcji to dobrze, by zastali jak najładniejszy kod.

Pozdrawiam

edit: Do czasu poprawy kodu dodałem w pierwszym poście ostrzeżenie o nie-perfekcyjności kodu 🙂

Link do komentarza
Share on other sites

Absolutnie nie traktuj naszych uwag jako czepiania się. Przecież po to jest Forum, by dyskutować. Program, który pierwszego dnia wydaje się fajny, po miesiącu okazuje się żenująco prymitywny nawet dla autora - każdy przez to przechodzi. Dobrze jest wiedzieć, że można go poprawić w wielu miejscach a niektóre konstrukcje nie przyjdą do głowy same - trzeba je zobaczyć. I po to są nasze propozycje. Ja, dzięki czytaniu postów na Forum chyba nauczyłem się BASCOMa "przez dyfuzję", choć (na szczęście) nigdy nie musiałem go używać w praktyce.

Elvis - masz mnie 😥 Na usprawiedliwienie (i auto-pocieszenie) mogę powiedzieć tylko tyle, że nie popełnia błędów ten kto nic nie robi. Pisałem z głowy bardziej zwracając uwagę na bity diodek. Swoją drogą zawsze mnie irytowała ta semantyka sizeof'a choć rozumiem, że autorzy języka musieli wybrać jakiś uniwersalną jednostkę długości niezależną od struktury pamięci komputera ani od wielkości typów podstawowych.

Link do komentarza
Share on other sites

Jestem ciekaw ile to by dało oszczędności RAMu i flasha.

Proszę bardzo, już informuję 🙂

( Zamiast "(uint8_t ms) " użyłem "(uint16_t ms)" ponieważ niektóre delaye są dłuższe.

Stara wersja (info przy kompilacji):


Program:    2362 bytes (28.8% Full)
(.text + .data + .bootloader)

Data:         24 bytes (2.3% Full)
(.data + .bss + .noinit)

Nowa wersja:

Program:    1170 bytes (14.3% Full)
(.text + .data + .bootloader)

Data:          2 bytes (0.2% Full)
(.data + .bss + .noinit)

A zmian przecież tak dużo nie ma 🙂

Wstrzymałem się jeszcze z przebudową funkcji do zapalania diod ( ale faktycznie pomysł Marka1707 jest sprytny 🙂 )

Absolutnie nie traktuj naszych uwag jako czepiania się

Nie jesteśmy w piaskownicy 🙂 Jestem szalenie wdzięczny za wasze uwagi.

Link do komentarza
Share on other sites

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!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.