B4J Question HELP (plotting temperature profile chart)

walterf25

Expert
Licensed User
Longtime User
Hi Everyone, I'm working on a small project using ABMaterial and the frappe charts library found here, so far everything seems to be working fine for me.

What I am doing is connecting to a Temperature Chamber through Ethernet and reading the temperature profiles already stored in the Temp Controller, the project is running on a Raspberry Pi and as I mentioned all that is working just fine.
I am listing the profile names in a table and here's what that looks like:
1718145582301.png

When the user clicks on the profile number, for example in the example above, the profile #8 has been clicked on, and the profile steps are retrieved which is a Json string and when parsed I can see the step type as Soak or as RampTime along with the temperature target value and the time duration.

The problem I am having is that when trying to plot the profile it doesn't look the way it's supposed to.

This is what the selected profile should look like:
1718146016818.png


But instead when I try to plot the values this is what I get instead.
1718146061578.jpeg


I know at first sight both charts look similar, but if you pay close attention you will see that the times does not align to the top chart.
I Realize this has to do with my code, but my brain just can't figure it out.

Here's the json string that is received from the Temperature Controller when clicked on any of the profile names. In this instance I have selected the profile name "10*20*60MIN*X3".
profileinfo: {"name": "10*60*20MIN*X3", "log": false, "haswaits": false, "hasenables": false, "steps": [{"type": "soak", "duration": {"hours": 0, "minutes": 10, "seconds": 0}, "loops": [{"max": 180.0, "min": -70.0, "mode": "", "gsoak": false, "target": 0.0, "rate": 0.0, "showEnable": false, "isCascade": false, "cascade": false, "enable": true}], "waits": [], "jstep": 1, "jcount": 1, "events": [{"number": 1, "value": "off"}, {"number": 2, "value": "off"}, {"number": 3, "value": "off"}, {"number": 4, "value": "off"}, {"number": 5, "value": "off"}, {"number": 6, "value": "off"}, {"number": 7, "value": "off"}, {"number": 8, "value": "off"}]}, {"type": "ramptime", "duration": {"hours": 0, "minutes": 20, "seconds": 0}, "loops": [{"max": 180.0, "min": -70.0, "mode": "", "gsoak": false, "target": 60.0, "rate": 0.0, "showEnable": false, "isCascade": false, "cascade": false, "enable": true}], "waits": [], "jstep": 1, "jcount": 1, "events": [{"number": 1, "value": "off"}, {"number": 2, "value": "off"}, {"number": 3, "va
lue": "off"}, {"number": 4, "value": "off"}, {"number": 5, "value": "off"}, {"number": 6, "value": "off"}, {"number": 7, "value": "off"}, {"number": 8, "value": "off"}]}, {"type": "soak", "duration": {"hours": 0, "minutes": 10, "seconds": 0}, "loops": [{"max": 180.0, "min": -70.0, "mode": "", "gsoak": false, "target": 0.0, "rate": 0.0, "showEnable": false, "isCascade": false, "cascade": false, "enable": true}], "waits": [], "jstep": 1, "jcount": 1, "events": [{"number": 1, "value": "off"}, {"number": 2, "value": "off"}, {"number": 3, "value": "off"}, {"number": 4, "value": "off"}, {"number": 5, "value": "off"}, {"number": 6, "value": "off"}, {"number": 7, "value": "off"}, {"number": 8, "value": "off"}]}, {"type": "ramptime", "duration": {"hours": 0, "minutes": 20, "seconds": 0}, "loops": [{"max": 180.0, "min": -70.0, "mode": "", "gsoak": false, "target": 10.0, "rate": 0.0, "showEnable": false, "isCascade": false, "cascade": false, "enable": true}], "waits": [], "jstep": 1, "jcount": 1, "events": [{"number": 1
, "value": "off"}, {"number": 2, "value": "off"}, {"number": 3, "value": "off"}, {"number": 4, "value": "off"}, {"number": 5, "value": "off"}, {"number": 6, "value": "off"}, {"number": 7, "value": "off"}, {"number": 8, "value": "off"}]}, {"type": "soak", "duration": {"hours": 0, "minutes": 10, "seconds": 0}, "loops": [{"max": 180.0, "min": -70.0, "mode": "", "gsoak": false, "target": 0.0, "rate": 0.0, "showEnable": false, "isCascade": false, "cascade": false, "enable": true}], "waits": [], "jstep": 1, "jcount": 1, "events": [{"number": 1, "value": "off"}, {"number": 2, "value": "off"}, {"number": 3, "value": "off"}, {"number": 4, "value": "off"}, {"number": 5, "value": "off"}, {"number": 6, "value": "off"}, {"number": 7, "value": "off"}, {"number": 8, "value": "off"}]}, {"type": "ramptime", "duration": {"hours": 0, "minutes": 20, "seconds": 0}, "loops": [{"max": 180.0, "min": -70.0, "mode": "", "gsoak": false, "target": 60.0, "rate": 0.0, "showEnable": false, "isCascade": false, "cascade": false, "enable": tr
ue}], "waits": [], "jstep": 1, "jcount": 1, "events": [{"number": 1, "value": "off"}, {"number": 2, "value": "off"}, {"number": 3, "value": "off"}, {"number": 4, "value": "off"}, {"number": 5, "value": "off"}, {"number": 6, "value": "off"}, {"number": 7, "value": "off"}, {"number": 8, "value": "off"}]}, {"type": "soak", "duration": {"hours": 0, "minutes": 10, "seconds": 0}, "loops": [{"max": 180.0, "min": -70.0, "mode": "", "gsoak": false, "target": 0.0, "rate": 0.0, "showEnable": false, "isCascade": false, "cascade": false, "enable": true}], "waits": [], "jstep": 1, "jcount": 1, "events": [{"number": 1, "value": "off"}, {"number": 2, "value": "off"}, {"number": 3, "value": "off"}, {"number": 4, "value": "off"}, {"number": 5, "value": "off"}, {"number": 6, "value": "off"}, {"number": 7, "value": "off"}, {"number": 8, "value": "off"}]}, {"type": "ramptime", "duration": {"hours": 0, "minutes": 20, "seconds": 0}, "loops": [{"max": 180.0, "min": -70.0, "mode": "", "gsoak": false, "target": 10.0, "rate": 0.0, "sho
wEnable": false, "isCascade": false, "cascade": false, "enable": true}], "waits": [], "jstep": 1, "jcount": 1, "events": [{"number": 1, "value": "off"}, {"number": 2, "value": "off"}, {"number": 3, "value": "off"}, {"number": 4, "value": "off"}, {"number": 5, "value": "off"}, {"number": 6, "value": "off"}, {"number": 7, "value": "off"}, {"number": 8, "value": "off"}]}, {"type": "soak", "duration": {"hours": 0, "minutes": 10, "seconds": 0}, "loops": [{"max": 180.0, "min": -70.0, "mode": "", "gsoak": false, "target": 0.0, "rate": 0.0, "showEnable": false, "isCascade": false, "cascade": false, "enable": true}], "waits": [], "jstep": 1, "jcount": 1, "events": [{"number": 1, "value": "off"}, {"number": 2, "value": "off"}, {"number": 3, "value": "off"}, {"number": 4, "value": "off"}, {"number": 5, "value": "off"}, {"number": 6, "value": "off"}, {"number": 7, "value": "off"}, {"number": 8, "value": "off"}]}, {"type": "ramptime", "duration": {"hours": 0, "minutes": 20, "seconds": 0}, "loops": [{"max": 180.0, "min": -
70.0, "mode": "", "gsoak": false, "target": 60.0, "rate": 0.0, "showEnable": false, "isCascade": false, "cascade": false, "enable": true}], "waits": [], "jstep": 1, "jcount": 1, "events": [{"number": 1, "value": "off"}, {"number": 2, "value": "off"}, {"number": 3, "value": "off"}, {"number": 4, "value": "off"}, {"number": 5, "value": "off"}, {"number": 6, "value": "off"}, {"number": 7, "value": "off"}, {"number": 8, "value": "off"}]}, {"type": "soak", "duration": {"hours": 0, "minutes": 10, "seconds": 0}, "loops": [{"max": 180.0, "min": -70.0, "mode": "", "gsoak": false, "target": 0.0, "rate": 0.0, "showEnable": false, "isCascade": false, "cascade": false, "enable": true}], "waits": [], "jstep": 1, "jcount": 1, "events": [{"number": 1, "value": "off"}, {"number": 2, "value": "off"}, {"number": 3, "value": "off"}, {"number": 4, "value": "off"}, {"number": 5, "value": "off"}, {"number": 6, "value": "off"}, {"number": 7, "value": "off"}, {"number": 8, "value": "off"}]}, {"type": "ramptime", "duration": {"hours":
0, "minutes": 20, "seconds": 0}, "loops": [{"max": 180.0, "min": -70.0, "mode": "", "gsoak": false, "target": 10.0, "rate": 0.0, "showEnable": false, "isCascade": false, "cascade": false, "enable": true}], "waits": [], "jstep": 1, "jcount": 1, "events": [{"number": 1, "value": "off"}, {"number": 2, "value": "off"}, {"number": 3, "value": "off"}, {"number": 4, "value": "off"}, {"number": 5, "value": "off"}, {"number": 6, "value": "off"}, {"number": 7, "value": "off"}, {"number": 8, "value": "off"}]}, {"type": "soak", "duration": {"hours": 0, "minutes": 10, "seconds": 0}, "loops": [{"max": 180.0, "min": -70.0, "mode": "", "gsoak": false, "target": 0.0, "rate": 0.0, "showEnable": false, "isCascade": false, "cascade": false, "enable": true}], "waits": [], "jstep": 1, "jcount": 1, "events": [{"number": 1, "value": "off"}, {"number": 2, "value": "off"}, {"number": 3, "value": "off"}, {"number": 4, "value": "off"}, {"number": 5, "value": "off"}, {"number": 6, "value": "off"}, {"number": 7, "value": "off"}, {"number
": 8, "value": "off"}]}], "gs_dev": [{"value": 5.6}]}

From there I extract the Step Types, Duration, temp target from the loops section and my code to iterate though each step type, duration etc. is this:

Temperature Profile:
        Dim j As JSONParser
        j.Initialize(StdOut)
        Dim l As Map = j.NextObject
        Log("m: " & l)
   
        Dim steps As List = l.Get("steps")
        Dim x As List
        Dim y As List
        x.Initialize
        y.Initialize
   
        Dim prevTime As Int = 0
        Dim currentTemperature As Float = 0
        Dim stepType As String
        x.Add(prevTime)
        y.Add(currentTemperature)
       
        Dim totalTime As Int = 0
   
        For i = 0 To steps.Size - 1
            Dim targetVal As Float
            Dim s As Map = steps.Get(i)
            Dim duration As Map = s.Get("duration")
            Dim loops As List = s.Get("loops")
            Dim target As Map = loops.Get(0)
            targetVal = target.Get("target")
       
            Dim hours, minutes, seconds As Int
            stepType = s.Get("type")
            hours = duration.Get("hours")
            minutes = duration.Get("minutes")
            seconds = duration.Get("seconds")
            totalTime = totalTime + minutes
            Dim lastSoak As Float
            If stepType = "soak" Then
                prevTime = prevTime + minutes
                lastSoak = y.Get(y.Size - 1)
                x.Add(prevTime)
                y.Add(lastSoak)  
                Log("soak time: " & prevTime & " target: " & lastSoak)
            Else If stepType = "ramptime" Then
                Dim lastTarget As Float = targetVal
                Dim rampTime As Int = prevTime + minutes
                ' Add starting point of ramp
                Log("ramptime: " & minutes & " Target: " & lastTarget)
                x.Add(minutes)
                y.Add(lastTarget)
                ' Add end point of ramp
                Log("ramptime: " & rampTime & " Target: " & targetVal)
                    x.Add(rampTime)
                    y.Add(targetVal)
                prevTime = rampTime
            End If
        Next

The x and y lists are passed to the chart to plot the profile, but as I mentioned above, I am unable to get the profile I am plotting to match what the profile actually should look like.

I know this is probably something very simple, but as I am working on multiple projects I have not been able to focus and dedicate my time 100% to this problem, I am hoping someone can help me or point me in the right direction.

Thanks everyone!.
 

Daestrum

Expert
Licensed User
Longtime User
I think it may be these lines causing the problem
B4X:
            Log("ramptime: " & minutes & " Target: " & lastTarget)
            'x.Add(minutes)     <------ Comment out this line
            'y.Add(lastTarget)  <------ Comment out this line
            ' Add end point of ramp
            Log("ramptime: " & rampTime & " Target: " & targetVal)
            x.Add(rampTime)
            y.Add(targetVal)
            prevTime = rampTime

If you add this code below to the end of your code you will see the spurious values that were passed.
B4X:
    For t = 0 To x.Size-1
        Log("X: " & x.Get(t) & ", Y: " & y.Get(t))
    Next

The X value should only increase, but there were values that stepped back on the ramp stages where the commented lines were adding minutes & target values.
 
Last edited:
Upvote 0

walterf25

Expert
Licensed User
Longtime User
I think it may be these lines causing the problem
B4X:
            Log("ramptime: " & minutes & " Target: " & lastTarget)
            'x.Add(minutes)     <------ Comment out this line
            'y.Add(lastTarget)  <------ Comment out this line
            ' Add end point of ramp
            Log("ramptime: " & rampTime & " Target: " & targetVal)
            x.Add(rampTime)
            y.Add(targetVal)
            prevTime = rampTime

If you add this code below to the end of your code you will see the spurious values that were passed.
B4X:
    For t = 0 To x.Size-1
        Log("X: " & x.Get(t) & ", Y: " & y.Get(t))
    Next

The X value should only increase, but there were values that stepped back on the ramp stages where the commented lines were adding minutes & target values.
That wasn't the problem, but thanks for your suggestion.
 
Upvote 0
Top