Is there a limitation on "setWatch"?

Posted on
of 2
/ 2
  • Hi,

    I'm workin on a project.
    I need to scan 8 external buttons.
    Therefore I use the setWatch function.
    But it looks like the Espruino can't handle 8 setWatch functions.
    If I disable (make a comment of it) a few setWatch, then it is working fine for these buttons.

    The pins I used are C7, C8, C9, C10, C11, A8, A9 ad A10
    Tis is the setWatch line

      setWatch(visitorScoreUp, A9, {repeat: true, edge: 'falling', debounce: 300});

    The other pin of the button is connected to the GND


  • Fri 2019.08.09

    Hello Peter. I see you are a recent forum poster. Welcome to the world of Espruino!

    There are too many questions here to answer accurately, such as which board, which version of Espruino, what is function visitorScoreUp() doing, how are the setWatch() functions initialized, etc.

    Many of us would like to assist with our time gratis, but please follow the forum post instructions at:­/

    so that we may be able to assist you here. Although I don't see a documentation comment that would limit the number, it most likely is in the way the setWatch() functions are being set up.

  • Ok sorry ;)

    I have a "Original Espruino", it is running version "2v04" "AT command Networking Only"

    and this is the function:

    function visitorScoreUp() {

    if (visitorScore < 1) visitorScore = 0 ;
    if (visitorScore > 9) visitorTextOffset = 0;
    else visitorTextOffset = 15;
    drawOnBoard({title: visitorScore, posX: 235 + visitorTextOffset, posY: 85, vector: 45, color: colorArray.white});


    Every button is calling more or less the same function.


  • I see no reason why it should not work... Question is: how do you distinguish which button was pressed... or do you not need to know? ...looks like you do not need to know. How do you set your pins before you set the watch..."input_pullup"?

  • The project is a scoreboard.

    By pressing buttons (8 in total), the score and other things must be counting up or down.
    So, yes.. it is necessary to distinguish witch button is pressed.
    Therfore I've added 8 lines with a "setWatch" at the end of the program.
    Each line is observing a different pin.

    Everything is working, except the I have 8 setWatches activated. Then it is unstable the first minute after starting up. and only the first 4 or 5 setWatches are working.

  • Gordon says 16 in­319081/#comment14191905 post #6.

    Maybe too much memory used, maybe an issue with analog A8/A9/A10 pins.

  • Ok, I've changed the wiring on the pins to C4, C5, ... C11.
    and also changed the setWatch to "Rising". and the common wire on the buttons to "bat".
    the debounce is on 1000 for all pins.
    it looks a little bit better, bu still not stable.
    when I press C4 and C5, some other functions are called as well.
    Maybe are C4 and C5 not the correct pins?

  • Fri 2019.08.09

    Thank you for the detail Peter. That gets us all on the same page.

    'Maybe too much memory used'

    Have you tried to see if there are in fact memory leaks? Before first execution and just after upload, what is the result of process.memory()? Please post. Then run the code. Perform the test again and post that result. Do several more times to see if the total memory count goes down. My guess is no.

    Could you please check what the pinMode() is being assigned on each button tied to a pin. getPinMode(), . . . and/or, . . . is an external pull-up/pull-down resistor attached to each button? A schematic would assist here.

    Please post the snippet on how the setWatch() functions are set up and how are they first fired. Is this being done on the Right-Hand editor side of the WebIDE or the console Left-Hand side?

    'I've added 8 lines with a "setWatch" at the end'

    Have your tried eight individual button setWatch() functions, or is that the 'unstable' you are referring to in #5?

    Fr #6 'maybe an issue with analog A8/A9/A10 pins.'

    Is the pinMode() being set to 'analog'? You may be on to something here as setWatch() uses debounce for detection. The PWM (if being used that way) input may not have a detectable edge, similarly to a digital input. It is possible that analog input may work. I am not able to provide a definitive answer.­bal_pinMode­lobal_setWatch


    'the debounce is on 1000 for all pins'

    Try a value around 25-50. I'm not sure if that is a duration in msec or the number of detectable edges. It is likely that if 1000 is in msec, that is a full second and maybe out of the bounds of what you are attempting to track. If it is actual edge transitions, 1000 total may never be seen. See setWatch() link above.

  • Hi,

    I've run getPinMode() for each pin, and the return was "input" for all off them.

    There's no external resistor attached to the buttons. Is this needed?
    What resistor do I need in case of falling and rising? and if I use "rising", do I need to have the BAT connected to the button, or the GND?
    Do I need to use pinMode(B1, 'input_pullup'); in combination with a external registor?

    ={ free: 1608, usage: 632, total: 2240, history: 43,
    gc: 0, gctime: 5.47504425048, "stackEndAddress": 536909532, flash_start: 134217728, "flash_binary_end": 237920,
    "flash_code_start": 134459392, flash_length: 262144 }

    The setWatch is on the right-hand side of WebIDE, as part of my program.
    There are 8 setWatch in my program. If I put a "//" in front of the line where setWatch is, and leave only one (or 2 or 3) it works. So each setWatch and the associated function works fine.
    The problem occurs only if I set all the setWatch active.

    If I run the program, at the start I see that the value's are rising on the screen, witch means that the inputs are "active".. ? and the functions are called.
    After a while it is more stable, bu when I press a button, it looks like there are several functions called, because the values are changing on the screen.

    I've tried 25-50 as debounce, but then the values are rising faster. Therefore 1000.

  • Update:

          I've added : pinMode(Cx, 'input_pulldown');

    for each input I've used, and changed the debounce to 200. Now it looks stable !!! :)

  • Fri 2019.08.09

    'process.memory() ={ free: 1608, usage: 632, total: 2240, history: 43,'

    Thank you for posting the memory check. Nothing out of the ordinary there for the Original Espruino board. What were the results of continued observation? I'm guessing no leaks, as a solution was finally found.

    'I've added : pinMode(Cx, 'input_pulldown');'

    With as many combinations of pinMode() that are available, it is always a good idea to check the chip datasheet, link found beneath 'Information' heading towards the end of each specific Espruino board info page. A little study here goes a long way to understanding.


    It can be see the internal resistance is 30-50K with 40K being nominal. So depending on the design, in this case it sounds like the pin was just connected to the V+ side of the button, thus when specifying 'pulldown' the input signal to the pin would now be stable.

    'There's no external resistor attached to the buttons. Is this needed?'

    Depends on your design requirements.

    In general however, without the appropriate pinMode() a 40K resistance allows for a very small current, but must be overcome in order to change the detectable state. Having a direct short is not advisable, although will provide what appears to be the results one is after. It is always a good idea to use a current limiter when yanking a pin to any state, so the processor is protected. This also prevents shorting your supply and activating your home ceiling smoke detector!

    Use Ohm's Law here to calculate the appropriate size based on the voltage detected. Somewhere from ~1K -> ~4.7K -> ~10K would be in the right range, and low enough a value to provide enough current to override the internal ~40K nominal value.

  • Tx for your help!!!
    I'm a dummy in this, but I was able to build my project successfully :)

    The next step will be building the big scoreboard.
    First I will connect the controller with the scoreboard with a wire.
    But the goal is to make this wireless.

    I don't know how complicated this is.. and what are the possibilities of wireless connection between 2 Espruino's. And what the possible distance of wireless communication is.
    On the location, there's no internet, so I have to do it with bluetooth I guess...
    Any tips are welcome ;)

  • Fri 2019.08.09

    'Tx for your help!!!'

    Rx Glad to help!

    Was in your shoes two years ago, writing my first line of microcontroller code and relate to some of the frustrations you may have had.

    'I'm a dummy in this, but I was able to build my project successfully'

    How so? Started with a project concept. Accumulated parts for the project. Wired both input and output. Then coded snippets to allow that hardware to work. Dug into the nuts and bolts of specific Espruino commands. Created forum questions in order to seek a solution. Waded through the responses and 'applied' that knowledge to each task. Combined the tasks into what even you describe as a 'successful' result, . . . and all in one day!

    I'd be pretty proud of your accomplishments!!

    What kind of range is needed for the wireless part? Could build a phone app controller with WiFi or BLE, could use two WiFi devices, RF using the SX1276

    Some sample code using one device as a server station and as an access point

    The search box in the upper right hand corner of the main site is quite handy here:­6

    or even Google with the site: specifier keyword such as

    Google   connecting two wifi devices

  • That is a limitation of the microcontroller:

    You can't setWatch on two pins with the same number (eg. A5 and C5) - this is a limitation of the STM32F1

    From the Known problems section in the Original Espruino Board's docs.

  • So, I suspect the original problem was that the input signal was floating.

    1. If you connect a button only to GND (or VCC) you need a pullup (or
      pulldown) resistor. (done in #10 with an internal resistor)
    2. If you connect a button to GND (or VCC) when not pressed and to VCC (or GND) when pressed there is no problem.
  • @PeterD, the initial setup had two issues as pointed out by last two posts:

    1. @AkosLukacs - you can not have watches on pins of different ports - C and A - with same pin numbers - 8, 9, 10: in your case C8, C9, C10, A8, A9, A10. I would not necessarily call them problems, but more so restrictions / constraints­problems . The reason why not same pin numbers of different ports can be used is the way timers can be assigned to be triggered by pin changes. The timers are used to handle the debouncing. - Therefore, to your question in the conversation's title: Yes, there is a limit to how many pins you can watch at one time. With little more hardware - a few chips - you can though extend it almost infinitely.

    2. @maze1980: Input was floating... State changes in a CMOS like hardware need a current to flow - either to 'charge or discharge a gate connected to the pin with or from electrons'... and the charging and discharging has to happen within a reasonable short amount of time in order to make the detection work reliable and predictable, and short means: nanoseconds to milliseconds at most. Setting the pin mode to "input_pull" fixes it... as also indicated in my first response in post #4...

    Latter a lot to take in when 'playing' with micro controllers - software and hardware - especially when new to the field. But there is no reason to be discouraged... it is exciting to enter this world and make it work for you.


    Current to flow is done by connecting something either to ground / GND / 0 Volts (V) or VBB / VDD / 3.3 / 5 V (­upply_pin), when the' other side is connected to the opposite' - 3.3V or GND, respectively - or simply: the negative and positive pole of a battery. When not connected, no charging or discharging happens.

    The electronic component inside the processor that is connected to a pin is a transistor - a component that can transmit or resist transmission of electrons (hence its name). A transistor has three (3) zones / connections, where one of them controls whether current - electrons - can flow or not - is/are transmitted or not - between the other two. For one of the two types of (Field Effect Transistors / FET) transistors, current flows when the controlling zone is charged, and no current flows when it is discharged. The controlling zone is connected to the micro controller's pin, and the other two zones to the detection circuitry.

    The fun comes when the pin is connected to both sides, but with the twist the one connection is permanent and thru a resistor which 'slows down' the charging and discharging' process, and the other one is only temporary connected - when the switch is pressed.

    Think of the controlling zone of a transistor as of a water bucket where a fat pipe - posing practically no resistances to the water flow - and another very slim pipe - posing a high resistance to water flow - is connected to, and think of the charging and discharging as of filling and emptying of the bucket.

    If the the fat pipe is connected to a (sufficient) water source and the slim pipe to the drain, the bucket will fill, because the draining isn't fast enough to keep the bucket 'empty'. A while after disconnecting the fat pip from the water source, the bucket will eventually be empty.

    Now think of a passage where passing is controlled by the 'fullness' of the bucket: when the bucket is more than two thirds full, things will begin to pass and the surge of passing can be detected and interpreted as the fat pipe has been connected: your switch has been pressed. Otherwise, when bucket is less than a third full, nothing passes / passing stops (decrease of passing can be detected to... and the difference is in the option: trigger / detection "raising" vs. "falling" vs. "both" - and the debounce helps to ignore erroneous "sporadic gulps" or "sporadic throw-ups"... you want to detect only real steady and solid ones...

    As for thinking: with now permanent drain of the bucket, the bucket would eventually be empty after a very long time: all water evaporated... (if conditions right). This explains why the first few button presses worked... but after the gates were charged / discharged, nothing more happened...

    I guess you can make the bridge back to the pinMode(<pin>,"pull_down"); - connecting the pin internally to a current flow resistance to GND - and your switch with practically no resistance - when pressed - connected to the pin and 3.3V, and coding setWatch(<function>,<pin>,options:{edge:­"rising",debounce:50,repeat:true});

    Enjoy the journey in your new world... youtube has tons of good material helping you along this journey... (of course bad and boring - copycats - too... to understand BJTs and FETs -two very different transistor types with two main types of each you can find at:­ac4

    and N MOSFET Experiment
    ...and finally­uZY

    . The third one will confuse you first even more, because when current was discovered and defined, the atomic structure of materia and electrons were not yet... and current is reverse to actual flow of electrons... haha...

    ...and putting the icing on the cake - as it just did for me.. Unintended - this youtube caught my attention...­lPY

    ... LOL ... and even more LOOOL watching the youtube companion's clip.

  • To get your final board going, connect an ESP-8266 ESP-01 to your original board and get yourself an Espruino wifi. One you operate as an access point with Web server and the other with an plain station and 'browser' that refreshes periodically with an http request to the server and displays the result on your display the way you already do... (another option is to go for bluetooth, but I would start with Wifi / Wireless LAN).

  • Hi @ all,

    Tx all for your help and support.
    I was able to build something in a very short time at a very low cost.
    As I said before, I would like to make a scoreboard for a baseball team.
    This is a non professional team, and a commercial scoreboard is way too expensive.

    My first objective was to build a "controller". This controller will be connected to a large screen. Wired or wireless, that is not yet decided.
    The prototype of the controller is finished.
    I know that the buttons are not aligned, and I can make it look better.. but it's a prototype.
    I've uploaded a video in youtube, this way you can see how it's build ;) :­TEw

  • Looks amazing... the arrangement of the buttons has just to be declared as "ergonomic" - no doubts remain.

    For the big board, did you consider to use a RGB LEDs / Neopixels for the board? see: Large Display for Game Board. --- You would have to used strings higher pixel density (this is 30 /m, but there exist 60 /m and even 144 /m). And as you can see in the code, they are driven by the Espriuno Graphics object... which you already know how to code - write strings, draw lines and shapes, etc.

  • In the topic of setWatch limitation - I have a strange behaviour of setWatch.
    I'm using rotary encoder (not the poteniometer, but the one you install on motor to read impulses).

      let count = 0;
      pinMode(, "input_pulldown");
      setWatch(() => {
        const state = digitalRead(;
        if (state === 1)
      },, { repeat: true, edge: "rising" });
      setInterval(() => {
        count = 0;
      }, 1000);

    Code should count impulses per second, and it does. However strange thing is that at low speed it counts 45-50 impulses, at high speed (~x2) it counts 43-48 impulses. Clearly expectation was quite the opposite:)

    Assuming code and wiring is ok - I was wondering if maybe I'm hitting speed limitation of Espruino - which is simply not able to process frequently enough impulses.

    I'm using ESP32 and Espruino 2.04

  • The problem might be the speed. Have you tried the Encoder module?

  • For the big board, I'll use the WS2811 leds (Neopixel)
    I've made holes is a carton box and put the leds in there. :)
    This was more easy to develop the code. I'll test the brightness soon.
    The board must be visible during summer days as well ;)

  • @AkosLukacs no, but if I check source code of this module I'm doing pretty much same thing.

  • The encoder module might be slightly better, because that is minified (less characters == faster execution).
    If you can keep a steady RPM, and gradually increase the speed, you can figure out a rough limit of Espruino's setWatch processing speed.

  • Nice! I think if you use black background, that increases the contrast in bright daylight.
    Don't know how the wiring looks now, but if it's one strip, injecting power from multiple points can increase the light output.

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

Is there a limitation on "setWatch"?

Posted by Avatar for PeterD @PeterD