经过前几期的学习,我们已经掌握了读取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
我要赚赏金
