Project tutorial

Jumbo Vaping Mod © GPL3+

Custom 6V battery powered RDA Electronic Cigarette for Thick Cloud Chasing

  • 1,078 views
  • 0 comments
  • 2 respects

Components and supplies

Necessary tools and machines

09507 01
Soldering iron (generic)
Hy gluegun
Hot glue gun (generic)

Apps and online services

About this project

About

Electronics Cigarette (aka Vape) is one of the fastest growing and controversial consumer product of these days. I was into smoking for about last 10 years and decided to try out vaping. Now I am smoking free for few weeks and feeling better. Bought some devices from local stores but I was not satisfied with the performance and decided to make my own Mod (E-Cig Electronics+Battery is called Mod). This is how this project started - personal, open source, powerful and re-programmable Jumbo size Mod.

Vaping in Action

Vaping !

Display Parameters

Technical Specification / Features

  • 6 Volt 7500 mAh System with Sealed Lead Acid Battery
  • Max 120 Watt Power Output
  • PWM Power Control, Maximum Voltage Sag 15% of Nominal Voltage
  • Supported Atomizer : 0.2 - 2.0 Ohms
  • Brick Build and Weight about 3 Pounds
  • Charging Range 9-35 V DC.
  • Charging Option : Car Charging/Solar Charging/ Laptop Power Supply Charging
  • Keypad for Direct Power Input,
  • Voltage, Current, Power Sensing
  • Firmware Upgrade-able for more Features !

Building the Device

By connecting, soldering and gluing following parts with soldering iron and hot glue, all the pieces are put together to realize the mod.

The Mod is build around arduino pro mini. At first it was neat when I started like this

Things got ugly with interconnections and somehow ended up like this -

Hardware Explained

The Casing is a Walabot spare casing. On the front side I installed the OLED display and the keypad with hot glue. A 510 tank holder is attached on top and electronics are placed inside of the casing. Using a pair of plastic hinge, the casing is attached with the 6v battery.

Charging is done with LM2596 module which can receive any voltage 9 to 35 volts DC from Car battery, Laptop Power Supply or Solar Panel and charge up the 6 volt battery.

The CPU/MCU is the Arduino pro mini which monitors charging, battery voltage, driving the display, user input from keypad, current sensing to atomizer, atomizer driving with gate pulse to Mosfet etc.

The coil drive and sensing block has a low Rds logic level MOSFET to regulate the power to the atomizer coil, ACS712 current sensor to measure current, a voltage divider to measure voltage and send these information to MCU.

Programming port allows upload of firmware to the MCU through serial port

Conclusion

Vaping may not be healthier but it is definitely better alternative of smoking. Some of the health risk of vaping may be COPD ( breathing problem due to narrowed airway ) , risk of high BP and heart problem if vaped too much (say 30 ml 12 mg per day) with high level of Nicotine. After all, drinking 20 liters of water of eating 10 kg vegetables at once is not healthy either.

From my personal experience, it is definitely a better alternative and cool thing to do. It feels better after switching to vaping ! If you are a smoker then try building your vape and stop smoking.

Code

C code for the ModC/C++
ver 0.0..1 (Beta)
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(A0, A1, 12, 11,13); 
 
///////////////////////////////////////

#define MENU_ITEMS 5
const char *menu_strings[MENU_ITEMS] = { "Quick VAPING", "Advance VAPING", "Settings", "APPs & Games","LOCK Device" };

#define KEY_NONE 0
#define KEY_PREV 1
#define KEY_NEXT 2
#define KEY_SELECT 3
#define KEY_BACK 4

uint8_t uiKeyPrev = 2;
uint8_t uiKeyNext = 3;
uint8_t uiKeySelect = 4;
uint8_t uiKeyBack = 5;

uint8_t uiKeyCodeFirst = KEY_NONE;
uint8_t uiKeyCodeSecond = KEY_NONE;
uint8_t uiKeyCode = KEY_NONE;


uint8_t menu_current = 0;
uint8_t menu_redraw_required = 0;
uint8_t last_key_code = KEY_NONE;


float V=0.0;
float I=0.0;
float P=0.0;
uint8_t D= 50; // 0-100 drive stregth pwm

const uint8_t mv_logo[] PROGMEM = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFE,
0x01, 0x80, 0x7F, 0xFF, 0xFF, 0xF8, 0x3E, 0x78, 0x1F, 0xFF, 0xFF, 0xF1, 0xFF, 0x37, 0x0F, 0xFF,
0xFF, 0xC3, 0xFF, 0x8F, 0xC7, 0xFF, 0xFF, 0x8F, 0xFF, 0x0F, 0xF3, 0xFF, 0xFF, 0x1F, 0xFC, 0x27,
0xF9, 0xFF, 0xFE, 0x3F, 0xF8, 0x73, 0xFC, 0xFF, 0xFE, 0x7F, 0xE0, 0xF9, 0xFE, 0x7F, 0xFC, 0xFF,
0xC7, 0xFC, 0xFE, 0x3F, 0xF8, 0xFF, 0x8F, 0xFE, 0x7F, 0x3F, 0xF9, 0xFE, 0x1F, 0xFF, 0x63, 0x9F,
0xF9, 0xFC, 0x3F, 0xFF, 0x01, 0x9F, 0xF3, 0xF8, 0x7F, 0xFF, 0xFC, 0xCF, 0xF3, 0xE1, 0xFF, 0xFF,
0xFE, 0x4F, 0xF3, 0xC3, 0xFF, 0xFF, 0xFF, 0x0F, 0xE7, 0x87, 0xFF, 0xFF, 0xFF, 0x8F, 0xE7, 0x0F,
0xFF, 0xFF, 0xFF, 0xCF, 0xE6, 0x13, 0xFF, 0x0F, 0xF3, 0xE7, 0xE4, 0x13, 0xFE, 0x0F, 0xF3, 0xE3,
0xE0, 0x31, 0xFE, 0x0F, 0xE7, 0xE3, 0xE0, 0x71, 0xFC, 0x27, 0xE7, 0xE7, 0xC1, 0xF5, 0xFC, 0x27,
0xEF, 0xEF, 0xC3, 0xF4, 0xFD, 0x27, 0xCF, 0xCF, 0xE3, 0xF4, 0xF9, 0x33, 0xCF, 0xCF, 0xF3, 0xF6,
0x79, 0x33, 0xDF, 0xCF, 0xF3, 0xF6, 0x73, 0x33, 0x9F, 0xCF, 0xF9, 0xF7, 0x33, 0x39, 0x9F, 0x9F,
0xF9, 0xF7, 0x27, 0x39, 0x3F, 0x9F, 0xFC, 0xF7, 0x27, 0x3D, 0x3F, 0x3F, 0xFC, 0xF7, 0x8F, 0x3C,
0x7E, 0x3F, 0xFE, 0x77, 0x8F, 0x3C, 0x7E, 0x7F, 0xFF, 0x37, 0xCF, 0x3E, 0x7C, 0xFF, 0xFF, 0x1F,
0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF,
0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF8, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF

};


