Raspberry Pi Sequential Timer Problem...

Hello,

I am facing a Peculiar issue with a Xojo App compiled for Raspberry Pi, the same App works without any problem on my Windows, MACOS and Linux desktops…

The Problem…
I have a Listbox with some parameters that need to be sent serially to a microcontroller, Each Row of the list corresponds to a step sequence that the microcontroller needs to execute in that step routine while each row has 10 columns, of which the column 3 to column 10 are parameters pertaining to each step. Each Step has a specific address in the microcontroller’s EEPROM, so at each tick of Timer1, a string command which specifies the storage pointer is sent out serially.

The 8 individual parameters for that step need to be sent, so this is sent with at each tick of timer2, the microcontroller receives this and stores the 8 parameters in their assigned address space.

Essentially it is like a nested For loop, timer1 outer for loop while timer2 inner for loop…

I have Three Timers on a form/Window, The first timer is initiated by the user interaction with a ui element on the form/window a push button. Timer1 has a large period of 10 Seconds, This timer1 initiates another timer2, Timer2 has a period of 1 sec, 8 parameters are sent serially in Timer2.

Only Timer1 is running on the Raspberry Pi, the second timer starts the row parameters are sent out but the end of timer2 must increment to the next step, the second address pointer isn’t being sent out by timer1, so the timer1 first address pointer is sent out, serially followed by the first step parameters, this is continuously cycled.

However, the same code compiled for a desktop machine runs fine… all Steps 1 to 18 are sent sequentially in between their respective parameters. This doesnt happen on the RasPi???

Appreciate your help, thanking you in Advance…

These parameters are stored in a Text file as a CSV, at the Open event, the list is updated with the parameters…
TheA1.txt CSV file at the end of this post…

frmRunSystem Open Event code…

Var File as FolderItem


Var lstCount As Integer
Var LstIndex as Integer



lbxProcess.HeaderAt(0) = "Step"
lbxProcess.HeaderAt(1) = "Action"
lbxProcess.HeaderAt(2) = "Units"
lbxProcess.HeaderAt(3) = "Temp"
lbxProcess.HeaderAt(4) = "Pressure"
lbxProcess.HeaderAt(5) = "Action Time"
lbxProcess.HeaderAt(6) = "Inject O2"
lbxProcess.HeaderAt(7) = "inject N2"
lbxProcess.HeaderAt(8) = "Apply Vac"
lbxProcess.HeaderAt(9) = "Exe Step"
lbxProcess.ColumnWidths = "5%,40%,5%,10%,10%,10%,5%,5%,5%,5%"

#If TargetWindows Then
  File = Volume(0).Child("CocoReactor").Child("Methods")
  
  If File Is Nil Then
    Return
  End If
  For Each Method_File As Folderitem In File.Children
    If Method_File <> Nil Then
      cbxMethod.AddRow(Method_File.Name)
    End If
  Next
#EndIf

#If TargetARM Then
  File = Volume(0).Child("home").Child("pi").Child("CocoReactor").Child("Methods")
 
  If File Is Nil Then
    Return
  End If
  For Each Method_File As Folderitem In File.Children
    If Method_File <> Nil Then
      cbxMethod.AddRow(Method_File.Name)
    End If
  Next
#Endif
'Action Event of the push Button Setup
pbtnRun.Enabled = False
pbtnAbort.Enabled = False
ProcessLstCount = 0
Timer1.Period = 10000
Timer1.RunMode = Timer.RunModes.Multiple

The Timer1 Action Event…

Var Parm As Integer
Var FName as String 
Var TxCommand as String 

TxStChr = "#"
TxEndChr = "@"
TxP1 = "MU"
TxP2 = "SI"
FName = cbxMethod.Text
TxP3 = Mid(FName, 1, 2)
TxP4 = "ST"

ProcessLstCount = lbxProcess.RowCount
Parm = ProcessLstIndx + 1

If Parm < 10 Then
  TxP5 = "0" + Str(Parm)
Else
  TxP5 = Str(Parm)
