Skocz do zawartości

StrongVoltage

Użytkownicy
  • Zawartość

    11
  • Rejestracja

  • Ostatnio

Wszystko napisane przez StrongVoltage

  1. Naprawdę gratuluję podejścia do tematu i chęci, według mnie naprawdę dobrze jest samemu wykonać niektóre elementy wyposażenia warsztatowego. Zawsze zdobędzie się pewną wiedzę i doświadczenie, a sprzęt posłuży dobrze przez spory kawałek czasu. I o ile nie chcę czepiać się już niektórych faktów, ponieważ w poście wyżej temat naprawdę został wyczerpany, to sprawa zabezpieczenia Twojego zasilacza musi być rozwiązana. Jeżeli chcesz by podziałał przez ładny kawałek czasu i był odporny na pomyłki użytkownika (które każdemu nawet przypadkiem mogą się zdarzyć), musisz pomyśleć o ograniczeniu prądowym Twojego zasilacza. Niepotrzebnie narażasz się po prostu na koszta wymiany przetwornic i czas związany z naprawą, nie mówiąc już o uszkodzeniu zasilanego urządzenia. Zostawiam Ci link do filmu Great Scotta o zabezpieczeniu nadprądowym. Jeżeli naprawdę sobie ufasz i uważasz, że nie spalisz układu, przejrzyj chociaż z ciekawości, ta wiedza zawsze się przyda. A nóż jednak dodasz do swojego zasilacza coś od siebie a nie od chińczyka
  2. To prawda, całość ma bardziej formę gadżetu niż specjalistycznego urządzenia. Sprawdza się tylko wtedy, kiedy wiemy jaki gaz mierzymy (wówczas pokrętło ma sens). Hmm, no nie wiem, istnieje możliwość, że w moim przekształceniu jest błąd a mój prowadzący sprawdzający pracę nawet nie schylił się nad tym równaniem ... musiałbym jeszcze raz do tego podejść. Ale jeśli masz czas i umiejętności by przekształcić to równanie i mnie sprawdzić, to śmiało. Ta wiedza nie pójdzie na marne a człowiek uczy się na błędach. Jeżeli znajdziesz błąd i mi go przedstawisz, będę naprawdę wdzięczny
  3. Jeżeli podasz w wartość 5k jako zmienną w kodzie, wszystko powinno działać prawidłowo. Mam nadzieję, że to trochę pomogło. Z czystej ciekawości, do czego użyjesz tego modułu?
  4. Tak, jeśli widzi Ci się inna wartość tego rezystora, możesz ją zastąpić. W dokumentacji jest napisane dla jakiej wartości RL wykonane są wykresy, by można było je poprawnie odczytać. Nie rozumiem dlaczego miałbyś wymieniać ten rezystor?
  5. Moduł który pokazujesz ma już zamontowane wszystko co trzeba, by cały czujnik (ten w metalowej obudowie) działał. Ja używałem samego czujnika, bez płytki z wyprowadzeniami i potencjometru używałem na płytce stykowej. Potencjometr który widać na zdjęciu reguluje nastawę komparatora, wyznacza próg w którym moduł ma pokazywać stan niski/ wysoki. Rezystor RL jest gdzieś na tej płytce, ale niestety nie widzę wyraźnie ścieżek żeby powiedzieć gdzie jest dokładnie.
  6. Robc to rezystancja którą podaje się na wyjściu czujnika w celu utworzenia dzielnika napięcia. Czujnik w formie "surowej" nie poda żadnego napięcia, dlatego trzeba tą informację wyprowadzić budując dzielnik napięcia. W nocie katalogowej czujnika parametr ten nazywany jest RL (load resistance) i może być dowolny. Wyprowadzałem zależność na wartość tej rezystancji, ale ponieważ nie wpływa ona czysto matematycznie na wartość PPM gazu, nie zawarłem jej w pracy i zapodziałem obliczenia. 5.6k zostało dobrane eksperymentalnie po przez dostrajanie potencjometru 10k i sprawdzanie na serial monitorze "zmiany" odczytów dla (względnie) czystego powietrza. Najbliżej wartości współczynnika 9.83 znajdowało się w moim przypadku 5.6k.
  7. Słowem wstępu, projekt ten został wykonany w czasie pandemicznego wymogu pozostania w domu, kiedy to zbliżał się koniec semestru na mojej uczelni. Był to mój projekt zaliczeniowy z przedmiotu o wdzięcznej nazwie: "Układy mikroprocesorowe". Prowadzący udostępnił listę urządzeń, z której każdy może wybrać jedno. Po dokonaniu wyboru należało wykonać je w warunkach domowych do końca wówczas trwającego miesiąca. Jako że był to dość niewygodny moment do wychodzenia po części do sklepu, a na zamówienie ich i czekanie nie chciałem marnować czasu, zrobiłem szybki przegląd swojego warsztatu. Wśród przewalających się podzespołów i elementów udało mi się dostrzec czujnik gazów MQ-2, który kiedyś kupiłem w promocji wraz z czujnikami alkoholu MQ-3. Jako że na liście widniał czujnik gazów, niewiele myśląc zebrałem to co miałem i przystąpiłem do pracy. Efektem tej pracy jest właśnie... DETEKTOR GAZÓW W POWIETRZU ATMOSFERYCZNYM OPARTY NA CZUJNIKU MQ-2 Detektor gazów przystosowano do pomiaru stężeń czterech gazów: LPG, dymu, CO oraz H2. Urządzenie zaprojektowano tak, by miało kompaktową obudowę i prosty, intuicyjny interfejs użytkownika. Wszystkie elementy tego interfejsu opisano na rysunku 1. Gaz którego odczyt ma zostać dokonany, zostaje wybrany za pomocą pokrętła głównego. Zgodnie z jego nastawą detektor będzie przeliczał odczyty czujnika pod wybrany gaz i wyświetli wynik na skali ledowej, znajdującej się po lewej stronie urządzenia. Wartości zmierzonych stężeń przelicza się na jednostkę PPM (Part Per Milion). W zależności od wysokości stężenia, skala LED pokazuje nie tylko zakres, ale także za pomocą odpowiedniej barwy pokazuje czy dany gaz znajduje się w strefie małego, umiarkowanego czy też dużego niebezpieczeństwa. rysunek 1. opis elementów detektora Urządzenie nie jest skomplikowane zarówno w swojej budowie, ale także w działaniu. Cały proces zachodzący pod obudową wykonaną z PLA opisuje schemat algorytmu na rysunku 2. rysunek 2. schemat algorytmu detektora Czytając schemat elektryczny umieszczony na rysunku 3., od lewej strony widzimy źródło zasilania, którym są akumulatory li-ion o napięciu 4.2 [V] każdy. Układ może być zamiast z akumulatorów zasilany z zasilacza o napięciu od 9 do 12 [V], o wydajności minimum 1.5 [A]. Po załączeniu układu przyciskiem “start” zasilanie prowadzone jest na dwa stabilizatory liniowe LM7805. Jeden z nich zasila mikrokontroler oraz interfejs urządzenia, a drugi odpowiada za zasilenie czujnika MQ-2. Zastosowanie dwóch stabilizatorów wiąże się z zapotrzebowaniem czujnika na prąd. Aby nie wprowadzać zakłóceń w działaniu mikrokontrolera, czujnik zasilany jest osobno a sam stabilizator jest chłodzony dodatkowo radiatorem. Sercem urządzenia jest mikrokontroler Atmega328PU. Zastosowano go ze względu na odpowiednio dużą liczbę dostępnych portów oraz wbudowany przetwornik analogowo- cyfrowy. Mikrokontroler przyjmuje sygnał analogowy z czujnika gazów na pin A1, analizuje go, sprawdza nastawę przełącznika “S1” po przez weryfikację stanów portów A2-A5, a na koniec wyświetla wynik za pomocą diod LED podpiętych pod porty PD0-PD7 oraz PB0. Oprócz tego, układ podłączony jest do 10-cio pinowego gniazda CANDA, które umożliwia programowanie mikrokontrolera bez konieczności rozbierania urządzenia i wyjmowania Atmegi328PU. rysunek 3. schemat elektryczny detektora gazów Płytę główną detektora zaprojektowano przy pomocy programu Cadsoft Eagle. Wykonany w nim wzór został przeniesiony na miedziany laminat za pomocą metody termicznej, a następnie wytrawiony nadsiarczanem sodowym. rysunek 4. Po lewej projekt PCB, po prawej zmontowana płytka Obudowa została zaprojektowana w programie Fusion360. Rzut na model złożony w programie cadowskim ukazano na rysunku 5. Na podstawie utworzonego modelu wykonano wydruki 3D, które po oszlifowaniu oraz wyczyszczeniu skompletowały projekt i umożliwiły zabudowę elektroniki w kompaktowej obudowie. rysunek 5. model obudowy w Fusion360 Jednym z najważniejszych etapów konstruowania detektora było wyprowadzenie liniowej zależności na stężenie gazu. Nota katalogowa czujnika przedstawia charakterystykę PPM w skali logarytmicznej. Wyprowadzenie wzoru było konieczne aby umożliwić mikrokontrolerowi wykonywanie obliczeń: a) wyprowadzenie zależności ogólnej: a = (Y2 – Y1) : (X2 – X1) Y - Y1 = a*(X- X1) X= ((Y – Y1) : a) + X1 logX= ((log(Y – Y1)) : a) + X1 X = 10^ (((log(Y – Y1)) : a) + X1) gdzie: X= PPM, Y= Rs: Ro PPM = 10^ (((log((Rs: Ro) – Y1)) : a) + X1) b) przykład aplikacji wzoru dla odczytu stężenia gazu LPG w powietrzu: X1 = 200, X2 = 10000, Y2 = 1,6, Y1 = 0,26 X1 = log200 = 2,3 X2 = log10000 = 4 Y1 = log1,6 = 0,2 Y2 = log0,26 = -0,58 PPM = 10^ (((log((Rs: Ro) – 0,2)) : (-0,58)) + 2,3) rysunek 6. po lewej charakterystyka PPM= f(Rs/Ro) z datasheet MQ-2, po prawej charakterystyka PPM=f(Uo) wykonana na bazie obliczeń w programie Graph 4.4.2 Film z prezentacji działania urządzenia: Na koniec udostępniam jeszcze kod napisany w środowisku Atmel Studio: #define F_CPU 16000000 #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> int main(void) { //Deklaracja portów wyjściowych DDRD = (1 << PORTD0) | (1 << PORTD1) | (1 << PORTD2) | (1 << PORTD3) | (1 << PORTD4) | (1 << PORTD5) | (1 << PORTD6) | (1 << PORTD7); DDRB = (1 << PORTB0) | (1 << PORTB1); //Deklaracja portów wejściowych DDRC = 0x00; //Załączenie rezystorów podciągających do portów A2- A5 PORTC = 0x3C; //Skala ledowa zaczyna się ładować, aby po dotarciu do wartości maksymalnej uruchamić krótki, podwójny brzęk buzzera informujący o rozpoczęciu kalibracji czujnika PORTB |= (1<<PORTB0); _delay_ms(300); PORTD |= (1<<PORTD7); _delay_ms(300); PORTD |= (1<<PORTD6); _delay_ms(300); PORTD |= (1<<PORTD5); _delay_ms(300); PORTD |= (1<<PORTD4); _delay_ms(300); PORTD |= (1<<PORTD3); _delay_ms(300); PORTD |= (1<<PORTD2); _delay_ms(300); PORTD |= (1<<PORTD1); _delay_ms(300); PORTD |= (1<<PORTD0); _delay_ms(300); PORTB |= (1<<PORTB1); _delay_ms(300); PORTB &= ~(1<<PORTB1); _delay_ms(300); PORTB |= (1<<PORTB1); _delay_ms(300); PORTB &= ~(1<<PORTB1); _delay_ms(100); //Ustawienia rejestrów do obsługi przetwornika analogowo-cyfrowego: ADMUX = (1 << REFS0) | ( 1 << MUX0 ); ADCSRA = (1 << ADEN) | (1 << ADIE) | (1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2); DIDR0 = (1 << ADC0D); ADCSRA |= (1 << ADSC); TCCR0B = (1 << CS00) | (1 << CS02); //Deklaracja mierzonej wartości napięcia: double pomiar_V; //Parametry krzywej gazu LPG: double LPG_X1 = 2.3; double LPG_Y1 = 0.2; double LPG_a = 0.46; //Parametry krzywej dymu: double SMOKE_X1 = 2.3; double SMOKE_Y1 = 0.56; double SMOKE_a = 0.5; //Parametry krzywej tlenku węgla: double CO_X1 = 2.3; double CO_Y1 = 0.7; double CO_a = 0.31; //Parametry krzywej wodoru: double H2_X1 = 2.3; double H2_Y1 = 0.32; double H2_a = 0.45; //Parametry kalibracji czujnika: double ilosc_probek_kalibracyjnych = 60; double czas_probkowania_kalibracyjnego = 500; double rezystancja_Robc = 5.6; double wsp_czystosci_powietrza = 9.83; //Parametry próbkowania napięcia: double ilosc_probek_pomiarowych = 60; double czas_probkowania_pomiarowego = 5; double Rs_do_Ro = 0; //Zmienna zliczania: int i = 0; //Zmienna zliczająca- suma: int suma = 0; //Deklaracja Ro: double Ro = 0; //***********************kalibracja czujnika**************************: //W pętli "for" odczytywane jest napięcie z czujnika gazu. Czujnik jest //wystawiony na czyste powietrze. Kalibracja polega na wyznaczeniu rezy- //stanchi Ro dla czystego powietrza. Po kazdej pętli odczytane napięcie //jest sumowane. Suma tych napięć po zakończeniu pętli jest dzielona //przez liczbę próbek, otrzymując średnią wartość rezystancji. Wartość ta //podzielona przez współczynnik czystego powietrza (9.83) daje rezysta- //ncje Ro, na której będą oparte następne obliczenia. Obliczenia te wy- //konywane są raz. for (i=0;i<ilosc_probek_kalibracyjnych;i++) { pomiar_V = ADC; ADCSRA |= (1 << ADSC); Ro = ((1024-pomiar_V)/pomiar_V)*rezystancja_Robc; _delay_ms(czas_probkowania_kalibracyjnego); suma = suma+Ro; } Ro = suma/ilosc_probek_kalibracyjnych; Ro = Ro/wsp_czystosci_powietrza; //Opadanie wskazania ledowego i podwójny sygnał z buzzera informuje użytkownika o zakończeniu klibracji urządzenia PORTD &= ~(1<<PORTD0); _delay_ms(300); PORTD &= ~(1<<PORTD1); _delay_ms(300); PORTD &= ~(1<<PORTD2); _delay_ms(300); PORTD &= ~(1<<PORTD3); _delay_ms(300); PORTD &= ~(1<<PORTD4); _delay_ms(300); PORTD &= ~(1<<PORTD5); _delay_ms(300); PORTD &= ~(1<<PORTD6); _delay_ms(300); PORTD &= ~(1<<PORTD7); _delay_ms(300); PORTB &= ~(1<<PORTB0); _delay_ms(300); PORTB |= (1<<PORTB1); _delay_ms(300); PORTB &= ~(1<<PORTB1); _delay_ms(300); PORTB |= (1<<PORTB1); _delay_ms(300); PORTB &= ~(1<<PORTB1); _delay_ms(100); while(1) { //Zmienna zliczania: int j = 0; //Zmienna zliczająca- razem: int razem = 0; //Deklaracja liczonej rezystancji czujnika: double Rs = 0; //************************pomiar z czujnika************************: //W pętli "for" wyliczana jest wartość rezystancji na podstawie na- //pięcia z czujnika gazu. Obliczane rezystancje są sumowane. Po za- //kończeniu pętli, suma rezystancji jest dzielona przez liczbę pró- //bek i otrzymujemy przybliżony odczyt rezystancji czujnika. for (j=0;j<ilosc_probek_pomiarowych;j++) { pomiar_V = ADC; ADCSRA |= (1 << ADSC); Rs = ((1024-pomiar_V)/pomiar_V)*rezystancja_Robc; razem = razem + Rs; _delay_ms(czas_probkowania_pomiarowego); } Rs = razem/ilosc_probek_pomiarowych; //Znając Rs oraz Ro obliczamy ich stosunek i podstawiamy do wzoru //na zawartość cząstek LPG w powietrzu. Rs_do_Ro = Rs/Ro; _delay_ms(10); //Zawartość PPM gazu LPG w powietrzu: if (!(PINC & 0b00100000)) { double PPM = 0; PPM = pow(10,((log(Rs_do_Ro - LPG_Y1)/((-1)*LPG_a)) + LPG_X1)); _delay_ms(10); if ((PPM >= 0)&&(PPM <= 500)) { PORTB = 0b00000001; PORTD = 0b00000000; } if ((PPM >= 500)&&(PPM <= 1000)) { PORTB = 0b00000001; PORTD = 0b10000000; } if ((PPM >= 1000)&&(PPM <=2000)) { PORTB = 0b00000001; PORTD = 0b11000000; } if ((PPM >= 2000)&&(PPM <=5000)) { PORTB = 0b00000001; PORTD = 0b11100000; } if ((PPM >= 5000)&&(PPM <=7500)) { PORTB = 0b00000001; PORTD = 0b11110000; } if ((PPM >= 7500)&&(PPM <=10000)) { PORTB = 0b00000001; PORTD = 0b11111000; } if ((PPM >= 10000)&&(PPM <=15000)) { PORTB = 0b00000001; PORTD = 0b11111100; } if ((PPM >= 15000)&&(PPM <=20000)) { PORTB = 0b00000001; PORTD = 0b11111110; } if (PPM >= 20000) { PORTB = 0b00000001; PORTD = 0b11111111; } } //Zawartość PPM dymu w powietrzu: if (!(PINC & 0b00010000)) { double PPM = 0; PPM = pow(10,((log(Rs_do_Ro - SMOKE_Y1)/((-1)*SMOKE_a)) + SMOKE_X1)); _delay_ms(10); if ((PPM >= 0)&&(PPM <= 500)) { PORTB = 0b00000001; PORTD = 0b00000000; } if ((PPM >= 500)&&(PPM <= 1000)) { PORTB = 0b00000001; PORTD = 0b10000000; } if ((PPM >= 1000)&&(PPM <=2000)) { PORTB = 0b00000001; PORTD = 0b11000000; } if ((PPM >= 2000)&&(PPM <=5000)) { PORTB = 0b00000001; PORTD = 0b11100000; } if ((PPM >= 5000)&&(PPM <=7500)) { PORTB = 0b00000001; PORTD = 0b11110000; } if ((PPM >= 7500)&&(PPM <=10000)) { PORTB = 0b00000001; PORTD = 0b11111000; } if ((PPM >= 10000)&&(PPM <=15000)) { PORTB = 0b00000001; PORTD = 0b11111100; } if ((PPM >= 15000)&&(PPM <=20000)) { PORTB = 0b00000001; PORTD = 0b11111110; } if (PPM >= 20000) { PORTB = 0b00000001; PORTD = 0b11111111; } } //Zawartość PPM CO w powietrzu: if (!(PINC & 0b00001000)) { double PPM = 0; PPM = pow(10,((log(Rs_do_Ro - CO_Y1)/((-1)*CO_a)) + CO_X1)); _delay_ms(10); if ((PPM >= 0)&&(PPM <= 500)) { PORTB = 0b00000001; PORTD = 0b00000000; } if ((PPM >= 500)&&(PPM <= 1000)) { PORTB = 0b00000001; PORTD = 0b10000000; } if ((PPM >= 1000)&&(PPM <=2000)) { PORTB = 0b00000001; PORTD = 0b11000000; } if ((PPM >= 2000)&&(PPM <=5000)) { PORTB = 0b00000001; PORTD = 0b11100000; } if ((PPM >= 5000)&&(PPM <=7500)) { PORTB = 0b00000001; PORTD = 0b11110000; } if ((PPM >= 7500)&&(PPM <=10000)) { PORTB = 0b00000001; PORTD = 0b11111000; } if ((PPM >= 10000)&&(PPM <=15000)) { PORTB = 0b00000001; PORTD = 0b11111100; } if ((PPM >= 15000)&&(PPM <=20000)) { PORTB = 0b00000001; PORTD = 0b11111110; } if (PPM >= 20000) { PORTB = 0b00000001; PORTD = 0b11111111; } } //Zawartość PPM H2 w powietrzu: if (!(PINC & 0b00100000)) { double PPM = 0; PPM = pow(10,((log(Rs_do_Ro - H2_Y1)/((-1)*H2_a)) + H2_X1)); _delay_ms(10); if ((PPM >= 0)&&(PPM <= 500)) { PORTB = 0b00000001; PORTD = 0b00000000; } if ((PPM >= 500)&&(PPM <= 1000)) { PORTB = 0b00000001; PORTD = 0b10000000; } if ((PPM >= 1000)&&(PPM <=2000)) { PORTB = 0b00000001; PORTD = 0b11000000; } if ((PPM >= 2000)&&(PPM <=5000)) { PORTB = 0b00000001; PORTD = 0b11100000; } if ((PPM >= 5000)&&(PPM <=7500)) { PORTB = 0b00000001; PORTD = 0b11110000; } if ((PPM >= 7500)&&(PPM <=10000)) { PORTB = 0b00000001; PORTD = 0b11111000; } if ((PPM >= 10000)&&(PPM <=15000)) { PORTB = 0b00000001; PORTD = 0b11111100; } if ((PPM >= 15000)&&(PPM <=20000)) { PORTB = 0b00000001; PORTD = 0b11111110; } if (PPM >= 20000) { PORTB = 0b00000001; PORTD = 0b11111111; } } //Po dotarciu do końca komendy, pętla rozpoczyna się od począ- //tku mierząc jeszcze raz napięcie na czujniku. _delay_ms(100); } return(0); } Jeżeli dotrwaliście aż do tego momentu, to bardzo dziękuje wam za uwagę. Mam nadzieję, że ten projekt będzie pomocny dla każdej osoby rozpoczynającej swoje przygody z czujnikiem gazu MQ-2. Osobiście jestem zadowolony z rezultatu jaki osiągnąłem tym projektem. Mam jednak do niego sporo zastrzeżeń i kiedy będę miał możliwość, planuję do niego wrócić wprowadzając następujące zmiany: Skala ledowa zostanie zastąpiona wyświetlaczem 2x16 aby widzieć dokładny odczyt PPM wybranego gazu. Urządzenie zostanie wyposażone we własne źródło zasilania. Atmega328 będzie zastąpiona przez mikrokontroler atmega8. Obudowa zostanie lepiej uszczelniona. Czujnik zostanie wyprowadzony na długim przewodzie jako sonda, którą można umieścić w dowolnym miejscu. W programie napisane zostanie proste menu, dzięki czemu będzie można wygodnie wybrać gaz, przeprowadzić kalibrację (aby wyeliminować czekanie po uruchomieniu i pamiętać stałą wartość czujnika) oraz opcjonalnie zmienić współczynnik czystego powietrza. Przydatny link: Wyjaśnienie działania czujnika MQ-2 https://sandboxelectronics.com/?p=165
  8. Zawsze zastanawiałem się nad działaniem i obsługą tego modułu oraz jego rodziny. Jednym z planowanych przeze mnie projektów na przyszłość jest właśnie mała frezarka. Wielkie dzięki za ten artykuł, bardzo dobrze wyjaśnił mi moje wątpliwości i odpowiedział na pytania związane z obsługą tego modułu
  9. Słowem wstępu, wyobraźmy sobie że jesteśmy na słonecznej, piaszczystej plaży wzdłuż której rosną wysokie, bogate w orzechy kokosowe palmy. Pod jedną z nich stoi lokalny, doświadczony, zbieracz kokosów, u którego mamy zamiar nauczyć się tego ciężkiego rzemiosła. Jako zaledwie początkujący adepci tej trudnej sztuki, nie mamy jednak zielonego pojęcia jak się do tego zabrać. Dlatego nasz nowy mentor musi nam wytłumaczyć co i jak powinniśmy zrobić. Może on nam wytłumaczyć wszystko krok po kroku. Opisać dokładne pozycje naszych kończyn, prędkość z jaką będziemy się wspinać i sposób odbierania kokosu. Oczywiście opisanie nam tego na tyle dokładnie, byśmy mogli bezbłędnie przystąpić do pracy wymagałoby dużo czasu i energii. Zamiast tego, może pokazać nam osobiście jak to zrobić i dać nam przystąpić do pracy. W krótkim i bogatym w informacje czasie, będziemy wiedzieli jak przystąpić do pracy. Ten wpis brał udział konkursie na najlepszy artykuł o elektronice lub programowaniu. Sprawdź wyniki oraz listę wszystkich prac » Partnerem tej edycji konkursu (marzec 2020) był popularny producent obwodów drukowanych, firma PCBWay. Po tym ciut przydługawym wstępie, którym starałem się nakreślić pewien problem, możemy przystąpić do właściwego omówienia tematu. Istnieje wiele metod programowania robotów przemysłowych (manipulatorów). Wykonują one precyzyjne prace, wymagające wielu skomplikowanych ruchów. Jednak poza nimi, roboty mogą też wykonywać mniej skomplikowane ruchy np. podczas zmiany pozycji lub przełączenia między poszczególnymi pracami. O ile do wykonania operacji precyzyjnych niezbędny jest szczegółowo opracowany program, o tyle podczas ruchów mniej skomplikowanych czas programowania można ukrócić do metod Online Programming. Krótki film przedstawiający podział metod programowania Metody te pozwalają operatorowi manualnie lub za pomocą odpowiedniego kontrolera ustawić poszczególne pozycje robota, które zostaną przez niego zapamiętane w czasie bieżącym oraz odtworzone w postaci pożądanego przez nas ruchu. Programowanie robota spawalniczego przy pomocy metody teach-in Programowanie robota Festo BionicCobot przy pomocy metody play-back Programowanie play-back opiera się na sczytywaniu przez oprogramowanie pozycji robota, zapisywanie ich oraz odtwarzanie poprzez bezpośrednie poruszanie jego konstrukcją. Aby było to możliwe, każdy stopień swobody robota musi posiadać sensor umożliwiający określenie jego dokładnej pozycji. Oprócz tego napęd robota musi działać w wyrachowany i delikatny sposób, aby konstrukcja była jednocześnie sztywna i można było nią poruszać ręcznie. Programowanie teach-in z kolei polega na ustawieniu robota w ustalonych pozycjach za pomocą odpowiedniego kontrolera, za pomocą którego te pozycje zostaną zapisane a następnie odtworzone. Odtwarzanie kolejno zapisanych pozycji daje w efekcie płynny, ciągły ruch maszyny. Wyżej wspomniane metody omówimy na realnym przykładzie. Za pomocą kontrolera będziemy mogli stosować na prostym manipulatorze metodę teach-in. Robot napędzany jest serwami modelarskimi oraz wykonany w technice druku 3D. Serwa posiadają wbudowane potencjometry sczytujące pozycje kątowe wałów, jednak bez ingerencji w ich budowę ciężko będzie korzystać z tych potencjometrów do określania pozycji robota. Dlatego manualne ustawienie pozycji manipulatora metodą play-back wypada z puli naszych opcji. Poza tym istniałaby duża szansa na uszkodzenie stosowanych w robocie serw. Zamiast tego, posłużymy się kontrolerem, który będzie kinetycznym modelem naszego manipulatora i pozwoli także zahaczyć o ideę play-back. Ramię manipulatora wydrukowane w 3D, poniżej link do źródła https://www.thingiverse.com/thing:1015238 Kontroler odpowiada kinematyce prezentowanego robota i ma umieszczone potencjometry w każdym jego punkcie swobody. Poruszając nim, możemy ustalić rzeczywistą pozycję naszego manipulatora. Budując r obota o mniej skomplikowanej budowie, możemy pozostać przy samych potencjometrach np. zamontowanych na płytce stykowej. Jednak w przypadku tego robota korzystanie z tego rozwiązania byłoby trudniejsze i mniej wygodne w użytku. Model kinematyczny manipulatora Znając już budowę kontrolera oraz manipulatora, należy je już tylko do siebie podłączyć. Oprócz tego do układu dodane zostaną przyciski nagrywania oraz odtwarzania ruchu. Elektronika opiera się o mikrokontroler atmega328p. Zasilanie układu odbywa się z sieci napięciem 230 V. W obudowie znajduje się układ prostujący, przetwornica step-down zasilająca serwomechanizmy oraz płytka arduino ze wspomnianym wcześniej mikrokontrolerem. Dla wygody wszystkie piny arduino zostały wyprowadzone na zewnątrz obudowy. Cały schemat przedstawianej konstrukcji znajduje się poniżej: Schemat układu Lista opisanych komponentów: -S1 – włącznik główny, -S2 – przycisk nagrywania, -S3 – przycisk odtwarzania, -D1 – mostek Graetza 400V ; 4A, -D2 – zielona dioda LED, -C1 – kondensator elektrolityczny 1000µF ; 50V, -C2 – kondensator elektrolityczny 220µF ; 25V, -C3 – kondensator elektrolityczny 22µF ; 25V, -C4 – kondensator ceramiczny 100nF, -C5 – kondensator ceramiczny 22pF, -C6 – kondensator ceramiczny 22pF, -C7 – kondensator ceramiczny 100nF, -R1 – rezystor 150 Ω, -R2, R3, R4 – rezystor 1 kΩ, -POT 1, POT 2, POT 3, POT 4, - 10 kΩ, -Stabilizator napięcia LM7805, -Przetwornica step-down LM2596, -X1 – kwarc 16 MHz, Połączenie układu Po podłączeniu całej elektroniki można przystąpić do omówienia kodu arduino. Program ten został już zaopatrzony w bogatą ilość komentarzy, które na pewno pomogą osobom dopiero rozpoczynającym swoją przygodę z arduino: //biblioteka umożliwiająca nie tylko sterowanie serwami, ale także ich prędkością //nie jest ona koniecznością, wystarczy standardowa biblioteka <servo.h> oraz pozbycie się zmiennej 'predkosc' z koduć #include <VarSpeedServo.h> //definiujemy serwa używane w robocie: VarSpeedServo servo1; VarSpeedServo servo2; VarSpeedServo servo3; VarSpeedServo servo4; //definiujemy przyciski nagrywania i odtwarzania: const int przycisk_A = 2; const int przycisk_B = 3; //definiujemy wartości dla wciśniętych przycisków nagrywania i odtwarzania: int przycisk_A_ON = 0; boolean przycisk_B_ON = false; //definiujemy potencjometry: const int potencjometr1 = A0; const int potencjometr2 = A1; const int potencjometr3 = A2; const int potencjometr4 = A3; //definiujemy zmienne służące do odczytu wartości napięć z potencjometrów: int potencjometr_1_odczyt; int potencjometr_2_odczyt; int potencjometr_3_odczyt; int potencjometr_4_odczyt; //definiujemy zmienne służące do zapisu wartości kąta położenia poszczególnego serwa: int potencjometr_1_zapis; int potencjometr_2_zapis; int potencjometr_3_zapis; int potencjometr_4_zapis; //definiujemy tablice zapisujące położenie serwa: int Pozycja_serva1[]={1,1,1,1,1}; int Pozycja_serva2[]={1,1,1,1,1}; int Pozycja_serva3[]={1,1,1,1,1}; int Pozycja_serva4[]={1,1,1,1,1}; void setup() { //definiujemy piny do których podłączone są serwa: servo1.attach(6); servo2.attach(9); servo3.attach(10); servo4.attach(11); //definiujemy piny wejściowe przycisków nagrywania i odtwarzania: pinMode(przycisk_A, INPUT_PULLUP); pinMode(przycisk_B, INPUT_PULLUP); //inicjalizacja portu szeregowego do podglądu działania programu: Serial.begin(9600); } void loop() { //ustalanie prędkości serw w zakresie od 0 do 180: int predkosc = 90; //zapis formuły umieszczania odczytanej z potencjometrów wartości do tabeli: potencjometr_1_odczyt = analogRead(potencjometr1); potencjometr_1_zapis = map (potencjometr_1_odczyt, 0, 1023, 20, 175); potencjometr_2_odczyt = analogRead(potencjometr2); potencjometr_2_zapis = map (potencjometr_2_odczyt, 0, 1023, 5, 175); potencjometr_3_odczyt = analogRead(potencjometr3); potencjometr_3_zapis = map (potencjometr_3_odczyt, 0, 1023, 5, 175); potencjometr_4_odczyt = analogRead(potencjometr4); potencjometr_4_zapis = map (potencjometr_4_odczyt, 0, 1023, 20, 160); //serwa przyjmują pozycje zapisane w tabelach: servo1.write(potencjometr_1_zapis, predkosc); servo2.write(potencjometr_2_zapis, predkosc); servo3.write(potencjometr_3_zapis, predkosc); servo4.write(potencjometr_4_zapis, predkosc); //przy kolejnym wciśnięciu przycisku nagrywania tabela każdego serwa zostanie //nadpisana, zapamiętując obecną pozycję serwa: if(digitalRead(przycisk_A) == HIGH) { przycisk_A_ON++; switch(przycisk_A_ON) { case 1: Pozycja_serva1[0] = potencjometr_1_zapis; Pozycja_serva2[0] = potencjometr_2_zapis; Pozycja_serva3[0] = potencjometr_3_zapis; Pozycja_serva4[0] = potencjometr_4_zapis; Serial.println("Pozycja pierwsza zapisana"); break; case 2: Pozycja_serva1[1] = potencjometr_1_zapis; Pozycja_serva2[1] = potencjometr_2_zapis; Pozycja_serva3[1] = potencjometr_3_zapis; Pozycja_serva4[1] = potencjometr_4_zapis; Serial.println("Pozycja druga zapisana"); break; case 3: Pozycja_serva1[2] = potencjometr_1_zapis; Pozycja_serva2[2] = potencjometr_2_zapis; Pozycja_serva3[2] = potencjometr_3_zapis; Pozycja_serva4[2] = potencjometr_4_zapis; Serial.println("Pozycja trzecia zapisana"); break; case 4: Pozycja_serva1[3] = potencjometr_1_zapis; Pozycja_serva2[3] = potencjometr_2_zapis; Pozycja_serva3[3] = potencjometr_3_zapis; Pozycja_serva4[3] = potencjometr_4_zapis; Serial.println("Pozycja czwarta zapisana"); break; case 5: Pozycja_serva1[4] = potencjometr_1_zapis; Pozycja_serva2[4] = potencjometr_2_zapis; Pozycja_serva3[4] = potencjometr_3_zapis; Pozycja_serva4[4] = potencjometr_4_zapis; Serial.println("Pozycja piąta zapisana"); break; } } //po wciśnięciu przycisku odtwarzania serwa będą przyjmować zapisane w tabelach pozycje //z odczekaniem 1.5 sekund w każdej pozycji: if(digitalRead(przycisk_B) == HIGH) { przycisk_B_ON = true; } if(przycisk_B_ON) { for(int i=0; i<5; i++) { servo1.write(Pozycja_serva1[i],predkosc); servo2.write(Pozycja_serva2[i],predkosc); servo3.write(Pozycja_serva3[i],predkosc); servo4.write(Pozycja_serva4[i],predkosc); Serial.println("Odtwórz ruchy"); delay(1500); } } //czas opóźnienia działania programu, od jego nastawy zależy płynnośc pracy robota: delay(200); } Program działa w sposób następujący: Po uruchomieniu programu, za pomocą modelu kinematycznego będzie można bezpośrednio kontrolować ruch manipulatora, Jeżeli wciśniemy przycisk S2 (nagrywania), obecnie ustawiona pozycja robota zostanie zapisana, Program umożliwia zapisanie pięciu różnych pozycji, Jeżeli wybierzemy przycisk S3 (odtwarzania), robot zacznie odtwarzać wybrane przez nas pozycje w nieskończonej pętli, Aby wytyczyć nową sekwencję ruchów należy zresetować układ. Efekt działania powyższego kodu przedstawia się następująco: Dzięki funkcji monitora szeregowego w arduino można obserwować pracę manipulatora bezpośrednio: Przepraszam wszystkich czytelników za jakość nagrań wideo, niestety ograniczały mnie możliwości sprzętowe. Przedstawiony wyżej kod jest prosty a przykład nieskomplikowany, jednak doskonale pokazuje podstawy działania tej metody. Nie mniej jednak mam nadzieję, że artykuł okaże się dla wielu osób pomocny. Oprócz tego zostawiam jeszcze bibliotekę <VarSpeedServo> VarSpeedServo-master.zip Powodzenia we wszelkich przyszłych projektach i przygodach z elektroniką!
×
×
  • 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.