Is a thread really independent?

I’m writing an application which will run on a Raspberry Pi in a box with only some LEDs, hardware buttons and a 4-line LCD as a display. And lots of input/output (sensors, relays etc.).

To offer more insight as to what it’s doing I’ve added quite a lot of spoken messages, which really do help. I’m using a system call to flite, via shell.execute.

This all works, but because the program execution is blocked until the shell.execute command returns, and speaking a message takes a while, I’ve had a few instances of high-priority signal inputs havng to wait until a stream of messages has been spoken.

To try to get around this I’ve put the shell.execute command in a thread, accessing an array of messages which can be updated in the main program. Here is the code:

[code]var message as string
var s as new Shell
var command as string

while speakQueue.LastRowIndex >= 0
message = speakQueue(0)
command = “flite -voice kal16 -t “”” + message + “”""

speakQueueEmpty = true

and here is the method which is called in the main program to speak the message. It has message as string as its argument.

[code]// add new message to the speakQueue
AddMessage(“added message to speakQueue:” + message, MessageType.Normal)
AddMessage("speakQueue length = " + str(speakQueue.LastRowIndex + 1), MessageType.Normal)

if speakQueueEmpty then
AddMessage(“speakQueueEmpty is TRUE, so starting speakThread”, MessageType.Normal)
speakQueueEmpty = false
end if[/code]

The properties speakQueueEmpty and speakQueue have Public scope.
The AddMessage() entries here are for debugging: they send the appropriate message to a serial console, with ANSI text emphasis according to the MessageType.

What they show me is that even for a string of spoken messages issued one immediately after the other, the thread is processing them individually.

So is it the case that even for a shell.execute in a thread that the whole program waits for the return? Or have I made a coding error?


a shell that is synchronous in a thread probably wont make any difference
threads are scheduled cooperatively and a synchronous call to an os service in the shell will block the until it returns which also may cause the thread to be blocked and then everything is blocked

have you tried using a shell that is async to run the speech ?

Hi Richard,

I would expect you to find issues reading multiple hardware sensors with raw data that needs processing in real time when using a Pi.
it is not an embedded hardware replacement due to the issues you are now seeing.

anything you do in the same thread will stop all hardware sensor reading, which will either be noticed a lot, if the thread is busy a long time or seen as a glitch when a reading is lost in your testing period due to some short event happening in the OS that you do not know about.

all my Pi projects using sensors or encoders, anything that is not a simple button actually, has an off board PIC to buffer the data and then the Pi requests any new data (vial the serial interface) which it displays.
this is 100% reliable where the Pi only version was nothing like it.

as good as Pi is at many things, a replacement embedded micro it is not, nor was it designed to be.

2 cents of experience for you!


Thanks Norman,

No I haven’t. I’m not sure I know how to do that. Could you point me in the right direction?


Thanks Mark,

that’s an interesting idea, though actually I’m not sure my application is that critical. The input signals are states, which change infrequently (eg a hardware line indicating bad weather). There are some others, eg limit switches for the motion system (the whole thing is to control a roll-off roof for an astronomical observatory by the way) but these have a direct hardware feed-through to the motor controller, which is itself very intelligent (it’s a RoboteQ device).

To add to the fun and games, there’s a serial connection to the RoboteQ and a TCP link to a helper app I’ve written in C++ which uses BLE to talk to attitude sensors on the telescopes and a laser obstruction detection system. That’s the one who’s signal has to get through with minimal delay. These BLE devices are running on Arduinos. For security, I’ve doubled up the BLE link for that one with an ultrasonic signal which triggers a dedicated receiver to open a relay – though I haven’t yet linked that to the main motor contactor (a 250amp automotive relay). It only drives one of the inputs to the Pi at the moment.

I’ve been testing this system on a high-fidelity hardware simulator to avoid risks to the real hardware, and have found it to be reliable so far, except for the delays I’ve mentioned. Of course, I haven’t yet run the formal testing to check all branches and failure cases.

Thanks for the ideas!


Shell.Mode (or ExecuteMode in r2) lets you set the mode to asynchronous. When run as async it calls the event (DataAvailable/ResultReturned) when the shell results are returned rather than blocking.


Paul, where is this event exposed?

[quote=457732:@Richard Francis]Thanks Norman,

No I haven’t. I’m not sure I know how to do that. Could you point me in the right direction?

Depending on what version your using
2019r1.1 and older - set Shell.Mode = 1
2019r2 and newer uh … Shell.ExecuteMode = Shell.ExecuteModes.Asynchronous

Hi Richard,
a very interesting project, the detailed explanation shows well that the majority of the stuff should be fine in your environment, except the BLE which may be an issue, maybe an ESP unit which works on 868 MHz or so might be a more reliable solution, they could be a two way system of very high reliability where the ESP can store events and have a handshake, unless you are able to do this already with the BLE, just as an alternate thought.

