1.1 立项目标
1.2 立项指标
-
多种数字和模拟信号的输入输出:用户可以选择不同的输入输出模式,并通过设备的操作界面进行设置。例如,用户可以选择某个GPIO口作为模拟输入引脚,然后通过设备的操作界面设置输入的电压值,以模拟外部信号的输入,达到调试简易传感器读取和执行器输出功能。
-
支持PWM输出、舵机控制特性:用户可以选择某个GPIO口作为PWM输出引脚,并通过设备的操作界面设置PWM输出的频率和占空比。用户还可以选择某个GPIO口作为舵机控制引脚,并通过设备的操作界面设置舵机的角度。
-
因此系统具有一定的电流输出能力、信号辨识能力和显示交互功能。
4.1 系统设计流程图
4.2 电路原理图
6.1 PCB板图
6.2 3D封装效果图
6.3 实物图
6.4 遇到的问题
7.1 版本1.0
-
#include <U8g2lib.h>
-
#include <Encoder.h>
-
#include <ESP32Servo.h>
-
#include <FastLED.h>
-
#include <WS2812FX.h>
// #define ENCODER_DO_NOT_USE_INTERRUPTS
#include <U8g2lib.h>
#include <Encoder.h>
#include <ESP32Servo.h>
#include <FastLED.h>
#include <WS2812FX.h>
#define OLED_CLOCK 5
#define OLED_DATA 4
#define OLED_RESET U8X8_PIN_NONE
#define ENCODER_CLK 7
#define ENCODER_DT 6
#define ENCODER_SW 8
#define SERVO_PIN 19
#define LED_PIN 18
#define NUM_LEDS 4
#define SENSOR_PIN 0
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/OLED_CLOCK, /* data=*/OLED_DATA, /* reset=*/OLED_RESET); // ESP32 Thing, pure SW emulated I2C
Encoder encoder(ENCODER_CLK, ENCODER_DT);
// ESP32PWM pwm;
Servo myservo; // create servo object to control a servo
CRGB leds[NUM_LEDS];
int currentMenu = 0;
int servoAngle = 0;
int ledColorIndex = 0;
int sensorValue = 0;
int encoderButtonState = 0;
long position = 0;
long newPos = 0;
void setup() {
ESP32PWM::allocateTimer(0);
ESP32PWM::allocateTimer(1);
ESP32PWM::allocateTimer(2);
ESP32PWM::allocateTimer(3);
myservo.setPeriodHertz(50); // standard 50 hz servo
myservo.attach(SERVO_PIN, 1000, 2000); // attaches the servo on pin 18 to the servo object
Serial.begin(9600);
u8g2.begin();
u8g2.setFont(u8g2_font_ncenB14_tr);
pinMode(ENCODER_SW, INPUT_PULLUP);
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
// pwm.setPeriodHertz(50);
// pwm.attachServo(SERVO_PIN);
}
void loop() {
u8g2.clearBuffer();
switch (currentMenu) {
case 0: // Main menu
u8g2.setCursor(0, 20);
u8g2.print("1. Servo");
u8g2.setCursor(0, 40);
u8g2.print("2. WS2812");
u8g2.setCursor(0, 60);
u8g2.print("3. Sensor");
break;
case 1: // Servo menu
// int servoencoderValue = 0;
u8g2.setCursor(0, 20);
u8g2.print("Servo Angle: ");
u8g2.setCursor(30, 40);
u8g2.print(servoAngle);
// Handle servo control
servoAngle = servoAngle + checkencoder();
if (servoAngle > 180) {
servoAngle = 180;
} else if (servoAngle < 0) {
servoAngle = 0;
}
myservo.write(servoAngle);
break;
case 2: // WS2812 menu
// int LEDencoderValue = 0;
u8g2.setCursor(0, 20);
u8g2.print("LED Color: ");
u8g2.setCursor(30, 40);
u8g2.print(ledColorIndex);
// Handle LED color control
ledColorIndex = ledColorIndex + checkencoder();
if (ledColorIndex < 0) {
ledColorIndex = 0;
} else if (ledColorIndex > 2) {
ledColorIndex = 2;
}
setLedColor();
break;
case 3: // Sensor menu
u8g2.setCursor(0, 20);
u8g2.print("Sensor Value: ");
u8g2.setCursor(30, 40);
u8g2.print(sensorValue);
// Read sensor value
sensorValue = analogRead(SENSOR_PIN);
break;
}
u8g2.sendBuffer();
// Handle menu navigation
encoderButtonState = digitalRead(ENCODER_SW);
if (encoderButtonState == LOW) {
delay(50); // Debounce delay
encoderButtonState = digitalRead(ENCODER_SW);
if (encoderButtonState == LOW) {
currentMenu++;
if (currentMenu > 3) {
currentMenu = 0;
}
delay(200); // Debounce delay
}
}
}
int checkencoder() {
newPos = encoder.read();
Serial.println("newPos:" + String(newPos) + "position:" + String(position));
delay(1);
if (newPos > position) {
position = newPos;
return 1;
} else if (newPos < position) {
position = newPos;
return -1;
}
return 0;
}
void setLedColor() {
switch (ledColorIndex) {
case 0:
leds[0] = CRGB::Red;
leds[1] = CRGB::Red;
leds[2] = CRGB::Red;
leds[3] = CRGB::Red;
break;
case 1:
leds[0] = CRGB::Green;
leds[1] = CRGB::Green;
leds[2] = CRGB::Green;
leds[3] = CRGB::Green;
break;
case 2:
leds[0] = CRGB::Blue;
leds[1] = CRGB::Blue;
leds[2] = CRGB::Blue;
leds[3] = CRGB::Blue;
break;
}
FastLED.show();
}
7.2 版本1.1
// #define ENCODER_DO_NOT_USE_INTERRUPTS
#include <U8g2lib.h>
#include <Encoder.h>
#include <ESP32Servo.h>
#include <FastLED.h>
#include <WS2812FX.h>
#define OLED_CLOCK 5
#define OLED_DATA 4
#define OLED_RESET U8X8_PIN_NONE
#define ENCODER_CLK 7
#define ENCODER_DT 6
#define ENCODER_SW 8
#define SERVO_PIN 19
#define LED_PIN 18
#define NUM_LEDS 4
#define SENSOR_PIN 0
#define SENSOR_PIN2 1
#define BUZZER 13
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/OLED_CLOCK, /* data=*/OLED_DATA, /* reset=*/OLED_RESET); // ESP32 Thing, pure SW emulated I2C
// 创建Encoder对象
Encoder myEncoder(ENCODER_CLK, ENCODER_DT);
// ESP32PWM pwm;
Servo myservo; // create servo object to control a servo
CRGB leds[NUM_LEDS];
int currentMenu = 0;
int servoAngle = 0;
int ledColorIndex = 0;
int sensorValue = 0;
int sensorValue2 = 0;
int BuzzerValue = 128;
int encoderButtonState = 0;
long position = 0;
long newPos = 0;
long oldPosition = 0;
int increment = 0;
int ws = 0;
void setup() {
myservo.setPeriodHertz(50); // standard 50 hz servo
myservo.attach(SERVO_PIN, 1000, 2000); // attaches the servo on pin 18 to the servo object
Serial.begin(9600);
u8g2.begin();
u8g2.setFont(u8g2_font_ncenB14_tr);
pinMode(ENCODER_SW, INPUT_PULLUP);
pinMode(ENCODER_CLK, INPUT_PULLUP);
pinMode(ENCODER_DT, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = getColor(-1);
}
FastLED.show();
// pwm.setPeriodHertz(50);
// pwm.attachServo(SERVO_PIN);
}
void loop() {
u8g2.clearBuffer();
switch (currentMenu) {
case 0: // Main menu
u8g2.setCursor(30, 20);
u8g2.print("Main menu");
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(0, 40);
u8g2.print("1. Servo");
u8g2.setCursor(0, 60);
u8g2.print("2. WS2812");
u8g2.setCursor(64, 40);
u8g2.print("3. Sensor");
u8g2.setCursor(64, 60);
u8g2.print("4. Buzzer");
break;
case 1: // Servo menu
// int servoencoderValue = 0;
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 20);
u8g2.print("Servo Angle: ");
u8g2.setCursor(30, 40);
u8g2.print(servoAngle);
u8g2.sendBuffer();
while (1) {
if (checkencoder() == true) {
setservo();
increment = 0;
}
if (checkswitch() == true) {
break;
}
}
break;
case 2: // WS2812 menu
// int LEDencoderValue = 0;
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 20);
u8g2.print("LED Color: ");
u8g2.setCursor(30, 40);
u8g2.print(ledColorIndex);
u8g2.sendBuffer();
// Handle LED color control
while (1) {
if (checkencoder() == true) {
setLedColor();
increment = 0;
}
if (checkswitch() == true) {
break;
}
}
break;
case 3: // Sensor menu
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(10, 30);
u8g2.print("Sensor1: ");
u8g2.setCursor(64, 30);
u8g2.print(sensorValue);
u8g2.setCursor(10, 60);
u8g2.print("Sensor2: ");
u8g2.setCursor(64, 60);
u8g2.print(sensorValue2);
// Read sensor value
sensorValue = analogRead(SENSOR_PIN);
sensorValue2 = analogRead(SENSOR_PIN2);
break;
case 4: // Buzzer menu
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 20);
u8g2.print("Buzzer Value: ");
u8g2.setCursor(30, 40);
u8g2.print(BuzzerValue);
// Handle Buzzer control
while (1) {
if (checkencoder() == true) {
setbuzzer();
increment = 0;
}
if (checkswitch() == true) {
break;
}
}
break;
}
increment = 0;
u8g2.sendBuffer();
// Handle menu navigation
if (checkswitch() == true) {
currentMenu++;
if (currentMenu > 4) {
currentMenu = 0;
}
delay(200); // Debounce delay
}
}
bool checkencoder() {
long newPosition = myEncoder.read();
if (newPosition != oldPosition) {
// Serial.println(newPosition + String(";") + oldPosition);
increment = newPosition - oldPosition;
oldPosition = newPosition;
return true;
}
return false;
}
bool checkswitch() {
encoderButtonState = digitalRead(ENCODER_SW);
if (encoderButtonState == LOW) {
delay(50); // Debounce delay
encoderButtonState = digitalRead(ENCODER_SW);
if (encoderButtonState == LOW) {
return true;
} else {
return false;
}
} else {
return false;
}
}
void setLedColor() {
ledColorIndex = ledColorIndex + increment;
if (ledColorIndex < 0) {
ledColorIndex = 0;
} else if (ledColorIndex > 10) {
ledColorIndex = 10;
}
u8g2.setCursor(30, 40);
u8g2.print(ledColorIndex);
u8g2.sendBuffer();
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = getColor(ledColorIndex);
}
FastLED.show();
delay(1);
}
void setservo() {
servoAngle = servoAngle + increment*3;
if (servoAngle > 180) {
servoAngle = 180;
} else if (servoAngle < 0) {
servoAngle = 0;
}
u8g2.setCursor(30, 40);
u8g2.print(servoAngle);
u8g2.sendBuffer();
myservo.write(servoAngle);
}
void setbuzzer() {
BuzzerValue = BuzzerValue + increment*8;
if (BuzzerValue > 255) {
BuzzerValue = 255;
} else if (BuzzerValue < 0) {
BuzzerValue = 0;
}
u8g2.setCursor(30, 40);
u8g2.print(BuzzerValue);
u8g2.sendBuffer();
analogWrite(BUZZER, BuzzerValue);
}
CRGB getColor(int index) {
switch (index) {
case 0:
return CRGB::Red;
case 1:
return CRGB::Green;
case 2:
return CRGB::Blue;
case 3:
return CRGB::Yellow;
case 4:
return CRGB::Magenta;
case 5:
return CRGB::Cyan;
case 6:
return CRGB::White;
case 7:
return CRGB::Purple;
case 8:
return CRGB::Orange;
case 9:
return CRGB::Pink;
default:
return CRGB::Black;
}
}
7.3 版本1.2
// #define ENCODER_DO_NOT_USE_INTERRUPTS
#include <U8g2lib.h>
#include <Encoder.h>
#include <ESP32Servo.h>
#include <FastLED.h>
#include <WS2812FX.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#define OLED_CLOCK 5
#define OLED_DATA 4
#define OLED_RESET U8X8_PIN_NONE
#define ENCODER_CLK 7
#define ENCODER_DT 6
#define ENCODER_SW 8
#define SERVO_PIN 19
#define LED_PIN 18
#define NUM_LEDS 4
#define SENSOR_PIN 0
#define SENSOR_PIN2 1
#define BUZZER 13
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
//创建Bluetooth对象
BLECharacteristic *pCharacteristic;
//创建SSD1306屏幕对象
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/OLED_CLOCK, /* data=*/OLED_DATA, /* reset=*/OLED_RESET); // ESP32 Thing, pure SW emulated I2C
// 创建Encoder对象
Encoder myEncoder(ENCODER_CLK, ENCODER_DT);
// ESP32PWM pwm;
Servo myservo; // create servo object to control a servo
CRGB leds[NUM_LEDS];
int currentMenu = 0;
int servoAngle = 0;
int ledColorIndex = 0;
int sensorValue = 0;
int sensorValue2 = 0;
int BuzzerValue = 128;
int encoderButtonState = 0;
long position = 0;
long newPos = 0;
long oldPosition = 0;
int increment = 0;
bool deviceConnected = false;
char BLEbuf[256] = { 0 };
uint32_t cnt = 0;
String message_c;
char *message;
// const char *message1;
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer *pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer *pServer) {
deviceConnected = false;
}
};
class MyCallbacks : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
if (rxValue.length() > 0) {
Serial.print("------>Received Value: ");
for (int i = 0; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
}
Serial.println();
}
}
};
void setup() {
myservo.setPeriodHertz(50); // standard 50 hz servo
myservo.attach(SERVO_PIN, 1000, 2000); // attaches the servo on pin 18 to the servo object
Serial.begin(115200);
u8g2.begin();
u8g2.clearDisplay();
pinMode(ENCODER_SW, INPUT_PULLUP);
pinMode(ENCODER_CLK, INPUT_PULLUP);
pinMode(ENCODER_DT, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = getColor(-1);
}
FastLED.show();
// Create the BLE Device
BLEDevice::init("ESP32 BLE vor");
// 创建蓝牙服务器
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// // 创建广播服务的UUID
BLEService *pService = pServer->createService(SERVICE_UUID);
// 创建广播服务的UUID
pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY);
pCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic *pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE);
pCharacteristic->setCallbacks(new MyCallbacks());
// 开始蓝牙服务
pService->start();
// 开始广播
pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");
}
void loop() {
u8g2.clearBuffer();
switch (currentMenu) {
case 0: // Main menu
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(7, 22);
u8g2.print("Main menu");
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(0, 40);
u8g2.print("1. Servo");
u8g2.setCursor(0, 60);
u8g2.print("2. WS2812");
u8g2.setCursor(64, 40);
u8g2.print("3. Sensor");
u8g2.setCursor(64, 60);
u8g2.print("4. Buzzer");
break;
case 1: // Servo menu
// int servoencoderValue = 0;
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 20);
u8g2.print("Servo Angle: ");
u8g2.setCursor(30, 40);
u8g2.print(servoAngle);
u8g2.sendBuffer();
while (1) {
if (checkencoder() == true) {
setservo();
increment = 0;
}
if (checkswitch() == true) {
break;
}
}
break;
case 2: // WS2812 menu
// int LEDencoderValue = 0;
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 20);
u8g2.print("LED Color: ");
u8g2.setCursor(30, 40);
u8g2.print(ledColorIndex);
u8g2.sendBuffer();
// Handle LED color control
while (1) {
if (checkencoder() == true) {
setLedColor();
increment = 0;
}
if (checkswitch() == true) {
break;
}
}
break;
case 3: // Sensor menu
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(10, 30);
u8g2.print("Sensor1: ");
u8g2.setCursor(64, 30);
u8g2.print(sensorValue);
u8g2.setCursor(10, 60);
u8g2.print("Sensor2: ");
u8g2.setCursor(64, 60);
u8g2.print(sensorValue2);
// Read sensor value
sensorValue = analogRead(SENSOR_PIN);
sensorValue2 = analogRead(SENSOR_PIN2);
break;
case 4: // Buzzer menu
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 20);
u8g2.print("Buzzer Value: ");
u8g2.setCursor(30, 40);
u8g2.print(BuzzerValue);
// Handle Buzzer control
while (1) {
if (checkencoder() == true) {
setbuzzer();
increment = 0;
}
if (checkswitch() == true) {
break;
}
}
break;
case 5: // Blue uart
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 20);
u8g2.print("Blue uart : ");
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(0, 40);
u8g2.print(BuzzerValue);
// Handle Buzzer control
while (1) {
setbluetooth();
if (checkswitch() == true) {
break;
}
}
break;
default:
break;
}
increment = 0;
u8g2.sendBuffer();
// Handle menu navigation
if (checkswitch() == true) {
currentMenu++;
if (currentMenu > 5) {
currentMenu = 0;
}
delay(200); // Debounce delay
}
}
bool checkencoder() {
long newPosition = myEncoder.read();
if (newPosition != oldPosition) {
// Serial.println(newPosition + String(";") + oldPosition);
increment = newPosition - oldPosition;
oldPosition = newPosition;
return true;
}
return false;
}
bool checkswitch() {
encoderButtonState = digitalRead(ENCODER_SW);
if (encoderButtonState == LOW) {
delay(50); // Debounce delay
encoderButtonState = digitalRead(ENCODER_SW);
if (encoderButtonState == LOW) {
return true;
} else {
return false;
}
} else {
return false;
}
}
void setLedColor() {
ledColorIndex = ledColorIndex + increment;
if (ledColorIndex < 0) {
ledColorIndex = 0;
} else if (ledColorIndex > 10) {
ledColorIndex = 10;
}
u8g2.setCursor(30, 40);
u8g2.print(ledColorIndex);
u8g2.sendBuffer();
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = getColor(ledColorIndex);
}
FastLED.show();
delay(1);
}
void setservo() {
servoAngle = servoAngle + increment * 3;
if (servoAngle > 180) {
servoAngle = 180;
} else if (servoAngle < 0) {
servoAngle = 0;
}
u8g2.setCursor(30, 40);
u8g2.print(servoAngle);
u8g2.sendBuffer();
myservo.write(servoAngle);
}
void setbuzzer() {
BuzzerValue = BuzzerValue + increment * 8;
if (BuzzerValue > 255) {
BuzzerValue = 255;
} else if (BuzzerValue < 0) {
BuzzerValue = 0;
}
u8g2.setCursor(30, 40);
u8g2.print(BuzzerValue);
u8g2.sendBuffer();
analogWrite(BUZZER, BuzzerValue);
}
void setbluetooth() {
if (deviceConnected) { //设备连接后,每秒钟发送txValue。
memset(BLEbuf, 0, 32);
message_c = "s "+String(servoAngle)+" w"+String(ledColorIndex)+" s"+String(analogRead(SENSOR_PIN))+"s"+String(analogRead(SENSOR_PIN2))+"b"+String(BuzzerValue)+"\n";
char* p = const_cast<char*>(message_c.c_str());
memcpy(BLEbuf, p, 32);
pCharacteristic->setValue(BLEbuf);
pCharacteristic->notify(); // Send the value to the app!
Serial.print("*** Sent Value: ");
Serial.print(BLEbuf);
Serial.println(" ***");
// sensorValue = analogRead(SENSOR_PIN);
// sensorValue2 = analogRead(SENSOR_PIN2);
// memset(BLEbuf, 0, 256);
// // sprintf(message, "S%dW%dS%dS%dB%d", servoAngle, ledColorIndex, sensorValue, sensorValue2, BuzzerValue);
// sprintf(message, "S%dW%d", servoAngle, ledColorIndex);
// // message_c = message;
// // char* p = const_cast<char*>(message.c_str());
// // message1 = message;
// memcpy(BLEbuf, message, 256);
// // memcpy(BLEbuf, message_c, 32);
// pCharacteristic->setValue(BLEbuf);
// pCharacteristic->notify(); // Send the value to the app!
// delay(10);
u8g2.setCursor(0, 40);
u8g2.print(BLEbuf);
// // u8g2.setCursor(0, 60);
// // u8g2.print(message_c.substring(15, 32));
u8g2.sendBuffer();
// Serial.println("Sent Value:" + String(BLEbuf));
delay(100);
}
}
CRGB getColor(int index) {
switch (index) {
case 0:
return CRGB::Red;
case 1:
return CRGB::Green;
case 2:
return CRGB::Blue;
case 3:
return CRGB::Yellow;
case 4:
return CRGB::Magenta;
case 5:
return CRGB::Cyan;
case 6:
return CRGB::White;
case 7:
return CRGB::Purple;
case 8:
return CRGB::Orange;
case 9:
return CRGB::Pink;
default:
return CRGB::Black;
}
}
7.4 版本1.3
// #define ENCODER_DO_NOT_USE_INTERRUPTS
#include <U8g2lib.h>
#include <Encoder.h>
#include <ESP32Servo.h>
#include <FastLED.h>
#include <WS2812FX.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#define OLED_CLOCK 5
#define OLED_DATA 4
#define OLED_RESET U8X8_PIN_NONE
#define ENCODER_CLK 7
#define ENCODER_DT 6
#define ENCODER_SW 8
#define SERVO_PIN 19
#define LED_PIN 18
#define NUM_LEDS 4
#define SENSOR_PIN 0
#define SENSOR_PIN2 1
#define BUZZER 13
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
//创建Bluetooth对象
BLECharacteristic *pCharacteristic;
//创建SSD1306屏幕对象
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/OLED_CLOCK, /* data=*/OLED_DATA, /* reset=*/OLED_RESET); // ESP32 Thing, pure SW emulated I2C
// 创建Encoder对象
Encoder myEncoder(ENCODER_CLK, ENCODER_DT);
// ESP32PWM pwm;
Servo myservo; // create servo object to control a servo
CRGB leds[NUM_LEDS];
int currentMenu = 0;
int servoAngle = 0;
int ledColorIndex = 0;
int sensorValue = 0;
int sensorValue2 = 0;
int BuzzerValue = 128;
int encoderButtonState = 0;
long position = 0;
long newPos = 0;
long oldPosition = 0;
int increment = 0;
bool deviceConnected = false;
char BLEbuf[256] = { 0 };
uint32_t cnt = 0;
String message_c;
char *message;
// const char *message1;
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer *pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer *pServer) {
deviceConnected = false;
}
};
class MyCallbacks : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
if (rxValue.length() > 0) {
Serial.print("------>Received Value: ");
for (int i = 0; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
}
Serial.println();
}
}
};
void appCpuLoop(void *pvParameters) {
while (true) {
if (currentMenu != 5) {
memset(BLEbuf, 0, 32);
message_c = "s " + String(servoAngle) + "w" + String(ledColorIndex) + " s" + String(analogRead(SENSOR_PIN)) + "s" + String(analogRead(SENSOR_PIN2)) + "b" + String(BuzzerValue) + "\r\n";
char *p = const_cast<char *>(message_c.c_str());
memcpy(BLEbuf, p, 32);
pCharacteristic->setValue(BLEbuf);
pCharacteristic->notify(); // Send the value to the app!
Serial.print("*** Sent Value: ");
Serial.print(BLEbuf);
Serial.println(" ***");
delay(700);
}
delay(300);
}
vTaskDelete(NULL);
}
void setup() {
myservo.setPeriodHertz(50); // standard 50 hz servo
myservo.attach(SERVO_PIN, 1000, 2000); // attaches the servo on pin 18 to the servo object
Serial.begin(115200);
u8g2.begin();
u8g2.clearDisplay();
pinMode(ENCODER_SW, INPUT_PULLUP);
pinMode(ENCODER_CLK, INPUT_PULLUP);
pinMode(ENCODER_DT, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = getColor(-1);
}
FastLED.show();
// Create the BLE Device
BLEDevice::init("ESP32 BLE vor");
// 创建蓝牙服务器
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// // 创建广播服务的UUID
BLEService *pService = pServer->createService(SERVICE_UUID);
// 创建广播服务的UUID
pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY);
pCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic *pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE);
pCharacteristic->setCallbacks(new MyCallbacks());
// 开始蓝牙服务
pService->start();
// 开始广播
pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");
xTaskCreatePinnedToCore(appCpuLoop, //具体实现的函数
"APP_CPU_LOOP", //任务名称
8192, //堆栈大小
NULL, //输入参数
1, //任务优先级
NULL, //
1 //核心 0\1
);
}
void loop() {
u8g2.clearBuffer();
switch (currentMenu) {
case 0: // Main menu
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(7, 22);
u8g2.print("Main menu");
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(0, 40);
u8g2.print("1. Servo");
u8g2.setCursor(0, 60);
u8g2.print("2. WS2812");
u8g2.setCursor(64, 40);
u8g2.print("3. Sensor");
u8g2.setCursor(64, 60);
u8g2.print("4. Buzzer");
break;
case 1: // Servo menu
// int servoencoderValue = 0;
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 20);
u8g2.print("Servo Angle: ");
u8g2.setCursor(30, 40);
u8g2.print(servoAngle);
u8g2.sendBuffer();
while (1) {
if (checkencoder() == true) {
setservo();
increment = 0;
}
if (checkswitch() == true) {
break;
}
}
break;
case 2: // WS2812 menu
// int LEDencoderValue = 0;
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 20);
u8g2.print("LED Color: ");
u8g2.setCursor(30, 40);
u8g2.print(ledColorIndex);
u8g2.sendBuffer();
// Handle LED color control
while (1) {
if (checkencoder() == true) {
setLedColor();
increment = 0;
}
if (checkswitch() == true) {
break;
}
}
break;
case 3: // Sensor menu
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(10, 30);
u8g2.print("Sensor1: ");
u8g2.setCursor(64, 30);
u8g2.print(sensorValue);
u8g2.setCursor(10, 60);
u8g2.print("Sensor2: ");
u8g2.setCursor(64, 60);
u8g2.print(sensorValue2);
// Read sensor value
sensorValue = analogRead(SENSOR_PIN);
sensorValue2 = analogRead(SENSOR_PIN2);
break;
case 4: // Buzzer menu
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 20);
u8g2.print("Buzzer Value: ");
u8g2.setCursor(30, 40);
u8g2.print(BuzzerValue);
// Handle Buzzer control
while (1) {
if (checkencoder() == true) {
setbuzzer();
increment = 0;
}
if (checkswitch() == true) {
break;
}
}
break;
case 5: // Blue uart
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.setCursor(0, 20);
u8g2.print("Blue uart : ");
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(0, 40);
u8g2.print(BuzzerValue);
// Handle Buzzer control
while (1) {
setbluetooth();
if (checkswitch() == true) {
break;
}
}
break;
default:
break;
}
increment = 0;
u8g2.sendBuffer();
// Handle menu navigation
if (checkswitch() == true) {
currentMenu++;
if (currentMenu > 5) {
currentMenu = 0;
}
delay(200); // Debounce delay
}
}
bool checkencoder() {
long newPosition = myEncoder.read();
if (newPosition != oldPosition) {
// Serial.println(newPosition + String(";") + oldPosition);
increment = newPosition - oldPosition;
oldPosition = newPosition;
return true;
}
return false;
}
bool checkswitch() {
encoderButtonState = digitalRead(ENCODER_SW);
if (encoderButtonState == LOW) {
delay(50); // Debounce delay
encoderButtonState = digitalRead(ENCODER_SW);
if (encoderButtonState == LOW) {
return true;
} else {
return false;
}
} else {
return false;
}
}
void setLedColor() {
ledColorIndex = ledColorIndex + increment;
if (ledColorIndex < 0) {
ledColorIndex = 0;
} else if (ledColorIndex > 10) {
ledColorIndex = 10;
}
u8g2.setCursor(30, 40);
u8g2.print(ledColorIndex);
u8g2.sendBuffer();
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = getColor(ledColorIndex);
}
FastLED.show();
delay(1);
}
void setservo() {
servoAngle = servoAngle + increment * 3;
if (servoAngle > 180) {
servoAngle = 180;
} else if (servoAngle < 0) {
servoAngle = 0;
}
u8g2.setCursor(30, 40);
u8g2.print(servoAngle);
u8g2.sendBuffer();
myservo.write(servoAngle);
}
void setbuzzer() {
BuzzerValue = BuzzerValue + increment * 8;
if (BuzzerValue > 255) {
BuzzerValue = 255;
} else if (BuzzerValue < 0) {
BuzzerValue = 0;
}
u8g2.setCursor(30, 40);
u8g2.print(BuzzerValue);
u8g2.sendBuffer();
analogWrite(BUZZER, BuzzerValue);
}
void setbluetooth() {
if (deviceConnected) { //设备连接后,每秒钟发送txValue。
memset(BLEbuf, 0, 32);
message_c = "s " + String(servoAngle) + "w" + String(ledColorIndex) + " s" + String(analogRead(SENSOR_PIN)) + "s" + String(analogRead(SENSOR_PIN2)) + "b" + String(BuzzerValue) + "\r\n";
char *p = const_cast<char *>(message_c.c_str());
memcpy(BLEbuf, p, 32);
pCharacteristic->setValue(BLEbuf);
pCharacteristic->notify(); // Send the value to the app!
Serial.print("*** Sent Value: ");
Serial.print(BLEbuf);
Serial.println(" ***");
// sensorValue = analogRead(SENSOR_PIN);
// sensorValue2 = analogRead(SENSOR_PIN2);
// memset(BLEbuf, 0, 256);
// // sprintf(message, "S%dW%dS%dS%dB%d", servoAngle, ledColorIndex, sensorValue, sensorValue2, BuzzerValue);
// sprintf(message, "S%dW%d", servoAngle, ledColorIndex);
// // message_c = message;
// // char* p = const_cast<char*>(message.c_str());
// // message1 = message;
// memcpy(BLEbuf, message, 256);
// // memcpy(BLEbuf, message_c, 32);
// pCharacteristic->setValue(BLEbuf);
// pCharacteristic->notify(); // Send the value to the app!
// delay(10);
u8g2.setCursor(0, 40);
u8g2.print(BLEbuf);
// // u8g2.setCursor(0, 60);
// // u8g2.print(message_c.substring(15, 32));
u8g2.sendBuffer();
// Serial.println("Sent Value:" + String(BLEbuf));
delay(100);
}
}
CRGB getColor(int index) {
switch (index) {
case 0:
return CRGB::Red;
case 1:
return CRGB::Green;
case 2:
return CRGB::Blue;
case 3:
return CRGB::Yellow;
case 4:
return CRGB::Magenta;
case 5:
return CRGB::Cyan;
case 6:
return CRGB::White;
case 7:
return CRGB::Purple;
case 8:
return CRGB::Orange;
case 9:
return CRGB::Pink;
default:
return CRGB::Black;
}
}
-
8. 功能展示及说明
8.1 主菜单显示
8.2 舵机控制
8.3 WS2812控制
8.4 ADC读取
8.5 蜂鸣器PWM
8.6 蓝牙交互
- 第一次是RT-Thread的【基于RT-Thread+RA6M4的智能鱼缸系统设计之鱼我所欲也】活动,作品是2022年暑假做的获得第六名,还是比较开心!
- 第二次2023年寒假做的是【基于MAX7800羽毛板语音控制ESP8266小车】,成绩还没有出来,第七名。
- 第三次2023年春做的【基于腾讯云的CH32V307开发板远程机械臂小车】,由于图床引用CSDN导致最后评审没有显示出来,最后获得安慰奖
-
希望得捷电子优化国内访问网站浏览和提高scheme-it工具设计水平;
-
期待硬禾联合各大平台推出更多有质量有意义持续性的创客活动!
评论(0)
您还未登录,请登录后发表或查看评论