#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#define TFT_DC 2
#define TFT_CS 3
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
#define IR_PIN A0
uint32_t lastCode;
#define CODE_0 2540240640
#define CODE_1 3476094720
#define CODE_2 3877175040
#define CODE_3 2239430400
#define CODE_4 4010868480
#define CODE_5 3342401280
#define CODE_6 2774204160
#define CODE_7 3175284480
#define CODE_8 3041591040
#define CODE_9 2907897600
#define CODE_ADD 4244832000
#define CODE_SUB 1738080000
#define CODE_C 1336999680
#define CODE_POWER 1570963200
#define CODE_MUL 534839040
#define CODE_EQUAL 1470693120
#define CODE_DIV 1871773440
#define CODE_MENU 501415680
#define CODE_BS 1036189440
long num1=0,num2=0;
char op=0;
String inputStr;
String history[5];
uint8_t histIdx=0,histCount=0,pageFlag=0;
// 水平居中打印
void printCenter(const char *txt,int y,uint16_t color,uint8_t size)
{
int16_t x1,y1;uint16_t w,h;
tft.setTextSize(size);
tft.getTextBounds(txt,0,y,&x1,&y1,&w,&h);
int x=(tft.width()-w)/2;
tft.setTextColor(color);
tft.setCursor(x,y);
tft.println(txt);
}
// 右对齐打印,不换行避免纵向截断
void printRA(const char *txt,int y,uint16_t c)
{
int16_t x1,y1;uint16_t w,h;
tft.setTextSize(2);
tft.getTextBounds(txt,0,y,&x1,&y1,&w,&h);
tft.setTextColor(c);
tft.setCursor(tft.width()-w-1,y);
tft.print(txt);
}
// 右下角签名,预留安全底边不截断
void printSign()
{
tft.setTextSize(2);
printRA(" ",240,ILI9341_GREEN);
printRA(" ",265,ILI9341_GREEN);
}
uint32_t readIR()
{
if(digitalRead(IR_PIN))return 0;
uint32_t t=micros();
while(!digitalRead(IR_PIN));
uint32_t low=micros()-t;
if(low<5000){
while(digitalRead(IR_PIN));
while(!digitalRead(IR_PIN));
return lastCode;
}
while(digitalRead(IR_PIN));
uint32_t code=0;
for(uint8_t i=0;i<32;i++){
while(!digitalRead(IR_PIN));
uint32_t s=micros();
while(digitalRead(IR_PIN));
if(micros()-s>1000)code|=1UL<<i;
}
lastCode=code;
return code;
}
// 主计算器界面
void refreshScreen()
{
tft.fillScreen(ILI9341_BLACK);
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(10,20);
tft.print("CALC");
tft.drawFastHLine(10,45,tft.width()-20,ILI9341_DARKGREY);
tft.setTextSize(3);
tft.setTextColor(ILI9341_YELLOW);
tft.setCursor(10,55);
tft.print(inputStr);
if(op!=0){
tft.setTextSize(2);
tft.setTextColor(ILI9341_CYAN);
tft.setCursor(10,120);
tft.print(num1);
tft.print(op);
tft.print(" ?");
}
printSign();
pageFlag=0;
}
// 开机欢迎页(文字全部居中)
void showWelcome()
{
tft.fillScreen(ILI9341_BLACK);
printCenter("CALC",60,ILI9341_YELLOW,3);
printCenter("IR Remote",120,ILI9341_CYAN,2);
printCenter("Press any key",160,ILI9341_CYAN,2);
printSign();
pageFlag=1;
}
void calcReset()
{
num1=0;op=0;inputStr="";histIdx=0;histCount=0;
showWelcome();
}
// 等于运算弹窗
void calcEqual()
{
if(inputStr.length()==0||op==0)return;
num2=inputStr.toInt();
long res=0;
if(op=='+')res=num1+num2;
if(op=='-')res=num1-num2;
if(op=='*')res=num1*num2;
if(op=='/'){if(num2==0)return;res=num1/num2;}
String rec=String(num1)+String(op)+String(num2)+"="+String(res);
if(histCount<5)history[histCount++]=rec;
else{for(int i=0;i<4;i++)history[i]=history[i+1];history[4]=rec;}
histIdx=histCount-1;
tft.fillScreen(ILI9341_BLACK);
tft.setTextSize(3);
tft.setTextColor(ILI9341_YELLOW);
tft.setCursor(10,40);
tft.print(num1);tft.print(op);tft.print(num2);tft.print("=");tft.print(res);
printSign();
pageFlag=1;
num1=res;inputStr="";op=0;
}
// 单条历史翻阅
void showHistory(int dir)
{
if(histCount==0)return;
histIdx+=dir;
if(histIdx<0)histIdx=histCount-1;
if(histIdx>=histCount)histIdx=0;
tft.fillScreen(ILI9341_BLACK);
tft.setTextSize(2);
tft.setTextColor(ILI9341_CYAN);
tft.setCursor(10,40);
tft.print("H ");tft.print(histIdx+1);tft.print("/");tft.print(histCount);
tft.setCursor(10,90);tft.print(history[histIdx]);
printSign();
pageFlag=1;
}
// MENU全部历史弹窗(修复自动换行)
void showAllHistory()
{
tft.fillScreen(ILI9341_BLACK);
tft.setTextSize(2);
tft.setTextColor(ILI9341_CYAN);
tft.setCursor(10,10);
tft.println("HIST");
if(histCount==0)
{
tft.println("Empty");
}
else
{
for(uint8_t i=0;i<histCount;i++)
{
tft.print(i+1);
tft.print(". ");
tft.println(history[i]);
}
}
printSign();
pageFlag=1;
}
void setup()
{
Serial.begin(115200); // 新增UART初始化
tft.begin();
calcReset();
}
void loop()
{
uint32_t code=readIR();
if(code==0){
delay(5);
return;
}
// 完全复刻稳定原版弹窗逻辑
if(pageFlag == 1)
{
refreshScreen();
delay(100);
return;
}
// 数字输入
if(code==CODE_0)inputStr+="0";
else if(code==CODE_1)inputStr+="1";
else if(code==CODE_2)inputStr+="2";
else if(code==CODE_3)inputStr+="3";
else if(code==CODE_4)inputStr+="4";
else if(code==CODE_5)inputStr+="5";
else if(code==CODE_6)inputStr+="6";
else if(code==CODE_7)inputStr+="7";
else if(code==CODE_8)inputStr+="8";
else if(code==CODE_9)inputStr+="9";
// 四则运算符
else if(code==CODE_ADD){if(inputStr.length()>0)num1=inputStr.toInt();op='+';inputStr="";}
else if(code==CODE_SUB){if(inputStr.length()>0)num1=inputStr.toInt();op='-';inputStr="";}
else if(code==CODE_MUL){if(inputStr.length()>0)num1=inputStr.toInt();op='*';inputStr="";}
else if(code==CODE_DIV){if(inputStr.length()>0)num1=inputStr.toInt();op='/';inputStr="";}
// 清除输入
else if(code==CODE_C)inputStr="";
// 电源重置
else if(code==CODE_POWER){calcReset();return;}
// 等于弹窗
else if(code==CODE_EQUAL){calcEqual();return;}
// 上一条历史
else if(code==CODE_MUL){showHistory(-1);return;}
// 下一条历史
else if(code==CODE_DIV){showHistory(1);return;}
// MENU全部历史
else if(code==CODE_MENU){showAllHistory();return;}
// 退格删除
else if(code==CODE_BS){if(inputStr.length()>0)inputStr.remove(inputStr.length()-1);}
// ============ 新增UART双向通信代码 ============
// 接收电脑串口指令
if(Serial.available() > 0)
{
char cmd = Serial.read();
if(cmd == 'C') inputStr = "";
if(cmd == 'R') calcReset();
}
// 实时打印计算器状态到电脑串口
Serial.print(F("输入:"));
Serial.print(inputStr);
Serial.print(F(" 运算符:"));
Serial.print(op);
Serial.print(F(" 数字1:"));
Serial.println(num1);
// ==============================================
refreshScreen();
delay(100);
}