Różnice
Różnice między wybraną wersją a wersją aktualną.
| Poprzednia rewizja po obu stronach Poprzednia wersja Nowa wersja | Poprzednia wersja | ||
|
projekty:zasilacz_do_plytek_prototypowych [2018/05/28 13:43] yazjack [Zasilacz do płytek prototypowych] |
— (aktualna) | ||
|---|---|---|---|
| Linia 1: | Linia 1: | ||
| - | ===== Zasilacz do płytek prototypowych ===== | ||
| - | ^Zamieszany|[[user>yazjack]] | | ||
| - | ^Rozpoczęto|2017-07-08 | | ||
| - | ^Status|{{tag>zakończony}} | | ||
| - | ^Tagi|{{tag>projekt}} | | ||
| - | Zasilacz do 2 płytek prototypowych z czterema liniami regulowanego napięcia, zabezpieczeniem przeciwzwarciowym i wyświetlaczem pokazującym napięcie, prąd i moc dla każdej z szyn. | ||
| - | ==== Założenia ==== | ||
| - | |||
| - | Celem projektu było stworzenie zasilacza do płytek prototypowych, który posiadałby zabezpieczenie przeciwzwarciowe i byłby w stanie wyświetlać podstawowe informacje takie jak napięcie na szynach, napięcie na układach, natężenie prądu i pobór mocy. Takie zastawienie stanowi bardzo duże ułatwienie przy nauce elektroniki, pozwalając na obserwację w czasie rzeczywistym, jak zachowuje się układ. Jest też całkiem przydatnym narzędziem dla bardziej zaawansowanego użytkownika, pozwalającym na szybkie eliminowanie błędów i chroniącym przed błędami wynikającymi z generalnego gapiostwa. | ||
| - | Przewidziałem 4 linie zasilania, na najpopularniejsze napięcia 3.3V, 5V, 9V, 12V. Na późniejszym etapie zdecydowałem się na indywidualną regulację każdej z nich. | ||
| - | |||
| - | ==== Iteracje ==== | ||
| - | === Iteracja I === | ||
| - | W pierwszym rzucie była zabawa na płytce prototypowej. Uparłem się na bezpieczniki PPTC i spędziłem sporo czasu nad sygnalizowaniem stanu bezpiecznika diodami. Udało zrobić takie cudo na bazie PFET i diody Zenera. Świeciło ładnie i działało nieźle na wysokim prądzie zwarciowym (bezpiecznik od razu wywalał na zasilaczu 6A), ale okazało się, że w praktyce PPTC spokojnie się nagrzewa i nie od razu odcina prąd a stopniowo go ogranicza. Cóż, nieśmiertelne RTFM. | ||
| - | |||
| - | {{https://trello-attachments.s3.amazonaws.com/5a156db2be9d8433cfe1eaaa/5a1e9a337659b28037f7455f/d0e8e883d782dabdef6eaec7a7740913/IMG_20170717_123945.jpg?400}} | ||
| - | |||
| - | A tutaj można sobie popatrzeć jak to działa: http://everycircuit.com/circuit/5346630058639360 | ||
| - | |||
| - | Idąc dalej, użyłem lutowanej płytki prototypowej i w większości gotowych układów, żeby zmajstrować takiego oto potworka: | ||
| - | |||
| - | {{https://trello-attachments.s3.amazonaws.com/5a156db2be9d8433cfe1eaaa/5a1e9a337659b28037f7455f/45e46a970c81781c914445bbf470d9d9/img_20170729_195520_1024.jpg?400}} | ||
| - | |||
| - | Niby działało, ale z był problem z zabezpieczeniem przecizwarciowym, a to ważna rzecz. | ||
| - | |||
| - | === Iteracja II === | ||
| - | Na poważnie trzeba było się wziąć za porządną implementację pomysłu. Zaprojektowałem układ od nowa, z zabezpieczeniem z prawdziwego zdarzenia, odpuszczając sobie gotowe bucki na rzecz własnych i trawiąc dedykowaną płytkę. Na rysunku wygląda to tak: | ||
| - | |||
| - | {{https://trello-attachments.s3.amazonaws.com/5a156db2be9d8433cfe1eaaa/5a1e9a337659b28037f7455f/2f306ca534834de16360dca144f2d5ae/BSup-v2-PCB-prototype.jpg?800}} | ||
| - | |||
| - | Finalny efekt natomiast można zobaczyć w gablotce. Nawet działało, do czasu kiedy nie podkusiło mnie na zrobienie obudowy i nie zwarłem brzegu układu z obudową zasilacza. Zrobiło *bum* i zdechło. Nie miałem już serca do wymiany wszystkich spalonych podzespołów, to co miałem pod ręką wymieniłem, ale uszkodził się jeden z regulatorów napięcia i stwierdziłem, że nie wydam 20PLN na coś, co nie do końca mi odpowiada. A nie odpowiadała mi wielkość całego pudełka, za mały wyświetlacz (na którym na dodatek trudno było pomieścić wszystkie info) i nieintuicyjna obsługa, brak możliwości łatwej regulacji zabezpieczenia i napięcia szyn. I tak oto przechodzimy do kolejnego podejścia (WIP). W przypływie szalonego "geniuszu" połączyłem też napięcie do logiki za bezpiecznikiem. Także ten, hard reset jak malowany. | ||
| - | |||
| - | === Iteracja III === | ||
| - | |||
| - | Tym razem walka odbywa się o możliwie najciaśniejsze spakowanie całości, siłą rzeczy w technologii SMD. Projekt w zasadzie pozostaje ten sam, z drobnymi różnicami wynikającymi ze zmian podzespołów. Zrezygnowałem też całkowicie z użycia gotowych płytek na rzecz własnego rozmieszczenia układów. Poza sterowaniem, bo tak wygodniej i nikt nie ma tyle czasu żeby sprawić żeby to zadziałało. Konieczny będzie także dobór większego wyświetlacza, najprędzej skończę z LCD z racji kosztów, chociaż większy OLED byłby fajniejszy. Chwilowo projekt jest z lekka zawieszony z uwagi na brak środków i czasu na jego dokończenie. Aczkolwiek mam już większość elementów pasywnych i układów od majfrendów. Pozostało dokończyć projekt płytki, dokupić brakujące elementy i będzie śmigać. | ||
| - | |||
| - | {{https://trello-attachments.s3.amazonaws.com/5a156db2be9d8433cfe1eaaa/5a1e9a337659b28037f7455f/a52b0d9245f2c9b39da945d5f1dbbb41/BSupSMD.jpg?800}} | ||
| - | |||
| - | ===== Wykonanie ===== | ||
| - | ==== Hardware ==== | ||
| - | === Iteracja I === | ||
| - | Wykonanie na płytce prototypowej i uniwersalnej w THT | ||
| - | |||
| - | === Iteracja II === | ||
| - | Wykonanie na płytce trawionej w THT | ||
| - | |||
| - | === Iteracja III === | ||
| - | Wykonanie na płytce drukowanej SMD | ||
| - | |||
| - | ==== Kod ==== | ||
| - | === Oprogramowanie układu z podejścia I i II === | ||
| - | |||
| - | <code cpp> | ||
| - | |||
| - | #include <Wire.h> | ||
| - | #include <Adafruit_INA219.h> | ||
| - | #include "SSD1306Ascii.h" | ||
| - | #include "SSD1306AsciiAvrI2c.h" | ||
| - | |||
| - | #define I2C_ADDRESS 0x3C | ||
| - | SSD1306AsciiAvrI2c oled; | ||
| - | Adafruit_INA219 ina219_A(0x40); | ||
| - | Adafruit_INA219 ina219_B(0x41); | ||
| - | Adafruit_INA219 ina219_C(0x44); | ||
| - | Adafruit_INA219 ina219_D(0x45); | ||
| - | |||
| - | void setup(void) | ||
| - | { | ||
| - | uint32_t currentFrequency; | ||
| - | |||
| - | Serial.begin(9600); | ||
| - | |||
| - | // Initialize the INA219. | ||
| - | // By default the initialization will use the largest range (32V, 2A). However | ||
| - | // you can call a setCalibration function to change this range (see comments). | ||
| - | ina219_A.begin(); | ||
| - | ina219_B.begin(); | ||
| - | ina219_C.begin(); | ||
| - | ina219_D.begin(); | ||
| - | oled.begin(&Adafruit128x64, I2C_ADDRESS); | ||
| - | oled.setFont(System5x7); | ||
| - | | ||
| - | // To use a slightly lower 32V, 1A range (higher precision on amps): | ||
| - | //ina219.setCalibration_32V_1A(); | ||
| - | // Or to use a lower 16V, 400mA range (higher precision on volts and amps): | ||
| - | ina219_A.setCalibration_16V_400mA(); | ||
| - | ina219_B.setCalibration_16V_400mA(); | ||
| - | ina219_C.setCalibration_16V_400mA(); | ||
| - | ina219_D.setCalibration_16V_400mA(); | ||
| - | } | ||
| - | |||
| - | void loop(void) | ||
| - | { | ||
| - | float shuntvoltage_A = 0; | ||
| - | float shuntvoltage_B = 0; | ||
| - | float shuntvoltage_C = 0; | ||
| - | float shuntvoltage_D = 0; | ||
| - | float busvoltage_A = 0; | ||
| - | float busvoltage_B = 0; | ||
| - | float busvoltage_C = 0; | ||
| - | float busvoltage_D = 0; | ||
| - | float current_A = 0; | ||
| - | float current_B = 0; | ||
| - | float current_C = 0; | ||
| - | float current_D = 0; | ||
| - | float loadvoltage_A = 0; | ||
| - | float loadvoltage_B = 0; | ||
| - | float loadvoltage_C = 0; | ||
| - | float loadvoltage_D = 0; | ||
| - | float power_A = 0; | ||
| - | float power_B = 0; | ||
| - | float power_C = 0; | ||
| - | float power_D = 0; | ||
| - | float offset = 0; | ||
| - | float current_off_A = 0; | ||
| - | | ||
| - | shuntvoltage_A = ina219_A.getShuntVoltage_mV(); | ||
| - | shuntvoltage_B = ina219_B.getShuntVoltage_mV(); | ||
| - | shuntvoltage_C = ina219_C.getShuntVoltage_mV(); | ||
| - | shuntvoltage_D = ina219_D.getShuntVoltage_mV(); | ||
| - | busvoltage_A = ina219_A.getBusVoltage_V(); | ||
| - | busvoltage_B = ina219_B.getBusVoltage_V(); | ||
| - | busvoltage_C = ina219_C.getBusVoltage_V(); | ||
| - | busvoltage_D = ina219_D.getBusVoltage_V(); | ||
| - | current_A = ina219_A.getCurrent_mA(); | ||
| - | current_B = ina219_B.getCurrent_mA(); | ||
| - | current_C = ina219_C.getCurrent_mA(); | ||
| - | current_D = ina219_D.getCurrent_mA(); | ||
| - | loadvoltage_A = busvoltage_A + (shuntvoltage_A / 1000); | ||
| - | loadvoltage_B = busvoltage_B + (shuntvoltage_B / 1000); | ||
| - | loadvoltage_C = busvoltage_C + (shuntvoltage_C / 1000); | ||
| - | loadvoltage_D = busvoltage_D + (shuntvoltage_D / 1000); | ||
| - | |||
| - | power_A = loadvoltage_A * current_off_A / 1000; | ||
| - | power_B = loadvoltage_B * current_B / 1000; | ||
| - | power_C = loadvoltage_C * current_C / 1000; | ||
| - | power_D = loadvoltage_D * current_D / 1000; | ||
| - | |||
| - | current_off_A = current_A+0.7; | ||
| - | | ||
| - | if(current_off_A<=0){ | ||
| - | current_off_A=0; | ||
| - | power_A = 0; | ||
| - | } | ||
| - | | ||
| - | if(current_B<=0){ | ||
| - | current_B = 0; | ||
| - | power_B = 0; | ||
| - | } | ||
| - | | ||
| - | if(current_C<=0){ | ||
| - | current_C = 0; | ||
| - | power_C = 0; | ||
| - | } | ||
| - | | ||
| - | if(current_D<=0){ | ||
| - | current_D = 0; | ||
| - | power_D = 0; | ||
| - | } | ||
| - | | ||
| - | float busvoltage_A_r = 0; | ||
| - | busvoltage_A_r = ((int)(busvoltage_A*100))/100.0; | ||
| - | |||
| - | oled.setCursor(16,1); | ||
| - | oled.print("BUS1"); | ||
| - | oled.setCursor(46,1); | ||
| - | oled.print("BUS2"); | ||
| - | oled.setCursor(76,1); | ||
| - | oled.print("BUS3"); | ||
| - | oled.setCursor(106,1); | ||
| - | oled.print("BUS4"); | ||
| - | | ||
| - | oled.setCursor(0,2); | ||
| - | oled.print("Vb"); | ||
| - | oled.setCursor(16,2); | ||
| - | oled.print(busvoltage_A, 1); | ||
| - | oled.setCursor(46,2); | ||
| - | oled.print(busvoltage_B, 1); | ||
| - | oled.setCursor(76,2); | ||
| - | oled.print(busvoltage_C, 1); | ||
| - | oled.setCursor(106,2); | ||
| - | oled.print(busvoltage_D, 1); | ||
| - | | ||
| - | oled.setCursor(0,3); | ||
| - | oled.print("Vl"); | ||
| - | oled.setCursor(16,3); | ||
| - | oled.print(loadvoltage_A, 2); | ||
| - | oled.setCursor(46,3); | ||
| - | oled.print(loadvoltage_B, 2); | ||
| - | oled.setCursor(76,3); | ||
| - | oled.print(loadvoltage_C, 2); | ||
| - | oled.setCursor(106,3); | ||
| - | oled.print(loadvoltage_D, 2); | ||
| - | | ||
| - | oled.setCursor(0,4); | ||
| - | oled.print("mA"); | ||
| - | oled.setCursor(16,4); | ||
| - | oled.print(current_A, 0); | ||
| - | oled.setCursor(46,4); | ||
| - | oled.print(current_B, 0); | ||
| - | oled.setCursor(76,4); | ||
| - | oled.print(current_C, 0); | ||
| - | oled .setCursor(106,4); | ||
| - | oled.print(current_D, 0); | ||
| - | | ||
| - | oled.setCursor(0,5 ); | ||
| - | oled.print("W"); | ||
| - | oled.setCursor(16,5); | ||
| - | oled.print(power_A, 2); | ||
| - | oled.setCursor(46,5); | ||
| - | oled.print(power_B, 2); | ||
| - | oled.setCursor(76,5); | ||
| - | oled.print(power_C, 2); | ||
| - | oled.setCursor(106,5); | ||
| - | oled.print(power_D, 2); | ||
| - | |||
| - | delay(100); | ||
| - | } | ||
| - | |||
| - | </code> | ||
| - | |||
| - | ==== Kosztorys ==== | ||
| - | |||
| - | ==== Worklog ==== | ||
| - | |||
| - | * 08.07.2017 - rozpoczęcie prac nad pierwszym prototypem | ||
| - | * 15.07.2017 - pierwszy prototyp | ||
| - | * 31.07.2017 - drugi prototyp | ||
| - | * 01.08.2017 - rozpoczęcie prac nad projektem trzeciego prototypu | ||
| - | ===== Możliwości rozwoju projektu ===== | ||
| - | |||
| - | * implementacja na SMD i dalsze dopracowanie elektroniki (uwzględniona w trzecim projekcie) | ||
| - | * porządne UI z prawdziwego zdarzenia, tak żeby na każdym poziomie ogarnięcia można było użytkować urządzenie bez szkolenia | ||
| - | * obudowa spełniająca założenie powyżej | ||
| - | * dobre rozwiązanie regulacji napięcia szyn | ||
| - | * wymyślenie funkcjonalnego złącza pomiędzy zasilaczem i płytką, tak żeby było fizycznie i elektrycznie stabilne i nie zajmowało dużo miejsca na płytkach | ||