I'm having some problems with my BME280 module, so I tried some experiments with the internal Temperature Sensor (to eliminate external errors).
I don't seem to be able to define an I2c object as shared (might not be just I2c, but this is what I am testing).
For example, this code works (the MQTT class just makes MQTT stuff easier):
Class MQTT
Shared mcUIDString As String
Shared Sub Publish(topic As String, value As String)
If mcUIDString = Nothing Then
mcUIDString = Device.mcUID().ToString("X8")
End If
Dim text_string As ListOfByte = New ListOfByte()
text_string.Add(value)
Lplan.Publish("MCThings/" + mcUIDString + "/" + topic, text_string)
End Sub
Shared Sub Publish(topic As String, value As Object)
Dim text As String = value.ToString()
If mcUIDString = Nothing Then
mcUIDString = Device.mcUID().ToString("X8")
End If
Dim text_string As ListOfByte = New ListOfByte()
text_string.Add(text)
Lplan.Publish("MCThings/" + mcUIDString + "/" + topic, text_string)
End Sub
Shared Sub Publish_exact(topic As String, text As String)
Dim text_String As ListOfByte = New ListOfByte()
text_String.Add(text)
Lplan.Publish(topic, text_String)
End Sub
Shared Sub BeaconPublish(data_Type As Byte, data As Integer)
data = data & 0x0fffffff //blank top byte (can only send 24 bits maximum)
Dim hi_byte As Byte = ((data >> 16) & 0xff).ToByte()
Dim mid_byte As Byte = ((data >> 8) & 0xff).ToByte()
Dim low_byte As Byte = (data & 0xff).ToByte()
Dim beconData As ListOfByte = New ListOfByte()
beconData.Add(data_Type)
beconData.Add(hi_byte)
beconData.Add(mid_byte)
beconData.Add(low_byte)
Lplan.SetBeaconData(beconData)
Lplan.SendBeacon()
End Sub
Shared Sub Subscribe(topic As String)
Lplan.Subscribe(topic)
End Sub
End Class
Class Main
//Shared Internal_Temp As TempSensor
Shared booted As Boolean
Shared count As Integer
Shared Event Boot()
booted = True
count = 5
//Internal_Temp = New TempSensor()
End Event
Shared Event Publish_Values() RaiseEvent Every 10 Seconds
LedGreen = True
If booted Then
MQTT.Publish("Status", "Booted")
booted = False
End If
Dim Internal_Temp As TempSensor = New TempSensor()
Dim TempC As Float = Internal_Temp.GetTemp()
MQTT.Publish("Temperature", TempC)
Dim Uptime As Integer = Device.Uptime()
MQTT.Publish("Uptime", Uptime)
Dim BattVolt As Integer = Device.BatteryVoltage()
MQTT.Publish("BatteryVoltage", BattVolt)
count = count + 1
MQTT.Publish("Count", count)
LedGreen = False
End Event
End Class
Class TempSensor
// Function returns the temperature in degree celcius or
// Float.NaN if something is wrong
Public sensor As I2c
Public Sub New()
sensor = I2c.Create(400000, Pin.SCL, Pin.SDA, 0x48)
End Sub
Public Function GetTemp() As Float
// Define the properties of the I2C peripheral and device address
//Dim sensor As I2c
//sensor = I2c.Create(400000, Pin.SCL, Pin.SDA, 0x48)
// Power up the sensor and give it some time to settle
Device.EnableTempSensor()
Thread.Sleep(40000) // See page 13 of the datasheet
// Read the sensor (only 2 bytes to read
Dim res As ListOfByte = sensor.Read(2)
// See Tmp102 documentation how to interpret the data (page 8)
Dim temp As Float = Float.NaN
If res <> Nothing Then
// Shift the partial part to the right nibble
Dim part As Float = res(1) >> 4
// Temperature partial is 1/16*n where n is between 0 and 15
part = part / 16
// Sign extend the byte to an integer
temp = res(0).SignExtend() + part
Else
LedRed = True
Thread.Sleep(50000)
LedRed = False
End If
// power off
Device.DisableTempSensor()
Return temp
End Function
Shared Function GetDieTemp() As Float
// Just get the temperature and return
Return Device.TempDie
End Function
Shared Function ToFarenheit(celcius As Float) As Float
Return (celcius * 9) / 5 + 32
End Function
Shared Function ToCelcius(farenheit As Float) As Float
Return (farenheit - 32) * 5 / 9
End Function
End Class
Note the "Dim Internal_Temp As TempSensor = New TempSensor()" in Class Main.
If I Try to Make this a shared variable of class main, it causes the module to reset. This does not work:
Class MQTT
Shared mcUIDString As String
Shared Sub Publish(topic As String, value As String)
If mcUIDString = Nothing Then
mcUIDString = Device.mcUID().ToString("X8")
End If
Dim text_string As ListOfByte = New ListOfByte()
text_string.Add(value)
Lplan.Publish("MCThings/" + mcUIDString + "/" + topic, text_string)
End Sub
Shared Sub Publish(topic As String, value As Object)
Dim text As String = value.ToString()
If mcUIDString = Nothing Then
mcUIDString = Device.mcUID().ToString("X8")
End If
Dim text_string As ListOfByte = New ListOfByte()
text_string.Add(text)
Lplan.Publish("MCThings/" + mcUIDString + "/" + topic, text_string)
End Sub
Shared Sub Publish_exact(topic As String, text As String)
Dim text_String As ListOfByte = New ListOfByte()
text_String.Add(text)
Lplan.Publish(topic, text_String)
End Sub
Shared Sub BeaconPublish(data_Type As Byte, data As Integer)
data = data & 0x0fffffff //blank top byte (can only send 24 bits maximum)
Dim hi_byte As Byte = ((data >> 16) & 0xff).ToByte()
Dim mid_byte As Byte = ((data >> 8) & 0xff).ToByte()
Dim low_byte As Byte = (data & 0xff).ToByte()
Dim beconData As ListOfByte = New ListOfByte()
beconData.Add(data_Type)
beconData.Add(hi_byte)
beconData.Add(mid_byte)
beconData.Add(low_byte)
Lplan.SetBeaconData(beconData)
Lplan.SendBeacon()
End Sub
Shared Sub Subscribe(topic As String)
Lplan.Subscribe(topic)
End Sub
End Class
Class Main
Shared Internal_Temp As TempSensor
Shared booted As Boolean
Shared count As Integer
Shared Event Boot()
booted = True
count = 5
Internal_Temp = New TempSensor()
End Event
Shared Event Publish_Values() RaiseEvent Every 10 Seconds
LedGreen = True
If booted Then
MQTT.Publish("Status", "Booted")
booted = False
End If
//Dim Internal_Temp As TempSensor = New TempSensor()
Dim TempC As Float = Internal_Temp.GetTemp()
MQTT.Publish("Temperature", TempC)
Dim Uptime As Integer = Device.Uptime()
MQTT.Publish("Uptime", Uptime)
Dim BattVolt As Integer = Device.BatteryVoltage()
MQTT.Publish("BatteryVoltage", BattVolt)
count = count + 1
MQTT.Publish("Count", count)
LedGreen = False
End Event
End Class
Class TempSensor
// Function returns the temperature in degree celcius or
// Float.NaN if something is wrong
Public sensor As I2c
Public Sub New()
sensor = I2c.Create(400000, Pin.SCL, Pin.SDA, 0x48)
End Sub
Public Function GetTemp() As Float
// Define the properties of the I2C peripheral and device address
//Dim sensor As I2c
//sensor = I2c.Create(400000, Pin.SCL, Pin.SDA, 0x48)
// Power up the sensor and give it some time to settle
Device.EnableTempSensor()
Thread.Sleep(40000) // See page 13 of the datasheet
// Read the sensor (only 2 bytes to read
Dim res As ListOfByte = sensor.Read(2)
// See Tmp102 documentation how to interpret the data (page 8)
Dim temp As Float = Float.NaN
If res <> Nothing Then
// Shift the partial part to the right nibble
Dim part As Float = res(1) >> 4
// Temperature partial is 1/16*n where n is between 0 and 15
part = part / 16
// Sign extend the byte to an integer
temp = res(0).SignExtend() + part
Else
LedRed = True
Thread.Sleep(50000)
LedRed = False
End If
// power off
Device.DisableTempSensor()
Return temp
End Function
Shared Function GetDieTemp() As Float
// Just get the temperature and return
Return Device.TempDie
End Function
Shared Function ToFarenheit(celcius As Float) As Float
Return (celcius * 9) / 5 + 32
End Function
Shared Function ToCelcius(farenheit As Float) As Float
Return (farenheit - 32) * 5 / 9
End Function
End Class
So if I change Internal_sensor from a local variable to a Shared variable, the module resets. What am I doing wrong? The TempSensor object should be created at boot, and should persist as a shared variable of class Main, but I'm guessing from the resets, it is being destroyed. No errors in MCStudio, and builds fine.
I'm wanting to do this as I want to create a BME280 object (one per sensor), but it seems that I have to create a new object every time I want to use it. I can't make a persistent I2C object.
Any suggestions would be appreciated.