![Fabriquez un ventilateur électrique avec FireBeetle Board ESP32: 8 étapes Fabriquez un ventilateur électrique avec FireBeetle Board ESP32: 8 étapes](https://img.gwsigeps.com/img/circuits/make-an-electric-fan-with-firebeetle-board-esp32-7.jpg)
Table des matières:
- Provisions:
- Étape 1: Matériel nécessaire
- Étape 2: Connexion du matériel
- Étape 3: Imprimez la croûte avec une imprimante 3D.
- Étape 4: Fixez le codeur rotatif sur la croûte
- Étape 5: Fixez OLED2864 sur la croûte.
- Étape 6: connectez le BME280
- Étape 7: Allouer le ventilateur
- Étape 8: Assemblage complet de la machine
L'été arrive avec une chaleur de plus en plus chaude. C'est le bon moment pour préparer un truc d'été! Par conséquent, j'ai acheté une petite ferme en ligne; c'est bon sauf qu'il ne peut pas diriger.
Cependant, est-ce un problème? Non! En tant qu’ingénieur créatif, c’est mon heure de spectacle!
Provisions:
Étape 1: Matériel nécessaire
Contrôleur FireBeetle ESP32 × 1
FireBeetle Covers-Gravity Shield Expansion × 1
Gravité: Écran I2C OLED-2864 × 1
Capteur de température et d'humidité BME × 1
EC11J encodeur rotatif × 1
9g micro servo (1,6 kg) × 1
Ligne Dupont × 10 croûte imprimée avec l'imprimante 3D Overlord × 1
* Pas besoin de souder pendant tout le processus de travail.
Étape 2: Connexion du matériel
Connectez l’interface I2C de l’OLED12864 directement à l’interface I2C du blindage d’extension Gravity, puis connectez A du codeur rotatif EC11J à D0, B à D1, C à D8. Puis connectez le micro-servo à D3 et connectez l'interface SPI de BME280 directement à l'interface SPI de Gravity Expansion Shield, CS (Chip Select) à D5.
Le schéma de circuit est comme ci-dessous:
Étape 3: Imprimez la croûte avec une imprimante 3D.
Cliquez ici pour télécharger le programme et le code source pour l'impression 3D.
Ceci est imprimé par l'imprimante 3d Overlord.
Étape 4: Fixez le codeur rotatif sur la croûte
Fix avec de la colle holt-melt
Reliez l'EC11J au Gravity Board avec Dupont
Étape 5: Fixez OLED2864 sur la croûte.
Reliez l’écran OLED à Gravity Board avec Dupont et l’interface de connexion est I2C
Étape 6: connectez le BME280
Le BME280 utilise une interface SPI. Veuillez vous reporter au schéma de circuit précédent pour plus de détails sur la connexion.
Étape 7: Allouer le ventilateur
Retirez la batterie au lithium et connectez l'alimentation du ventilateur à Vcc et GND de FireBeetle ESP32, en connectant la batterie au lithium à FireBeetle ESP32. Ensuite, connectez le micro servo à D3.
Fixer les fils de Dupont avec de la colle holt-melt
Réglez le micro servo avec de la colle holt-melt
Étape 8: Assemblage complet de la machine
Couvrez le fond et fixez-le avec de la colle thermofusible, puis téléchargez le programme.
Code
#include // Nécessaire uniquement pour Arduino 1.6.5 et les versions antérieures
#include #include "SSD1306.h" // alias pour `#include" SSD1306Wire.h "` #include "OLEDDisplayUi.h" #include "images.h" #include #include #define SEA_LEVEL_PRESSURE 1013.25f minuteur; int timeCounter = 0; booléen uiEnable = true; DFRobot_BME280 bme (BME_CS); // SPI SSD1306 display (0x3c, D7, D6); Servo mymotor; OLEDDisplayUi ui (& display); modèle enum {MODEL_NULL, MODEL_LEFT, MODEL_RIGHT, MODEL_BUTTON}; énumération 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; dir booléen = true; int frameIndex = 0; long readEncoderValue (void) {return encoderValue / 4; } boolean isButtonPushDown (void) {if (! digitalRead (buttonPin)) {delay (5); if (! digitalRead (buttonPin)) {tandis que (! digitalRead (buttonPin)); retourne vrai; }} return false; } void msOverlay (affichage OLEDDisplay *, état OLEDDisplayUiState *) {if (frameIndex == 0) return; display-> setTextAlignment (TEXT_ALIGN_RIGHT); display-> setFont (ArialMT_Plain_10); display-> drawString (128, 0, String (angleValue)); } void drawFrame1 (affichage OLEDDisplay *, état OLEDDisplayUiState *, 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 (affichage OLEDDisplay *, état OLEDDisplayUiState *, 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 (); // illustre les 3 tailles par défaut incluses. Les polices proviennent du fichier SSD1306Fonts.h // Outre les polices par défaut, un programme sera utilisé pour convertir les polices TrueType dans ce 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, chaîne ("Pa:") + chaîne (pa)); } void drawFrame3 (affichage OLEDDisplay *, état OLEDDisplayUiState *, int16_t x, int16_t y) {// affichage de démonstration de l'alignement du texte-> setFont (ArialMT_Plain_16); // Les coordonnées définissent le point de départ gauche de l'affichage du texte-> setTextAlignment (TEXT_ALIGN_LEFT); display-> drawString (x, y, "définir la vitesse"); display-> drawString (40 + x, y + 17, String (speedValue)); } void drawFrame4 (affichage OLEDDisplay *, état OLEDDisplayUiState *, int16_t x, int16_t y) {// affichage de démonstration de l'alignement du texte-> setFont (ArialMT_Plain_16); // Les coordonnées définissent le point de départ gauche de l'affichage du texte-> setTextAlignment (TEXT_ALIGN_LEFT); display-> drawString (x, y, "modèle de ventilateur"); if (motorState == MOTOR_STATIC) {display-> drawString (40 + x, y + 27, "STATIC"); } else if (motorState == MOTOR_AUTO) {display-> drawString (40 + x, y + 27, "AUTO"); }} // Ce tableau conserve les pointeurs de fonction sur toutes les images // les images sont les vues uniques qui glissent dans les images FrameCallback = {drawFrame1, drawFrame2, drawFrame3, drawFrame4}; // combien y a-t-il d'images? int frameCount = 4; // Les superpositions sont statiquement dessinées au-dessus d'un cadre, par exemple. une horloge OverlayCallback recouvre = {msOverlay}; int overlaysCount = 1; void ec11Init (void) {pinMode (encoderPinA, INPUT); pinMode (encoderPinB, INPUT); pinMode (buttonPin, INPUT); digitalWrite (encoderPinA, HIGH); // tourne la résistance de rappel sur digitalWrite (encoderPinB, HIGH); // tourne la résistance de pullup sur 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 (frames, frameCount); ui.setOverlays (overlays, 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 (dir == 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) {valeur longue = readEncoderValue (); if (uiEnable == true) {if (valeur> 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; si (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 goingTimeBudget = ui.update (); if (whileTimeBudget> 0) {delay (goingTimeBudget); } doButton (); timer.run (); } void updateEncoder ()
LOL ~ bien fait!