#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <SPI.h>
//#include <Fonts/FreeMonoBold9pt7b.h>
//#include <Fonts/FreeMonoBoldOblique12pt7b.h>
//#include <Fonts/FreeMonoBold12pt7b.h>
//#include <Fonts/FreeMonoBold18pt7b.h>
//#include <Fonts/FreeMonoBold24pt7b.h>
//#include <Fonts/FreeMonoBold9pt7b.h>
//#include <Fonts/FreeMonoBoldOblique12pt7b.h>
//#include <Fonts/FreeMonoBoldOblique18pt7b.h>
//#include <Fonts/FreeMonoBoldOblique24pt7b.h>
//#include <Fonts/FreeMonoBoldOblique9pt7b.h>
#define TFT_CS 10
#define TFT_RST 9
#define TFT_DC 8
#define TFT_SCLK 13
#define TFT_MOSI 11
//voltage measurement sample count amount
#define NUM_SAMPLES 5
boolean lockout;
boolean undervoltagelockout;
float p = 3.1415926;
//voltage divider:
int sum = 0; //sum of samples taken
unsigned char sample_count = 0; //current sample number
float voltage = 0.0; //calculated voltage
int voltageDividerPin = A1;
unsigned long voltageTimer = 0;
int batteryBar = 0;
int batteryBarPrint = 0;
//button declarations
//FIRE
const int fireButtonPin = 4; //declare fire button pin
int fireButtonState = HIGH; //variable to store fire button state
int lastFireButtonState = 0; //variable to store last fire button state for counter
byte fireButtonPushCounter = 1; //counter for the number of fire button presses
int lastFireButtonPushCounter = 0;
unsigned long fireButtonTimer = 0;
unsigned long lockDelayTimer = 0;
int lastLockoutState = HIGH;
//UP /DOWN
const int upButtonPin = 7; //declare up button pin
int upButtonState = HIGH;
const int downButtonPin = 6; //declare down button pin
int downButtonState = HIGH;
int lastUpButtonState = 0; //variable to store last up button state
int lastDownButtonState = 0;
unsigned long upDownButtonTimer = 0;
//PWM Mosfet section
const int gatePin = 3; // declare mosfet gate pin
int dutyCyclePercent = 0; // value from 0-255 for PWM output
int dutyCycleOutput = 0; // variable for duty cycle 0-100% screenprint
int lastDutyCyclePercent = 0;
const int screenPin = 5;
int screenDimIncrement = 0;
boolean screenDimBool;
unsigned long screenDimTimer = 0;
//figure these out
const float ammeterPin = A0;
const double GAUSS_PER_STEP = 1.8;
double ampVal = 0;
double ammeterPrint = 0;
unsigned long ampTimer = 0;
int wattVal = 0;
int wattPrint = 0;
int rmsVal = 0;
double resistance = 0;
uint16_t time = millis();
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
void setup()
{
tft.initSPI(ISR_BLOCK); // You will need to do this in every sketch
tft.fillScreen(ILI9341_BLACK);
tft.invertDisplay(false);
tft.setRotation(2);
tft.setTextColor(ILI9341_WHITE);
tft.setTextWrap(false);
// tft.setFont(&FreeMonoBold9pt7b);
// tft.println("Vaporizer initialized, mod setup and screen display begin--");
// delay(1500);
Serial.begin(9600);
pinMode(fireButtonPin, INPUT_PULLUP);
pinMode(upButtonPin, INPUT_PULLUP);
pinMode(downButtonPin, INPUT_PULLUP);
//pinMode(gatePin, OUTPUT);
//pinMode(screenPin, OUTPUT);
pinMode(ammeterPin, INPUT);
pinMode(voltageDividerPin, INPUT);
//tft.println("pins are activated");
//delay(1500);
//tft.fillScreen(ILI9341_BLACK);
boolean lockout = false;
boolean undervoltagelockout = false;
screenDimIncrement = 255;
analogWrite(screenPin, screenDimIncrement);
boolean screenDimBool = false;
//take initial battery reading
while (sample_count < NUM_SAMPLES) {
sum += analogRead(voltageDividerPin);
sample_count++;
delay(10);
}
voltage = ((float)sum / (float)NUM_SAMPLES * 5.015) / 1024.0;
sample_count = 0;
sum = 0;
voltageTimer = millis();
screenDimTimer = millis();
dutyCycleOutput = map(dutyCyclePercent,0,100,0,255);
//battery bar:
tft.drawRoundRect(15, 31, 12, 110, 6, ILI9341_WHITE);
//% box:
tft.drawRoundRect(34,31,80,58,8, ILI9341_WHITE);
//%box inside:
tft.fillRoundRect(36,33,76,54,8, ILI9341_BLACK);
//R/W/A/RMS box:
tft.drawRoundRect(40, 94, 69, 60, 8, ILI9341_WHITE);
//R/W/A/RMS inside:
tft.fillRoundRect(42, 96, 65, 56, 8, ILI9341_BLACK);
//LeviticusVapes:
tft.setTextSize(1);
tft.setCursor(23,10);
tft.print("Leviticus Vapes");
//Batt:
tft.setTextSize(1);
tft.setCursor(7,143);
tft.print(voltage*11.132);
//RES:
tft.setTextSize(1);
tft.setCursor(50,104);
tft.print("Res = ");
tft.setCursor(81,104);
tft.print(resistance);
//WATT:
tft.setCursor(44,114);
tft.print("Watt = ");
tft.setCursor(81,114);
tft.print(wattVal);
//AMP:
tft.setCursor(50,124);
tft.print("Amp = ");
tft.setCursor(81,124);
tft.print(ammeterPrint);
//RMS:
tft.setCursor(50,134);
tft.print("RMS = ");
tft.setCursor(81,134);
tft.print(rmsVal);
//%:
if(dutyCyclePercent>0 && dutyCyclePercent <10){
tft.setTextSize(2);
tft.setCursor(64,51);
tft.print(dutyCyclePercent);
tft.print("%");
}
if(dutyCyclePercent>=10 && dutyCyclePercent <100){
tft.setTextSize(2);
tft.setCursor(57,51);
tft.print(dutyCyclePercent);
tft.print("%");
}
if(dutyCyclePercent >= 100){
tft.setTextSize(2);
tft.setCursor(57,51);
tft.print("MAX");
}
if(dutyCyclePercent <= 0){
tft.setTextSize(2);
tft.setCursor(57,51);
tft.print("MIN");
}
}
void loop()
{
tft.setTextColor(ILI9341_WHITE);
if(lockout == false){
screendim();
readbattery();
firecheck();
updowncheck();
} else {
screendim();
readbattery();
lockedMode();
}
if(undervoltagelockout == true){
uvlocheck();
screendim();
} else {
undervoltagelockout = false;
}
if(dutyCyclePercent != lastDutyCyclePercent){
dutyCycleOutput = map(dutyCyclePercent,0,100,0,255);
tft.fillRoundRect(36,33,76,54,8, ILI9341_BLACK);
if(dutyCyclePercent>0 && dutyCyclePercent <10){
tft.setTextSize(2);
tft.setCursor(64,51);
tft.print(dutyCyclePercent);
tft.print("%");
}
if(dutyCyclePercent>=10 && dutyCyclePercent <100){
tft.setTextSize(2);
tft.setCursor(57,51);
tft.print(dutyCyclePercent);
tft.print("%");
}
if(dutyCyclePercent >= 100){
tft.setTextSize(2);
tft.setCursor(57,51);
tft.print("MAX");
}
if(dutyCyclePercent <= 0){
tft.setTextSize(2);
tft.setCursor(57,51);
tft.print("MIN");
}
}
lastDutyCyclePercent = dutyCyclePercent;
tft.setTextSize(1);
tft.setCursor(7,143);
tft.print(voltage * 11.132);
if(lockout != lastLockoutState){
while (sample_count < NUM_SAMPLES) {
sum += analogRead(voltageDividerPin);
sample_count++;
delay(10);
}
voltage = ((float)sum / (float)NUM_SAMPLES * 5.015) / 1024.0;
sample_count = 0;
sum = 0;
voltageTimer = millis();
tft.fillRoundRect(17, 33, 8, 106, 3,ILI9341_BLACK);
tft.fillRect(7,143,30,10,ILI9341_BLACK);
if((voltage * 11.132) >= 11.4){
tft.fillRoundRect(17, 33, 8, 106, 3, ILI9341_GREEN);
}
if((voltage * 11.132) >= 10.8 && (voltage * 11.132) < 11.4){
tft.fillRoundRect(17, 60, 8, 79, 3, ILI9341_GREEN);
}
if((voltage * 11.132) >= 10.2 && (voltage * 11.132) < 10.8){
tft.fillRoundRect(17, 87, 8, 52, 3, ILI9341_GREEN);
}
if((voltage * 11.132) >= 9.8 && (voltage * 11.132) < 10.2){
tft.fillRoundRect(17, 114, 8, 25, 3, ILI9341_YELLOW);
}
if((voltage * 11.132) <= 0 && (voltage * 11.132) < 9.8){
tft.fillRoundRect(17, 136, 8, 3, 3, ILI9341_RED);
}
if(lockout == false){
tft.fillRoundRect(36,33,76,54,8, ILI9341_BLACK);
if(dutyCyclePercent>0 && dutyCyclePercent <10){
tft.setTextSize(2);
tft.setCursor(64,51);
tft.print(dutyCyclePercent);
tft.print("%");
}
if(dutyCyclePercent>=10 && dutyCyclePercent <100){
tft.setTextSize(2);
tft.setCursor(57,51);
tft.print(dutyCyclePercent);
tft.print("%");
}
if(dutyCyclePercent >= 100){
tft.setTextSize(2);
tft.setCursor(57,51);
tft.print("MAX");
}
if(dutyCyclePercent <= 0){
tft.setTextSize(2);
tft.setCursor(57,51);
tft.print("MIN");
}
}
}
lastFireButtonState = fireButtonState;
lastUpButtonState = upButtonState;
lastDownButtonState = downButtonState;
lastLockoutState = lockout;
}
void firecheck()
{ //Fire Button Workings
fireButtonState = digitalRead(fireButtonPin);
if(fireButtonState == LOW){
dutyCycleOutput = map(dutyCyclePercent,0,100,0,255);
analogWrite(gatePin, dutyCycleOutput);
screenDimTimer = millis();
if (fireButtonState != lastFireButtonState){
delay(50);
if(screenDimBool == true){
screenDimBool = false;
}
tft.fillRoundRect(17, 33, 8, 106, 3, ILI9341_YELLOW);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(1);
tft.setCursor( 19, 56 );
tft.print("L");
tft.setCursor( 19, 66 );
tft.print("O");
tft.setCursor( 19, 76 );
tft.print("A");
tft.setCursor( 19, 86 );
tft.print("D");
tft.setCursor( 19, 96 );
tft.print("E");
tft.setCursor( 19, 106);
tft.print("D");
tft.setTextColor(ILI9341_WHITE);
fireButtonTimer = millis();
ampTimer = millis();
if (millis()-lockDelayTimer >= 500){
fireButtonPushCounter = 1;
}
if (millis()-lockDelayTimer < 500){
fireButtonPushCounter += 1;
}
tft.fillRoundRect(36,33,76,54,8, ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(52,51);
tft.print("FIRE");
}
if (millis()-ampTimer>=300){
ampVal = analogRead(ammeterPin) - 220;
ammeterPrint = (ampVal / GAUSS_PER_STEP)*(-1);
tft.fillRect(81,124,25,10, ILI9341_BLACK);
tft.setTextSize(1);
tft.setCursor(81,124);
tft.print(ammeterPrint,1);
wattVal = ammeterPrint * (voltage*11.132);
tft.fillRect(81,114,25,10, ILI9341_BLACK);
tft.setCursor(81,114);
tft.print(wattVal);
resistance = (voltage * 11.132)/ammeterPrint;
tft.fillRect(81,104,25,10, ILI9341_BLACK);
tft.setCursor(81, 104);
tft.print(resistance,1);
// rmsVal =
ampTimer=millis();
}
if (fireButtonPushCounter % 5 == 0 || millis()-fireButtonTimer >= 9950){
analogWrite(gatePin, 0);
screenDimTimer = millis();
if (fireButtonPushCounter % 5 == 0){
fireButtonPushCounter = 0;
}
if (millis()-fireButtonTimer >= 9950){
tft.fillRoundRect(36,33,76,54,8, ILI9341_BLACK);
tft.setTextSize(1);
tft.setCursor(49,41);
tft.print("Auto-Fire");
tft.setCursor(54,61);
tft.print("Timeout");
fireButtonTimer = 0;
delay(2000);
}
tft.fillRoundRect(36,33,76,54,8, ILI9341_BLACK);
tft.setTextSize(1);
tft.fillRoundRect(36,33,76,54,8, ILI9341_BLACK);
tft.setCursor(56,53);
tft.print("LOCKED");
delay(50);
lockout = true;
lockedMode();
}else{
lockout = false;
}
} else {
analogWrite(gatePin, 0);
if (fireButtonState != lastFireButtonState){
delay(50);
lockDelayTimer = millis();
screenDimTimer = millis();
ampTimer = 0;
tft.fillRoundRect(36,33,76,54,8, ILI9341_BLACK);
if(dutyCyclePercent>0 && dutyCyclePercent <10){
tft.setTextSize(2);
tft.setCursor(64,51);
tft.print(dutyCyclePercent);
tft.print("%");
}
if(dutyCyclePercent>=10 && dutyCyclePercent <100){
tft.setTextSize(2);
tft.setCursor(57,51);
tft.print(dutyCyclePercent);
tft.print("%");
}
if(dutyCyclePercent >= 100){
tft.setTextSize(2);
tft.setCursor(57,51);
tft.print("MAX");
}
if(dutyCyclePercent <= 0){
tft.setTextSize(2);
tft.setCursor(57,51);
tft.print("MIN");
}
}
}
// lastFireButtonState = fireButtonState;
}
void updowncheck() //Up/Down buttons workingzz
{
upButtonState = digitalRead(upButtonPin);
downButtonState = digitalRead(downButtonPin);
if (upButtonState == LOW && downButtonState == HIGH){
screenDimTimer=millis();
if (upButtonState != lastUpButtonState){
upDownButtonTimer = millis();
if(screenDimBool == true){
screenDimBool = false;
}
}
if(millis()-upDownButtonTimer < 2200){
dutyCyclePercent +=1;
delay(200);
}
if(millis()-upDownButtonTimer >= 2200){
dutyCyclePercent +=1;
delay(75);
}
if(millis()-upDownButtonTimer >= 5200){
dutyCyclePercent +=2;
delay(50);
}
}
if (downButtonState == LOW && upButtonState == HIGH){
screenDimTimer=millis();
if(downButtonState != lastDownButtonState){
upDownButtonTimer = millis();
if(screenDimBool == true){
screenDimBool = false;
}
}
if(millis()-upDownButtonTimer < 2200){
dutyCyclePercent -=1;
delay(200);
}
if(millis()-upDownButtonTimer >=2200){
dutyCyclePercent -=1;
delay(75);
}
if(millis()-upDownButtonTimer >=5200){
dutyCyclePercent -=2;
delay(50);
}
}
if (upButtonState == LOW && downButtonState == LOW){
upDownButtonTimer = 0;
dutyCyclePercent = dutyCyclePercent;
screenDimTimer = millis();
}
if (upButtonState == HIGH && downButtonState == HIGH){
upDownButtonTimer = 0;
if(downButtonState != lastDownButtonState || upButtonState != lastUpButtonState){
screenDimTimer = millis();
}
}
if (dutyCyclePercent >= 100){
dutyCyclePercent = 100;
}
if (dutyCyclePercent <= 0){
dutyCyclePercent = 0;
}
// lastUpButtonState = upButtonState;
// lastDownButtonState = downButtonState;
}
void readbattery()
{
if(fireButtonState == HIGH){
if((millis()-voltageTimer)/1000 == 5){
// take a number of analog samples and add them up
while (sample_count < NUM_SAMPLES) {
sum += analogRead(voltageDividerPin);
sample_count++;
delay(10);
}
// calculate the voltage
// use 5.0 for a 5.0V ADC reference voltage
// 5.015V is the calibrated reference voltage
// send voltage for display on Serial Monitor
// voltage multiplied by 11 when using voltage divider that
// divides by 11. 11.132 is the calibrated voltage divide
// value
voltage = ((float)sum / (float)NUM_SAMPLES * 5.015) / 1024.0;
sample_count = 0;
sum = 0;
voltageTimer = millis();
tft.fillRect(7,143,30,10,ILI9341_BLACK);
tft.fillRoundRect(17, 33, 8, 106, 3, ILI9341_BLACK);
if((voltage * 11.132) >= 11.4){
tft.fillRoundRect(17, 33, 8, 106, 3, ILI9341_GREEN);
}
if((voltage * 11.132) >= 10.8 && (voltage * 11.132) < 11.4){
tft.fillRoundRect(17, 60, 8, 79, 3, ILI9341_GREEN);
}
if((voltage * 11.132) >= 10.2 && (voltage * 11.132) < 10.8){
tft.fillRoundRect(17, 87, 8, 52, 3, ILI9341_GREEN);
}
if((voltage * 11.132) >= 9.8 && (voltage * 11.132) < 10.2){
tft.fillRoundRect(17, 114, 8, 25, 3, ILI9341_YELLOW);
}
if((voltage * 11.132) <= 0 && (voltage * 11.132) < 9.8){
tft.fillRoundRect(17, 136, 8, 3, 3, ILI9341_RED);
}
if((voltage * 11.132) < 9.6){
undervoltagelockout = true;
}
}
}else{
if(lockout==false){
undervoltagelockout = false;
if(millis()-voltageTimer >= 300){
while (sample_count < NUM_SAMPLES) {
sum += analogRead(voltageDividerPin);
sample_count++;
delay(10);
}
voltage = ((float)sum / (float)NUM_SAMPLES * 5.015) / 1024.0;
sample_count = 0;
sum = 0;
voltageTimer = millis();
tft.fillRect(7,143,30,10,ILI9341_BLACK);
}
}
}
}
void lockedMode()
{
analogWrite(gatePin, 0);
fireButtonState = digitalRead(fireButtonPin);
if(fireButtonState == LOW){
screenDimTimer=millis();
if(fireButtonState != lastFireButtonState){
delay(50);
if(screenDimBool == true){
screenDimBool = false;
}
if (millis()-lockDelayTimer >= 1000){
fireButtonPushCounter = 1;
}
if(millis()-lockDelayTimer < 1000){
fireButtonPushCounter += 1;
}
tft.fillRoundRect(36,33,76,54,8, ILI9341_BLACK);
tft.setTextSize(1);
tft.setCursor(56,53);
tft.print("UNLOCK");
}else{
lockout = true;
}
if (fireButtonPushCounter % 5 == 0)
{ //unlock after 5 button presses
tft.fillRoundRect(36,33,76,54,8, ILI9341_BLACK);
tft.setTextSize(1);
tft.setCursor(50,53);
tft.print("UNLOCKED");
fireButtonPushCounter = 0;
lockout = false;
delay(1000);
}else{
lockout = true;
}
} else {
analogWrite(gatePin, 0);
if(fireButtonState != lastFireButtonState){
delay(50);
screenDimTimer=millis();
lockDelayTimer = millis();
tft.setTextSize(1);
tft.fillRoundRect(36,33,76,54,8, ILI9341_BLACK);
tft.setCursor(56,53);
tft.print("LOCKED");
}
}
// lastFireButtonState = fireButtonState;
}
void uvlocheck()
{
tft.fillRoundRect(36,33,76,54,8, ILI9341_BLACK);
analogWrite(gatePin, 0);
tft.setTextSize(1);
tft.setCursor(56,53);
tft.print("CHARGE");
tft.setCursor(48,63);
tft.print("BATTERIES");
tft.setTextSize(1);
tft.setCursor(41,83);
tft.print("Undervoltage");
tft.setCursor(53,93);
tft.print("Lockout");
tft.fillRoundRect(36,33,76,54,8, ILI9341_BLACK);
}
void screendim()
{
if(screenDimBool == false){
while(screenDimIncrement < 255){
screenDimIncrement += 17;
analogWrite(screenPin, screenDimIncrement);
delay(10);
}
if((millis()-screenDimTimer)/1000 >= 10){
while(screenDimIncrement > 0){
screenDimIncrement -= 17;
analogWrite(screenPin, screenDimIncrement);
delay(10);
}
if(screenDimIncrement == 0){
screenDimBool = true;
}
}
}else{
screenDimBool = true;
}
}