I’m a big fan of the W3C Web of Things standard, which defines a lot of those things. It’s not intended for scientific hardware specifically, more aimed at common IoT devices like light bulbs and thermostats, but there’s no reason it can’t handle more complicated datatytpes. We use it for the OpenFlexure Microscope, and it has proven to be quite a good solution, especially when trying to integrate multiple different devices together.
I think, provided your device is powerful enough to handle HTTP, it’s usually a good way to go. There are tons of good libraries in different languages supporting HTTP interfaces, and lots of good conventions on how to write them.
I was recently involved in a really fun project led by @beniroquai where we hooked up the OpenFlexure software, an OpenTrons OT2, and ImJoy for image processing, all controlled by a Jupyter notebook. I think the OpenTrons sort of has an HTTP interface, but it doesn’t expose the full functionailty: it’s mostly intended to be used to upload a protocol, which the OT2 then executes using its on-board computer. I am fairly sure the most successful configuration ran the Jupyter notebook directly on the OT2, which does give a Python API for its own functions, and then used the HTTP API to control the OpenFlexure server. It’s written up in a paper in Advanced Biology (open access).
By chance or context, the pipetting robot I’m working on has components similar to OT’s: a web GUI → JSON → python module → GCODE → hardware drivers.
What troubles me is that I can’t really envision how to standardize the hardware driver end. We’re using Arduino with GRBL, so HTTP may be impossible. Do you think the WoT standard can help?
A solution for CNC controllers may be Klipper, which @jeremycahill is already considering. Klipper can drive many CNC controller boards (many different and many simultaneously), and be driven through a virtual serial interface or API server.
Klipper seems nice for hardware-agnosticism and the web-standard stuff (which I have to read up on).
We use a valid JSON (ASCII Serial/Uart) as the command and as the response. It allows us to use things like BT Serial protocols, along with other types of communication mechanisms, in a pretty general way.
It contains a meta section at the top level and then a data section for the bulk data. It’s not terribly consistent, there are other sections that deliver data which have custom names.
But happy to share the details. I’m realizing in writing this I don’t think I have it described well, though if you have a device you could easily see it. It’s often shortened before the data is saved (the full raw output isn’t necessarily saved) so it’s not really visible in the existing saved data we have. If you’re interested I can post here an example and break it down if that’s helpful.
This is interesting - whenever I’ve had to design a serial protocol, usually I’ve been trying to minimise the microcontroller code, so I “just do something simple”, which inevitably results in an ad-hoc protocol that won’t quite match anything else. It would be cool to see what libraries/frameworks you use, and whether they make the microcontroller code simpler or more complicated… I’m also curious how powerful a microcontroller you need - I guess even an ATMEGA328 can probably handle a bit of JSON, if there’s a reasonably efficient library?
The Web of Things standard (which I agree is waaay more complicated than most instrument developers want to read) does quite a nice job of separating out the self-documenting “thing description” model of a “thing”, from the implementation in a particular protocol (HTTP, WebSockets, MQTT, etc) which they call the “protocol binding”. Sending valid JSON via serial feels to me like it is very close to the WebSocket protocol binding (which is also a two-way text channel), so it might be interesting to think about how close the two protocols are.
Having said that, there is no serial protocol binding - so this would end up being a new standard anyway, and unless lots of others want to adopt it, there’s no benefit to changing anything…
I think the place for HTTP (and ideally the WoT standard) is in the link between your web GUI and your python module. That’s how it works for the OT2 and the OpenFlexure Microscope: the embedded computer runs a web server (in Python, not that that’s essential) which handles all the nice self-documenting HTTP API stuff, and a lower-level serial protocol is responsible for communication between Python and the Arduino.
Given that G code is a well-accepted standard, and the GRBL firmware is very well tested, I don’t think anybody would gain anything from shoe-horning it in to a web of things protocol without good reason. I’m a big fan of the WoT approach, but I need to remember to pay attention to its limitations! I probably also ought to have used g code when I first wrote the firmware for the Sangaboard motor controller we use - but I didn’t, and inertia means we’ve never changed that.
I think there possibly is scope for the Web of Things standard to help when you’re using a more powerful microcontroller (i.e. one with a network interface), because it enables lots of devices to talk, without needing to embed a more powerful computer. When buying a new, big, expensive piece of lab kit, for example, it would save a lot of headaches if it came with an RJ45 socket, rather than a badly-written USB driver. However, if you already have a serial protocol that works nicely, why change it.
To your sidenote - the GRBL module is a contribution that was added by a collaborator, working in something of a hurry to connect a bunch of things together - I guess he just didn’t find the other solutions. I am 100% sure he would have used them if he’d found them - Bene would always much rather pull in existing code than write stuff from scratch. I’m often guilty of implementing stuff myself if it looks simple, rather than learning my way around a library I don’t fully understand: I try to force myself to find and use existing libraries whenever I can though, because it is much better for the community even if it is more work for me in the short term…
I’m not sure if its the same or similar to HTTP, but the GUI currently controls the module through a (far from perfect) websocket.
GRBL is surely not web-able. I understand that the ATMEGA328 has very little space left for extra features. If it were a requirement, then lots of CNC controllers support control over a network (like the Duet, or this) and…
I’ve just learnt that Klipper can be controlled through HTTP and MQTT by using Moonraker (a Python3 webserver for Klipper).
So… most connections will go through HTTP or Web Sockets, for the lowest possible cost, except for the USB connection to the Arduino. I don’t know if CNC controllers can be synced with sufficient accuracy over a network. Would be cool though!
Just to clarify, I wasn’t criticising
It’s kind of funny that writing one’s own GRBL driver is a thing (?)
Happy new year to you too - WebSockets are defined as one of the “protocol bindings” for Web of Things, so you can be a fully-fledged WoT device that way. The WebSocket binding probably results in more verbose JSON messages than something written from scratch though, and I’ve not used it myself. In the long-term utopia where there are nice clients for WoT devices in lots of languages, it might save you writing a bunch of boilerplate code - but at the moment it might just make your job harder!
For sure getting WoT control of an ATMEGA328 is a very tall order, but these days there are plenty microcontrollers available for a similar price with a lot more power, that could easily handle a basic HTTP server (like the Duet you linked to). I don’t think you should need to jump to something like a Raspberry Pi unless you want a lot of extra features - I suspect running on a Pi (which has a full Linux OS) rather than a microcontroller would be far worse for your timing accuracy than using (wired) network vs serial or USB communications. That said, I think you are still right to keep GRBL and the USB connection as it’s simple, reliable, and already working nicely