经过前几期的学习,我们已经掌握了读取BH1750数据、读取按键状态、驱动屏幕等操作,只需要将这些知识进行整合 就能做出一个测光表了
前期回顾:
[Let'sDo第3期任务][电子测光表][过程贴]编程实现按键状态的采集
https://forum.eepw.com.cn/thread/387692/1
https://forum.eepw.com.cn/thread/387934/1
https://forum.eepw.com.cn/thread/387935/1
代码:
关键代码在前几期已经做了介绍,这里就不重复介绍了,很简单,大家可以参考一下
#include <Arduino.h> #include <TFT_eSPI.h> #include <Wire.h> #include <SPI.h> #include <cmath> #include <BH1750.h> TFT_eSPI tft; BH1750 lightSensor; TFT_eSprite sprite = TFT_eSprite(&tft); 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; 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; void setup() { pinMode(A0, INPUT); pinMode(A1, INPUT); Wire.begin(42, 41); lightSensor.begin(); tft.init(); tft.setRotation(1); tft.fillScreen(TFT_BLACK); tft.setSwapBytes(true); sprite.createSprite(240, 135); sprite.fillSprite(TFT_BLACK); sprite.setTextSize(2); } void displaySP() { int thisColor = gCurMenu == MENU_SP ? TFT_GREEN : TFT_WHITE; sprite.setTextColor(thisColor, TFT_BLACK); sprite.drawRect(0, 0, 240, 40, thisColor); sprite.setTextSize(4); sprite.setCursor(5, 5); sprite.printf("1/%.0f\n", 1.0 / gSp); } void displayAperture() { int thisColor = gCurMenu == MENU_AP ? TFT_GREEN : TFT_WHITE; sprite.setTextColor(thisColor, TFT_BLACK); sprite.drawRect(155, 55, 85, 50, thisColor); sprite.setCursor(160, 50); sprite.setTextSize(2); sprite.printf("F\n"); sprite.setCursor(160, 70); sprite.setTextSize(4); if (gAperture < 10) sprite.printf("%.1f\n", gAperture); else sprite.printf("%.0f\n", gAperture); } void displayISO() { int thisColor = gCurMenu == MENU_ISO ? TFT_GREEN : TFT_WHITE; sprite.setTextColor(thisColor, TFT_BLACK); sprite.drawRect(0, 55, 150, 50, thisColor); sprite.setCursor(5, 50); sprite.setTextSize(2); sprite.printf("ISO\n"); sprite.setCursor(5, 70); sprite.setTextSize(4); sprite.printf("%d\n", gIso); } void displayLx() { gLux = lightSensor.readLightLevel(); sprite.setTextSize(2); sprite.setCursor(5, 115); sprite.setTextColor(TFT_WHITE, TFT_BLACK); sprite.printf("%d Lx \n", gLux); } void displayMode() { int thisColor = gCurMenu == MENU_MODE ? TFT_GREEN : TFT_WHITE; sprite.fillRect(214, 114, 26, 18, thisColor); sprite.setTextColor(TFT_BLACK, thisColor); sprite.setTextSize(2); sprite.setCursor(216, 116); sprite.printf("%s\n", gModel == MODE_AV ? "AV" : "TV"); } void buttonFunc() { if (digitalRead(A0) == 0 || digitalRead(A1) == 0) { delay(50); if (digitalRead(A0) == 0 && digitalRead(A1) == 0) { if(gModel == MODE_AV) { if (gCurMenu == MENU_ISO) { gCurMenu = MENU_AP; } else if (gCurMenu == MENU_AP) { gCurMenu = MENU_MODE; } else if (gCurMenu == MENU_MODE) { gCurMenu = MENU_ISO; } } else { if (gCurMenu == MENU_ISO) { gCurMenu = MENU_SP; } else if (gCurMenu == MENU_SP) { gCurMenu = MENU_MODE; } else if (gCurMenu == MENU_MODE) { gCurMenu = MENU_ISO; } } while (digitalRead(A0) == 0) { delay(1); } } else if (digitalRead(A0) == 0) { switch (gCurMenu) { case MENU_SP: { gSpIndex++; if (gSpIndex >= gSpListSize) { gSpIndex = 0; } gSp = gSpList[gSpIndex]; break; } case MENU_AP: { gCurApertureIndex++; if (gCurApertureIndex >= gApertureListSize) { gCurApertureIndex = 0; } gAperture = gApertureList[gCurApertureIndex]; break; } case MENU_ISO: { gCurIsoIndex++; if (gCurIsoIndex >= gIsoListSize) { gCurIsoIndex = 0; } gIso = gIsoList[gCurIsoIndex]; break; } case MENU_MODE: { if(gModel == MODE_AV) { gModel = MODE_TV; } else { gModel = MODE_AV; } break; } } while (digitalRead(A0) == 0) { delay(1); } } else if (digitalRead(A1) == 0) { switch (gCurMenu) { case MENU_SP: { gSpIndex--; if(gSpIndex < 0) { gSpIndex = gSpListSize - 1; } gSp = gSpList[gSpIndex]; break; } case MENU_AP: { gCurApertureIndex--; if(gCurApertureIndex < 0) { gCurApertureIndex = gApertureListSize - 1; } gAperture = gApertureList[gCurApertureIndex]; break; } case MENU_ISO: { gCurIsoIndex--; if(gCurIsoIndex < 0) { gCurIsoIndex = gIsoListSize - 1; } gIso = gIsoList[gCurIsoIndex]; break; } case MENU_MODE: { if(gModel == MODE_AV) { gModel = MODE_TV; } else { gModel = MODE_AV; } break; } } while (digitalRead(A1) == 0) { delay(1); } } } } // 计算快门速度 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() { buttonFunc(); calcFunc(); sprite.fillSprite(TFT_BLACK); displayLx(); displaySP(); displayAperture(); displayISO(); displayMode(); sprite.pushSprite(0, 0); // delay(50); }
效果展示:
TV模式
AV模式
演示视频:
https://www.bilibili.com/video/BV1jAB4YgEvf/
EETV视频链接:https://v.eepw.com.cn/video/play/id/16195