B4R Question Normal behavior?

kolbe

Active Member
Licensed User
Longtime User
In the following code the log outputs two different values, so somehow readbyte changes when Get_Data is called.

Master is a WireMaster.

B4X:
Private readbyte(1) As Byte

readbyte = master.RequestFrom(CSS811_ADDRESS,1)

Log(Bit.Get(readbyte(0),4))
If (Bit.Get(readbyte(0),3) = 1) Then 'data valid
   Log("Data is ready")
   Get_Data
End If
Log(Bit.Get(readbyte(0),4))

Get_Data does a similar thing

B4X:
Private readbyte(4) As Byte

readbyte = master.RequestFrom(CSS811_ADDRESS,4)

So what is going on here?
 
Last edited:

kolbe

Active Member
Licensed User
Longtime User
Can you upload the full code?

B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 600
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
    Private timer1 As Timer
    Private master As WireMaster
    Private led As Pin
    Private const CSS811_ADDRESS As Byte = 0x5a 'or 0x5b
    Private const STATUS As Byte = 0
    Private const MODE As Byte = 1
    Private const DATA As Byte = 2
    Private const ERROR As Byte = 0xe0
    Private const APP_START As Byte = 0xf4
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    master.Initialize
    led.Initialize(13,led.MODE_OUTPUT)
    led.DigitalWrite(False)
    timer1.Initialize("Loop_Tick",1000)
    Log("AppStart")
    Delay(1000)
'    Set_Mode
    Chip_Mode
    timer1.Enabled=True
End Sub

Private Sub Loop_Tick
    Chip_Status
    Log("--")
End Sub

Private Sub Chip_Status
    Private readbyte(1) As Byte
    Private writebyte(1) As Byte
   
    writebyte(0) = STATUS
    master.WriteTo2(CSS811_ADDRESS,True,writebyte)
   
    Delay(50)
   
    readbyte = master.RequestFrom(CSS811_ADDRESS,1)
   
    If readbyte.Length=1 Then
        Log("Status: ",Bit.ToBinaryString(readbyte(0)))

        If (Bit.Get(readbyte(0),0) = 1) Then 'app error
            Chip_Error
            Log("App Error")
        End If
       
        Log(Bit.Get(readbyte(0),4))
        If (Bit.Get(readbyte(0),3) = 1) Then 'data valid
            Log("Data is ready")
            Get_Data
        End If
        Log(Bit.Get(readbyte(0),4))
       
        If (Bit.Get(readbyte(0),4) = 1) Then 'valid app loaded
            Log("A valid app is loaded")
            If (Bit.Get(readbyte(0),7) = 1) Then 'app is running
                Log("In application mode")
            Else 'in boot mode, need to start app
                Log("In boot mode")
                Start_App
            End If
        End If

    Else
        Log("status request failed ",readbyte.Length)
       
    End If
End Sub

Private Sub Chip_Error
    Private readbyte(1) As Byte
    Private writebyte(1) As Byte
   
    writebyte(0) = ERROR
    master.WriteTo2(CSS811_ADDRESS,True,writebyte)
   
    Delay(50)
   
    readbyte = master.RequestFrom(CSS811_ADDRESS,1)
   
    If readbyte.Length=1 Then
        Log("Error: ",Bit.ToBinaryString(readbyte(0)))

        If (Bit.Get(readbyte(0),0) = 1) Then Log("Invalid register")
        If (Bit.Get(readbyte(0),1) = 1) Then Log("Invalid read")
        If (Bit.Get(readbyte(0),2) = 1) Then Log("Invalid app mode")
        If (Bit.Get(readbyte(0),3) = 1) Then Log("Max sensor error")
        If (Bit.Get(readbyte(0),4) = 1) Then Log("Heater current error")
        If (Bit.Get(readbyte(0),5) = 1) Then Log("Heater voltage error")
       
    Else
        Log("status request failed ",readbyte.Length)
       
    End If
End Sub

Private Sub Chip_Mode
    Private readbyte(1) As Byte
    Private writebyte(1) As Byte
   
    writebyte(0) = MODE
    master.WriteTo2(CSS811_ADDRESS,True,writebyte)
   
    Delay(50)
   
    readbyte = master.RequestFrom(CSS811_ADDRESS,1)
   
    If readbyte.Length=1 Then
        Log("Mode: ",Bit.ToBinaryString(readbyte(0)))

        If (Bit.Get(readbyte(0),2) = 1) Then Log("Interupt Disabled") 'interupt on/off
        If (Bit.Get(readbyte(0),3) = 1) Then Log("Normal interupt") 'interupt mode
        If Bit.ShiftRight(Bit.And(readbyte(0),0x70),4) <> 1 Then
            Log("App mode#: ",Bit.ShiftRight(Bit.And(readbyte(0),0x70),4)) ' app mode
            Set_Mode
        End If
    Else
        Log("mode request failed ",readbyte.Length)
       
    End If
End Sub

Private Sub Set_Mode
    Private writebyte(2) As Byte
   
    writebyte(0) = MODE
    writebyte(1) = 0x10 'constant power mode
    master.WriteTo2(CSS811_ADDRESS,True,writebyte)
    Log("setting mode to 1")
   
    Delay(50)
   
End Sub

Private Sub Start_App
    Private writebyte(1) As Byte
   
    writebyte(0) = APP_START
    master.WriteTo2(CSS811_ADDRESS,True,writebyte)
    Log("start application")
   
    Delay(50)
   
End Sub

Sub Get_Data
    Private readbyte(4) As Byte
    Private writebyte(1) As Byte
   
    writebyte(0)= DATA
    master.WriteTo2(CSS811_ADDRESS,True,writebyte)
    Delay(50)

    readbyte = master.RequestFrom(CSS811_ADDRESS,4)
   
    If readbyte.Length=4 Then
        Private msb, lsb As Byte
        msb=readbyte(0)
        lsb=readbyte(1)
        Log("CO2 ",Bit.ShiftLeft(msb,8)+lsb)
        msb=readbyte(2)
        lsb=readbyte(3)
        Log("VOC ",Bit.ShiftLeft(msb,8)+lsb)

    Else
        Log("Data failed ",readbyte.Length)
       
    End If
   
End Sub

Private Sub Blink(count As Int)
    For i =1 To count
        led.DigitalWrite(True)
        Delay(100)
        led.DigitalWrite(False)
        Delay(100)
    Next
   
End Sub
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
B4X:
readbyte = master.RequestFrom(CSS811_ADDRESS,1)

The data is stored in an internal buffer owned by master.
After the line above, readbyte array points to this buffer.

Calling master.RequestFrom will overwrite the same internal buffer and will affect all arrays pointing to this buffer.
The solution is simple:
B4X:
If readbyte.Length=1 Then
     Dim b As Byte = readbyte(0)
     'now work with b only
 
Upvote 0

kolbe

Active Member
Licensed User
Longtime User
Interesting. Thanks for the explanation.

For those curious, the code above will get the the VOC and eCO2 from the CCS811.
 
Upvote 0
Top