const uint8_t ryan_logo[] PROGMEM = {
0x0C, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x37, 0x80,
0x00, 0x88, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x60, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x70, 0x81, 0xFF,
0xFF, 0xF0, 0x00, 0x20, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x10, 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
0x07, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF,
0xC0, 0x26, 0x0F, 0xFF, 0xFF, 0xFF, 0xF0, 0x27, 0x0F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x1F, 0xFF,
0xFF, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x1F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x20, 0x3F, 0xFF, 0xFF, 0xC0,
0x00, 0x20, 0x7F, 0xE0, 0x02, 0x00, 0x00, 0x10, 0x6E, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00,
0x02, 0x00, 0x00, 0x00, 0x04, 0x72, 0x00, 0x00, 0x00, 0x60, 0x00, 0xBC, 0x01, 0x80, 0x00, 0x60,
0x00, 0xB0, 0x01, 0x80, 0x00, 0x60, 0x06, 0xD0, 0x01, 0xC0, 0x00, 0xF0, 0x4F, 0x58, 0x03, 0xE0,
0x00, 0xF0, 0xDF, 0x58, 0x03, 0xE0, 0x01, 0xF0, 0xFF, 0x10, 0x07, 0xE0, 0x03, 0xF0, 0xFF, 0x80,
0x0F, 0xE3, 0xFF, 0xF0, 0xFF, 0xC0, 0x1F, 0xF9, 0xFF, 0x30, 0xFF, 0xFF, 0xFF, 0xE4, 0xFF, 0x30,
0xFF, 0xFF, 0xFF, 0xE0, 0xFE, 0x20, 0xFF, 0xFF, 0xFD, 0xC0, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xF0,
0x3E, 0x08, 0xFF, 0xFF, 0xFD, 0xF4, 0x0C, 0x08, 0xFF, 0xFF, 0xF9, 0x7C, 0x04, 0x0F, 0xFF, 0xFF,
0xFB, 0xF0, 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xC0, 0x60, 0x0F, 0xFF, 0xFF, 0x77, 0xFE, 0x20, 0x0F,
0xFF, 0xFF, 0x8F, 0xFC, 0x70, 0x0F, 0xFF, 0xFF, 0x87, 0xF0, 0x70, 0x0F, 0xFF, 0xFF, 0xFE, 0x18,
0x70, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x40, 0x1F, 0xFF, 0xFF,
0xFF, 0xFE, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFF, 0xBF, 0xC1, 0x80, 0x7F,
0xFF, 0xFC, 0x3F, 0xC0, 0x00, 0x7F, 0xFF, 0xC1, 0x0F, 0xC0, 0x00, 0xFF, 0xFF, 0x60, 0x0F, 0x00,
0x00, 0xFF, 0xFF, 0x60, 0x07, 0x80, 0x01, 0xFF, 0xFF, 0x30, 0x02, 0x80, 0x01, 0xFF, 0xFF, 0x30,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1C, 0x00, 0x00, 0x04, 0x7F, 0xFF, 0x0F, 0x00, 0x00, 0x04, 0x3F
  
};




void setup() {
  // rotate screen, if required
  u8g.setRot180();
  drawInit();
  delay(3000);
   drawLogo();
  delay(3000);
//  u8g.clearDisplay();
  
  uiSetup();                                // setup key detection and debounce algorithm
  menu_redraw_required = 1;     // force initial redraw

 
}

void loop() {  
   while(1)
              {
                  for(int i=0;i<4;i++)
                  {
                analogWrite(10,D*2.5);
                calculate();   
                drawInfo();
                delay(900);
                  }

                  for(int i=0;i<7;i++)
                  {
                analogWrite(10,0);
                calculate();   
                drawInfo();
                delay(900);
                  }
                  
               }


  uiStep();                                     // check for key press
    
  if (  menu_redraw_required != 0 ) {
    u8g.firstPage();
    do  {
      drawMenu();
    } while( u8g.nextPage() );
    menu_redraw_required = 0;
  }

  updateMenu();                            // update menu bar
  
  
}




void uiSetup(void) {
  // configure input keys 
  
  pinMode(uiKeyPrev, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeyNext, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeySelect, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeyBack, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(6, OUTPUT);           // set pin to input with pullup
  pinMode(7, OUTPUT);           // set pin to input with pullup
  pinMode(8, OUTPUT);           // set pin to input with pullup
  pinMode(9, OUTPUT);           // set pin to input with pullup
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);

  
}

