Analog configuration on the puck.js?

Posted on
  • Hi,
    Is there any ability to change the analog configuration on the puck.js (nRF52832) to use different gain, differential input, etc? Basically access the configuration settings for a channel?

    Probably an @Gordon question...


  • I'm afraid not, no. However if you find that the nRF52 chip itself allows some extra feature that you need then let me know... Worst case you could almost certainly configure it yourself with one or two poke32 commands.

  • Thanks! Any thoughts on implementing support for the analog comparator?

  • Ok, I just added support to the low-level library. Check out the examples there:

    While there aren't interrupts there directly you can still hook it up to do some pretty interesting things (eg counting changes in the input or accurately measuring the time between them). If you desperately need them you can always change the state of a pin, then short that to another pin that you can use with setWatch.

  • Did you actually have a use-case for this in mind? Or you just thought it'd be cool to have?

  • Hi @Gordon,
    Sorry for the silence -- I wasn't monitoring this site. Nice job on the comparator function so far...
    You hinted at what I want to do: I want to measure the frequency of a fairly slow signal (0.1 - 1 hz). I was thinking of comparator crossings and a timer. In the nRF architecture, they actually have the ability to 'wire' this up so that the processor is only involved minimally. I totally understand that I'm going to need to write embedded code to do that, but I'm at the proto phase right now, so any ideas that can efficiently do this would be appreciated!


  • Ok, great! So do you need to measure the frequency of every pulse, or just the amount of pulses in a minute (for instance)?

    The nRF52832 doesn't have any timers (except the 32kHz real-time clock) that run when the device is in low-power mode, which makes the first option more difficult. I think at the moment we have:

    1. Count the number of pulses, and then check every so often - very low power
    2. Loop the comparator to an output pin, physically join that to another pin, and use setWatch on that to count using JavaScript and the RTC.

    I've asked on Nordic's support site if there's another option - it might be possible to use the RTC to increment a timer 32k times a second.

    Personally, if it's good enough, I think pulse counting would be the simplest and lowest power option.

  • Hi @Gordon, option 1 would be fine. This is still for a prototype, but power is important. For the product, I'd want to investigate using the Nordic PPI and a counter/timer in counter mode. I think that's much more difficult with Espruino since it is a lot of low layer stuff.

    Thanks for the brain cycles on this!

  • Here you go:

    var ll = require("NRF52LL");
    // source of events - compare D31 against vref/2
    var comp = ll.lpcomp({pin:D31,vref:8});
    // A place to recieve events - a counter
    var ctr = ll.timer(3,{type:"counter"});
    // Set up and enable PPI
    ll.ppiEnable(0, comp.eCross, ctr.tCount);
    /* This function triggers a Task by hand to 'capture' the counter's value. It can then clear it and read back the relevant `cc` register */
    function getCtr() {
      poke32(ctr.tClear,1); // reset it
      return peek32([0]);
    // Every 10 seconds, wake and print out the number of crosses
    setInterval(function() {
    }, 10000);

    It configures hardware to count crosses using the comparator:

    • You have to use pins with analog inputs - check the pinout page for the board you're using for info
    • The voltage reference is in 16ths - so vref:8 is a half of VCC. You can also use another analog pin as a reference - proper docs in
    • They are 32 bit counters, so you've got no issue with the counter overflowing
    • It seems pretty low power - drawing around 100uA

    Hope that helps!

  • There's also now support in the LL libs for the ADC and the RTC, so if you wanted to measure pulse length in a low-power way you could use the button length example:

    var ll = require("NRF52LL");
    // Source of events - the button
    // Note: this depends on the polarity of the physical button (this assumes that 0=pressed)
    var btnu = ll.gpiote(0, {type:"event",pin:BTN,lo2hi:1,hi2lo:0});­
    var btnd = ll.gpiote(1, {type:"event",pin:BTN,lo2hi:0,hi2lo:1});­
    // A place to recieve Tasks - the RTC
    var rtc = ll.rtc(2);
    poke32(rtc.prescaler, 0); // no prescaler, 32 kHz
    poke32(rtc.tStop, 1); // ensure RTC is stopped
    // Set up and enable PPI to start and stop the RTC
    ll.ppiEnable(0, btnd.eIn, rtc.tStart);
    ll.ppiEnable(1, btnu.eIn, rtc.tStop);
    // Every so often, check the RTC and report the result
    setInterval(function() {
      poke32(rtc.tClear, 1);  
    }, 5000);

    Nothing stops you hooking that up with the 'button press counter' example so you can then get the average button press length with time_button_pressed / button_presses

  • A public THANKS! to @Gordon!!!


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

Analog configuration on the puck.js?

Posted by Avatar for billsalt @billsalt