Choosing my SBC hardware. - Page 1
Forum section: electronics / general

author: Simon
author_rank: Unknown
timestamp: May 24, 2025, 12:44:22 pm
content: Right, my objective is to get a small computer running Linux and a HMI program written in Qt with a CAN bus link.Plenty of CAN bus shields out there for the RPi 40 pin header that other SBC's adopt so no problem. I have seen the Radxa X4 that is x86 based with a 40 pin RPi compatible header and would solve a lot of the getting a version of Linux that runs on this board problem but it looks like availability is not there yet.Plenty on Qt on RPi, I expect it to work on virtually any other Linux variant it can run on with x86 hardware.Any suggestions on boards or are RPi just as good as anything.

author: Karel
author_rank: Super Contributor
timestamp: May 24, 2025, 12:52:44 pm
content: The safest bet is to go with an RPI. Not so much because of the hardware (there are better and cheaper SBC's around)but because of the (software)support and the eco system.The competitors of the RPI don't care much about software support and security patches.

author: Simon
author_rank: Unknown
timestamp: May 24, 2025, 01:02:48 pm
content: Well I was trying to get a proper OS onto my RPi5 rather that the awful pi os. I have this problem where the mouse keeps jumping back to the top left corner, happens on both the 4 and 5.

author: Karel
author_rank: Super Contributor
timestamp: May 24, 2025, 01:34:19 pm
content: Quote from: Simon on May 24, 2025, 01:02:48 pmNever heard of it. What makes you think it's the fault of the os? To me it looks like a hardware problem.Are you using the officially recommended psu?99% pct of "weird" problems on the RPI are caused by not using the official psu.Try also another mouse, a cheap and simple wired one like the HP X900 for example. Works fine here on RPI4 with both Raspbian and RPIos.

author: Simon
author_rank: Unknown
timestamp: May 24, 2025, 02:37:05 pm
content: I've had it on both my 4 and 5 and using the RPi mouse with the nice bit RPi5 PSU. Might be a monitor resolution thing - yea don't fall for the 4K claims, they just don't do High DPI awareness or settings.

author: Infraviolet
author_rank: Super Contributor
timestamp: May 28, 2025, 01:41:38 am
content: "The competitors of the RPI don't care much about software support and security patches."In theory those shouldn't matter so much for an x86 board than can run a normal Linux distro, because so long as there's one (long term stable) library of some kind from the vendor which lets you handle GPIO and other low level feature access (which will always be board specific), then all the support for higher level parts of software is handled by the developers of whichever normal x86 Linux distro you've chosen. Security patches in particular are usually going to be related to higher level functionality, and anything internet related, with an x86 board you'd just get these as you would for your chosen Linux distro if it was running on a laptop/desktop/server.I am particularly interested in x86 SBCs, there's a real attraction to having something small, lower powered (watts needed) than a PC and with GPIO but which unlike a Pi can run just the same compiled software as Linux PC can. I'm aware of two major manufacturers of these: Radxa has a few x86 boards, as does LattePanda. I believe, in theory, these should all be able to run any Linux distro an older (when considering the lower end options from Radxa and LattePanda read: weak compared to laptops of even 10 years ago) PC can. I think they tend to have a bit of a strange BIOS/UEFI, as this is firmly in the realm of something board specific rather than at the operating system level, but so long as it can boot from a typical live Linux USB normal installations of Ubuntu/Mint/Debian/... should be possible. I'd be interested to know more from anyone who's had experience with any of these x86 boards.

author: Karel
author_rank: Super Contributor
timestamp: May 28, 2025, 07:37:47 am
content: Quote from: Infraviolet on May 28, 2025, 01:41:38 amAn RPI can run the same software as on a pc, heavy software runs just slower.If you wish, you can install openSuse, Debian, Ubuntu, Fedora.The problem is, x86 cannot compete with Arm in terms of speed/powerconsumption ratio.As a result, when using Linux, it doesn't make sense to use an x86 based sbc.

author: DiTBho
author_rank: Super Contributor
timestamp: May 28, 2025, 10:38:16 am
content: Get x86 sbc.More support, less problems.E.g. Zima-Blades are very nice.

author: Infraviolet
author_rank: Super Contributor
timestamp: May 28, 2025, 05:19:16 pm
content: "An RPI can run the same software as on a pc"No, not when you're considering legacy software which comes pre-compiled (either where source code was never published or where compiling is so tricky and dependency filled a task that you'd rather just have pre-compiled binaries), and this does apply on Linux, whilst you're far more likely to have compilable source code than for Windows programs, you still have some situations on Linux where this is not the case, particularly if you're running exe programs under wine on Linux (yes I know that would tend to be a pretty heavy stack for an embedded system to be using, but it can happen). And on a Pi, or any other ARM SBC, you can only install special ARM version of distros from those distros which maintain ARM versions, not the normal distro versions.

author: Simon
author_rank: Unknown
timestamp: May 28, 2025, 07:53:14 pm
content: There is no debian version for the RPi5, only the awful pios, apparently there are compatibility issues. I do not know what they did to debian to turn it into pios for the RPi5 but yea.

author: KE5FX
author_rank: Super Contributor
timestamp: May 28, 2025, 08:05:56 pm
content: The LattePanda product family is very nice, if sourcing from China isn't an issue for your application.

author: Simon
author_rank: Unknown
timestamp: May 29, 2025, 06:49:06 am
content: I'm liking the look of the lattepanda. It includes the memory which makes it price competitive with the RPi and takes out that headache. SD cards are just a pain and anything else is expensive. My thinking with the RPi was that Linux has native support for a CAN controller on the native SPI port. I'll have to figure out how to setup an elcheapo adapter that probably has a USB/USART adapter in the middle and that is all the system will see.

