I'm writing a piece of code that receives data from a TWELITE DIP and then moves the servomotors based on the input, then transmit data from a BMP390 and MPU6050. However, I just found out that a couple of libraries were incompatible with the R3, so I purchased a ESP32-WROOM-32. However, I am very confused as I only understand a bit about pinout diagrams, and asking GPT gave me answers about GPIO pins that do not match, as far as I can understand.
It said stuff like GPIO 18, but it doesn't say anything like that on the silk nor the pinout...
GPIO stands for General Purpose Input Output.
In this diagram that is referred to as 'D' (for data) so what you see as D18 is the same as GPIO 18.
(note. This is only applicable to an ESP32 nodeMCU, an ESP8266 nodeMCU is more confusing)
The advantage of 'actual' intelligence is that a person can imagine what is going on.
If you have any specific questions about things, feel free to ask.
Is this the actual board you have ? (there are so many variants of ESP32 that it is important to make sure)
Yup, that's the board. I want to connect scl, sda, and the equivalent of pins 9 and 10 for the 2 servos, whatever they may be called officially.
That is confusing. (9 & 10 ??)
Those pins are marked D22 & D21 AKA GPIO 22 & 21. They can be referred to as '22' & '21' in your code.
can you give a link to the actual board you purchased?
As @Deva_Rishi says
that would depend on your code and wiring
There are nodeMCU boards that are ESP32 based, The link provided by the OP shows such an example. 'nodeMCU' is ambiguous.
Thanks @Deva_Rishi , my mistake.
NodeMCU is a low-cost open source IoT platform.[4][5] It initially included firmware which runs on the ESP8266 Wi-Fi SoC from Espressif Systems, and hardware which was based on the ESP-12 module.[6][7] Later, support for the ESP32 32-bit MCU was added.
My code is a bit long, but here it goes.
#pragma once
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP3XX.h>
#include <Adafruit_MPU6050.h>
#include <SoftwareSerial.h>
#include <Servo.h>
#include "SercmdE.h"
Servo servoL;
Servo servoR;
int servoLPin = 9;
int servoRPin = 10;
// Version Information
String VersionNumber = "3";
// BMP390 (Altitude Sensor)
Adafruit_BMP3XX bmp;
bool isInitialAltitudeSet = false;
float initialAltitude = 0;
// MPU6050 (Accelerometer and Gyroscope)
Adafruit_MPU6050 mpu;
// TWELITE Communication
#define RX_PIN 2
#define TX_PIN 3
SoftwareSerial MWSerial(RX_PIN, TX_PIN);
SerCmdE ser;
byte u8MyAddr = 0x78;
byte u8DistAddr = 0x00;
byte u8DistAddrAlt = 0x81;
int schedule_send = 0;
// Servo Pin Definitions
#define SERVO_PIN_1 9
#define SERVO_PIN_2 10
Servo servo1;
Servo servo2;
// Program Control
bool stopRequested = false;
unsigned long lastReadingTime = 0;
const unsigned long readingInterval = 500; // Interval between sensor readings
void setup() {
Serial.begin(115200);
servoL.attach(servoLPin);
servoR.attach(servoRPin);
servoL.write(90); // Set the servo to the center position initially
servoR.write(90);
delay(500);
while (!Serial);
Serial.print("MONOWIRELESS Sensor and Servo Control version");
Serial.println(VersionNumber);
// Initialize BMP390
if (!bmp.begin_I2C()) {
Serial.println("BMP390 failed");
while (1);
}
bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_16X);
bmp.setPressureOversampling(BMP3_OVERSAMPLING_16X);
bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_DISABLE);
for (int i = 0; i < 5; i++) {
bmp.readTemperature();
bmp.readPressure();
delay(500);
}
Serial.println("BMP390 initialized");
// Initialize MPU6050
if (!mpu.begin()) {
Serial.println("MPU6050 failed");
while (1);
}
delay(500);
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
Serial.println("MPU6050 initialized");
// Initialize Servos
servo1.attach(SERVO_PIN_1);
servo2.attach(SERVO_PIN_2);
// Initialize TWELITE Communication
MWSerial.begin(38400);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
char recv;
// Check if data is available to read from Serial Monitor
if (Serial.available()) {
recv = char(Serial.read());
// Control the servo based on input
if (recv == '0') {
servoL.write(70);
servoR.write(110);
}
if (recv == '1') {
servoL.write(72);
servoR.write(108);
}
if (recv == '2') {
servoL.write(75);
servoR.write(105);
}
if (recv == '3') {
servoL.write(78);
servoR.write(102);
}
if (recv == '4') {
servoL.write(80);
servoR.write(100);
}
if (recv == '5') {
servoL.write(82);
servoR.write(98);
}
if (recv == '6') {
servoL.write(85);
servoR.write(95);
}
if (recv == '7') {
servoL.write(88);
servoR.write(92);
}
if (recv == '8') {
servoL.write(90);
servoR.write(90);
}
if (recv == '9') {
servoL.write(92);
servoR.write(88);
}
if (recv == 'a') {
servoL.write(95);
servoR.write(85);
}
if (recv == 'b') {
servoL.write(98);
servoR.write(82);
}
if (recv == 'c') {
servoL.write(100);
servoR.write(80);
}
if (recv == 'd') {
servoL.write(102);
servoR.write(78);
}
if (recv == 'e') {
servoL.write(105);
servoR.write(75);
}
if (recv == 'f') {
servoL.write(108);
servoR.write(72);
}
if (recv == 'g') {
servoL.write(110);
servoR.write(70);
}
if (recv == 's') { // If 's' is received, stop the servo at the center
servoL.write(90);
servoR.write(90);
}
}
delay(100);
Serial.print('R'); // Send a response character to indicate the program is running
// Check for Stop Command
if (Serial.available() > 0) {
String command = Serial.readStringUntil('\n');
command.trim();
if (command.equalsIgnoreCase("stop")) {
stopRequested = true;
Serial.println("Stop command received. Halting program...");
}
}
// Halt Program if Stopped
if (stopRequested) {
Serial.println("Program halted.");
while (true) delay(100);
}
// Read Sensors and Send Data at Regular Intervals
if (millis() - lastReadingTime >= readingInterval) {
lastReadingTime = millis();
// Read Sensor Data
float sensorData[7];
// BMP390: Altitude4
float pressure = bmp.readPressure();
if (!isnan(pressure)) {
float altitude = bmp.readAltitude(1012);
if (!isInitialAltitudeSet) {
initialAltitude = altitude;
isInitialAltitudeSet = true;
sensorData[0] = 0;
} else {
sensorData[0] = altitude - initialAltitude;
}
} else {
sensorData[0] = 0; // Default value if sensor fails
Serial.println("Error: BMP390");
}
// MPU6050: Acceleration and Gyroscope
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
sensorData[1] = a.acceleration.x;
sensorData[2] = a.acceleration.y;
sensorData[3] = a.acceleration.z;
sensorData[4] = g.gyro.x * 180.0 / PI;
sensorData[5] = g.gyro.y * 180.0 / PI;
sensorData[6] = g.gyro.z * 180.0 / PI;
// Print Data
Serial.print("Sensor Data: [");
for (int i = 0; i < 7; i++) {
Serial.print(sensorData[i], 1);
if (i < 6) Serial.print(", ");
}
Serial.println("]");
// Transmit Data via TWELITE
byte encodedData[28];
SerCmdE::encode((byte*)sensorData, sizeof(sensorData), encodedData, 26);
encodedData[26] = '\r';
encodedData[27] = '\n';
for (int i = 0; i < 28; ++i) MWSerial.write(encodedData[i]);
}
// Check for Incoming TWELITE Data
if (bTWELITEDataArrived()) {
if (ser.latest.devid == u8DistAddr || ser.latest.devid == u8DistAddrAlt) {
// Control Servo 1
servo1.write(ser.latest.data[0]);
// Control Servo 2 if there's additional data
if (sizeof(ser.latest.data) > 1) {
servo2.write(ser.latest.data[1]);
}
}
}
}
bool bTWELITEDataArrived() {
int c = MWSerial.read();
digitalWrite(LED_BUILTIN, c > 0 ? HIGH : LOW);
if (c >= 0) {
ser.decode(c);
return ser.isValid;
}
return false;
}
As for the wiring, I'll do whatever is the most convenient.
Esp32 is nice board, but choosing right pins is not straightforward. There are several pins you should avoid if you have not been studying.
For I2C use pins 21 and 22:
- GPIO 21 (SDA)
- GPIO 22 (SCL)
For servos and for softwareserial use any pins between 18 - 33.
Also, Esp32 has multiple hardware serial ports, so if you want/need you can use them instead of softwareserial.
Okay, Thanks!
You have quite a few libraries.
Are they all compatible with the ESP32.
I know that the Servo library is not.
You need to use the ESP32Servo library.
I would check the others
Those pins are not appropriate. First of all they are not exposed, and if they were (as on a 38-pin board) they should be avoided since they are connected to the SPI-flash.
There are 3 hwSerial ports available on an ESP32 (someone mentioned that already) and the pins to be used can be specified if required. So there really is no need for swSerial ! Also your choice of pins is unfortunate. GPIO 3 is the default RX-pin of UART0 (Serial) and is also connected to the USB to TTL converter.
Probably easiest to use pins 16 & 17 with Serial2 (those are it's default pins)
Does this do the job?
#pragma once
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP3XX.h>
#include <Adafruit_MPU6050.h>
#include <HardwareSerial.h>
#include <ESP32Servo.h>
#include "SercmdE.h"
Servo servoL;
Servo servoR;
int servoLPin = 18;
int servoRPin = 19;
// Version Information
String VersionNumber = "3";
// BMP390 (Altitude Sensor)
Adafruit_BMP3XX bmp;
bool isInitialAltitudeSet = false;
float initialAltitude = 0;
// MPU6050 (Accelerometer and Gyroscope)
Adafruit_MPU6050 mpu;
// TWELITE Communication
HardwareSerial MWSerial(2); // aparently this selects uart 2 and i don't have to input pins, automatically 16 & 17
SerCmdE ser;
byte u8MyAddr = 0x78;
byte u8DistAddr = 0x00;
byte u8DistAddrAlt = 0x81;
int schedule_send = 0;
I think so.
That is not the most common way to do it.
UART2 can simply be referred to in the code as 'Serial2' no extra object declaration required.
within setup() just simply
Serial2.begin(38400);
Thank you so much!
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.