#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
// 根据电路图定义的引脚
#define TFT_DC 9 // 连接lcd1:D/C -> uno:9
#define TFT_CS 10 // 连接lcd1:CS -> uno:10
#define POT_PIN A0 // 电位器连接A0
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// 系统参数
const int GRAPH_X = 20;
const int GRAPH_Y = 60;
const int GRAPH_W = 200;
const int GRAPH_H = 120;
const float MIN_TEMP = 36.0;
const float MAX_TEMP = 42.0;
const float ALARM_TEMP = 38.0;
const float STABLE_THRESHOLD = 0.1;
const unsigned long STABLE_TIME = 5000;
// 运行数据
float tempHistory[GRAPH_W];
float currentTemp = 36.5;
bool isAlarming = false;
bool isLocked = false;
unsigned long lastUpdate = 0;
unsigned long stableStartTime = 0;
// 颜色定义
#define BG_COLOR 0x0000
#define AXIS_COLOR 0x5AEB
#define NORMAL_COLOR 0x07E0
#define ALARM_COLOR 0xF800
#define TEXT_COLOR 0xFFFF
#define LOCK_COLOR 0x03EF
// 前置声明所有函数
int mapTempToY(float temp);
void drawUI();
void updateDisplay();
void updateLineChart();
void lockTemperature();
void handleAlarm();
void setup() {
Serial.begin(9600);
pinMode(POT_PIN, INPUT); // 初始化电位器引脚
tft.begin();
tft.setRotation(3);
tft.fillScreen(BG_COLOR);
// 初始化温度数组
for(int i=0; i<GRAPH_W; i++) {
tempHistory[i] = mapTempToY(36.5);
}
drawUI(); // 绘制界面
}
void loop() {
static float lastTemp = currentTemp;
// 使用电位器控制温度波动幅度 (0-5V对应0.0-1.0的比例)
float potValue = analogRead(POT_PIN) / 1023.0;
if(millis() - lastUpdate > 500 && !isLocked) {
lastUpdate = millis();
// 修改后的温度模拟(加入电位器控制)
currentTemp = 36.5 + potValue * 2.0 * sin(millis()/8000.0) + random(-3,3)/50.0;
currentTemp = constrain(currentTemp, MIN_TEMP, MAX_TEMP); // 限制温度范围
// 稳定性检测
if(fabs(currentTemp - lastTemp) < STABLE_THRESHOLD) {
if(stableStartTime == 0) stableStartTime = millis();
else if(millis() - stableStartTime > STABLE_TIME) lockTemperature();
} else {
stableStartTime = 0;
}
lastTemp = currentTemp;
// 报警检测
isAlarming = currentTemp >= ALARM_TEMP;
updateDisplay();
tft.drawFastHLine(GRAPH_X, mapTempToY(38.0), 200, 0xff10);
}
// 报警闪烁
handleAlarm();
}
void handleAlarm() {
static unsigned long lastBlink = 0;
static bool blinkState = false;
if(isAlarming && millis() - lastBlink > 500) {
lastBlink = millis();
blinkState = !blinkState;
tft.fillRoundRect(160, 35, 70, 25, 5, blinkState ? ALARM_COLOR : TEXT_COLOR);
tft.setTextColor(blinkState ? TEXT_COLOR : ALARM_COLOR);
tft.setCursor(170, 38);
tft.print("FEVER!");
}
}
void drawUI() {
// 1. 标题栏
tft.fillRect(0, 0, 240, 30, LOCK_COLOR);
tft.setTextColor(TEXT_COLOR);
tft.setTextSize(2);
tft.setCursor(50, 8);
tft.print("Temp Monitor");
// 2. 当前温度显示区
tft.drawRoundRect(10, 35, 220, 25, 5, TEXT_COLOR);
// 3. 绘制折线图框架
tft.drawRoundRect(GRAPH_X-2, GRAPH_Y-2, GRAPH_W+4, GRAPH_H+4, 5, TEXT_COLOR);
// 4. 绘制坐标轴
for(float temp=MIN_TEMP; temp<=MAX_TEMP; temp+=1.0){
int y = mapTempToY(temp);
tft.drawFastHLine(GRAPH_X-5, y, 5, AXIS_COLOR);
tft.setTextSize(1);
tft.setTextColor(AXIS_COLOR);
tft.setCursor(5, y-4);
tft.print(temp,0);
}
}
void updateDisplay() {
// 1. 更新温度显示
tft.fillRect(40, 35, 110, 25, BG_COLOR);
tft.setTextSize(2);
tft.setTextColor(isAlarming ? ALARM_COLOR : NORMAL_COLOR);
tft.setCursor(40, 38);
tft.print(currentTemp,1);
tft.print(" C");
// 2. 更新折线图
updateLineChart();
// 3. 更新状态指示
if(!isLocked && stableStartTime > 0) {
int remain = (STABLE_TIME - (millis() - stableStartTime)) / 1000 + 1;
tft.fillRoundRect(160, 35, 70, 25, 5, LOCK_COLOR);
tft.setTextColor(TEXT_COLOR);
tft.setCursor(170, 38);
tft.print(remain);
tft.print("s");
}
}
void updateLineChart() {
// 左移历史数据
for(int i=0; i<GRAPH_W-1; i++) tempHistory[i] = tempHistory[i+1];
tempHistory[GRAPH_W-1] = mapTempToY(currentTemp);
// 清空图表区(保留坐标轴)
tft.fillRect(GRAPH_X, GRAPH_Y, GRAPH_W, GRAPH_H, BG_COLOR);
// 重绘坐标轴
for(float temp=MIN_TEMP; temp<=MAX_TEMP; temp+=1.0){
tft.drawFastHLine(GRAPH_X-5, mapTempToY(temp), 5, AXIS_COLOR);
}
// 绘制折线
for(int x=1; x<GRAPH_W; x++) {
int x1 = GRAPH_X + x - 1;
int x2 = GRAPH_X + x;
int y1 = tempHistory[x-1];
int y2 = tempHistory[x];
uint16_t color = (y1+y2)/2 < mapTempToY(ALARM_TEMP) ? NORMAL_COLOR : ALARM_COLOR;
tft.drawLine(x1, y1, x2, y2, color);
}
}
void lockTemperature() {
isLocked = true;
// 显示锁定状态
tft.fillRoundRect(160, 35, 70, 25, 5, LOCK_COLOR);
tft.setTextColor(TEXT_COLOR);
tft.setCursor(165, 38);
tft.print("LOCKED");
// 在图表区显示最终温度
tft.setTextSize(3);
tft.setTextColor(NORMAL_COLOR);
tft.setCursor(GRAPH_X + 50, GRAPH_Y + 50);
tft.print(currentTemp,1);
tft.print("C");
}
// 辅助函数
int mapTempToY(float temp) {
return GRAPH_Y + GRAPH_H - (temp - MIN_TEMP)/(MAX_TEMP-MIN_TEMP)*GRAPH_H;
}