author: Nominal Animal
author_rank: Super Contributor
timestamp: May 29, 2025, 09:11:35 am
content: Unless you're happy to do everything via the Raspberry Pi community and foundation, and not directly with individual FOSS projects, I would not base a product on Raspberry Pi.Realistically, it is best to consider Raspberry Pi as a vendor-supported walled garden, where GPL is a curse word. If you don't mind working within that, RPi is fine. If you are anything like me and like to do your own systems integration for appliances, and select projects based on their technical merits instead of their leaders' social skills, I'd say it is not a good fit. Otherswilldisagree, so take this as my opinion and experience only, one data point among many.I would look intoOrangePi RV, a StarFive JH7110 quad core RISC-V SoC with HDMI, WiFi, BT5, GbE, native CAN bus on GPIO pins, and a M.2 M-key PCIe 2.0 (one lane only) for 2280 SSD. The 8GB RAM version is not too expensive, I see several at AliExpress (official OrangePi resellers; OrangePi = Shenzhen Xunlong Software Co. Ltd.) for 70€ including shipping and VAT 25.5% to Finland. Uses an USB-C 5V power supply (5V 4A recommended).I am myself looking atOrangePi RV2for firewall/router/edge server; it has similar capabilities and price, but two GbE ports and two M.2 M-key PCIe 2.0 (two lanes each); one 2230 and one 2280. (@brucehoult mentioned that RV is a bit faster than RV2 on this kind of workloads, but I really like the two ethernet ports.) OrangePi does have a M.2 M-key cable extension, though, so that you can use up to two M.2 M-key PCIe/NVMe SSDs (both PCIe 2.0, two lanes each).If you can afford it, I would warmly recommend getting some different boards, and examining how they can be maintained long-term, and how you like 'em. OrangePis have build automation based on Debian, and you can see the development atgithub.com/orangepi-xunlong/(official repositories). Others I personally might consider areRadxa Rock 3A,Rock 3B, andOdroid M1S(usingMCP2515 for CANbus).As to CAN bus itself, I'm not sure I like the idea of connecting CAN bus directly to the SBC. I'd prefer to have some kind of electrical safety stuff in between.. perhaps SPI (using MCP2515), even isolated via TI ISO7741 and a suitable isolated DC-DC converter for "extra safety". Yes, I know: I use isolators way too often, feel free to laugh at me.. but my devices are pretty robust, although I also do spend quite a lot of time in the integration phase – it took me over a week to configure my new laptop to my liking. The Linux kernel does include an MCP2515 driver you can use via Device Tree (overlay snippet) on any SBC that exposes a SPI bus on the System-on-Chip. The overlay is a small bit of compiled text description of the hardware and what it is connected to.

author: Simon
author_rank: Unknown
timestamp: May 29, 2025, 10:03:07 am
content: with regards to the Orange Pi it is RISC-V? so another architecture. Will Qt compile to this?there are isolated CAN bus "hats" for RPi type SBC. Yes I also tend to isolate buses as well, I have found that this is not a cure all though. I recently designed a machine that used 2 servo motors running CAN Open. I thought isolating the CAN bus to my ECU would make it all dandy. Well if you have big enough current spikes that does no really help at all. I had problems with my laptop connected via the programmer to debug, it caused problems so I got an isolator, still did not help much. What did was getting the motors working together properly. Of course when you are connecting out to the great unknown isolated is a very good idea.

author: DiTBho
author_rank: Super Contributor
timestamp: May 29, 2025, 12:56:31 pm
content: RISC-V is still not for people who are not willing to hack the kernel etc.I wouldn't recommend in this specific case.

author: Simon
author_rank: Unknown
timestamp: May 29, 2025, 12:58:41 pm
content: quite, sounds like more trouble than it is worth. I think I'll consider the lattepanda, once I have a CAN bus working off my laptop I'll grab one and see what I can do.

author: Nominal Animal
author_rank: Super Contributor
timestamp: May 29, 2025, 01:34:46 pm
content: I haven't yet decided whether RISC-V support in the Linux kernel is stable enough for HMI and basic networky server thingies; I think they ought to be, but I'll find out in time. My "gut" says that whenever graphics acceleration is involved, all stability guarantees and uptimes measured in years are gone anyway: the hardware and the drivers just are not "rock solid" in that sense.Quote from: Simon on May 29, 2025, 10:03:07 amOrange Pi RV and RV2 are RISC-V,Orange Pi 3Bis a quad-core Cortex-A55, i.e. 64-bit ARM.Yes, Qt supports both 32-bit and 64-bit RISC-V; seehere for Qt-5.15, andhere for Qt 6. With RV or RV2, you'd compile forrv64gcinstruction set architecture instead of sayx86_64(64-bit Intel/AMD) oraarch64(64-bit ARM). The target quad isriscv64-unknown-linux-gnu, and tripleriscv64-linux-gnu. If you compile on the target device itself, you don't need to worry about that either.The Debian port you would use on OrangePi RV or RV2 isriscv64, and Debian has cross-build toolchains too. You can use theriscv64testingimages. There is no official release for riscv64 yet, but it might not be too far off (seehere).OrangePi 3B is another option, this time ARM64/AARCH64 (quad-core Cortex-A55), based on Rockchip RK3566. The 4G version with M.2 M-key SATA/PCIe SSD slot would cost me50 €including shipping and VAT 25.5%, and you'd need to use MCP2515 or similar (SPI to CAN-bus). The useful pins are in the middle of the standard two-row 0.1" pitch pin header:3.3V ● × (GPIO4_A1)MOSI ● ● GNDMISO ● × (UART9_TX)CLK ● ● CS0GND ● ● CS1with 3.3V logic on all these pins. There is also 5V nearby if needed. Note that TI ISO7741 and ISO6741 are perfect for isolating this (if you use only one CS pin on the isolated side, not both), and you can use any logic level voltage between 2.5V and 5.5V on the other side. As to OS, you can use Android, Debian, Ubuntu, Arch, and OpenHarmony at least.And then there isOdroid H4, Intel Alder Lake-N -based SoC; tech specshere. Use a M.2 M-key NVMe SSD, as it can boot off of one; you don't need an SD card or eMMC. The downside is that there is no SPI, only a couple of USB 2.0 on the pin header, HDMI CEC, two I²C, and one UART with RTS and CTS, all signals at 3.3V logic. You'd want to use an USB-based CAN bus adapter with this one, either an existing one like CANable, or one you make yourself. The pin header provides both 3.3V (max 700mA) and 5V (max 1000mA, or always-on max 600mA). HardKernel is South Korean company that designed and manufactures Odroid SBCs.