void uiStep(void) {
  uiKeyCodeSecond = uiKeyCodeFirst;
  if ( digitalRead(uiKeyPrev) == LOW )
    uiKeyCodeFirst = KEY_PREV;
  else if ( digitalRead(uiKeyNext) == LOW )
    uiKeyCodeFirst = KEY_NEXT;
  else if ( digitalRead(uiKeySelect) == LOW )
    uiKeyCodeFirst = KEY_SELECT;
  else if ( digitalRead(uiKeyBack) == LOW )
    uiKeyCodeFirst = KEY_BACK;
  else 
    uiKeyCodeFirst = KEY_NONE;
  
  if ( uiKeyCodeSecond == uiKeyCodeFirst )
    uiKeyCode = uiKeyCodeFirst;
  else
    uiKeyCode = KEY_NONE;
}


void drawInit (void)
{
    u8g.firstPage();  
  do {
u8g.drawBitmapP( 40, 0, 6, 48, mv_logo);
u8g.setFont(u8g_font_8x13);
u8g.setFont(u8g_font_8x13);
u8g.drawStr( 4,64, "Mountain Vapers");

  } while( u8g.nextPage() );

  
  
}

void drawLogo (void)
{
    u8g.firstPage();  
  do {
u8g.drawBitmapP( 40, 0, 6, 56, ryan_logo);
u8g.setFont(u8g_font_5x8);
u8g.drawStr( 0,64, "CLOUD CHASING WEATHER MAN");

  } while( u8g.nextPage() );

  
  
}




void drawMenu(void) {
  uint8_t i, h;
  u8g_uint_t w, d;

  u8g.setFont(u8g_font_6x13);
  u8g.setFontRefHeightText();
  u8g.setFontPosTop();
  
  h = u8g.getFontAscent()-u8g.getFontDescent();
  w = u8g.getWidth();
  for( i = 0; i < MENU_ITEMS; i++ ) {
    d = (w-u8g.getStrWidth(menu_strings[i]))/2;
    u8g.setDefaultForegroundColor();
    if ( i == menu_current && i<=3) {
      u8g.drawBox(0, i*h+1+3, w, h);
      u8g.setDefaultBackgroundColor();
    }
    if ( i == menu_current && i==4) {
      u8g.drawBox(0, i*h+1+10, w, h);
      u8g.setDefaultBackgroundColor();
    }
    
    if (i<=3)
    {u8g.drawStr(d, i*h+4, menu_strings[i]);}
    if (i==4)
    u8g.drawStr(d, i*h+10, menu_strings[i]);
  }
}

void updateMenu(void) {
  if ( uiKeyCode != KEY_NONE && last_key_code == uiKeyCode ) {
    return;
  }
  last_key_code = uiKeyCode;
  
  switch ( uiKeyCode ) {
    case KEY_NEXT:
      menu_current++;
      if ( menu_current >= MENU_ITEMS )
        menu_current = 0;
      menu_redraw_required = 1;
      break;
    case KEY_PREV:
      if ( menu_current == 0 )
        menu_current = MENU_ITEMS;
      menu_current--;
      menu_redraw_required = 1;
      break;
  }
}

/// this subroutine updates v, i , p on screen
void drawInfo (void)
{
    u8g.firstPage();  
  do {
u8g.setFont(u8g_font_8x13);
u8g.drawStr( 4,14, "V = ");u8g.setPrintPos(30, 14);u8g.print(V);u8g.drawStr( 80, 14, "Volts");
u8g.drawStr( 4,26, "I = ");u8g.setPrintPos(30, 26);u8g.print(I);u8g.drawStr( 80, 26, "Amps ");
u8g.drawStr( 4,38, "P = ");u8g.setPrintPos(30, 38);u8g.print(P);u8g.drawStr( 80, 38, "Watts");


  } while( u8g.nextPage() );

  
  
}


void calculate(void)
{
     V = 0.0; I = 0.0; P = 0.0;
      for(int i=0;i<20;i++)
     {            
     V = V + (2*(101.7/101.8)*5.0*analogRead(A2)/1023);
     I = I+((5.0*analogRead(A3)/1023)-2.5)/0.066;                 
     delay(5);
     }

     V=V/20.0; I = -I/20.0;  P = (D*2.5*V/255.0)*I;

     
}            
C code for the Mod v2C/C++
Charging Detection, Atomizer Detection and Coil Resistance measurement added
Short Circuit protection implemented
#include "U8glib.h"

 
U8GLIB_SSD1306_128X64 u8g(A0, A1, 12, 11,13); 



///////////////////////////////////////

#define MENU_ITEMS 5
const char *menu_strings[MENU_ITEMS] = { "Quick VAPING", "Advance VAPING", "Settings", "APPs & Games","LOCK Device" };

#define KEY_NONE 0
#define KEY_PREV 1
#define KEY_NEXT 2
#define KEY_SELECT 3
#define KEY_BACK 4

uint8_t uiKeyPrev = 2;
uint8_t uiKeyNext = 3;
uint8_t uiKeySelect = 4;
uint8_t uiKeyBack = 5;

uint8_t uiKeyCodeFirst = KEY_NONE;
uint8_t uiKeyCodeSecond = KEY_NONE;
uint8_t uiKeyCode = KEY_NONE;


uint8_t menu_current = 0;
uint8_t menu_redraw_required = 0;
uint8_t last_key_code = KEY_NONE;


float V=0.0;
float I=0.0;
float P=0.0;
float R=0.0;
uint8_t D= 40; // 0-100 drive stregth pwm

