Baize_ServoDriver_esp32——arduino 32路舵机驱动板(esp32主控,免费开源,附程序、固件)
?該機器人開發板的用法和介紹以本文章為準。
最新的代碼github倉庫為準:https://github.com/Allen953/Baize_ServoDriver_esp32
介紹
倉庫總是存放最新代碼,CSDN的代碼可能存在滯后?!
出于制作機器人的需要,設計了這塊兒32路舵機驅動板,板子可以驅動從5~12V的pwm舵機,適應電壓范圍較寬,所以用起來會非常方便。
板載有電壓監測電路和蜂鳴器,這樣如果你使用電池為機器人供電時,可以通過電壓檢測電路來測量電池電量情況,如果電量過低,則需要報警并停止機器人動作,提示我們進行充電。
板載還有mpu6050,這樣我們可以感知機器人的姿態等信息,可以根據機器人姿態進行動作的規劃。
同時板載一個小型彩色屏幕1.14寸,140*240的分辨率,可以實時顯示板子和機器人的狀態,方便機器人的現場測試。
板子上還有幾個獨立按鍵,作為調試按鈕,可以靈活定制按鈕功能,對機器人進行調試。
硬件原理圖及PCB文件和資料開源鏈接:GitHub - Allen953/Baize_ServoDriver_esp32
?如果你的Arduino IDE由于配置問題無法正確編譯倉庫代碼,可以直接燒錄倉庫里代碼文件旁邊的固件(bin文件)來對板子進行測試,效果是一樣的,只是省去了用Arduino IDE編譯代碼這個過程。
具體的燒錄固件的方法見此教程:https://blog.csdn.net/qqliuzhitong/article/details/125852218
接線說明
兩排排針用于接32路舵機用,舵機線由S,V,G構成,注意正反。
藍色接線端子用于接電源,如果用電池直供板子,則調帽調到左邊,用于檢測默認電池輸入電壓。如果電池經過壓降模塊之后,給板子供電,則板子檢測到的電壓為板子本身的電壓,無法反映電池真實電壓,這時,將電池正極接入綠色接線端子的S端子里面,同時將跳帽移到右邊,這時板子電壓檢測綠色端子S端輸入的電壓,即電池電壓。
電壓過低,則啟動蜂鳴器報警同時停止程序運行。
?例程1:按鍵檢測
/*******************************************************Baize_ServoDriver_esp32功能:測試獨立按鍵引腳:key1:35 key2:34 key3:39 key4:36Designer: AllenE-mail:953598974@qq.comDate:2022-09-09 21:08 *******************************************************/#define key1 35 #define key2 34 #define key3 39 #define key4 36void setup() {Serial.begin(115200);pinMode(key1,INPUT);pinMode(key2,INPUT);pinMode(key3,INPUT);pinMode(key4,INPUT); }void loop() {Serial.print("key1:");Serial.print(digitalRead(key1));Serial.print(" ");Serial.print("key2:");Serial.print(digitalRead(key2));Serial.print(" ");Serial.print("key3:");Serial.print(digitalRead(key3));Serial.print(" ");Serial.print("key4:");Serial.print(digitalRead(key4));Serial.println(); }當我們按下某個按鍵之后,打開串口,我們會發現這個按鍵從0變為了1,即從低電平變為高電平。
?例程2:發現(校驗)板子上的iic設備
/*******************************************************Baize_ServoDriver_esp32功能:掃描iic設備引腳:SDA:21 SCL:22Designer: AllenE-mail:953598974@qq.comDate:2022-08-22*******************************************************/ #include <Wire.h>void setup() {Wire.begin();Serial.begin(115200); }void loop() {byte error, address;int nDevices;Serial.println("Scanning...");nDevices = 0;for(address = 1; address < 127; address++ ) {Wire.beginTransmission(address);error = Wire.endTransmission();if (error == 0){Serial.print("I2C device found at address 0x");if (address<16) Serial.print("0");Serial.print(address,HEX);Serial.println(" !");nDevices++;}else if (error==4) {Serial.print("Unknown error at address 0x");if (address<16) Serial.print("0");Serial.println(address,HEX);} }if (nDevices == 0)Serial.println("No I2C devices found\n");elseSerial.println("done\n");delay(5000); }?例程3:控制32路舵機勻速旋轉從0-180度,再從180-0度
/*******************************************************Baize_ServoDriver_esp32功能:測試舵機引腳:SDA:21 SCL:22對于ARDUINO UNO,SCL:A5,SDA:A4Designer: AllenE-mail:953598974@qq.comDate:2022-08-22 *******************************************************/#include <Wire.h> #include <Adafruit_PWMServoDriver.h>Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x41);//#define SERVOMIN 102 //0.5/20 * 4096 = 102 //#define SERVOMID 307 //1.5/20 * 4096 = 307 //#define SERVOMAX 512 //2.5/20 * 4096 = 512//實際測試 #define SERVOMIN 102 #define SERVOMID 327 #define SERVOMAX 552 void setup() {Serial.begin(115200);Serial.println("16 channel Servo test!");pwm.begin();pwm1.begin();pwm.setPWMFreq(50); // Analog servos run at ~50 Hz updatespwm1.setPWMFreq(50); // Analog servos run at ~50 Hz updates }void loop() {for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {for(int i=0;i<16;i++){pwm.setPWM(i, 0, pulselen);pwm1.setPWM(i, 0, pulselen);}delayMicroseconds(200);}for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {for(int i=0;i<16;i++){pwm.setPWM(i, 0, pulselen);pwm1.setPWM(i, 0, pulselen);}delayMicroseconds(200);} }?例程4:控制32路舵機從0,90,180,90,0度之間循環。
/*******************************************************Baize_ServoDriver_esp32功能:測試舵機引腳:SDA:21 SCL:22對于ARDUINO UNO,SCL:A5,SDA:A4Designer: AllenE-mail:953598974@qq.comDate:2022-08-22 *******************************************************/#include <Wire.h> #include <Adafruit_PWMServoDriver.h>Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x41);#define SERVOMIN 102 //0.5/20 * 4096 = 102 #define SERVOMID 307 //(102+512)/2=307 #define SERVOMAX 512 //2.5/20 * 4096 = 512//pwm.setPWM(i, 0, pulse);i=0~15對應第0-15個舵機;pwm1.setPWM(j, 0, pulse);j=0~15對應第16-31個舵機,void setup() {Serial.begin(115200);Serial.println("16 channel Servo test!");pwm.begin();pwm1.begin();pwm.setPWMFreq(50); // Analog servos run at ~50 Hz updatespwm1.setPWMFreq(50); // Analog servos run at ~50 Hz updates }void loop() {//全部舵機轉到0度for(int i=0;i<16;i++){pwm.setPWM(i, 0, SERVOMIN);pwm1.setPWM(i, 0, SERVOMIN);}delayMicroseconds(200);delay(1000);//全部舵機轉到90度for(int i=0;i<16;i++){pwm.setPWM(i, 0, SERVOMID);pwm1.setPWM(i, 0, SERVOMID);}delayMicroseconds(200);delay(1000);//全部舵機轉到180度for(int i=0;i<16;i++){pwm.setPWM(i, 0, SERVOMAX);pwm1.setPWM(i, 0, SERVOMAX);}delayMicroseconds(200);delay(1000);//全部舵機轉到90度for(int i=0;i<16;i++){pwm.setPWM(i, 0, SERVOMID);pwm1.setPWM(i, 0, SERVOMID);}delayMicroseconds(200);delay(1000); }?例程5:控制32路舵機從0-180度之間循環,正弦速度。?
/*******************************************************Baize_ServoDriver_esp32功能:測試舵機引腳:SDA:21 SCL:22對于ARDUINO UNO,SCL:A5,SDA:A4Designer: AllenE-mail:953598974@qq.comDate:2022-11-13 15:47 *******************************************************/#include <Wire.h> #include <Adafruit_PWMServoDriver.h>#define pi 3.1415926 #define pi2 1.5707963 #define radtodeg 57.295780 //position = -pi/2 * cos((pi/2) * t) + pi/2 //velocity = (pi^2)/4 * sin((pi/2) * t)Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x41);//#define SERVOMIN 102 //0.5/20 * 4096 = 102 //#define SERVOMID 307 //1.5/20 * 4096 = 307 //#define SERVOMAX 512 //2.5/20 * 4096 = 512 //實際測試 #define SERVOMIN 102 #define SERVOMID 327 #define SERVOMAX 552 long time_p = 0;void setup() {// put your setup code here, to run once:Serial.begin(115200);pwm.begin();pwm1.begin();pwm.setPWMFreq(50); // Analog servos run at ~50 Hz updatespwm1.setPWMFreq(50); // Analog servos run at ~50 Hz updates }void loop() {// put your main code here, to run repeatedly:float t = float(millis())/1000.0;float v = (pi*pi)/4 * sin((pi2) * t);float p = -pi2 * cos((pi2) * t) + pi2;int pulselen = int(map(p * radtodeg,0.0,180.0,float(SERVOMIN),float(SERVOMAX)));for(int i=0;i<16;i++){pwm.setPWM(i, 0, pulselen);pwm1.setPWM(i, 0, pulselen);}Serial.println(pulselen);delay(10); }?
?例程6:測試MPU6050
/*******************************************************Baize_ServoDriver_esp32功能:測試mpu6050引腳:SDA:21 SCL:22對于ARDUINO UNO,SCL:A5,SDA:A4Designer: AllenE-mail:953598974@qq.comDate:2022-08-22 *******************************************************/#include "Wire.h" //I2C通訊庫 #include "I2Cdev.h" // #include "MPU6050.h" //mpu6050庫MPU6050 mympu; //定義mympu對象float pi=3.1415926; //Π的值,用于單位轉換 float AcceRatio=16384.0; //加速度計比例系數 float GyroRatio=131.0; //陀螺儀比例系數 //定義3個變量,用于存儲傾角數據 float angle_x=0.0,angle_y=0.0,angle_z=0.0; int16_t ax=0,ay=0,az=0,gx=0,gy=0,gz=0; //加速度計陀螺儀原始數據 float accx=0.0,accy=0.0,accz=0.0;void setup(){ Wire.begin();//開啟iic通訊,mpu6050的數據傳輸協議為iicSerial.begin(115200);//打開串口mympu.initialize(); //初始化mpu6050 }void loop() {//通過調用該函數,一次性從mpu6050獲取6軸數據mympu.getMotion6(&ax,&ay,&az,&gx,&gy,&gz);accx=ax/AcceRatio; //x軸加速度accy=ay/AcceRatio; //y軸加速度accz=az/AcceRatio; //z軸加速度angle_x=(atan(accx/accz)*180/pi); //計算身體前后的傾角,繞y軸的轉角angle_y=(atan(accy/accz)*180/pi); //計算身體左右的傾角,繞x軸的轉角Serial.print(az);Serial.print(" ");//將z軸加速度原始數據輸出Serial.print(accx);Serial.print(" ");//將3軸加速度輸出(單位:g)Serial.print(accy);Serial.print(" ");//將兩個轉角從串口輸出Serial.print(accz);Serial.print(" ");//將兩個轉角從串口輸出Serial.print(angle_x);Serial.print(" ");//將兩個轉角從串口輸出Serial.print(angle_y);Serial.println(" ");delay(100); }這個例程貌似跑不通,但是燒錄mpu6050庫里面的dmp例程可以跑通,庫里的其他例程好像也跑不通,應該是代碼哪里有問題。
/*******************************************************Baize_ServoDriver_esp32功能:測試MPU6050(DMP例程)引腳:MOSI:21 CLK:18 RS:12 RES:13 CS:5 BLK:15Designer: AllenE-mail:953598974@qq.comDate:2022-09-09 21:58 *******************************************************/ #include "I2Cdev.h"#include "MPU6050_6Axis_MotionApps20.h"#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE#include "Wire.h" #endifMPU6050 mpu;#define OUTPUT_READABLE_YAWPITCHROLL#define INTERRUPT_PIN 2 // use pin 2 on Arduino Uno & most boards bool blinkState = false;bool dmpReady = false; // set true if DMP init was successful uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) uint16_t packetSize; // expected DMP packet size (default is 42 bytes) uint16_t fifoCount; // count of all bytes currently in FIFO uint8_t fifoBuffer[64]; // FIFO storage buffer// orientation/motion vars Quaternion q; // [w, x, y, z] quaternion container VectorInt16 aa; // [x, y, z] accel sensor measurements VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements VectorFloat gravity; // [x, y, z] gravity vector float euler[3]; // [psi, theta, phi] Euler angle container float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector// packet structure for InvenSense teapot demo uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high void dmpDataReady() {mpuInterrupt = true; }void setup() {// join I2C bus (I2Cdev library doesn't do this automatically)#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIREWire.begin();Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIREFastwire::setup(400, true);#endif// initialize serial communication// (115200 chosen because it is required for Teapot Demo output, but it's// really up to you depending on your project)Serial.begin(115200);while (!Serial); // wait for Leonardo enumeration, others continue immediately// initialize deviceSerial.println(F("Initializing I2C devices..."));mpu.initialize();pinMode(INTERRUPT_PIN, INPUT);// verify connectionSerial.println(F("Testing device connections..."));Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));// wait for readySerial.println(F("\nSend any character to begin DMP programming and demo: "));while (Serial.available() && Serial.read()); // empty bufferwhile (!Serial.available()); // wait for datawhile (Serial.available() && Serial.read()); // empty buffer again// load and configure the DMPSerial.println(F("Initializing DMP..."));devStatus = mpu.dmpInitialize();// supply your own gyro offsets here, scaled for min sensitivitympu.setXGyroOffset(220);mpu.setYGyroOffset(76);mpu.setZGyroOffset(-85);mpu.setZAccelOffset(1788); // 1688 factory default for my test chip// make sure it worked (returns 0 if so)if (devStatus == 0) {// Calibration Time: generate offsets and calibrate our MPU6050mpu.CalibrateAccel(6);mpu.CalibrateGyro(6);mpu.PrintActiveOffsets();// turn on the DMP, now that it's readySerial.println(F("Enabling DMP..."));mpu.setDMPEnabled(true);// enable Arduino interrupt detectionSerial.print(F("Enabling interrupt detection (Arduino external interrupt "));Serial.print(digitalPinToInterrupt(INTERRUPT_PIN));Serial.println(F(")..."));attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);mpuIntStatus = mpu.getIntStatus();// set our DMP Ready flag so the main loop() function knows it's okay to use itSerial.println(F("DMP ready! Waiting for first interrupt..."));dmpReady = true;// get expected DMP packet size for later comparisonpacketSize = mpu.dmpGetFIFOPacketSize();} else {// ERROR!// 1 = initial memory load failed// 2 = DMP configuration updates failed// (if it's going to break, usually the code will be 1)Serial.print(F("DMP Initialization failed (code "));Serial.print(devStatus);Serial.println(F(")"));} }void loop() {// if programming failed, don't try to do anythingif (!dmpReady) return;if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { // Get the Latest packet mpu.dmpGetQuaternion(&q, fifoBuffer);mpu.dmpGetGravity(&gravity, &q);mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);Serial.print("ypr\t");Serial.print(ypr[0] * 180/M_PI);Serial.print("\t");Serial.print(ypr[1] * 180/M_PI);Serial.print("\t");Serial.println(ypr[2] * 180/M_PI);} }?例程7:測試蜂鳴器?
/*******************************************************Baize_ServoDriver_esp32功能:測試蜂鳴器引腳:D2(GPIO2)Designer: AllenE-mail:953598974@qq.comDate:2022-08-22*******************************************************/ #define LED_PWM 2 //把調用的GPIO引腳進行了一個宏定義 int freq = 5000; int ledChannel = 0; int resolution = 8; void setup() {ledcSetup(ledChannel, freq, resolution);ledcAttachPin(LED_PWM, ledChannel); } void loop() {ledcWrite(ledChannel, 180);delay(100);ledcWrite(ledChannel, 0);delay(100); }?例程8:帶電壓監測的板子測試程序
升級版,主控esp32。供電范圍5-12V。當我用7.4V的2S鋰電池給舵機供電時,用這個程序來進行板子測試,由于測試時間較長,擔心電池過放,所以通過電壓監測,當電壓過低時,將不再驅動舵機工作。
/*******************************************************Baize_ServoDriver_esp32功能:測試顯示屏引腳:MOSI:21 CLK:18 RS:12 RES:13 CS:5 BLK:15Designer: AllenE-mail:953598974@qq.comDate:2022-08-22 *******************************************************/#include <Wire.h> #include <Adafruit_PWMServoDriver.h>Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x41);#define SERVOMIN 102 //0.5/20 * 4096 = 102 #define SERVOMAX 512 //2.5/20 * 4096 = 512 //pcb板測試時,如果是2S的鋰電池供電,則以此電壓為閾值,低于此電壓時,不再驅動舵機運動,保護電池。 float voltage_threshold = 6.5; int voltage_testpin = 26; float voltage_b = 0.0;bool servo_f = 1;void setup() {Serial.begin(115200);Serial.println();Serial.println("16 channel Servo test!");pwm.begin();pwm1.begin();pwm.setPWMFreq(50); // Analog servos run at ~50 Hz updatespwm1.setPWMFreq(50); // Analog servos run at ~50 Hz updatesdelay(200);for(int i=0;i<16;i++){pwm.setPWM(i, 0, SERVOMIN); // 驅動32路舵機轉到0度pwm1.setPWM(i, 0, SERVOMIN);// 驅動32路舵機轉到0度}delay(2000);for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {for(int i=0;i<16;i++){pwm.setPWM(i, 0, pulselen);pwm1.setPWM(i, 0, pulselen);}delayMicroseconds(200);} }void loop() {if(servo_f==1){for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {for(int i=0;i<16;i++){pwm.setPWM(i, 0, pulselen);pwm1.setPWM(i, 0, pulselen);}delayMicroseconds(200);}//電壓檢測int voltage_sum = 0.0;for(int i=0;i<10;i++){voltage_sum += float(analogRead(voltage_testpin))/4095.0*3.3*4.0;Serial.println(analogRead(voltage_testpin));delay(100);}voltage_b = voltage_sum / 10.0;Serial.println(voltage_b);if(voltage_b<voltage_threshold)servo_f = 0;for(int i=0;i<16;i++){pwm.setPWM(i, 0, SERVOMIN); // 驅動32路舵機轉到0度pwm1.setPWM(i, 0, SERVOMIN);// 驅動32路舵機轉到0度}delay(2000);}}?例程9:顯示屏測試
我們還是使用TFT_ESPI庫來驅動這塊屏幕,首先進行自定義設置:?
最終Setup24_ST7789.h文件內容如下:
// ST7789 240 x 240 display with no chip select line #define USER_SETUP_ID 24#define ST7789_DRIVER // Configure all registers#define TFT_WIDTH 135 #define TFT_HEIGHT 240//#define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue //#define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red//#define TFT_INVERSION_ON //#define TFT_INVERSION_OFF// DSTIKE stepup //#define TFT_DC 23 //#define TFT_RST 32 //#define TFT_MOSI 26 //#define TFT_SCLK 27// Generic ESP32 setup #define TFT_MISO 19 #define TFT_MOSI 23 #define TFT_SCLK 18 #define TFT_CS 5 // Not connected #define TFT_DC 12 #define TFT_RST 13 // Connect reset to ensure display initialises#define TFT_BL 15 #define TFT_BACKLIGHT_ON HIGH // Level to turn ON back-light (HIGH or LOW)// For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation // #define TFT_CS -1 // Define as not used // #define TFT_DC PIN_D1 // Data Command control pin // #define TFT_RST PIN_D4 // TFT reset pin (could connect to NodeMCU RST, see next line) //#define TFT_RST -1 // TFT reset pin connect to NodeMCU RST, must also then add 10K pull down to TFT SCK#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH #define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters #define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters #define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm #define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:. #define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-. //#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT #define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts#define SMOOTH_FONT// #define SPI_FREQUENCY 27000000 #define SPI_FREQUENCY 40000000#define SPI_READ_FREQUENCY 20000000#define SPI_TOUCH_FREQUENCY 2500000// #define SUPPORT_TRANSACTIONS?注釋原本的設置文件,并將自定義設置文件取消注釋使之生效:
?然后燒錄例程程序即可,打開如下例程:
然后添加一句屏幕旋轉的代碼:
?效果如下圖:
?自定義代碼:
/*******************************************************Baize_ServoDriver_esp32功能:測試顯示屏引腳:MOSI:21 CLK:18 RS:12 RES:13 CS:5 BLK:15Designer: AllenE-mail:953598974@qq.comDate:2022-08-22 *******************************************************/ #include <SPI.h> #include <TFT_eSPI.h>TFT_eSPI TFT = TFT_eSPI();void setup() {TFT.init();TFT.setRotation(3);TFT.fillScreen(TFT_BLACK);TFT.initDMA(); }void loop() {TFT.setCursor(10, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println("Hello Allen!\n"); }效果:
/*******************************************************Baize_ServoDriver_esp32功能:測試顯示屏引腳:MOSI:21 CLK:18 RS:12 RES:13 CS:5 BLK:15Designer: AllenE-mail:953598974@qq.comDate:2022-08-22 *******************************************************/ #include <SPI.h> #include <TFT_eSPI.h>TFT_eSPI TFT = TFT_eSPI();void setup() {TFT.init();TFT.setRotation(3);TFT.fillScreen(TFT_BLACK);TFT.initDMA(); }void loop() {for(int i=0;i<100;i++){TFT.setCursor(10, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println("Voltage:\n"); TFT.setCursor(105, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println(i); delay(1000);}}??例程10:顯示屏電壓監測
/*******************************************************Baize_ServoDriver_esp32功能:測試顯示屏引腳:MOSI:21 CLK:18 RS:12 RES:13 CS:5 BLK:15Designer: AllenE-mail:953598974@qq.comDate:2022-08-22 *******************************************************/#include <Wire.h> #include <Adafruit_PWMServoDriver.h> #include <SPI.h> #include <TFT_eSPI.h>TFT_eSPI TFT = TFT_eSPI();Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x41);#define SERVOMIN 102 //0.5/20 * 4096 = 102 #define SERVOMID 307 //(102+512)/2=307 #define SERVOMAX 512 //2.5/20 * 4096 = 512 //pcb板測試時,如果是2S的鋰電池供電,則以此電壓為閾值,低于此電壓時,不再驅動舵機運動,保護電池。 int voltage_testpin = 16; float vol = 0.0;void setup() {TFT.init();TFT.setRotation(3);TFT.fillScreen(TFT_BLACK);TFT.initDMA();Serial.begin(115200);Serial.println();Serial.println("16 channel Servo test!");pwm.begin();pwm1.begin();pwm.setPWMFreq(50); // Analog servos run at ~50 Hz updatespwm1.setPWMFreq(50); // Analog servos run at ~50 Hz updatesdelay(200);for(int i=0;i<16;i++){pwm.setPWM(i, 0, SERVOMIN); // 驅動32路舵機轉到0度pwm1.setPWM(i, 0, SERVOMIN);// 驅動32路舵機轉到0度}delay(2000);for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {for(int i=0;i<16;i++){pwm.setPWM(i, 0, pulselen);pwm1.setPWM(i, 0, pulselen);}delayMicroseconds(200);} }void loop() {//全部舵機轉到0度for(int i=0;i<16;i++){pwm.setPWM(i, 0, SERVOMIN);pwm1.setPWM(i, 0, SERVOMIN);}delayMicroseconds(200);vol = float(analogRead(voltage_testpin))/4095.0*3.3*4.0;TFT.setCursor(10, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println("Voltage:\n"); TFT.setCursor(105, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println(vol); delay(1000);//全部舵機轉到90度for(int i=0;i<16;i++){pwm.setPWM(i, 0, SERVOMID);pwm1.setPWM(i, 0, SERVOMID);}delayMicroseconds(200);vol = float(analogRead(voltage_testpin))/4095.0*3.3*4.0;TFT.setCursor(10, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println("Voltage:\n"); TFT.setCursor(105, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println(vol); delay(1000);//全部舵機轉到180度for(int i=0;i<16;i++){pwm.setPWM(i, 0, SERVOMAX);pwm1.setPWM(i, 0, SERVOMAX);}delayMicroseconds(200);vol = float(analogRead(voltage_testpin))/4095.0*3.3*4.0;TFT.setCursor(10, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println("Voltage:\n"); TFT.setCursor(105, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println(vol); delay(1000);//全部舵機轉到90度for(int i=0;i<16;i++){pwm.setPWM(i, 0, SERVOMID);pwm1.setPWM(i, 0, SERVOMID);}delayMicroseconds(200);vol = float(analogRead(voltage_testpin))/4095.0*3.3*4.0;TFT.setCursor(10, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println("Voltage:\n"); TFT.setCursor(105, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println(vol); delay(1000);}例程11:角度映射
/*******************************************************Baize_ServoDriver_esp32功能:角度映射引腳:SDA:21 SCL:22對于ARDUINO UNO,SCL:A5,SDA:A4Designer: AllenE-mail:953598974@qq.comDate:2022-08-24 *******************************************************///#define SERVOMIN 102 //0.5/20 * 4096 = 102 //#define SERVOMID 307 //1.5/20 * 4096 = 307 //#define SERVOMAX 512 //2.5/20 * 4096 = 512 //實際測試 #define SERVOMIN 102 #define SERVOMID 327 #define SERVOMAX 552int hello[18]={1500,1529,1500,1549,1529,1481,1434,1500,1355,1466,1513,1546,1423,1452,1500,1444,1529,1586};void setup() {// put your setup code here, to run once:Serial.begin(115200);Serial.print("{");delay(1);for(int i=0;i<18;i++){Serial.print(map(hello[i],500,2500,SERVOMIN,SERVOMAX));Serial.print(",");delay(1);}Serial.print("}");}void loop() {// put your main code here, to run repeatedly:}例程12:串口控制舵機角度
/*******************************************************Baize_ServoDriver_esp32功能:串口輸入角度,板子驅動舵機轉到該角度引腳:SDA:21 SCL:22Designer: AllenE-mail:953598974@qq.comDate:2022-08-23*******************************************************/ #include <Wire.h> #include <Adafruit_PWMServoDriver.h>Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); //驅動1~16或(0~15)號舵機 Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x41); //驅動17~32或(16~31)號舵機#define SERVOMIN 102 //0.5/20 * 4096 = 102 #define SERVOMID 307 //1.5/20 * 4096 = 307 #define SERVOMAX 512 //2.5/20 * 4096 = 512void setup() {// put your setup code here, to run once:Serial.begin(115200);pwm.begin();pwm1.begin();pwm.setPWMFreq(50); // Analog servos run at ~50 Hz updatespwm1.setPWMFreq(50); // Analog servos run at ~50 Hz updates}void loop() {// put your main code here, to run repeatedly:while(!(Serial.available()>0));int pwm=Serial.parseInt();for(int i=0;i<16;i++){pwm.setPWM(i, 0, pwm);}pwm1.setPWM(0, 0, pwm);pwm1.setPWM(1, 0, pwm);delay(500);}例程13:從顯示屏上顯示歐拉角
/*******************************************************Baize_ServoDriver_esp32功能:屏幕顯示歐拉角引腳:MOSI:21 CLK:18 RS:12 RES:13 CS:5 BLK:15Designer: AllenE-mail:953598974@qq.comDate:2022-09-09 23:03 *******************************************************/ #include <SPI.h> #include <TFT_eSPI.h>TFT_eSPI TFT = TFT_eSPI();#include "I2Cdev.h"#include "MPU6050_6Axis_MotionApps20.h"#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE#include "Wire.h" #endifMPU6050 mpu;#define OUTPUT_READABLE_YAWPITCHROLL#define INTERRUPT_PIN 2 // use pin 2 on Arduino Uno & most boards bool blinkState = false;bool dmpReady = false; // set true if DMP init was successful uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) uint16_t packetSize; // expected DMP packet size (default is 42 bytes) uint16_t fifoCount; // count of all bytes currently in FIFO uint8_t fifoBuffer[64]; // FIFO storage buffer// orientation/motion vars Quaternion q; // [w, x, y, z] quaternion container VectorInt16 aa; // [x, y, z] accel sensor measurements VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements VectorFloat gravity; // [x, y, z] gravity vector float euler[3]; // [psi, theta, phi] Euler angle container float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector// packet structure for InvenSense teapot demo uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high void dmpDataReady() {mpuInterrupt = true; }void setup() {TFT.init();TFT.setRotation(3);TFT.fillScreen(TFT_BLACK);TFT.initDMA();// join I2C bus (I2Cdev library doesn't do this automatically)#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIREWire.begin();Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIREFastwire::setup(400, true);#endif// initialize serial communication// (115200 chosen because it is required for Teapot Demo output, but it's// really up to you depending on your project)Serial.begin(115200);while (!Serial); // wait for Leonardo enumeration, others continue immediately// initialize deviceSerial.println(F("Initializing I2C devices..."));mpu.initialize();pinMode(INTERRUPT_PIN, INPUT);// verify connectionSerial.println(F("Testing device connections..."));Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));// wait for readySerial.println(F("\nSend any character to begin DMP programming and demo: "));while (Serial.available() && Serial.read()); // empty bufferwhile (!Serial.available()); // wait for datawhile (Serial.available() && Serial.read()); // empty buffer again// load and configure the DMPSerial.println(F("Initializing DMP..."));devStatus = mpu.dmpInitialize();// supply your own gyro offsets here, scaled for min sensitivitympu.setXGyroOffset(220);mpu.setYGyroOffset(76);mpu.setZGyroOffset(-85);mpu.setZAccelOffset(1788); // 1688 factory default for my test chip// make sure it worked (returns 0 if so)if (devStatus == 0) {// Calibration Time: generate offsets and calibrate our MPU6050mpu.CalibrateAccel(6);mpu.CalibrateGyro(6);mpu.PrintActiveOffsets();// turn on the DMP, now that it's readySerial.println(F("Enabling DMP..."));mpu.setDMPEnabled(true);// enable Arduino interrupt detectionSerial.print(F("Enabling interrupt detection (Arduino external interrupt "));Serial.print(digitalPinToInterrupt(INTERRUPT_PIN));Serial.println(F(")..."));attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);mpuIntStatus = mpu.getIntStatus();// set our DMP Ready flag so the main loop() function knows it's okay to use itSerial.println(F("DMP ready! Waiting for first interrupt..."));dmpReady = true;// get expected DMP packet size for later comparisonpacketSize = mpu.dmpGetFIFOPacketSize();} else {// ERROR!// 1 = initial memory load failed// 2 = DMP configuration updates failed// (if it's going to break, usually the code will be 1)Serial.print(F("DMP Initialization failed (code "));Serial.print(devStatus);Serial.println(F(")"));} }void loop() {TFT.setCursor(10, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println("R:");TFT.setCursor(50, 10, 4);TFT.println(ypr[0] * 180/M_PI);TFT.setCursor(10, 40, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println("P:");TFT.setCursor(50, 40, 4);TFT.println(ypr[1] * 180/M_PI);TFT.setCursor(10, 70, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println("Y:");TFT.drawFloat(ypr[2] * 180/M_PI, 3, 50, 70); // Draw float using current font // TFT.setCursor(50, 70, 4); // TFT.println(ypr[2] * 180/M_PI);// if programming failed, don't try to do anythingif (!dmpReady) return;if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { // Get the Latest packet mpu.dmpGetQuaternion(&q, fifoBuffer);mpu.dmpGetGravity(&gravity, &q);mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);Serial.print("ypr\t");Serial.print(ypr[0] * 180/M_PI);Serial.print("\t");Serial.print(ypr[1] * 180/M_PI);Serial.print("\t");Serial.println(ypr[2] * 180/M_PI);}delay(50);TFT.fillScreen(TFT_BLACK); }例程14:按鍵參數調節
/*******************************************************Baize_ServoDriver_esp32功能:按鍵調參引腳:MOSI:21 CLK:18 RS:12 RES:13 CS:5 BLK:15Designer: AllenE-mail:953598974@qq.comDate:2022-09-09 23:30 *******************************************************/ #include <SPI.h> #include <TFT_eSPI.h> #define key1 35 #define key2 34 #define key3 39 #define key4 36bool key1s=0,key2s=0,key3s=0,key4s=0; int a=0,b=0;TFT_eSPI TFT = TFT_eSPI(); char cmd = 'e';//a:forward b:backward c:left d:right e:stop long times=0;void setup() {Serial.begin(115200);TFT.init();TFT.setRotation(3);TFT.fillScreen(TFT_BLACK);TFT.initDMA();pinMode(key1,INPUT);pinMode(key2,INPUT);pinMode(key3,INPUT);pinMode(key4,INPUT);times = millis(); }void loop() { // TFT.setCursor(10, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小 // TFT.setTextColor(TFT_WHITE, TFT_BLACK); // TFT.println("Hello Allen!\n");if(cmd == 'a'){}else if(cmd == 'b'){}else if(cmd == 'd'){}else if(cmd =='e'){Serial.println("hello");if(digitalRead(key1)==1){delay(5);if(digitalRead(key1)==1){if(key1s==0){a++;key1s=1;}}}if(digitalRead(key1)==0){delay(5);if(digitalRead(key1)==0){if(key1s==1){key1s=0;}}}if(digitalRead(key2)==1){delay(5);if(digitalRead(key2)==1){if(key2s==0){a--;key2s=1;}}}if(digitalRead(key2)==0){delay(5);if(digitalRead(key2)==0){if(key2s==1){key2s=0;}}}}else if(cmd == 'f'){}TFT.setCursor(10, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println("a:");TFT.drawNumber(a, 50, 10); // Draw float using current fontif(millis()-times>100){TFT.fillScreen(TFT_BLACK);times = millis();} }?加強版,可以切換參數,多參數調節
/*******************************************************Baize_ServoDriver_esp32功能:按鍵調參引腳:MOSI:21 CLK:18 RS:12 RES:13 CS:5 BLK:15Designer: AllenE-mail:953598974@qq.comDate:2022-09-10 16:54 *******************************************************/ #include <SPI.h> #include <TFT_eSPI.h> #define key1 35 #define key2 34 #define key3 39 #define key4 36bool key1s=0,key2s=0,key3s=0,key4s=0; int a=0,b=0;//光標位置,一共四行,定義為0,1,2,3 int insert_f=0;struct pr{String name;int num; };pr pro[4]={"P:",0,"I:",0,"D:",0,"O:",0};TFT_eSPI TFT = TFT_eSPI(); char cmd = 'e';//a:forward b:backward c:left d:right e:stop long times=0;void setup() {Serial.begin(115200);TFT.init();TFT.setRotation(3);TFT.fillScreen(TFT_BLACK);TFT.initDMA();pinMode(key1,INPUT);pinMode(key2,INPUT);pinMode(key3,INPUT);pinMode(key4,INPUT);times = millis(); }void loop() { // for(int i=0;i<4;i++) // { // TFT.setCursor(50, 30*(i), 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小 // TFT.setTextColor(TFT_WHITE, TFT_BLACK); // TFT.println(" "); // }if(millis()-times>100){TFT.fillScreen(TFT_BLACK);times = millis();}// TFT.setCursor(10, 10, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小 // TFT.setTextColor(TFT_WHITE, TFT_BLACK); // TFT.println("Hello Allen!\n");if(cmd == 'a'){}else if(cmd == 'b'){}else if(cmd == 'c'){}else if(cmd == 'd'){}else if(cmd =='e'){Serial.println("hello");if(digitalRead(key1)==1){delayMicroseconds(10);if(digitalRead(key1)==1){if(key1s==0){pro[insert_f].num++;key1s=1;} // else // { // pro[insert_f].num++; // delay(500); // }}}if(digitalRead(key1)==0){delayMicroseconds(10);if(digitalRead(key1)==0){if(key1s==1){key1s=0;}}}if(digitalRead(key2)==1){delayMicroseconds(10);if(digitalRead(key2)==1){if(key2s==0){pro[insert_f].num--;key2s=1;} // else // { // pro[insert_f].num--; // delay(500); // }}}if(digitalRead(key2)==0){delayMicroseconds(10);if(digitalRead(key2)==0){if(key2s==1){key2s=0;}}}//key3:向上翻頁if(digitalRead(key3)==1){delayMicroseconds(10);if(digitalRead(key3)==1){if(key3s==0){if(insert_f==0){insert_f=3; }elseinsert_f--;key3s=1;}}}if(digitalRead(key3)==0){delayMicroseconds(10);if(digitalRead(key3)==0){if(key3s==1){key3s=0;}}}//key4:向下翻頁if(digitalRead(key4)==1){delayMicroseconds(10);if(digitalRead(key4)==1){if(key4s==0){if(insert_f==3){insert_f=0; }elseinsert_f++;key4s=1;}}}if(digitalRead(key4)==0){delayMicroseconds(10);if(digitalRead(key4)==0){if(key4s==1){key4s=0;}}}}else if(cmd == 'f'){}for(int i=0;i<4;i++){TFT.setCursor(10, 30*(i), 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println(pro[i].name);TFT.drawNumber(pro[i].num, 50, 30*(i)); // Draw float using current font }TFT.setCursor(120, 30*(insert_f), 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println("<--");}例程15:連接wifi熱點
/*******************************************************Baize_ServoDriver_esp32功能:連接WiFi熱點引腳:key1:35 key2:34 key3:39 key4:36Designer: AllenE-mail:953598974@qq.comDate:2022-09-13 15:06 *******************************************************/ #include <WiFi.h> #define MAX_SRV_CLIENTS 3 //最大同時聯接數,即你想要接入的設備數量,8266tcpserver只能接入五個,哎const char *ssid = "Baize"; const char *password = "baizerobot"; WiFiServer server(8266);//你要的端口號,隨意修改,范圍0-65535 WiFiClient serverClients[MAX_SRV_CLIENTS];void setup() {Serial.begin(9600);delay(10);pinMode(16, OUTPUT);digitalWrite(16, 0);WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED){delay(500);}server.begin();server.setNoDelay(true); //加上后才正常些 }void loop() {blink();uint8_t i;if (server.hasClient()){for (i = 0; i < MAX_SRV_CLIENTS; i++){if (!serverClients[i] || !serverClients[i].connected()){if (serverClients[i]) serverClients[i].stop();//未聯接,就釋放serverClients[i] = server.available();//分配新的continue;}}WiFiClient serverClient = server.available();serverClient.stop();}for (i = 0; i < MAX_SRV_CLIENTS; i++){if (serverClients[i] && serverClients[i].connected()){digitalWrite(16, 0);//有鏈接存在,就一直長亮if (serverClients[i].available()){while (serverClients[i].available()) Serial.write(serverClients[i].read());}}}if (Serial.available()){size_t len = Serial.available();uint8_t sbuf[len];Serial.readBytes(sbuf, len);//push UART data to all connected telnet clientsfor (i = 0; i < MAX_SRV_CLIENTS; i++){if (serverClients[i] && serverClients[i].connected()){serverClients[i].write(sbuf, len); //向所有客戶端發送數據delay(1);}}} }void blink() {static long previousMillis = 0;static int currstate = 0;if (millis() - previousMillis > 200) //200ms{previousMillis = millis();currstate = 1 - currstate;digitalWrite(16, currstate);} }例程16:ESP32-ROS串口話題通信(發布話題)
/** rosserial Publisher Example* Prints "hello world!"*/ /*******************************************************Baize_ServoDriver_esp32功能:WiFi話題通信引腳:SDA:21 SCL:22Designer: AllenE-mail:953598974@qq.comDate:2022-09-13 19:35*******************************************************/#include <ros.h> #include <std_msgs/String.h> #include <SPI.h> #include <TFT_eSPI.h> // Hardware-specific library TFT_eSPI TFT = TFT_eSPI(); // Invoke custom libraryros::NodeHandle nh; std_msgs::String str_msg; ros::Publisher chatter("chatter", &str_msg); char hello[15] = "hello world!"; long time_s=0; void setup() {nh.initNode();nh.advertise(chatter);TFT.init();TFT.setRotation(3);TFT.fillScreen(TFT_BLACK);TFT.initDMA();TFT.setCursor(0, 0, 4);// Set the font colour to be white with a black backgroundTFT.setTextColor(TFT_WHITE, TFT_BLACK);// We can now plot text on screen using the "print" classTFT.println("Initialised default\n"); time_s = millis(); } void loop() {str_msg.data = hello;chatter.publish( &str_msg );nh.spinOnce();time_s = millis(); delay(1000); }例程17:ESP32-ROS串口話題通信(訂閱話題消息并在顯示屏上顯示)
/*******************************************************Baize_ServoDriver_esp32功能:WiFi話題通信訂閱消息并顯示引腳:SDA:21 SCL:22Designer: AllenE-mail:953598974@qq.comDate:2022-09-13 21:40*******************************************************/#include <ros.h> #include <std_msgs/String.h>#include <SPI.h> #include <TFT_eSPI.h> // Hardware-specific library TFT_eSPI TFT = TFT_eSPI(); // Invoke custom libraryvoid chatterCallback(const std_msgs::String& msg) { // TFT.fillScreen(TFT_BLACK);TFT.setCursor(0, 30, 4);// Set the font colour to be white with a black backgroundTFT.setTextColor(TFT_WHITE, TFT_BLACK);// We can now plot text on screen using the "print" classTFT.println(msg.data); }ros::NodeHandle nh;std_msgs::String str_msg; ros::Publisher chatter("gun", &str_msg); ros::Subscriber<std_msgs::String> sub("message", chatterCallback); char hello[13] = "hello!";void setup() {nh.initNode();nh.advertise(chatter);nh.subscribe(sub);TFT.init();TFT.setRotation(3);TFT.fillScreen(TFT_BLACK);TFT.initDMA();TFT.setCursor(0, 0, 4);// Set the font colour to be white with a black backgroundTFT.setTextColor(TFT_WHITE, TFT_BLACK);// We can now plot text on screen using the "print" classTFT.println("Initialised default\n"); }void loop() {str_msg.data = hello;chatter.publish( &str_msg );nh.spinOnce();delay(1000); }?例程18:獲取網絡時間并顯示在顯示屏上
/**ESP32 最簡單直接獲取網絡時間方法 */#include <WiFi.h> #include <SPI.h> #include <TFT_eSPI.h>TFT_eSPI TFT = TFT_eSPI();#define NTP1 "ntp1.aliyun.com" #define NTP2 "ntp2.aliyun.com" #define NTP3 "ntp3.aliyun.com"//填寫WIFI入網信息 const char* ssid = "Zhitong"; // WIFI賬戶 const char* password = "95359897"; // WIFI密碼void setClock() {struct tm timeinfo;if (!getLocalTime(&timeinfo)){//如果獲取失敗,就開啟聯網模式,獲取時間Serial.println("Failed to obtain time");// WiFi.disconnect(false);WiFi.mode(WIFI_STA);//開啟網絡 WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED){delay(500);Serial.print(".");}configTime(8 * 3600, 0, NTP1, NTP2,NTP3);return;}Serial.println(&timeinfo, "%F %T %A"); // 格式化輸出:2021-10-24 23:00:44 SundaySerial.print(asctime(&timeinfo));//默認打印格式:Mon Oct 25 11:13:29 2021// WiFi.disconnect(true);//斷開網絡連接,關閉網絡TFT.fillScreen(TFT_BLACK);TFT.setCursor(0, 0, 4);//前倆參數是位置(橫縱坐標),第三個參數是字體大小TFT.setTextColor(TFT_WHITE, TFT_BLACK);TFT.println(asctime(&timeinfo)); }void setup() {TFT.init();TFT.setRotation(3);TFT.fillScreen(TFT_BLACK);TFT.initDMA();Serial.begin(115200);Serial.println();//設置ESP32工作模式為無線終端模式WiFi.mode(WIFI_STA);WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED){delay(500);Serial.print(".");}Serial.println("WiFi connected!");configTime(8 * 3600, 0, NTP1, NTP2,NTP3);setClock();// 從網絡時間服務器上獲取并設置時間// 獲取成功后芯片會使用RTC時鐘保持時間的更新// WiFi.disconnect(true);//斷開wifi網絡 // WiFi.mode(WIFI_OFF);//關閉網絡Serial.println("WiFi disconnected!"); }void loop() {Serial.println("Waiting 10s before the next round...");delay(1000);setClock(); }?
問題匯總
1.焊接完成以后,esp32模組發燙
板子焊接完成之后,在測試過程中,發現esp32模組一直在發燙,找不到原因,用萬用表測量之后發現3V3和GND短路了。但是不知道在整個電路中到底是哪個部分短路的,因為板子上有大量的3V3和GND。
然后考慮到,可以先把esp32模組取下來,然后再測試,由于取下來再焊上去非常麻煩。所以就用割板刀把esp32模組的3V3電源供電給斷開,這樣esp32模組就從3V3供電里面隔離出來了,然后再次用萬用表測量之后,發現除了esp32模組之外,另一邊的3V3和GND是正常的。而esp32模組這邊的3V3和GND是短路的,這邊只有esp32模組這一個元器件,所以推測是esp32模組短路,看來還是要拆下來esp32模組。
最終將esp32模組拆下來換了一個新的上去,發現一切正常。單獨測量那個換下來的esp32模組,發現他本身還是短路的。
最終雖然解決了問題,但是由于模組都是新的,也不知道第一個模組是為什么短路了。
焊接是用的焊臺焊接的,不知道是不是焊接過程中,esp32模組內部的元器件是否發生了錯位,最后導致的模組內部短路。
總結
以上是生活随笔為你收集整理的Baize_ServoDriver_esp32——arduino 32路舵机驱动板(esp32主控,免费开源,附程序、固件)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Apollo详解之定位模块———导航设备
- 下一篇: android 陀螺仪滤波_Arduin