FireBeetleボードESP32で扇風機を作る:8つのステップ(写真付き)

FireBeetleボードESP32で扇風機を作る:8つのステップ(写真付き)

目次:

Anonim

夏は着実に暖かさを増して来ています。今、夏のものを準備するのに適した時期です──より良いです!したがって、私はオンラインで小型のファンを購入しました。操縦できないこと以外は良いです。

しかし、これは問題ですか?いいえ!クリエイティブエンジニアとして、それは私のショータイムです!

用品:

ステップ1:必要としているハードウェア

FireBeetle ESP32コントローラー×1

FireBeetleカバー - 重力I / O拡張シールド×1

重力:I2C OLED-2864ディスプレイ×1

BME温湿度センサー×1

EC11Jロータリーエンコーダ×1

9gマイクロサーボ(1.6kg)×1

デュポンライン×10 Overlord 3Dプリンターでプリントしたクラスト×1

*全作業過程の間にはんだ付けする必要性無し。

ステップ2:ハードウェア接続

OLED12864のI2CインターフェースをGravity ExpansionシールドのI2Cインターフェースに直接接続し、EC11JロータリーエンコーダのAをD0に、BをD1に、CをD8に接続します。次にマイクロサーボをD3に接続し、BME280のSPIインターフェースを重力拡張シールドのSPIインターフェースに直接接続し、CS(チップセレクト)をD5に接続します。

回路図は以下の通りです。

ステップ3:3Dプリンターで地殻を印刷する

3D印刷用のプログラムとソースコードをダウンロードするには、ここをクリックしてください。

これはOverlord 3Dプリンターによって印刷されます。

ステップ4:ロータリーエンコーダを外皮に固定する

ホルトメルト接着剤で固定する

デュポンで重力委員会にEC11Jを接続してください

ステップ5:地殻にOLED2864を修正

デュポンで重力板にOLEDディスプレイを接続してください、そして、接続インタフェースはI2Cです

ステップ6:BME280を接続する

BME280はSPIインターフェースを使用しています。接続の詳細については前の回路図を参照してください。

ステップ7:ファンの割り当て

リチウム電池を取り外し、ファンの電源をFireBeetle ESP32のVccとGNDに接続し、リチウム電池をFireBeetle ESP32に接続します。その後、マイクロサーボをD3に接続してください。

デュポンワイヤーをホルトメルト接着剤で固定する

ホルトメルト接着剤でマイクロサーボを設定する

ステップ8:完全な機械組み立て

底を覆い、それをホットメルト接着剤で固定して、プログラムをダウンロードしてください。

コード

#include // Arduino 1.6.5以前にのみ必要

#include #include "SSD1306.h" // `#include" SSD1306Wire.h "` #include "OLEDDisplayUi.h" #include "images.h"のエイリアス#include #include #define BME_CS D5単純なBME_CS D5タイマー; int timeCounter = 0。ブール値uiEnable = true; DFRobot_BME280 bme(BME_CS)。 // SPI SSD1306ディスプレイ(0x3c、D7、D6)。サーボ筋運動OLEDディスプレイディスプレイ(&display);列挙型モデル{MODEL_NULL、MODEL_LEFT、MODEL_RIGHT、MODEL_BUTTON}。列挙型setFrame {SET_NULL、SET_FRAME_2_ON、SET_FRAME_2_OFF、SET_FRAME_3_ON、SET_FRAME_3_OFF}。列挙体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。揮発性の長いエンコーダ値= 0。 long lastencoderValue = 0。 int lastMSB = 0。 int lastLSB = 0。 int speedValue = 5。 int angleValue = 90;ブール値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)); trueを返します。 falseを返します。 void msOverlay(OLEDDisplay *表示、OLEDDisplayUiState * state){if(frameIndex == 0)が返されます。 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(); //含まれている3つのデフォルトサイズを示します。フォントはSSD1306Fonts.hファイルから来ています。//デフォルトフォントの他に、TrueTypeフォントをこのフォーマットに変換するプログラムがあります。display-> setTextAlignment(TEXT_ALIGN_LEFT); display-> setFont(ArialMT_Plain_16); display-> drawString(x、y、String( "Temp:")+ String(temp)); display-> drawString(x、17 + y、文字列( "Hum:")+文字列(alt)); display-> drawString(x、34 + y、文字列( "Pa:")+文字列(pa)); void drawFrame3(OLEDDisplay * display、OLEDDisplayUiState * state、int16_t x、int16_t y){//テキスト配置デモdisplay-> setFont(ArialMT_Plain_16); //座標はテキスト表示の左の始点を定義します - > 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){//テキスト配置デモdisplay-> setFont(ArialMT_Plain_16); //座標はテキスト表示の左の始点を定義します - > setTextAlignment(TEXT_ALIGN_LEFT); display-> drawString(x、y、 "FAN Model"); if(motorState == MOTOR_STATIC){display-> drawString(40 + x、y + 27、 "STATIC");それ以外の場合(motorState == MOTOR_AUTO){display-> drawString(40 + x、y + 27、 "AUTO"); //この配列は、すべてのフレームへの関数ポインタを保持します。//フレームは、FrameCallback内をスライドする単一のビューです。frames = {drawFrame1、drawFrame2、drawFrame3、drawFrame4}; //フレーム数は? int frameCount = 4; //オーバーレイはフレームの上に静的に描画されます。クロックOverlayCallback overlay = {msOverlay}。 int overlayysCount = 1; void ec11Init(void){pinMode(encoderPinA、INPUT); pinMode(encoderPinB、INPUT); pinMode(buttonPin、INPUT); digitalWrite(encoderPinA、HIGH); // digitalWrite(encoderPinB、HIGH)のプルアップ抵抗をオンにします。 // 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(overlay、overlayysCount); 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(フレームインデックス> 3)フレームインデックス= 0。 ui.switchToFrame(frameIndex);そうでなければ(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;それ以外の場合(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(値> 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 ++;}そうでなければ((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 residualTimeBudget = ui.update();} if(residualTimeBudget> 0){delay(residualTimeBudget); doButton(); timer.run(); void updateEncoder()

笑〜よくやった!