Skocz do zawartości

Leoneq

Użytkownicy
  • Zawartość

    142
  • Rejestracja

  • Ostatnio

  • Wygrane dni

    9

Leoneq wygrał w ostatnim dniu 4 września

Leoneq ma najbardziej lubianą zawartość!

Reputacja

167 Mistrz

2 obserwujących

O Leoneq

  • Ranga
    5/10
  • Urodziny 23.02.2004

Informacje

Ostatnio na profilu byli

892 wyświetleń profilu
  1. Kiedy zaczyna się zabawę z lampami, czy to do budowy radia, czy wzmacniacza audio, należy załatwić sobie dobre zasilanie. Zwykle to zasilanie jest wbudowane w urządzenie, więc co nowe urządzenie lampowe (czy to radio, czy wzmacniacz) musiałbym kupować nowy transformator. To czego potrzebowałem to zasilacz, jak najbardziej uniwersalny (układy lampowe buduję bardziej w celach edukacyjnych niż praktycznych), co pozwoli mi na wykorzystanie tylko jednego transformatora do wszystkich moich projektów lampowych. Chciałem, aby zasilacz był podobny do szkolnych zasilaczy laboratoryjnych, i był możliwie bezpieczny. Zacząłem sobie od rozrysowania schematu, a zarazem obliczeń: Jak widać, wiele do szczęścia nie potrzeba. Jest to jeden z najprostszych zasilaczy jaki można zrobić - i to wykorzystując elementy głównie z odzysku. Zaczynając od lewej: zasilanie do układu jest dostarczane przez popularne złącze IEC. Faza jest odcinana pierwszym wyłącznikiem, nie można było także zapomnieć o bezpieczniku. Transformator jaki wykorzystałem to TS50/5 polskiej firmy Zatra, który dostałem od znajomego nauczyciela. Posiada on 3 uzwojenia wtórne - 2x 270v, 6.3v i 4v (na schemacie dwa ostatnie powinny być rozłączone). Jeżeli ktoś nie ma takiego transformatora, może wyprostować bezpośrednio napięcie gniazdkowe, ale tylko przy zastosowaniu transformatora o przekładni 1:1. Będzie on stanowił izolację galwaniczną. Napięcie żarzenia wielu lamp to 6.3v. Niektóre lampy grzeje się wyższym napięciem, którego ten transformator niestety nie dostarcza, więc musiałem się zadowolić tymi ponad 6 woltami. Uzwojenie to od razu zasila małą żaróweczkę sygnalizującą pracę zasilacza. Dla jasności: lampy można żarzyć napięciem zarówno stałym, jak i przemiennym. Napięcie anodowe lamp (to wysokie, niebezpieczne) jest prostowane scalonym mostkiem greatza (z zasilacza komputerowego). Wyprostowane napięcie jest wygładzane przez filtr RC, a następnie ograniczane bardzo prostym układem z wykorzystaniem tranzystora MOSFET. Ten także jest z odzysku, posiada niską rezystancję w stanie przewodzenia, wytrzymuje dużą moc - i co najważniejsze - posiada zabezpieczenie w postaci diod zenera między bramką a źródłem. Działają one jako zabezpieczenie przeciwprzepięciowe - w teorii, potencjometr tutaj służy jako dzielnik napięcia, a rezystor obniża napięcie (gdyż mosfet to element sterowany napięciem). Jeżeli nastąpi tam przebicie, tranzystorowi na szczęście się nic nie stanie. Ale dlaczego w ogóle ten tranzystor dałem? Nie wszystkie lampy mają jedno napięcie anodowe, więc napięcie to można ograniczać - w czym pomaga panelowy woltomierz wskazówkowy, z posobnikiem w szeregu. Trudno znaleźć cyfrowe woltomierze na tak wysokie napięcie. Na samym końcu układu - jest przełącznik, który pozwala na zasilenie docelowego urządzenia, lub poprowadzenie napięcia przez rezystory mocy. Mają one 2 zastosowania: pozwalają dobrać napięcie, kiedy zasilacz nie jest zewnętrznie obciążony, oraz rozładowują kondensator, co jest bardzo ważną rzeczą. I najważniejsza rzecz - cała obudowa jest porządnie uziemiona. Aby wyrównać potencjały, masę napięcia anodowego także uziemiłem. Obliczenia skomplikowane nie są - na początku potrzebowałem znać moc urządzenia, aby wiedzieć jaki bezpiecznik dobrać. Z racji tego (a przynajmniej tak myślę, może błędnie myślę ), że poza transformatorem nie ma elementów LC (po stronie napięcia przemiennego), cos fi jest bliski 1, a więc moc bierna jest niewielka - dlatego jej nie brałem pod uwagę (równania 1.1-2). Nie brałem pod uwagę także strat na samym transformatorze. Następnie obliczyłem rezystor jaki jest potrzebny do filtru RC, oraz prąd i napięcie jakie będą po wyprostowaniu. Miałem na uwadze, że napięcie w gniazdku wynosi 240v, a transformator był na 220v, i że napięcie to może być wyższe (równania 3.1-3.4). Na samym końcu, korzystając z praw Ohma i Kirchoffa, obliczyłem posobnik dla woltomierza. Oryginalnie wyskalowany był na 0-40v, więc zmieniłem to na 0-500v. Woltomierz miał rezystancję 48kΩ. Starą skalę zeskanowałem, w gimpie przerobiłem, i wydrukowałem na papierze samoprzylepnym. Po zebraniu wszystkich potrzebnych elementów, wziąłem się za obudowę. Trochę mi to zajęło, ponieważ prawie wszystko robiłem ręcznie. Bazą obudowy jest aluminiowy radiator z starego zasilacza impulsowego - do którego z boku są przykręcone blachy aluminiowe, a u góry profil. Wszystko ze złomu. Rączka została wykonana z stali nierdzewnej. Najwięcej czasu zajął front obudowy, do którego wykonałem rysunek, a następnie wyfrezowałem blachę zgodnie z tym rysunkiem. (Niestety zdjęć z tego procesu nie mam). Następnie zasilacz zacząłem lutować - oczywiście wszystkie przewody są zakończone termokurczkami, wszystko jest porządnie przykręcone, a obudowa działa jak świetny radiator. No i podsumowanie. Zasilacz działa, bez obciążenia napięcie anodowe wynosi maks. 428v, oraz 375v z obciążeniem. Maksymalny prąd wynosi 48mA, co można zwiększyć, podłączając równolegle drugą połówkę uzwojenia. No i - zgodnie z przewidywaniami, napięcie faktycznie jest wyższe. Napięcie żarzenia wynosi obecnie 6.8v, ale jest to dość nieznaczna różnica. Rozładowanie kondensatora trwa ok. 5 sekund, z włączonym obciążeniem. Myślę że bez obciążenia, nawet w ciągu doby nie rozładowałby się do zera. Przy budowie jednak popełniłem kilka błędów: górny łącznik, łączący front z górą obudowy, ma źle umiejscowione utwory, przez co górna blacha trochę wystaje. Żarówka (jak i kondensator) trzyma się na kablach, co nie jest dobrą praktyką. Mogłem także dać więcej zabezpieczeń, np. ograniczenie prądu, zabezpieczenie przeciw odwrotnej polaryzacji, czy przeciw zwarciowe. Rezystor filtru także jest mocno przedobrzony - moc którą pobierze wynosi mniej niż 1 wat, i bardziej on służy za element montażowy. Mimo wszystko, zasilacz działa, poza obciążeniem nic się nie grzeje. Projekt tym samym uznaję za udany.
  2. Sprawdź konsolę, czy może skrypt palety kolorów nie wywala. Jeżeli w ogóle nie działa, spróbuj uruchomić go na komputerze - będziemy już coś wiedzieli. Jak na komputerze się nie uruchomi, to albo kombinujesz dalej co masz źle, albo szukasz innego skryptu na paletę.
  3. Z tego co widzę, highByte(); i lowByte(); nie będzie działać, jeżeli szyna adresów będzie szersza od 16 linii (użyjemy zmiennej większej od int16_t, więc wyślemy tylko 8 bitów po lewej i 8 po prawej). Przesunięciem bitowym (>> i <<) można obsłużyć większe dane. Ale do małych pamięci jak najbardziej można użyć tamtych funkcji, chociaż przesunięcie bitowe mi się wydaje lepszym rozwiązaniem.
  4. Zabierając się za rozbudowane projekty, jest szansa że zabraknie nam pamięci. Jeżeli potrzebujemy przechować np. dużą tablicę zmiennych, możemy ją załadować do zewnętrznej pamięci RAM. Co jednak, gdy potrzebujemy przechować duże dane, ale stałe? Najlepiej podpiąć zewnętrzną kość pamięci. Co prawda, nie będzie możliwości zapisu danych (a przynajmniej tak łatwo) ale nasz mikrokontroler uzyska nawet kilka megabitów (!) dodatkowej pamięci. Może to być program, tekst, a nawet obrazek. Programując mikrokontroler najprawdopodobniej wgrywasz program do pamięci FLASH. Do dyspozycji możesz mieć także małą, dodatkową pamięć EEPROM. Czym się one różnią? Pamięć FLASH to ewolucja pamięci EEPROM. Same pamięci PROM są dość stare, mają ok. 50 lat. Są one jednorazowe - można je zaprogramować tylko raz. Ich nowocześniejszą wersją jest pamięć UVEPROM - które łatwo rozpoznać po okienku, które pozwala światłu ultrafioletowemu kasować całą pamięć. Pamięć EEPROM można skasować i zaprogramować elektrycznie, lecz zwykle z pomocą 12V. Z racji tego że te pamięci są stare jak komputery, interfejs jest równoległy; do podłączenia mamy, zwykle ośmiobitową, szynę danych, oraz szynę adresów - jej długość będzie zależeć od pojemności kości. Rozwój elektroniki sprawił, że powstał kolejny rodzaj pamięci: FLASH. Do programowania nie wymagają wysokiego napięcia, a do kasowania światła UV. Aby je zaprogramować, muszą być najpierw wyczyszczone, co można robić co najmniej stronami (nie pozwalają czyścić pojedynczych bajtów). Pamięci te zaczęto masowo stosować jeszcze pod koniec XX wieku. Kości pamięci. Od lewej: PROM, UV EPROM, FLASH (w dwóch obudowach), EEPROM (po I2C) Do podstawowych rozwiązań powinny wystarczyć małe pamięci EEPROM, które podłączymy po I2C. Trochę większe pamięci można podłączyć przez SPI. Lecz do niektórych rozwiązań najlepiej wykorzystać właśnie te starsze kości. I właśnie do nich zrobiłem programator, który dedykuję kościom FLASH (ponieważ tych mam najwięcej... ) przeróbka na EPROM/EEPROM jest możliwa oczywiście, należy zaopatrzyć płytkę w wyższe napięcie i odpowiedni MOSFET. Następnie najlepiej zapoznać się z notą katalogową wybranej pamięci, i przerobić program. Wracając do pamięci FLASH - zajrzyjmy do noty katalogowej wybranej kości - tutaj 29F002, w której był przechowywany BIOS komputera PC. Wiemy zatem, że jest to kostka o pojemności dwóch megabitów, wyprodukowana w technologii CMOS (jest wrażliwa na ładunek elektrostatyczny). Posiada dość niski czas odczytu (120ns), pobiera mało prądu, i co najważniejsze - nie wymaga wysokiego napięcia do programowania/kasowania. Ilość pinów może przerażać, lecz nie ma się czego bać. VCC i GND to zasilanie, na które podajemy 5V. Pin CE (Chip Enable) uaktywnia kość. Jeżeli z szyn korzysta więcej urządzeń niż jedno, to nasza kość pamięci nie będzie im przeszkadzać. Kreska nad nim oznacza, że jest on aktywny w stanie niskim - czyli żeby włączyć czip, musimy podciągnąć ten sygnał do masy. W programatorze będzie on zwarty do masy, jako że to jedyny układ korzystający z szyn. Pin OE (Output Enable) pozwoli na odczyt danych. W chwili podpięcia tego sygnału do masy, na szynę danych ustawiany jest bajt z podanego adresu. Pin WE (Write Enable) pozwala na zapis. Bajt który w chwili zapisu będzie na szynie danych, zostanie zapisany do podanego adresu. Pozostałe piny (D0..D7) to szyna danych, a A0..A17 to szyna adresu. Liczby na tych szynach są zapisywane w systemie binarnym - co oznacza że możemy operować na 262 144 (2^18) liczbach, a każda liczba może mieć wartość z zakresu 0-255. Jeżeli wiemy jak podłączyć naszą kość, możemy to już zrobić: przygotowałem także schemat układu. Sercem programatora jest Atmega 8, z racji tego że 328 nie miałem żadnej wolnej (nie ma powodu żeby jej nie stosować). Wokół niej powinien się znajdować przycisk reset z rezystorem podciągającym, kondensator do filtrowania zasilania. Przejdźmy do połączenia pamięci z atmegą - dlaczego między nimi są 2 układy? Są to dwa rejestry przesuwne, 74HC595. Dzięki trzem pinom z mikrokontrolera możemy obsłużyć aż 16 (a nawet więcej, bo rejestry można łączyć) pinów. Jeżeli dana pamięć ma szerszą szynę adresów, nieużyte piny powinniśmy połączyć z masą. Co do szyny danych, tą podłączyłem bezpośrednio do Atmegi. Piny RX i TX są zarezerwowane dla konwertera USB-UART, w celu komunikacji z komputerem. Tak wygląda układ zmontowany przeze mnie: Niebieski, podłużny element to drabinka rezystorowa, zastępująca 8 rezystorów podciągających szynę danych do masy. Dałem na wszelki wypadek. Teraz należy odpowiednio zaprogramować mikrokontroler. Obecnie dane do wgrania są przechowywane w pamięci mikrokontrolera, co będzie działać dopóki chcemy wgrywać małe dane. Pracuję nad programem w VS, który będzie przekazywał dane z komputera do Atmegi - w razie czego zaktualizuję post. Gotowa paczka z kodem i generatorem są na dole do pobrania. Kod napisałem w VS Code, z wtyczką Platformio (kod powinien być w 100% kompatybilny z Arduino IDE). Zacznijmy od zdefiniowania pinów: #include <Arduino.h> #define SHIFT_DATA 2 #define SHIFT_CLK 3 #define SHIFT_LATCH 4 #define D0 5 #define D7 12 #define WRITE_EN 13 #define OUTPUT_EN A0 Pierwsze 3 piny są dla rejestru przesuwnego. Podaliśmy także Pierwszy i ostatni pin szyny danych - będziemy operować na pętlach for(), więc nie musimy podawać wszystkich pinów (ważne żeby były podłączone po kolei). Kolejne dwa piny to WE i OE (CE jest zwarty do masy). Przejdźmy do właściwego kodu. Zaczniemy od napisania funkcji niezbędnych do działania urządzenia: void setAddress(int address) { shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, address >> 8); shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, address); digitalWrite(SHIFT_LATCH, LOW); digitalWrite(SHIFT_LATCH, HIGH); digitalWrite(SHIFT_LATCH, LOW); } Funkcja ta ustawi wybrany adres na szynie adresów. Najpierw wysyłamy do rejestrów pierwsze 8 bitów zmiennej. potem 8 kolejnych, ponieważ funkcja shiftOut() może wysłać tylko ośmiobitowy bajt. Po wysłaniu bitów zatwierdzamy je, ustawiając na chwilę latch w stan wysoki. void setDataBusOut() { for(int i = D0; i <= D7; i++) pinMode(i, OUTPUT); } void setDataBusIn() { for(int i = D0; i <= D7; i++) pinMode(i, INPUT); } Z racji tego, że na szynie danych będziemy zapisywać i odczytywać dane, te funkcje umożliwią ustawić szynę jako wejście lub wyjście. void setByte(byte out) { for(int i = D0; i <= D7; i++) digitalWrite(i, bitRead(out, i - D0)); } byte readByte() { byte bajt = 0; for(int i = D0; i <= D7; i++) if(digitalRead(i)) bitSet(bajt, i - D0); return bajt; } Funkcja setByte() ustawi dany bajt na szynie danych. Z kolei readByte() zwróci bajt, który jest obecnie na szynie danych. Wykorzystałem tutaj funkcje bitSet i bitRead, które pozwalają na operacje na bitach (odsyłam do dokumentacji Arduino). Jeżeli chodzi o podstawowe funkcje - to tyle. Teraz przeanalizujmy poszczególne arkusze noty katalogowej: Wygląda skomplikowanie, ale nie ma się czego bać. W celu odczytania bajtu z pamięci, musimy ustawić docelowy adres. Pin CE musi być zwarty do masy (u nas jest), a pin WE do dodatniej szyny zasilania. Następnie krótko po podpięciu OE do masy, dostajemy dane na szynie danych. Zróbmy zatem funkcję, która zwróci odczytany bajt: byte readData(int adr) { byte bajt = 0; setDataBusIn(); digitalWrite(WRITE_EN, HIGH); digitalWrite(OUTPUT_EN, HIGH); setAddress(adr); digitalWrite(OUTPUT_EN, LOW); delayMicroseconds(1); bajt = readByte(); digitalWrite(OUTPUT_EN, HIGH); return bajt; } Najpierw ustawiamy szynę danych jako wejście. Upewniamy się, że WE i OE są w stanie wysokim. Wysyłamy docelowy adres, ustawiamy OE na stan niski, czekamy chwilę, odczytujemy bajt, i ustawiamy OE z powrotem na stan wysoki. Zwracamy odczytany bajt. Teraz czas na prawdziwą zabawę. Dlaczego nagle jakieś komendy mamy wysyłać? Otóż jest to zabezpieczenie przed przypadkowym skasowaniem/zapisaniem danych. Wysłanie komend polega na wysłaniu 3 odpowiednich danych w odpowiednie adresy. Kolejno AA do adresu 555, 55 do adresu 2AA, i A0 do 555. Literka 'H' oznacza że liczby te są zapisane w systemie heksadecymalnym - tutaj mocno polecam pobawić się kalkulatorem w trybie programisty: Tak więc operacja zapisu sprowadza się do zapisania 4 bajtów. Zapiszmy funkcję zapisującą jeden bajt: void writeByte(byte bajt, int adr) { digitalWrite(OUTPUT_EN, HIGH); digitalWrite(WRITE_EN, HIGH); setAddress(adr); setByte(bajt); digitalWrite(WRITE_EN, LOW); digitalWrite(WRITE_EN, HIGH); } Myślę że objaśniać nie trzeba. Teraz zapiszmy funkcję zapisującą jeden bajt w pamięci: void programData(byte bajt, int adr) { setDataBusOut(); writeByte(0xAA, 0x555); writeByte(0x55, 0x2AA); writeByte(0xA0, 0x555); writeByte(bajt, adr); delayMicroseconds(1); } Na końcu dodałem mały odstęp czasowy, ponieważ czip po zapisie przez chwilę jeszcze prowadzi wewnętrzne operacje. Do zrobienia została jeszcze jedna rzecz - nie można zapisywać zapisanej już pamięci. Dlatego patrzymy w notę jak wyczyścić kość: Całość się sprowadza do wysłania 6 bajtów. void chipErase() { setDataBusOut(); writeByte(0xAA, 0x555); writeByte(0x55, 0x2AA); writeByte(0x80, 0x555); writeByte(0xAA, 0x555); writeByte(0x55, 0x2AA); writeByte(0x10, 0x555); delayMicroseconds(1); } I jeżeli chodzi o kwestię techniczną - to tyle. Przejdźmy zatem do setup(): void setup() { pinMode(SHIFT_DATA, OUTPUT); pinMode(SHIFT_CLK, OUTPUT); pinMode(SHIFT_LATCH, OUTPUT); pinMode(WRITE_EN, OUTPUT); pinMode(OUTPUT_EN, OUTPUT); digitalWrite(OUTPUT_EN, HIGH); digitalWrite(WRITE_EN, HIGH); writeByte(0xf0, 0x0000); //reset Serial.begin(115200); delay(3000); Serial.println("programator FLASH v1.0 - gotowy."); } Piny sterujące ustawiamy jako wyjście (i od razu jako stan wysoki), oraz resetujemy czip. Do tego wystarczy jedna komenda jak widać. W loopie zaś sprawdzamy jedynie czy z serialu przyszły nowe dane: void loop() { if(Serial.available()) readSerial(Serial.read()); } Jeżeli tak, wykonujemy dużego switcha: void readSerial(byte bajt) { switch(bajt) { case 'E': Serial.println("Czyszcze pamiec FLASH..."); chipErase(); delay(200); Serial.println("Wyczyszczono!"); break; case 'W': Serial.println("Wgrywam przykladowy program..."); for(int i = 0; i < sizeof(data); i++) programData(data[i], i); Serial.println("Wgrano pomyslnie!"); break; case 'R': Serial.println("Odczytuje dane od adresu 0x0000..."); for(int y = 0; y <= 249; y+=5) { for(int x = 0; x <= 4; x++) { Serial.print(readData(x+y), HEX); Serial.print(" "); } for(int x = 0; x <= 4; x++) Serial.print(char(readData(x+y))); Serial.println(""); } break; case 'T': Serial.println("Resetuje pamiec..."); setDataBusOut(); writeByte(0xF0, 0x0000); setDataBusIn(); break; default: Serial.println("Programator FLASH v1.0 - by Leoneq ;3"); Serial.println("-------------------------------------------"); Serial.println("E - Wyczysc pamiec"); Serial.println("R - Odczytaj zawartosc pamieci"); Serial.println("W - Wgraj przykladowy program"); Serial.println("T - Zresetuj pamiec FLASH"); break; } } Oczywiście te funkcje są przykładowe, zachęcam do samodzielnej zabawy z programem. Zostaje teraz kwestia samych danych do zapisu. Jak napisałem, docelowo mają one być nadawane z komputera PC, a obecnie są one przechowywane w pamięci uC: //generated data const byte data[11] = {B00100001, B11111111, B00000001, B11111001, B00111110, B00000001, B11010011, B00000000, B11000011, B00000100, B00000000}; Specjalnie do tego zadania napisałem generator w C++. Tworzy on z plików .bin (kod maszynowy) tablicę zmiennych. #include <iostream> #include <fstream> #include <bitset> using namespace std; ifstream source; fstream output; //0x21 0xFF 0x01 0xF9 0x3E 0x01 0xD3 0x00 0xC3 0x04 0x00 int main() { cout << "FLASH code generator v1.0\nby Leoneq ;3\n" ; source.open("ROM.bin", ios::binary | ios::ate); if(source.good()) cout << "Successfully opened the file.\n"; else cout << "Couldn't open the file. Put 'ROM.bin' in the same directory where .exe is."; int size = source.tellg(); source.close(); source.open("ROM.bin", ios::binary); char buffer[size]; source.read (buffer, size); source.close(); output.open("array.txt", ios::out); output << "//generated data\nconst byte data[" << size << "] = {"; for(int i = 0; i < (size-1); i++) output << "B" << bitset<8> (buffer[i]) << ", "; output <<"B" << bitset<8> (buffer[size]) << "};"; cout << "The array is in 'array.txt'. Exit..."; return 0; } Program wczytuje plik ROM.bin, który powinien znajdować się w tym samym miejscu co .exe, a wygenerowaną tablicę zapisze w array.txt. Tą tablicę należy skopiować do kodu Atmegi, wgrać i... cieszyć się programatorem. Linki: dokumentacja kości FLASH nota katalogowa rejestrów przesuwnych datasheet mikrokontrolera opis funkcji shiftOut(); bitSet(); bitRead(); ------------------ W planach mam więcej poradników tego typu, dlatego prosiłbym o komentarze co jest dobrze napisane, a co źle. Dzięki ^^ box.zip
  5. Spróbuj te funkcje zdeklarować przed funkcją setup - przenieś je na górę, i powinno być ok.
  6. Silniki obecnie są zwykłe z przekładniami xd W artykule chyba nawet link jest do nich. Musiałbym chyba sam silnik wymienić, albo w przekładnię zajrzeć. Jak znajdę chwilę to jeszcze się pobawię z tymi napędami, najwyżej wymienię na te żółte 48:1.
  7. Linear advance to taka technika jakby, która koryguje przyspieszenie i zwolnienie karetki (na początku kreska filamentu z dyszy jest cieńsza, na końcu grubsza). Funkcja ta podaje na początku zatem więcej filamentu, na końcu odrobinę mniej. Każda drukarka ją może mieć, która ma marlina.
  8. Właśnie problem jest taki, że jeden silnik jest normalny, a drugi "załącza się" od pewnego napięcia - niżej się nie załączy. Próbowałem różne progi ustawiać, skutkowało to zbyt nagłymi ruchami robota.
  9. W planach mam zrobić "ultimate useless box" - z wyświetlaczem, drugim serwem na klapkę, a nawet napędem do uciekania. Ale to bardzo odległe plany.
  10. Aż tak mi sie nie nudzi xd Chociaż warto spróbować. Praktyki z 555 nigdy nie za dużo.
  11. Dziękuję ^^ Wiem że masa powinna być na górze, nie mam tylko co dać na górę - najwyżej sztucznie dociążyć, nie wiem czy to coś da. Filmik postaram się wrzucić pod wieczór, jak internet będzie odrobinę szybszy. ------------------------------------------------------------------------- edit: Jest i filmik pokazujący działanie robota. Wiem że dużo nie potrafi, ale bardzo satysfakcjonujące jest jak robot w końcu stoi, a nawet można go lekko szturchnąć - po całym tygodniu kodowania i naprawiania po upadkach. Jak się nie zaliczy na rabat, to trudno, i tak już mi dużo pomógł
  12. Witam. Ten projekt, mimo że wygląda na dość prosty, musiałem go bardzo rozpracować - jest to praca na "wprowadzenie do wykonywania zawodu", czyli mechatronikę. Założenia były takie: zrobić projekt, który widać że działa, jest stosunkowo prosty w konstrukcji. Wybór padł na useless box, czyli bezużyteczne pudełko. Bezużyteczne pudełka nie robią nic pożytecznego - jeżeli ktoś im przeszkodzi w byciu przyciskiem do papieru, albo kurzołapem - same się wyłączą. Tak więc, uznałem że optymalnie będzie to zrealizować na timerze 555 i serwie modelarskim. Zacząłem od sprawdzenia datasheeta serwa. Gdzieś przeczytałem, że serwa steruje się nie przez PWM a PPM (pulse position modulation). Nie miałem czasu badać tego aż tak, więc przyjąłem po prostu informacje z datasheeta. Kąt nachylenia od 0 do 180 stopni, i moment 1,8kg/cm powinien starczyć z dużym zapasem. Zgodnie z tym diagramem, trzeba wygenerować sygnał PWM o częstotliwości 50Hz - jedna ramka ma długość 20ms. Z forbotowego kursu elektroniki wiemy, że takie coś można wygenerować timerem w trybie astabilnym. Tak wygląda schemat żywcem wzięty z datasheeta 555: Działanie tego układu jest następujące: po podłączeniu zasilania kondensator C ładuje się - przez co na wyjściu jest stan wysoki. Ładuje się on przez rezystory Ra i Rb podłączone do zasilania. Kiedy kondensator naładuje się do 2/3 napięcia zasilania, wyjście jest ustawiane na stan niski, a kondensator się rozładowuje przez rezystor Rb podłączony do pinu “discharge”. Po rozładowaniu do 1/3 napięcia zasilania, wyjście znowu jest ustawiane na stan wysoki, a kondensator się ładuje - cykl się powtarza. Czas wysoki będzie zatem zależny od Ra i Rb, a niski od Rb. Zgodnie z pierwszym diagramem, aby wychylić serwo o -90 stopni wypełnienie musi wynosić 1ms. Aby orczyk się obrócił do +90 stopni, sygnał musi mieć wypełnienie 2ms. Wykonałem wstępne obliczenia - do powyższego schematu zostały dołączone wzory: Rezystancja niestety wychodziła ujemna. Wniosek prosty - ten układ nie nadaje się do naszego zastosowania, a przynajmniej w takiej formie. Tak jak w forbotowym przykładzie z kursu elektroniki, dodałem diodę równolegle z Rb. Od teraz Ra odpowiadał tylko za ładowanie kondensatora, a Rb tylko za rozładowywanie. Dlatego we wzorze na th mogę pominąć Rb: Jak widać, obliczyłem 3 rezystory - wspólny, rozładowujący, i 2 ładujące. Pierwszy spowoduje schowanie ramienia, drugi spowoduje jego wychylenie. Wszystko powinien rozjaśnić schemat: Nie miałem akurat żadnego akumulatora, więc źródło zasilania stanowią 4 paluszki AAA. Kondensator C1 filtruje zasilanie, i tam gdzie się dało umieściłem konektory. Płytkę zlutowałem na protoboardzie: Obudowę wydrukowałem na drukarce 3D, białym PLA od Spectrum. "Wnętrzności" pudełka wydrukowałem kolorem czerwonym. Po złożeniu, całość wyglądała tak: Wykorzystałem tutaj sprężynę z długopisu, spinacz jako oś dla klapki, całość skręciłem różnymi śrubkami. Przyszedł czas na odpalenie, a tu niespodzianka: nie działa (wow). Znaczy - działa, ale ramię ma za mało mocy do przełączenia dźwigni. Orczyk był prawidłowo przykręcony, okazało się że wypełnienie musiało być złe. Szybkie rozkręcanie, i patrzymy w oscyloskop: Eksperymentalnie dobrałem nowe wartości rezystora. Potencjometr szeregowo połączyłem z Rb, i udało się dobrać dobrą rezystancję. Po zmierzeniu miernikiem, okazało się że należy wlutować rezystor 2.7kΩ. Tak też zrobiłem - a bezużyteczne pudełko w końcu mogło się bronić przed napastliwą działalnością człowieka. Założenia projektu zostały spełnione, a projekt zaakceptowany. Projekt można uznać za zakończony sukcesem. Linki: datasheet SG90: http://www.ee.ic.ac.uk/pcheung/teaching/DE1_EE/stores/sg90_datasheet.pdf datasheet NE555: http://www.ti.com/lit/ds/symlink/ne555.pdf
×
×
  • Utwórz nowe...