#Region Project Attributes
#AutoFlushLogs: True
#CheckArrayBounds: True
#StackBufferSize: 300
#End Region
'Ctrl+Click to open the C code folder: ide://run?File=%WINDIR%\System32\explorer.exe&Args=%PROJECT%\Objects\Src
'Weather-Station-Solar-Wemos-D1-Ver1 by Mark Read 2021
'Hardware: Wemos D1 Mini, BME280 - Humidity, Pressure And Temperature
' with TP4056, Solar Panel And Lit-Ion Battery
'
'- Serial monitor data And thingspeak also in subs
'- Upload to Thingspean via MQTT
'- Using deep sleep To preserve battery
'- Using UDP For remote data viewing
'
'Status: under construction
'
'Connecting the BME280 Sensor:
'Sensor -> Board
'-----------------------------
'Vin (Voltage In) -> 3.3V
'Gnd (Ground) -> Gnd
'SDA (Serial Data) -> D1
'SCK (Serial Clock) -> D2
Sub Process_Globals
Public Serial1 As Serial
Public WiFi As ESP8266WiFi
Public Udp As WiFiUDP
Public WiFiClient As WiFiSocket
Private MQTT As MqttClient
Private MQTTOptions As MqttConnectOptions
Public MQTTApiKey As String="xxxxxxxxxxxxxxxxxxxx" ' from my Profile
Public WriteAPIKey As String="xxxxxxxxxxxxxxxxxxxxx" ' Channel Settings for my test channel
Public UserName As String="xxxx" ' from my Profile
Public WifiSSID As String="xxxxxx"
Public WifiPass As String="xxxxxx"
Public ThinkspeakServer As String="mqtt.thingspeak.com"
Private ChannelID As String="xxxxxxxxxx" ' Destination channel number
Private ClientID As String="MyWeatherSender" ' anything you wish
Public UDPPort As Int=8888
Public BroadcastIP() As Byte=Array As Byte(192,168,255,255)
Public WiFiLEDPin As Pin
Public ResetPin As Pin
Public LEDPinNumer As Int=12 ' using pin D6 on Wemos
Public TEMPERATURE, PRESSURE, HUMIDITY As Double
Public HeatIndex, DewPoint, Altitude As Double
Public BC As ByteConverter
Public DeepSleepMinutes As Int=15
'Public DelayTimer As Timer
'Coefficents for the environmental calculations
Dim hi_coeff1 As Double = -42.379
Dim hi_coeff2 As Double = 2.04901523
Dim hi_coeff3 As Double = 10.14333127
Dim hi_coeff4 As Double = -0.22475541
Dim hi_coeff5 As Double = -0.00683783
Dim hi_coeff6 As Double = -0.05481717
Dim hi_coeff7 As Double = 0.00122874
Dim hi_coeff8 As Double = 0.00085282
Dim hi_coeff9 As Double = -0.00000199
Dim RefTemperature As Double = 15.0
Dim RefPressure As Double = 1014.6
'Dim RefAltitude As Double = 541 ' only used to calculate the equivalent Sea level pressure
End Sub
Private Sub AppStart
Serial1.Initialize(115200)
Log("AppStart")
WiFiLEDPin.Initialize(LEDPinNumer, WiFiLEDPin.MODE_OUTPUT)
ResetPin.Initialize(0, ResetPin.MODE_INPUT_PULLUP)
If WiFi.IsConnected=False Then
ConnectToNetwork
End If
'initialise BME280
RunNative("setup",Null)
'initialise MQTT
MQTT.Initialize2(WiFiClient.Stream, ThinkspeakServer,1883, ClientID,"MQTT_MessageArrived", "MQTT_Disconnected")
MQTTOptions.Initialize(UserName, MQTTApiKey)
Log("I am awake ...")
Private RunTime As ULong= Millis() 'prepare a subroutine timer
If WiFi.IsConnected=False Then
ConnectToNetwork
End If
'get sensor data
ReadSensor
'calculate environmental values
EnviroSettings
'update remote viewer
'BroadcastOverUDP
'upload to thingspeak
UploadThinkgspeak
Log("Time for one iteration of the read/write cycle: ", Millis()-RunTime, " ms")
Log("")
Log("*******************************************************")
Log("Going to sleep ...")
DeepSleep(DeepSleepMinutes*60*1000) 'pass ms to sub
End Sub
Sub UploadThinkgspeak
Log("Trying to upload ...")
If MQTT.Connect2(MQTTOptions) Then
Log("Connected to thingspeak")
Dim PayLoad, Topic As String
PayLoad=JoinStrings(Array As String("field1=",TEMPERATURE,"&field2=",PRESSURE,"&field3=",Altitude,"&field4=", _
HeatIndex,"&field5=",HUMIDITY,"&field6=",DewPoint))
Log("Sending: ", PayLoad)
Topic=JoinStrings(Array As String("channels/", ChannelID, "/publish/", WriteAPIKey))
Log("Success=1, Failure=0: ",MQTT.Publish(Topic,PayLoad))
Else
Log("Error - Not connected")
End If
MQTT_Disconnected
End Sub
Sub MQTT_MessageArrived (Topic As String, Payload() As Byte)
Log("Message arrived. Topic=", Topic, " payload: ", Payload)
End Sub
Sub MQTT_Disconnected
Log("Disconnected")
MQTT.Close
End Sub
Sub BroadcastOverUDP
Dim bytes() As Byte
Udp.Initialize(UDPPort, "UDP_PacketArrived")
Udp.BeginPacket(BroadcastIP, UDPPort)
bytes = BC.DoublesToBytes(Array As Double(TEMPERATURE))
Udp.Write(bytes)
bytes = BC.DoublesToBytes(Array As Double(PRESSURE))
Udp.Write(bytes)
bytes = BC.DoublesToBytes(Array As Double(HUMIDITY))
Udp.Write(bytes)
Udp.SendPacket
Udp.Close
Log("Packets sent")
End Sub
Sub UDP_PacketArrived (Data() As Byte, ip1() As Byte, port1 As UInt)
' we do not expect a return packet!
End Sub
Sub ReadSensor
Log("Trying to read sensor ...")
RunNative("read",Null)
Dim T, P, H As Double
'NumberFormat(TEMPERATURE,1,1) - last number is decimal places
T=NumberFormat(TEMPERATURE,1,1)
P=NumberFormat(PRESSURE,1,0)
H=NumberFormat(HUMIDITY,1,0)
TEMPERATURE=T
PRESSURE=P
HUMIDITY=H
' comment out when not needed
'DebugLog
End Sub
Sub DebugLog
Log("Temperature: ", TEMPERATURE)
Log("Pressure: ", PRESSURE)
Log("Altitude: ", Altitude)
Log("HeatIndex: ", HeatIndex)
Log("Humidity: ", HUMIDITY)
Log("DewPoint: ", DewPoint)
End Sub
Sub EnviroSettings
If TEMPERATURE=0 Or PRESSURE=0 Or HUMIDITY=0 Then
Return 'cannot calulate with zero
End If
'******************************************************************************************************
' Altitude
If PRESSURE>0 And RefPressure>0 And RefTemperature>0 Then
Altitude = Power(RefPressure / PRESSURE,0.190234)-1
Altitude = Altitude*((RefTemperature + 273.15) / 0.0065)
End If
'******************************************************************************************************
' Heat Index
Dim t As Double=(TEMPERATURE * (9/5) +32) ' we need degree F
' Using both Rothfusz And Steadman's equations
' http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
If t<= 40 Then
HeatIndex=TEMPERATURE
Else
HeatIndex = 0.5 * (t + 61 + ((t - 68) * 1.2) + (HUMIDITY * 0.094))
If HeatIndex>=79 Then
'http://www.wolframalpha.com/input/?source=nav&i=b%3D+x1+%2B+x2*T+%2B+x3*H+%2B+x4*T*H+%2B+x5*T*T+%2B+x6*H*H+%2B+x7*T*T*H+%2B+x8*T*H*H+%2B+x9*T*T*H*H
HeatIndex = hi_coeff1 + (hi_coeff2 + hi_coeff4 * HUMIDITY + t * (hi_coeff5 + hi_coeff7 * HUMIDITY)) * t _
+ (hi_coeff3 + HUMIDITY * (hi_coeff6 + t * (hi_coeff8 + hi_coeff9 * t))) * HUMIDITY
If (HUMIDITY<13) And (t>=80) And (t<=112) Then
HeatIndex =HeatIndex-((13 - HUMIDITY) * 0.25) * Sqrt((17 - Abs(t - 95)) * 0.05882)
Else If (HUMIDITY>85) And (t>=80) And (t<=87) Then
HeatIndex = HeatIndex+(0.02 * (HUMIDITY - 85) * (87 - t))
End If
End If
End If
HeatIndex = (HeatIndex-32)*(5/9) 'convert back to celcius
'******************************************************************************************************
' Dew Point
'Equations courtesy of Brian McNoldy from http://andrew.rsmas.miami.edu;
If TEMPERATURE>0 And HUMIDITY>0 Then
'DewPoint = 243.04 * (Logarithm(Humidity/100,10) + ((17.625 * Temperature)/(243.04 + Temperature)))(17.625 - Logarithm(Humidity/100,10) - ((17.625 * Temperature)/(243.04 + Temperature)))
DewPoint = TEMPERATURE - ((100 -HUMIDITY)/5)
End If
End Sub
Sub ConnectToNetwork
If WiFi.IsConnected Then
'Log("disconnecting Wifi")
WiFiLEDPin.DigitalWrite(False)
Return
'WiFi.Disconnect
End If
If WiFi.Connect2(WifiSSID, WifiPass) Then
Log("Connected successfully to: ", WifiSSID)
Log(WiFi.LocalIp)
WiFiLEDPin.DigitalWrite(True)
Else
Log("Failed to connect.")
End If
End Sub
Private Sub DeepSleep(ms As ULong)
WiFiLEDPin.DigitalWrite(False)
RunNative("deepSleep", ms * 1000)
End Sub
#if C
void deepSleep(B4R::Object* o) {
ESP.deepSleep(o->toULong());
}
#end if
#if C
#include <Wire.h>
#include "cactus_io_BME280_I2C.h"
BME280_I2C bme(0x76);
void setup(B4R::Object* o){
bme.begin();
bme.setTempCal(-1);
}
void read (B4R::Object* o) {
bme.readSensor();
b4r_main::_temperature=bme.getTemperature_C();
b4r_main::_pressure=bme.getPressure_MB();
b4r_main::_humidity=bme.getHumidity();
}
#End if