Avatar for Gordon


Member since Sep 2013 • Last active Apr 2018

Most recent activity

  • in Pico / Wifi / Original Espruino
    Avatar for Gordon

    That's an odd one - just tried here with:

    var WIFI_NAME = "...";
    var WIFI_OPTIONS = { password : "..." };
    var wifi;
    function getPage() {
      require("http").get("http://www.pur3.co.­uk/hello.txt", function(res) {
        res.on('data', function(d) {
    function onInit() {
      wifi = require("Wifi");
      wifi.connect(WIFI_NAME, WIFI_OPTIONS, function(err) {
        if (err) {
          console.log("Connection error: "+err);


    Compacting Flash...
    Calculating Size...
    Compressed 114368 bytes to 4481
    Running onInit()...
    --->Hello World!
    Compacting Flash...
    Calculating Size...
    Compressed 114368 bytes to 8578
    Running onInit()...
    --->Hello World!

    And it seems to work...

    Could it be that in setConfig you're actually forcing a connect again, then saving?

    In that case, it'd be saving the current state (which is in the middle of a connection), but then onInit is firing off a second connection?

    Having said all that, saving the network details the way you're doing (re-saving all your code) isn't ideal. In 1v96 I added Storage module which allows you to save small amounts of data. For instance:

    // update wifi details
    function setConfig(name, password) {
        name:name, password:password});
    function onInit() {
      var WIFI_NAME = "...";
      var WIFI_OPTIONS = { password : ".." };
      var wifiConfig = require("Storage").readJSON("wifi");
      if (wifiConfig) {
        WIFI_NAME = wifiConfig.name;
        WIFI_OPTIONS = { password : wifiConfig.password };
      wifi.connect(WIFI_NAME, WIFI_OPTIONS, function(err) {

    So now when you change your wifi details it modifies just the wifi details in a file called wifi, but leaves everything else the same (and doesn't require a reboot).

  • in News
    Avatar for Gordon

    For the last few years I have sold Espruino boards via Tindie, which has worked out pretty well.

    However there are a few issues - like a lack of non-dollar currencies, having to go to a different website to buy, and most of all, the lack of tax calculations. I've had to charge 20% extra to everyone regardless of whether you were in the EU or not, which artificially inflates the price for non-EU citizens.

    So I've decided to launch shop.espruino.com. Over time I'll add more products - for instance starter kits - but right now it's got all the Espruino boards, as well as:

    • The new Espruino Pixl.js - it's not in stock just yet, but is in production and I should have stock before 15 May. I've decided to take preorders for it so I have a better idea of demand.
    • Pre-programmed Bluetooth MDBT42 modules
    • As well as accessories like the Puck.js covers

    Please take a look! for the first week I'm offering 15% off if you use the code HELLOWORLD at checkout - and that includes preorders of Pixl.js as well.

    Note: You'll need to view the cart first, add HELLOWORLD and then check out. If you go straight to check out there's nowhere to enter the code.

  • in Porting to new Devices
    Avatar for Gordon

    Could it be that the ESP32 advertises that it supports secure connections (bonding), but that code isn't implemented?

    You might be able to see if bonding succeeds when using the nRF connect app?

    If so, just make sure that the ESP32 doesn't say it supports bonding - then you should be fine for connections on Windows.

    I guess eventually supporting bonding (so you can do secure connections) would be good. It's needed for HID emulation on windows - but for most stuff it's not needed.

  • in Puck.js
    Avatar for Gordon

    Could you maybe try setting it up with the headless startup? https://github.com/espruino/EspruinoHub#­headless-startup

    That way you should get a log saved (I think) in the system, and we could see if it was trying to do anything when you got the error... but also, it'll auto-restart itself if there is a problem :)

    This does look like 100% a Noble issue though, so you could try and raise it there. Looking at it, the error comes from https://github.com/noble/noble/blob/mast­er/lib/hci-socket/gap.js#L149

    Basically what's happened is some advertising data has been received that is malformed (or most likely just truncated). So either a device is broadcasting the wrong stuff (less likely as I think the Nordic SDK actually sanity checks things), or very occasionally an advertising packet is received wrong and the CRC for it passes.

    Actually I'd guess that in:

          case 0x02: // Incomplete List of 16-bit Service Class UUID
          case 0x03: // Complete List of 16-bit Service Class UUIDs
            for (j = 0; j < bytes.length; j += 2) {
              serviceUuid = bytes.readUInt16LE(j).toString(16);
              if (advertisement.serviceUuids.indexOf(serv­iceUuid) === -1) {

    The buffer's length is somehow not a multiple of two, and that causes the out of bounds access.

    You could just drop them a PR with for (j = 0; j < bytes.length; j += 2) { changed to for (j = 0; j < bytes.length-1; j += 2) { and that'd fix it.

    Same for all of the loops in that function - if it's 128 bit (16 bytes) it should check against length-15, and so on. Otherwise I could do it?

    Good job it's JavaScript - if that was C it'd be a massive security hole that you could exploit with malformed advertising packets :)

  • in Porting to new Devices
    Avatar for Gordon

    You shouldn't need HID to get NUS to work at all - by default HID isn't enabled.

    Windows is a bit odd - have you tried with the Puck so you know how it generally works? Usually you pair in the OS (but it doesn't stay connected) and then you can connect from the IDE separately.

    For the NUS you should need:

    • The ESP32 to advertise the NUS UUID
    • The ESP32 to have the NUS service and 2 characteristics

    It might also help to try changing the advertising name of the ESP32 to Espruino - if the IDE is unable to find devices by the UUID they advertise then it defaults to doing it based on if the name starts with Puck.js/Espruino/etc

  • in ESP32
    Avatar for Gordon

    @user88194 in your case the problem is var g in init - you're defining it locally, so g won't exist when used in start. Try:

    var g;
    function start(){
    E.on('init', function() { 
      // I2C
      g = require("SSD1306").connect(I2C1, start);
  • in Interfacing
    Avatar for Gordon

    They are making normal encoders into I2C ones with a microcontroller. Unfortunately they're not selling all-in-one I2C encoders yet - although with 4 wires needed it's not making wiring easier ;)

    OneWire would have been very cool though - and you could have chained them then.

    ... having said that I'm sure I've seen 2/3 axis magnetometers (which are already I2C) used as rotation encoders, possibly in a self-contained module.

  • in Puck.js
    Avatar for Gordon

    .data is the raw BLE data that got received - the other data has been decoded from it... eg. the service UUID "e20a39f4-73f5-4bc4-a12f-17d1ad07a961" that was received is 226,10,57,244,... which you can see (backwards) in the advertising data:

  • in Projects
    Avatar for Gordon

    Try using the latest from GitHub now, and put in TIM1/etc rather than just TIM.

    eg for STM32F4 TIM1 you now get:

    var TIM1 = {
      "a": {
        "CR1": 1073807360,
        "CR2": 1073807364,
        "SMCR": 1073807368,
        "DIER": 1073807372,
        "SR": 1073807376,
        "EGR": 1073807380,
        "CCMR1": 1073807384,
        "CCMR2": 1073807388,
        "CCER": 1073807392,
        "CNT": 1073807396,
        "PSC": 1073807400,
        "ARR": 1073807404,
        "RCR": 1073807408,
        "CCR1": 1073807412,
        "CCR2": 1073807416,
        "CCR3": 1073807420,
        "CCR4": 1073807424,
        "BDTR": 1073807428,
        "DCR": 1073807432,
        "DMAR": 1073807436,
        "OR": 1073807440
      "f": {}