Hi Everyone, I am working on a project where I have a raspberry pi 4B where I have a b4j app running which communicates with a 32 channel Analog to Digital Converter we designed and built at work, the communication is via I2C protocol, this part works very well as far as I have been able to test.
The B4J app running on the raspberry pi collects around 1000 samples per second on each device, so far I have been testing with only 4 channels. I thought about using MTTQ library so that I can send the collected data of every iteration to another B4J App running on my Laptop PC so that I can plot the data on a XY line chart, while this is all working great, I have noticed that the Sub client_MessageArrived (Topic As String, Payload() As Byte) function is not raised as fast as I would expect.
I have made some time measurements on the app running on the raspberry pi and how long it takes to read between 32 bytes and 40 bytes and so far I have seen that it takes anywhere between 2 to 8 milliseconds per read, the data of all 4 channels is included in the 32 byte array read every iteration. The data is then sent or published via the MTTQ client library on every iteration.
What I would expect is that this data should arrive just as fast as it is sent, but I am seeing a delay of between 2 to 4 seconds on the PC laptop.
I was wondering if anyone has done any work using the MQTT library, I realize that using this library is probably not ideal for what I am trying to accomplish, essentially I am trying to plot data almost LIVE so that we can visually see changes on power, current and voltage on devices we are testing.
As context, we have also created a python script which does pretty much the same thing, it reads data from the i2c devices, saves data to a large array, then plotting the data. I see a huge difference between the speed using python and Java, however I would really love to find a better solution using B4X since I am more familiar with it than any other programming language.
Below is the relevant code from both b4j apps, the first one which reads data via i2c on the raspberry pi and publishes the data to a certain topic, and the second one which is running on my laptop pc which receives the data published to the same topic.
	
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
This function is from the library I wrapped using the pi4j v2 java library, as you can see that's where I am taking the measurements of how long it takes to read 32 to 40 bytes of data and where I am seeing that it takes only between 2 to 8 milliseconds per read.
	
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
Here's where I collect data up to 1000 samples every iteration, then the data is sent via the MQTT library.
The following function is where the data published is received and sent to the XY charts to plot the data as is received.
	
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
If anyone has any experience using the MQTT library and can provide some assistance in figuring out why the data is received every 2 to 4 seconds rather than a few milliseconds please let me know.
			
			The B4J app running on the raspberry pi collects around 1000 samples per second on each device, so far I have been testing with only 4 channels. I thought about using MTTQ library so that I can send the collected data of every iteration to another B4J App running on my Laptop PC so that I can plot the data on a XY line chart, while this is all working great, I have noticed that the Sub client_MessageArrived (Topic As String, Payload() As Byte) function is not raised as fast as I would expect.
I have made some time measurements on the app running on the raspberry pi and how long it takes to read between 32 bytes and 40 bytes and so far I have seen that it takes anywhere between 2 to 8 milliseconds per read, the data of all 4 channels is included in the 32 byte array read every iteration. The data is then sent or published via the MTTQ client library on every iteration.
What I would expect is that this data should arrive just as fast as it is sent, but I am seeing a delay of between 2 to 4 seconds on the PC laptop.
I was wondering if anyone has done any work using the MQTT library, I realize that using this library is probably not ideal for what I am trying to accomplish, essentially I am trying to plot data almost LIVE so that we can visually see changes on power, current and voltage on devices we are testing.
As context, we have also created a python script which does pretty much the same thing, it reads data from the i2c devices, saves data to a large array, then plotting the data. I see a huge difference between the speed using python and Java, however I would really love to find a better solution using B4X since I am more familiar with it than any other programming language.
Below is the relevant code from both b4j apps, the first one which reads data via i2c on the raspberry pi and publishes the data to a certain topic, and the second one which is running on my laptop pc which receives the data published to the same topic.
			
				i2c_Read function:
			
		
		
		Public Sub i2c1_read(register As Int, numofbytestoread As Int) As Byte()
    Dim byte_array(numofbytestoread) As Byte
    Dim successful As Boolean = False
    Do While successful = False
    Try
        Dim start As Long = DateTime.Now
    i2c1.ReadBytesI2C(register, byte_array)
        Dim stop As Long = DateTime.Now
        Log("time elapsed from i2c_read: " & ((stop - start)/1000))
    successful = True
    Catch
            successful = False
    End Try
    Loop
    Return byte_array