you are most certainly eliminating all the real world issue if simulating, it appears you are aware that opening it up to the world out there is likely to break something!

I am not sure which version of the Pi you are using, but the serial port priority changed in the 3 version(hardware on bluetooth, software on serial pins), so it sounds as if you must be using a 3 if you are running BLE.

lets hear what happens when you get it in the wild, I would love to see it working in the telescopes, I wonder where it is!!! mmmmm

sorry, off topic.

Hi Mark,

indeed I found the BLE a bit flakey on a R-Pi3, which is why I went for the ultrasonic backup. In the meantime I’ve moved it all to a R-Pi4 and the BLE has been very solid. Funny, I had put it down to the Arduino 101’s, but as of the switch to the R-Pi4 there have been no BLE issues (except a weird one which only shows up just after power-up: that’s definitely off-topic!).

The simulator is, as I’ve said, high fidelity. All hardware is replicated, including the RoboteQ controller (albeit a low current version - only 30 amps!, but running the same firmware), the encoder, all electronics boxes, the attitude sensors (mounted on servos to replicate telescope motion), the full laser sub-system with its auxiliary sensors, in a compact layout, and many other signal sources.

[quote]you are most certainly eliminating all the real world issue if simulating, it appears you are aware that opening it up to the world out there is likely to break something!

Indeed: I used to build satellites for a living before retirement and I’m using the same techniques :wink: Simulate, emulate, test, test again, test all imaginable errors and worst cases and finally import it to the target environment.

Check out for a taste :wink: (the old video dates from when I had a fully Arduino-based roof control system)


ok off topic now, WOW, beautiful, very interesting to see.
until 3 years ago I lived in Lanzarote where I am sure you know of the very dark skies, now in Alicante on the peninsular near the coast wherein is not so dark!.

If you feel the need to do any bespoke hardware at a very low level then thats what my life has been as a primary, to replace the Arduinos that is, I really do not like that IDE or language.
for me its design, build, test, tweak test, test and test again then rebuild, no simulation for me!

I would love to hear from you how you get along in the final stage and how it all performs.
I have not yet got a Pi4 but its on my list of ‘don’t need but do want’ along with the very compact 3+.

feel free to contact me off forum with any updates.

73 de G0EBB

Hi Mark,

indeed I missed some steps, most of which you mentioned: analyse, design, simulate, build, emulate, test, tweak, test (loop the last 2 until no further errors show up), test again, test all imaginable errors and worst cases (at least input voltage and RFI based on sources easily available: lacking a thermal chamber I can’t easily do temperature), and finally import to the target.

I’ll update this thread when I eventually move to the target. I’ll build a new system for the final implementation (it’s a box made of 4 slices: R-Pi; sensor conditioning; i/o and protection (TVS diodes on all external inputs); and a 15W dc/dc converter + 2x RS232 output boards, plus an optional top panel (optional in the sense that it fully works without this panel) with hardware control buttons, indicator LEDs and a 4x20 LCD display). I’m using ribbon cable between the slices, but if I were to design it again, I would use a “mother board” across the bottom with card-edge connectors.

I’ll keep the original unit and the simulation/emulation environment operational for troubleshooting and validation of updates.

In the end I have 4x R-Pi-4’s – due to lead time quotes I ordered 2 (1 for the development model, 1 for the final target) from 2 different suppliers, but they all arrived well ahead of the expected delivery.


Hi Richard,

I have so many prorotype stuff here, and I will never get rid of them.

just wondering what the RS232 interfacing is and if they are actually on one Pi.
for my most recent project the Pi (on a 3) the serial port (the internal Pi one switched from the bluetooth port) was not quite up to the reliability I expected (on receive) so I ended up running a console app for all the serial send/receive which meant it has its own core in the Pi and the GUI is then basically running on the main thread and that solved all my timing issues.
I did test and has 3 console apps running with 3 devices sending my maximum data packets and they worked very well.
its a bit of a pain to get your head around at first but overcame the Pi low performance issues I had.

look forward to the update.


The principle use of RS232 is to interface to the RoboteQ motor controller. It runs at 115200 baud (non-selectable) and due to overlap with the Bluetooth, (which I also need), I started with the mini-UART. With the R-Piv3 I found this to be pretty flakey at 115200. For that reason I opted to use an external FTDI USB-RS232 chip driven from the Pi’s USB. I’m using a small PCB by EasySync (a partner or subsidiary of FTDI). That works fine.

However, I still had the hardware connection to the mini-UART on the board, so I decided to use that as a console window, which I thought wold be handy as the unit will mostly be running as a stand-alone box. I’m converting to RS232 voltages with another small PCB from WaveShare (I have previously made these sorts of MAX232 converter myself, but the cost of the WaveShare board was less than having a bare PCB made). With the Pi4 I can reliably run this at 115200 and I’m using it to log diagnostic messages from the box.

Both of these are driven from the same Xojo app.