author: DiTBho
author_rank: Super Contributor
timestamp: May 29, 2025, 02:08:49 pm
content: Quote from: Nominal Animal on May 29, 2025, 01:34:46 pmYes I don't doubt it, but let's take for example one that "should" have support and then in fact they don'tThe RBM33G: in theory it's as you say, in practice ... default kernels come with USB PHY turned off, you don't see the USB disk, and there's no way that the developers (few, and with so many things to do), will release a patch for this thing.Either you are willing to solve it yourself (kernel hacking), or you're left with an SBC that doesn't boot from USB.I fixed it myself, but I don't feel comfortable recommending that SBC to others.I only gave an example, but you get what I mean: on risc-v there are few people, sure mora than on MIPS, but much less than on x86, so don't expect them to fix everything that doesn't work, because it will remain broken for many months, potentially years.

author: DiTBho
author_rank: Super Contributor
timestamp: May 29, 2025, 02:40:03 pm
content: Userland side, a couple of other problems that come to mind.When you have sources that have architectural constraints, and the maintainer is not interested in adding support for risc-v or arm.An example is the mac-fdisk tool (similar to fdisk, but for mac-partitions)On Gentoo is { ~mips, ~arm } because it doesn't even compile. It lacks a stupid #ifdef that takes into account what the "arch" command reports during the configure phase.arch -> { arm?, riscv? } not mentioned -> does not compileIt's a really stupid example, and in fact the problem can be solved in 5 seconds if you know where to put your hands, but you understand the problem better.(and note, no one has fixed this in gentoo in 5 years!!!)Things get much more complicated when a software has dependencies with non-C compilers.GoLang, Rust, etc etc. often the support is nothing more than a limp "yes, it compiles, but no one has tested it"

author: nctnico
author_rank: Super Contributor
timestamp: May 29, 2025, 02:54:48 pm
content: What has worked well for me is the iMX series from NXP. The current mature version is the iMX8 series (Arm64 core). Plenty of manufacturers out there which make these boards including support for bootloader, kernel and OS. I'm running the Arm64 version of Debian on these systems together with the iMX8 specific drivers. Support from NXP is quite good but likely you won't need it when you buy a module which has everything integrated already. Do yourself a big favour and stay clear of Yocto; stick with Debian (or Android).