const uint8_t mv_logo[] PROGMEM = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFE,
0x01, 0x80, 0x7F, 0xFF, 0xFF, 0xF8, 0x3E, 0x78, 0x1F, 0xFF, 0xFF, 0xF1, 0xFF, 0x37, 0x0F, 0xFF,
0xFF, 0xC3, 0xFF, 0x8F, 0xC7, 0xFF, 0xFF, 0x8F, 0xFF, 0x0F, 0xF3, 0xFF, 0xFF, 0x1F, 0xFC, 0x27,
0xF9, 0xFF, 0xFE, 0x3F, 0xF8, 0x73, 0xFC, 0xFF, 0xFE, 0x7F, 0xE0, 0xF9, 0xFE, 0x7F, 0xFC, 0xFF,
0xC7, 0xFC, 0xFE, 0x3F, 0xF8, 0xFF, 0x8F, 0xFE, 0x7F, 0x3F, 0xF9, 0xFE, 0x1F, 0xFF, 0x63, 0x9F,
0xF9, 0xFC, 0x3F, 0xFF, 0x01, 0x9F, 0xF3, 0xF8, 0x7F, 0xFF, 0xFC, 0xCF, 0xF3, 0xE1, 0xFF, 0xFF,
0xFE, 0x4F, 0xF3, 0xC3, 0xFF, 0xFF, 0xFF, 0x0F, 0xE7, 0x87, 0xFF, 0xFF, 0xFF, 0x8F, 0xE7, 0x0F,
0xFF, 0xFF, 0xFF, 0xCF, 0xE6, 0x13, 0xFF, 0x0F, 0xF3, 0xE7, 0xE4, 0x13, 0xFE, 0x0F, 0xF3, 0xE3,
0xE0, 0x31, 0xFE, 0x0F, 0xE7, 0xE3, 0xE0, 0x71, 0xFC, 0x27, 0xE7, 0xE7, 0xC1, 0xF5, 0xFC, 0x27,
0xEF, 0xEF, 0xC3, 0xF4, 0xFD, 0x27, 0xCF, 0xCF, 0xE3, 0xF4, 0xF9, 0x33, 0xCF, 0xCF, 0xF3, 0xF6,
0x79, 0x33, 0xDF, 0xCF, 0xF3, 0xF6, 0x73, 0x33, 0x9F, 0xCF, 0xF9, 0xF7, 0x33, 0x39, 0x9F, 0x9F,
0xF9, 0xF7, 0x27, 0x39, 0x3F, 0x9F, 0xFC, 0xF7, 0x27, 0x3D, 0x3F, 0x3F, 0xFC, 0xF7, 0x8F, 0x3C,
0x7E, 0x3F, 0xFE, 0x77, 0x8F, 0x3C, 0x7E, 0x7F, 0xFF, 0x37, 0xCF, 0x3E, 0x7C, 0xFF, 0xFF, 0x1F,
0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF,
0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF8, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF

};


const uint8_t ryan_logo[] PROGMEM = {
0x0C, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x37, 0x80,
0x00, 0x88, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x60, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x70, 0x81, 0xFF,
0xFF, 0xF0, 0x00, 0x20, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x10, 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
0x07, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF,
0xC0, 0x26, 0x0F, 0xFF, 0xFF, 0xFF, 0xF0, 0x27, 0x0F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x1F, 0xFF,
0xFF, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x1F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x20, 0x3F, 0xFF, 0xFF, 0xC0,
0x00, 0x20, 0x7F, 0xE0, 0x02, 0x00, 0x00, 0x10, 0x6E, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00,
0x02, 0x00, 0x00, 0x00, 0x04, 0x72, 0x00, 0x00, 0x00, 0x60, 0x00, 0xBC, 0x01, 0x80, 0x00, 0x60,
0x00, 0xB0, 0x01, 0x80, 0x00, 0x60, 0x06, 0xD0, 0x01, 0xC0, 0x00, 0xF0, 0x4F, 0x58, 0x03, 0xE0,
0x00, 0xF0, 0xDF, 0x58, 0x03, 0xE0, 0x01, 0xF0, 0xFF, 0x10, 0x07, 0xE0, 0x03, 0xF0, 0xFF, 0x80,
0x0F, 0xE3, 0xFF, 0xF0, 0xFF, 0xC0, 0x1F, 0xF9, 0xFF, 0x30, 0xFF, 0xFF, 0xFF, 0xE4, 0xFF, 0x30,
0xFF, 0xFF, 0xFF, 0xE0, 0xFE, 0x20, 0xFF, 0xFF, 0xFD, 0xC0, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xF0,
0x3E, 0x08, 0xFF, 0xFF, 0xFD, 0xF4, 0x0C, 0x08, 0xFF, 0xFF, 0xF9, 0x7C, 0x04, 0x0F, 0xFF, 0xFF,
0xFB, 0xF0, 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xC0, 0x60, 0x0F, 0xFF, 0xFF, 0x77, 0xFE, 0x20, 0x0F,
0xFF, 0xFF, 0x8F, 0xFC, 0x70, 0x0F, 0xFF, 0xFF, 0x87, 0xF0, 0x70, 0x0F, 0xFF, 0xFF, 0xFE, 0x18,
0x70, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x40, 0x1F, 0xFF, 0xFF,
0xFF, 0xFE, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFF, 0xBF, 0xC1, 0x80, 0x7F,
0xFF, 0xFC, 0x3F, 0xC0, 0x00, 0x7F, 0xFF, 0xC1, 0x0F, 0xC0, 0x00, 0xFF, 0xFF, 0x60, 0x0F, 0x00,
0x00, 0xFF, 0xFF, 0x60, 0x07, 0x80, 0x01, 0xFF, 0xFF, 0x30, 0x02, 0x80, 0x01, 0xFF, 0xFF, 0x30,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1C, 0x00, 0x00, 0x04, 0x7F, 0xFF, 0x0F, 0x00, 0x00, 0x04, 0x3F
  
};




void setup() {
  // rotate screen, if required
  u8g.setRot180();
  drawInit();
  delay(1500);
   drawLogo();
  delay(1500);
//  u8g.clearDisplay();
  
  uiSetup();                                // setup key detection and debounce algorithm
  menu_redraw_required = 1;     // force initial redraw

 
}

