Jekyll2022-10-18T11:02:05+00:00http://info.mkrsgh.org/feed.xmlinfo.mkrsgh.orgMakers Guesthouse customer portalMakers Guesthouseinfo@mkrsgh.orgOpen House at Makers: micro:bit2022-10-18T00:00:00+00:002022-10-18T00:00:00+00:00http://info.mkrsgh.org/blog/makerspace/2022/10/18/Open-House-Microbit<p><a href="https://www.microbit.org/">micro:bit</a> is a pocket-sized computer board designed by BBC, to encourage kids to learn how computers work, rather than simply consuming. The fourth Open House event at Makers Siem Reap, kids met the board and learnt programming. Here is the summary of the event.</p> <h2 id="the-microbit">The micro:bit</h2> <figure class=""> <a href="/assets/img/posts/microbit-on-keyboard.jpg" class="image-popup"> <img src="/assets/img/posts/resized/microbit-on-keyboard-800x600.jpg" alt="A micro:bit on a eyboard" srcset=" /assets/img/posts/resized/microbit-on-keyboard-480x360.jpg 480w, /assets/img/posts/resized/microbit-on-keyboard-800x600.jpg 800w, /assets/img/posts/microbit-on-keyboard.jpg 1024w" /> </a> <figcaption> A micro:bit </figcaption> </figure> <p>micro:bit is a direct successor of <a href="https://en.wikipedia.org/wiki/BBC_Micro">BBC Micro</a>, a 8-bit computer in the 1980s, designed for educational programs, with unique interfaces to expand the ability of the computer, supporting not only BASIC but also Pascal, C, and LISP(!).</p> <p><img src="/assets/img/posts/BBC_Micro_Front_Restored.jpg" alt="BBC Micro" /></p> <p>After decades, BBC released an open-source hardware in 2016, distributed many free boards to schools in UK. Instead of 8-bit CPU at 2 Mhz clock, micro:bit, it runs on 16 MHz 32-bit ARM Cortex-M0 microcontroller. Expandability is also properly inherited; the board has many input and output pins on an edge connector, a USB interface, and 2.4 Ghz Bluetooth. The on-board LED array and sensors provide out-of-box experience.</p> <p>The board is now popular not only in UK, but many other countries, including EU countries, Singapore, Taiwan, and Japan. You can see <a href="https://microbit.org/impact/foundation-reports/">reports</a> at the official web site.</p> <h2 id="makecode-an-online-platform-to-code">MakeCode, an online platform to code</h2> <p>The kids were first introduced into an online platform by Microsoft, <a href="https://makecode.microbit.org/">MakeCode</a>, in which kids write code, see the code in action on a simulator, and download the compiled code to run it on micro:bit. The platform is also a place to find resources, such as tutorials with video, and example projects. You can choose a computer language from Blocks, with which you put together to write code, Python, or JavaScript. Blocks was chosen for primary school kids.</p> <figure class=""> <a href="/assets/img/posts/screenshot-makecode-org.png" class="image-popup"> <img src="/assets/img/posts/resized/screenshot-makecode-org-800x462.png" alt="Screenshot of makecode" srcset=" /assets/img/posts/resized/screenshot-makecode-org-480x277.png 480w, /assets/img/posts/resized/screenshot-makecode-org-800x462.png 800w, /assets/img/posts/screenshot-makecode-org.png 1234w" /> </a> <figcaption> Screenshot of makecode </figcaption> </figure> <p>The interface is easy to understand and use. Some have already learnt other block programming languages, like <a href="https://scratch.mit.edu/">Scratch</a>, which made a huge difference in catching up with a new platform. Block programming languages have a common interface; many blocks to choose from a panel, and a work space. They share the same goal — get them into programming and engineering at a young age — but with micro:bit, there is a distinct difference; real feedbacks from the code. You can see the code in action on a real hardware, interact with the code and the hardware with hands, and bring the code elsewhere to experiment, play a game with others, or to show off your achievement.</p> <h2 id="the-lesson">The lesson</h2> <p>Kids learnt the basics of MakeCode and micro:bit in several tutorials, such as using the on-board LED display, seeing the code on the in-browser simulator, and uploading the code to micro:bit. The workflow is simple; put blocks into the work space, see how it works on the simulator, download the firmware in hex, and copy-and-pate the firmware to micro:bit.</p> <figure class=""> <a href="/assets/img/posts/kid-show-off-her-work.jpg" class="image-popup"> <img src="/assets/img/posts/resized/kid-show-off-her-work-800x1066.jpg" alt="A kid explaining what she learnt in the class to her mother" srcset=" /assets/img/posts/resized/kid-show-off-her-work-480x640.jpg 480w, /assets/img/posts/resized/kid-show-off-her-work-800x1066.jpg 800w, /assets/img/posts/kid-show-off-her-work.jpg 1024w" /> </a> <figcaption> She is explaining what she learnt in the class to her mother. </figcaption> </figure> <p>For some kids, the tutorials were bit too easy. I decided to make the class more challenging to these kids. On Sunday, the second part involved an external component; an addressable full colour LED ring. LED strips are ubiquitous these days. Display stands at shops, lighting systems on passenger aircraft, even food carts have LED strips. However, the LED ring we used in the class is <em>smart</em>, meaning you can control not only brightness of all LEDs, but also colour of each pixel individually, hence <em>addressable</em>.</p> <figure class=""> <a href="/assets/img/posts/screenshot-makecode-led-rainbow.png" class="image-popup"> <img src="/assets/img/posts/resized/screenshot-makecode-led-rainbow-800x477.png" alt="Code to show rotating rainbow" srcset=" /assets/img/posts/resized/screenshot-makecode-led-rainbow-480x286.png 480w, /assets/img/posts/resized/screenshot-makecode-led-rainbow-800x477.png 800w, /assets/img/posts/screenshot-makecode-led-rainbow.png 1236w" /> </a> <figcaption> Code to show rotating rainbow </figcaption> </figure> <p>Addressable LED is becoming very popular in smart device market. Some examples of smart devices include smart speakers that understand voice commands, smart wall switches that you can turn on or off devices physically and remotely, and smart locks that do not require physical keys. With addressable LED, you can change the colour of lighting system in rooms, show patterns of colours, and control the lights from your smartphone or via voice commands. With a bit of computer skills, you can even automate them — turn on the light when I enter the room, change the colour to light blue at 11:00 p.m., turn off the light when I am sleeping and such.</p> <p>The LED ring is, essentially, a display in a different form. Displaying a desired pattern on a display always requires some efforts. However, thanks to a library for addressable LEDs, kids can show simple patterns on the LED ring without hassle. In a few minutes, kids could display a rainbow pattern.</p> <figure class=""> <a href="/assets/img/posts/rotating-rainbow-and-microbit.jpg" class="image-popup"> <img src="/assets/img/posts/resized/rotating-rainbow-and-microbit-800x600.jpg" alt="micro:bit is displaying a pattern of rotating rainbow" srcset=" /assets/img/posts/resized/rotating-rainbow-and-microbit-480x360.jpg 480w, /assets/img/posts/resized/rotating-rainbow-and-microbit-800x600.jpg 800w, /assets/img/posts/rotating-rainbow-and-microbit.jpg 1024w" /> </a> <figcaption> micro:bit is displaying a pattern of rotating rainbow </figcaption> </figure> <p>In addition to the LED ring, they used a few other electronic components in the experiment; a breadboard, alligator clips, an external battery, and wires. They are building blocks in electronics. Breadboard is a quick solution in prototyping. Instead of building a complete circuit on a circuit board, you can quickly experiment your idea on a breadboard. No soldering is required. Just connect pins with wires. If you are curious why it is called “breadboard”, watch the following video.</p> <style> .embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 80%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } </style> <div class="embed-container"> <iframe title="YouTube video player" width="640" height="390" src="//www.youtube.com/embed/HrG98HJ3Z6w" frameborder="0" allowfullscreen=""></iframe> </div> <h2 id="thoughts-after-the-classes">Thoughts after the classes</h2> <p>I found that the real feedbacks from the reality was surprisingly great in educational programs. Most of other online block programming languages run in a browser, and the result can be seen in the browser. They are great, too, but micro:bit gives you real feedback and interactions. You can show your work to others. In software development, almost all your works are invisible except for some lucky developers, like frontend engineers. This is why I like electronics. I’ll remember kid’s face when they see their code in action.</p> <p>Luckily, all of kids have past experience in other block programmings; they knew not only how to put blocks together, but also what a variable is, what can be done with conditions and flow controls, and how program works in general. All of them made a huge difference in the class. If you master one computer language, learning another is far easier because computer languages share many same ideas. There are, of course, differences between languages, but what you have learnt in another language will not be wasted. If they knew almost nothing in programming and using a computer — like some local students I taught before — it would have took longer. This is why BBC developed micro:bit; “get them into programming and engineering at a young age”. Unlike when computers were “new thing” in decades ago, these skills are now a must, and you should get started as earlier as possible, not when you are <em>forced</em> to learn. Many teachers had to learn how to teach in online class after COVID-19 without proper trainings or support.</p> <p>I have personal experiences with people who are not familiar with modern technologies. They don’t know how to share files, collaborate with others on a file or a document, or get things done effectively. They are mostly from older generations, and at higher positions. They will retire soon, and young generation should know better. Good engineers love to be “the worst guy in the band” because it is fun to work with competent, productive team members, and everyone in the team learns a lot from others.</p> <h2 id="final-words">Final words</h2> <p>We had Open House events for kids on every weekends. In the past classes, kids learnt how to <a href="/blog/makerspace/2022/09/05/First-Electronics-Class-for-Kids-at-Makers-Siem-Reap/">solder components on an electronic circuit</a>, <a href="/blog/makerspace/2022/09/30/Open-House-at-Makers-Paper-Crafts/">built a paper craft glider</a>, and <a href="/blog/makerspace/2022/10/03/Open-House-3D-Modeling/">model 3D objects</a>.</p> <p>We post upcoming Open House events to <a href="https://www.facebook.com/groups/SiemReapParenting/">Siem Reap Parenting</a> Facebook group and <a href="https://twitter.com/makers_gh">Twitter</a>. If you have a kid, and would like to help the kid to develop technology skills, please join the group or follow us on Twitter. For details and reservation, please <a href="https://t.me/mkrsgh">contact us on Telegram</a>.</p>Tomoyuki Sakuraimicro:bit is a pocket-sized computer board designed by BBC, to encourage kids to learn how computers work, rather than simply consuming. The fourth Open House event at Makers Siem Reap, kids met the board and learnt programming. Here is the summary of the event.Open House at Makers: 3D Modeling2022-10-03T00:00:00+00:002022-10-03T00:00:00+00:00http://info.mkrsgh.org/blog/makerspace/2022/10/03/Open-House-3D-Modeling<p>In the last week’s Open House at Makers Siem Reap, we had 3D modeling classes, in which kids learnt how 3D object is designed with CAD, or Computer Assisted Design. Here is the summary.</p> <figure class=""> <a href="/assets/img/posts/sliced-name-tag.png" class="image-popup"> <img src="/assets/img/posts/resized/sliced-name-tag-800x570.png" alt="Sliced name tag with Cura" srcset=" /assets/img/posts/resized/sliced-name-tag-480x342.png 480w, /assets/img/posts/resized/sliced-name-tag-800x570.png 800w, /assets/img/posts/sliced-name-tag.png 1281w" /> </a> <figcaption> 3D objects must be sliced before printing </figcaption> </figure> <h2 id="an-online-cad-system-tinkdercad">An online CAD system, tinkdercad</h2> <figure class=""> <a href="/assets/img/posts/tinkercad-screenshot.png" class="image-popup"> <img src="/assets/img/posts/resized/tinkercad-screenshot-800x593.png" alt="Screen shot of tinkercad" srcset=" /assets/img/posts/resized/tinkercad-screenshot-480x356.png 480w, /assets/img/posts/resized/tinkercad-screenshot-800x593.png 800w, /assets/img/posts/tinkercad-screenshot.png 1247w" /> </a> <figcaption> Screen shot of tinkercad </figcaption> </figure> <p>The CAD system used in the class is <a href="https://www.tinkercad.com/">tinkercad</a>, created by Autodesk, the vendor of the de-facto CAD system in commercial industry, Autocad. tinkdercad is a web application, meaning you do not have to install anything. It runs on modern browsers. The CAD system is designed for kids and students, and has easy-to-use interfaces and many pre-designed basic objects. After learning basic operations, like placing and moving objects, designing objects is surprisingly easy. It lacks full-fledged CAD features commonly found in real CAD systems, but <a href="https://www.tinkercad.com/things">the gallery has a number of great designs</a>.</p> <h2 id="the-name-tag">The name tag</h2> <p>The design the kids worked on was a name tag. A plate of plastic with a small hole and a name. It is slightly bigger than average name tags because texts are bit difficult to print. Most of fonts have very small details, and even a 0.4 mm nozzle cannot handle the details very well. The filament was white PLA so that kids can paint later. The height of the plate is 3 mm, strong enough for a tag.</p> <figure class=""> <a href="/assets/img/posts/girl-designing-3d-object.jpg" class="image-popup"> <img src="/assets/img/posts/resized/girl-designing-3d-object-480x640.jpg" alt="A girl is designing an 3D object on a computer at Makers Siem Reap" srcset=" /assets/img/posts/resized/girl-designing-3d-object-480x640.jpg 480w, /assets/img/posts/girl-designing-3d-object.jpg 800w" /> </a> <figcaption> A girl is working on her own original design. Designing an object is much more fun than you might imagine. </figcaption> </figure> <p>It seemed that the kids were impressed with the possibilities in 3D modeling. In the 3D world on a computer, you can design anything you want. As a bonus, their designs were printed with our 3D printer, and given to them after the class. Here is one of the name tags painted by a kid.</p> <figure class=""> <a href="/assets/img/posts/painted-name-tag.jpg" class="image-popup"> <img src="/assets/img/posts/resized/painted-name-tag-800x600.jpg" alt="A name tag painted by a kid" srcset=" /assets/img/posts/resized/painted-name-tag-480x360.jpg 480w, /assets/img/posts/resized/painted-name-tag-800x600.jpg 800w, /assets/img/posts/painted-name-tag.jpg 1280w" /> </a> <figcaption> The printed tag was painted later with acrylic paint </figcaption> </figure> <h2 id="an-advanced-cad-system-freecad">An advanced CAD system, FreeCAD</h2> <figure class=""> <a href="/assets/img/posts/freecad-screenshot.png" class="image-popup"> <img src="/assets/img/posts/resized/freecad-screenshot-800x473.png" alt="Screen shot of FreeCAD" srcset=" /assets/img/posts/resized/freecad-screenshot-480x284.png 480w, /assets/img/posts/resized/freecad-screenshot-800x473.png 800w, /assets/img/posts/freecad-screenshot.png 1256w" /> </a> <figcaption> Screen shot of FreeCAD </figcaption> </figure> <p>One of my local students has been learning 3D modeling as well, but with a 3D parametric modeler, <a href="https://www.freecadweb.org/">FreeCAD</a>. This is a CAD system for industrial design, such as parts, architectures, and robots (see <a href="https://www.freecadweb.org/features.php">Key FreeCAD Features</a>). Unlike tinkercad, FreeCAD requires all the metrics, sizes and positions. You cannot tell the computer to place an object “around here”. Instead, you have to tell the exact size and position of the object. The learning curve of FreeCAD is rather steep, but worth the efforts. The model you print must follow the law of physics, and your design must take into account various techniques to workaround physical limitations with many features of FreeCAD. Here is an introductory video for beginners.</p> <style> .embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 80%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } </style> <div class="embed-container"> <iframe title="YouTube video player" width="640" height="390" src="//www.youtube.com/embed/u8otDF_C_fw" frameborder="0" allowfullscreen=""></iframe> </div> <h2 id="final-words">Final words</h2> <p>You can use tinkdercad for free after registration. It also has features specifically for teachers and educators. If you would like to have a similar class for your students at school, we can help.</p> <p>We had Open House classes for kids on every weekends. In the past classes, kids learnt <a href="/blog/makerspace/2022/09/05/First-Electronics-Class-for-Kids-at-Makers-Siem-Reap/">how to solder components on an electronic circuit</a>, and <a href="/blog/makerspace/2022/09/30/Open-House-at-Makers-Paper-Crafts/">built a paper craft glider</a>.</p> <p>Our 3D printers are available for registered members at USD 1 per hour. Materials are not included, and you must attend a safety course before printing. A 3D printer crash course is available for beginners, in which you will learn problems and solutions in 3D printing. If you are brave enough to design your own objects, join our CAD course. For details, please <a href="https://t.me/mkrsgh">contact us on Telegram</a>.</p>Tomoyuki SakuraiIn the last week’s Open House at Makers Siem Reap, we had 3D modeling classes, in which kids learnt how 3D object is designed with CAD, or Computer Assisted Design. Here is the summary.Open House at Makers: Paper crafts2022-09-30T00:00:00+00:002022-09-30T00:00:00+00:00http://info.mkrsgh.org/blog/makerspace/2022/09/30/Open-House-at-Makers-Paper-Crafts<p>Our open house event at Makers Siem Reap the last weekends, Kids made a paper glider. Paper craft is not just an activity for kids at school, but a serious art. Here is the summary of the class.</p> <figure class=""> <a href="/assets/img/posts/Kids_and_Gilders.jpg" class="image-popup"> <img src="/assets/img/posts/resized/Kids_and_Gilders-800x600.jpg" alt="Kids with their gliders ready for test flight" srcset=" /assets/img/posts/resized/Kids_and_Gilders-480x360.jpg 480w, /assets/img/posts/resized/Kids_and_Gilders-800x600.jpg 800w, /assets/img/posts/Kids_and_Gilders.jpg 1280w" /> </a> <figcaption> Kids with their gliders ready for test flight </figcaption> </figure> <p>All the necessary tools were provided, including the printed design of the glider. In the class, the kids cut all the parts with scissors and an art knife. They had to think carefully, and choose the right tool to cut. Cutting papers is not simple nor easy as it seems. You have to cut <em>exactly</em> the centre of lines, which is an important skill when you build a paper craft for display. For longer curves, use scissors. For smaller parts, or straight lines, use a knife. Rotate papers as necessary. These small steps eventually make it possible to build more complicated ones.</p> <figure class=""> <a href="/assets/img/posts/Kids_Making_Gliders.jpg" class="image-popup"> <img src="/assets/img/posts/resized/Kids_Making_Gliders-800x600.jpg" alt="Kids looking at the glider design" srcset=" /assets/img/posts/resized/Kids_Making_Gliders-480x360.jpg 480w, /assets/img/posts/resized/Kids_Making_Gliders-800x600.jpg 800w, /assets/img/posts/Kids_Making_Gliders.jpg 1280w" /> </a> <figcaption> Kids are ready to tackle the challenge </figcaption> </figure> <p>It took more than an hour (again). It was fun to see the kids talked less as they proceeded the build process. They slowly focused on their project. Engineers call this “flow state”. Joel Spolsky explains what would happen when engineers are in a state of flow, often referred as “being in the zone”:</p> <div class="card"> <div class="card-header"> <strong>Joel on flow</strong> </div> <div class="card-body"> <quote class="card-text">They lose track of time and produce great stuff through absolute concentration. This is when they get all of their productive work done.</quote> <div class="text-right"> — <a href="https://www.joelonsoftware.com/2000/04/19/where-do-these-people-get-their-unoriginal-ideas/" class="card-link"> Joel Spolsky </a> </div> </div> </div> <p>When you work on a big, complicated paper model, you need a state like this and the total silence. In my opinion, paper craft is one of the best way to develop patience.</p> <h2 id="yasuaki-ninomiya-a-demigod-of-paper-glider">Yasuaki Ninomiya, a demigod of paper glider</h2> <p>Ninomiya, a Japanese professional engineer, has been designing more then 2,600 paper gliders for a long time. He is the winner of the first international paper aircraft competition in 1967. His series of books, <a href="https://www.amazon.co.jp/%E3%82%88%E3%81%8F%E9%A3%9B%E3%81%B6%E7%B4%99%E9%A3%9B%E8%A1%8C%E6%A9%9F%E3%80%88Vol-1%E3%80%89%E2%80%95%E5%88%87%E3%82%8A%E3%81%AC%E3%81%8F%E6%9C%AC-%E4%BA%8C%E5%AE%AE-%E5%BA%B7%E6%98%8E/dp/4416395124">“Paper gliders that fly really well”</a> are my bibles. The book contains several his designs that you can cut out from the book so that you don’t have to print. He had published a design every month on a science magazine for 49 years.</p> <p>The glider the kids made in the class is one of his well-known designs. You can find it at <a href="https://creativepark.canon/en/contents/CNT-0011974/index.html">Canon Creative Park: Racer538 (Yellow)</a>.</p> <h2 id="origami">Origami</h2> <p>“Origami” is a Japanese art, well known by many. Many of readers might have known paper animals or flowers, built from a piece of paper. They are often taught at preschools and primary schools. However, there are serious engineers who apply the same technique to the real world problems. The video below, “Engineering with Origami”, explains modern applications with Origami.</p> <style> .embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 80%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } </style> <div class="embed-container"> <iframe title="YouTube video player" width="640" height="390" src="//www.youtube.com/embed/ThwuT3_AG6w" frameborder="0" allowfullscreen=""></iframe> </div> <p>Note that the Origamis in the video are mathematically designed, not the result of random trials and errors. Another reason why you need to learn mathematics.</p> <p>If you are interested in Origami, the sprucecrafts has an article for you: <a href="https://www.thesprucecrafts.com/top-origami-for-beginners-2540688">10 Simple Origami Projects for Beginners</a>.</p> <h2 id="paper-models">Paper models</h2> <p>A paper model is a paper craft that replicates a real object, such as animals, vehicles, or insects. My favorite is aircraft.</p> <p><a href="https://en.wikipedia.org/wiki/Airbus_Beluga">Airbus A300-600ST</a>, known as “Beluga”, is a variant of A300 wide-body airliner, designed to carry aircraft parts. The following video shows how to build a paper model of it. While watching the video, imagine:</p> <ul> <li>how the author designed 2D parts from 3D model</li> <li>how much effort were made to cut the small parts</li> <li>how long it took to put everything together</li> <li>how the author made the video</li> </ul> <style> .embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 80%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } </style> <div class="embed-container"> <iframe title="YouTube video player" width="640" height="390" src="//www.youtube.com/embed/i7ESSvMGZBc" frameborder="0" allowfullscreen=""></iframe> </div> <p>Canon Creative Park has <a href="https://creativepark.canon/en/categories/CAT-ST01-0089/index.html">a dedicated category for aircraft paper models</a>, which includes one of the most beautiful passenger aircrafts in the world, <a href="https://creativepark.canon/en/contents/CNT-0010071/index.htmlhttps://creativepark.canon/en/contents/CNT-0010071/index.html">Airbus A340</a>.</p> <p>It is not trivial at all to design airplanes. But for simple designs, you can design your own with a bit of learning and patience thanks to <a href="https://www.blender.org/">blender</a> and a blender plugin, <a href="http://addam.github.io/Export-Paper-Model-from-Blender/">Export-Paper-Model-from-Blender</a>. See <a href="http://addam.github.io/Export-Paper-Model-from-Blender/">a wolf head</a>, which a dad made for his kid.</p> <h2 id="final-words">Final words</h2> <p>From the experiences in the classes, I came to a conclusion that a class should be a two-hours session with a short break. The class should be sufficiently challenging. It is possible to teach something within an hour, but I will leave it to teachers at schools.</p> <p>We have paper craft airplanes in stock. Some are just for display, and others actually fly. We can help your project and teach you techniques in paper crafts when you need. If you are interested, <a href="https://t.me/mkrsgh">contact us on Telegram</a>.</p>Tomoyuki SakuraiOur open house event at Makers Siem Reap the last weekends, Kids made a paper glider. Paper craft is not just an activity for kids at school, but a serious art. Here is the summary of the class.First electronics class for kids at Makers Siem Reap2022-09-05T00:00:00+00:002022-09-05T00:00:00+00:00http://info.mkrsgh.org/blog/makerspace/2022/09/05/First-Electronics-Class-for-Kids-at-Makers-Siem-Reap<p>The last Sunday was the longest day in my life in Cambodia: the first day of my class for kids at Makers Siem Reap. Here is the summary.</p> <figure class=""> <a href="/assets/img/posts/the-led-candle.jpg" class="image-popup"> <img src="/assets/img/posts/resized/the-led-candle-800x544.jpg" alt="top and bottom view of the LED candle" srcset=" /assets/img/posts/resized/the-led-candle-480x326.jpg 480w, /assets/img/posts/resized/the-led-candle-800x544.jpg 800w, /assets/img/posts/the-led-candle.jpg 1022w" /> </a> <figcaption> The LED candle </figcaption> </figure> <p>The project the students worked on was an LED candle with ATtiny13a, a project I designed a few weeks ago. The project is simple to design, yet challenging to implement. Two subjects in the class; understanding different noises and soldering. The latter is the most difficult part.</p> <h2 id="pink-noise-or-1f-noise">Pink noise, or 1/f noise</h2> <p>Pink noise, or 1/f noise, is a noise human being feel comfortable with. Pink noise can be found everywhere. Sound of river, speed of breeze, and activities of neurons, all of them have pink noise. Unlike a pure random noise, or white noise, it has a specific tendency in its frequencies. It is used in many products and services; modern electric fans have a button to change rhythm of wind speed, music broadcasting services often provides “natural sounds” to which users listen before sleeping. LED candles in the market realistically <strong>flick</strong> the fire in one way or another. My LED candle has a simple pseudo pink noise generator to flick the fire, using simple math operations. Students saw the difference between white and pink noise, and how they look.</p> <h2 id="soldering">Soldering</h2> <p>I have been soldering for decades, yet, I am not very good at it. Some might say soldering is too difficult for kids. I would say “it is difficult for anyone”. The circuit board used was a paper universal board, which is cheap, and easy to cut. The following video, which is edited very well, explains basic techniques and common mistakes.</p> <style> .embed-container { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 80%; } .embed-container iframe, .embed-container object, .embed-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } </style> <div class="embed-container"> <iframe title="YouTube video player" width="640" height="390" src="//www.youtube.com/embed/6rmErwU5E-k" frameborder="0" allowfullscreen=""></iframe> </div> <p>The components are: an LED, two 3D objects (fire and candle), a resistor, a sliding switch, a paired wire, and a coin-cell battery holder. The circuit is super simple; nothing more than <a href="https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink">the Blink</a> circuit. However, it turned out that routing signal lines on the board was the most difficult part. I will design a proper PCB with printed copper traces so that students need to solder just components. Students learnt soldering techniques, such as the basics and pre-soldering. As a safety measure, which has the lowest priority in this country, they had to wear protective goggles during the work. Luckily, nobody got burns. From now on, they can proudly say “I did it before!”.</p> <figure class=""> <a href="/assets/img/posts/kids-soldering.jpg" class="image-popup"> <img src="/assets/img/posts/resized/kids-soldering-1500x1000.jpg" alt="Kids are soldering in the class for the first time in their life" srcset=" /assets/img/posts/resized/kids-soldering-480x320.jpg 480w, /assets/img/posts/resized/kids-soldering-800x533.jpg 800w, /assets/img/posts/resized/kids-soldering-1500x1000.jpg 1500w, /assets/img/posts/kids-soldering.jpg 2048w" /> </a> <figcaption> Soldering for the first time in their life </figcaption> </figure> <p>In a conversation with a mother, there seems to be a real demand for modern educational programs. There are international schools for expats (naturally, they have better programs and environments than local ones), yet no STEM program exists. It was my guess, but a conviction now.</p> <p>After longer-than-planned hours, they finished their work. The final ritual of making a circuit: powering the circuit. It’s always a mix of a hope and an anxiety. You made a lot of efforts to do everything right, yet are unsure that the efforts were enough. When not enough, you usually see “magic smoke”, the smoke as a result of short circuits. Or, nothing at all. Luckily, they shouted “it worked!”. The words all engineers love to hear. The LED candles were happily flickering.</p> <h2 id="the-lesson-learnt">The lesson learnt</h2> <p>I will make a printed PCB with component marking silk on it, instead of a universal board, so that students can focus on soldering components. With that improvements, the class will be shorter.</p> <p>I will give more information to possible students and parents, Some were not able to join the class due to limited resources. Definitely, I need extra activities which requires less supervision so that others can enjoy them while I am teaching and monitoring the class for possible accidents. I already have some ideas, but I was too focused on my first class for kids yesterday. Here, I would like to apologize them for not meeting their expectations.</p> <h2 id="the-led-candle-project">The LED candle project</h2> <p><img src="https://raw.githubusercontent.com/trombik/kicad-led-candle/main/kicad/led-candle.svg" alt="the schematic of the LED candle" /></p> <p>The project is published on GitHub, including the schematic, and the 3D objects, which can be found at: <a href="https://github.com/trombik/kicad-led-candle">trombik/kicad-led-candle</a>. The code, <a href="https://github.com/trombik/kicad-led-candle/blob/main/src/main.c">main.c</a>, is written in Arduino, but there are very few Arduino functions (<code class="language-plaintext highlighter-rouge">pinMode()</code> and <code class="language-plaintext highlighter-rouge">digitalWrite()</code>). They are easy to replace with pure C counterparts. It is possible to replace the logic of noise generation, from pink to white noise, using a C preprocessor variable to see the difference.</p> <h2 id="final-words">Final words</h2> <p>The class was hit-and-miss. I did well in some areas, but not in others. The class will be better. If you are interested, let us know. You can contact me on Telegram (the user name is <a href="https://t.me/mkrsgh">@mkrsgh</a>) in advance. A kid must be attended with a parent or a guardian. We are open for public any time. I will explain what kids and parents can do at Makers when you stop by. On weekends, from 10:00 to 14:00, there will be various activities for kids (and parents!). We are just next door to <a href="https://www.babelsiemreap.com/">Babel Guesthouse</a>, near the National 6 and Wat Bor road. If kids have specific subjects to learn, I love to hear. I promise your kids will have a unique experience.</p> <iframe width="100%" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://www.openstreetmap.org/export/embed.html?bbox=103.86054039001466%2C13.357663974686954%2C103.86401116847993%2C13.361995949512423&layer=mapnik&marker=13.359829971822904%2C103.8622784614563" style="border: 1px solid black"></iframe> <p><br /><small><a href="https://www.openstreetmap.org/?mlat=13.35983&mlon=103.86228#map=18/13.35983/103.86228&layers=N">View Larger Map</a></small></p>Tomoyuki SakuraiThe last Sunday was the longest day in my life in Cambodia: the first day of my class for kids at Makers Siem Reap. Here is the summary.What I teach in my class at Makers2022-08-25T00:00:00+00:002022-08-25T00:00:00+00:00http://info.mkrsgh.org/blog/makerspace/2022/08/25/What-I-Teach-in-Class-at-Makers<p>When I started my electronics class, I was not sure how it would go. After months, the students finally write actual code that does something more than blinking an LED.</p> <p>The class started from the very basics, such as what the voltage is, how electrons flow in a circuit, and how to break (and save) an LED. They have been thorough the Ohms law, measuring voltage and current, testing circuits, programming the Blink, controlling GPIO pins, understanding how MOSFET works, using Pulse Width Modulation, controlling I2C devices, and using libraries in C++. Without any electronics background, that was a huge achievement for them.</p> <figure class=""> <a href="/assets/img/posts/a-female-student.jpg" class="image-popup"> <img src="/assets/img/posts/resized/a-female-student-800x1067.jpg" alt="She is the fastest learner in my class" srcset=" /assets/img/posts/resized/a-female-student-480x640.jpg 480w, /assets/img/posts/resized/a-female-student-800x1067.jpg 800w, /assets/img/posts/a-female-student.jpg 1500w" /> </a> <figcaption> She is the fastest learner in my class </figcaption> </figure> <p>One of my students has always good questions. She is very curious. While I was explaining an electronic component in a circuit, she asked “what is that component?”. I was very happy for noticing it. Even though the component was not the subject of the class, I tried to explain what it is. Curiosity makes the learning process fun. Unsurprisingly, she is the fastest learner.</p> <figure class=""> <a href="/assets/img/posts/a-male-student.jpg" class="image-popup"> <img src="/assets/img/posts/resized/a-male-student-1500x1125.jpg" alt="Making the first circuit in his life" srcset=" /assets/img/posts/resized/a-male-student-480x360.jpg 480w, /assets/img/posts/resized/a-male-student-800x600.jpg 800w, /assets/img/posts/resized/a-male-student-1500x1125.jpg 1500w, /assets/img/posts/a-male-student.jpg 2000w" /> </a> <figcaption> Making the first circuit in his life </figcaption> </figure> <p>Another student has his own objectives. He is quiet, and has not explained what exactly he would like to achieve in my class. However, I am sure he has his own goals. The last week, he made, unusually, a request: he would like to learn 3D design because he would like to make a case for his bare hard disk, probably a hard disk he salvaged from a computer. Engineering is to solve a problem. He found his own problem that he wants to solve. That is the best motivation in learning. Be it learning a language, making food, or anything, it is always good to have problems. Like, “I want to be steady with the (boy|girl)”, “I want to make my parents happier by making a dinner for them”. When you have motivations, learning is not a burden.</p> <p>Very few students in this country have opportunity to learn modern technologies. Although some universities allege they teach “IT”, their definition of “IT” is not same as ours. Well, the definition of “IT” is vague. I don’t now what it really means. However, I do know that it does not mean how to use Word or Excel. Some say “you should do your business in Phnom Penh” but if you can afford education in the capital, you do not need me.</p> <figure class=""> <a href="/assets/img/posts/Sharp_MZ-80K_computer.jpg" class="image-popup"> <img src="/assets/img/posts/resized/Sharp_MZ-80K_computer-800x601.jpg" alt="MZ-80K, a Z80A-compatible, 8 bit computer (Wikipedia)" srcset=" /assets/img/posts/resized/Sharp_MZ-80K_computer-480x360.jpg 480w, /assets/img/posts/resized/Sharp_MZ-80K_computer-800x601.jpg 800w, /assets/img/posts/Sharp_MZ-80K_computer.jpg 1023w" /> </a> <figcaption> MZ-80K, a Z80A-compatible, 8 bit computer (<a href="https://en.wikipedia.org/wiki/Sharp_MZ">Wikipedia</a>) </figcaption> </figure> <p>My hope was that, firstly, my class would help students like me. I was one of very rare kids who love computer. At that time, computer was rare, no geeky friends in the class, and nobody knew programming. As I did not have a computer, my first program was on a paper. The only computer I could use was MZ-80K (see the above picture) at a local children’s center. In a rural town, nobody was able to teach me programming. My teacher was a BASIC reference manual by the manufacture (at that time, a computer came with a computer language manual!). It would be great if I could help children in a similar situation.</p> <p>Secondly, I would like to provide timely help when they need. Unlike when I was a kid, there are many online resources. You can learn many things online. However, you need a guide whom you can ask. Which website is better to learn X? There are many websites that teach you important health information, or so they claim, for instance. What would you do if something does not work as expected? Subtle details matter in computing. My responsibility is to help students when they need help with what they need.</p> <p>The learning process in the class is not only meant for electronics nor programming. Students have to use their hands, understand why theories do not work in practice, and realize why details matter. Real hands-on experience. They learn theories, build circuits, and see real electronic signal in circuits. You can learn much more than that by reading text books, but knowledges and theories do not work without experimentations which I provide in my class.</p> <p>The life of computer engineers is called “dog-year”. A dog’s life is usually 10, or 20 years, while human-being’s life is much longer. An year for a dog is like 7-10 years for human-being. As a result, an year for dogs passes much faster. Engineers, especially computer engineers, must learn much faster than any other jobs. New technology today will be obsoleted the next year. Now, this is true in any other job today. You have to catch up any new technology to maximize your value in the market. After COVID-19, teachers are expected to know how to teach in an online class room. Cashiers are expected to be familiar with online ordering systems. Like it or not, you have to keep learning. The world where you could stick to a specific skill is in the history book. But if you know “how to learn”, you don’t have to be afraid, and that is what I really want to teach. It is challenging, but you don’t have to be afraid.</p>Tomoyuki SakuraiWhen I started my electronics class, I was not sure how it would go. After months, the students finally write actual code that does something more than blinking an LED.A simple Arduino kitchen timer2022-06-10T00:00:00+00:002022-06-10T00:00:00+00:00http://info.mkrsgh.org/blog/makerspace/2022/06/10/Simple-Arduino-Kitchen-Timer<p>As an example for beginners, I needed an example program that does a simple thing, with very few standard functions of Arduino. Here is an example Arduino program; a simple kitchen timer.</p> <p>The program uses just a few standard functions;</p> <ul> <li><a href="https://www.arduino.cc/reference/en/language/functions/digital-io/digitalwrite/">digitalWrite()</a></li> <li><a href="https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/">digitalRead()</a></li> <li><a href="https://www.arduino.cc/reference/en/language/functions/time/delay/">delay()</a></li> </ul> <p>This article is a brief summary of one of my electronics classes on every weekends.</p> <h2 id="requirements">Requirements</h2> <p>The kitchen timer has a tactile switch, and an LED. Here is what the kitchen timer does. It should:</p> <ul> <li>Start the timer when the button is pressed</li> <li>Blink the LED at low frequency (1 Hz) until the timer reaches the defined time (<code class="language-plaintext highlighter-rouge">WAIT_TIME_SEC</code>, 7 seconds).</li> <li>Blink the LED at a high frequency when the timer reaches the defined time.</li> </ul> <p>As an example for beginners, it also should:</p> <ul> <li>Use input and output</li> <li>Use a few standard functions (<code class="language-plaintext highlighter-rouge">digitalRead()</code>, <code class="language-plaintext highlighter-rouge">digitalWrite()</code>, and <code class="language-plaintext highlighter-rouge">delay()</code>)</li> <li>Use a few commonly-available components</li> </ul> <h2 id="materials">Materials</h2> <ul> <li>Arduino Nano, or Arduino Uno</li> <li>Jumper wires</li> <li>An LED (any color) and a current limiting resistor (1K ohms should work with any LED)</li> <li>A tactile switch</li> <li>A breadboard</li> </ul> <h2 id="schematic">Schematic</h2> <figure class=""> <img src="/assets/img/posts/arduino-kitchen-timer.svg" alt="Schematic of the simple Arduino kitchen timer" /><figcaption> the schematic of the simple Arduino kitchen timer </figcaption></figure> <h2 id="wiring">Wiring</h2> <figure class=""> <img src="/assets/img/posts/arduino-kitchen-timer.jpg" alt="Schematic of the simple Arduino kitchen timer" /><figcaption> the schematic of the simple Arduino kitchen timer </figcaption></figure> <p>Connect a tactile switch to <code class="language-plaintext highlighter-rouge">START_BUTTON_GPIO_NUM</code> (<code class="language-plaintext highlighter-rouge">D9</code>) pin. Connect the other pin of the tactile switch to <code class="language-plaintext highlighter-rouge">GND</code>. As commented in the schematic, <code class="language-plaintext highlighter-rouge">D9</code> is an input pin with the internal pull-up resistor enabled. That means, when the button is not pressed, the voltage is VCC, or +5V. When pressed, it’s 0V. Thanks to the internal pull-up resistor, the pin does not make short-circuit.</p> <p>Connect an LED to <code class="language-plaintext highlighter-rouge">LED_GPIO_NUM</code> (<code class="language-plaintext highlighter-rouge">D10</code>) pin with a resistor. 1K resistor should work regardless of the color of the LED.</p> <h2 id="the-program">The program</h2> <p>The program does include some comments. Note that they are intended for my students.</p> <script src="https://gist.github.com/trombik/61b779f20bbe2e658ea873b5c5f8b9b7.js"></script> <h3 id="define"><code class="language-plaintext highlighter-rouge">#define</code></h3> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#define LED_GPIO_NUM (10) #define START_BUTTON_GPIO_NUM (9) </span> <span class="cp">#define WAIT_TIME_SEC (7) #define WAIT_TIME_MS (WAIT_TIME_SEC * 1000) </span> <span class="cp">#define DELAY_TIME_SEC (0.5) #define DELAY_TIME_MS (DELAY_TIME_SEC * 1000) </span></code></pre></div></div> <p><code class="language-plaintext highlighter-rouge">#define</code> defines a macro variable. This is not a C or C++ function, but a C++ preprocessor statement. These macro variables are replaced by the preprocessor at <em>compile time</em>. Examples:</p> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#define SOME_TEXT "Some text here" </span></code></pre></div></div> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#define SOME_NUMBER (1) </span></code></pre></div></div> <p>Every time C preprocessor encounters <code class="language-plaintext highlighter-rouge">SOME_TEXT</code> or <code class="language-plaintext highlighter-rouge">SOME_NUMBER</code>, the macro variables are replaced with their values. When the value is a number, always enclose it with <code class="language-plaintext highlighter-rouge">()</code>, which prevents surprises. Without <code class="language-plaintext highlighter-rouge">()</code>, it works sometimes, and not always. An example:</p> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#define TWO 1 + 1 </span></code></pre></div></div> <p>This defines <code class="language-plaintext highlighter-rouge">TWO</code> as number 2. When you multiply it, the result is a surprise.</p> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#define TWO 1 + 1 </span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">TWO</span> <span class="o">*</span> <span class="mi">2</span><span class="o">:</span> <span class="c1">// i is 3.</span> </code></pre></div></div> <p>This is because of the precedence in the math. The actual code after preprocessing is:</p> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">+</span> <span class="mi">1</span> <span class="o">*</span> <span class="mi">2</span><span class="p">;</span> </code></pre></div></div> <p>To define numbers, always enclose them with <code class="language-plaintext highlighter-rouge">()</code> to avoid this problem.</p> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#define TWO (1 + 1) </span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">TWO</span> <span class="o">*</span> <span class="mi">2</span><span class="p">;</span> <span class="c1">// i is 4.</span> </code></pre></div></div> <p>Macro variables should have a unit at the end so that readers understand what it is not only from the name, but also the unit. <code class="language-plaintext highlighter-rouge">WAIT_TIME_MS</code> is clearer than <code class="language-plaintext highlighter-rouge">WAIT_TIME</code> because it is evident that the variable is time in seconds. <code class="language-plaintext highlighter-rouge">_MS</code> is often used to represent as milliseconds.</p> <h3 id="global-variables">Global variables</h3> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">started_time_ms</span><span class="p">;</span> <span class="kt">int</span> <span class="n">led_state</span><span class="p">;</span> </code></pre></div></div> <p>The program needs to remember two things; time when the timer has started and the state of the led. As these are referenced in functions, they need to be a global variable.</p> <p>To obtain time, <a href="https://www.arduino.cc/reference/en/language/functions/time/millis/"><code class="language-plaintext highlighter-rouge">millis()</code></a> is used. <code class="language-plaintext highlighter-rouge">millis()</code> returns a value in <code class="language-plaintext highlighter-rouge">unsigned long</code>, not <code class="language-plaintext highlighter-rouge">int</code>. To obtain voltage of GPIO pins, <a href="https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/"><code class="language-plaintext highlighter-rouge">digitalRead()</code></a> is used. It returns <code class="language-plaintext highlighter-rouge">HIGH</code> or <code class="language-plaintext highlighter-rouge">LOW</code> as <code class="language-plaintext highlighter-rouge">int</code>.</p> <h3 id="the-setup-function">The <code class="language-plaintext highlighter-rouge">setup</code> function</h3> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">setup</span><span class="p">()</span> <span class="p">{</span> <span class="n">pinMode</span><span class="p">(</span><span class="n">LED_GPIO_NUM</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span> <span class="cm">/* enable input on START_BUTTON_GPIO_NUM pin with a pullup resistor */</span> <span class="n">pinMode</span><span class="p">(</span><span class="n">START_BUTTON_GPIO_NUM</span><span class="p">,</span> <span class="n">INPUT_PULLUP</span><span class="p">);</span> <span class="n">initializeLED</span><span class="p">();</span> <span class="n">waitForeverUntilButtonIsPressed</span><span class="p">();</span> <span class="n">resetTimer</span><span class="p">();</span> <span class="p">}</span> </code></pre></div></div> <p>The <code class="language-plaintext highlighter-rouge">setup()</code> below does four things:</p> <ol> <li>configure <code class="language-plaintext highlighter-rouge">LED_GPIO_NUM</code> pin as output</li> <li>configure <code class="language-plaintext highlighter-rouge">START_BUTTON_GPIO_NUM</code> pin as input with an internal pull-up resistor enabled</li> <li>initialize the LED</li> <li>wait until the button switch is pressed</li> <li>reset the timer and start</li> </ol> <p>Except <code class="language-plaintext highlighter-rouge">INPUT_PULLUP</code>, everything is straightforward. What is <code class="language-plaintext highlighter-rouge">INPUT_PULLUP</code>?</p> <p>A pull-up resistor (and a pull-down resistor) is a resistor to keep a voltage at a certain level, usually, <code class="language-plaintext highlighter-rouge">VCC</code>. Here is three switches as input, without a resistor, with a pull-up resistor, and with a pull-down resistor.</p> <figure class=""> <img src="/assets/img/posts/pullup-and-pulldown-resistors.svg" alt="Switches as input, with a pull-up resistor, with a pull-down resistor, and without a resistor." /><figcaption> Switches as input, with a pull-up resistor, with a pull-down resistor, and without a resistor. </figcaption></figure> <p>The first one — without a resistor — is dangerous, and you should not use it because, when you push <code class="language-plaintext highlighter-rouge">SW2</code>, <code class="language-plaintext highlighter-rouge">VCC</code> and <code class="language-plaintext highlighter-rouge">GND</code> are connected, which is a short-circuit. There should be something that prevents the short-circuit. Pull-up resistor and pull-down resistor do that job.</p> <p>The second one has a pull-up resistor, <code class="language-plaintext highlighter-rouge">R2</code>. When the switch, <code class="language-plaintext highlighter-rouge">SW3</code>, is open, the voltage at the <code class="language-plaintext highlighter-rouge">GPIO</code> is <code class="language-plaintext highlighter-rouge">VCC</code> (the resistor <em>pulls up</em> the voltage to <code class="language-plaintext highlighter-rouge">VCC</code>). When the switch is closed, the voltage is 0V.</p> <p>The third one has a pull-down resistor, <code class="language-plaintext highlighter-rouge">R3</code>. When the switch, <code class="language-plaintext highlighter-rouge">SW4</code>, is open, the voltage at the <code class="language-plaintext highlighter-rouge">GPIO</code> is 0V (the resistor <em>pulls down</em> the voltage to <code class="language-plaintext highlighter-rouge">GND</code>). When the switch is closed, the voltage is <code class="language-plaintext highlighter-rouge">VCC</code>.</p> <p>The value of pull-up, and pull-down resistors is usually 10K ohm or so. The value affects the current when the switch is opened or closed. When <code class="language-plaintext highlighter-rouge">VCC</code> is 5V, the current is $ I = { V \over R } = { 5 \over 10,000 } = 0.5 (mA)$.</p> <p>Some GPIO pins have <em>internal</em> pull-up resistors built-in. If you enable one with <code class="language-plaintext highlighter-rouge">pinMode(pin, INPUT_PULLUP)</code>, it is not necessary to add an external pull-up resistor to the switch because the pin is internally connected to <code class="language-plaintext highlighter-rouge">VCC</code> through a pull-up resistor.</p> <h3 id="the-loop-function">the <code class="language-plaintext highlighter-rouge">loop()</code> function</h3> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">loop</span><span class="p">()</span> <span class="p">{</span> <span class="n">delay</span><span class="p">(</span><span class="n">DELAY_TIME_MS</span><span class="p">);</span> <span class="cm">/* millis() returns the current time since the micro computer started. * the return value is an unsigned int. */</span> <span class="k">if</span> <span class="p">(</span><span class="n">started_time_ms</span> <span class="o">+</span> <span class="n">WAIT_TIME_MS</span> <span class="o"><=</span> <span class="n">millis</span><span class="p">())</span> <span class="p">{</span> <span class="n">notifyUser</span><span class="p">();</span> <span class="n">waitForeverUntilButtonIsPressed</span><span class="p">();</span> <span class="n">initializeLED</span><span class="p">();</span> <span class="n">resetTimer</span><span class="p">();</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">toggleLED</span><span class="p">();</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <p>In the <code class="language-plaintext highlighter-rouge">loop()</code>, it has a <code class="language-plaintext highlighter-rouge">delay()</code> and a <code class="language-plaintext highlighter-rouge">if-else</code>. <code class="language-plaintext highlighter-rouge">started_time_ms</code> holds the time in millisecond when the timer has started. <code class="language-plaintext highlighter-rouge">WAIT_TIME_MS</code> — a macro variable — is <code class="language-plaintext highlighter-rouge">7000</code>. <code class="language-plaintext highlighter-rouge">started_time_ms + WAIT_TIME_MS</code> is the time when the timer should notify the user. Otherwise, toggle the LED, i.e. if the lED is on, turn it off and vice versa.</p> <h3 id="initializeled">initializeLED()</h3> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">initializeLED</span><span class="p">()</span> <span class="p">{</span> <span class="n">led_state</span> <span class="o">=</span> <span class="n">LOW</span><span class="p">;</span> <span class="n">digitalWrite</span><span class="p">(</span><span class="n">LED_GPIO_NUM</span><span class="p">,</span> <span class="n">led_state</span><span class="p">);</span> <span class="p">}</span> </code></pre></div></div> <p>The function sets <code class="language-plaintext highlighter-rouge">led_state</code> to <code class="language-plaintext highlighter-rouge">LOW</code>, the initial state. Nothing new here.</p> <h3 id="isbuttonpressed">isButtonPressed()</h3> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">bool</span> <span class="nf">isButtonPressed</span><span class="p">()</span> <span class="p">{</span> <span class="cm">/* if (digitalRead(START_BUTTON_GPIO_NUM) == LOW) { return true; } else { return false; } */</span> <span class="cm">/* same as the above code */</span> <span class="k">return</span> <span class="n">digitalRead</span><span class="p">(</span><span class="n">START_BUTTON_GPIO_NUM</span><span class="p">)</span> <span class="o">==</span> <span class="n">LOW</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>The function returns <code class="language-plaintext highlighter-rouge">true</code> or <code class="language-plaintext highlighter-rouge">false</code>. If <code class="language-plaintext highlighter-rouge">START_BUTTON_GPIO_NUM</code> is <code class="language-plaintext highlighter-rouge">LOW</code>, return <code class="language-plaintext highlighter-rouge">true</code> (the button is pressed). Otherwise, <code class="language-plaintext highlighter-rouge">false</code>.</p> <h3 id="toggleled">toggleLED()</h3> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">toggleLED</span><span class="p">()</span> <span class="p">{</span> <span class="cm">/* if (led_state == HIGH) { led_state = LOW; } else { led_state = HIGH; } */</span> <span class="cm">/* same as the above code. it's called a "ternary operator". * x = condition ? condition is true : condition is false */</span> <span class="n">led_state</span> <span class="o">=</span> <span class="n">led_state</span> <span class="o">==</span> <span class="n">HIGH</span> <span class="o">?</span> <span class="n">LOW</span> <span class="o">:</span> <span class="n">HIGH</span><span class="p">;</span> <span class="n">digitalWrite</span><span class="p">(</span><span class="n">LED_GPIO_NUM</span><span class="p">,</span> <span class="n">led_state</span><span class="p">);</span> <span class="p">}</span> </code></pre></div></div> <p>The function <em>toggle</em> the LED. Instead of <code class="language-plaintext highlighter-rouge">if-else</code>, a ternary operator is used as a short-hand.</p> <h2 id="further-improvements">Further improvements</h2> <p>This kitchen timer is so simple and it has a room for improvements.</p> <p>The kitchen timer only blinks the LED. When making food, you do not want to watch the timer. Instead, the timer should beep, optionally blink the LED.</p> <p>The timer is a fixed timer, namely 7 seconds. This is not very practical. Users should be able to set arbitrary time period, such as 1 minutes, 7 minutes and 30 seconds.</p> <p>The only feedback is the LED. Users should be able to know the remaining time. The timer should show the remaining time in a display in real time.</p> <p>When the button is not pressed for a while and the timer has NOT started, say 5 minutes, it should sleep to save power.</p> <h2 id="final-words">Final words</h2> <p>This post is a summary of my class. Of course, I teach more than what is described here, usually in two 2-hours classes, depending on the skill level of students. If you can understand everything by reading this post, you don’t have to attend the class. If you don’t, join the class where I will explain and answers all your questions.</p> <p>Happy hacking!</p>Tomoyuki SakuraiAs an example for beginners, I needed an example program that does a simple thing, with very few standard functions of Arduino. Here is an example Arduino program; a simple kitchen timer.Simple doorbell button example with esphome2022-06-07T00:00:00+00:002022-06-07T00:00:00+00:00http://info.mkrsgh.org/blog/makerspace/2022/06/07/Simple-Doorbell-Button-Example-with-esphome<p><code class="language-plaintext highlighter-rouge">esphome</code> is a framework for ESP32 and ESP8266 with which you can create simple devices by just writing YAML files instead of writing code. I choose <code class="language-plaintext highlighter-rouge">esphome</code> when the device I need is simple because, in simple devices, I do not have to write same code again and again. <code class="language-plaintext highlighter-rouge">esphome</code> provides components for common tasks, such as OTA, Web interface of the device, and Home Assistant integration.</p> <p>I need a doorbell-over-WiFi that does a simple thing, notifying me when pressed. I used a slack channel for notifications from my devices. That means, the device should send a message to the channel, and my phone pops up a notification on screen.</p> <h2 id="requirements">Requirements</h2> <ul> <li>it posts a message to a <a href="https://slack.com/">slack</a> channel when a button is pressed</li> <li>it works on a battery so that I can install it anywhere</li> <li>it is a simple device that anyone can build in a few minutes as an example of <code class="language-plaintext highlighter-rouge">esphome</code></li> </ul> <p>From the requirements, you definitely need to deep sleep the device. ESP8266 is a WiFi device, and WiFi requires more power than other wireless protocols. The device should wake up only when the button is pressed. Otherwise, sleep.</p> <p>I chose slack for the notification channel, but many chat services provide APIs to post messages. With small modifications to the configuration, it should be easy to post messages to other services.</p> <h2 id="esp8266-and-deep-sleep">ESP8266 and deep sleep</h2> <p>ESP8266 in deep sleep consumes very few power, like a few micro ampere. You can run ESP8266 on battry more than a year (<a href="https://makecademy.com/esp8266-battery">How to Run Your ESP8266 for Years on a Battery</a>).</p> <p>To enable deep sleep, you need to connect <code class="language-plaintext highlighter-rouge">GPIO16</code> to <code class="language-plaintext highlighter-rouge">RST</code>. On NodeMCU, <code class="language-plaintext highlighter-rouge">GPIO16</code> is labeled as <code class="language-plaintext highlighter-rouge">D0</code>. During the sleep, the voltage is HIGH.</p> <p>To wake up the device, you need a rising edge signal on <code class="language-plaintext highlighter-rouge">RST</code> pin. As the voltage is HIGH in deep sleep, you need to pull the voltage of the pin to LOW, and then HIGH. This can be implemented with a simple button (normally open).</p> <p>A pin of the button is connected to <code class="language-plaintext highlighter-rouge">GPIO16</code> and <code class="language-plaintext highlighter-rouge">RST</code>, and another to <code class="language-plaintext highlighter-rouge">GND</code>. When the button is not pressed, the voltage is HIGH. When pressed, the voltage is LOW, and when released, the voltage is HIGH. This creates a rising signal.</p> <p>As a feedback and for debugging, an LED should indicate request status. Say, short blinks on success, and a longer blink on failure.</p> <h2 id="materials">Materials</h2> <ul> <li>a ESP8266 development board</li> <li>a USB cable</li> <li>an LED and a resistor to limit current through the LED (1K ohm should work fine)</li> <li>a tact switch, or a button</li> <li>some wires and a breadboard</li> </ul> <h2 id="schematic">Schematic</h2> <figure class=""> <img src="/assets/img/posts/esp-doorbell-schematic.svg" alt="esp-doorbell schematic" /><figcaption> the schematic of esp-doorbell </figcaption></figure> <h2 id="the-esphome-configuration">The <code class="language-plaintext highlighter-rouge">esphome</code> configuration</h2> <p>Here, I will explain the configuration sections. The latest code in GitHub can be found at <a href="https://github.com/trombik/esphome-makers/blob/main/config/backgarden-switch-doorbell-1.yml">my GitHub repository</a>.</p> <p>Each section has links to the official documentation. Remember to read them.</p> <h3 id="substitutions-section">Substitutions section</h3> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span> <span class="c1"># common strings used throughout the program. something unique to the device.</span> <span class="na">substitutions</span><span class="pi">:</span> <span class="na">myname</span><span class="pi">:</span> <span class="s">backgarden-doorbell-1</span> <span class="na">location</span><span class="pi">:</span> <span class="s2">"</span><span class="s">backgarden"</span> </code></pre></div></div> <p><code class="language-plaintext highlighter-rouge">substitutions</code> is used to replace strings. They are like macros. You can reference them in the configuration. My devices always have <code class="language-plaintext highlighter-rouge">location</code> in <code class="language-plaintext highlighter-rouge">substitutions</code> because I need to know device’s location, and embed the location in messages or logs. To reference them, use <code class="language-plaintext highlighter-rouge">${location}</code>. When <code class="language-plaintext highlighter-rouge">esphome</code> parses and compiles the configuration, <code class="language-plaintext highlighter-rouge">${location}</code> is replaced with its value.</p> <p>See the official documentation at <a href="https://esphome.io/guides/configuration-types.html?#substitutions">Substitutions</a>.</p> <h3 id="esphome-section">esphome section</h3> <p>This is the core of the configuration. All the logics to meet the requirements are implemented here.</p> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">esphome</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">${myname}</span> <span class="na">on_boot</span><span class="pi">:</span> <span class="c1"># post a message to slack upon boot. with priority higher than 200, the</span> <span class="c1"># network is available.</span> <span class="c1"># see:</span> <span class="c1"># https://esphome.io/components/esphome.html#on-boot</span> <span class="c1"># https://esphome.io/components/http_request.html</span> <span class="na">priority</span><span class="pi">:</span> <span class="m">200</span> <span class="na">then</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">http_request.post</span><span class="pi">:</span> <span class="c1"># the URL of slack web hook.</span> <span class="na">url</span><span class="pi">:</span> <span class="kt">!secret</span> <span class="s">slack_webhook_url_esphome_doorbell</span> <span class="c1"># disable TLS verification because it does not work on ESP8266.</span> <span class="na">verify_ssl</span><span class="pi">:</span> <span class="no">false</span> <span class="na">headers</span><span class="pi">:</span> <span class="na">Content-Type</span><span class="pi">:</span> <span class="s">application/json</span> <span class="na">json</span><span class="pi">:</span> <span class="c1"># see how to format at:</span> <span class="c1"># https://api.slack.com/reference/surfaces/formatting</span> <span class="na">text</span><span class="pi">:</span> <span class="kt">!lambda</span> <span class="pi">|-</span> <span class="s">snprintf(id(buf), sizeof(id(buf)), "@here Someone pushed me at %s", "${location}");</span> <span class="s">return id(buf);</span> <span class="c1"># enable group mention, makes `@here` work</span> <span class="na">link_names</span><span class="pi">:</span> <span class="s2">"</span><span class="s">true"</span> <span class="c1"># give feedback to users. was it successful?</span> <span class="na">on_response</span><span class="pi">:</span> <span class="na">then</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">if</span><span class="pi">:</span> <span class="na">condition</span><span class="pi">:</span> <span class="na">lambda</span><span class="pi">:</span> <span class="s2">"</span><span class="s">return</span><span class="nv"> </span><span class="s">status_code</span><span class="nv"> </span><span class="s">==</span><span class="nv"> </span><span class="s">200;"</span> <span class="c1"># when success, blink the LED twice</span> <span class="na">then</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">output.turn_on</span><span class="pi">:</span> <span class="s">led</span> <span class="pi">-</span> <span class="na">delay</span><span class="pi">:</span> <span class="s">0.3s</span> <span class="pi">-</span> <span class="na">output.turn_off</span><span class="pi">:</span> <span class="s">led</span> <span class="pi">-</span> <span class="na">delay</span><span class="pi">:</span> <span class="s">0.3s</span> <span class="pi">-</span> <span class="na">output.turn_on</span><span class="pi">:</span> <span class="s">led</span> <span class="pi">-</span> <span class="na">delay</span><span class="pi">:</span> <span class="s">0.3s</span> <span class="pi">-</span> <span class="na">output.turn_off</span><span class="pi">:</span> <span class="s">led</span> <span class="c1"># when error happens, blink the LED once, and longer</span> <span class="na">else</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">output.turn_on</span><span class="pi">:</span> <span class="s">led</span> <span class="pi">-</span> <span class="na">delay</span><span class="pi">:</span> <span class="s">3s</span> <span class="pi">-</span> <span class="na">output.turn_off</span><span class="pi">:</span> <span class="s">led</span> <span class="c1"># then, regardless of status code, deep sleep.</span> <span class="pi">-</span> <span class="na">deep_sleep.enter</span><span class="pi">:</span> <span class="na">id</span><span class="pi">:</span> <span class="s">deep_sleep_1</span> </code></pre></div></div> <p><code class="language-plaintext highlighter-rouge">esphome</code> component has several options to configure, and here, I need <code class="language-plaintext highlighter-rouge">on_boot</code>, which is an Automation that runs on boot. When the device boots, <code class="language-plaintext highlighter-rouge">on_boot</code> runs once. It then post a HTTP request to slack web-hook URL.</p> <p>The web-hook URL is encrypted because anyone with the URL can post messages to the slack channel, which is not what you want.</p> <p><code class="language-plaintext highlighter-rouge">http_request.post</code> is an action that posts HTTP requests. The body is a JSON object, and the HTTP header must include <code class="language-plaintext highlighter-rouge">Content-Type: application/json</code>. The JSON object is an API call to slack API. The API are documented at <a href="https://api.slack.com/reference/messaging/payload">Reference: Message payloads</a>. <code class="language-plaintext highlighter-rouge">@here</code> is used in the message text so that slack application on mobile devices or web browser application will notify me of the message.</p> <p>When <code class="language-plaintext highlighter-rouge">http_request.post</code> has received a HTTP response from the API, the device blinks a LED, short blinks on success, and longer blinks on failure.</p> <p>It then enters into deep sleep by calling <code class="language-plaintext highlighter-rouge">deep_sleep.enter</code> action.</p> <p>See the official documentation at <a href="https://esphome.io/components/esphome.html">ESPHome Core Configuration</a>, and <a href="https://esphome.io/guides/automations.html">Automations and Templates</a>.</p> <h3 id="other-sections">Other sections</h3> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">esp8266</span><span class="pi">:</span> <span class="na">board</span><span class="pi">:</span> <span class="s">nodemcuv2</span> </code></pre></div></div> <p><code class="language-plaintext highlighter-rouge">esp8266</code> section configures architecture-specific settings. At least, you need to specify <code class="language-plaintext highlighter-rouge">board</code>.</p> <p>See the official documentation at <a href="https://esphome.io/devices/esp8266.html">Generic ESP8266</a>.</p> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">logger</span><span class="pi">:</span> <span class="na">level</span><span class="pi">:</span> <span class="s">debug</span> <span class="na">debug</span><span class="pi">:</span> <span class="na">update_interval</span><span class="pi">:</span> <span class="s">5s</span> </code></pre></div></div> <p>It is always a good idea to enable debug log. You can see logs over WiFi, or serial port.</p> <p>See the official documentation at <a href="https://esphome.io/components/logger.html">Logger Component</a> and <a href="https://esphome.io/components/debug.html">Debug Component</a>.</p> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">api</span><span class="pi">:</span> <span class="na">password</span><span class="pi">:</span> <span class="kt">!secret</span> <span class="s">api_password</span> </code></pre></div></div> <p><code class="language-plaintext highlighter-rouge">api</code> component enables the device to communicate to other devices, such as <code class="language-plaintext highlighter-rouge">esphome</code> web UI, or Home Assistant. Use <code class="language-plaintext highlighter-rouge">password</code> and protect the communication.</p> <p>See the official documentation at <a href="https://esphome.io/components/api.html">Native API Component</a></p> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># OTA is enabled here but it does not work because the device is almost always</span> <span class="c1"># in deepsleep.</span> <span class="na">ota</span><span class="pi">:</span> <span class="na">password</span><span class="pi">:</span> <span class="kt">!secret</span> <span class="s">ota_password</span> </code></pre></div></div> <p>With <code class="language-plaintext highlighter-rouge">ota</code> component, it is possible to update firmware over WiFi. However, as documented in the comment above, it is very difficult to use OTA if the device is sleeping.</p> <p>See the official documentation at <a href="https://esphome.io/components/ota.html">OTA Update Component</a>.</p> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># the WiFi SSID and password for your network.</span> <span class="na">wifi</span><span class="pi">:</span> <span class="na">ssid</span><span class="pi">:</span> <span class="kt">!secret</span> <span class="s">wifi_ssid</span> <span class="na">password</span><span class="pi">:</span> <span class="kt">!secret</span> <span class="s">wifi_password</span> </code></pre></div></div> <p><code class="language-plaintext highlighter-rouge">wifi</code> component configures WiFi and network settings. Simply provide <code class="language-plaintext highlighter-rouge">ssid</code> and <code class="language-plaintext highlighter-rouge">password</code>.</p> <p>See the official documentation at <a href="https://esphome.io/components/wifi.html">WiFi Component</a>.</p> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">globals</span><span class="pi">:</span> <span class="c1"># a buffer to hold the message string because snprintf(3) is used to create</span> <span class="c1"># the message.</span> <span class="c1">#</span> <span class="c1"># you may remove this and snprintf(3) above if the message is a static,</span> <span class="c1"># fixed message.</span> <span class="pi">-</span> <span class="na">id</span><span class="pi">:</span> <span class="s">buf</span> <span class="na">type</span><span class="pi">:</span> <span class="s">char[512]</span> <span class="na">restore_value</span><span class="pi">:</span> <span class="s">no</span> <span class="na">initial_value</span><span class="pi">:</span> <span class="s2">"</span><span class="s">"</span> </code></pre></div></div> <p><code class="language-plaintext highlighter-rouge">globals</code> is a section to define global variables that you can use in code. Because the message is dynamically created, you need a variable to keep the string.</p> <p>See the official documentation at <a href="https://esphome.io/guides/automations.html">Global Variables</a>.</p> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># to post HTTP requests, you need http_request component.</span> <span class="na">http_request</span><span class="pi">:</span> <span class="na">useragent</span><span class="pi">:</span> <span class="s">esphome/${myname}</span> <span class="na">timeout</span><span class="pi">:</span> <span class="s">10s</span> </code></pre></div></div> <p><code class="language-plaintext highlighter-rouge">http_request</code> component is required to sent HTTP requests.</p> <p>See the official documentation at <a href="https://esphome.io/components/http_request.html">HTTP Request</a>.</p> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">text_sensor</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">platform</span><span class="pi">:</span> <span class="s">wifi_info</span> <span class="na">ip_address</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">ESP IP Address ${myname}</span> <span class="na">ssid</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">ESP Connected SSID ${myname}</span> <span class="na">bssid</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">ESP Connected BSSID ${myname}</span> <span class="na">mac_address</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">ESP Mac Wifi Address ${myname}</span> <span class="na">scan_results</span><span class="pi">:</span> <span class="na">name</span><span class="pi">:</span> <span class="s">ESP Latest Scan Results ${myname}</span> <span class="na">sensor</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">platform</span><span class="pi">:</span> <span class="s">wifi_signal</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">WiFi</span><span class="nv"> </span><span class="s">Signal</span><span class="nv"> </span><span class="s">Sensor</span><span class="nv"> </span><span class="s">${myname}"</span> <span class="na">update_interval</span><span class="pi">:</span> <span class="s">60s</span> <span class="pi">-</span> <span class="na">platform</span><span class="pi">:</span> <span class="s">uptime</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Uptime Sensor ${myname}</span> </code></pre></div></div> <p><code class="language-plaintext highlighter-rouge">wifi_info</code> <code class="language-plaintext highlighter-rouge">text_sensor</code> and <code class="language-plaintext highlighter-rouge">wifi_signal</code> <code class="language-plaintext highlighter-rouge">sensor</code> publish WiFi-related diagnosis information. Useful for debugging. All my devices have these. The information is published to Home Assistant, and you can see it on the web interface.</p> <p>See the official documentation at <a href="https://esphome.io/components/text_sensor/wifi_info.html">WiFi Info Text Sensor</a>, <a href="https://esphome.io/components/sensor/wifi_signal.html">WiFi Signal Sensor</a>, and <a href="https://esphome.io/components/sensor/uptime.html">Uptime Sensor</a>.</p> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># the pin to give feedback with an LED.</span> <span class="na">output</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">platform</span><span class="pi">:</span> <span class="s">gpio</span> <span class="na">pin</span><span class="pi">:</span> <span class="s">D6</span> <span class="na">id</span><span class="pi">:</span> <span class="s">led</span> <span class="na">inverted</span><span class="pi">:</span> <span class="no">false</span> </code></pre></div></div> <p><code class="language-plaintext highlighter-rouge">gpio</code> <code class="language-plaintext highlighter-rouge">output</code> is a component to control GPIO pins. The pin is used to give HTTP status. The component has an <code class="language-plaintext highlighter-rouge">id</code>, and the value is <code class="language-plaintext highlighter-rouge">led</code>. This <code class="language-plaintext highlighter-rouge">id</code> is required to reference this component from other part of the code, <code class="language-plaintext highlighter-rouge">http_request.post</code> action in this example.</p> <p>See the official documentation at <a href="https://esphome.io/components/output/gpio.html">GPIO Output</a>.</p> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">deep_sleep</span><span class="pi">:</span> <span class="na">id</span><span class="pi">:</span> <span class="s">deep_sleep_1</span> <span class="c1"># sleep indefinitely. the max value of sleep_duration on ESP8266 is about 3</span> <span class="c1"># hours 46 minutes. a value bigger than this makes ESP8266 in deep sleep</span> <span class="c1"># indefinitely.</span> <span class="na">sleep_duration</span><span class="pi">:</span> <span class="s">4h</span> </code></pre></div></div> <p><code class="language-plaintext highlighter-rouge">deep_sleep</code> component is used to enter into deep sleep. The component has <code class="language-plaintext highlighter-rouge">id</code> because the component is referenced from the <code class="language-plaintext highlighter-rouge">on_boot</code> automation. As I would like to keep the device in deep sleep until someone presses the button, the <code class="language-plaintext highlighter-rouge">sleep_duration</code> is longer than the max value of <code class="language-plaintext highlighter-rouge">sleep_duration</code>.</p> <p>See the official documentation at <a href="https://esphome.io/components/deep_sleep.html">Deep Sleep Component</a>.</p> <h2 id="limitations">Limitations</h2> <p>The device needs a few seconds to post a message because it needs to boot, configure the WiFi interface, obtain an IP address from DHCP server. It is mostly harmless in this application because I do not need real time notifications. A few seconds delay is acceptable. If you need quick response, here is some ideas.</p> <p>Using static IP address reduces the delay because the devices does not ask DHCP server for an IP address. However, you need to configure a static IP address for the device, and maintain it. To use a static IP address, see <code class="language-plaintext highlighter-rouge">manual_ip</code> option in <a href="https://esphome.io/components/wifi.html">WiFi Component</a>.</p> <p>Disabling WiFi scanning also reduces the delay because it skips scanning for WiFi access points. See <code class="language-plaintext highlighter-rouge">fast_connect</code> option in <a href="https://esphome.io/components/wifi.html">WiFi Component</a>.</p> <p>Using a power source, and disabling deep sleep. The device is up and running all the time, and the response is immediate. However, you have to give up battery operation, and the configuration must be modified.</p> <h2 id="final-words">Final words</h2> <p>Building an <code class="language-plaintext highlighter-rouge">esphome</code> device is easy. However, that does not necessarily mean you don’t have to lean C or C++. Some concepts require understanding of C or C++. <code class="language-plaintext highlighter-rouge">esphome</code> looks simple but it can implement complicated logics, too. You need to understand event-driven programming.</p> <p>Always read the official documentation. Their documentation is generally good (except internal APIs).</p> <p>Happy hacking!</p>Tomoyuki Sakuraiesphome is a framework for ESP32 and ESP8266 with which you can create simple devices by just writing YAML files instead of writing code. I choose esphome when the device I need is simple because, in simple devices, I do not have to write same code again and again. esphome provides components for common tasks, such as OTA, Web interface of the device, and Home Assistant integration.Review: fab-manager2022-05-18T00:00:00+00:002022-05-18T00:00:00+00:00http://info.mkrsgh.org/blog/makerspace/2022/05/18/Review-fab-manager<p>Recently, I found a hidden gem; fab-manager. I was looking for a solution to manage machine reservations for customers. Possible alternatives are: writing a custom Google Forms application, using other generic resource management system, or — drum roll — <em>Excel</em>. I do not like any of them, and accidentally found fab-manager. It looked great, and it actually is. If you are a makerspace with unique subscription models, or need tight integration with other systems, you might better wait for a while. But if you are flexible, fab-manager is a great candidate.</p> <p>Here is my review — or my feature requests. I hope my review does not sound like rants.</p> <h2 id="about-fab-manager">About fab-manager</h2> <p>It is a rails application for makerspaces. You can manage users, machines, reservations, subscriptions, and training classes. <a href="https://www.fab-manager.com/quotation-workshop">The official website</a> explains better than my poor English does. As they have a live demo, give it a try. If you are running a makerspace, you will quickly understand what it does and why you need it.</p> <h2 id="the-documentation-is-sparse">The documentation is sparse</h2> <p>This is the first issue I encountered.</p> <p>The official user guide is <a href="https://github.com/sleede/fab-manager/tree/master/doc/fr">a PDF file</a>, written in French. If you don’t speak French, you have to cross your fingers and hope Google Translate does a good job. The PDF is not generated from code or files in the repository. That means it is possible that the file is out-of-date. I don’t understand French, but noticed some screen captures in the file are not the latest.</p> <p>Managing items like machines, users and other <em>simple</em> settings is not very difficult. They are very similar to ones in other systems. However, settings related to business logics, such as payment, subscriptions, and pricing, are very complicated and, quite possibly, they might cause serious troubles if you don’t understand correctly.</p> <p>Each management UI has <em>feature tour</em>, which navigates you to each UI component and tabs in the page. It is helpful for beginners to learn general ideas.</p> <p>The most difficult part was pricing and subscriptions. The system assumes a business logic, probably a common sales strategy. I cannot find what their assumption is. After a few hours of trial-and-error, I, kind of, was able to guess how they implemented pricing, subscriptions, groups, and tags. If you have a different strategy, it is not possible in the current system.</p> <p>Created subscriptions are shown to users, but it is not clear that what users will get from the subscription. Usually, a subscription offers cheaper rate for reserving machines, and free trainings, but the system shows just subscription name, and expiration date. You can add a text to a subscription, but it is a fixed explanation, meaning, it will not reflect changes when you change the subscription settings. It is possible to attach a file to a subscription, but, of course, the file will not reflect changes.</p> <p>It would be nice to have English documentation.</p> <p>It would be nice if each form fields has a clickable tool-chip help button so that help texts have more details and explanations, and do not overwhelm UI.</p> <p>It would be nice to have a knowledge base article to explain how to implement a sales strategy.</p> <p>It would be nice to have the official knowledge base so that users can jump to a knowledge base article of the current UI.</p> <p>It would be nice to show subscription details with rates, the amount of discount, and other benefits. A comparison table would be nice, too.</p> <h2 id="oauth2-support">OAuth2 support</h2> <p>At the moment, OAuth2 authentication support is limited. It is all or nothing. The default authentication uses the database. If you enable OAuth2, you cannot use the default authentication in addition to OAuth2. It was a surprise that, when I tested OAuth2, my administration account, the one created during the initial installation, was disabled, and I could not manage the system because the account was in the disabled database. You can configure OAuth2 from the web UI, but CLI access is required to actually switch. You are out of luck if you want to support multiple OAuth2 providers.</p> <p>It would nice to have an wizard to setup OAuth2 for common OAuth2 providers, such as GitHub and Google.</p> <p>It would be nice to support multiple OAuth2 providers.</p> <h2 id="registration-process-asks-too-much-private-information">Registration process asks too much private information</h2> <p>The sign-up form asks 11 questions, including nine required fields. It asks “Sex”, “Birthday”, and a cryptic checkbox, “I am an organization”. Optional fields include “Phone” and “Address”. You can make them required or optional field, but you cannot remove the fields.</p> <p>The current trend in sign-up process is that, ask fewer questions. If some fields are necessary, such as real name, ask the user to add the field after registration is completed, saying “To use this and that, you need to register your real name”. I hope the developers to follow the trend. All I want is an easier sign-up process, and let them explore what they can do with the system.</p> <h2 id="too-many-save-buttons">Too many <code class="language-plaintext highlighter-rouge">Save</code> buttons</h2> <p>Almost everywhere, you have to click a <em>Save</em> button whenever you change a setting. If you forget to do so, and move to another management module, your change will be lost without a warning. There is no <em>Save changes</em>.</p> <p>It would be nice to have a “Save changes” to save all the changes you have made.</p> <p>It would be nice if the system ask “you have unsaved changes, do you want save them? Otherwise, your changes will be lost”.</p> <h2 id="slot-management-needs-improvements">Slot management needs improvements</h2> <p>Trainings and machines are managed by <em>slot</em>. A slot is a duration of time, such as one hour, and assigned to machines or trainings. Users choose slots of machines or trainings they want to reserve. You need to create slots for machines and trainings. That means users cannot reserve a specific slot if the slot does not exist. You may create a training at 13:00, but what if it is not convenient time for users? Users cannot ask a reservation at different time or date. For that, you need to create all the possible slots for each machine or training. Creating slots is not a great user experience, requiring many clicks.</p> <p>You can create recurring slots, slots assigned to dates at specific interval, say, “once in a week”, or “once in a month, but no “everyday”, “every weekends”, or “every Monday”.</p> <p>You can create tags. Tags are, probably (I can only guess), designed for a proof of clearance. Tags are assigned to users and machines (actually slots of machines) so that you can require users to achieve a tag before using a machine. Say, “you need to take a safety training before reserving and using 3D printer”, which is a very common criteria. The tags tab in “Users Management” does not explain anything. When a user does not have a required tag to reserve a machine, the slots in the calender are simply hidden. There is no way to know why 3D printer is not shown, what requirements users should have, and how to achieve the requirements.</p> <p>Hopefully, slot management will improve in the future as it is one of the planned features.</p> <h2 id="single-language-in-i18n">Single language in i18n</h2> <p>The system supports i18n, but you can choose only one language. Users cannot choose their languages.</p> <p>It would be nice if the system supports multiple languages at the same time. Of course, you would have to manage all your own texts in multiple languages. That would be a lot of efforts, but with default fallback language, it would be possible.</p> <h2 id="development">Development</h2> <p>Even as a amateur programmer, I am scary when I see a huge commit with a line of commit log without tests. Thousand lines of code need detailed commit log, and tests. In the repository, I could not find automated tests other than a vulnerability scanning.</p> <h2 id="final-words">Final words</h2> <p>As an administrator, I hope the user experiences will improve. I can only imagine how hard to improve the system, and how complicated the business logics in the system are. Time will tell.</p> <p>Current limitations, or <em>features</em>, probably come from their marketing strategy. It seems like the majority of their customers are a makerspace at a university. They probably don’t need registration, or paid subscriptions. They need Active Directory support than OAuth2. Just my guess.</p> <p>If you are thinking about hosting the system on premises, think carefully. The development is active, and they do not support skipping releases. You have to follow every release and update your installation. Is that worth the effort? I deployed my instance on AWS because I had been a system administrator for a long time, I know how to make it easier, and I need my local patches to the code. If you are new to Unix, or don’t know system administration, you should choose one of the cloud offerings. The cost of AWS EC2 instance is not very cheaper than their price. If you are still interested in self-hosting, my ansible fole, <a href="https://github.com/trombik/ansible-role-fab_manager">trombik.fab_manager</a>, may help. My deployment project is also available at <a href="https://github.com/trombik/ansible-project-fab">trombik/ansible-project-fab</a>.</p> <p>Fab-manager is a great system for makerspaces. I do appreciate their decision to make it open-source for a very niche market. The system implements common business requirements, such as machine reservation, training course, pricing, and subscription. I researched on alternatives before finding fab-manager, but none is practical. I don’t want to manage reservations in Excel sheets. Without doubt, fab-manager is the way to go.</p>Tomoyuki SakuraiRecently, I found a hidden gem; fab-manager. I was looking for a solution to manage machine reservations for customers. Possible alternatives are: writing a custom Google Forms application, using other generic resource management system, or — drum roll — Excel. I do not like any of them, and accidentally found fab-manager. It looked great, and it actually is. If you are a makerspace with unique subscription models, or need tight integration with other systems, you might better wait for a while. But if you are flexible, fab-manager is a great candidate.Supporting honest business: an electrician2022-04-10T00:00:00+00:002022-04-10T00:00:00+00:00http://info.mkrsgh.org/blog/makerspace/2022/04/10/Supporting-Honest-Business-Electrician<p>Many tourists say Cambodian people are nice, easygoing, and friendly. While it is an aspect of the people, there are other points of view. In this post, I would like to introduce an electrician and issues we encounter in Cambodia — or other countries in the region.</p> <figure class=""> <a href="/assets/img/Mr-Puth-Nong.jpg" class="image-popup"> <img src="/assets/img/resized/Mr-Puth-Nong-480x640.jpg" alt="Mr Puth Nong (left) and his team" srcset=" /assets/img/resized/Mr-Puth-Nong-480x640.jpg 480w, /assets/img/Mr-Puth-Nong.jpg 750w" /> </a> <figcaption> Mr Puth Nong (left) and his team </figcaption> </figure> <p>Mr Puth Nong (left in the photo) speaks good English, certainly not the best in the town, but we can communicate without issues. He is a good engineer, judging from his works and how he works. He keeps promises, and is on time. He actually replies to your questions in Telegram chat. At the site survey before the deal, he explains what is the root cause, and what needs to be done, or what he would deliver. He listens and understands your requirements, and provides alternative solutions where necessary. He is slightly more expensive than “brothers and sisters” explained later, but it is worth the extra. His team is efficient, and the boss manages the team very well. He has “hire-and-forget” capability, which does not require further guidance after once the deal is made.</p> <p>All in all, he is the one I am happy to work with. Ask me if you need a good engineer for your business, I’ll share his contact under his permission.</p> <p class="notice--info">While I am not an electrician, I had been managing various IT vendors and it was my job to assess how they talk and what they promise before making deals.</p> <h2 id="the-background">The background</h2> <p>The reason I introduce him in this post is that I would like to explain issues we encounter — you probably might have known better than I do if you are a business owner — and to promote ones who do business with modern, accepted practices.</p> <p>Being a tourist is one thing, and living and doing business is another. It is true that Cambodia is business-friendly — licences, visa, regulations, etc — however, business owners often have difficulties here: finding reliable, and competent technicians.</p> <p>When you have common technical issues, such as plumbing or electronic one, it is not very difficult to find solutions here. It seems that everyone knows someone to fix these issues; “my brother can fix it”.</p> <p class="notice--info">Brothers and sisters in this context do not necessarily mean <em>real</em> brothers and sisters. They might be a niece or nephew, a son of his friend, someone they know, or even someone they don’t.</p> <h2 id="a-typical-case">A typical case</h2> <p>Here is a typical case. The case is not specific to the country. You most likely have heard of similar stories in other countries in the region.</p> <p>You ask a technician that someone introduced, to fix an issue. He is supposed to speak English, claimed by the man-in-the-middle. He wants to see what the issue is to estimate the cost and man-hour for the work. He promises to come at 9:00 tomorrow.</p> <p>He comes to your place with the man-in-the-middle by surprise after an hour — contrary to the promise — just because that time was convenient for him. You interrupt what you are working on at that time, and tries to explain the issue, and find out that his English is slightly better than simple greetings. The man-in-the-middle <em>kindly</em> translates your conversation. You point out that he is not an English speaker, but it is not a problem because “he understands everything”, the man-in-the-middle claims. You are a bit afraid of <em>lost in translation</em>, but you have no other options.</p> <p>At the end of the discussion, you ask a quote. The quote is sometimes twice or three times more than what you usually expects. When you tell him that the price is bit expensive, the price goes down to slightly more reasonable price without explanation.</p> <p>On the day of the work, he comes late without notice. When the issue is relatively simple, such as a broken valve, he fixes it. Otherwise, you need to explain your requirements, acceptable solutions, and what you actually need. Again, <em>lost in translation</em> sneaks in. He does what you tell, nothing more or nothing less, even when the solution is not optimal or desired.</p> <p>After lots of frustrating conversations, the issue is finally gone, or you hope so. If you are not lucky enough, it repeats again. In this process, you are wasting money and — more importantly — time.</p> <p>Like any other South East Asian countries, many technicians do not speak English; I never met one while I was in Thailand. That is understandable and acceptable. What I don’t like is that they claim they do even when it turns out to be false quickly after a short conversation. I would say they are not lying, but the point is, they are not very honest, either. Some might say I should speak the local language, which is true. However, I deliberately speak English in business and my classes because English comprehension is quite important in modern world, which is particularly true in this country where it relies on foreign tourists, customers, and businesses. It is widely shared among all generations that English skill provides better salary. In IT industry, I never trust those who cannot speak, read, or write English.</p> <p>Similarly, cheating and double-pricing is not uncommon. They cheat not only tourists but even local customers. “Bellum omnium contra omnes” — the war of all against all in English — is the business practice they know and they have been doing. I know there are exceptions, of course, but they are not the rule.</p> <p>Modern business entities in this country know better, and are adapting common and accepted business practices now, and we should promote the trend.</p> <p class="notice--info">For the sake of many guides, and tuk-tuk drivers, I would like to emphasize that it is surprisingly less likely for them to cheat you. Unlike other very touristic towns in the region, — Phuket or Ho Chi Minh City for example — they do know honest services are more profitable in the long term. You would be charged slightly more than local residents — e.g. for local transportation — but I would say it is a fair expectation, and acceptable.</p> <h2 id="conclusions">Conclusions</h2> <p>I hope that the post does not sound like just another rant. Instead, we should support and promote local businesses that does the Right Thing ™. I will continue writing similar posts in the future.</p>Tomoyuki SakuraiMany tourists say Cambodian people are nice, easygoing, and friendly. While it is an aspect of the people, there are other points of view. In this post, I would like to introduce an electrician and issues we encounter in Cambodia — or other countries in the region.A kitchen Comes to Makers2022-04-03T00:00:00+00:002022-04-03T00:00:00+00:00http://info.mkrsgh.org/blog/makerspace/2022/04/03/a-Kitchen-Comes-to-Makers<p>Finally, we have a kitchen at Makers, Siem Reap. It is an open-air, shared kitchen at our garden. We needs more for it, but at least, you can make simple foods, coffee, and cocktails.</p> <figure class=""> <a href="/assets/img/kitchen.jpg" class="image-popup"> <img src="/assets/img/resized/kitchen-800x600.jpg" alt="Our open-air kitchen" srcset=" /assets/img/resized/kitchen-480x360.jpg 480w, /assets/img/resized/kitchen-800x600.jpg 800w, /assets/img/kitchen.jpg 1000w" /> </a> <figcaption> Our open-air kitchen </figcaption> </figure> <p>One of staff members from Babel Guesthouse almost made it, and a neighbor finished it.</p> <p>Cambodian people is very good at making these things: welding, plumbing, and molding concrete. It looks like a family or a household has at least one in the member, who has these skills. One day, I will learn the basics — especially welding — but until then, they are completely new to me.</p>Tomoyuki SakuraiFinally, we have a kitchen at Makers, Siem Reap. It is an open-air, shared kitchen at our garden. We needs more for it, but at least, you can make simple foods, coffee, and cocktails.