Other people’s pain inspires me. OK. Before you Array.prototype.push() me into the same category you’d find people like Hitler, Trump and Putin, hang on for a second. Pain can indeed be inspirational. It’s what pushed medicine to its state of the art status. But I am not talking about literal pain, but rather a kind of situation. “pain in the behind” During the last presentation I’ve attended at , which was naturally all about innovation, and how to turn good into great, and great into undeniably awesome, I couldn’t help but notice that funnily enough scrolling through the presentation, required an extra hand — a lovely assistant of sorts. In 2017. Which made me think of solving a real problem, one that might seem trivial at first, but when you’re a very hands on type of presenter, like I would be, if I did not have to fiddle with keyboards, that is — it’s a real pain. A real struggle some might say… HMH — Dublin Well, it just so happens that a few weeks ago I purchased on a whim — which I rarely do — a tiny beacon called . I was one of the few lucky ones who acted fast enough before the initial batch . Puck.js sold out on Pimoroni Now, my initial experience was not the greatest with it, something which I documented on their . Thankfully, the fix was very quickly added, and off I was coding the solution for … Web IDE Github page The problem When presenting in Microsoft PowerPoint, you either have an assistant, or you attach yourself to the keyboard while presenting, unless you have a remote of sorts that you can click back and forth. The proposed solution Use Puck.js as a remote to solve the problem. Having Puck.js as a remote opens up two solutions actually, given the fact that it features both Bluetooth and IR. But IR … I don’t know, I was never a fan of IR. Everything I own is Bluetooth. I must keep the trend up, right? Going backwards is not innovative. One does not not innovate! The challenge I initially knew nothing about programming a Puck, or the Espruino API so I just went blindly into it — well, as blindly as someone who has written JavaScript for a few years, can do. Fail fast, fail early? Maybe. Anyhow, the first head-scratcher was actually not getting the Puck’s single button advertise a one letter string — namely “n” for next, and “p” for previous, but making both of those work. While normally people present progressively, at times you have situations when you have to back a slide or two, so while I got the “next” function going quite quickly, making the “previous” one work became more of a challenge than I thought. My first go at it was timing my “clicks” setWatch(function(e) {if(e.time-e.lastTime < 1){sendPrev();console.log(e.time-e.lastTime);}}, BTN, {edge:”rising”, debounce:50, repeat:true}); setWatch(function(e) {if(e.time-e.lastTime > 1){sendNext();console.log(e.time-e.lastTime);}}, BTN, {edge:”rising”, debounce:50, repeat:true}); But the results were flaky enough for me not to be confident taking this into the boardroom for half the engineers to see. Buggy implementations are one thing, bad ones are another. So what does an engineer do when plan A fails? Well, I have this that says not to worry when plan A fails, as there’s plenty letters in the Alphabet. SIGG bottle Tru dat! Looking around me, I started thinking what I tend to have with or around me whenever I do a presentation. One would be my mug off coffee but I am not going to dip my Puck into the coffee no matter how much it looks like a turned inside-out Oreo. The only other thing is my phone… My phone! Yes. That’s it! My phone has a magnetic . The operative word here is . Besides temperature, NFC and light sensors, the Puck also has a magnetometer. I love magnets! They stick together! You get the picture. :) So I swiftly tried this bit of code out to test the readings: Torro flip-case magnetic Like the wallpaper sticks to the wall, like the seashore clings to the sea … Puck.magOn();Puck.on('mag', function(xyz) { console.log(xyz);}); Turns out the values are returned as X, Y and Z values. When the Puck is at least 1cm away from my case, the reading is below zero on the X values. As soon as the Puck gets close enough, the X value jumps way above zero. What does that mean? An if statement of course! Puck.on(‘mag’, function(value) {if(value.x > 0){sendPrev(); // fire the “p” character}}); The implementation It worked. It bloody worked! The moment I get close to my phone with the Puck, the presentation goes back one slide. Of course the final code is slightly more complex, as I wanted to make sure the magnetometer is not permanently on, and only gets turned on if it’s not already on and turns itself off after 30 minutes to conserve energy. You know, like you and the missus before bed on your birthday… ;) If you haven’t pressed the button for half an hour, chances are you’re either done and dusted with the presentation or you’ve been abducted by friendly aliens to an outer-galaxy party. That being said, the magnetometer turns on as soon as you first press the button. The final “production” code is below. Sunday afternoon hacking at its best, right? :) The above code now has a revised version as well, kindly offered by Espruino forum member oesterle , involving the following improvements: Ensure BLE is turned on when Puck is powered on or battery is replaced. Ensure mag turning off doesn’t happen in the middle of presenting. Puck.magOn() doesn’t return a boolean to check if on/off; added code to fix this. Simplified character sending code to remove duplicate code. Added catchy keyboard Bluetooth device name. :-) The 2nd implementation Given the fact that I very proudly , I’ve gotten some feedback from a forum member and , one of the Puck.js developers. This resulted in some code evolution and implementation fixes. , my only fault being timing the button’s release rather than its press. Sorting that out results the following code — and the ideal production scenario, where a short press (< 0.5s) means “next”, and a long press (>0.5s) means “previous”, making the magnetic sensor workaround unnecessary. Yay! shared my code, and this article on the Espruino forum Gordon Turns out, my initial plan was actually a very sound approach