We built and delivered over 1000 ocean buoys in a design cycle that lasted about 9 months based on the pocketbeagle MCM. The original plan was to build a PCA on which the pocketbeagle sat (in order to satisfy some “COTS” spec) but the cost of doing so got prohibitive, so we just squished the boards into one. Not so much difference. Our initial prototypes used BB blue and pocketbeagle, and they worked fine with a tangle of wires connecting to different sensors and interfaces. We had no issues flashing things, ever; that just worked (but on the PB we used SD cards, obviously). I think I’m chiming in with Gwen on some of this here:
In our case we built everything to run on Linux using a mix of python3 and C. I definitely regret not doing all in C. It would have been nice to have compile-time checking of code, as the linter just can’t catch everything we threw at that codebase. But python did let us add some fairly complex features very quickly compared to C. I would absolutely not field a hardware system using JS, but I highly value reliability (says the guy who did half of it in python, so take that for what it’s worth). One of our biggest issues was boot time, which we never got better than 30 seconds (but most of the time I had to do that was off the clock anyway).
If I were doing what I guess you’re doing, I’d move the hardware interfaces into a compiled solution and focus hard on error trapping. A system shouldn’t lock up because a voltage went out of range (unless it went too high and you blew up the input, but that’s bad hardware design). Realistically almost all of the work we did on that job was learning about errors to trap. Python’s duck typing is awesome for prototyping but made my life hell in a tight delivery schedule. Trapping things like “the logs partition is full” seems hard in JS - a bugaboo which made my stuff die in 24 days, if I recall correctly.
Anyway, if you separate the UI (in JS, or whatever it has to be) from the hardware interface, it would be easier to make the system more robust and capable. I would do all the HW interface in C if I had to do it again, and it wouldn’t have taken much longer to implement, might have cost me 10% additional dev time. Define the inputs very well on the hardware side (i.e. clamp them), and in the software reject any signal outside the expected range. If you can completely eliminate the OS and go to a compiled baremetal solution (or a stripped down RTOS like what TI offer for Sitara) you will eliminate the linux cruft (you probably don’t need chrony, syslog, a filesystem, etc.) which makes for a simpler system that is easier to debug. Of course then you’ll spend a lot more time programming, but your yogurt machine won’t need to reboot so much.
The biggest issue we have in this type of job is testing. Software guys know how to build a nice test framework. It works great all the way up till you have to deal with some external piece of hardware that might not always do what you expect. In my case, I had a modem which worked well except when it failed in a variety of exciting ways; a GPS receiver which occasionally reported impossible locations, and a series of different analog- and digital-output sensors which all found interesting ways to work wrongly. I’ve built test hardware for jobs, but I’ve never had to automate testing of a system involving so many disparate parts. That’s really, really hard to automate, and I’ve yet to find an approach which doesn’t require me to turn it into a career. As I said above, defining the range of the inputs is key, but it’s so much easier to do with an analog signal than a digital protocol. Even then, should actuator 1 do X when both sensors 1 and 2 are at their negative limits - sometimes these things aren’t completely obvious until you think them through.
Those are just some thoughts from someone who has been there. Good luck though.
Jim