void loop() {  
   
   //////////////////////////////////////////////////////
   while(1)
              {
                  for(int i=0;i<10;i++) // higher i value longer on time
                  {
                analogWrite(10,D*2.5); // higher D value more Vape
                calculate();  
                short_ckt_check(); 
                drawInfo();
                delay(250);
                  }

                  for(int i=0;i<30;i++)
                  {
                analogWrite(10,0);
                calculate();   
                short_ckt_check(); 
                drawInfo();
                delay(250);
                  }
                  
               }
//////////////////////////////////////////////////////////////

  uiStep();                                     // check for key press
    
  if (  menu_redraw_required != 0 ) {
    u8g.firstPage();
    do  {
      drawMenu();
    } while( u8g.nextPage() );
    menu_redraw_required = 0;
  }

  updateMenu();                            // update menu bar
  
  
}




void uiSetup(void) {
  // configure input keys 
  
  pinMode(uiKeyPrev, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeyNext, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeySelect, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeyBack, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(6, OUTPUT);           // set pin to input with pullup
  pinMode(7, OUTPUT);           // set pin to input with pullup
  pinMode(8, OUTPUT);           // set pin to input with pullup
  pinMode(9, OUTPUT);           // set pin to input with pullup
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);

  
}

void uiStep(void) {
  uiKeyCodeSecond = uiKeyCodeFirst;
  if ( digitalRead(uiKeyPrev) == LOW )
    uiKeyCodeFirst = KEY_PREV;
  else if ( digitalRead(uiKeyNext) == LOW )
    uiKeyCodeFirst = KEY_NEXT;
  else if ( digitalRead(uiKeySelect) == LOW )
    uiKeyCodeFirst = KEY_SELECT;
  else if ( digitalRead(uiKeyBack) == LOW )
    uiKeyCodeFirst = KEY_BACK;
  else 
    uiKeyCodeFirst = KEY_NONE;
  
  if ( uiKeyCodeSecond == uiKeyCodeFirst )
    uiKeyCode = uiKeyCodeFirst;
  else
    uiKeyCode = KEY_NONE;
}


void drawInit (void)
{
    u8g.firstPage();  
  do {
u8g.drawBitmapP( 40, 0, 6, 48, mv_logo);
u8g.setFont(u8g_font_8x13);
u8g.setFont(u8g_font_8x13);
u8g.drawStr( 4,64, "Mountain Vapers");

  } while( u8g.nextPage() );

  
  
}

void drawLogo (void)
{
    u8g.firstPage();  
  do {
u8g.drawBitmapP( 40, 0, 6, 56, ryan_logo);
u8g.setFont(u8g_font_5x8);
u8g.drawStr( 0,64, "CLOUD CHASING WEATHER MAN");

  } while( u8g.nextPage() );

  
  
}




void drawMenu(void) {
  uint8_t i, h;
  u8g_uint_t w, d;

  u8g.setFont(u8g_font_6x13);
  u8g.setFontRefHeightText();
  u8g.setFontPosTop();
  
  h = u8g.getFontAscent()-u8g.getFontDescent();
  w = u8g.getWidth();
  for( i = 0; i < MENU_ITEMS; i++ ) {
    d = (w-u8g.getStrWidth(menu_strings[i]))/2;
    u8g.setDefaultForegroundColor();
    if ( i == menu_current && i<=3) {
      u8g.drawBox(0, i*h+1+3, w, h);
      u8g.setDefaultBackgroundColor();
    }
    if ( i == menu_current && i==4) {
      u8g.drawBox(0, i*h+1+10, w, h);
      u8g.setDefaultBackgroundColor();
    }
    
    if (i<=3)
    {u8g.drawStr(d, i*h+4, menu_strings[i]);}
    if (i==4)
    u8g.drawStr(d, i*h+10, menu_strings[i]);
  }
}

void updateMenu(void) {
  if ( uiKeyCode != KEY_NONE && last_key_code == uiKeyCode ) {
    return;
  }
  last_key_code = uiKeyCode;
  
  switch ( uiKeyCode ) {
    case KEY_NEXT:
      menu_current++;
      if ( menu_current >= MENU_ITEMS )
        menu_current = 0;
      menu_redraw_required = 1;
      break;
    case KEY_PREV:
      if ( menu_current == 0 )
        menu_current = MENU_ITEMS;
      menu_current--;
      menu_redraw_required = 1;
      break;
  }
}

/// this subroutine updates v, i , p on screen
void drawInfo (void)
{
    u8g.firstPage();  
  do {
u8g.setFont(u8g_font_8x13);
u8g.drawStr( 4,14, "V = ");u8g.setPrintPos(35, 14);u8g.print(V);u8g.drawStr( 85, 14, "Volts");
u8g.drawStr( 4,26, "I = ");u8g.setPrintPos(35, 26);u8g.print(I);u8g.drawStr( 85, 26, "Amps ");
u8g.drawStr( 4,38, "P = ");u8g.setPrintPos(35, 38);u8g.print(P);u8g.drawStr( 85, 38, "Watts");
if(analogRead(A6)>100) 
  {u8g.drawStr( 0,62, "Battery Charging");}
else
  {   if (R>5.0)
      {u8g.drawStr( 0,62, "No Atomizer Coil");}
      else
      {u8g.drawStr( 4,62, "R = ");u8g.setPrintPos(35, 62);u8g.print(R);u8g.drawStr( 85, 62, "Ohms");}
  }

  } while( u8g.nextPage() );

  
  
}


void calculate(void)
{
     V = 0.0; I = 0.0; P = 0.0;
      for(int i=0;i<20;i++)
     {            
     V = V + (2*(101.7/101.8)*5.0*analogRead(A2)/1023);
     I = I+((5.0*analogRead(A3)/1023)-2.5)/0.066;                 
     delay(5);
     }

     V=V/20.0; I = -I/20.0;  P = (D*2.5*V/255.0)*I;
     R=P/(I*I);
     R=R-0.07; // substructing mosfet channel and wire resistance

     
}    

