通过ESP32 的蓝牙功能,(代码中用的BLE)将测光数据传到手机上。
1、蓝牙把测光数据传到手机
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <Wire.h>
#include <M5_DLight.h>
// BLE 相关设置
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
BLEServer *pServer = NULL;
BLECharacteristic *pCharacteristic = NULL;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint32_t value = 1; // 从1开始
// 显示屏和传感器设置
#define TFT_CS 7 // CS 引脚
#define TFT_DC 39 // DC 引脚
#define TFT_RST 40 // RESET 引脚
#define TFT_BACKLIGHT 45 // 背光控制引脚
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
M5_DLight sensor;
// 按钮引脚
const int buttonA_PIN = 12; // 按钮 A 引脚
const int buttonB_PIN = 13; // 按钮 B 引脚
// ISO 级别
int isoLevels[] = {100, 200, 300, 400, 500, 600};
int isoIndex = 0;
int currentISO = isoLevels[isoIndex];
// EV 相关变量
float F; // 光圈
float T; // 快门速度
uint16_t lux; // 光照强度
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
}
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
void setup() {
Serial.begin(115200);
pinMode(TFT_BACKLIGHT, OUTPUT);
digitalWrite(TFT_BACKLIGHT, HIGH); // 打开背光
// 初始化屏幕
tft.init(135, 240); // 根据屏幕分辨率初始化
tft.setRotation(3); // 设置屏幕方向
tft.fillScreen(ST77XX_BLACK); // 背景色设为黑色
// 按钮引脚设置为输入
pinMode(buttonA_PIN, INPUT_PULLUP);
pinMode(buttonB_PIN, INPUT_PULLUP);
// 初始化传感器
sensor.begin();
sensor.setMode(CONTINUOUSLY_H_RESOLUTION_MODE);
// 初始化 BLE 设备
BLEDevice::init("Long name works now");
// 创建 BLE 服务器
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// 创建 BLE 服务
BLEService *pService = pServer->createService(SERVICE_UUID);
// 创建 BLE 特征
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_WRITE
);
// 设置初始特征值
pCharacteristic->setValue(String(value).c_str());
// 启动服务
pService->start();
Serial.println("Service started");
// 开始广播
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06);
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();
Serial.println("Advertising started. Now you can read it in your phone!");
}
void updateDisplay() {
// 显示信息
tft.fillScreen(ST77XX_BLACK);
tft.setTextColor(ST77XX_WHITE);
tft.setCursor(10, 10);
tft.setTextSize(2);
tft.print("ISO: ");
tft.println(currentISO);
tft.setCursor(10, 40);
tft.print("Lux: ");
tft.println(lux);
tft.setCursor(10, 70);
tft.print("F: ");
tft.println(F, 2);
tft.setCursor(10, 100);
tft.print("T: ");
tft.println(T, 4);
}
void loop() {
// 获取光照强度
lux = sensor.getLUX();
float ev = 2 + log10(lux / 10.0);
float evWithISO = ev - log2(currentISO / 100.0);
// 计算光圈和快门速度
T = pow(2, evWithISO - 2);
F = sqrt(pow(2, evWithISO) * T);
// 更新按钮状态
if (digitalRead(buttonA_PIN) == LOW) { // 按下按钮 A 增加 ISO
isoIndex = (isoIndex + 1) % 6;
currentISO = isoLevels[isoIndex];
delay(200); // 防抖延时
}
if (digitalRead(buttonB_PIN) == LOW) { // 按下按钮 B 减少 ISO
isoIndex = (isoIndex - 1 + 6) % 6;
currentISO = isoLevels[isoIndex];
delay(200); // 防抖延时
}
// 更新显示
updateDisplay();
// BLE 处理
if (deviceConnected) {
// 构建数据字符串
String data = "lux:" + String(lux) + ", iso:" + String(currentISO) + ", F:" + String(F, 2) + ", T:" + String(T, 4);
pCharacteristic->setValue(data.c_str());
pCharacteristic->notify();
Serial.print("Sending data: ");
Serial.println(data); // 打印发送的数据
delay(200); // 每200毫秒发送一次
}
else {
if (oldDeviceConnected) {
delay(500); // 等待 Bluetooth 栈准备好
pServer->startAdvertising(); // 重新开始广播
Serial.println("Start advertising");
oldDeviceConnected = deviceConnected;
}
}
// 处理设备连接状态
if (deviceConnected && !oldDeviceConnected) {
oldDeviceConnected = deviceConnected;
}
}
具体看代码。
通过nrf connect最新版的程序,顺利读取到光线数据,并结合前面,按按钮A和B可以调整ISO值
我要赚赏金
