Please post what you're working on!

Posted on
of 6
  • @jefure thank you very much I will look in to that this when my soil sensors arrive from eBay

  • That's great - thanks for letting us know! It's really nice to see a post showing how to set something like that up from beginning to end.

  • Maybe not as sexy as some other projects, but here it goes

    I'm working on a better way to heat my apartment using electric oil heaters, pucks and Wemo plugs.

    1. I'm using Puck.js as temperature sensors, attached to ceiling or walls to measure and average temperature across rooms.
    2. Pucks advertise the temperature via BLE (low-energy, super-long adv. period, very rare temperature reads every few minutes to maximise battery life).
    3. A running instance of EspruinoHUB serves as BLE -> MQTT bridge.
    4. Node-red instance reacts to MQTT messages.
    5. I'm implementing logic which will guarantee temperatures in a set range, in specific rooms, at different days of the week.
    6. Node-red talks via uPnP to Belkin Wemo Insight power switches, turning oil heaters on and off to maintain the temperature.
  • I've create a Puck Decision Engine.­on-Engine

    Pretty simple starter project.

  • Neat idea! A bit like a magic 8 ball :)

  • Hi all. I've just created a web app that can use Puck.js to help users type, as an alternative to traditional keyboard entry. Maybe useful for those with reduced mobility.
    It includes predicted words logic, as well as basic settings.

    Once connected to Puck.js from the menu bar button, a single click starts the row selector. Another click will select the row and start iterating through the letters in the row.

    Also works without Puck.js by using the keyboard's space bar instead.

    ClickType web app
    Github project

  • Nice - that's really neat! It's really cool to see it being used as an accessibility device. With something like this there's loads of scope for making novel controllers - for instance car air pressure sensors are dead easy to wire up (power/gnd/signal) and you could then use suck/blow to control it for people who can't move anything.

    Out of interest, was this made for someone in particular to use?

  • No, I didn't make it for anyone in particular. Perhaps if I had known someone that could use it, I would have spent more time improving it. I just got the idea after playing with the Puck and realising that there could be many uses for people with disabilities.

  • Hi everybody. I need read/write some data from a standard ISO 7816 smart card. Normally a PC use a USB smart card reader. I'm wondering if someone tried to use the UART to interact directly with the smart card chip.

    Thanks for any suggestion

  • I don't see a reason why you couldn't do that. If you found a description of what you needed to send (or even better, some C code that did what you need) then we could help you write the JavaScript for it.

    Please could you start a new thread for that though? This one is getting huge and is ideally for posting up things that users have created with Puck.js :)

  • i'm hoping to get my first complete working version of a synthesizer using a few micro controllers, and a puck as a midi controller. it will use the light sensor as a theremin, and the button as a wobble controller. i also added a 20 watt per channel stereo amplifier shield, so it can fill a room with sound.

    i'll add some details when back from my business trip this week.

  • Hello,
    So I did started a 3D model of the Pixl.js based on the Eagle files.
    So far it's more or less complet and accurate.
    See it below:

    // Written in 2018 by Alain Sézille
    // Any license defined in the librairies used rule their use herein
    // Any license about the Pixl.js board is applyable
    // The following termes apply exclusively to my own work and do not overrule any other licenses and copyrights for the components and informations used below
    // To the extent possible under law, the author(s) have dedicated all
    // copyright and related and neighboring rights to this software to the
    // public domain worldwide. This software is distributed without any
    // warranty.
    // You should have received a copy of the CC0 Public Domain
    // Dedication along with this software.
    // If not, see <­/zero/1.0/>.
    // Following libraries should be installed into Openscad libraries directory
    // eagle-pcb from­
    // MCAD from
    // Magpie from
    include </home/alain/.local/share/OpenSCAD/libra­ries/eagle-pcb/common.scad>
    include </home/alain/.local/share/OpenSCAD/libra­ries/eagle-pcb/resistor.scad>
    include </home/alain/.local/share/OpenSCAD/libra­ries/eagle-pcb/SparkFun-Connectors.scad>­
    include </home/alain/.local/share/OpenSCAD/libra­ries/eagle-pcb/diode.scad>
    include </home/alain/.local/share/OpenSCAD/libra­ries/eagle-pcb/Eagle-Library.scad>
    // Missing colors used below
    // General size of the Pixl.js board
    board_thickness = 1.600000;
    board_origin = [0.000000,0.000000];
    eta = 0.1;
    fn = 18;
    module downside() {
        rotate([180,0,0])  children();
    module transrot(tr = [0,0,0], rt = 0) {
        translate(tr) rotate([0,0,rt]) children();
    module C0603K(tr = [0,0,0], rt = 0) {
       transrot (tr,rt) downside()    resistor_C0603K("C0603K", 10603);
    module R0603(tr = [0,0,0], rt = 0) {
       transrot (tr,rt) downside()  resistor_R0603("R0603", 10603);
    module R1210(tr = [0,0,0], rt = 0) {
       transrot (tr,rt) downside()  rcsmd([12 * 0.254, 10 * 0.254], "R0603", 10603);
    module SOT23_5(tr = [0,0,0], rt = 0) {
        transrot (tr,rt) downside()  Eagle_Library_SOT23_5L("SOT23_5", 23.5);
    module SOD323_W(tr = [0,0,0], rt = 0) {
       transrot (tr,rt)  downside()  diode_SOD323_R("SOD323_W", 23.5);
    module USB_MICROB(tr = [0,0,0], rt = 0) {
       transrot (tr,rt) downside() rotate([0,0,-90]) SparkFun_Connectors_USB_AB_MICRO_SMD();
    module SMT_JUMPER_3_1_NC_TRACE_NO_SILK(tr = [0,0,0], rt = 0) {
        // transrot (tr,rt) 
    module SMT_JUMPER_3_NO_NO_SILK(tr = [0,0,0], rt = 0) {
        // transrot(tr,rt) 
    module COINCELL(thickness = 3.5, diameter = 20.0) {
            color(silver) translate([0,0,thickness/2]) cylinder(r=diameter/2, h=thickness, center=true);
    module CR2032_SMD(tr = [0,0,0], rt = 0) {
      transrot(tr,rt) downside()  COINCELL(3.64,20);
    module TACT_MEDI_RIGHT_ANGLE(tr = [0,0,0], rt = 0) {
        union() {
            // body
            cube([7.8, 2.45, 3.4], center=true);
            // button
            translate([0, (2.45/2), 0])
            cube([3, 1.05, 1.5], center=true);
    module MDBT40(tr = [0,0,0], rt = 0) {
        union() {
            // pcb of module Dimensions: 16mm x 10mm x 2.2mm thick
            cube([16.3, 10, 0.7], center=true);
            // ceramic antenna
            cube([1,8,1], center=true);
            // main shield of module
            cube([11.65,8.25,1.38], center=true);
    module JHD12864_G176BSW(tr = [0,0,0], rt = 0) {
        transrot (tr,rt) 
        union() {
            // pcb of module Dimensions: 16mm x 10mm x 2.2mm thick
            cube([59.2,41.4,4.7], center=false);
            // main shield of module
            cube([55.6,32.3-2.5,4.7], center=false);
            // viewable lcd part
            cube([50,25.4,4.7], center=false);
    module M3(tr = [0,0,0], rt = 0) {
       transrot(tr,rt) translate(board_origin) color(red) cylinder(r=3/2, h=board_thickness);
    module PINNED_CONNECTOR(headerHeight = 9, headerWidth = 2.54,headerNbPins = 8, headerPinHeight = 11.5) {
        // defaults valeus are for arduino sized connectors
        union() {
            // main body
            cube([headerWidth, headerWidth * headerNbPins, headerHeight], center=false);
            // pins through PCB
            for (a = [ 1 : 1 : headerNbPins ])
              translate([2.54/2, a*2.54-2.54/2, headerHeight-headerPinHeight])
              cylinder(d1=0.64, d2=0.64, h=headerPinHeight, center=false);
    module ARDUINO_CONNECTORS(tr = [0,0,0], rt = 0) {
        union () {
            // 10 pins connector,
            translate([0, 17.526, 0])        
            PINNED_CONNECTOR(headerNbPins = 10);
            // 8 pins connector,
            translate([0, 44.45, 0])
            PINNED_CONNECTOR(headerNbPins = 8);
            // 8 pins connector,
            translate([49.53-1.27, 26.67, 0])
            PINNED_CONNECTOR(headerNbPins = 8);
            // 6 pins connector
            translate([49.53-1.27, 49.53, 0])
            PINNED_CONNECTOR(headerNbPins = 6);
    module 1X02_S(tr = [0,0,0], rt = 0) {
        transrot (tr,rt) 
        cube(6,4.5,3, center=true);
    //Created by generate-scad.ulp version 0.1
    module pixljs(){
    	board_thickness = 1.600000;
    	eta = 0.1;
    	board_size = [60.000000,52.500000,board_thickness];
    	fn = 18;
    	board_origin = [0.000000,0.000000];
        board_downside=0; //-(board_thickness);
            // Board without components holes
                // Holes
    			translate([2.400,41.750,-eta])cylinder(r­=0.500000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([2.400,39.450,-eta])cylinder(r­=0.500000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([57.600,39.450,-eta])cylinder(­r=0.500000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([57.600,41.750,-eta])cylinder(­r=0.500000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([57.600,18.050,-eta])cylinder(­r=0.500000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([57.600,20.350,-eta])cylinder(­r=0.500000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([2.400,20.350,-eta])cylinder(r­=0.500000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([2.400,18.050,-eta])cylinder(r­=0.500000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([1.945,7.375,-eta])cylinder(r=­0.750000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([58.295,7.375,-eta])cylinder(r­=0.750000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([58.295,45.700,-eta])cylinder(­r=0.750000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([1.945,45.700,-eta])cylinder(r­=0.750000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([3.000,3.000,-eta])cylinder(r=­1.600000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([3.000,49.500,-eta])cylinder(r­=1.600000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([57.000,49.500,-eta])cylinder(­r=1.600000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([57.000,3.000,-eta])cylinder(r­=1.600000, h=board_thickness+eta*2,$fn=fn); //hole
    			translate([6.387,14.438,-eta])cylinder(r­=0.508000, h=board_thickness+eta*2,$fn=fn); //1X04-S 1
    			translate([8.927,14.438,-eta])cylinder(r­=0.508000, h=board_thickness+eta*2,$fn=fn); //1X04-S 2
    			translate([11.467,14.438,-eta])cylinder(­r=0.508000, h=board_thickness+eta*2,$fn=fn); //1X04-S 3
    			translate([14.007,14.438,-eta])cylinder(­r=0.508000, h=board_thickness+eta*2,$fn=fn); //1X04-S 4
    			translate([50.600,3.950,-eta])cylinder(r­=0.400000, h=board_thickness+eta*2,$fn=fn); //H2-2.0-6X4.5MM +
    			translate([48.600,3.950,-eta])cylinder(r­=0.400000, h=board_thickness+eta*2,$fn=fn); //H2-2.0-6X4.5MM -
    			translate([48.300,1.870,-eta])cylinder(r­=0.508000, h=board_thickness+eta*2,$fn=fn); //1X02-S 1
    			translate([50.840,1.870,-eta])cylinder(r­=0.508000, h=board_thickness+eta*2,$fn=fn); //1X02-S 2
    			translate([45.510,7.150,-eta])cylinder(r­=0.400000, h=board_thickness+eta*2,$fn=fn); //JHD12864-G176BSW LEDA
    			translate([14.720,7.150,-eta])cylinder(r­=0.400000, h=board_thickness+eta*2,$fn=fn); //JHD12864-G176BSW LEDK
    			translate([7.660,50.003,-eta])cylinder(r­=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 0
    			translate([10.200,50.257,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 1
    			translate([12.740,50.003,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 2
    			translate([15.280,50.257,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 3
    			translate([35.600,1.743,-eta])cylinder(r­=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 3.3V
    			translate([17.820,50.003,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 4
    			translate([20.360,50.257,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 5
    			translate([33.060,1.997,-eta])cylinder(r­=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 5V
    			translate([22.900,50.003,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 6
    			translate([25.440,50.257,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 7
    			translate([29.504,50.003,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 8
    			translate([32.044,50.257,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 9
    			translate([34.584,50.003,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 10
    			translate([37.124,50.257,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 11
    			translate([39.664,50.003,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 12
    			translate([42.204,50.257,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO 13
    			translate([20.360,1.997,-eta])cylinder(r­=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO A0
    			translate([17.820,1.743,-eta])cylinder(r­=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO A1
    			translate([15.280,1.997,-eta])cylinder(r­=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO A2
    			translate([12.740,1.743,-eta])cylinder(r­=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO A3
    			translate([10.200,1.997,-eta])cylinder(r­=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO A4
    			translate([7.660,1.743,-eta])cylinder(r=­0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO A5
    			translate([47.284,50.257,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO AREF
    			translate([44.744,50.003,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO GND
    			translate([27.980,1.997,-eta])cylinder(r­=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO GND.
    			translate([30.520,1.743,-eta])cylinder(r­=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO GND..
    			translate([40.680,1.743,-eta])cylinder(r­=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO I/OREF
    			translate([43.220,1.997,-eta])cylinder(r­=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO N/C
    			translate([38.140,1.997,-eta])cylinder(r­=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO RESET
    			translate([52.364,50.257,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO SCL
    			translate([49.824,50.003,-eta])cylinder(­r=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO SDA
    			translate([25.440,1.743,-eta])cylinder(r­=0.450000, h=board_thickness+eta*2,$fn=fn); //ARDUINO VIN
    			translate([57.251,33.405,-eta])cylinder(­r=0.600000, h=board_thickness+eta*2,$fn=fn); //USB-MICROB P$3
    			translate([57.200,26.420,-eta])cylinder(­r=0.600000, h=board_thickness+eta*2,$fn=fn); //USB-MICROB P$4
            // Components added 
    		TACT_MEDI_RIGHT_ANGLE([2.400,40.600,0],9­0);  //BTN1 
    		TACT_MEDI_RIGHT_ANGLE([57.600,40.600,0],­270);  //BTN2 
    		TACT_MEDI_RIGHT_ANGLE([57.600,19.200,0],­270);  //BTN3 
    		TACT_MEDI_RIGHT_ANGLE([2.400,19.200,0],9­0);  //BTN4 
    		C0603K([24.400,21.800,board_downside],90­);  //C1 1uF 25v
    		C0603K([27.800,22.800,board_downside],18­0);  //C2 1uF 25v
    		C0603K([13.800,36.300,board_downside],0)­;  //C3 10uF 6.3v
    		C0603K([47.000,14.400,board_downside],90­);  //C4 1uF 25v
    		C0603K([19.400,26.200,board_downside],27­0);  //CTUNE1 TBD
    		C0603K([18.100,25.300,board_downside],27­0);  //CTUNE2 TBD
    		SOD323_W([50.300,17.100,board_downside],­0);  //D1 
    		SOD323_W([41.200,17.200,board_downside],­270);  //D2 NO_FIT
    		//translate([10.197,14.438,board_downsid­e])1X04_S();  //DBG 
    		SOT23_5([44.200,14.500,board_downside],9­0);  //IC2 MIC5225-3.3	//translate([49.600,3.200,board_downside­])rotate([0,0,180])H2_2_0_6X4_5MM();  //J1 2p-2.0
    		SMT_JUMPER_3_1_NC_TRACE_NO_SILK([44.800,­17.100,board_downside],180);  //JP1 COINCELL_VREG
    		SMT_JUMPER_3_NO_NO_SILK([40.920,5.540,bo­ard_downside],0);  //JP2 5VSRC
    		1X02_S([49.570,1.870,board_downside],0);­  //PWR 
    		R0603([11.100,22.400,board_downside],270­);  //R1 100
    		JHD12864_G176BSW([0.620,5.750,0],0);  //U$1 JHD12864
    		MDBT40([8.400,29.880,board_downside],90)­;  //U$2 MDBT42Q
    		CR2032_SMD([41.500,33.050,board_downside­],90);  //U$3 CR2032-SMD
    		ARDUINO_CONNECTORS([2*35.600-0*2.54,2*26­.000,board_downside],270);  //U$4 ARDUINO
    		USB_MICROB([57.200,29.900,board_downside­],90);  //U$5 USB-MICROB
    		R1210([52.750,14.600,board_downside],180­);  //U$6 PTCFUSE
    		M3([3.000,3.000,0],0);  //U$7 
    		M3([3.000,49.500,0],0);  //U$8 
    		M3([57.000,49.500,0],0);  //U$9 
    		M3([57.000,3.000,0],0);  //U$10 
    pixljs(); //Show module
  • Wow, that's excellent! Please could I put that in the Espruino boards repository? Image of what it looks like attached.

    Just some notes for anyone else trying this:

    • You need 'OpenSCAD' to run this script
    • You only need to get (and then modify the paths at the top)
    • The forum inserts annoying line-break characters that'll trip up OpenSCAD. Copy and paste the file above into the Espruino IDE and then copy it from there into OpenSCAD and it'll be fine :)

    1 Attachment

    • pixl_scad.png
  • Hi,
    Sure you can put it wherever you like...
    That said I faced difficulties to join it as a simple file from Firefox: for instance I can select the file to be joined but it doesn't appear in the files under my post.
    However, it works from Chrome! So...

    2 Attachments

  • nice... for my 3d printing exercises of 'holdings' for a pixl I created this PixlPlug.stl file (in Tinkercad).

    3 Attachments

  • Hi, I'm about to enter a 25-hour hackathon over the weekend, and I'm planning on using four puckjs buttons to send simple click messages to a web bluetooth website and receive messages to light up the LEDs on the pucks.

  • Busy with many projects but one people may find interesting is a strain gauge with puck.js

  • Fri 2019.06.21

    Hello Jenny,

    These tutorials might provide one choice using ultrasonic:­_robot

    Otherwise I.R. beam (optical) break, such as a TV remote signal, or the radar RCWL-0516 Microwave (radio) Radar Sensor come to mind.

  • Hi,
    I have a floor stand for a phone/tablet set up next to a recliner, so that I can read ebooks hands free (I have both neck and wrist joint issues from too many years of holding books in my lap to read). The problem is that the phone/tablet wobbles whenever I swipe the screen to change page. So I went looking for a simple control I could hold in my hand to turn the pages. Cue puck.js.

    It arrived this morning, and after a little hiccup I got it working. I needed to turn on location services (bluetooth was already on) on my android phone to detect the DfuTarg in order to flash the firmware.

    Then with the help of the "DIY Hands-free music control with Puck.js" YouTube video, I was able to put together the code snippet below, which on a short button press sends the right arrow key (Play Books = next page) and on a longer press sends the left arrow key (Play Books = previous page)

    And I'm in business :-)

    It seems a shame to use such a versatile device for such a simple thing, but it is going to make reading so much easier on my neck and wrists. Perhaps there are others out there who also need something to help them read hands free.

    var kb = require("ble_hid_keyboard");
    NRF.setServices(undefined, { hid : });
    setWatch(function(e) {
      var len = e.time - e.lastTime;
      if(len < 0.3) {
         kb.tap(kb.KEY.RIGHT, 0);
         } else {
    }, BTN, {edge:"falling",repeat:true,debounce:50}­);
  • That's brilliant - thanks for sharing it and posting your code up!

    Honestly, this is exactly the sort of thing it's designed for: making it easy and fun to create things.

  • Working on a pixl+multi for a first project to learn JS: a universal conference badge, as geeky as possible. I'm not used AT ALL to the object and event-driven aspects of JS (my only programming experience is C on micro-controllers).
    I often tinker on the train so I changed Web IDE to offline.

    @Gordon: would it be possible to opensource the pixl+multi, including HW? Obviously the schematic is quite different from the nodeconf badge and I'm a bit lost.

  • Sat 2019.10.05

    @DBovey I just googled: 'nodeconf badge espruino'­313468/

    has the links to hardware and software you seek

    or, if you are after the Pixl source, from the main web site

    beneath the 'Information' heading:­d/tree/master/Pixl.js/pdf

    re: 'my only programming experience is C on micro-controllers'

    A good starting point:­­/Learn/JavaScript

  • @Robin I'm pretty sure that's the older badge.

    @DBovey yes, absolutely. It is all published already -­8/tree/master/sch is what you need I believe. There's a link on the Pixl.js multicolour page but it's not very obvious - I'll make sure I tweak that.

    JS's callbacks/promises can definitely take a while to get to grips with if you're coming from something like C, but it's worth it. They're really powerful when you're there.

    The badge sounds like a fun project though - please let us know how you get on!

    PS. I'm afraid I don't think there are enough posts specific to the multicolour badge to warrant adding a new forum for them yet - there'd only be about 3 posts in there! If you have any questions the Pixl.js forum (as you have used) is definitely the right place.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

Please post what you're working on!

Posted by Avatar for Gordon @Gordon