![Wykonaj wentylator elektryczny z płytą FireBeetle ESP32: 8 kroków (ze zdjęciami) Wykonaj wentylator elektryczny z płytą FireBeetle ESP32: 8 kroków (ze zdjęciami)](https://img.gwsigeps.com/img/circuits/make-an-electric-fan-with-firebeetle-board-esp32-7.jpg)
Spisu treści:
- Kieszonkowe dzieci:
- Krok 1: Sprzęt w potrzebie
- Krok 2: Połączenie sprzętowe
- Krok 3: Wydrukuj skorupę z drukarką 3D.
- Krok 4: Przymocuj Rotary Encoder do skorupy
- Krok 5: Napraw OLED2864 na skorupie
- Krok 6: Podłącz BME280
- Krok 7: Przydziel wentylator
- Krok 8: Kompletny zespół maszyny
Nadchodzi lato ze stale rosnącym ciepłem. Teraz jest odpowiedni czas na przygotowanie letniej rzeczy! Dlatego kupiłem mały wentylator na linii; jest dobry, z wyjątkiem tego, że nie może sterować.
Czy to jednak problem? Nie! Jako kreatywny inżynier, to mój czas na pokaz!
Kieszonkowe dzieci:
Krok 1: Sprzęt w potrzebie
Kontroler FireBeetle ESP32 × 1
FireBeetle Covers-Gravity I / O Expansion Shield × 1
Grawitacja: Wyświetlacz I2C OLED-2864 × 1
Czujnik temperatury i wilgotności BME × 1
Koder EC11J × 1
9 g mikro serwo (1,6 kg) × 1
Dupont line × 10 Crust drukowany przez drukarkę Overlord 3D × 1
* Nie ma potrzeby lutowania podczas całego procesu roboczego.
Krok 2: Połączenie sprzętowe
Podłącz interfejs I2C OLED12864 bezpośrednio do interfejsu I2C osłony Gravity Expansion i podłącz enkoder obrotowy A z EC11J do D0, B do D1, C do D8. Następnie podłącz mikro serwo do D3 i podłącz interfejs SPI BME280 bezpośrednio do interfejsu SPI Gravity Expansion shield, CS (Chip Select) do D5.
Schemat obwodu jest następujący:
Krok 3: Wydrukuj skorupę z drukarką 3D.
Kliknij tutaj, aby pobrać program i kod źródłowy do druku 3D.
Jest to drukowane przez drukarkę 3D Overlord.
Krok 4: Przymocuj Rotary Encoder do skorupy
Fix z klejem holt-topienia
Połącz EC11J z Gravity Board z Dupont
Krok 5: Napraw OLED2864 na skorupie
Podłącz wyświetlacz OLED do płyty Gravity z Dupont, a interfejsem połączenia jest I2C
Krok 6: Podłącz BME280
BME280 wykorzystuje interfejs SPI, szczegółowe informacje na temat połączenia można znaleźć w poprzednim schemacie obwodu
Krok 7: Przydziel wentylator
Wyjmij baterię litową i podłącz zasilanie wentylatora do Vcc i GND FireBeetle ESP32, krawędź łącząca baterię litową z FireBeetle ESP32. Następnie podłącz mikropomocowanie do D3.
Napraw przewody Dupont za pomocą kleju holt-topliwego
Ustaw mikro serwo z klejem holt-topliwym
Krok 8: Kompletny zespół maszyny
Przykryj spód i zamocuj klejem topliwym, a następnie pobierz program.
Kod
#include // Potrzebny tylko dla Arduino 1.6.5 i wcześniejszych
#include #include "SSD1306.h" // alias dla `#include" SSD1306Wire.h "` #include "OLEDDisplayUi.h" #include "images.h" #include #include #define SEA_LEVEL_PRESSURE 1013.25f #define BME_CS D5 SimpleTimer regulator czasowy; int timeCounter = 0; boolean uiEnable = true; DFRobot_BME280 bme (BME_CS); // Wyświetlacz SPI SSD1306 (0x3c, D7, D6); Servo mymotor; OLEDDisplayUi ui (i wyświetlacz); enum model {MODEL_NULL, MODEL_LEFT, MODEL_RIGHT, MODEL_BUTTON}; enum setFrame {SET_NULL, SET_FRAME_2_ON, SET_FRAME_2_OFF, SET_FRAME_3_ON, SET_FRAME_3_OFF}; enum motorModel {MOTOR_AUTO, MOTOR_STATIC}; char commondModel = MODEL_NULL; char setFrameValue = SET_NULL; char motorState = MOTOR_STATIC; int encoderPinA = D0; int encoderPinB = D1; int buttonPin = D8; volatile int lastEncoded = 0; volatile long encoderValue = 0; long lastencoderValue = 0; int lastMSB = 0; int lastLSB = 0; int speedValue = 5; int angleValue = 90; boolean dir = true; int frameIndex = 0; long readEncoderValue (void) {return encoderValue / 4; } boolean isButtonPushDown (void) {if (! digitalRead (buttonPin)) {delay (5); if (! digitalRead (buttonPin)) {while (! digitalRead (buttonPin)); powrót prawda; }} return false; } void msOverlay (OLEDDisplay * display, OLEDDisplayUiState * state) {if (frameIndex == 0) zwraca; display-> setTextAlignment (TEXT_ALIGN_RIGHT); display-> setFont (ArialMT_Plain_10); display-> drawString (128, 0, String (angleValue)); } void drawFrame1 (OLEDDisplay * display, OLEDDisplayUiState * state, int16_t x, int16_t y) {display-> setTextAlignment (TEXT_ALIGN_LEFT); display-> setFont (ArialMT_Plain_24); display-> drawString (15 + x, 10+ y, „ChoCho”); } void drawFrame2 (OLEDDisplay * display, OLEDDisplayUiState * state, int16_t x, int16_t y) {float temp = bme.temperatureValue (); float pa = bme.pressureValue (); float hum = bme.altitudeValue (SEA_LEVEL_PRESSURE); float alt = bme.humidityValue (); // Pokazuje 3 załączone domyślne rozmiary. Czcionki pochodzą z pliku SSD1306Fonts.h // Oprócz domyślnych czcionek będzie program do konwersji czcionek TrueType na ten format display-> setTextAlignment (TEXT_ALIGN_LEFT); display-> setFont (ArialMT_Plain_16); display-> drawString (x, y, String ("Temp:") + String (temp)); display-> drawString (x, 17 + y, String ("Hum:") + String (alt)); display-> drawString (x, 34 + y, String ("Pa:") + String (pa)); } void drawFrame3 (OLEDDisplay * display, OLEDDisplayUiState * state, int16_t x, int16_t y) {// Wyświetlenie wyrównania tekstu demo-> setFont (ArialMT_Plain_16); // Współrzędne definiują lewy punkt początkowy wyświetlania tekstu-> setTextAlignment (TEXT_ALIGN_LEFT); display-> drawString (x, y, „Set Speed”); display-> drawString (40 + x, y + 17, String (speedValue)); } void drawFrame4 (OLEDDisplay * display, OLEDDisplayUiState * state, int16_t x, int16_t y) {// Wyświetlenie wyrównania tekstu demo-> setFont (ArialMT_Plain_16); // Współrzędne definiują lewy punkt początkowy wyświetlania tekstu-> setTextAlignment (TEXT_ALIGN_LEFT); display-> drawString (x, y, „FAN Model”); if (motorState == MOTOR_STATIC) {display-> drawString (40 + x, y + 27, „STATIC”); } else if (motorState == MOTOR_AUTO) {display-> drawString (40 + x, y + 27, „AUTO”); }} // Ta tablica przechowuje wskaźniki funkcji do wszystkich ramek // ramek to pojedyncze widoki, które przesuwają się w ramkach FrameCallback = {drawFrame1, drawFrame2, drawFrame3, drawFrame4}; // ile jest klatek? int frameCount = 4; // Nakładki są statycznie rysowane na górze ramki, np. zegar Nakładki OverlayCallback = {msOverlay}; int overlaysCount = 1; void ec11Init (void) {pinMode (encoderPinA, INPUT); pinMode (encoderPinB, INPUT); pinMode (buttonPin, INPUT); digitalWrite (encoderPinA, HIGH); // włącz rezystor pullup na digitalWrite (enkoderPinB, HIGH); // włącz rezystor pullup na attachInterrupt (D0, updateEncoder, CHANGE); attachInterrupt (D1, updateEncoder, CHANGE); } void displayInit (void) {ui.setTargetFPS (60); ui.setActiveSymbol (activeSymbol); ui.setInactiveSymbol (inactiveSymbol); ui.setIndicatorPosition (BOTTOM); ui.setIndicatorDirection (LEFT_RIGHT); ui.setFrameAnimation (SLIDE_LEFT); ui.setFrames (frame, frameCount); ui.setOverlays (nakładki, overlaysCount); ui.disableAutoTransition (); ui.switchToFrame (frameIndex); ui.init (); display.flipScreenVertically (); } void motorInit (void) {mymotor.attach (D3); mymotor.write (speedValue); } void updateUi (void) {if (timeCounter> 50) {display.displayOff (); uiEnable = false; } else {display.displayOn (); uiEnable = true; timeCounter ++; } if (commondModel == MODEL_RIGHT) {frameIndex ++; if (frameIndex> 3) frameIndex = 0; ui.switchToFrame (frameIndex); } else if (commondModel == MODEL_LEFT) {frameIndex--; if (frameIndex <0) frameIndex = 3; ui.switchToFrame (frameIndex); } commondModel = MODEL_NULL; } void updateMotor (void) {if (motorState == MOTOR_AUTO) {if (katalog == true) {angleValue + = speedValue; } else {angleValue - = speedValue; }} if (angleValue> 180) dir = false; else if (angleValue <0) dir = true; mymotor.write (angleValue); } void doButton (void) {if (isButtonPushDown ()) {if (uiEnable == false) {commondModel = MODEL_NULL; } else {commondModel = MODEL_BUTTON; } timeCounter = 0; } if (readEncoderValue ()! = 0) {long value = readEncoderValue (); if (uiEnable == true) {if (wartość> 0) {commondModel = MODEL_RIGHT; } else {commondModel = MODEL_LEFT; }} timeCounter = 0; encoderValue = 0; } if (frameIndex == 2) {if (commondModel == MODEL_BUTTON) {if (setFrameValue == SET_FRAME_2_ON) {setFrameValue = SET_FRAME_2_OFF; } else {setFrameValue = SET_FRAME_2_ON; } commondModel = MODEL_NULL; } if (setFrameValue == SET_FRAME_2_ON) {if (commondModel == MODEL_RIGHT) {speedValue ++; } else if ((commondModel == MODEL_LEFT)) {speedValue--; } if (speedValue> 20) speedValue = 20; if (speedValue <0) speedValue = 0; commondModel = MODEL_NULL; }} if (frameIndex == 3) {if (commondModel == MODEL_BUTTON) {if (setFrameValue == SET_FRAME_3_ON) {setFrameValue = SET_FRAME_3_OFF; } else {setFrameValue = SET_FRAME_3_ON; } commondModel = MODEL_NULL; } if (setFrameValue == SET_FRAME_3_ON) {if ((commondModel == MODEL_RIGHT) || (commondModel == MODEL_LEFT)) {motorState = (motorState == MOTOR_AUTO)? MOTOR_STATIC: MOTOR_AUTO; } commondModel = MODEL_NULL; }}} void setup () {ec11Init (); displayInit (); motorInit (); bme.begin (); timer.setInterval (200, updateUi); timer.setInterval (50, updateMotor); } void loop () {int remainTimeBudget = ui.update (); if (remainTimeBudget> 0) {delay (remainTimeBudget); } doButton (); timer.run (); } void updateEncoder ()
LOL ~ dobrze zrobione!