-
Notifications
You must be signed in to change notification settings - Fork 0
/
ws.weatherstation.sb
214 lines (177 loc) · 7.59 KB
/
ws.weatherstation.sb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
'//******************************************************************************
'// Laird Technologies (c) 2013
'//
'// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'// +++++ ++
'// +++++ When UwTerminal downloads the app it will store it as a filenname ++
'// +++++ which consists of all characters up to the first . and excluding it ++
'// +++++ ++
'// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'//
'// Code for weather station, adapted from Laird examples
'//
'// 2015-05-10 19:25
'//
'//******************************************************************************
'//******************************************************************************
'// Definitions
'//******************************************************************************
'//This defines how the application startsup and is a bit mask.
'//Bit 0 == 1 then OnStartup() is called just before waitevent
'//Bit 1 == 1 then StartAds() is called just before waitevent
#DEFINE AUTO_STARTUP 3
'//Set this to 0 to disable all debugging messages
#DEFINE ENABLE_DEBUG_PRINTS 1
#DEFINE DEVICENAME "Weather"
#DEFINE DEVICENAME_WRITABLE 0
// At time of writing, no matching APPEARANCE exists (2014-08-27)
#DEFINE APPEARANCE 0
#DEFINE MANF_NAME "Wulf inc."
#DEFINE MODELSTR "BL600"
#DEFINE SERIALNUM "s001"
#DEFINE HWREV "Hw v0.0.0"
#DEFINE SWREV "Sw v0.0.1"
//#define SYSID "\01\02\03\04\05\06\07\08"
#DEFINE SYSID "@"
//#define REGLIST "\DE\AD\C0\DE"
#DEFINE REGLIST ""
//#define PNPID "\01\04\BF\03\20\00\01"
#DEFINE PNPID ""
#DEFINE CHAR_CR 13
// The below parameters are chosen to have as low power consumption as possible
'// Minimum acceptable connection interval
#DEFINE MIN_CONN_INTERVAL 3000000
'// Maximum acceptable connection interval
#DEFINE MAX_CONN_INTERVAL 4000000
'// Slave latency -- number of conn events that can be missed
'// Effective Conn interval will be (SLAVE_LATENCY+1)*ACTUAL_CONN_INTERVAL
#DEFINE SLAVE_LATENCY 6
'// Connection supervisory timeout - max 32 seconds
#DEFINE CONN_SUP_TIMEOUT 10000000 //32000000
'//DiscoverableMode, set to BLE_DISCOVERABILITY_xxx
#DEFINE DISCOVERY_MODE BLE_DISCOVERABILITY_GENERAL
#DEFINE MAX_DEVNAME_CHRS 15
'//Set Appearance advertise 0 to suppress
#DEFINE ADV_APPEARANCE 1
'//Advertise interval (ms)
#DEFINE ADV_INTERVAL_MS 900 //1000
'//Advertise timeout (0 means no timeout)
#DEFINE ADV_TIMEOUT_MS 0 //10000
'//Whitelist Policy in Adverts
#DEFINE ADV_WHITELIST_FILTER_POLICY ADV_FILTERPOLICY_ANY
'//Minimum long term key size in octets
#DEFINE MIN_LTK_SIZE 8
'//Maximum long term key size in octets
#DEFINE MAX_LTK_SIZE 16
'// Set this to non-zero to enable notify on batt service
#DEFINE BATT_NOTIFY 0
#DEFINE BATT_INIT_LEVEL_PERC 100
'//This sets the pairing i/o capability using bonding
// Set authentication to none ("Just works")
#DEFINE PAIRING_IOCAPABILITY BLE_IOCAPABILITY_NONE
'//Connection Update Negotiation paramters
// Not exactly sure what this does
#DEFINE FIRST_CONN_PARAMS_UPDATE_DELAY 5000
#DEFINE NEXT_CONN_PARAMS_UPDATE_DELAY 5000
#DEFINE MAX_CONN_PARAMS_UPDATE_DELAY 15000
// ------- Weather station constants --------
#DEFINE MAX_SUPPLY_VOLTAGE_MV 3600
#DEFINE MIN_SUPPLY_VOLTAGE_MV 1600
#DEFINE MAX_CAP_ADC_VALUE 412
#DEFINE MIN_CAP_ADC_VALUE 132
// Time between measurements in milliseconds (60000 is one min)
#DEFINE MEAS_INTERVAL_MS 10000
#DEFINE WIND_SPEED_MEAS_TIME_MS 5000
// Timers
#DEFINE TIMER_MAIN 0
#DEFINE TIMER_WIND_SPEED 1
#DEFINE RIS_EDGE_PER_REV 4
'//******************************************************************************
'// Library Import
'//******************************************************************************
'//#include "$.lib.ble.sb"
#include "lib/ws.weather.station.sblib"
'//******************************************************************************
'// Global Variable Declarations
'//******************************************************************************
DIM adc1
DIM WSCnt
DIM startTick
DIM lastEdge : lastEdge = 0
DIM risEdgePerRev
'//******************************************************************************
'// Function and Subroutine definitions
'//******************************************************************************
'//******************************************************************************
'// Handler definitions
'//******************************************************************************
// GPIO configuration
rc=GpioSetFunc(15,1,0) // Wind speed digital input
AssertResCode(rc,8001)
rc=GpioSetFunc(1,3,0x13) // Super cap voltage
AssertResCode(rc,8001)
// Decrease power consumption by disabling UART
UartClose()
FUNCTION HndlrStartMeas()
// Internal Voltage
adc1=GpioRead(1)
DIM battLvl, rc
battLvl=(adc1-MIN_CAP_ADC_VALUE)*100/(MAX_CAP_ADC_VALUE-MIN_CAP_ADC_VALUE)
DbgMsgVal("Battery (%): ",battLvl)
rc=SetBattLevel(battLvl)
AssertResCode(rc,8002)
// Wind Speed
WSCnt=0
TimerStart(TIMER_WIND_SPEED,WIND_SPEED_MEAS_TIME_MS,0)
rc=GpioAssignEvent(0,15,0)
AssertResCode(rc,8003)
DbgMsg("Measurement started")
ENDFUNC 1
FUNCTION HndlrBTDisconnect(BYVAL hConn AS INTEGER, BYVAL nRsn AS INTEGER) AS INTEGER
//Start advertising directly after disconnect
dim rc
dim adv : adv=ADV_IND
rc=StartAds(adv)
if rc==0 then
DbgMsg("Start Adverts after disconnect")
endif
ENDFUNC 1
FUNCTION HndlrWSCnt()
if WSCnt == 0 then
startTick = GetTickCount()
else
lastEdge = GetTickSince(startTick)
endif
WSCnt=WSCnt+1
ENDFUNC 1
FUNCTION HndlrWSTimeout()
DIM rpm : rpm = 0
DIM windSpeed
DbgMsg("Wind speed timeout")
// Disable edge detect from anemometer
rc=GpioUnAssignEvent(0)
AssertResCode(rc,8004)
// Calculate rev/min
if lastEdge != 0 then
rpm = (WSCnt*60*1000)/RIS_EDGE_PER_REV/lastEdge
endif
// Calculate wind speed
windSpeed = rpm // TODO: Add factor after calibration! In fact, the calibration should be a BL value
DbgMsgVal("Wind speed (m/s*10^2):",windSpeed)
SetWindSpeed(windSpeed)
// TODO: Send all data not already sent
ENDFUNC 1
'//******************************************************************************
'// Equivalent to main() in C
'//******************************************************************************
ONEVENT EVTMR0 CALL HndlrStartMeas
ONEVENT EVTMR1 CALL HndlrWSTimeout
ONEVENT EVDISCON CALL HndlrBTDisconnect
ONEVENT EVDETECTCHAN0 CALL HndlrWSCnt
//ONEVENT EVCHARHVC CALL HndlrResetData //TODO: write Hndlr
TimerStart(TIMER_MAIN, MEAS_INTERVAL_MS,1)
'//------------------------------------------------------------------------------
'// Wait for a synchronous event.
'// An application can have multiple <WaitEvent> statements
'//------------------------------------------------------------------------------
waitevent