void short_ckt_check (void)
{

    if (I>20.0)
      {
        analogWrite(10,0);
        while(1)
        {
          delay(200);
             u8g.firstPage();  
           do {
            u8g.setFont(u8g_font_8x13);
            {u8g.drawStr( 4,62, "Short Circuit !!!");}


               } while( u8g.nextPage() );

        } 
        }
       }
    


     
C code for the Mod v3C/C++
Power Control Added
Minor correction to current offset for no load
Fixes for some calculation
Logo time reduced
#include "U8glib.h"

 
U8GLIB_SSD1306_128X64 u8g(A0, A1, 12, 11,13); 


const byte ROW0 = 9;
const byte ROW1 = 8;
const byte ROW2 = 7;
const byte ROW3 = 6;
const byte COL0 = 5;
const byte COL1 = 4;
const byte COL2 = 3;
const byte COL3 = 2;
///////////////////////////////////////

#define MENU_ITEMS 5
const char *menu_strings[MENU_ITEMS] = { "Quick VAPING", "Advance VAPING", "Settings", "APPs & Games","LOCK Device" };

#define KEY_NONE 0
#define KEY_PREV 1
#define KEY_NEXT 2
#define KEY_SELECT 3
#define KEY_BACK 4

uint8_t uiKeyPrev = 2;
uint8_t uiKeyNext = 3;
uint8_t uiKeySelect = 4;
uint8_t uiKeyBack = 5;

uint8_t uiKeyCodeFirst = KEY_NONE;
uint8_t uiKeyCodeSecond = KEY_NONE;
uint8_t uiKeyCode = KEY_NONE;


uint8_t menu_current = 0;
uint8_t menu_redraw_required = 0;
uint8_t last_key_code = KEY_NONE;


float V=0.0;
float I=0.0;
float P=0.0;
float R=0.0;
uint8_t D= 46; // 0-100 drive stregth pwm

const uint8_t mv_logo[] PROGMEM = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFE,
0x01, 0x80, 0x7F, 0xFF, 0xFF, 0xF8, 0x3E, 0x78, 0x1F, 0xFF, 0xFF, 0xF1, 0xFF, 0x37, 0x0F, 0xFF,
0xFF, 0xC3, 0xFF, 0x8F, 0xC7, 0xFF, 0xFF, 0x8F, 0xFF, 0x0F, 0xF3, 0xFF, 0xFF, 0x1F, 0xFC, 0x27,
0xF9, 0xFF, 0xFE, 0x3F, 0xF8, 0x73, 0xFC, 0xFF, 0xFE, 0x7F, 0xE0, 0xF9, 0xFE, 0x7F, 0xFC, 0xFF,
0xC7, 0xFC, 0xFE, 0x3F, 0xF8, 0xFF, 0x8F, 0xFE, 0x7F, 0x3F, 0xF9, 0xFE, 0x1F, 0xFF, 0x63, 0x9F,
0xF9, 0xFC, 0x3F, 0xFF, 0x01, 0x9F, 0xF3, 0xF8, 0x7F, 0xFF, 0xFC, 0xCF, 0xF3, 0xE1, 0xFF, 0xFF,
0xFE, 0x4F, 0xF3, 0xC3, 0xFF, 0xFF, 0xFF, 0x0F, 0xE7, 0x87, 0xFF, 0xFF, 0xFF, 0x8F, 0xE7, 0x0F,
0xFF, 0xFF, 0xFF, 0xCF, 0xE6, 0x13, 0xFF, 0x0F, 0xF3, 0xE7, 0xE4, 0x13, 0xFE, 0x0F, 0xF3, 0xE3,
0xE0, 0x31, 0xFE, 0x0F, 0xE7, 0xE3, 0xE0, 0x71, 0xFC, 0x27, 0xE7, 0xE7, 0xC1, 0xF5, 0xFC, 0x27,
0xEF, 0xEF, 0xC3, 0xF4, 0xFD, 0x27, 0xCF, 0xCF, 0xE3, 0xF4, 0xF9, 0x33, 0xCF, 0xCF, 0xF3, 0xF6,
0x79, 0x33, 0xDF, 0xCF, 0xF3, 0xF6, 0x73, 0x33, 0x9F, 0xCF, 0xF9, 0xF7, 0x33, 0x39, 0x9F, 0x9F,
0xF9, 0xF7, 0x27, 0x39, 0x3F, 0x9F, 0xFC, 0xF7, 0x27, 0x3D, 0x3F, 0x3F, 0xFC, 0xF7, 0x8F, 0x3C,
0x7E, 0x3F, 0xFE, 0x77, 0x8F, 0x3C, 0x7E, 0x7F, 0xFF, 0x37, 0xCF, 0x3E, 0x7C, 0xFF, 0xFF, 0x1F,
0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF,
0xFF, 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF8, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF

};