End if

TxCommand = TxStchr + TxP1 + TxP2 + TxP3 + TxP4 + TxP5 + TxEndChr
frmMain.SerialConnection1.Write TxCommand
lblUserfeedback.Value = "Uploading Step Parameters to System:" + TxCommand
Parindx = 0
Timer2.Period = 1000
Timer2.RunMode = Timer.Runmodes.Multiple

If ProcessLstindx < ProcessLstCount - 1 Then
  
Else
  me.RunMode = Timer.RunModes.Off
  pbtnAbort.Enabled = True
  pbtnRun.Enabled = True
  pbtnSetup.Enabled = False
End If

Timer2 Action Event…

Var LstParPos As Integer

If Parindx <= 8 Then
  lstparpos = Parindx + 2
  lblUserfeedback.Value = "Uploading Data to Control Unit:" + lbxProcess.Cell(ProcessLstIndx, lstParPos)
  frmMain.SerialConnection1.Write lbxProcess.Cell(ProcessLstIndx, lstParPos) + ChrB(13)
  Parindx = Parindx + 1
Else
  me.Runmode = Timer.Runmodes.Off
  ProcessLstindx = ProcessLstindx + 1
End If

A1.txt File…

1,CoCo Powder to Reactor,125,35,0,30,0,0,0,1
2,Pre Treatment Water to Reactor,2,35,0,1,0,0,0,1
3,Pre Treatment Water to Reactor,5,45,0,1,0,0,0,1
4,PC to Alkali Vessel,2,55,0,1,0,0,0,1
5,SH to Alkali Vessel,0,0,0,0,0,0,0,0
6,AC to Alkali Vessel,0,0,0,0,0,0,0,0
7,Reaction,0,75,2,90,1,0,0,1
8,Water Repleneshing,1,75,2,10,0,0,0,1
9,Water Repleneshing,1,75,2,10,1,0,0,1
10,Water Repleneshing,1,75,2,10,1,0,0,1
11,Water Repleneshing,0,0,0,0,0,0,0,0
12,Water Repleneshing,0,0,0,0,0,0,0,0
13,Chemical,0,0,0,0,0,0,0,0
14,Drying,0,75,0,180,0,0,1,1
15,Roasting-1,0,110,1,30,0,1,0,1
16,Roasting-2,0,0,0,0,0,0,0,0
17,Roasting-3,0,0,0,0,0,0,0,0
18,Roasting-4,0,0,0,0,0,0,0,0

Please accept my apologies if you’ve already done all the things I’m suggesting, but you have to check the simple stuff first or none of the more complicated things will help :wink:

Are you able to run the app in debug mode via the remote debugger stub program on the Pi? And if so can you put some breakpoints in the timer code so that you know it’s actually running or not? Unfortunately the state of Xojo breakpoints at this moment I wouldn’t trust that fact that it didn’t completely but if it does then you know that code is running. If it doesn’t break properly then you’ll need to add some message boxes or some logging support or something even just a listbox on a separate window that you can do an addrow to at the top of the timer action events just to be sure they are actually running. I doubt this is the problem as those are common things and there would be many many bug reports if timers just didn’t work on the pi.

After that is there some way you can verify that any data is actually being sent out the raspberry pi serial ports at all? Some kind of console to connect them to or just another USB/Serial adaptor on your development machine with a very simple xojo app to receive anything that is sent just so you can see if there are any bits there at all.

What are you using for the serial output on the Pi? The built in serial port that is also used for the terminal sign on? (if so make sure that it turned off or it won’t be able to use it for anything else) or a software bit-banged serial port such as you can create on any GPIO pin? (I’ve had trouble with these) or a USB/Serial adaptor?

Sorry, tried replying back yesterday, there seems to be some problem, i had typed a reply but wasn’t allowing me to post it .
First I would like to thank you for the prompt reply.

Frankly, I didn’t use breakpoints but had used a message box to flag each significant iteration. Not very comfortable with the remote debugger on RasPi.

