While Loop or setWatch?

Posted on
  • I am interfacing Azoteq IQS263 Capacitive Touch sensor (Datasheet) with Espruino. The sensor is I2C interface with RDY line.

    As per the datasheet the device will response when RDY pin goes low. So I will have to wait and monitor when the RDY pin goes low to start and communication. Well in active this pin is bi-directional and communication windows opens when it is LOW and resumes sensing/calculating when it is HIGH.

    What should be the approach for this?
    1- While loop??

     while(rdyPin.read()){ //wait for the IQS to change from ready to not ready
      }
    

    OR

    setWatch(watchFun, rdyPin, {repeat: true, edge: 'falling' });
    
  • Thr 2020.04.09

    Infinite while is problematic. Simple explanation:

    see post #2 read entire thread setTimeout, setInterval, setWatch logic

    Using a watch provides the aditional ability to put the device to sleep and save battery.

    https://www.espruino.com/Power+Consumpti­on

  • RDY Pin which is something set by the sensor and keeps changing by IQS263 sensor. So MCU can request a I2C communication window when this pin goes down. That is the reason why while loop will not be an infinite.

    What my goal is to perform i2c read/write only when this PIN goes gown, that means I have to put some wait and poll the pin until it goes LOW.

    I see lots of implementation for this sensor in C/C++ where people set the falling interrupt on RDY pin and perform read/write.

    Since Espruino does not support interrupt directly [ here ]and setWatch callback only executes in main loop [ here ], I only see only option to setup the IRQ optionin setWatch and provide native calls to perform communication to sensor.

    Am I making things complicated here? Is there a simple approach available?

  • 'Am I making things complicated here?'

    Not at all. Here is what you are after:

    setWatch with Inline C code

  • good to know!! @Robin Thanks

    Do you have any idea how to do read or write on I2C bus with this approach, i mean Inline C code makes a read/write calls to I2C ?

  • So MCU can request a I2C communication window when this pin goes down. That is the reason why while loop will not be an infinite.

    'Infinite' at your terms: no - but in Espruino's architecture: infinite enough to qualify... and even more so if you even think remotely to put something like this onto an ESP8266EX chip.

    For sure Espruino supports interrupts... directly in it's firmware, and puts a marker into the event queue as you define in the setWatch()... that makes it so easy and simple to use. Your application JS code (function) will be called as soon as nothing else more pressing is going on and your last event driven application JS piece has completed.

    In Espruino, everything is event driven... either by a pin signal or a time (which is a timer signal). I'm not sure you really need inline C. But feel free to be its guest and share your experience.

    As stated - everything in Espruino is event driven / has to be event driven - even a polling is event driven: a time - setTimout() or setInterval() - sets up timer that will fire and in the end pull the 'spaghetto' out of the plate of (code) spaghetti and mumpf it. Just make sure - in order to be a good 'spaghetto citizen' - its (execution) length does not qualify for infinite or resource hogging, because as long as your one spaghetto is in process, no other spaghetto can run... Be aware that many drivers / connectors to sensors use modules written in JavaScript... so - for example - receiving data will not happen - until the 'data read' event is first in the event queue and next for execution.

    This - TSO - time sharing option - is one of the oldest architectures... around with the first main frames that gave multiple users so called 'simultaneous terminal access' (vs. console access, which in the early days was the only terminal): a 'pseudo multi-/parallel- tasking' that is done in JS in Espruino as well as in the Browser (in the Browser only until recently...): an application process or flow is divided up into many short code pieces (spaghetti) where one plants the seed of the next(s) one(s) by setting up an timer or pin interrupt (javascript) handler. This way it seems to us 'slow' humans as if things are handled in parallel / multi-tasking, where when closely looked at, each piece is happening so fast that we feel a particular application has the processor's attention at all times.

    Benefit of this setup is that there is no complicated locking/synchronization required between the apps... it's almost like transactional: a once started piece of code always finishes and what is. done is done without any other application interference... The price pay: you pay upfront by thinking thru the process and identify the pieces and their triggers (interrupts they setup for the next one).

    Speaking of interference: if you go into async yourself, you are on your own - or to bare metal... and in the end: you have changed nothing: it is still single threaded... and if your thread takes too long to relent, some one else - other application thread - will pay for it.

  • Thr 2020.04.09

    While I'm still trying to track down a forum thread, I believe one uses peek and poke registers.

    EDIT:
    This was the post, but it is a bit basic using write to a pin, and I never followed through for bi-directional.
    InlineC with NRF52832 on custom board

    Not sure what max time duration during CS will provide, but another idea would be to poll using setInterval. See the second to last line, link in post #4 beneath heading 'Interrupts' print(c.get()); but in your case, have the get() function return some flag or data at that point, to activate the read/parse part in a function.

    I thought I had a forum thread that did what you are after, but it was with a manual clocking of the CS pin with SPI, not I2C. Although this isn't your module, there are some sample snippets to follow. One idea would be to look at the underlying .js code as a template and write your own.

    https://www.espruino.com/BMP280

  • Thanks @allObjects for making me correct on my understanding. I am pretty much new to this type of architecture, and mostly worked on c#/ JavaScript web based application system. Electronics is my hobby and I like Esprunio because of its power and portability on embedded devices.

    My requirement is very very close to this there where Arduino code needs to be translated in JavaScript.

    
                while (digitalRead(clk) == LOW) {}
    

    The only change is the pin, which in my case is not CS but a normal Pin which is controlled by sensor, but still very close to my issue.
    And Gordon’s response

    The issue you're hitting is that setWatch timestamps the events and put them in a queue to execute with JS - but as you notice it's won't execute JavaScript in the interrupt itself.

    I will follow the thread and see if this help me.

  • this is the Arduino code that I want to convert

  • @Abhigkar

    this is about the mainline I would go: If there is no (Espruino) JS module yet for connecting / talking to Azoteq IQS263 Capacitive Touch sensor, take the Arduino code and put it into a module.

    How would that go? ...take a peek at other modules talking I2C to sensors.

    In addition to the .connect(...) that sets 'all' up includes in its arguments the pin you connect to the sensor 'RDY' pin and callback for handler in the application level. In setup process at last you add a setWatch(callback,rdyWatchingPin,<option­s>).

    Their are variations of this: you may crate a start and stop listening - like .enable(boole) on the connection module instance to let application control when to be called rather than put all into the .connect().

    You can always let the application do all things. On the other hand, you would like to put as much 'low level' handling into the module, for example: detection of short touch, long touch, etc., and pass that in the callback or make even different callback with this information, including time, touch time, last time, etc. To get some ideas, look at the Espruino event object.

    For the programming paradigm, do not think server-side JS, like nodeJS, but more browser JS as you are very familiar with and threat the sensor like a html ui action element, for example, as a button, or a canvas where you clicked on and you get tons of info with the event that is delivered to the attached event handler(s).

    Enjoy the ride!

  • Since Espruino does not support interrupt directly and setWatch callback only executes in main loop, I only see only option to setup the IRQ option in setWatch

    Realistically the vast majority of hardware is absolutely fine waiting a little while after asserting the IRQ line - you don't generally need to jump in and do stuff immediately, and executing in the main loop is fine.

    Having said that, generally when I'm writing modules, if I'm only expecting to wait for a few milliseconds (eg. ~10ms) then I'll just add a while (pin.read()); as you suggest (ideally with a timeout - so var timeout=100;while (--timeout && pin.read());).

    If it's more than 10ms I'd use setWatch though

  • Thanks @Gordon for your suggestions. I will try it for sure. Since there is already Arduino library available, will it be worth to try to add the C code in Espruino src as a lib and compile it locally? As you are doing with microbit, hexbadge and BangleJS as a same way add my C code in lib folder and compile?

    Another question, what will happen if there is an un-handled exception in Espruino? A restart/reset?

    To get some ideas, look at the Espruino event object.

    @allObjects, As I am exploring all available option, I would like to know where I can fine re information about is Espruino event object?

  • Since there is already Arduino library available, will it be worth to try to add the C code in Espruino src as a lib and compile it locally?

    If it is worth to you then go on. However arduino (C++) code and Espruino C code can be quite different so it may not be trivial to port arduino library to espruino. C module is necessity if you cannot do it in JS (no JS api exposed) or for performance reasons. However you lose the modularity. Anyone using same sensor would need to build own espruino version. If you do it as JS module the code can be put here https://www.espruino.com/modules/ and people can use it without custom Espruino build.

  • Tue 2020.04.14

    'where I can fine re information about is Espruino event object'

    The reference made in post #10 is to the detail provided once the watch fires. The easiest way to see what is available is to create a new var inside the watch and assign 'e' to that var, then follow that with the 'debugger' command. Fire the watch. Attempting to just write to the console will result in [object Object]

    The return property set is described in the second to last full pp beneath the description heading.

    https://www.espruino.com/Reference#l__gl­obal_setWatch



    In the off chance that comment was a reference to Espruinos 'E' class as there are a few events within it:

    Search 'E Class' or nav on left-hand side 'E'

    https://www.espruino.com/Reference#t_E
    https://www.espruino.com/Reference#t_l_E­_errorFlag
    https://www.espruino.com/Reference#t_l_E­_init


    'what will happen if there is an un-handled exception in Espruino'

    when within the user JS code and not from within the underlying C source
    Typically nothing out of the ordinary. Where necessary, I wrap internal function code sections with try/catch blocks and throw my own exceptions. Gordon provided this nice snippet that may help, regarding assertions:

    post #6 and #7 How to determine which setWatch callback

  • I am facing a strange behavior that I am not sure if it is expected or my code is wrong.

    I am doing a simple setWatch on a Pin which is toggling very fast by the IQS263.

    var countWatch=0;
    var initWatch = setWatch(function(e) { 
      if( countWatch >= 300 ) clearWatch(initWatch);
      print(e);
      countWatch++;
      }, D17, { repeat:true, edge:'falling',data:D17  }
    );
    

    I am getting an error in between

    Prompt not detected - upload failed. Trying to recover..

    Execution Interrupted during event processing.
    ERROR: Ctrl-C while processing interval - removing it.
    Execution Interrupted during event processing.
    

    Am I doing something wrong here?
    My need to perform I2C read from the sensor when D17 is low.

    Sometimes I also got the error like:

    New interpreter error: FIFO_FULL
    

    And

    New interpreter error: CALLBACK
    

    Often device is also gets reset loosing all RAM content

  • Tue 2020.04.21

    Hi @Abhigkar I feel somewhat vindicated as I have been experiencing the exact issues, doing nearly the exact task as described. If you check out the last five threads (click on @Robin profile and search conversations) I started over six weeks ago, you'll see basically the same. Here is one that will provide some insight.

    Technique needed to notify of low memory

    While still trying to track down, just to understand what is going on, I am able to answer some observations I've seen.


    'setWatch on a Pin which is toggling very fast'

    Within your project, what is:
    Duration between pulse leading edges :: freq?
    Width of pulse?
    How many (besides the attempt to stop L3) pulses?

    It is likely a buffer is overflowing as the amount of data a setWatch can capture is around 100 bytes. (but I see you are not using the 'data' property) See one of my threads from over six months ago. Memory fills up, then the device locks up with a myriad ~(five or so) of possible errors, the Ctrl+C being one of them.



    Have been working on an attempt to gate the inbound pulses, but keep getting distracted trying to understand why memory ~400JsVars just vanishes. Also very likely a similar situation to what you are experiencing. That has been quite an undertaking also. My last thread regarding trace() might provide some insight also, and will be updating that later today with another round of discoveries on what might be going on.


    May I ask where are you located, Time Zone/Country so that I may stay glued to the forum during the same time to exchange ideas quicker? I'm in the midwest USA, CST. (-5 GMT) + DST

  • Thanks @Robin for the response. My Tz is UK BST (GMT+1). I am also available on gitter, if you feel comfortable..

  • Okay, six hours apart including DST, just ate lunch, your day is about over. I'll plan on an earlier morning start, should we need to comm back-n-forth quickly. Are weekends better, or are you stuck quarantined as we are for the next few weeks?

    As this is posted beneath other boards, may I inquire which one? I had basically the same issue(s) using the STM32 and what seems worse with the nRF52. My need is to resolve with the nRF52 for a project requiring BLE, but will work on a tutorial over the next many months for both devices.

    'I am also available on gitter'

    Thanks for that, but I'd like to keep things simpler right now, and any detail either of us uncover will be extremely helpful in correcting what is going on, or finding a suitable solution or work around. Posting here will leave a record that is easily accessed. It might make sense to create a new thread for each new issue, although I feel you'll probably encounter every stumbling block ;-) I did over the last few months, and likely in the same order, so continuing here is fine by me.

  • are you stuck quarantined as we are for the next few weeks

    Yes, I am, as in lockdown situation, I am sitting home all the time.

    should we need to comm back-n-forth quickly

    Sounds like a plan with only catch that I don't check forum posts regularly. Would miss the notification. Gitter mobile app push a message notification as someone will messaged me. But I am good both week and weekend options.

    As this is posted beneath other boards, may I inquire which one
    yes of course!! This is cheap chinese fitness tracker, with

    1. nrf52832
    2. with stock bootloader (SDK11 SoftDevice v 132 v2.0.0)
    3. KX022 Accelerator , Si114x HR, IQS263 touch screen sensor, 8 Mbit SPI flash, 128x64 OLED

    I am able to flash espruino latest (build on my own, for new board file, and nordic SDK11 libs), a github repository is setup (which is not in a good shape yet) to protect ongoing work.

    I also have BangleJS to compare the compiler result on need basis.

  • Tue 2020.04.21

    Good Morning @Abhigkar, me off to the rack.

    Wondering, do you have access to a Logic Analyzer? Quite frankly I wasted a year until I had to have one to solve an issue. See images at this post I made a year ago.

    see #3 post   Programming the Ublox NEO-6M GPS configuration

    They are aournd $20USD on BangGood and well worth the time savings, for stuff like this. While it's unlikely there is a massive amount of data being sent, 'seeing' the data sent makes writing code to detect bits is a lot easier!

  • They are aournd $20USD on BangGood

    if buying from china these are more like $5, e.g. here https://www.aliexpress.com/item/32847322­743.html
    What is inside is actually nice generic USB2.0 chip FX2LP CY7C68013A which is quite versatile (firmware is loaded over usb, there are opensource examples) and there is even slightly cheaper 'developer' board that can work as this logic analyzer - it is the same thing or even better as it has 16 channels, not 8. It is between $3-$4 like here https://www.aliexpress.com/item/32976439­459.html

    Definitely good thing to have.

    Oh and it is documented here https://sigrok.org/wiki/Lcsoft_Mini_Boar­d and the 24MHz 8Ch analyzer is e.g. here https://sigrok.org/wiki/MCU123_USBee_AX_­Pro_clone

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

While Loop or setWatch?

Posted by Avatar for Abhigkar @Abhigkar

Actions