/*
* Unary calculator for Exp, Ln, Sin, Tan, and 1/x
*/
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
#include <TouchScreen.h>
MCUFRIEND_kbv tft; // define tft_lcd object (thin film transistor lcd)
#define MINPRESSURE 200
#define MAXPRESSURE 1000
// Touch panels vary; calibrate to get proper pins:
/*
These are the pins for the shield coordinates,
obtained from TouchScreen_Calibr_native example
(in MCUFRIEND.kvb examples):
*/
#define YP A2 // coordinate y plus
#define XM A1 // coordinate x minus
#define YM 6 // coordinate y minus
#define XP 7 // coordinate x plus
const int TS_LEFT=177,TS_RT=952,TS_TOP=213,TS_BOT=956; // 240x320 ID=0x9340
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); // define touchscreen object
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define CYAN 0x07FF
#define LIGHTGREY 0xC618
#define GREY 0x8410
#define WHITE 0xFFFF
#define BUTTON_X 30
#define BUTTON_Y 123
#define BUTTON_W 51
#define BUTTON_H 50
#define BUTTON_SPACING_X 07
#define BUTTON_SPACING_Y 07
#define BUTTON_TEXTSIZE 2
char buttonlabels[16][5] = { "1", "2", "3","exp", "4", "5", "6","ln", "7", "8", "9","sin","DEL","0","1/x","tan"};
uint16_t buttoncolors[16] = { CYAN,CYAN,CYAN,GREY,CYAN,CYAN,CYAN,GREY,CYAN,CYAN,CYAN,GREY,RED,CYAN,GREY,GREY };
Adafruit_GFX_Button buttons[16];
int col=0,row=0,z=0, i, j;
#define TEXT_X 5
#define TEXT_Y 25
#define TEXT_W (tft.width()-10)
#define TEXT_H 70
#define TEXT_TSIZE 3
#define TEXT_TCOLOR BLUE
char q; // button variable
int presskey;
static float num1; // variable for input number
int operator_type=0;
#define TEXT_LEN 10
char textfield[TEXT_LEN+1] = "";
uint8_t textfield_i=0;
float result=0;
TSPoint tp;
boolean n=false; // screen will be cleared when n=true
int nc; // cases for button pressed
float fn; // inputted number digit by digit
#define TS_MINX 138
#define TS_MINY 236
#define TS_MAXX 772
#define TS_MAXY 869
void setup()
{
Serial.begin(9600); // only use for debugging
tft.reset();
uint16_t ID = tft.readID();
if (ID == 0xD3D3) ID = 0x9486; // write-only shield
tft.begin(ID);
tft.setRotation(0); //PORTRAIT
tft.fillScreen(LIGHTGREY);
//welcome screen
uint16_t width = tft.width() - 1;
uint16_t height = tft.height() - 1;
uint8_t border = 10;
tft.fillScreen(GREY);
tft.fillRect(border, border, (width - border * 2), (height - border * 2), WHITE);
tft.setTextSize (3);
tft.setTextColor(RED);
tft.setCursor ((tft.width()/2)-70, 40);
tft.println("ADVANCED");
tft.setCursor ((tft.width()/2)-85, 85);
tft.println("CALCULATOR");
tft.setCursor ((tft.width()/2)-17, 160);
tft.setTextSize (2);
tft.setTextColor(BLACK);
tft.println("ENA");
tft.setTextColor(BLUE);
tft.setCursor ((tft.width()/2)-95, 250);
tft.println("Touch to Proceed");
//wait for touch
do{
tp= ts.getPoint();
pinMode(XM, OUTPUT); // Pins for TFT control
pinMode(YP, OUTPUT);
} while((tp.z < MINPRESSURE ) || (tp.z > MAXPRESSURE));
tp.x = map(tp.x, TS_LEFT, TS_RT, 0, tft.width());
tp.y = map(tp.y, TS_TOP, TS_BOT, 0, tft.height());
// calculator output screen
tft.fillScreen(LIGHTGREY);
tft.setCursor ((tft.width()/2)-65, 5);
tft.setTextSize (2);
tft.setTextColor(BLACK);
tft.println("Unary Mode");
tft.drawRect(TEXT_X, TEXT_Y, TEXT_W, TEXT_H, BLACK);
// Button initialize
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
row=i;col=j;
buttons[z].initButton(&tft, BUTTON_X+col*(BUTTON_W+BUTTON_SPACING_X),
BUTTON_Y+row*(BUTTON_H+BUTTON_SPACING_Y), // x, y, w, h, outline, fill, text
BUTTON_W, BUTTON_H, BLACK, buttoncolors[z],BLACK,
buttonlabels[z], BUTTON_TEXTSIZE);
buttons[z].drawButton();
z++;
}
}
}
void loop()
{
// wait for button press
do {
tp= ts.getPoint();
pinMode(XM, OUTPUT); // Pins for TFT control
pinMode(YP, OUTPUT);
} while((tp.z < MINPRESSURE ) || (tp.z > MAXPRESSURE));
tp.x = map(tp.x, TS_LEFT, TS_RT, 0, tft.width());
tp.y = map(tp.y, TS_TOP, TS_BOT, 0, tft.height());
// clear results
if (n == true)
{
tft.setCursor(TEXT_X + 2, TEXT_Y+40);
tft.setTextColor(TEXT_TCOLOR, LIGHTGREY);
tft.setTextSize(TEXT_TSIZE);
tft.print(" ");
tft.setCursor(TEXT_X + 2, TEXT_Y+10);
tft.print(" ");
n = false;
}
//get button
for (uint8_t b=0; b<16; b++)
{
if (buttons[b].contains(tp.x, tp.y))
{
buttons[b].press(true); // button pressed
q=b;
}
else
{
buttons[b].press(false); // button not pressed
}
}
// when number button is pressed:
if(q == 0 || q==1 || q==2 || q== 4 || q==5 ||
q==6 || q==8 || q==9 || q==10 || q==13)
{
switch (q)
{
case 0: nc = 1; pressed_button();animate();display_text(); break;
case 1: nc = 2; pressed_button();animate();display_text(); break;
case 2: nc = 3; pressed_button();animate();display_text(); break;
case 4: nc = 4; pressed_button();animate();display_text(); break;
case 5: nc = 5; pressed_button();animate();display_text(); break;
case 6: nc = 6; pressed_button();animate();display_text(); break;
case 8: nc = 7; pressed_button();animate();display_text(); break;
case 9: nc = 8; pressed_button();animate();display_text(); break;
case 10: nc = 9; pressed_button();animate();display_text(); break;
case 13: nc = 0; pressed_button();animate();display_text(); break;
}
}
// form input number digit by digit:
if (nc > 0 || q==13)
{
switch (presskey)
{ // can input up to 5 digits:
case 0: fn = nc; break;
case 1: fn = fn*10 + nc; break;
case 2: fn = fn*10 + nc; break;
case 3: fn = fn*10 + nc; break;
case 4: fn = fn*10 + nc; break;
}
nc=0;
presskey++; // 1st press = units; 2nd press = tens; 3rd press = hundreds; etc.
delay(200);
}
// when operator button is pressed:
if(q == 3 || q==7 || q==11 || q== 12 || q==14 || q==15 )
{
presskey=0;
num1 = fn;
switch (q)
{
case 3: operator_type = 1; pressed_button();animate();display_result(num1); break;
case 7: operator_type = 2; pressed_button();animate();display_result(num1); break;
case 11: operator_type = 3; pressed_button();animate();display_result(num1); break;
case 15: operator_type = 4; pressed_button();animate();display_result(num1); break;
case 14: operator_type = 5; pressed_button();animate();display_result(num1); break;
case 12: pressed_button();animate();clr_button(); break;
}
}
}
// pressed button
void pressed_button()
{
textfield[textfield_i] = buttonlabels[q][0];
textfield_i++;
textfield[textfield_i] = 0; // zero terminate
}
//Animate
void animate()
{
if (buttons[q].justPressed())
{
buttons[q].drawButton(true); // draw invert
delay(300);
buttons[q].drawButton();
}
}
//text display
void display_text()
{
tft.setCursor(TEXT_X + 2, TEXT_Y+10);
tft.setTextColor(TEXT_TCOLOR, WHITE);
tft.setTextSize(TEXT_TSIZE);
tft.print(textfield);
}
//display result
void display_result(float num)
{
switch (operator_type)
{
case 1:result=exp(num);break;
case 2:result=log(num);break;
case 3:result=sin(num);break;
case 4:result=tan(num);break;
case 5:result=1/num;break;
}
tft.setCursor(TEXT_X + 2, TEXT_Y+40);
tft.setTextColor(TEXT_TCOLOR, WHITE);
tft.setTextSize(TEXT_TSIZE);
tft.print('=');
tft.print(result,4); // result to 4 decimal places
}
//clr button
void clr_button()
{
q=0;
num1 = 0;
nc=0;
fn=0;
result=0;
//char textfield[TEXT_LEN+1] = "";
tft.setCursor(TEXT_X + 2, TEXT_Y+40);
tft.setTextColor(TEXT_TCOLOR, LIGHTGREY);
tft.setTextSize(TEXT_TSIZE);
tft.print(" ");
tft.setCursor(TEXT_X + 2, TEXT_Y+10);
tft.print(" ");
textfield_i=0;
operator_type=0;
n=true;
}
Comments
Please log in or sign up to comment.