{"id":1942,"date":"2022-12-14T23:02:39","date_gmt":"2022-12-14T22:02:39","guid":{"rendered":"https:\/\/theroamingworkshop.cloud\/b\/?p=1942"},"modified":"2023-04-14T23:14:45","modified_gmt":"2023-04-14T22:14:45","slug":"temps-i-7-diy-desktop-clock-with-wifi-temperature-pressure-sensor-and-48h-autonomy","status":"publish","type":"post","link":"https:\/\/theroamingworkshop.cloud\/b\/en\/1942\/temps-i-7-diy-desktop-clock-with-wifi-temperature-pressure-sensor-and-48h-autonomy\/","title":{"rendered":"Temps-i 7: DIY desktop clock with WIFI, temperature-pressure sensor and +48h autonomy."},"content":{"rendered":"\n<p>After lots of comings and goings, trials, redesigns, burnts, cuts and some minor explosions, finally I can bring a smart desktop clock I have been working on for the last 2 years. Making a detailed tutorial can be even longer and tedious, so I hope these traces can help make your own. I warn you this takes a lot of time and practice, and can&#8217;t be done carelessly&#8230;<\/p>\n\n\n\n<div id=\"menu\" style=\"padding:20px 20px 20px 20px; border-left:2px solid darkgrey;\">\n<p style=\"font-weight:bold;\">Content<\/p>\n<\/div>\n<script>\nvar text;\nvar element;\n\nfunction fillmenu(){\n\nfor (let i=0; i<window.document.getElementsByTagName(\"h2\").length; i++){\nelement = window.document.getElementsByTagName(\"h2\")[i];\ntext = \"\u25b9 \"+element.innerHTML;\nvar newelement = document.createElement(\"a\");\nnewelement.innerHTML=text;\nvar postid=window.document.getElementsByTagName(\"article\")[0].id;\nvar url = \"https:\/\/theroamingworkshop.cloud\/b\/?p=\"+postid.substr(5,postid.length)+\"#\"+element.id;\nnewelement.setAttribute(\"href\", url);\nnewelement.appendChild(document.createElement(\"br\"));\nwindow.document.getElementById(\"menu\").appendChild(newelement);\nconsole.log(text);\n}\n}\nif(window.location.href.includes(\"tag\")){\n\n}else{\nwindow.setTimeout(fillmenu,2000);\n}\n\n<\/script>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-is-tempsi-7\">What's Temps-i 7?<\/h2>\n\n\n\n<p>Let's break down its name:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Temps<\/strong> mean time in the Valencia dialect,<\/li>\n\n\n\n<li><strong>i<\/strong> for internet, where it gets the time,<\/li>\n\n\n\n<li><strong>7<\/strong> for the display, which uses 7 segments for every digit.<\/li>\n<\/ul>\n\n\n\n<p>These three concepts define this compact desktop clock, with WIFI connectivity, temperature sensor and good autonomy.<\/p>\n\n\n\n<p>Let's see how it's made!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"components\">Components<\/h2>\n\n\n\n<p>First, let's see the recipe ingredients and what each one does:<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps1.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"500\" height=\"500\" data-id=\"1649\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps1.jpg\" alt=\"\" class=\"wp-image-1649\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps1.jpg 500w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps1-300x300.jpg 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps1-150x150.jpg 150w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/a><figcaption class=\"wp-element-caption\">Sparkfun Esp32 Thing<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps2-edited.jpeg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"497\" height=\"497\" data-id=\"1651\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps2-edited.jpeg\" alt=\"\" class=\"wp-image-1651\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps2-edited.jpeg 497w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps2-edited-300x300.jpeg 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps2-edited-150x150.jpeg 150w\" sizes=\"auto, (max-width: 497px) 100vw, 497px\" \/><\/a><figcaption class=\"wp-element-caption\">Segment display<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps3.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1100\" height=\"1422\" data-id=\"1652\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps3.jpg\" alt=\"\" class=\"wp-image-1652\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps3.jpg 1100w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps3-232x300.jpg 232w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps3-792x1024.jpg 792w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps3-768x993.jpg 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps3-676x874.jpg 676w\" sizes=\"auto, (max-width: 1100px) 100vw, 1100px\" \/><\/a><figcaption class=\"wp-element-caption\">BMP-280<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps4.jpeg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"225\" height=\"225\" data-id=\"1653\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps4.jpeg\" alt=\"\" class=\"wp-image-1653\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps4.jpeg 225w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps4-150x150.jpeg 150w\" sizes=\"auto, (max-width: 225px) 100vw, 225px\" \/><\/a><figcaption class=\"wp-element-caption\">Resistors<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps5.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"961\" data-id=\"1654\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps5.jpg\" alt=\"\" class=\"wp-image-1654\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps5.jpg 1280w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps5-300x225.jpg 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps5-1024x769.jpg 1024w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps5-768x577.jpg 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps5-676x508.jpg 676w\" sizes=\"auto, (max-width: 1280px) 100vw, 1280px\" \/><\/a><figcaption class=\"wp-element-caption\">Custom PCB<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps6.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"960\" data-id=\"1655\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps6.jpg\" alt=\"\" class=\"wp-image-1655\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps6.jpg 1280w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps6-300x225.jpg 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps6-1024x768.jpg 1024w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps6-768x576.jpg 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps6-676x507.jpg 676w\" sizes=\"auto, (max-width: 1280px) 100vw, 1280px\" \/><\/a><figcaption class=\"wp-element-caption\">LiPo 3.7v 1000mAh<\/figcaption><\/figure>\n<\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a rel=\"noreferrer noopener\" href=\"https:\/\/learn.sparkfun.com\/tutorials\/esp32-thing-hookup-guide\" target=\"_blank\">Sparkfun ESP32-Thing<\/a><\/strong> board<br>>>Top performance microcontroller with WIFI and Bluetooth connectivity thanks to the ESP32 integrated chip, ideal for IoT projects.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>4 digits 7 segments<\/strong> red color display.<br>&gt;&gt;Shows time and temperature.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/learn.adafruit.com\/adafruit-bmp280-barometric-pressure-plus-temperature-sensor-breakout\/overview\"><strong>BMP-280<\/strong><\/a> module.<br>&gt;&gt;Temperature and barometric pressure compact digital sensor.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>100 Ohm <strong>resistors<\/strong><br>&gt;&gt;Needed to reduce display current, without lowering brightness excessively  (admits up to 1k Ohm, but leds would be hardly visible with daylight).<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>PCB<\/strong> with custom circuit.<br>&gt;&gt;Simplifies display and resistors connectiont to the microcontroller.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>1000mAh<\/strong> 3.7v LiPo <strong>battery<\/strong><br>&gt;&gt;Ensures an autonomy up to 48 hours without external voltage.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Jumper cables<\/strong>.<br>&gt;&gt;For additional connections of external modules.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Push button<\/strong><br>&gt;&gt;Used to switch the program on display.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"electronic-design\">Electronic design<\/h2>\n\n\n\n<p>It's very important to <strong>study the electronic components<\/strong> being used, read all the <strong>specifications<\/strong> and <strong>prototype<\/strong> with all precautions before we start soldering like crazy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"component-selection\">Component selection<\/h3>\n\n\n\n<p>The components listed earlier are not a mere coincidence or copied from elsewhere. They're the most successful trial of many others and meets the project needs:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The 4 digit display <strong>shows exactly what I'm after<\/strong>: the time. If I can also use it to show temperature, that's fine. But a better quality display, like LCD, would be <strong>unnecessarily demanding<\/strong>, and <strong>autonomy<\/strong> is another key requirement.<\/li>\n\n\n\n<li>The microcontroller includes <strong>internet connectivity<\/strong>, as well as enough <strong>computing capacity<\/strong>. It also has <strong>sufficient in\/out pins<\/strong> to control the display without a gpio expansor. Some other options I've tried:\n<ul class=\"wp-block-list\">\n<li><strong>More compact<\/strong> microcontrollers: Teensy 4, Digispark, SparkFun Pro Micro. <strong>They need a GPIO expansor<\/strong> (like PCF8574) <strong>and\/or a WIFI module<\/strong> (like ESP-01). This also involves too many more connections.<\/li>\n\n\n\n<li>Microcontrollers <strong>integrating WIFI and sufficient I\/O<\/strong>, like NodeMCU ESP8266. Got out-dated and <strong>lacks processing capacity<\/strong> as the counter delayed almost 4 seconds every minute.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"prototyping-electronic-circuit\">Prototyping electronic circuit<\/h3>\n\n\n\n<p>Having researched and obtained the components, connect them in a <strong>prototype board<\/strong> (protoboard) to test their operation.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps11.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps11-1024x768.jpg\" alt=\"\" class=\"wp-image-1656\" width=\"512\" height=\"384\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps11-1024x768.jpg 1024w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps11-300x225.jpg 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps11-768x576.jpg 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps11-676x507.jpg 676w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps11.jpg 1280w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>In my case, after different pin combinations, the most organised way is the following:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-center\" data-align=\"center\">ESP32-Thing<\/th><th class=\"has-text-align-center\" data-align=\"center\">Component<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">VBAT<\/td><td class=\"has-text-align-center\" data-align=\"center\">LiPo +<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">3V3<\/td><td class=\"has-text-align-center\" data-align=\"center\">BMP-280 3V3<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GND<\/td><td class=\"has-text-align-center\" data-align=\"center\">LiPo -<br>BMP GND<br>BMP SD0<br>Push -<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO21<\/td><td class=\"has-text-align-center\" data-align=\"center\">BMP SDA<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO04<\/td><td class=\"has-text-align-center\" data-align=\"center\">BMP SCL<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO32<\/td><td class=\"has-text-align-center\" data-align=\"center\">Push +<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO17<\/td><td class=\"has-text-align-center\" data-align=\"center\">Display Digit 1<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO23<\/td><td class=\"has-text-align-center\" data-align=\"center\">Display Digit 2<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO19<\/td><td class=\"has-text-align-center\" data-align=\"center\">Display Digit 3<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO25<\/td><td class=\"has-text-align-center\" data-align=\"center\">Display Digit 4<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO15<\/td><td class=\"has-text-align-center\" data-align=\"center\">Display Segment A<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO22<\/td><td class=\"has-text-align-center\" data-align=\"center\">Display Segment B<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO27<\/td><td class=\"has-text-align-center\" data-align=\"center\">Display Segment C<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO12<\/td><td class=\"has-text-align-center\" data-align=\"center\">Display Segment D<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO13<\/td><td class=\"has-text-align-center\" data-align=\"center\">Display Segment E<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO18<\/td><td class=\"has-text-align-center\" data-align=\"center\">Display Segment F<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO26<\/td><td class=\"has-text-align-center\" data-align=\"center\">Display Segment G<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">GPIO14<\/td><td class=\"has-text-align-center\" data-align=\"center\">Display Segment P (dot)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"pinout-schematic\">Pinout schematic<\/h3>\n\n\n\n<p>Once the prototype is achieved, you should save it in a schematic diagram using <strong>EDA<\/strong> software (<strong>e<\/strong>lectronic <strong>d<\/strong>esign <strong>a<\/strong>utomation) like <strong><a rel=\"noreferrer noopener\" href=\"https:\/\/www.kicad.org\/\" target=\"_blank\">Kicad<\/a><\/strong>, where you can also generate a PCB design that can be sent for manufacturing. Otherwise, you can always save the schematic in paper, as you wont remember where every cable was going in a couple months time...<\/p>\n\n\n\n<p><strong>Kicad<\/strong> is a bit tricky and it's good to practice with simpler projects. Despite this, it's quite manageable for medium users as it basically consists of <strong>searching and choosing symbols for our components<\/strong> and <strong>connect their pins accordingly to specifications<\/strong>.<\/p>\n\n\n\n<p>To avoid messing the sketch up with cables, I used names in every connection, which is also valid in <strong>Kicad<\/strong>. Also, you'll see that the <strong>ESP32-Thing is made up of two 20x pin headers<\/strong>, as I didn't find a working symbol and didn't have time to design one properly. What really matters is that the design is <strong>working and coherent<\/strong> with reality.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps17.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"385\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps17-1024x385.png\" alt=\"\" class=\"wp-image-1924\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps17-1024x385.png 1024w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps17-300x113.png 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps17-768x289.png 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps17-1536x578.png 1536w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps17-676x254.png 676w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps17.png 1767w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Kicad shematic<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Next step is to <strong>assign footprints<\/strong> that are realistic for each symbol, so then we can design a printed circuit board that we can order (usually in China) for 15\u20ac \/ 5 boards.<\/p>\n\n\n\n<p>You don't need to go crazy on this, specially if you're not experienced. I only need to make soldering connections simpler, as in this case <strong>you need about 90 of them <\/strong>but keeping a compact design.<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps18.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"616\" data-id=\"1925\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps18-1024x616.png\" alt=\"\" class=\"wp-image-1925\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps18-1024x616.png 1024w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps18-300x180.png 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps18-768x462.png 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps18-676x407.png 676w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps18.png 1297w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">PCB design in Kicad<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps19.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"558\" data-id=\"1926\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps19-1024x558.png\" alt=\"\" class=\"wp-image-1926\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps19-1024x558.png 1024w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps19-300x163.png 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps19-768x418.png 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps19-1536x836.png 1536w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps19-676x368.png 676w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps19.png 1919w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">PCB 3D viewer<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps20-edited.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"960\" data-id=\"1928\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps20-edited.jpg\" alt=\"\" class=\"wp-image-1928\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps20-edited.jpg 960w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps20-edited-300x300.jpg 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps20-edited-150x150.jpg 150w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps20-edited-768x768.jpg 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps20-edited-676x676.jpg 676w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/a><figcaption class=\"wp-element-caption\">Ordered PCBs<\/figcaption><\/figure>\n<\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"clock-programming\">Clock programming<\/h2>\n\n\n\n<p>Most microcontrollers, like the ESP32-Thing, are <strong>compatible with the <a rel=\"noreferrer noopener\" href=\"https:\/\/www.arduino.cc\/en\/software\" target=\"_blank\">Arduino IDE<\/a><\/strong>, which makes it simpler to connect the board to a PC and load a clock program.<\/p>\n\n\n\n<p>Before starting, it's important to make a <strong>list of tasks and functions<\/strong> that we want to include in the program and modify it as we code. This way you can try different functions separately and debug every step to find errors quickly. In my case, and after many trials, the program will consist of the following:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Define libraries and variables.<\/li>\n\n\n\n<li>Configure pins.<\/li>\n\n\n\n<li>Connect WiFi.<\/li>\n\n\n\n<li>Get date via SNTP.<\/li>\n\n\n\n<li>Disconnect and turn off WiFi (saves battery).<\/li>\n\n\n\n<li>Convert date into digits.<\/li>\n\n\n\n<li>Show digits on display.<\/li>\n\n\n\n<li>Start timer.<\/li>\n\n\n\n<li>Start reading program change pin.<\/li>\n\n\n\n<li>Change program on pushbutton activation.\n<ol class=\"wp-block-list\">\n<li>Read sensors.<\/li>\n\n\n\n<li>Show temperature on display.<\/li>\n<\/ol>\n<\/li>\n\n\n\n<li>Update time after timer ending (every minute).<\/li>\n\n\n\n<li>Restart timer.<\/li>\n<\/ol>\n\n\n\n<p>I don't want to spend too long on the code, and it's also not the most tidy I have, but here it is for anyone who wants to copy it, and also on github:<\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/TheRoam\/Tempsi-7\">https:\/\/github.com\/TheRoam\/Tempsi-7<\/a><\/p>\n\n\n\n<div style=\"height:350px;overflow-x:hidden;padding:2px 2px 2px 2px;\"><pre class=\"wp-block-code\"><code style=\"display:block;width:100%;\">\/\/----------------------------------------------------------------\/\/\n\/\/    Temps-i 7 WiFi clock and temperature in 4 digit display     \/\/\n\/\/  v 1.0.1                                                       \/\/\n\/\/                                                                \/\/\n\/\/  Interfaces:                                                   \/\/\n\/\/  - Sparkfun ESP32-Thing micocontroller                         \/\/\n\/\/  - BMP-280 temperature and pressure digital sensor             \/\/\n\/\/  - 4 digit 7 segment display                                   \/\/\n\/\/  - Programm push button                                        \/\/\n\/\/  - LiPo Battery                                                \/\/\n\/\/                                                                \/\/\n\/\/  Detailed documentation:                                       \/\/\n\/\/  https:\/\/theroamingworkshop.cloud                              \/\/\n\/\/                                                                \/\/\n\/\/                \u00a9 THE ROAMING WORKSHOP 2022                     \/\/\n\/\/----------------------------------------------------------------\/\/\n#include < esp_wifi.h >\n#include < WiFi.h >\n#include < WiFiMulti.h >\n#include \"time.h\"\n#include \"sntp.h\"\n#include < Wire.h >\n#include < Adafruit_BMP280.h >\n\/\/ Spaces inside <> only shown for correct html display. Remove them in Arduino IDE\n\/\/BMP280 sensor using I2C interface\nAdafruit_BMP280 bmp;\n#define BMP_SCK  (4)\n#define BMP_MISO (21)\n#define BMP_MOSI (4)\n#define BMP_CS   (21)\n\/\/Sensor variables\nfloat TEMP=0;     \/\/temperature variable\nfloat ALT=0;      \/\/altitude variable\nfloat PRES=0;     \/\/pressure variable\nfloat hREF=1020.0;\/\/sea level reference pressure in hPa\n\/\/define time variables\nRTC_DATA_ATTR long long TIME=0; \/\/concatenated time\nRTC_DATA_ATTR long long d=0;  \/\/day\nRTC_DATA_ATTR long long m=0;  \/\/month\nRTC_DATA_ATTR long long Y=0;  \/\/year\nRTC_DATA_ATTR long long H=0;  \/\/hour\nRTC_DATA_ATTR long long M=0;  \/\/minute\nRTC_DATA_ATTR long long S=0;  \/\/second\nRTC_DATA_ATTR uint32_t dS=0;  \/\/seconds counter for dot\nRTC_DATA_ATTR struct tm timeinfo; \/\/saves full date variable\nlong long inicio=0; \/\/saves start time\nlong long ahora=0;  \/\/saves current time\n\/\/Define digit pins in an array, in display order, for looping\n\/\/Numbers match ESP32-Thing GPIO number\nint DigPins[4]{\n  17,\/\/ first digit (GPIO 17)\n  23,\/\/second digit (GPIO 23)\n  19,\/\/third digit  (GPIO 19)\n  25\/\/fourth digit  (GPIO  25)\n};\n\/\/Define segment pins\n\/\/Numbers match ESP32-Thing GPIO number\nint SegPins[8]{\n  14,   \/\/P\n  26,   \/\/g\n  18,   \/\/f\n  13,   \/\/e\n  12,   \/\/d\n  27,   \/\/c\n  22,   \/\/b\n  15    \/\/a\n};\n\/\/Auxiliary variables\n\/\/Numbers match ESP32-Thing GPIO number\nint ProgPin=32;   \/\/Pin no used for program\nint ButtonStatus=1;\nint ledPin=5;     \/\/Used to blink the ESP32-Thing blue led\nint ProgNum=-1;   \/\/Define a variable to keep track of current program number\n\/\/ WIFI\n\/\/ Define your wifi network and credentials\nchar ssid1[] = \"YOUR_WIFI_SSID1\";\nchar pass1[] = \"YOUR_WIFI_PASS1\";\nchar ssid1[] = \"YOUR_WIFI_SSID2\";\nchar pass1[] = \"YOUR_WIFI_PASS2\";\nWiFiMulti wifiMulti;\n\/\/ NTP variables\n\/\/ Update time zone if needed\nconst char* ntpServer1 = \"pool.ntp.org\";\nconst char* ntpServer2 = \"time.nist.gov\";\nconst long  gmtOffset_sec = 3600;\nconst int   daylightOffset_sec = 0; \/\/this will be corrected later with software\nconst char* time_zone = \"CET-1CEST,M3.5.0,M10.5.0\/3\";  \/\/ TimeZone rule for Europe\/Rome including daylight adjustment rules (optional)\n\/\/ Displayed characters in every digit are a byte array indicating ON (1) and OFF (0) segments\n\/\/ Use a wiring pattern that matches an understandable byte chain so you can make them up easily\n\/\/ Segment\/byte pattern: Babcdefgp --> where 1 is HIGH (ON) and 0 is LOW (OFF)\n\/\/ Refer to a character by calling this array, i.e.:\n\/\/  - call number 3 by calling ns[3]\n\/\/  - call letter A by calling ns[20]\n\/\/  - call underscore symbol (_) by calling ns[49]\nbyte ns[50]{ \/\/ Array Position - Byte character\n  B11111100,\/\/ 0-0\n  B01100000,\/\/ 1-1\n  B11011010,\/\/ 2-2\n  B11110010,\/\/ 3-3\n  B01100110,\/\/ 4-4\n  B10110110,\/\/ 5-5\n  B10111110,\/\/ 6-6\n  B11100000,\/\/ 7-7\n  B11111110,\/\/ 8-8\n  B11110110,\/\/ 9-9\n  B11111101,\/\/ 10-0.\n  B01100001,\/\/ 11-1.\n  B11011011,\/\/ 12-2.\n  B11110011,\/\/ 13-3.\n  B01100111,\/\/ 14-4.\n  B10110111,\/\/ 15-5.\n  B10111111,\/\/ 16-6.\n  B11100001,\/\/ 17-7.\n  B11111111,\/\/ 18-8.\n  B11110111,\/\/ 19-9.\n  B11101110,\/\/ 20-A\n  B00111110,\/\/ 21-b\n  B10011100,\/\/ 22-C\n  B01111010,\/\/ 23-d\n  B10011110,\/\/ 24-e\n  B10001110,\/\/ 25-f\n  B10111100,\/\/ 26-G\n  B00101110,\/\/ 27-h\n  B00001100,\/\/ 28-I\n  B11111000,\/\/ 29-J\n  B01101110,\/\/ 30-K(H)\n  B00011100,\/\/ 31-L\n  B00101010,\/\/ 32-m(n)\n  B00101010,\/\/ 33-n\n  B00111010,\/\/ 34-o\n  B11001110,\/\/ 35-P\n  B11100110,\/\/ 36-q\n  B00001010,\/\/ 37-r\n  B10110110,\/\/ 38-S\n  B00011110,\/\/ 39-t\n  B01111100,\/\/ 40-U\n  B00111000,\/\/ 41-v\n  B00111000,\/\/ 42-w(v)\n  B01101110,\/\/ 43-X(H)\n  B01110110,\/\/ 44-y\n  B11011010,\/\/ 45-Z\n  B00000001,\/\/ 46-. (dot)\n  B11000110,\/\/ 47-* (astherisc)\n  B00000010,\/\/ 48-- (hyphon)\n  B00010000,\/\/ 49-_ (underscore)\n};\n\/\/array to store displayed digits\nint digits[4];\n\/\/digit calculation variables\nint first_digit = 0;\nint second_digit = 0;\nint third_digit = 0;\nint fourth_digit = 0;\n\/\/counters for looping digits and current number\nint dig=0;\nint n=0;\nint dot=1;\nvoid setup()\n{\n  \/\/ Start disabling bluetooth and WIFI to save energy\n  \/\/ Just power WIFI later, when needed.\n  esp_err_t esp_bluedroid_disable(void);\n  esp_err_t esp_bt_controller_disable(void);\n  WiFi.disconnect(true);\n  WiFi.mode(WIFI_OFF);\n  \n  \/\/ Start serial communication for any debug messages\n  \/\/ Commented for production; uncomment for debugging\n  \/\/Serial.begin(115200);\n  \/\/Define I2C pins, as we are not using standard ones\n  Wire.begin(21,4);\n  \/\/ Activate digit pins looping the pin array.\n  for (dig=0; dig<4; dig++){\n    pinMode(DigPins[dig], OUTPUT);\n  }\n  for (dig=0; dig<4; dig++){  \/\/set them LOW (turn them OFF)\n    digitalWrite(DigPins[dig], LOW);\n  }\n  \/\/ Activate segment pins\n  for (int i=0; i<8; i++){\n    pinMode(SegPins[i],OUTPUT);\n  }\n  \/\/ Activate LED pin\n  pinMode(ledPin, OUTPUT);\n  \/\/ Activate PROG pin\n  pinMode(ProgPin, INPUT_PULLUP);\n  \/\/ Turn ON Wifi\n  wifiON();\n  \n  \/\/ Setup NTP parameters\n  sntp_set_time_sync_notification_cb( timeavailable );\n  sntp_servermode_dhcp(1);\n  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);\n  \/\/wait for date\n  do{\n    delay(100);\n  }while(TIME==0);\n  delay(500);\n  \/\/WIFI can be turned off now\n  wifiOFF();  \n  \/\/ Setup BMP280\n  unsigned status;\n  \/\/BMP-280 I2C Address:\n  \/\/ 0x76 if SD0 is grounded\n  \/\/ 0x77 if SD0 is high\n  status = bmp.begin(0x76);\n  if (!status) {\n    Serial.println(F(\"Could not find a valid BMP280 sensor, check wiring or \"\n                      \"try a different address!\"));\n    Serial.print(\"SensorID was: 0x\"); Serial.println(bmp.sensorID(),16);\n    Serial.print(\"        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\\n\");\n    Serial.print(\"   ID of 0x56-0x58 represents a BMP 280,\\n\");\n    Serial.print(\"        ID of 0x60 represents a BME 280.\\n\");\n    Serial.print(\"        ID of 0x61 represents a BME 680.\\n\");\n    ESP.restart();\n    while (1) delay(10);\n  }\n  \/\/Default settings from datasheet.\n  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     \/\/ Operating Mode.\n                  Adafruit_BMP280::SAMPLING_X2,     \/\/ Temp. oversampling\n                  Adafruit_BMP280::SAMPLING_X16,    \/\/ Pressure oversampling\n                  Adafruit_BMP280::FILTER_X16,      \/\/ Filtering.\n                  Adafruit_BMP280::STANDBY_MS_500); \/\/ Standby time.\n  \/\/get initial readings\n  readSensors();\n  \n  \/\/ Get correct time\n  sync_clock();\n  num_shift();\n  \/\/ Set start time\n  inicio = millis();\n  \/\/ Set dot time\n  dS=millis();\n}\nvoid loop(){\n  \/\/ After setup, this function will loop until shutdown.\n  \n  \/\/ Start time counter using chip's milisecond counter\n  uint32_t ahora=millis();\n  \n  \/\/ Check if the counter has reached 60000 miliseconds.\n  \/\/ Calibrate if you realize that time desyncs\n  \/\/ This depends on processor calculation, which can vary with input voltage (if on batteries) and temperature.\n  while ( (ahora-inicio+(S*1000)) < 59500){\n    \/\/ Run dot blinker when not showing temperature\n    \/\/commented as it sometimes desyncs the hour digit (needs fixing)\n    \/*if(ProgNum==-1){\n      dot_blinker();\n    }*\/\n    \n    \/\/ Reading push button:\n    \/\/ when pressed change status\n    if(digitalRead(ProgPin)==1){\n      ButtonStatus=1;\n    }\n    \/\/ when released after press, set \"program change\" status\n    \/\/ this avoids constant change when holding\n    if(digitalRead(ProgPin)==0 &#038;&#038; ButtonStatus==1){\n      ButtonStatus=2;\n    }\n    \/\/ Status 2 -> Programm change\n    if(ButtonStatus==2){\n      \/\/reset status\n      ButtonStatus=0;\n      \/\/update programm number\n      ProgNum=-ProgNum;\n      Serial.println(ProgNum);\n      \/\/change to temp\n      if(ProgNum==1){\n       \/\/light LED\n       digitalWrite(ledPin, HIGH); \n       \/\/save TIME\n       TIME=digits[0]*1000+(digits[1]-10)*100+digits[2]*10+digits[3];\n       \/\/show temp\n       room_temp();\n      }else if(ProgNum==-1){  \/\/change to time\n        \/\/turn off LED\n        digitalWrite(ledPin, LOW);\n        \/\/restore time\n        split_time(TIME);\n      }\n    }\n    \n    \/\/update time counter\n    ahora=millis();\n    num_shift();\n    delay(6);\n  }\n  \/\/ End of while() after 60 seconds\n  \/\/ Reset initial time\n  S=0;\n  inicio=millis();\n  \/\/make sure there's dot at the end\n  if(digits[1]<=10){\n    digits[1]+10;\n    dot=0;\n  }\n  \/\/update time\n  \/\/if program is in temperature, change to time\n  if(ProgNum==1){\n    split_time(TIME);\n    ProgNum=-1;\n  }\n  updateMinutes();\n}\n\/\/-WIFI function\n\/\/--Setup and turn Wifi ON\nvoid wifiON(){\n  \/\/ Set up WIFI (ESP32 Thing only working with wifiMulti library)\n  Serial.println(\"Conectando\");\n  wifiMulti.addAP(ssid1,pass1);\n  \/\/wifiMulti.addAP(ssid2,pass2);\n  int led=1;\n  int boot=1;\n  wifiMulti.run();\n  \/\/WiFi.disconnect(true);\n  \n  while((WiFi.status() != WL_CONNECTED)){\n    digitalWrite(ledPin, HIGH);\n    delay(500);\n    digitalWrite(ledPin,LOW);\n    delay(500);\n    wifiMulti.run();\n  }\n  \/\/ Make sure LED is off when finished\n  digitalWrite(ledPin,LOW);\n  \/\/ When CONNECTED, while loop ends.\n  Serial.print(\"Conectado a \");\n  Serial.println(WiFi.SSID());\n  Serial.println(WiFi.localIP());\n}\n\/\/-Disable WIFI\nvoid wifiOFF(){\n  \/\/turn WIFI off as it's not needed any more\n  WiFi.disconnect(true);\n  WiFi.mode(WIFI_OFF);\n  \/\/disable wifi (deinit clears all flash data)\n  esp_wifi_deinit();\n}\n\/\/----BMP280 functions\n\/\/-Read sensor data\nvoid readSensors(){\n  TEMP=bmp.readTemperature();\n  Serial.println(\"T: \"+(String)TEMP+\"\u00baC\");\n  PRES=bmp.readPressure();\n  Serial.println(\"P: \"+(String)PRES+\"hPa\");\n  ALT=bmp.readAltitude(hREF);\n  Serial.println(\"h: \"+(String)ALT+\"msnm\");\n}\n\/\/----NTP functions\n\/\/-Callback function (get's called when time adjusts via NTP)\nvoid timeavailable(struct timeval *t)\n{\n  Serial.println(\"Got time adjustment from NTP!\");\n  simpleTime();\n}\nvoid simpleTime()\n{ \n  if(!getLocalTime(&#038;timeinfo)){\n    Serial.println(\"No time available (yet)\");\n    return;\n  }\n  Serial.print(\"Synced time: \");\n  Serial.println(&#038;timeinfo, \"%A, %B %d %Y %H:%M:%S\");\n  \/\/save time\n  sync_clock();\n}\n\/\/-\n\/\/PROGRAM #0: HELLO at startup\n\/\/function to say \"HOLA\" at start up while connecting to WiFi\nvoid ini_HOLA(){\n  int h=30;\n  int o=34;\n  int l=31;\n  int a=20;\n  digits[0]=46;\n  digits[1]=46;\n  digits[2]=46;\n  digits[3]=46;\n}\n\/\/PROGRAM #1: WiFi synced time\n\/\/function that gets current time via WiFi\nvoid sync_clock(){\n  Y=timeinfo.tm_year;\n    TIME=TIME+Y*10000000000;\n  m=timeinfo.tm_mon;\n  m=m+1;\n    TIME=TIME+m*100000000;\n  d=timeinfo.tm_mday;\n    TIME=d*1000000;\n  H=timeinfo.tm_hour;\n  \/\/check daylight saving time and correct hour\n  \/\/\"27 Mar (03 27) +1 hour; 30 Oct (10 30) back -1 hour\"\n  if( ( m*100+d >= 327 ) && ( m*100+d < 1030 ) ){\n    H=H+1;\n  }else{\n    H=H;\n  }\n  TIME=TIME+H*10000;\n  M=timeinfo.tm_min;\n    TIME=TIME+M*100;\n  S=timeinfo.tm_sec;\n    TIME=TIME+S;\n    \n  \/\/split current 4 digit time into sigle digits\n  split_time((TIME\/100)-((TIME\/100)\/10000)*10000);\n}\n\/\/number splitting function to separate time string into digits\nvoid split_time(long long num) {\n  first_digit = num \/ 1000;\n  digits[0] = first_digit;\n  int first_left = num - (first_digit * 1000);\n  second_digit = first_left \/ 100;\n  digits[1] = second_digit;\n  \/\/a\u00f1adimos el segundero fijo (sumamos 10)\n  digits[1] = digits[1]+10;\n  int second_left = first_left - (second_digit * 100);\n  third_digit = second_left \/ 10;\n  digits[2] = third_digit;\n  fourth_digit = second_left - (third_digit * 10);\n  digits[3] = fourth_digit;\n}\n\/\/ number shifting function\nvoid num_shift(){\n  for (dig=0; dig<4; dig++){\/\/ turn digits off\n    digitalWrite(DigPins[dig], HIGH);\n  }\n  \n  \/\/turn them ON (LOW) one by one\n    digitalWrite(DigPins[n], LOW);\n    for(int seg=7; seg>=0; seg--){\n      \/\/read byte array for digit\n      int x = bitRead(ns[digits[n]],seg);\n      \/\/turn the segments ON or OFF\n      digitalWrite(SegPins[seg],x);\n    }\n    n++;\/\/ move to next no.\n    if (n==4){\/\/ if no. is 4, restart\n      n=0;\n    }\n}\n\/\/Getting room temperature from LM35 sensor via NodeMCU analog input pin (ADC)\nvoid room_temp(){\n  readSensors();\n  \/\/This will return temperature in XY.Z format\n  \/\/We don't want the integer value, so we can use the four digits to display temperature units as well \"XY\u00baC\"\n  \/\/Getting first digit in byte format ns[X] where X=int(XY.Z\/10)=int(X.YZ)=X\n  digits[0]=int(TEMP\/10)-int(TEMP\/100)*10;\n  \/\/Getting second digit in byte format ns[Y] where Y=int(XY.Z)-X*10=int(XY.Z)-int(XY.Z\/10)*10\n  digits[1]=int(TEMP\/1)-int(TEMP\/10)*10;\n  \/\/Setting temperature units as degree celsius (\u00baC) in byte format\n  digits[2]=47; \/\/astherisc *\n  digits[3]=22; \/\/character C\n}\nvoid updateMinutes(){\n  \/\/add 1 to the last digit\n  digits[3]=digits[3]+1;\n  \/\/if greater than 9, reset to 0\n  if (digits[3]>9){\n    digits[3]=0;\n    \/\/then add 1 to the third digit\n    updateM0();\n  }\n  \/\/send last digit to display\n  digitalWrite(DigPins[3], LOW);\n}\nvoid updateM0(){\n  \/\/add 1 to third digit\n  digits[2]=digits[2]+1;\n  \/\/if greater than 5, reset to 0\n  if (digits[2]>5){\n    digits[2]=0;\n    \/\/then add 1 to current hours\n    updateH1();\n  }\n  \/\/send digit to display\n  digitalWrite(DigPins[2], LOW);\n}\nvoid updateH1(){\n  \/\/add 1 hour\n  digits[1]=digits[1]+1;\n  \/\/ if greater than 19, reset to 10\n  \/\/ (instead of number 0-9, we use numbers 10-19 in order to add the \"dot\" to the display)\n  if (digits[1]>19){\n    digits[1]=10;\n    \/\/then add 1 to the first digit\n    updateH0();\n  }\/\/ reset when it's 24h (go back to 00)\n  if(digits[1]>13 && digits[0]==2){\n    digits[0]=0;\n    digits[1]=10;\n  }\n  \/\/display digits\n  digitalWrite(DigPins[1], LOW);\n  digitalWrite(DigPins[0], LOW);\n}\nvoid updateH0(){\n  \/\/add 1 to first digit\n  digits[0]=digits[0]+1;\n  \/\/if greater than 2, reset to 0 (it shouldn't happen as we reset earlier, but just in case..)\n  if (digits[0]>2){\n    digits[0]=0;\n  }\n  \/\/display digit\n  digitalWrite(DigPins[0], LOW);\n}\nvoid dot_blinker(){\n  \/\/every second, blink the dot\n    if( millis()-dS > 1000 && dot == 1){\n      digits[1]=digits[1]-10;\n      dS=millis();\n      dot=0;\n    }\n    if( millis()-dS > 250 && dot == 0){\n      digits[1]=digits[1]+10;\n      dot=1;\n    }\n}\n<\/code><\/pre><\/div>\n\n\n\n<p>Notice you'll need these <strong>additional libraries<\/strong> installed using the Arduino IDE:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>esp32<\/strong> board manager by <strong>Espressif<\/strong><\/li>\n\n\n\n<li><strong>WiFiMulti<\/strong> library<\/li>\n\n\n\n<li><strong>Adafruit_BMP280<\/strong> library\n<ul class=\"wp-block-list\">\n<li>(the rest of the libraries derive from these ones)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>You should <strong>constantly try the performance of the code during prototyping<\/strong> so you can change any pin assignment in case of any malfunctioning. If it's all soldered and something fails, it will be really hard to find and solve the error, if it's from a connection.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"assembling\">Assembly<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"soldering\">Soldering<\/h3>\n\n\n\n<p>Once the code is checked and the PCB is designed, you can start soldering with caution, as a wrong movement can damage your modules or produce errors in the program.<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-4 is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps7.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"1280\" data-id=\"1658\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps7.jpg\" alt=\"\" class=\"wp-image-1658\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps7.jpg 960w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps7-225x300.jpg 225w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps7-768x1024.jpg 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps7-676x901.jpg 676w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/a><figcaption class=\"wp-element-caption\">BMP-280 soldered to board<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps8.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"960\" data-id=\"1659\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps8.jpg\" alt=\"\" class=\"wp-image-1659\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps8.jpg 1280w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps8-300x225.jpg 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps8-1024x768.jpg 1024w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps8-768x576.jpg 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps8-676x507.jpg 676w\" sizes=\"auto, (max-width: 1280px) 100vw, 1280px\" \/><\/a><figcaption class=\"wp-element-caption\">Esp32-Thing soldered to board<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps9.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"960\" data-id=\"1660\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps9.jpg\" alt=\"\" class=\"wp-image-1660\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps9.jpg 1280w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps9-300x225.jpg 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps9-1024x768.jpg 1024w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps9-768x576.jpg 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps9-676x507.jpg 676w\" sizes=\"auto, (max-width: 1280px) 100vw, 1280px\" \/><\/a><figcaption class=\"wp-element-caption\">Display soldered to board<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps10.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"960\" data-id=\"1661\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps10.jpg\" alt=\"\" class=\"wp-image-1661\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps10.jpg 1280w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps10-300x225.jpg 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps10-1024x768.jpg 1024w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps10-768x576.jpg 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps10-676x507.jpg 676w\" sizes=\"auto, (max-width: 1280px) 100vw, 1280px\" \/><\/a><figcaption class=\"wp-element-caption\">Resistors soldered to board<\/figcaption><\/figure>\n<\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"case-design\">Case design<\/h3>\n\n\n\n<p>Having it all soldered you'll have a better idea of the final volume of the device. I measure it all with precision using a digital caliper to make a 3D model of it.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps16.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps16.png\" alt=\"\" class=\"wp-image-1665\" width=\"416\" height=\"279\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps16.png 832w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps16-300x201.png 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps16-768x514.png 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/10\/temps16-676x453.png 676w\" sizes=\"auto, (max-width: 416px) 100vw, 416px\" \/><\/a><figcaption class=\"wp-element-caption\">Blender 3D model of all components in their final position<\/figcaption><\/figure>\n<\/div>\n\n\n<p>This way you can now <strong>design a case<\/strong> around the model so you can craft it using a 3D printer. You could also use other types of assembling materials like plywood or metal.<\/p>\n\n\n\n<p>I usually craft <strong>two pieces<\/strong> (one as a <strong>base<\/strong> and another one as a <strong>cover<\/strong>) so they can be screwed together. I also <strong>include different voids<\/strong> to allow for the connection of the USB cable, to add the program switch button and to add a rotary support to hold the clock in a slot in the television.<\/p>\n\n\n\n<p>I will also use white PLA in one piece and grey in the other to bring more life to the design, ending it all like this:<\/p>\n\n\n\n<iframe style=\"width:100%;height:350px;border:none\" src=\"https:\/\/theroamingworkshop.cloud\/threeJS\/models\/Tempsi7\/\"><\/iframe>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-4 is-cropped wp-block-gallery-4 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps22.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" data-id=\"1934\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps22-1024x768.jpg\" alt=\"\" class=\"wp-image-1934\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps22-1024x768.jpg 1024w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps22-300x225.jpg 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps22-768x576.jpg 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps22-676x507.jpg 676w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps22.jpg 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps25.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" data-id=\"1930\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps25-1024x768.jpg\" alt=\"\" class=\"wp-image-1930\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps25-1024x768.jpg 1024w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps25-300x225.jpg 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps25-768x576.jpg 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps25-676x507.jpg 676w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps25.jpg 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps24.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" data-id=\"1931\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps24-1024x768.jpg\" alt=\"\" class=\"wp-image-1931\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps24-1024x768.jpg 1024w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps24-300x225.jpg 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps24-768x576.jpg 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps24-676x507.jpg 676w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps24.jpg 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps23.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" data-id=\"1932\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps23-1024x768.jpg\" alt=\"\" class=\"wp-image-1932\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps23-1024x768.jpg 1024w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps23-300x225.jpg 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps23-768x576.jpg 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps23-676x507.jpg 676w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps23.jpg 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps21.jpg\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" data-id=\"1933\" src=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps21-1024x768.jpg\" alt=\"\" class=\"wp-image-1933\" srcset=\"https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps21-1024x768.jpg 1024w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps21-300x225.jpg 300w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps21-768x576.jpg 768w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps21-676x507.jpg 676w, https:\/\/theroamingworkshop.cloud\/b\/wp-content\/uploads\/2022\/12\/temps21.jpg 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/figure>\n\n\n\n<p>And that's it. I hope you liked it and find it useful. Now you can get your own WIFI clock crafted! Any doubt about this clock can be dropped on Twitter! \ud83d\udc26<\/p>\n\n\n\n<p>\ud83d\udc26 <code><a rel=\"noreferrer noopener\" href=\"https:\/\/twitter.com\/roamingworkshop\" target=\"_blank\">@RoamingWorkshop<\/a><\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>After lots of comings and goings, trials, redesigns, burnts, cuts and some minor explosions, finally I can bring a smart desktop clock I have been working on for the last 2 years. Making a detailed tutorial can be even longer and tedious, so I hope these traces can help make your own. I warn you [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1933,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[68],"tags":[435,403,401,441,409,443,439,437,407],"class_list":["post-1942","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-electronics","tag-diy","tag-electronica","tag-electronics","tag-esp32","tag-internet","tag-reloj","tag-reloj-inteligente","tag-smartwatch","tag-wifi","post-preview"],"_links":{"self":[{"href":"https:\/\/theroamingworkshop.cloud\/b\/wp-json\/wp\/v2\/posts\/1942","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/theroamingworkshop.cloud\/b\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/theroamingworkshop.cloud\/b\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/theroamingworkshop.cloud\/b\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/theroamingworkshop.cloud\/b\/wp-json\/wp\/v2\/comments?post=1942"}],"version-history":[{"count":4,"href":"https:\/\/theroamingworkshop.cloud\/b\/wp-json\/wp\/v2\/posts\/1942\/revisions"}],"predecessor-version":[{"id":1948,"href":"https:\/\/theroamingworkshop.cloud\/b\/wp-json\/wp\/v2\/posts\/1942\/revisions\/1948"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/theroamingworkshop.cloud\/b\/wp-json\/wp\/v2\/media\/1933"}],"wp:attachment":[{"href":"https:\/\/theroamingworkshop.cloud\/b\/wp-json\/wp\/v2\/media?parent=1942"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/theroamingworkshop.cloud\/b\/wp-json\/wp\/v2\/categories?post=1942"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/theroamingworkshop.cloud\/b\/wp-json\/wp\/v2\/tags?post=1942"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}