开箱贴:Let‘s do 第三季[电子测光表]开箱贴-电子产品世界论坛
过程贴:Let‘sdo第三季[电子测光表]过程贴-电子产品世界论坛
视频链接:DIY电子测光笔成果展示_哔哩哔哩_bilibili
EETV视频链接:https://v.eepw.com.cn/video/play/id/16198
ESP32代码:Pointer-Fly/esp32-bh1750
APP代码:Song/umbrella-new
整体代码如下,界面UI部分以及测光部分参考自群里大佬的设计,细节处有部分修改,同时整合了蓝牙控制舵机以及蓝牙读取光照强度功能。
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <SPI.h>
#include <ESP32Servo.h>
#include "HAL_DLight.h"
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789 Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST); // function prototypes void Disp_Init(); // Use dedicated hardware SPI pins M5_DLight sensor;
#define MAX_WIDTH 2500 #define MIN_WIDTH 500 #define SERVO_PIN 13
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_SERVO_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a9"
#define CHARACTERISTIC_LIGHT_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a0" // 定义 servo 对象 Servo my_servo;
BLECharacteristic *pCharacteristicLight;
enum MENU_ENUM { MENU_SP, MENU_AP, MENU_ISO, MENU_MODE, };
MENU_ENUM gCurMenu = MENU_ISO; enum MODE_ENUM { MODE_AV, MODE_TV, };
MODE_ENUM gModel = MODE_AV;
static int gIsoList[] = {12, 25, 50, 64, 80, 100, 125, 160, 200, 250, 320, 400, 500, 600, 800, 1600, 3200, 6400, 12800, 25600, 51200};
static int gIsoListSize = sizeof(gIsoList) / sizeof(int);
int gCurIsoIndex = 5; int gIso = gIsoList[gCurIsoIndex];
static float gSpList[] = {1.0 / 1, 1.0 / 2, 1.0 / 3, 1.0 / 4, 1.0 / 5, 1.0 / 6, 1.0 / 8, 1.0 / 10, 1.0 / 13, 1.0 / 15, 1.0 / 20, 1.0 / 25, 1.0 / 30, 1.0 / 40, 1.0 / 50, 1.0 / 60, 1.0 / 80, 1.0 / 100, 1.0 / 125, 1.0 / 160, 1.0 / 200, 1.0 / 250, 1.0 / 320, 1.0 / 400, 1.0 / 500, 1.0 / 640, 1.0 / 800, 1.0 / 1000, 1.0 / 1250, 1.0 / 1600, 1.0 / 2000, 1.0 / 2500, 1.0 / 3200, 1.0 / 4000, 1.0 / 5000, 1.0 / 6400, 1.0 / 8000, 1.0 / 12000};
static int gSpListSize = sizeof(gSpList) / sizeof(float); int gSpIndex = 8; float gSp = gSpList[gSpIndex];
static float gApertureList[] = {1, 1.2, 1.4, 1.8, 2, 2.4, 2.8, 3, 3.2, 3.5, 4, 4.5, 5, 5.6, 6.3, 7.1, 8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 26, 28, 32, 36, 40, 45, 52, 56, 64};
static int gApertureListSize = sizeof(gApertureList) / sizeof(float); int gCurApertureIndex = 5; float gAperture = gApertureList[gCurApertureIndex];
int gLux = 0;
void servoInit() { // 分配硬件定时器 ESP32PWM::allocateTimer(0); // 设置频率
my_servo.setPeriodHertz(50); // 关联 servo 对象与 GPIO 引脚,设置脉宽范围
my_servo.attach(SERVO_PIN, MIN_WIDTH, MAX_WIDTH); }
void servoDown() { for (int i = 180; i >= 0; i--) {
my_servo.write(i);
delay(15); } }
void servoUp() {
for (int i = 0; i <= 180; i++) {
my_servo.write(i);
delay(15);
}
}
class BLECallbacks : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic)
{
std::string value = pCharacteristic->getValue(); // 区分不同的特征值
if (pCharacteristic->getUUID().equals(BLEUUID(CHARACTERISTIC_SERVO_UUID))) {
if (value.length() > 0)
{
Serial.println("*********");
if (value[0] == '0')
{
Serial.println("Servo down");
servoDown();
}
else if (value[0] == '1')
{
Serial.println("Servo up");
servoUp();
}
Serial.println();
Serial.println("*********");
}
}
}
};
void BLE_Init() {Serial.println("Starting BLE work!");
BLEDevice::init("ESP32");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristicServo = pService->createCharacteristic(CHARACTERISTIC_SERVO_UUID,BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE);
pCharacteristicLight = pService->createCharacteristic(CHARACTERISTIC_LIGHT_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE);
pCharacteristicServo->setValue("0");
pCharacteristicServo->setCallbacks(new BLECallbacks());
pCharacteristicLight->setValue("0");
pCharacteristicLight->setCallbacks(new BLECallbacks());
pService->start(); // BLEAdvertising *pAdvertising = pServer->getAdvertising();
// this still is working for backward compatibility
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();
Serial.println("Characteristic defined! Now you can read it in your phone!");
}
void switchMenu() {
if (gModel == MODE_AV)
{
gCurMenu = (gCurMenu == MENU_ISO) ? MENU_AP : (gCurMenu == MENU_AP) ? MENU_MODE: MENU_ISO;
}
else
{
gCurMenu = (gCurMenu == MENU_ISO) ? MENU_SP : (gCurMenu == MENU_SP) ? MENU_MODE: MENU_ISO;
}
}
void adjustValue(int direction)
{
switch (gCurMenu)
{
case MENU_SP:
gSpIndex = (gSpIndex + direction + gSpListSize) % gSpListSize;
gSp = gSpList[gSpIndex];
break;
case MENU_AP:
gCurApertureIndex = (gCurApertureIndex + direction + gApertureListSize) % gApertureListSize;
gAperture = gApertureList[gCurApertureIndex];
break;
case MENU_ISO:
gCurIsoIndex = (gCurIsoIndex + direction + gIsoListSize) % gIsoListSize;
gIso = gIsoList[gCurIsoIndex];
break;
case MENU_MODE:
gModel = (gModel == MODE_AV) ? MODE_TV : MODE_AV;
break;
}
}
void keyScanTask(void *pvParameters) {
while (1)
{
if (digitalRead(17) == 0 || digitalRead(18) == 0)
{
delay(50);
if (digitalRead(17) == 0 && digitalRead(18) == 0)
{
switchMenu();
while (digitalRead(17) == 0)
{
delay(1);
}
}
else if (digitalRead(17) == 0)
{
adjustValue(1);
while (digitalRead(17) == 0)
{
delay(1);
}
}
else if (digitalRead(18) == 0)
{
adjustValue(-1);
while (digitalRead(18) == 0)
{
delay(1);
}
}
}
}
}
void setup() { Serial.begin(115200); // Initialize the keypad
pinMode(18, INPUT);
pinMode(17, INPUT);
sensor.begin();
delay(500);
sensor.setMode(CONTINUOUSLY_H_RESOLUTION_MODE);
servoInit();
Disp_Init();
BLE_Init();
xTaskCreatePinnedToCore(keyScanTask, "keyScanTask", 4096, NULL, 1, NULL, 1); }
void displayLx() { gLux = sensor.getLUX(); pCharacteristicLight->setValue(String(gLux).c_str());
tft.setTextSize(2);
tft.setCursor(5, 115);
tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
tft.printf("%d Lx n", gLux); }
void displayMode() { int thisColor = gCurMenu == MENU_MODE ? ST77XX_GREEN : ST77XX_WHITE;
tft.fillRect(214, 114, 26, 18, thisColor);
tft.setTextColor(ST77XX_BLACK, thisColor);
tft.setTextSize(2);
tft.setCursor(216, 116);
tft.printf("%sn", gModel == MODE_AV ? "AV" : "TV"); }
void displaySP() { int thisColor = gCurMenu == MENU_SP ? ST77XX_GREEN : ST77XX_WHITE;
tft.setTextColor(thisColor, ST77XX_BLACK);
tft.drawRect(0, 0, 240, 40, thisColor);
tft.setTextSize(4);
tft.setCursor(5, 5);
tft.printf("1/%.0fn", 1.0 / gSp); }
void displayAperture() { int thisColor = gCurMenu == MENU_AP ? ST77XX_GREEN : ST77XX_WHITE;
tft.setTextColor(thisColor, ST77XX_BLACK);
tft.drawRect(155, 55, 85, 50, thisColor);
tft.setCursor(160, 50);
tft.setTextSize(2);
tft.printf("Fn");
tft.setCursor(160, 70);
tft.setTextSize(4);
if (gAperture < 10) tft.printf("%.1fn", gAperture); else tft.printf("%.0fn", gAperture); }
void displayISO() { int thisColor = gCurMenu == MENU_ISO ? ST77XX_GREEN : ST77XX_WHITE;
tft.setTextColor(thisColor, ST77XX_BLACK);
tft.drawRect(0, 55, 150, 50, thisColor);
tft.setCursor(5, 50);
tft.setTextSize(2);
tft.printf("ISOn");
tft.setCursor(5, 70);
tft.setTextSize(4);
tft.printf("%dn", gIso); }
void Disp_Init() { pinMode(TFT_BACKLITE, OUTPUT);
digitalWrite(TFT_BACKLITE, HIGH); // turn on the TFT / I2C power supply pinMode(TFT_I2C_POWER, OUTPUT);
digitalWrite(TFT_I2C_POWER, HIGH); delay(10);
// initialize TFT tft.init(135, 240); // Init ST7789 240x135
tft.setRotation(3);
tft.fillScreen(ST77XX_BLACK); } // 计算快门速度
void calculateShutterSpeed() { float K = 12.5;
gSp = (gAperture * gAperture * 100) / (K * gIso * gLux); } // 计算光圈
void calculateAperture() { float K = 12.5; gAperture = sqrt((gIso * gLux * K * gSp) / 100); }
void calcFunc() { if (gModel == MODE_AV) { calculateShutterSpeed();
} else { calculateAperture(); } }
void loop() { displayLx();
displaySP();
displayAperture();
displayISO();
displayMode();
tft.setCursor(0, 0);
delay(50); }在此吐槽一下这个板子,可用的电源引脚有点少,因为没用面包板,所以全部采用焊线的方式进行连接
感谢电子产品世界EEPW和digikey平台给了本次电子产品DIY的帮助,同时感谢群友们的帮助,再次感谢!!!
我要赚赏金