I have Observed the following after due extensive testing…

  1. A single timer doesn’t seem to have issues, so modified my code suitable to use a Single timer on a window, also ensuring no multiple windows are active and other timer instances are running.

  2. I have created a single column Listbox, loaded all the relevant parameters that need to be transmitted through the serial port, Sending each parameter out by a timer running at 1000ms interval, so at each tick of the timer, one list item is sent out sequentially until all the list box items are sent out, and automatically closes the window. This code was put in the section where the timer mode is changed to off. Since the Timer stop happens before closing the window, I am sure that the timer is shutdown once the window is shut. To be doubly sure, if the tick count exceeds a message box is popped. This is not happening so the timer is indeed shut.

  3. In the Run Screen I have another timer, now only one instead of the earlier 3. This too is enabled only after all the parameters are loaded. The RasPi is Sending the data serially, no issues there.

  4. My New other problem with RasPi is that the serial data received event doesn’t seem to fire, if it fires it only happens for 1 time, later seems to get stuck, however, every other part of the program seems to work fine. So the new issue after the multiple timers seem to be Serial Reception, frankly didn’t write serial code on RasPi in 2020 or for that matter in Xojo2019R3. But the same code works on the desktop applications and almost every week write an Application for Serial Transmission & Reception for Desktops and in Xojo2019R3.

My conclusion…

  1. Multiple Timers on Raspi Buster (Latest Update) don’t work, if work erratic performance, unpredictable results.
  2. Serial Reception (DataReceived) has a problem, while no issues with the transmission.

When you use serial you need to lock the ARM to 250mhz per core. Or change the minUART to the PL011 and turn Bluetooth off.
Read here 4.6:
https://www.raspberrypi.org/documentation/configuration/device-tree.md#part4.6

Change the file in /boot/config.txt

Derk suggestion is a very good start point.

original Pi had the hardware serial port as the one available to the GPIO pins, when the onboard Bluetooth was introduced they changed this to make the GPIO use the soft(and not very reliable) port, its soft and unreliable as (Derk suggests) because its clock is related to the CPU speed, so when the CPU changes speed (for power save, boost of performance, whatever…) the serial port gets screwed up as the baud rate changes.

just disabling the bluetooth port is no guarantee to swap the serial port priority, a config file will also need updating.

sadly its not straight forward, well its linux, nothing is ever straight forward!

good luck, it does work perfectly when you get it right, but do not use high speed (>19200) to do your testing, start at 19200 first as your problems could easily be other connected hardware, as well as the serial port issue.

I reiterate, DO NOT be tempted to test anything at greater than 19200, serial data is very easily damaged by local noise and bad hardware, test low speed first and when that works, if you must make it faster, then you will know if its ok as it will still work at the higher baud rate.

115200 baud can be used without problems if you use the hardware uart (PL011).
You can swap bluetooth to the miniUART which will only work if you fixate the arm core speed. It’s best to turn it off completely if not used.

Hello,

Thanks for your inputs, yes but my Primary UART is ttyAMA0, this is done by adding a line to the config.sys…
“dtoverlay=pi3-disable-bt”, this apart I have also ensured that the console redirect is shutoff by editing the cmdline.txt. The Serial Port is Enabled in the RasPi Preferences

I have been using this config for several years, rather since RasPi3B+ became available. Never had an issue, Since my systems are instrument control we never go above the 9600 baud, so that also cannot be the problem, I was testing a Node-red flow which uses the Serial-in connected to a Debug node, likewise, an Inject node connected to Serial Out, The serial Out is working, however the Serial in doesn’t push data to the debug console.

I am trying to change the OS to Strech the late 2018 edition, will test and revert back. Think something to do with OS too

I tried the OS Strech Late 2018 Version, there is no issue with Serial Communication on this, the settings all remain the same for Serial Port Tx & Rx, It looks like Buster has some issues with the process, Node-red Application & Xojo Application are running Fine w.r.t the Serial Port issue I reported earlier.

The Timer issue however continues and definitely is a Xojo problem