author: Nominal Animal
author_rank: Super Contributor
timestamp: May 29, 2025, 03:27:55 pm
content: Quote from: DiTBho on May 29, 2025, 02:08:49 pmI know, as I have one myself, but RBM33G uses MT7621 SoC, which has no recent implementations or hardware commonly in use, and MediaTek/Ralink was never very forthcoming with the SoC details to open source folks.In comparison, RISC-V is open (well documented at the ISA level, supported by upstream gcc and clang), many of the SBCs provide schematics with ICs labeled (seeherefor OrangePi RV's), so they aremucheasier for non-vendor affiliated developers like ourselves to support. Besides, companies like StarFiveTech (manufacturer of the SoC used on OrangePi RV)actively contribute to open source projects; two prolific contributors, six total this year. They're pretty well grasped the open source concept, I think. So did Rockchip too until relatively recently, as USA–China relations took a downturn; right now they have just two active contributors to the kernel, u-boot, and other projects.It is true that OrangePi RV and RV2 support is still being upstreamed; for example, there is a person working on upstreaming the OrangePi u-boot support (sources for OrangePi u-boot v2024.01), but for now, one can simply use the fork. Similarly, the Device Tree patches are being upstreamed, but you can findOrangePi RV 5.15andOrangePi RV2 6.6kernel sources at GitHub.

author: Tation
author_rank: Regular Contributor
timestamp: May 29, 2025, 09:12:17 pm
content: AFAIK, Armbian is available for RPi5. I have not used it on RPi, though, but on Radxas. So far, so good.

author: SiliconWizard
author_rank: Super Contributor
timestamp: May 29, 2025, 11:12:03 pm
content: Question is, apart from basic interfaces (ethernet, USB, probably HDMI) and GUI libraries like Qt, what else do you need to support? How many will you build? Does it have to have a long-term availability guarantee? Do you expect the OS itself to be updated or will it be fixed during production and never get updated?If you want long-term support, RPi is probably one of your safest bets. They're not ideal, but the support is reasonable and they strive to have long-term availability. It may also be a safer bet than a chinese board if things go sour with China.x86 boards will allow you more flexibility in terms of software - you'll pretty much be able to install any Linux distro on them. They tend to be more expensive though and draw a bit more power.

author: Simon
author_rank: Unknown
timestamp: May 30, 2025, 06:20:43 am
content: Well in the end I want to end up with a handheld HMI that will operate off a cable to portable machines. CAN bus is pretty essential, if push came to shove and a UART were easier to deal with I could use a micro controller as a bridge but that is pretty much what most cheap USB/CAN adapters are. HDMI is something I have always wanted to avoid problems with combining different screens and boards. The quad SPI ports on SBC's don't seem to be completely standard but then getting a 7" HDMI screen is not easy so I'd have to see what is available.Updating Linux on the device is not essential as it would have about the functionality of a vending kiosk. I would want to be able to connect it to the internet probably over WIFI, I don't know if connecting to the internet immediately demands updates to the OS for security and what the chances are of the one application it would run being affected.I don't need it to be very low power, the screen will have to be bright enough to work outdoors (1000 nits/candles) and it should be powered from a machine although these are often battery powered. The lattepanda board boasts 2W and no need for a heatsink.

author: Nominal Animal
author_rank: Super Contributor
timestamp: May 30, 2025, 08:38:45 am
content: Quote from: Tation on May 29, 2025, 09:12:17 pmRaspberry Pi OS is a renamed fork of Armbian, because GPL and FOSS isewww.

author: Simon
author_rank: Unknown
timestamp: May 30, 2025, 09:47:53 am
content: Oh, but RPi still reference the Debian OS names for their own like bookworm. Presumably that is what it is anyway. One thing that leaves me wondering is that the RPi5 specifically: Currently there is no support to Raspberry Pi 5 as it doesn't have enough support in upstream Linux. Sayshttps://wiki.debian.org/RaspberryPiImagesBut PI OS is Debian based sharing its names....

author: Simon
author_rank: Unknown
timestamp: May 30, 2025, 09:29:44 pm
content: Well Im struggling to get my kvaser adapter to be recognized in linux (debian), downloaded drivers and followed instructions. I'm assuming that to connect to a cheap CAN adapter that is actually on a serial port via USB is going to be worse and certainly won't work with socket CAN and QT. But the lattepanda (got one arriving tomorrow) has a serial port. So I am probably going to end up using one of the serial ports on the lattepanda and connecting my own microcontroller with the bosch MCAN controller in it to interface. I expect that QT will be easier to setup with a real local UART than a CAN port that is on the end of a chain of three different comms systems.

author: Karel
author_rank: Super Contributor
timestamp: June 01, 2025, 06:36:33 am
content: Quote from: Simon on May 30, 2025, 09:29:44 pmYou do know that the RPI has a serial port as well?

author: Simon
author_rank: Unknown
timestamp: June 01, 2025, 12:26:41 pm
content: Yes I know, now that I will roll my own CAN bus adapter that can work as a real time coprocessor for the system it's irrelevant what board I use.

author: Psi
author_rank: Super Contributor
timestamp: June 01, 2025, 12:35:26 pm
content: Quote from: Simon on May 30, 2025, 09:29:44 pmOne thing of note, (i have not checked this exists on every LattePanda versions as there have newer ones), but LattePanda's always included an ATMega MCU on the board as well. This was very useful, as you could design and upload your own code to an MCU already build into the system with IO into the system.You could design your own power on/off sequences based on sending some UART data to the mcu, or keep an eye on things over USB to the main pc. etc..Edit: Looks like both the 3Delta and Sigma have a ATmega32U4 Co-Processor.

author: Simon
author_rank: Unknown
timestamp: June 01, 2025, 01:12:17 pm
content: Well my main use of a micro controller will be as my own CAN bus adapter, my trusty SAMC series has 2 very nice and capable CAN controllers in them so I won't really have much use for the onboard AVR.

author: Simon
author_rank: Unknown
timestamp: June 01, 2025, 01:45:35 pm
content: using the lattepanda option means that I don't need to spend the next year decoding this:https://wiki.qt.io/Cross-Compile_Qt_6_for_Raspberry_Piinto English. As with all Qt stuff what was written for the beginner in terms of instructions clearly is aimed at those with a decade of experience in software development but are new to just Qt.....I'm considering FLTK again, at least the write stuff in English.

author: DiTBho
author_rank: Super Contributor
timestamp: June 01, 2025, 02:22:42 pm
content: Have you also considered ZimaBlades?

author: Simon
author_rank: Unknown
timestamp: June 01, 2025, 04:16:05 pm
content: They have no storage and no RAM, their default setup seems to be a bundle of wires before you attach anything to them that is actually the outside world but good to know that there are other x86 boards out there.

author: Nominal Animal
author_rank: Super Contributor
timestamp: June 01, 2025, 04:51:01 pm
content: Note thatMakerbase CANable 2is a low-cost ($17) isolated USB to CAN adapter, supported by LinuxSocketCAN, which you can use viaQtCANBus and its socketcan plugin, or write your ownAF_CANsocket code. As it is an USB device, the SBC hardware architecture doesn't matter much, as long as it is supported by the Linux kernel.You set up the CAN bus similar to any other network (ifconfiget al., for example), and the application does not need to worry about device names or paths. If you write your own low-level socketCAN code, it is very similar to TCP/IP networking code. Both raw sockets (AF_CAN, SOCK_RAW, CAN_RAW) and broadcast-managed sockets (AF_CAN, SOCK_DGRAM, CAN_BCM) are available.Key point: you can use the same USB-CAN adapter on your development host, and write the application software there; you don't need to develop on the target architecture, as long as you test thoroughly. (With C and C++, it's mostly assumptions aboutintsize/range and such that bite you; better use<stdint.h>explicit-sizeintN_t,uintN_t, et cetera.)It also means you can switch SBCs even across architectures, without having to rewrite your application.

author: Simon
author_rank: Unknown
timestamp: June 02, 2025, 06:04:03 am
content: Yes that is an option. As I said isolation is all well and good but I can easily render it uselessbut it's worth the extra 5 bucks.What is slcan? I'm sure I have seen that elsewhere, something to do with a can bus adapter on a serial link? Unfortunately I have no OS programming skills as of yet other so I don't want to mess with drivers myself.The advantage of my own controller would be that I can pre-disect CAN open for example and possibly carry out other functions that benefit from the real time nature of a micro controller. I don't know if time stamping is done well by cheap adapters but as I already have a body of CAN code written up I know I have all of this and some functions could be done by the micro instead of the main system having loads more messages delivered to it and having to work it all out. The main PC device would just see the actual data and status of the CAN system. For example, I keep track of the heartbeat messages from all nodes, I can either send those straight through or as I have time stamps on all messages received with a resolution of 16µs I can simply tell the PC the overall bus status.I may also need the odd button or encoder input which a micro already acting as CAN bus bridge can also handle although I did once vow that each function would be it's own micro but then this is a single standard item so making up something specific makes sense.

author: Nominal Animal
author_rank: Super Contributor
timestamp: June 02, 2025, 08:55:00 am
content: Quote from: Simon on June 02, 2025, 06:04:03 amI use isolators for all sorts of purposes, and get ridiculed for it here!It's mostly that wall warts without protective ground (like USB power supplies) tend to have a different 0V output potential that those that do (like desktop and laptop power supplies), because we do not have polarized (live and neutral) sockets, they're both live. So, connecting an SBC to the same wall socket than my computer/laptop does not mean they have the same 0V ("GND") reference potential; it can differ by a couple of hundred volts. Also, when you need a low-noise frontend for some stuff, even if they share a ground it is a darn nice way to isolate the power domains, stopping the digital noise from affecting the frontend – especially nice when using batteries for the frontend (for ad-hoc tooling, which is what I often do). TI ISO67xx and ISO77xx also do automatic voltage level translation, too.And I'm not ashamed to admit that they also act as a nice barrier when I do something utterly stupid, like accidentally supplying 12V instead of 5V to the target device; that only blows the target device and the isolator (and its frontend/drivers), not my computers or the rest of the USB adapter. My-own-bacon protectors!Quote from: Simon on June 02, 2025, 06:04:03 amIt is the name of the Linux serial line CAN driver that supports CAN adapters using serial and USB-serial, implementing only sending and receiving frames in hardware, and talk to the host using LAWICEL ASCII protocol. Summary of the differences among various adaptershere.You can use either the LAWICEL ASCII protocol to talk to these, or use theslcanddaemon from thegithub.com/linux-can/can-utilspackage to bridge them to socketCAN. Withslcandin use, you can fully use them via socketCAN.Note that you don't normally need those sources, as most Linux distros have these packaged, usually ascan-utils. The code is not architecture-specific, and should work on all architectures supported by the Linux kernel.Quote from: Simon on June 02, 2025, 06:04:03 amSure! If you use a microcontroller with native USB (like my current favourite, Teensy 4.x), you can program it to use the LAWICEL ASCII protocol, or your own.I personally prefer to use multiple USB serial endpoints, so I can use one for the datagrams in some fixed format (noting that Teensy 4.x supports USB 2.0 High Speed, so you haveplentyof bandwidth, and datagrams can be up to 512 bytes long), and the other for command and control.Quote from: Simon on June 02, 2025, 06:04:03 amJust add an USB HID endpoint exposing itself as a keyboard or joystick or gamepad, and the kernel will handle them, providing to your Qt application as events.Or you could use a three USB serial endpoints, and use the third one for UI events.Because the endpoints are separate character devices (that you can give persistent names using a trivial udev rule), it also means you can use a separate thread for each, using Qt events to propagate events to the main UI thread, or mutex-protected shared variables (just don't keep it locked for long). This makes ahugedifference in responsivity and performance, especially with multi-core SBCs. Keeping the main Qt UI thread to just the UI events and not doing any "work" in it at all makes the UI extremely responsive even on slower SBCs; and using separate threads for the different types of communications buses not only allows you to use more of the cores, but it also lets the kernel schedule the treads optimally. When data becomes available, the thread can be scheduled immediately, without waiting for the "next time slice". It is a pattern that works extremely well with Linux SBCs.Consider an example UI + MCU, where you have a single UI pushbutton controlling a LED or a relay.The bad way to do this is to have the UI button handler write a command to the MCU whenever it is pushed on or off.The optimal (but over-engineered for such trivial example) way to do this is to have two worker threads. One thread sends commands to the MCU, and the other receives (status) responses from the MCU. There are three commands: Query, On, and Off. Each command is associated with a "line number", or rather an arbitrary numeric identifier chosen by the host, and will result in the MCU responding with a status block containing that identifier. For this simple example, the status block is trivial, as it only contains the identifier and the state of the LED or relay.When the program starts, the writer thread sends a Query command. (Note that it is best to start the second worker, reader first, and only send that Query when the reader thread is ready; you can trivially use a Semaphore for this. A mutex won't do, because they need to be unlocked by the same thread that locked them.)When the reader thread receives the status block, it uses the Qt (thread-safe) sendEvent() to send the status update event to your main UI window. In the window class implementation, you have a handler receiving the event, updating the button state to reflect whether it is on or off. Default the button state to disabled (and not reacting to clicking), because before the first state event, we don't know whether it is on or off, and which command clicking on the button would generate.Thereafter, whenever the button is pressed, it sends an event or queues a message to the writer thread to send an On or Off command, based on its current state.Clicking on the button does not change its state (becoming pressed or released). This means that quickly clicking on the button twice, too quickly for the MCU to respond in between, will result in two On commands, or two Off commands; never On + Off nor Off + On.It is only when the reader thread posts the event to the UI thread that the UI thread updates the button state to reflect the device state.One might think that having the UI button react to the press/click with such a latency (which is only a couple of milliseconds for such trivial cases, but can be human noticeable for more complex actions, especially those that require a remote response –– say a response from the engine management system) would annoy the user, but in practice, such a button tends to feelmuch more real: you cantrustits state to reflect the real world, instead of the UI.The numbering of commands and responses is useful when some commands involve remote work or timeouts. Then, the two worker threads maintain a list of pending commands with timestamps (and timeout times) –– In Linux, best useCLOCK_BOOTTIMEfor real-world timeout times –– and one of them, or perhaps a third thread, does the cleanup/removal and sending the timeout/lost event to the UI thread.In Linux, if you decrease the per-thread stack size to something reasonable (I use 4*PTHREAD_STACK_MIN), the cost of a thread is very small; basically just some RAM, even on small SBCs. Using many rather than multiplexing work to a single thread is not only more effective (because you then use more of multi-core processor), but can also simplify the code, as long as you use thread-safe inter-thread communication methods; semaphores for async state changes, mutex locks, and condvars (with an associated mutex) for lists, queues, and arrays. Qt does provide some that are thread-safe, plus mutexes, semaphores and condvars, but you can also use the pthread ones between worker threads. You only need to use the Qt thread-safe ones when talking between the UI thread and a worker thread. The Linux process schedulers are pretty darn well written, and even on a dual-core SBC having a dozen threads in a single application is no problem at all. If well written along the lines I described above, where threads block on waiting for a message or input or output (instead of polling!), they tend to be faster and use the resources more fully than single-threaded applications.Of course, that means you need to be proficient with multithreaded/parallel processing. For me, it was just a change in mindset, releasing my expectations about the order of things, and moving to an event-based thinking model. It works exceptionally well for user interfaces, too.Apologies for the wall of text, but I had lots to say. Hopefully at least some of it is useful! If not, I hope you skipped most of it.

author: Simon
author_rank: Unknown
timestamp: June 02, 2025, 09:39:31 am
content: Ah, I see. I have a cheap (waveshare?) USB/CAN adapter but if I query available ports with "ifconfig -a" I just see a serial port. I'll have to have a look at that.Threading wise I am way behind you. I have no idea how any of this is done yet. I get the principle of multiple threads and that if I can break things down into multiple threads it will spread he load and let stuff be more responsive but that is it at the moment.So I booted up my lattepanda, runs windowz 10 slowly as I'd expect with only 2GB of RAM and goodness knows what that SSD actually is. Installed the recommended Ubuntu on it and my god what a peice of garbage. As soon as I connected the wifi the mouse is leaving artefacts all over the screen but it's due an update when I get back tonight so might sort itself out. Ultimately I won't be using the desktop.Not very impressed with the power up sequence. when power is applied you have to wait for the blue light on the processor module to go out before pressing power, yea sure, try telling some oaf in the street that who just wants to use his machine. I'm sure it will be fine as they'd have to plug the machine into its power source first before they get round to starting the HMI.

author: Nominal Animal
author_rank: Super Contributor
timestamp: June 02, 2025, 12:10:34 pm
content: Note thatslcanddoesn't really do the translation itself; it simply opens the device, and sets a tty line discipline that connects it to socketcan network. It then just sits there, waiting for a signal to exit (poorly done, using one-second sleeps instead ofsigwaitinfo()), after which it simply resets the line discipline (tearing down the socketCAN device) and closes the socket.Quote from: Simon on June 02, 2025, 09:39:31 amUSB-CAN-A, USB ID1a86:7523?It uses its own binary protocol (describedhere under Documentation), so it isn't supported byslcand(source) –– or rather, the ASCII format line discipline that the kernel drivers use to connect it to the socketCAN network.CANable 2is open source(I linked to the MakerBase one above), and uses the ASCII protocol and does work with socketCAN viaslcand. If you want, you can omitslcandin your own program, and instead do what slcand does, keeping the socket open for the lifetime of the application.With very little work, you can make your own application (scan and) open/attach and detach/close CAN devices when desired, too: all you need to do, is open the device (fd= open(path-to-device, O_RDWR | O_NOCTTY | O_CLOEXEC)) set the serial/tty properties (termiossettings), then attach the N_SLCAN (17) line discipline using anioctl(fd, TIOCSETD, N_SLCAN)call.To detach (and when the application exits), useioctl(fd, TIOCSETD, N_TTY)to revert it to a normal serial device, reset the original termios settings (flushing buffers, usingtcflush(fd, TCIOFLUSH), and close the open descriptor usingclose(fd).Note: If you use an USB 2.0 hub (with a "transaction translator" (name?), so that the host connection is high speed even when downstream devices are high or full speed or a mix), you definitely can use more than one adapter just fine. USB 1.1 Full Speed is limited to 12 Mbit/s (or about 8 Mbit/s payload data in practice).If you use e.g. eudev (or systemd with udev), you can use libudev to get low-latency notifications on device events, so don't need to scan (except at startup).If you use an udev rule for supported USB adapters, you can add a symlink e.g./dev/slcan-vendor^model^serialor some such, and then trivially list them all usingscandir("/dev/", &namelist,filter, NULL), whereCode:int filter(const struct dirent *ent) { return !strncmp(ent->d_name, "slcan-", 6); }i.e. returns nonzero for the names that match theslcan-prefix. As the symlink name contains the vendor and model and serial in separable format, you can trivially generate the user-visible adapter names to select. Perhaps a menu with currently known possible devices, checkboxable to enable, with a bottom entry "Rescan"?Anyway, it would definitely be possible to add a new line discipline, sayN_BINCAN(31), with a straightforward kernel driver adding support for Waveshare-like USB adapters to socketCAN. Theslcankernel driver sources are atdrivers/net/can/slcan/(link to Linux kernel sources at Bootlin Elixir Cross Referencer), and is less than a thousand lines of C including whitespace and comments. The key is thestruct tty_ldisc_opsandstruct net_device_opsdefineddrivers/net/can/slcan/slcan-core.c: everything is event-driven, and these are the callbacks the kernel uses to transfer data.If I wasn't mentally broken the way I am, I'd whip up a driver and push it upstream.. but I am not able to anymore.Quote from: Simon on June 02, 2025, 09:39:31 amI really like pthreads (native kernel-managed Linux threads). It's not perfect, for example needing to initialize apthread_attr_tstructure to override the default stack size to something more reasonable can be annoying, but it is very comfy to me. Then again, I've been using it for over two decades for real work...Understanding theevent-driven programming modelis extremely important, as is the fact that ordering of accesses varies regardless of the one you think when writing it, unless you enforce it with either locking (mutexes, condition variables, semaphores, rwlocks) or thread-safe atomic operations (on systems with coherent caching). Qt provides some thread-safe operations, and its own wrappers around the locking primitives; so does glib when using gtk. You also avoid global variables (unless protected by locks), and instead prefer thread/work-specific dynamic allocations. So better get comfy with malloc/realloc/free, too!Also, to minimize boot time, look for an SBC that supports PCIe (NVMe) SSDs, and then pick one with the best random 4k read rate you can (considering price and availability and such). That gives you a lot of leeway on systems integration, i.e. how much youneedto optimize the boot process; you'll definitely see the difference. Unexpected poweroff protection is difficult (mostly due to syncing to storage needing some real-world time to complete), but software power-off is very easy nowadays in Linux. Usually, the physical power-on button is internally also wired to emit a please-power-off input event, which takes care of this on e.g. laptops, but does lead to the delayed-power-LED-turning-off effect. If you do expect power to be cut off unexpectedly, consider a supercap or similar to give the necessary time window to shutdown cleanly; this too can be optimized via scripts, for example immediately turning off all USB ports (if they have power control), the display, etc., killing unneeded processes, before forcibly syncing and unmounting the storage device.

author: tggzzz
author_rank: Super Contributor
timestamp: June 02, 2025, 01:59:35 pm
content: Quote from: Simon on June 02, 2025, 09:39:31 amBeginners tend to use threads too much, and often end up diddling thread priorities to work around today's problem (and re-introduce last week's problem). Thread priorities should be limited to "ISR", "emergency panic", and "everything else".Much better to use an event driven architecture with an explicit FSM, where events are passed through mailboxes/FIFOs between between FSM execution contexts. Analogy: synchronisers between hardware clock domains.An event is any single item that needs to be processed, e.g. an input captured in an interrupt routine, or a command from a front panel FSM, or the processing result, or output to be done etc. Each event is completely processed before processing the next event, thus avoiding all sorts of problems.Debug the FSMs on your PC using mock events created in your test harness.Debug the i/o and ISRs etc on your target hardware, with the events in FIFOs being directed to your logging on the PC.When those are OK separately, drop the FSMs into the target hardware, and monitor the FIFOs to see what's happening in the real operating environment. Done properly, such logging can be extremely fast and left enabled in production systems - invaluable during system integration

author: Nominal Animal
author_rank: Super Contributor
timestamp: June 02, 2025, 03:08:28 pm
content: Quote from: tggzzz on June 02, 2025, 01:59:35 pmI agree what you wrote in a microcontroller or realtime environment, but when using pthreads, that means standard Linux/POSIXy userspace application or service.If you eventhinkyou need to change thread priorities to fix some issue there, you're doing something very wrong.(I have only done that in very rare specific circumstances and only to fine-tune performance by ensuring that if there are more active threads than cores, a specific worker thread has priority. I do often run entire processes nice'd and ionice'd to run in the background when resources are otherwise idle only.)

author: Nominal Animal
author_rank: Super Contributor
timestamp: June 02, 2025, 03:28:41 pm
content: Let's take a look atslcandsource as an example case.On line 421 or thereabouts, you see a loop commented with"The Big Loop",while (slcand_running)sleep(1);This is a bad pattern. Not horribly bad, but not good either.Actually, that particular one is kinda buggy.slcand_runningabsolutely needs to bevolatile, and as it is modified by a signal handler, preferablyvolatile sig_atomic_t(likeexit_codeis).This is related to the bad beginner pattern of using too many threads that tggzzz mentioned, in the sense that in Linux/Unix/POSIXy fully hosted systems like here, the signals are delivered asynchronously using any thread within the process. Here, it's like all the work is done in the "worker threads" (signal handlers), with the main thread having nothing to do. (Again, the purpose ofslcandis to just keep the device open with N_SLCAN line discipline; it does not actually read/see/write any of the CAN data at all.)A better pattern, similar to using a finite state machine, would be to discard the signal handlers, and instead use a loop based onsigwaitinfo(). At the beginning of the program, the signals are blocked first,static const int signals[] = { SIGINT, SIGTERM, SIGHUP, SIGALRM, SIGCHLD, SIGUSR1 };sigset_t sigs;sigemptyset(&sigs);for (size_t i = 0; i < sizeof signals / sizeof signals; i++)sigaddset(&sigs, signals);sigprocset(SIG_BLOCK, &sigs);Then, instead of the loop, we wait for any of those signals to arrive,siginfo_t info;int signum;do {signum = sigwaitinfo(&sigs, &info);// Note: We can safely ignore any errors (signum==-1) here, and do.} while (signum <= 0);the signal number is insignum, and e.g.info.si_pidcontains the process ID that sent the signal, 0 for kernel.After the loop, the signals are still blocked –– sigwaitinfo() and sigtimedwait() "temporarily atomically unblock-block" the signals –– so receiving another signal during cleanup won't affect the application/service cleanup at all. Plus, this way you don't need to worry aboutEINTRerrors (that occur for "slow" calls like reading or writing to files/sockets/pipes, and that thread is used to deliver a signal to the process).So, I do agree that deciding what to move to a separate threadeffectivelydoes take some experience.

author: Nominal Animal
author_rank: Super Contributor
timestamp: June 02, 2025, 06:37:25 pm
content: Apologies for spammin' the thread, but I feel this is worth reading:With GUI toolkits like Qt and GTK and FLTK and others (except for SDL and Curses), the toolkit takes control of the main thread, and simply calls back to your own code whenever there is an event to be handled.We absolutely do not want to do anything time-consuming in that thread, because the UI is effectively stalled for the duration of handling each event in your own code. This is less important when you use X11 or Wayland, since the stall only affects that one process (application), and anyway the server buffers some user actions separately of event handling. It is extremely important if you run a single-app "kiosk" mode, say fullscreen Qt over raw framebuffer/DRI.Thus, in any GUI application running on a Linux SBC, be that on raw framebuffer or under a window manager and server, each application doing network/serial I/O or heavy computation should have at least one separate worker thread.For example programs we often skip threads, and use the main thread. That's fine, but I'm talking here about "proper" applications that you could sell, and be proud of the quality too.As an example, when opening some file that needs to be parsed, the file open dialog, when Open button is pressed, can actually cause a new thread to be created for parsing the file, with main window having an info/progress bar somewhere. The thread reads and processes the file, sending regular updates (a dozen to a hundred all told, no need to be exact) of the progress as UI toolkit events to the info/progress bar widget in the main thread (using thread-safe event interfaces). When the file has been read and parsed, the handles are passed as an UI toolkit event to the main application or main window, and the thread exits (which usually involves sending an UI event to the main application with the thread handle as a parameter, so that the main application can reap the defunct thread; this ensures its stack etc. is freed then and there, and does not just lie unused until the process exits).When we discuss things like whether you should use one or more threads when sending and receiving datagrams, that depends on the protocol and your needs, in my opinion. For synchronous query-response protocols, where you cannot have more than one query "in flight" at any time, one thread suffices. For IP networking, it depends on what kind of work is done on a per-peer/server/client basis; I've done both single-thread-nonblocking and thread-per-client myself.But if nothing else, understanding that with Qt/Gtk/FLTK/etc., the main thread is owned by the toolkit running its own event loop and only calling to your code to deliver events; and that any possibly blocking work or work that can take some time, really should be done in a different thread and not in the main thread event handler itself, is crucial. The single threaded approach will work on fast desktop computers under window manager, well for most examples even, but forproperGUI application development, you end up having to work with threads at some point. I say, as early as possible, because then you also get thefeel, the intuitive understanding, via experimentation and trial and error, of how to best use separate threads, and when to combine several threads into one for example by usingpoll() or ppoll()(better thanselect()) and so on.

author: Karel
author_rank: Super Contributor
timestamp: June 03, 2025, 08:52:44 am
content: Quote from: Nominal Animal on June 02, 2025, 06:37:25 pmIf the time consuming part uses a loop, you often can get away by periodically calling QCoreApplication::processEvents() (at least to prevent graphical artefacts)But I agree that using QThread is better, it's just that it requires more code.

author: Simon
author_rank: Unknown
timestamp: June 05, 2025, 06:28:58 am
content: So the Lattepanda has no alternative input to the power on button, How do you embed this into a device if the use has to press the power button on the board itself. There appear to the through hole pads for the power and reset buttons where connectors could go but there are filled with solder so scrap that idea.

author: Psi
author_rank: Super Contributor
timestamp: June 05, 2025, 12:19:05 pm
content: Quote from: Simon on June 05, 2025, 06:28:58 amAre you sure, im pretty sure there is a header for the power on pins.Which lattepanda did you get?Pretty sure the ATMega32 has access to power on too, being able to power on/off the full system from the co-pro was kinda the entire point of it.

author: Simon
author_rank: Unknown
timestamp: June 05, 2025, 05:52:10 pm
content: https://docs.lattepanda.com/content/1st_edition/hardware_introduction/Well there was a header there or at least pads for one, but the asshole have filled them in with solder. It is not a production solution to try and take the solder out to put a connector or wires in there. I don't think the micro controller has access but then we are back into the territory of assholes that are clueless and would be better not wasting our time. Why would I even want to replace a simple wire with a simple wire and a micro controller program I never needed but for their stupidity. Every time I think I have found something better I just discover a whole different version of fucking stupid problems!

author: Psi
author_rank: Super Contributor
timestamp: June 06, 2025, 02:28:15 am
content: Can you set the typical bios setting for AC Power Recovery / After Power Loss / Restore on AC Power Loss ? So that it powers on as soon as it gets power making the button redundant?For most embedded PC applications you would use that feature.Or will that not work for your application?

author: Simon
author_rank: Unknown
timestamp: June 06, 2025, 06:51:29 am
content: That would work just fine, I'll have a rummage in the bios. The documentation is a bit weak on details. I've not yet seen any clear explanation about how the Arduino system is physically connected to the main system, I guess it's through it's USB. It's a pity these product chase the latest craze. Why put an old AVR on a board that you are advertising as ideal for industrial applications. Put some decent ARM based chip like a SAMC that has was more industrial connectivity like CAN bus. Unless I have to use that Arduino "thing" for hardware reasons it will be completely ignored in favor of a SAMC, then I'll have plenty of low level connectivity.

author: Psi
author_rank: Super Contributor
timestamp: June 07, 2025, 06:21:01 am
content: To be fair, you bought the first generation that came out in 2018, back when they were a startup.And they can't really update it because it needs to stay the same for anyone using it in embedded projects.But yeah, they still have the ATMega32 on the latest ones. which does seem kinda stupid given what they could use instead.

author: Simon
author_rank: Unknown
timestamp: June 07, 2025, 11:41:14 am
content: Yes, the annoying thing is that there seems to be the pads right there and I could even solder my own connector on but they are filled in. All they had to do was not fill them with solder.

author: Simon
author_rank: Unknown
timestamp: June 08, 2025, 09:08:05 am
content: Yes there is a BIOS boot when powered setting, excellent suggestion.

author: DiTBho
author_rank: Super Contributor
timestamp: June 09, 2025, 10:19:14 am
content: OrangePi ultra comes with canbus, but I wouldn't recommend it because it has several hw and sw problems.