const uint8_t ryan_logo[] PROGMEM = {
0x0C, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x37, 0x80,
0x00, 0x88, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x60, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x70, 0x81, 0xFF,
0xFF, 0xF0, 0x00, 0x20, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x10, 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
0x07, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF,
0xC0, 0x26, 0x0F, 0xFF, 0xFF, 0xFF, 0xF0, 0x27, 0x0F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x1F, 0xFF,
0xFF, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x1F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x20, 0x3F, 0xFF, 0xFF, 0xC0,
0x00, 0x20, 0x7F, 0xE0, 0x02, 0x00, 0x00, 0x10, 0x6E, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00,
0x02, 0x00, 0x00, 0x00, 0x04, 0x72, 0x00, 0x00, 0x00, 0x60, 0x00, 0xBC, 0x01, 0x80, 0x00, 0x60,
0x00, 0xB0, 0x01, 0x80, 0x00, 0x60, 0x06, 0xD0, 0x01, 0xC0, 0x00, 0xF0, 0x4F, 0x58, 0x03, 0xE0,
0x00, 0xF0, 0xDF, 0x58, 0x03, 0xE0, 0x01, 0xF0, 0xFF, 0x10, 0x07, 0xE0, 0x03, 0xF0, 0xFF, 0x80,
0x0F, 0xE3, 0xFF, 0xF0, 0xFF, 0xC0, 0x1F, 0xF9, 0xFF, 0x30, 0xFF, 0xFF, 0xFF, 0xE4, 0xFF, 0x30,
0xFF, 0xFF, 0xFF, 0xE0, 0xFE, 0x20, 0xFF, 0xFF, 0xFD, 0xC0, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xF0,
0x3E, 0x08, 0xFF, 0xFF, 0xFD, 0xF4, 0x0C, 0x08, 0xFF, 0xFF, 0xF9, 0x7C, 0x04, 0x0F, 0xFF, 0xFF,
0xFB, 0xF0, 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xC0, 0x60, 0x0F, 0xFF, 0xFF, 0x77, 0xFE, 0x20, 0x0F,
0xFF, 0xFF, 0x8F, 0xFC, 0x70, 0x0F, 0xFF, 0xFF, 0x87, 0xF0, 0x70, 0x0F, 0xFF, 0xFF, 0xFE, 0x18,
0x70, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x40, 0x1F, 0xFF, 0xFF,
0xFF, 0xFE, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFF, 0xBF, 0xC1, 0x80, 0x7F,
0xFF, 0xFC, 0x3F, 0xC0, 0x00, 0x7F, 0xFF, 0xC1, 0x0F, 0xC0, 0x00, 0xFF, 0xFF, 0x60, 0x0F, 0x00,
0x00, 0xFF, 0xFF, 0x60, 0x07, 0x80, 0x01, 0xFF, 0xFF, 0x30, 0x02, 0x80, 0x01, 0xFF, 0xFF, 0x30,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1C, 0x00, 0x00, 0x04, 0x7F, 0xFF, 0x0F, 0x00, 0x00, 0x04, 0x3F
  
};




void setup() {
  // rotate screen, if required
  u8g.setRot180();
 drawInit();
  delay(500);
   drawLogo();
  delay(500);
//  u8g.clearDisplay();
  
  uiSetup();                                // setup key detection and debounce algorithm
  menu_redraw_required = 1;     // force initial redraw
// 4 switch algorithm //

pinMode (ROW0, OUTPUT);
pinMode (ROW1, OUTPUT);
pinMode (ROW2, OUTPUT);
pinMode (ROW3, OUTPUT);

digitalWrite (ROW0, LOW);
digitalWrite (ROW1, LOW);
digitalWrite (ROW2, LOW);
digitalWrite (ROW3, LOW);

pinMode (COL0, INPUT_PULLUP);
pinMode (COL1, INPUT_PULLUP);
pinMode (COL2, INPUT_PULLUP);
pinMode (COL3, INPUT_PULLUP);
 
}

void loop() {  
   
   //////////////////////////////////////////////////////
   while(1)
              {
                  for(int i=0;i<8;i++) // higher i value longer on time
                  {
                analogWrite(10,D*2.5); // higher D value more Vape
                calculate();  
                short_ckt_check(); 
                drawInfo();
                delay(250);
                // POWER CONTROL 
                  if (digitalRead(COL0)==0 | digitalRead(COL1)==0)
                D=D+1; 
                if (D>100) 
                D=100;
                
                if (digitalRead(COL2)==0 | digitalRead(COL3)==0)
                D=D-1; 
                if (D<0)
                D=0;
                 
               //////////////////

                
                  }

                  for(int i=0;i<30;i++)
                  {
                analogWrite(10,0);
                calculate();   
                short_ckt_check(); 
                drawInfo();
                delay(250);

                   // POWER CONTROL 
                if (digitalRead(COL0)==0 | digitalRead(COL1)==0)
                D=D+1; 
                if (D>100) 
                D=100;
                
                if (digitalRead(COL2)==0 | digitalRead(COL3)==0)
                D=D-1; 
                if (D<0)
                D=0;
                 
               //////////////////

                
                  }
                  
               }
//////////////////////////////////////////////////////////////

  uiStep();                                     // check for key press
    
  if (  menu_redraw_required != 0 ) {
    u8g.firstPage();
    do  {
      drawMenu();
    } while( u8g.nextPage() );
    menu_redraw_required = 0;
  }

  updateMenu();                            // update menu bar
  
  
}




void uiSetup(void) {
  // configure input keys 
  
  pinMode(uiKeyPrev, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeyNext, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeySelect, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(uiKeyBack, INPUT_PULLUP);           // set pin to input with pullup
  pinMode(6, OUTPUT);           // set pin to input with pullup
  pinMode(7, OUTPUT);           // set pin to input with pullup
  pinMode(8, OUTPUT);           // set pin to input with pullup
  pinMode(9, OUTPUT);           // set pin to input with pullup
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);

  
}

void uiStep(void) {
  uiKeyCodeSecond = uiKeyCodeFirst;
  if ( digitalRead(uiKeyPrev) == LOW )
    uiKeyCodeFirst = KEY_PREV;
  else if ( digitalRead(uiKeyNext) == LOW )
    uiKeyCodeFirst = KEY_NEXT;
  else if ( digitalRead(uiKeySelect) == LOW )
    uiKeyCodeFirst = KEY_SELECT;
  else if ( digitalRead(uiKeyBack) == LOW )
    uiKeyCodeFirst = KEY_BACK;
  else 
    uiKeyCodeFirst = KEY_NONE;
  
  if ( uiKeyCodeSecond == uiKeyCodeFirst )
    uiKeyCode = uiKeyCodeFirst;
  else
    uiKeyCode = KEY_NONE;
}


