Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Chris
    @cmidgley
    Thanks for the hint to recipes - I'll check it out. I know it's "possible" to get Arduino / ESP-IDF to work together, but was hoping to hear it was something you/others have done w/Moddable. Given that feedback, I'll refocus on porting to ESP-IDF. Thanks, Peter!
    Peter Hoddie
    @phoddie
    The biggest challenge, as I see it, is that Arduino code hits the hardware directly, which means you have the potential conflicts with the IDF use of the same hardware. My usual approach is to read the Arduino code and then rewrite it in JavaScript. But, that's me. And for some libraries, that isn't the right answer (I don't know anything about the LoRa stuff).
    Chris
    @cmidgley
    The LoRa stuff isn't super complex - it's SPI with ISR routines to respond to the packet receives/completions. My understanding is that ISR requires going into C (and then send it up to JS). I've not researched SPI in Moddable JS - was assuming it was best to do that in C as well, but perhaps not?
    Chris
    @cmidgley
    I see There is no JavaScript API to access SPI at this time so I think that answers this question!
    Peter Hoddie
    @phoddie
    There is a JavaScript API to access SPI.
    It works well. Our two recent ePaper display drivers use it.
    The ePaper blog post is good reading. If you really need to respond to LoRa interrupts from the ISR, then you need to use C though. If you can tolerate some latency, JavaScript could well work.
    Chris
    @cmidgley
    Interesting! Where is the SPI interface (and is there any doc on it)? As for JS latency vs. ISR, do you mean polling instead of an ISR, or a simple C ISR that callsback to JS to handle the completion, or...? LoRa is a very slow protocol (and transmit is limited by FCC regulations to seconds or minutes between packets!), so latency of the types we are talking about wouldn't be a big deal - except I'd need to check if the chip (SX1278) is able to continue to receive a packet while awaiting the prior packet offload to make sure I didn't experience high packet loss (it is a broadcast network, no packet acknowledgement/error handling, and given FCC rules doing a retry can delay a message by minutes)
    Peter Hoddie
    @phoddie
    The SPI class follows Ecma-419, so the standard is the documentation. Both of the new ePaper display drivers described in the blog use SPI, gdew0154m09 and IT8951 so they are good examples. The IT8951 does both read and write over SPI. Note that the latency of handling the interrupts in JavaScript is pretty small as long as the task isn't busy. You can always run that in its own virtual machine to ensure it isn't blocking if it comes to that.
    To trigger the ISR, you can uses an Ecma-419 Digital class with an onReadablle callback that is invoked when the interrupt triggers. The Digital class installs an ISR and triggers your JavaScript callback. This button code is a good example of how that works.
    Chris
    @cmidgley

    Perfect. I have the ESP-IDF port working in Moddable now (sending/receiving LoRa packets in Moddable) but I'm going to try to port to JS next as that would be much cleaner / more maintainable.

    You can always run that in its own virtual machine to ensure it isn't blocking if it comes to that.

    Is this using Workers? We have a discussion earlier (more than a year ago) where you said they were experimental. How are you feeling about the reliability of Workers now?

    Peter Hoddie
    @phoddie
    We use Workers in nearly every one of the projects we build for our clients. They are solid. But, it also sounds like you might not need that here.
    Chris
    @cmidgley
    I'm making progress - I have SPI initializing and talking to the chip, but don't yet have coms working yet. To debug I need to run two ESP32's at the same time (each with a LoRa chip). It appears I cannot run two instances of xsbug (at least on Windows) at the same time - is that correct, or is there a trick?
    Peter Hoddie
    @phoddie
    That sounds complicated and cool. One instance of xsbug can be used with several devices simultaneously. You can see that basic support by running one app on ESP32 and another in the simulator. I think our default scripts triggered by mcconfig kill the running instance of the seriall2xsbug bridge. So, you'll probably need to manually launch serial2xsbug twice, each with a different serial port. They will both connect to the same instance of xsbug.
    Chris
    @cmidgley
    Yes - that is working. It shows a unique machine tab for each device. I found the baud rate using mcconfig -v - it's 460800. Back to debugging!
    Peter Hoddie
    @phoddie
    Cool.
    FWIW - if/when you get to Workers, each worker appears as a separate machine tab in xsbug too.
    Chris
    @cmidgley
    Sweet! I am now sending and receiving LoRa packets with 100% Moddable JS code! Not doing interrupts yet (currently just polling) but that shouldn't be much work at this point. Thanks for the help!
    Peter Hoddie
    @phoddie
    That is impressive -- both that it works at all and that you did it so quickly.
    Any chance of a PR at some point??
    (I'm very curious to see examples using the Ecma-419 APIs.)
    Daniel Ashcraft
    @dashcraft
    Wow!
    Chris
    @cmidgley
    I'm glad to share the source but I don't think it will be in PR-ready condition. Done right, it should abstract away the hardware specifics from the LoRa interface (much like how SPI works) but right now it's really bringing forward the unique needs of the SX1278 chip. Plus I didn't attempt to create a full interface of all features - I implemented only the features that my project needs. When I get it cleaned up, I'll send a link to the source and you can let me know what you want to do with it (if anything).
    Peter Hoddie
    @phoddie
    That would be great, thanks. I can imagine implementing the whole thing is a non-trivial project. FWIW - there's a very deliberate API style in Ecma-419 for IO and peripherals. That might be interesting to apply here to abstract away those hardware specifics.
    Chris
    @cmidgley
    I wouldn't say I fully grok the Ecma-419 style, but did spend some time there to get a basic feel (and to consume the interfaces for Digital and SPI). Since this chip lives on SPI (perhaps others don't?) I wasn't clear if that meant it should have SPI instantiated outside of the LoRa object, or have the SPI pins/mode/etc passed in the dictionary on the constructor and then have the LoRa class instantiate SPI. I assumed you would just extend that dictionary for device specific features - in this case, frequency, bandwidth, coding rate, CRC, implicit/explicit, etc? Didn't see any naming standards or rules for custom extensions to that dictionary. Similar with adding methods that are unique to the class - such as getting the signal-to-noise ratio (SNR) or live changing a parameter that was specified in the constructor dictionary. Sufficient questions / lack of understanding that I didn't attempt to directly model it. Doesn't seem too difficult to fit into the model once those style issues are resolved, but as always the devil is in the details.
    Chris
    @cmidgley
    Here is the code. It's not fully tested, but I did implement all the core chip features (even though I said I wasn't going to!) and it's working well for me sending/receiving packets. No interrupts yet, so it can block (especially on transmit) for up to 400ms (LoRa is slow...) to send a packet. Likewise reads need to poll received()to see if a packet is waiting (then receive_packet will be quite fast as it reads from a FIFO on the chip). You will see in there a TODO comment on the SPI config about Port - I wasn't clear as some code sets port to "VSPI" or "HSPI" but other code samples use "0" and "1". Not sure what that value really means yet, especially since I set the pins. Also if you look at the constructor, you will see I had issues with SPI automatically managing the CS pin, and had to remove it from SPI and do it myself.
    Chris
    @cmidgley
    FYI - interesting side effect of running two ESP32 on xsbug (via two instances of serial2xsbug)... a breakpoint set on one machine is also set on the other. Doesn't appear you can isolate breakpoints across machines. Perhaps a preferences feature to consider? Also, at least on Windows with a trackpad, I find the mouse drops to a crawl (and is difficult to navigate) when hovering on the source pane. Otherwise it's fine. Not sure what's up with that!
    Peter Hoddie
    @phoddie
    Right -- I didn't mean to suggest you should try to apply the Ecma-419 style. It won't help your immediate needs. But it could be a good way to package this eventually. I'll take a look at the code (thanks for posting!).
    The values of the SPI port specifier depend on the host MCU. There's no way to standardize those across silicon.
    Often SPI manages CS in a way you don't want. It is pretty common to have to do that yourself to satisfy the peripheral hardware. SPI isn't really that standard....
    On xsbug, having the breakpoints apply across machines is a bug or a feature depending on your situation. It is also how xsbug maintains breakpoints across sessions. It could be possible to support breakpoints by machine, but restoring them for the next session then gets complicated because the VM don't have a persistent unique identifier that can be used to re-apply the correct breakpoints.
    Peter Hoddie
    @phoddie
    Not sure about the Windows performance (I seldom use it...). Is it possible you have a lot of traces going by that are bogging things down? @PrototypingAndy_twitter - do you see the performance problem @cmidgley describes?
    Peter Hoddie
    @phoddie
    Reading through your code -- cool to see how much of the Arduino code you were able to reuse. On CS, I think the issue is that the LoRa part requires the CS to go inactivate and then active between each transaction, but that isn't the behavior of the SPI class. It just guarantees that CS will be active during a transaction.
    Chris
    @cmidgley
    Thanks for all the info - makes perfect sense. I have interrupts triggering now, but I'm doing refactoring to handle optional async. At the same time I'm restructuring a bit to make it closer to ecma-419. Expect a code update in a while.
    Peter Hoddie
    @phoddie
    (I ordered a couple boards to be able to try this myself eventually.)
    Chris
    @cmidgley
    So from my reading, target (the constructor property) is opaque to the implementation, so I'm free to add members there as needed for the driver, correct? Likewise, I can add device-specific methods as needed (staying within the naming rules) and still be pseudo-ecma-419 compliant?
    Also, I see that many devices define device.io for things like SPI, button, LED, etc. When I run, for example, the io/digital/button example, it fails for both esp32 and esp32/heltec_wifi_kit_32 because it isn't defined. Are those just missing, or do I need to do something to get them for those devices?
    Peter Hoddie
    @phoddie
    Yes, target is just for you. And you can add methods and properties as needed.
    Peter Hoddie
    @phoddie
    The device global is what binds the Ecma-419 APIs to the specific hardware you are running on. It must be provided by the build target. Not all do yet. The ESP32 provider doesn't provide device.pin.button because that isn't defined by ESP32 but by a particular board, like Moddable Two.
    Chris
    @cmidgley
    OK - so the heltec board should have one, but doesn't yet. I'll ignore it for now then.
    Chris
    @cmidgley
    Do you have a 3d printer? I designed a case for them, that also holds the battery if wanted. Glad to share if interested.
    Lora Case
    Peter Hoddie
    @phoddie
    Very nice. I don't have a 3D printer, but I have friends. ;)
    Chris
    @cmidgley
    Here are the files: Heltec V2 Bottom and Heltec V2 Top
    Andy Carle
    @PrototypingAndy_twitter
    Yes, actually, I have noticed some weirdness with xsbug on Windows. That crept in sometime quite recently -- I was blaming a recent video driver update on my machine, but @cmidgley's experience suggests otherwise. I'll see if I can figure out when that started.
    Chris
    @cmidgley
    @PrototypingAndy_twitter I recall this issue when I was using Moddable a year ago ... so not sure it's a new issue. Just FYI. Thx.
    Andy Carle
    @PrototypingAndy_twitter
    Interesting. It definitely hasn't been happening on my machine for more than a couple of weeks. I wonder if something did change on my machine that puts me into that camp now. I'll take a look.
    Andy Carle
    @PrototypingAndy_twitter

    @cmidgley When you get a chance, could you try something for me? I just want to make sure we're looking at the same problem. In %MODDABLE%\tools\xsbug\behaviors.js and %MODDABLE%\tools\xsbug\ConsolePane.js, comment out the lines (three total) that reference application.cursor, then close xsbug and rebuild tools (build.bat).

    The diffs for the changes are:

    $ cd $MODDABLE/tools/xsbug
    
    andyc@ANDY-SURFACE MINGW64 /c/moddable/tools/xsbug (master)
    $ git diff behaviors.js
    diff --git a/tools/xsbug/behaviors.js b/tools/xsbug/behaviors.js
    index e41106e31..4aa9d9f71 100644
    --- a/tools/xsbug/behaviors.js
    +++ b/tools/xsbug/behaviors.js
    @@ -51,7 +51,7 @@ export class ButtonBehavior extends Behavior {
                    this.changeState(container, container.active ? 1 : 0);
            }
            onMouseEntered(container, x, y) {
    -               application.cursor = cursors.arrow;
    +               // application.cursor = cursors.arrow;
                    this.changeState(container, 2);
            }
            onMouseExited(container, x, y) {
    @@ -379,7 +379,7 @@ export class CodeBehavior extends Behavior {
                    return true;
            }
            onMouseEntered(code, x, y) {
    -               application.cursor = cursors.iBeam;
    +               // application.cursor = cursors.iBeam;
            }
            onReveal(code) {
                    this.getScroller(code).reveal(code.selectionBounds);
    
    andyc@ANDY-SURFACE MINGW64 /c/moddable/tools/xsbug (master)
    $ git diff ConsolePane.js
    diff --git a/tools/xsbug/ConsolePane.js b/tools/xsbug/ConsolePane.js
    index 12daa115d..899c9bbc7 100644
    --- a/tools/xsbug/ConsolePane.js
    +++ b/tools/xsbug/ConsolePane.js
    @@ -108,7 +108,7 @@ class ConsoleCodeBehavior extends CodeBehavior {
                    let bounds = code.bounds;
                    let offset = code.findLineBreak(code.hitOffset(x - bounds.x, y - bounds.y), false);
                    let color = this.colors.find(color => color.offset == offset);
    -               application.cursor = color ? cursors.link :  cursors.iBeam;
    +               // application.cursor = color ? cursors.link :  cursors.iBeam;
            }
            onTouchEnded(code, id, x, y, ticks) {
                    super.onTouchEnded(code, id, x, y, ticks);
    That eliminates the performance problem for me, at the cost of making the cursor not look correct when hovering over text. If it's the same for you, we'll work on sorting out how to fix that without disabling features. :)
    Chris
    @cmidgley
    @PrototypingAndy_twitter That looks like it's it! Nice and smooth.