End Sub
			
				read data from i2c devices:
			
		
		
		        For i = 0 To 999
        Dim start1 As Long = DateTime.Now
        Dim stop As Long = DateTime.Now
        i2c.SendRefresh(0x2)
        Dim vals() As Float = i2c.get_power_voltage_current
        xdata(i) = (stop - start) / 1000
        ydata(i) = vals(7)
        ydata2(i) = vals(4)
        ydata3(i) = vals(1)
        ydata4(i) = vals(10)
        Next
       
        mylist.Initialize
        mylist.Add(EncapsulateData(xdata, ydata))
        mylist.Add(EncapsulateData(xdata, ydata2))
        mylist.Add(EncapsulateData(xdata, ydata3))
        mylist.Add(EncapsulateData(xdata, ydata4))
        Dim b() As Byte = serializator.ConvertObjectToBytes(mylist)
        Try
            client.Publish2("datacollection", b, 2, False)
            Sleep(10)
        Catch
            Log("Error sending data")
        End TryThe following function is where the data published is received and sent to the XY charts to plot the data as is received.
			
				message received function:
			
		
		
		Sub client_MessageArrived (Topic As String, Payload() As Byte)
    Log("topic: " & Topic)
    Try
    Dim receivedObject As Object = serializator.ConvertBytesToObject(Payload)
    If Topic = "datacollection" Then
        Dim start As Long = DateTime.Now
        Dim m As mydata
        Dim m2, m3, m4 As mydata
        Dim l As List = receivedObject
        m = l.Get(0)
        m2 = l.Get(1)
        m3 = l.Get(2)
        m4 = l.Get(3)
        Dim xdata() As Object
        Dim ydata() As Object
        Dim xdata2() As Object
        Dim ydata2() As Object
        Dim xdata3() As Object
        Dim ydata3() As Object
        Dim xdata4() As Object
        Dim ydata4() As Object
        xdata = m.xxdata
        ydata = m.yydata
        xdata2 = m2.xxdata
        ydata2 = m2.yydata
        xdata3 = m3.xxdata
        ydata3 = m3.yydata
        xdata4 = m4.xxdata
        ydata4 = m4.yydata
            Log("xdata lenght: " & xdata.Length)
            Log("ydata lenght: " & ydata.Length)
       
        liveLC.updateLC("Board_ID", castObjectToDoubleArray(xdata), castObjectToDoubleArray(ydata))
        livelc2.updateLC("PPVUnreg_J10", castObjectToDoubleArray(xdata2), castObjectToDoubleArray(ydata2))
        liveLC3.updateLC("PPVUnreg_J14", castObjectToDoubleArray(xdata3), castObjectToDoubleArray(ydata3))
        liveLC4.updateLC("PPVUnreg_ProjRight", castObjectToDoubleArray(xdata4), castObjectToDoubleArray(ydata4))
        For ii = 0 To xdata.Length - 1
            Dim x As String = CastObjectToDouble(xdata(ii))
            Dim y As String = CastObjectToDouble(ydata(ii))
            Dim y2 As String = CastObjectToDouble(ydata2(ii))
            Dim y3 As String = CastObjectToDouble(ydata3(ii))
            Dim y4 As String = CastObjectToDouble(ydata4(ii))
            csvTable.Add(Array As String(x, y3, y2, y, y4))
        Next
        Dim stop As Long = DateTime.Now
        Log("time elapsed: " & (stop - start))
        ended = DateTime.Now
        Log("time elapsed betweem data received = " & (ended - begin))
    Else if Topic = "all/disconnect" Then
        Log("topic: " & Topic)
            Dim su As StringUtils
            su.SaveCSV(File.DirApp, "plot_data.csv", ",", csvTable)
    End If
    Catch
        Log("Error while processing messages")
        Dim su As StringUtils
        su.SaveCSV(File.DirApp, "plot_data.csv", ",", csvTable)
    End Try
End SubIf anyone has any experience using the MQTT library and can provide some assistance in figuring out why the data is received every 2 to 4 seconds rather than a few milliseconds please let me know.
 
				 
 
		 
			 
 
		 
 
		 
 
		 
			 
 
		 
 
		 
 
		