{"id":1528,"date":"2017-11-21T12:35:04","date_gmt":"2017-11-21T12:35:04","guid":{"rendered":"http:\/\/bryceautomation.com\/?p=1528"},"modified":"2017-11-21T12:45:31","modified_gmt":"2017-11-21T12:45:31","slug":"arduino-bottom-feed-vape-mod","status":"publish","type":"post","link":"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/","title":{"rendered":"Arduino Bottom Feed Vape Mod"},"content":{"rendered":"<h2>Introduction to\u00a0Arduino Bottom Feed Vape Mod<\/h2>\n<p>The purpose of this post is to simply show you how I built my\u00a0Arduino Bottom Feed Vape Mod.\u00a0 \u00a0 If you choose to implement any of this documentation in any way, please be responsible.\u00a0 \u00a0There are many dangers associated with using both the Lithium Batteries and the vape head.\u00a0 \u00a0Unforeseen failures can be catastrophic!\u00a0 You have been warned!<\/p><div id=\"bryce-3901342144\" class=\"bryce-afterfirst bryce-entity-placement\"><script async src=\"\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js?client=ca-pub-8316758073402323\" crossorigin=\"anonymous\"><\/script><ins class=\"adsbygoogle\" style=\"display:block;\" data-ad-client=\"ca-pub-8316758073402323\" \ndata-ad-slot=\"7728240895\" \ndata-ad-format=\"auto\"><\/ins>\n<script> \n(adsbygoogle = window.adsbygoogle || []).push({}); \n<\/script>\n<\/div>\n<p>Previously, I showed you how to build a <a href=\"https:\/\/bryceautomation.com\/index.php\/2017\/09\/26\/arduino-vape-box-mod\/\">standard mod with wifi.<\/a>\u00a0 \u00a0The code for this box will include wifi, however, I did not add the ESP8266-01 to this box.\u00a0 To add this feature, simply power the ESP8266-01 from the 3.3v regulator, and connect RX to TX, TX to RX between the processor and the ESP8266.\u00a0 You will need to disconnect the wifi module from TX and RX, however to upload code to the processor.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-1529 lazyload\" data-src=\"https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7386.jpg\" alt=\"Vape Mod BF\" width=\"1632\" height=\"1224\" data-srcset=\"https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7386.jpg 1000w, https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7386-300x225.jpg 300w, https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7386-768x576.jpg 768w, https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7386-1024x768.jpg 1024w\" data-sizes=\"(max-width: 1632px) 100vw, 1632px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1632px; --smush-placeholder-aspect-ratio: 1632\/1224;\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>The parts list will be the same as the <a href=\"https:\/\/bryceautomation.com\/index.php\/2017\/09\/26\/arduino-vape-box-mod\/\">last box<\/a>, with an additional 3034 mosfet, 7805 regulator, 370 aquarium air pump (6v), some tubing, a check valve, and a 120ml bottle.\u00a0 \u00a0 You will also need a bottom feed 510 connector.\u00a0 \u00a0The one I purchased was from <a href=\"https:\/\/bryceautomation.com\/index.php\/2017\/09\/26\/arduino-vape-box-mod\/\">Varitube<\/a>.\u00a0 I liked the Varitube connector, because it&#8217;s threads are long enough to pass through the top of the wooden box.<\/p>\n<h2>How it works<\/h2>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-1530 size-full lazyload\" data-src=\"https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7382-e1511265986733.jpg\" alt=\"Vape Mode Whole BF\" width=\"1224\" height=\"1632\" data-srcset=\"https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7382-e1511265986733.jpg 750w, https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7382-e1511265986733-225x300.jpg 225w, https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7382-e1511265986733-768x1024.jpg 768w\" data-sizes=\"(max-width: 1224px) 100vw, 1224px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1224px; --smush-placeholder-aspect-ratio: 1224\/1632;\" \/><\/p>\n<p>The green button is the power button.\u00a0 \u00a0This button supplies power to the processor, and other control components.<\/p>\n<p>The Yellow Button is for a 30% power boost.<\/p>\n<p>The red and black buttons are for selection &#8212; Raise and lower power, as well as various selections in configuration mode.<\/p>\n<p>Our top silver button is for the air pump.\u00a0 \u00a0This has two operating modes.\u00a0 \u00a0When the air pump is linked to the vape button (In configuration mode), this button will start the air pump when not vaping.\u00a0 \u00a0When you are vaping, the air pump is started automatically, so this button will inhibit the air pump.\u00a0 If the air pump is &#8220;decoupled&#8221; from the vape button in the configuration menu, this button will simple start and stop the air pump at will.<\/p>\n<p>The second silver button is for vaping.\u00a0 We also use this button to enter the configuration mode when pressed 5 times within 3 seconds.\u00a0 Configuration mode allows the alarm and time zone to be set.\u00a0 \u00a0You can also control the speed of the air pump, and couple the air pump to the vape button.\u00a0 \u00a0 Most of the configuration is stored to the EEPROM on board the ZS-042 real time clock module.\u00a0 \u00a0This way, when power is cycled, or the batteries are replaced, we don&#8217;t loose the settings.<\/p>\n<h2>E-Juice Delivery System<\/h2>\n<p>Since the battery pack will put out over 8 volts, I\u00a0 used a 7805 regulator to bring the voltage down to 5 volts before powering the air pump.\u00a0 \u00a0A 3034 MOSFET allows the processor to control when the air pump is energized, and it&#8217;s speed.<\/p>\n<p>We place pressure on the top of the 120ml bottle, and this causes the e-juice to flow up to the atomizer.\u00a0 A check valve at the top of the air pump prevents back flow into the air pump under certain conditions.<\/p>\n<p>The initial problem I had is that pressure is maintained on the 120ml bottle, which caused the atomizer to flood.\u00a0 \u00a0I resolved this by placing a small pinhole in the top of the 120ml bottle.\u00a0 Pressure will bleed off the 120ml bottle when the air pump is not running.<\/p>\n<p>Here&#8217;s the code!\u00a0 I have no claims that the code is perfect, and some of it is derived from other sources such as <a href=\"https:\/\/github.com\/kriswiner\/DS3231RTC\/blob\/master\/DS3231RTCBasicExample.ino\">this<\/a>.\u00a0 \u00a0You will also need the appropriate libraries installed in your Arduino IDE.<\/p>\n<p>[sourcecode]<\/p>\n<p>#include &lt;Wire.h&gt;<br \/>\n#include &lt;LiquidCrystal_I2C.h&gt;<br \/>\n#include &lt;SimpleDHT.h&gt;<br \/>\n#include &lt;LowPower.h&gt;<br \/>\n#include &quot;i2c.h&quot;<br \/>\n#include &quot;i2c_BMP280.h&quot;<\/p>\n<p>BMP280 bmp280;<br \/>\nLiquidCrystal_I2C lcd(0x3f, 20, 4);<br \/>\n#define AT24C32_ADDRESS 0x57 \/\/ On-board 32k byte EEPROM; 128 pages of 32 bytes each<\/p>\n<p>SimpleDHT22 dht22;<\/p>\n<p>\/\/Define the pins<br \/>\nconst int ButtonPin = 2;<br \/>\nconst int pinDHT22 = 3;<br \/>\nconst int DownPowerPin = 4;<br \/>\nconst int UpPowerPin = 5;<br \/>\nconst int AirButton = 6;<br \/>\nconst int BuzzerPin = 9;<br \/>\nconst int FiringPin = 10;<br \/>\nconst int AirMotor = 11;<br \/>\nconst int PowerBoost = 12;<br \/>\nconst int LedPin = 13;<\/p>\n<p>\/\/ Discrete Variable Declarations<br \/>\nint ButtonState = 0;<br \/>\nint PowerBoostState = 0;<br \/>\nint BuzzerShutoffOK = 1;<br \/>\nint PowerLevelRaw = 50;<br \/>\nint PowerLevelScaled = 0;<br \/>\nint PowerSetting = 10;<br \/>\nint UpPowerState = 1;<br \/>\nint DownPowerState = 1;<br \/>\nint AirButtonState = 1;<br \/>\nint TimeZone = 5;<br \/>\nint TimeZoneOffset = 5;<br \/>\nint DaylightSavings = 0;<br \/>\nint AdjustDelay = 200;<br \/>\nint AirMotorDuty = 0;<br \/>\nint LockVapeMotor = 0;<\/p>\n<p>\/\/ BMP280 Vars<br \/>\nfloat BMPtemperature;<br \/>\nfloat BMPpascal;<br \/>\nstatic float BMPmeters, BMPmetersold;<\/p>\n<p>\/\/ LCD Mode<br \/>\nint LCDMode = 0;<br \/>\nint AlarmHour = 4;<br \/>\nint AlarmMinute = 0;<\/p>\n<p>\/\/ Timers<br \/>\nunsigned long ButtonMillisStart = 0;<br \/>\nunsigned long ButtonMillisTimeout = 6000;<\/p>\n<p>unsigned long FlashMillisStart = 0;<br \/>\nunsigned long FlashMillisTimeout = 100;<\/p>\n<p>unsigned long SleepMillisStart = 0;<br \/>\nunsigned long SleepMillisTimeout = 300000;<\/p>\n<p>unsigned long ModeMillisStart = 0;<br \/>\nunsigned long ModeMillisTimeout = 3000;<\/p>\n<p>int ButtonTimeout = 0;<br \/>\nint VapeTime = 0;<br \/>\nint VapeTimeLast = 0;<\/p>\n<p>\/\/ Counters<br \/>\nint MyCounter = 0;<br \/>\nint LightCounter = 0;<br \/>\nint ModeCounter = 0;<\/p>\n<p>\/\/ One Shots<br \/>\nint ButtonRising = 0;<br \/>\nint ButtonFalling = 0;<br \/>\nint UpPowerONS = 0;<br \/>\nint DownPowerONS = 0;<br \/>\nchar LastSecond;<br \/>\nint ModeFlag = 0;<\/p>\n<p>\/\/ This is for the Real Time Clock<\/p>\n<p>#define DS3231_I2C_ADDRESS 0x68<br \/>\n\/\/ Convert normal decimal numbers to binary coded decimal<br \/>\nbyte decToBcd(byte val) {<br \/>\nreturn ( (val \/ 10 * 16) + (val % 10) );<br \/>\n}<br \/>\n\/\/ Convert binary coded decimal to normal decimal numbers<br \/>\nbyte bcdToDec(byte val) {<br \/>\nreturn ( (val \/ 16 * 10) + (val % 16) );<br \/>\n}<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br \/>\nvoid wakeUp()<br \/>\n{<br \/>\n\/\/ Just a handler for the pin interrupt.<br \/>\n}<br \/>\n\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>void setup() {<br \/>\nWire.begin();<br \/>\nSerial.begin(9600);<\/p>\n<p>\/\/Read Settings from EEPROM<\/p>\n<p>AlarmHour = readEEPROM(AT24C32_ADDRESS, 1, 1);<br \/>\nAlarmMinute = readEEPROM(AT24C32_ADDRESS, 1, 2);<br \/>\nTimeZone = readEEPROM(AT24C32_ADDRESS, 1, 3);<br \/>\nDaylightSavings = readEEPROM(AT24C32_ADDRESS, 1, 4);<br \/>\nPowerLevelRaw = readEEPROM(AT24C32_ADDRESS, 1, 5);<br \/>\nAirMotorDuty = readEEPROM(AT24C32_ADDRESS, 1, 6);<br \/>\nLockVapeMotor = readEEPROM(AT24C32_ADDRESS, 1, 7);<\/p>\n<p>\/\/Serial.print(&quot;Probe BMP280: &quot;);<br \/>\nif (bmp280.initialize()) { \/\/Serial.println(&quot;BMP Sensor found&quot;);<br \/>\n}<br \/>\nelse<br \/>\n{<br \/>\n\/\/Serial.println(&quot;BMP Sensor missing&quot;);<br \/>\nwhile (1) {}<br \/>\n}<\/p>\n<p>\/\/ onetime-measure:<br \/>\nbmp280.setEnabled(0);<br \/>\nbmp280.triggerMeasurement();<\/p>\n<p>\/\/LCD Setup<br \/>\nlcd.init(); \/\/initialize the lcd<\/p>\n<p>\/\/ RTC<br \/>\n\/\/ set the initial time here:<br \/>\n\/\/ DS3231 seconds, minutes, hours, day, date, month, year<br \/>\n\/\/setDS3231time(00,39,11,7,17,11,2017);<\/p>\n<p>\/\/ Setup Pin Modes<br \/>\npinMode(DownPowerPin, INPUT_PULLUP);<br \/>\npinMode(UpPowerPin, INPUT_PULLUP);<br \/>\npinMode(ButtonPin, INPUT_PULLUP);<br \/>\npinMode(PowerBoost, INPUT_PULLUP);<br \/>\npinMode(AirButton, INPUT_PULLUP);<br \/>\npinMode(LedPin, OUTPUT);<br \/>\n\/\/pinMode(AirMotor, OUTPUT); \/\/ Now Analog<br \/>\nlcd.noBacklight();<\/p>\n<p>\/\/Configure Wireless<br \/>\nlcd.backlight();<br \/>\nlcd.setCursor(0, 1);<br \/>\nlcd.print(&quot;Setting Mode&quot;);<br \/>\nSerial.println(&quot;AT+CWMODE=1&quot;);<br \/>\ndelay(1000);<\/p>\n<p>lcd.setCursor(0, 1);<br \/>\nlcd.print(&quot;Connecting Network&quot;);<br \/>\nSerial.println(&quot;AT+CWJAP=\\&quot;YourSSID\\&quot;,\\&quot;YourPassword\\&quot;&quot;);<br \/>\ndelay(3000);<\/p>\n<p>}<\/p>\n<p>\/\/ &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>\n\/\/ RTC Logic for Setting clock<br \/>\n\/\/ &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>\nvoid setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte<br \/>\ndayOfMonth, byte month, byte year) {<br \/>\n\/\/ sets time and date data to DS3231<br \/>\nWire.beginTransmission(DS3231_I2C_ADDRESS);<br \/>\nWire.write(0); \/\/ set next input to start at the seconds register<br \/>\nWire.write(decToBcd(second)); \/\/ set seconds<br \/>\nWire.write(decToBcd(minute)); \/\/ set minutes<br \/>\nWire.write(decToBcd(hour)); \/\/ set hours<br \/>\nWire.write(decToBcd(dayOfWeek)); \/\/ set day of week (1=Sunday, 7=Saturday)<br \/>\nWire.write(decToBcd(dayOfMonth)); \/\/ set date (1 to 31)<br \/>\nWire.write(decToBcd(month)); \/\/ set month<br \/>\nWire.write(decToBcd(year)); \/\/ set year (0 to 99)<br \/>\nWire.endTransmission();<br \/>\n}<\/p>\n<p>void readDS3231time(byte *second,<br \/>\nbyte *minute,<br \/>\nbyte *hour,<br \/>\nbyte *dayOfWeek,<br \/>\nbyte *dayOfMonth,<br \/>\nbyte *month,<br \/>\nbyte *year)<\/p>\n<p>{<br \/>\nWire.beginTransmission(DS3231_I2C_ADDRESS);<br \/>\nWire.write(0); \/\/ set DS3231 register pointer to 00h<br \/>\nWire.endTransmission();<br \/>\nWire.requestFrom(DS3231_I2C_ADDRESS, 7);<br \/>\n\/\/ request seven bytes of data from DS3231 starting from register 00h<br \/>\n*second = bcdToDec(Wire.read() &amp; 0x7f);<br \/>\n*minute = bcdToDec(Wire.read());<br \/>\n*hour = bcdToDec(Wire.read() &amp; 0x3f);<br \/>\n*dayOfWeek = bcdToDec(Wire.read());<br \/>\n*dayOfMonth = bcdToDec(Wire.read());<br \/>\n*month = bcdToDec(Wire.read());<br \/>\n*year = bcdToDec(Wire.read());<br \/>\n}<\/p>\n<p>\/\/ &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>\n\/\/ End of RTC Code<br \/>\n\/\/ &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n<p>\/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br \/>\nvoid loop() {<br \/>\n\/\/ read the state of the pushbuttons:<br \/>\n\/\/ Buttons default high, and ground when pressed.<br \/>\n\/\/ Therefore, we reverse the logic in the states.<br \/>\n\/\/ In the state tags, value of 1 = Pressed<br \/>\nReadButtons();<br \/>\nOffSetTimeZone();<\/p>\n<p>\/\/ Get the BMP280 Data<br \/>\nbmp280.awaitMeasurement();<br \/>\nbmp280.getTemperature(BMPtemperature);<br \/>\nbmp280.getPressure(BMPpascal);<br \/>\nbmp280.getAltitude(BMPmeters);<br \/>\nBMPmetersold = (BMPmetersold * 10 + BMPmeters) \/ 11;<\/p>\n<p>bmp280.triggerMeasurement();<\/p>\n<p>\/\/ get the milliseconds for the timers.<br \/>\nunsigned long CurrentMillis = millis();<\/p>\n<p>\/\/Low Power Setup<br \/>\n\/\/attachInterrupt(0, wakeUp, LOW);<br \/>\nif ((CurrentMillis &#8211; SleepMillisStart) &gt; SleepMillisTimeout) {<br \/>\nanalogWrite(AirMotor, 0);<br \/>\nanalogWrite(FiringPin, 0);<br \/>\nLowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF);<br \/>\n}<\/p>\n<p>\/\/ Power Level Control<br \/>\nif (DownPowerState) {<br \/>\nif (DownPowerONS == 0) {<br \/>\nPowerLevelRaw = PowerLevelRaw &#8211; 5;<br \/>\n}<br \/>\nDownPowerONS = 1;<br \/>\nif (PowerLevelRaw &lt; 0) {<br \/>\nPowerLevelRaw = 0;<br \/>\n}<br \/>\n} else {<br \/>\nDownPowerONS = 0;<br \/>\n}<\/p>\n<p>if (UpPowerState) {<br \/>\nif (UpPowerONS == 0) {<br \/>\nPowerLevelRaw = PowerLevelRaw + 5;<br \/>\n}<br \/>\nUpPowerONS = 1;<br \/>\nif (PowerLevelRaw &gt; 255) {<br \/>\nPowerLevelRaw = 255;<br \/>\n}<br \/>\n} else {<br \/>\nUpPowerONS = 0;<br \/>\n}<\/p>\n<p>PowerLevelScaled = PowerLevelRaw \/ 1;<br \/>\nif (PowerBoostState) {<br \/>\nPowerLevelScaled = PowerLevelScaled * 1.3;<br \/>\n}<\/p>\n<p>\/\/ General Mode Handling<\/p>\n<p>\/\/ ************************* Button is PRESSED *************************<br \/>\nif (ButtonState == HIGH) {<br \/>\nSleepMillisStart = CurrentMillis;<br \/>\nButtonFalling = 0;<\/p>\n<p>\/\/ Start Air motor if locked:<br \/>\nif (LockVapeMotor and !AirButtonState) {<br \/>\nanalogWrite(AirMotor, AirMotorDuty);<br \/>\n}else if(LockVapeMotor and AirButtonState){<br \/>\nanalogWrite(AirMotor,0);<br \/>\n}else if (!LockVapeMotor and AirButtonState){<br \/>\nanalogWrite(AirMotor,AirMotorDuty);<br \/>\n}else if (!LockVapeMotor and !AirButtonState){<br \/>\nanalogWrite(AirMotor,0);<br \/>\n}<\/p>\n<p>\/\/ Set Mode<br \/>\nif (ModeCounter &gt; 0 and ((CurrentMillis &#8211; ModeMillisStart) &gt; ModeMillisTimeout)) {<br \/>\nModeCounter = 0;<br \/>\n}<br \/>\nif (ModeCounter == 0) {<br \/>\nModeMillisStart = CurrentMillis;<br \/>\n}<\/p>\n<p>if (ModeFlag == 0) {<br \/>\nModeCounter ++;<br \/>\nModeFlag = 1;<br \/>\n}<\/p>\n<p>analogWrite(BuzzerPin, 2);<\/p>\n<p>\/\/ turn on the backlight on lcd<\/p>\n<p>if ((CurrentMillis &#8211; FlashMillisStart) &lt; FlashMillisTimeout) {<br \/>\nlcd.backlight();<br \/>\n} else if ((CurrentMillis &#8211; FlashMillisStart) &lt; (FlashMillisTimeout * 2)) {<br \/>\nlcd.noBacklight();<br \/>\n} else {<br \/>\nFlashMillisStart = CurrentMillis;<br \/>\n}<\/p>\n<p>VapeTime = ((CurrentMillis &#8211; ButtonMillisStart) \/ 1000);<br \/>\nif (VapeTime != VapeTimeLast) {<br \/>\nlcd.clear();<br \/>\nlcd.setCursor(0, 0);<br \/>\nlcd.print(&quot;*** Running ***&quot;);<br \/>\nlcd.setCursor(0, 1);<br \/>\nif (PowerBoostState == 1) {<br \/>\nlcd.print (&quot;High Power: &quot;);<br \/>\n} else {<br \/>\nlcd.print (&quot;Low Power: &quot;);<br \/>\n}<br \/>\nlcd.print(VapeTime);<br \/>\nVapeTimeLast = VapeTime;<br \/>\n}<\/p>\n<p>if ((CurrentMillis &#8211; ButtonMillisStart) &lt; ButtonMillisTimeout) {<br \/>\ndigitalWrite(LedPin, HIGH);<br \/>\nanalogWrite(FiringPin, PowerLevelScaled);<br \/>\n} else {<br \/>\nButtonTimeout = 1;<br \/>\ndigitalWrite(LedPin, LOW);<br \/>\nanalogWrite(BuzzerPin, 255);<br \/>\nanalogWrite(FiringPin, 0);<\/p>\n<p>\/\/ Clear One Shot<\/p>\n<p>}<br \/>\nButtonRising = 1;<br \/>\n} else {<br \/>\n\/\/ ************************* Button is RELEASED ************************<br \/>\nButtonRising = 0;<br \/>\nif (LockVapeMotor and !AirButtonState){<br \/>\nanalogWrite(AirMotor,0);<br \/>\n}else if (!LockVapeMotor and AirButtonState){<br \/>\nanalogWrite(AirMotor, AirMotorDuty);<br \/>\n}else if (!LockVapeMotor and !AirButtonState){<br \/>\nanalogWrite(AirMotor,0);<br \/>\n}else if (LockVapeMotor and AirButtonState){<br \/>\nanalogWrite(AirMotor, AirMotorDuty);<br \/>\n}<\/p>\n<p>ModeFlag = 0;<br \/>\nif (LightCounter &gt; 10000) {<br \/>\nLightCounter = 0;<br \/>\n}<br \/>\nif (ButtonFalling == 0) {<br \/>\nLightCounter = 0;<br \/>\n}<br \/>\nbyte second, minute, hour, dayOfWeek, dayOfMonth, month, year;<br \/>\nreadDS3231time(&amp;second, &amp;minute, &amp;hour, &amp;dayOfWeek, &amp;dayOfMonth, &amp;month,<br \/>\n&amp;year);<br \/>\nhour = hour + TimeZoneOffset + DaylightSavings;<br \/>\nif (hour == 24) {<br \/>\nhour = 0;<br \/>\n} else if (hour == -1) {<br \/>\nhour = 23;<br \/>\n} else if (hour == -2) {<br \/>\nhour = 22;<br \/>\n} else if (hour == -3) {<br \/>\nhour = 21;<br \/>\n} else if (hour == -4) {<br \/>\nhour = 20;<br \/>\n}<br \/>\nif (second != LastSecond) {<br \/>\nLightCounter++;<br \/>\nfloat temperature = 0;<br \/>\nfloat humidity = 0;<br \/>\nint err = SimpleDHTErrSuccess;<br \/>\nif ((err = dht22.read2(pinDHT22, &amp;temperature, &amp;humidity, NULL)) != SimpleDHTErrSuccess) {<br \/>\n\/\/Serial.print(&quot;Read DHT22 failed, err=&quot;); Serial.println(err);delay(200);<br \/>\nreturn;<br \/>\n}<\/p>\n<p>\/\/lcd.backlight();<br \/>\nif (LightCounter &gt; 300) {<br \/>\nlcd.noBacklight();<br \/>\n} else {<br \/>\nlcd.backlight();<br \/>\n}<br \/>\n\/\/lcd.clear();<br \/>\nlcd.setCursor(0, 0);<br \/>\nif (AirButtonState) {<br \/>\nlcd.print(&quot;Air Pump Running&quot;);<\/p>\n<p>} else {<br \/>\nif (hour &lt; 10) {<br \/>\nlcd.print(&quot;0&quot;);<br \/>\n}<br \/>\nlcd.print(hour);<br \/>\nlcd.print(&quot;:&quot;);<br \/>\nif (minute &lt; 10) {<br \/>\nlcd.print(&quot;0&quot;);<br \/>\n}<br \/>\nlcd.print(minute);<br \/>\nlcd.print(&quot;:&quot;);<br \/>\nif (second &lt; 10) {<br \/>\nlcd.print(&quot;0&quot;);<br \/>\n}<br \/>\nlcd.print(second);<br \/>\nlcd.print (&quot; &quot;);<br \/>\ntemperature = temperature * 1.8 + 32;<br \/>\nlcd.print(temperature);<br \/>\nlcd.print((char)223);<br \/>\nlcd.print (&quot;F &quot;);<br \/>\n}<\/p>\n<p>LastSecond = second;<\/p>\n<p>lcd.setCursor(0, 1);<br \/>\nlcd.print(&quot;Humidity: &quot;);<br \/>\nlcd.print(humidity);<br \/>\nlcd.print(&quot;% &quot;);<\/p>\n<p>lcd.setCursor(0, 2);<br \/>\nlcd.print(&quot;PSR: &quot;);<br \/>\nlcd.print(BMPpascal \/ 3386.38867);<br \/>\nlcd.print(&quot; In Hg &quot;);<\/p>\n<p>lcd.setCursor(0, 3);<br \/>\nlcd.print(&quot;PWR: &quot;);<br \/>\nlcd.print(PowerLevelScaled);<br \/>\nlcd.print(&quot; A: &quot;);<br \/>\nif (AlarmHour &lt; 10) {<br \/>\nlcd.print(&quot;0&quot;);<br \/>\n}<br \/>\nlcd.print(AlarmHour);<br \/>\nlcd.print(&quot;:&quot;);<br \/>\nif (AlarmMinute &lt; 10) {<br \/>\nlcd.print(&quot;0&quot;);<br \/>\n}<br \/>\nlcd.print(AlarmMinute);<br \/>\nlcd.print(&quot; &quot;);<br \/>\n}<br \/>\nButtonTimeout = 0;<br \/>\nButtonMillisStart = CurrentMillis;<br \/>\nif (BuzzerShutoffOK == 1) {<br \/>\nanalogWrite(BuzzerPin, 0);<br \/>\n}<br \/>\ndigitalWrite(LedPin, LOW);<br \/>\nanalogWrite(FiringPin, 0);<\/p>\n<p>ButtonFalling = 1;<br \/>\n}<\/p>\n<p>\/\/ Alarm Logic<br \/>\nbyte second, minute, hour, dayOfWeek, dayOfMonth, month, year;<br \/>\nreadDS3231time(&amp;second, &amp;minute, &amp;hour, &amp;dayOfWeek, &amp;dayOfMonth, &amp;month,<br \/>\n&amp;year);<\/p>\n<p>hour = hour + TimeZoneOffset + DaylightSavings;<br \/>\nif (hour == 24) {<br \/>\nhour = 0;<br \/>\n} else if (hour == -1) {<br \/>\nhour = 23;<br \/>\n} else if (hour == -2) {<br \/>\nhour = 22;<br \/>\n} else if (hour == -3) {<br \/>\nhour = 21;<br \/>\n} else if (hour == -4) {<br \/>\nhour = 20;<br \/>\n}<br \/>\nif ((hour == AlarmHour) and (minute == AlarmMinute)) {<br \/>\n\/\/Serial.println(&quot;Alarm&quot;);<br \/>\nBuzzerShutoffOK = 0;<br \/>\nanalogWrite(BuzzerPin, 255);<br \/>\n} else {<br \/>\nBuzzerShutoffOK = 1;<br \/>\n}<\/p>\n<p>if (UpPowerState and DownPowerState and PowerBoostState and ButtonState) {<br \/>\nanalogWrite(FiringPin, 0);<br \/>\nanalogWrite(AirMotor, 0);<\/p>\n<p>lcd.clear();<br \/>\nlcd.setCursor(0, 0);<br \/>\nlcd.print(&quot;Opening Garage Door&quot;);<br \/>\nlcd.setCursor(0, 1);<\/p>\n<p>lcd.setCursor(0, 1);<br \/>\nlcd.print(&quot;Connecting Door&#8230; &quot;);<br \/>\nSerial.println(&quot;AT+CIPSTART=\\&quot;TCP\\&quot;,\\&quot;192.168.1.178\\&quot;,80&quot;);<br \/>\ndelay(2000);<\/p>\n<p>lcd.setCursor(0, 1);<br \/>\nlcd.print(&quot;Setting Length&#8230; &quot;);<br \/>\nSerial.println(&quot;AT+CIPSEND=20&quot;);<br \/>\ndelay(1000);<\/p>\n<p>lcd.setCursor(0, 1);<br \/>\nlcd.print(&quot;Sending Command&#8230; &quot;);<br \/>\nSerial.println(&quot;GET \/?DoorCMD=DC&quot;);<br \/>\nSerial.println(&quot;&quot;);<br \/>\ndelay(3000);<\/p>\n<p>lcd.setCursor(0, 1);<br \/>\nlcd.print(&quot;Closing Connection &quot;);<br \/>\nSerial.println(&quot;AT+CIPCLOSE&quot;);<br \/>\ndelay(1000);<\/p>\n<p>lcd.clear();<\/p>\n<p>}<\/p>\n<p>if (ModeCounter == 5) {<\/p>\n<p>analogWrite(FiringPin, 0);<br \/>\nanalogWrite(BuzzerPin, 0);<br \/>\nanalogWrite(AirMotor, 0);<br \/>\nlcd.backlight();<br \/>\nLCDMode = 1;<br \/>\nlcd.clear();<br \/>\ndelay(500);<br \/>\n}<\/p>\n<p>\/\/ Set the Alarm<\/p>\n<p>while ((LCDMode &gt; 0) and (LCDMode &lt; 8)) {<br \/>\nModeCounter = 0;<br \/>\nanalogWrite(FiringPin, 0);<br \/>\nanalogWrite(BuzzerPin, 0);<br \/>\nanalogWrite(AirMotor, 0);<\/p>\n<p>ReadButtons();<br \/>\nif (ButtonState and (LCDMode == 1)) {<br \/>\nLCDMode = 2;<br \/>\nlcd.clear();<br \/>\ndelay(500);<br \/>\n}<\/p>\n<p>ReadButtons();<br \/>\nif (ButtonState and (LCDMode == 2)) {<br \/>\nLCDMode = 3;<br \/>\nlcd.clear();<br \/>\ndelay(500);<br \/>\n}<\/p>\n<p>ReadButtons();<br \/>\nif (ButtonState and (LCDMode == 3)) {<br \/>\nLCDMode = 4;<br \/>\nlcd.clear();<br \/>\ndelay(500);<br \/>\n}<\/p>\n<p>ReadButtons();<br \/>\nif (ButtonState and (LCDMode == 4)) {<br \/>\nLCDMode = 5;<br \/>\nlcd.clear();<br \/>\ndelay(500);<br \/>\n}<\/p>\n<p>ReadButtons();<br \/>\nif (ButtonState and (LCDMode == 5)) {<br \/>\nLCDMode = 6;<br \/>\nlcd.clear();<br \/>\ndelay(500);<br \/>\n}<br \/>\nReadButtons();<br \/>\nif (ButtonState and (LCDMode == 6)) {<br \/>\nLCDMode = 7;<br \/>\nlcd.clear();<br \/>\nlcd.setCursor(0, 0);<br \/>\nlcd.print(&quot;Raw Power = &quot;);<br \/>\nlcd.print(PowerLevelRaw);<br \/>\nlcd.setCursor(0, 1);<br \/>\nlcd.print(&quot;Ready to Write!&quot;);<br \/>\ndelay(500);<br \/>\n}<\/p>\n<p>ReadButtons();<br \/>\nif (ButtonState and (LCDMode == 7)) {<br \/>\nlcd.clear();<br \/>\nlcd.setCursor(0, 1);<br \/>\nlcd.print(&quot;Finished Setting&quot;);<br \/>\nwriteEEPROM(AT24C32_ADDRESS, 1, 1, AlarmHour);<br \/>\nwriteEEPROM(AT24C32_ADDRESS, 1, 2, AlarmMinute);<br \/>\nwriteEEPROM(AT24C32_ADDRESS, 1, 3, TimeZone);<br \/>\nwriteEEPROM(AT24C32_ADDRESS, 1, 4, DaylightSavings);<br \/>\nwriteEEPROM(AT24C32_ADDRESS, 1, 5, PowerLevelRaw);<br \/>\nwriteEEPROM(AT24C32_ADDRESS, 1, 6, AirMotorDuty);<br \/>\nwriteEEPROM(AT24C32_ADDRESS, 1, 7, LockVapeMotor);<\/p>\n<p>delay(1000);<br \/>\nLCDMode = 0;<br \/>\n}<\/p>\n<p>if ((LCDMode == 1) or (LCDMode == 2)) {<br \/>\nlcd.setCursor(0, 0);<br \/>\nlcd.print(&quot;Alarm: &quot;);<br \/>\nif (AlarmHour &lt; 10) {<br \/>\nlcd.print(&quot;0&quot;);<br \/>\n}<br \/>\nlcd.print(AlarmHour);<br \/>\nlcd.print(&quot;:&quot;);<br \/>\nif (AlarmMinute &lt; 10) {<br \/>\nlcd.print(&quot;0&quot;);<br \/>\n}<br \/>\nlcd.print(AlarmMinute);<br \/>\nlcd.print(&quot; &quot;);<br \/>\nlcd.setCursor(0, 1);<br \/>\nif (LCDMode == 1) {<br \/>\nlcd.print(&quot; *&quot;);<br \/>\n} else if (LCDMode == 2) {<br \/>\nlcd.print(&quot; *&quot;);<br \/>\n}<\/p>\n<p>if (UpPowerState and (LCDMode == 1)) {<br \/>\nAlarmHour ++;<br \/>\ndelay(AdjustDelay);<br \/>\n}<br \/>\nif (DownPowerState and (LCDMode == 1)) {<br \/>\nAlarmHour &#8211;;<br \/>\ndelay(AdjustDelay);<br \/>\n}<br \/>\nif (UpPowerState and (LCDMode == 2)) {<br \/>\nAlarmMinute ++;<br \/>\ndelay(AdjustDelay);<br \/>\n}<br \/>\nif (DownPowerState and (LCDMode == 2)) {<br \/>\nAlarmMinute &#8211;;<br \/>\ndelay(AdjustDelay);<br \/>\n}<\/p>\n<p>if (AlarmHour &gt; 23) {<br \/>\nAlarmHour = 0;<br \/>\n} else if (AlarmHour &lt; 0) {<br \/>\nAlarmHour = 23;<br \/>\n}<br \/>\nif (AlarmMinute &gt; 59) {<br \/>\nAlarmMinute = 0;<br \/>\n} else if (AlarmMinute &lt; 0) {<br \/>\nAlarmMinute = 59;<br \/>\n}<br \/>\n}<\/p>\n<p>if (LCDMode == 3) {<br \/>\nlcd.setCursor(0, 0);<br \/>\nlcd.print(&quot;Select Time Zone:&quot;);<br \/>\nlcd.setCursor(0, 1);<br \/>\nif (TimeZone == 1) {<br \/>\nlcd.print(&quot;Hawaii &quot;);<br \/>\n} else if (TimeZone == 2) {<br \/>\nlcd.print (&quot;Alaska &quot;);<br \/>\n} else if (TimeZone == 3) {<br \/>\nlcd.print (&quot;Pacific &quot;);<br \/>\n} else if (TimeZone == 4) {<br \/>\nlcd.print (&quot;Mountain &quot;);<br \/>\n} else if (TimeZone == 5) {<br \/>\nlcd.print (&quot;Central &quot;);<br \/>\n} else if (TimeZone == 6) {<br \/>\nlcd.print (&quot;Eastern &quot;);<br \/>\n}<\/p>\n<p>if (DownPowerState) {<br \/>\nTimeZone &#8211;;<br \/>\ndelay(AdjustDelay);<br \/>\n}<br \/>\nif (UpPowerState) {<br \/>\nTimeZone ++;<br \/>\ndelay(AdjustDelay);<br \/>\n}<\/p>\n<p>if (TimeZone &gt; 6) {<br \/>\nTimeZone = 6;<br \/>\n} else if (TimeZone &lt; 1) {<br \/>\nTimeZone = 1;<br \/>\n}<\/p>\n<p>}<\/p>\n<p>if (LCDMode == 4) {<br \/>\nlcd.setCursor(0, 0);<br \/>\nlcd.print(&quot;Daylight Savings:&quot;);<br \/>\nlcd.setCursor(0, 1);<br \/>\nif (DaylightSavings == 0) {<br \/>\nlcd.print(&quot;No &quot;);<br \/>\n} else if (DaylightSavings == 1) {<br \/>\nlcd.print (&quot;Yes &quot;);<br \/>\n}<\/p>\n<p>if (DownPowerState) {<br \/>\nDaylightSavings = 0;<br \/>\ndelay(AdjustDelay);<br \/>\n}<br \/>\nif (UpPowerState) {<br \/>\nDaylightSavings = 1;<br \/>\ndelay(AdjustDelay);<br \/>\n}<\/p>\n<p>}<\/p>\n<p>if (LCDMode == 5) {<br \/>\nlcd.setCursor(0, 0);<br \/>\nlcd.print(&quot;Air Motor Duty:&quot;);<br \/>\nlcd.setCursor(0, 1);<br \/>\nlcd.print(AirMotorDuty);<\/p>\n<p>if (DownPowerState) {<br \/>\nAirMotorDuty &#8211;;<br \/>\ndelay(AdjustDelay);<br \/>\n}<br \/>\nif (UpPowerState) {<br \/>\nAirMotorDuty ++;<br \/>\ndelay(AdjustDelay);<br \/>\n}<br \/>\nif (AirMotorDuty &gt; 255) {<br \/>\nAirMotorDuty = 255;<br \/>\n} else if (AirMotorDuty &lt; 0) {<br \/>\nAirMotorDuty = 0;<br \/>\n}<\/p>\n<p>}<\/p>\n<p>if (LCDMode == 6) {<br \/>\nlcd.setCursor(0, 0);<br \/>\nlcd.print(&quot;Lock Motor Vape:&quot;);<br \/>\nlcd.setCursor(0, 1);<br \/>\nif (LockVapeMotor == 0) {<br \/>\nlcd.print(&quot;No &quot;);<br \/>\n} else if (LockVapeMotor == 1) {<br \/>\nlcd.print (&quot;Yes &quot;);<br \/>\n}<\/p>\n<p>if (DownPowerState) {<br \/>\nLockVapeMotor = 0;<br \/>\ndelay(AdjustDelay);<br \/>\n}<br \/>\nif (UpPowerState) {<br \/>\nLockVapeMotor = 1;<br \/>\ndelay(AdjustDelay);<br \/>\n}<\/p>\n<p>}<\/p>\n<p>}<br \/>\n}<\/p>\n<p>void OffSetTimeZone() {<br \/>\nif (TimeZone == 1) {<br \/>\nTimeZoneOffset = -4;<br \/>\n} else if (TimeZone == 2) {<br \/>\nTimeZoneOffset = -3;<br \/>\n}<br \/>\nelse if (TimeZone == 3) {<br \/>\nTimeZoneOffset = -2;<br \/>\n}<br \/>\nelse if (TimeZone == 4) {<br \/>\nTimeZoneOffset = -1;<br \/>\n}<br \/>\nelse if (TimeZone == 5) {<br \/>\nTimeZoneOffset = 0;<br \/>\n} else if (TimeZone == 6) {<br \/>\nTimeZoneOffset = 1;<br \/>\n}<br \/>\n}<\/p>\n<p>void ReadButtons() {<br \/>\nButtonState = !digitalRead(ButtonPin);<br \/>\nPowerBoostState = !digitalRead(PowerBoost);<br \/>\nDownPowerState = !digitalRead(DownPowerPin);<br \/>\nUpPowerState = !digitalRead(UpPowerPin);<br \/>\nAirButtonState = !digitalRead(AirButton);<\/p>\n<p>}<\/p>\n<p>\/\/ Write one byte to the EEPROM<br \/>\nvoid writeEEPROM(uint8_t EEPROMaddress, uint8_t page, uint8_t entry, uint8_t data)<br \/>\n{<br \/>\n\/\/ Construct EEPROM address from page and entry input<br \/>\n\/\/ There are 128 pages and 32 entries (bytes) per page<br \/>\n\/\/ EEPROM address are 16-bit (2 byte) address where the MS four bits are zero (or don&#8217;t care)<br \/>\n\/\/ the next seven MS bits are the page and the last five LS bits are the entry location on the page<br \/>\nuint16_t pageEntryAddress = (uint16_t) ((uint16_t) page &lt;&lt; 5) | entry;<br \/>\nuint8_t highAddressByte = (uint8_t) (pageEntryAddress &gt;&gt; 8); \/\/ byte with the four MSBits of the address<br \/>\nuint8_t lowAddressByte = (uint8_t) (pageEntryAddress &#8211; ((uint16_t) highAddressByte &lt;&lt; 8)); \/\/ byte with the eight LSbits of the address<\/p>\n<p>Wire.beginTransmission(EEPROMaddress); \/\/ Initialize the Tx buffer<br \/>\nWire.write(highAddressByte); \/\/ Put slave register address 1 in Tx buffer<br \/>\nWire.write(lowAddressByte); \/\/ Put slave register address 2 in Tx buffer<br \/>\nWire.write(data); \/\/ Put data in Tx buffer<br \/>\ndelay(10); \/\/ maximum write cycle time per data sheet<br \/>\nWire.endTransmission(); \/\/ Send the Tx buffer<br \/>\ndelay(10);<br \/>\n}<\/p>\n<p>\/\/ Read one byte from the EEPROM<br \/>\nuint8_t readEEPROM(uint8_t EEPROMaddress, uint8_t page, uint8_t entry)<br \/>\n{<br \/>\nuint16_t pageEntryAddress = (uint16_t) ((uint16_t) page &lt;&lt; 5) | entry;<br \/>\nuint8_t highAddressByte = (uint8_t) (pageEntryAddress &gt;&gt; 8); \/\/ byte with the four MSBits of the address<br \/>\nuint8_t lowAddressByte = (uint8_t) (pageEntryAddress &#8211; ((uint16_t)highAddressByte &lt;&lt; 8)); \/\/ byte with the eight LSbits of the address<\/p>\n<p>uint8_t data; \/\/ `data` will store the register data<br \/>\nWire.beginTransmission(EEPROMaddress); \/\/ Initialize the Tx buffer<br \/>\nWire.write(highAddressByte); \/\/ Put slave register address 1 in Tx buffer<br \/>\nWire.write(lowAddressByte); \/\/ Put slave register address 2 in Tx buffer<br \/>\nWire.endTransmission(false); \/\/ Send the Tx buffer, but send a restart to keep connection alive<br \/>\nWire.requestFrom(EEPROMaddress, (uint8_t) 1); \/\/ Read one byte from slave register address<br \/>\ndelay(10); \/\/ maximum write cycle time per data sheet<br \/>\ndata = Wire.read(); \/\/ Fill Rx buffer with result<br \/>\ndelay(10);<br \/>\nreturn data; \/\/ Return data read from slave register<br \/>\n}<\/p>\n<p>[\/sourcecode]<\/p>\n<p>&nbsp;<\/p>\n<p>Again&#8230;\u00a0 \u00a0Be sure you know what you are doing.\u00a0 \u00a0I would recommend always using protected batteries, and add extra safety features to prevent reverse polarity, and overcurrent conditions.\u00a0 This document is simply how I built my own box for personal use.<\/p>\n<p>&#8212; Ricky Bryce<\/p>\n<div id=\"bryce-3479864111\" class=\"bryce-after-content bryce-entity-placement\"><script async src=\"\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js?client=ca-pub-8316758073402323\" crossorigin=\"anonymous\"><\/script><ins class=\"adsbygoogle\" style=\"display:block;\" data-ad-client=\"ca-pub-8316758073402323\" \ndata-ad-slot=\"4667596182\" \ndata-ad-format=\"auto\"><\/ins>\n<script> \n(adsbygoogle = window.adsbygoogle || []).push({}); \n<\/script>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Introduction to\u00a0Arduino Bottom Feed Vape Mod The purpose of this post is to simply show you how I built my\u00a0Arduino Bottom Feed Vape Mod.\u00a0 \u00a0 If you choose to implement any of this documentation in any way, please be responsible.\u00a0 \u00a0There are many dangers associated with using both the Lithium Batteries and the vape head.\u00a0 <a class=\"moretag btn btn-primary\" href=\"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/\">Read More \u00bb<\/a><\/p>\n","protected":false},"author":1,"featured_media":1529,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,5],"tags":[105,60],"class_list":{"0":"post-1528","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-advanced","8":"category-arduino-other-microprocessors","9":"tag-bottom-feed","10":"tag-vape-mod","11":"czr-hentry"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Arduino Bottom Feed Vape Mod -- built with Arduino Nano.<\/title>\n<meta name=\"description\" content=\"Documentation and source code of how I built my own bottom feed vape box using the Arduino Nano processor, and 120ml tank.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Arduino Bottom Feed Vape Mod -- built with Arduino Nano.\" \/>\n<meta property=\"og:description\" content=\"Documentation and source code of how I built my own bottom feed vape box using the Arduino Nano processor, and 120ml tank.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/\" \/>\n<meta property=\"og:site_name\" content=\"Bryce Automation\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/ricky.bryce.7\" \/>\n<meta property=\"article:published_time\" content=\"2017-11-21T12:35:04+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-11-21T12:45:31+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7386.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1000\" \/>\n\t<meta property=\"og:image:height\" content=\"750\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Ricky\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/index.php\\\/2017\\\/11\\\/21\\\/arduino-bottom-feed-vape-mod\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/index.php\\\/2017\\\/11\\\/21\\\/arduino-bottom-feed-vape-mod\\\/\"},\"author\":{\"name\":\"Ricky\",\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/#\\\/schema\\\/person\\\/5d5b0f6f6ad768f1ee52968338e63af7\"},\"headline\":\"Arduino Bottom Feed Vape Mod\",\"datePublished\":\"2017-11-21T12:35:04+00:00\",\"dateModified\":\"2017-11-21T12:45:31+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/index.php\\\/2017\\\/11\\\/21\\\/arduino-bottom-feed-vape-mod\\\/\"},\"wordCount\":2816,\"commentCount\":2,\"image\":{\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/index.php\\\/2017\\\/11\\\/21\\\/arduino-bottom-feed-vape-mod\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/bryceautomation.com\\\/wp-content\\\/uploads\\\/2017\\\/11\\\/IMG_7386.jpg\",\"keywords\":[\"Bottom Feed\",\"Vape Mod\"],\"articleSection\":[\"Advanced\",\"Arduino and other microprocessors\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/bryceautomation.com\\\/index.php\\\/2017\\\/11\\\/21\\\/arduino-bottom-feed-vape-mod\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/index.php\\\/2017\\\/11\\\/21\\\/arduino-bottom-feed-vape-mod\\\/\",\"url\":\"https:\\\/\\\/bryceautomation.com\\\/index.php\\\/2017\\\/11\\\/21\\\/arduino-bottom-feed-vape-mod\\\/\",\"name\":\"Arduino Bottom Feed Vape Mod -- built with Arduino Nano.\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/index.php\\\/2017\\\/11\\\/21\\\/arduino-bottom-feed-vape-mod\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/index.php\\\/2017\\\/11\\\/21\\\/arduino-bottom-feed-vape-mod\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/bryceautomation.com\\\/wp-content\\\/uploads\\\/2017\\\/11\\\/IMG_7386.jpg\",\"datePublished\":\"2017-11-21T12:35:04+00:00\",\"dateModified\":\"2017-11-21T12:45:31+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/#\\\/schema\\\/person\\\/5d5b0f6f6ad768f1ee52968338e63af7\"},\"description\":\"Documentation and source code of how I built my own bottom feed vape box using the Arduino Nano processor, and 120ml tank.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/index.php\\\/2017\\\/11\\\/21\\\/arduino-bottom-feed-vape-mod\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/bryceautomation.com\\\/index.php\\\/2017\\\/11\\\/21\\\/arduino-bottom-feed-vape-mod\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/index.php\\\/2017\\\/11\\\/21\\\/arduino-bottom-feed-vape-mod\\\/#primaryimage\",\"url\":\"https:\\\/\\\/bryceautomation.com\\\/wp-content\\\/uploads\\\/2017\\\/11\\\/IMG_7386.jpg\",\"contentUrl\":\"https:\\\/\\\/bryceautomation.com\\\/wp-content\\\/uploads\\\/2017\\\/11\\\/IMG_7386.jpg\",\"width\":1000,\"height\":750,\"caption\":\"Vape Mod BF\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/index.php\\\/2017\\\/11\\\/21\\\/arduino-bottom-feed-vape-mod\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/bryceautomation.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Arduino Bottom Feed Vape Mod\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/#website\",\"url\":\"https:\\\/\\\/bryceautomation.com\\\/\",\"name\":\"Bryce Automation\",\"description\":\"Automating Home and Industry...\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/bryceautomation.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/#\\\/schema\\\/person\\\/5d5b0f6f6ad768f1ee52968338e63af7\",\"name\":\"Ricky\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/bryceautomation.com\\\/wp-content\\\/wphb-cache\\\/gravatar\\\/a8f\\\/a8fe6bf79d292b388ffee281ccb12488x96.jpg\",\"url\":\"https:\\\/\\\/bryceautomation.com\\\/wp-content\\\/wphb-cache\\\/gravatar\\\/a8f\\\/a8fe6bf79d292b388ffee281ccb12488x96.jpg\",\"contentUrl\":\"https:\\\/\\\/bryceautomation.com\\\/wp-content\\\/wphb-cache\\\/gravatar\\\/a8f\\\/a8fe6bf79d292b388ffee281ccb12488x96.jpg\",\"caption\":\"Ricky\"},\"sameAs\":[\"http:\\\/\\\/bryceautomation.com\",\"https:\\\/\\\/www.facebook.com\\\/ricky.bryce.7\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/ricky-bryce-4367a416\\\/\"],\"url\":\"https:\\\/\\\/bryceautomation.com\\\/index.php\\\/author\\\/ricky\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Arduino Bottom Feed Vape Mod -- built with Arduino Nano.","description":"Documentation and source code of how I built my own bottom feed vape box using the Arduino Nano processor, and 120ml tank.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/","og_locale":"en_US","og_type":"article","og_title":"Arduino Bottom Feed Vape Mod -- built with Arduino Nano.","og_description":"Documentation and source code of how I built my own bottom feed vape box using the Arduino Nano processor, and 120ml tank.","og_url":"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/","og_site_name":"Bryce Automation","article_author":"https:\/\/www.facebook.com\/ricky.bryce.7","article_published_time":"2017-11-21T12:35:04+00:00","article_modified_time":"2017-11-21T12:45:31+00:00","og_image":[{"width":1000,"height":750,"url":"https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7386.jpg","type":"image\/jpeg"}],"author":"Ricky","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/#article","isPartOf":{"@id":"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/"},"author":{"name":"Ricky","@id":"https:\/\/bryceautomation.com\/#\/schema\/person\/5d5b0f6f6ad768f1ee52968338e63af7"},"headline":"Arduino Bottom Feed Vape Mod","datePublished":"2017-11-21T12:35:04+00:00","dateModified":"2017-11-21T12:45:31+00:00","mainEntityOfPage":{"@id":"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/"},"wordCount":2816,"commentCount":2,"image":{"@id":"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/#primaryimage"},"thumbnailUrl":"https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7386.jpg","keywords":["Bottom Feed","Vape Mod"],"articleSection":["Advanced","Arduino and other microprocessors"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/","url":"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/","name":"Arduino Bottom Feed Vape Mod -- built with Arduino Nano.","isPartOf":{"@id":"https:\/\/bryceautomation.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/#primaryimage"},"image":{"@id":"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/#primaryimage"},"thumbnailUrl":"https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7386.jpg","datePublished":"2017-11-21T12:35:04+00:00","dateModified":"2017-11-21T12:45:31+00:00","author":{"@id":"https:\/\/bryceautomation.com\/#\/schema\/person\/5d5b0f6f6ad768f1ee52968338e63af7"},"description":"Documentation and source code of how I built my own bottom feed vape box using the Arduino Nano processor, and 120ml tank.","breadcrumb":{"@id":"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/#primaryimage","url":"https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7386.jpg","contentUrl":"https:\/\/bryceautomation.com\/wp-content\/uploads\/2017\/11\/IMG_7386.jpg","width":1000,"height":750,"caption":"Vape Mod BF"},{"@type":"BreadcrumbList","@id":"https:\/\/bryceautomation.com\/index.php\/2017\/11\/21\/arduino-bottom-feed-vape-mod\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/bryceautomation.com\/"},{"@type":"ListItem","position":2,"name":"Arduino Bottom Feed Vape Mod"}]},{"@type":"WebSite","@id":"https:\/\/bryceautomation.com\/#website","url":"https:\/\/bryceautomation.com\/","name":"Bryce Automation","description":"Automating Home and Industry...","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/bryceautomation.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/bryceautomation.com\/#\/schema\/person\/5d5b0f6f6ad768f1ee52968338e63af7","name":"Ricky","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/bryceautomation.com\/wp-content\/wphb-cache\/gravatar\/a8f\/a8fe6bf79d292b388ffee281ccb12488x96.jpg","url":"https:\/\/bryceautomation.com\/wp-content\/wphb-cache\/gravatar\/a8f\/a8fe6bf79d292b388ffee281ccb12488x96.jpg","contentUrl":"https:\/\/bryceautomation.com\/wp-content\/wphb-cache\/gravatar\/a8f\/a8fe6bf79d292b388ffee281ccb12488x96.jpg","caption":"Ricky"},"sameAs":["http:\/\/bryceautomation.com","https:\/\/www.facebook.com\/ricky.bryce.7","https:\/\/www.linkedin.com\/in\/ricky-bryce-4367a416\/"],"url":"https:\/\/bryceautomation.com\/index.php\/author\/ricky\/"}]}},"_links":{"self":[{"href":"https:\/\/bryceautomation.com\/index.php\/wp-json\/wp\/v2\/posts\/1528","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bryceautomation.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bryceautomation.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bryceautomation.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bryceautomation.com\/index.php\/wp-json\/wp\/v2\/comments?post=1528"}],"version-history":[{"count":0,"href":"https:\/\/bryceautomation.com\/index.php\/wp-json\/wp\/v2\/posts\/1528\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/bryceautomation.com\/index.php\/wp-json\/wp\/v2\/media\/1529"}],"wp:attachment":[{"href":"https:\/\/bryceautomation.com\/index.php\/wp-json\/wp\/v2\/media?parent=1528"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bryceautomation.com\/index.php\/wp-json\/wp\/v2\/categories?post=1528"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bryceautomation.com\/index.php\/wp-json\/wp\/v2\/tags?post=1528"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}