void drawInit (void)
{
    u8g.firstPage();  
  do {
u8g.drawBitmapP( 40, 0, 6, 48, mv_logo);
u8g.setFont(u8g_font_8x13);
u8g.setFont(u8g_font_8x13);
u8g.drawStr( 4,64, "Mountain Vapers");

  } while( u8g.nextPage() );

  
  
}

void drawLogo (void)
{
    u8g.firstPage();  
  do {
u8g.drawBitmapP( 40, 0, 6, 56, ryan_logo);
u8g.setFont(u8g_font_5x8);
u8g.drawStr( 0,64, "CLOUD CHASING WEATHER MAN");

  } while( u8g.nextPage() );

  
  
}




void drawMenu(void) {
  uint8_t i, h;
  u8g_uint_t w, d;

  u8g.setFont(u8g_font_6x13);
  u8g.setFontRefHeightText();
  u8g.setFontPosTop();
  
  h = u8g.getFontAscent()-u8g.getFontDescent();
  w = u8g.getWidth();
  for( i = 0; i < MENU_ITEMS; i++ ) {
    d = (w-u8g.getStrWidth(menu_strings[i]))/2;
    u8g.setDefaultForegroundColor();
    if ( i == menu_current && i<=3) {
      u8g.drawBox(0, i*h+1+3, w, h);
      u8g.setDefaultBackgroundColor();
    }
    if ( i == menu_current && i==4) {
      u8g.drawBox(0, i*h+1+10, w, h);
      u8g.setDefaultBackgroundColor();
    }
    
    if (i<=3)
    {u8g.drawStr(d, i*h+4, menu_strings[i]);}
    if (i==4)
    u8g.drawStr(d, i*h+10, menu_strings[i]);
  }
}

void updateMenu(void) {
  if ( uiKeyCode != KEY_NONE && last_key_code == uiKeyCode ) {
    return;
  }
  last_key_code = uiKeyCode;
  
  switch ( uiKeyCode ) {
    case KEY_NEXT:
      menu_current++;
      if ( menu_current >= MENU_ITEMS )
        menu_current = 0;
      menu_redraw_required = 1;
      break;
    case KEY_PREV:
      if ( menu_current == 0 )
        menu_current = MENU_ITEMS;
      menu_current--;
      menu_redraw_required = 1;
      break;
  }
}

/// this subroutine updates v, i , p on screen
void drawInfo (void)
{
    u8g.firstPage();  
  do {
u8g.setFont(u8g_font_8x13);
u8g.drawStr( 4,14, "V = ");u8g.setPrintPos(35, 14);u8g.print(V);u8g.drawStr( 85, 14, "Volts");
u8g.drawStr( 4,26, "I = ");u8g.setPrintPos(35, 26);u8g.print(I);u8g.drawStr( 85, 26, "Amps ");
u8g.drawStr( 4,38, "P = ");u8g.setPrintPos(35, 38);u8g.print(P);u8g.drawStr( 85, 38, "Watts");
u8g.setFont(u8g_font_5x8);
if (digitalRead(COL0)==0 | digitalRead(COL1)==0)
u8g.drawStr( 40,48, "POWER ++");
if (digitalRead(COL2)==0 | digitalRead(COL3)==0)
u8g.drawStr( 40,48, "POWER --");

u8g.setFont(u8g_font_8x13);
   if (R>5.0)
      {u8g.drawStr( 0,62, "No Atomizer Coil");}
      else
      {u8g.drawStr( 4,62, "R = ");u8g.setPrintPos(35, 62);u8g.print(R);u8g.drawStr( 85, 62, "Ohms");}
  

  } while( u8g.nextPage() );

  
  
}


void calculate(void)
{
     V = 0.0; I = 0.0; P = 0.0;
      for(int i=0;i<20;i++)
     {            
     V = V + (2*(101.7/101.8)*5.0*analogRead(A2)/1023);
     /*
if internal ARef used
I= I+((2.56*analogRead(A3)/1023)-2.5)/0.066;
I= I/20.0; // put below
     */
     I = I+((5.0*analogRead(A3)/1023)-2.5)/0.066;                 
     delay(5);
     }

     V=V/20.0; I = -I/20.0; 
     if (I<0.5) I =0.0001;
     P = (D*2.5*V/255.0)*I;
     R=P/(I*I);
     R=R-0.07; // substructing mosfet channel and wire resistance

     
}    

void short_ckt_check (void)
{

    if (I>20.0)
      {
        analogWrite(10,0);
        while(1)
        {
          delay(200);
             u8g.firstPage();  
           do {
            u8g.setFont(u8g_font_8x13);
            {u8g.drawStr( 4,62, "Short Circuit !!!");}


               } while( u8g.nextPage() );

        } 
        }
       }
    


     

Schematics

Atomizer Drive, Protection, Charging, Sensing
Atomizer drive charging  sensing 4ardec7hu1
MCU, OLED Display, Keypad, Programming
Atomizer vape mod ui  prog t1tdhj0asn

Comments

Similar projects you might like

CPU and RAM Usage Monitor

Project showcase by thesahilsaluja

  • 1,246 views
  • 10 comments
  • 8 respects

AWS - Arduino Weather Station

Project tutorial by GilettaStefano

  • 5,539 views
  • 11 comments
  • 20 respects

Arduino Sunflower: An Electronic Sun-Dancer

Project tutorial by SURYATEJA

  • 2,842 views
  • 2 comments
  • 10 respects

Backpack Alarm

Project tutorial by Tomi Chen

  • 2,602 views
  • 12 comments
  • 28 respects

Arduino Based Security System

Project tutorial by Abishek Bhalaaji

  • 1,383 views
  • 5 comments
  • 8 respects

Hiking Tracker

Project tutorial by Shahariar

  • 5,097 views
  • 15 comments
  • 37 respects
Add projectSign up / Login