forked from RAKWireless/RAK13010-SDI12
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRAK13010_SDI_12_Interface.ino
184 lines (165 loc) · 5.88 KB
/
RAK13010_SDI_12_Interface.ino
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
/**
@file RAK13010_SDI_12_Interface.ino
@author rakwireless.com
@brief Arduino-based USB dongle translates serial comm from PC to SDI-12 (electrical and timing)
1.Allows user to communicate to SDI-12 devices from a serial terminal emulator (e.g. PuTTY).
2.Able to spy on an SDI-12 bus for troubleshooting comm between datalogger and sensors.
3.Can also be used as a hardware middleman for interfacing software to an SDI-12 sensor.
For example, implementing an SDI-12 datalogger in Python on a PC. Use verbatim mode
with feedback off in this case.
@version 0.1
@date 2022-03-11
@copyright Copyright (c) 2022
**/
#include "RAK13010_SDI12.h" // Click to install library: // Click to install library: http://librarymanager/All#RAK13010
#define HELPTEXT \
"OPTIONS:\r\n" \
"help : Print this message\r\n" \
"mode s : SDI-12 command mode (uppercase and ! automatically corrected) " \
"[default]\r\n" \
"mode v : verbatim mode (text will be sent verbatim)\r\n" \
"fb on : Enable feedback (characters visible while typing) [default]\r\n" \
"fb off : Disable feedback (characters not visible while typing; may be desired " \
"for developers)\r\n" \
"(else) : send command to SDI-12 bus"
#define TX_PIN WB_IO6 // The pin of the SDI-12 data bus.
#define RX_PIN WB_IO5 // The pin of the SDI-12 data bus.
#define OE WB_IO4 // Output enable pin, active low.
RAK_SDI12 mySDI12(RX_PIN,TX_PIN,OE);
void setup()
{
pinMode(WB_IO2, OUTPUT);
digitalWrite(WB_IO2, HIGH); // Power the sensors.
// Initialize Serial for debug output.
time_t timeout = millis();
// Serial.begin(115200,RAK_CUSTOM_MODE); // Uncomment if using RUI BSP.
Serial.begin(115200);
while (!Serial)
{
if ((millis() - timeout) < 5000)
{
delay(100);
}
else
{
break;
}
}
mySDI12.begin(); // Initiate serial connection to SDI-12 bus.
delay(500);
mySDI12.forceListen();
Serial.println(HELPTEXT); // Print help text (may wish to comment out if used for communicating to software).
}
void loop()
{
static String serialMsgStr;
static boolean serialMsgReady = false;
static String sdiMsgStr;
static boolean sdiMsgReady = false;
static boolean verbatim = false;
static boolean feedback = true;
// READ SERIAL (PC COMMS) DATA
// If serial data is available, read in a single byte and add it to a String on each iteration.
if (Serial.available())
{
char inByte1 = Serial.read();
if (feedback)
{
Serial.print(inByte1);
}
if (inByte1 == '\r' || inByte1 == '\n')
{
serialMsgReady = true;
}
else
{
serialMsgStr += inByte1;
}
}
/*
* @brief READ SDI-12 DATA
* If SDI-12 data is available, keep reading until full message consumed
* (Normally I would prefer to allow the loop() to keep executing while the string
* is being read in--as the serial example above--but SDI-12 depends on very precise
* timing, so it is probably best to let it hold up loop() until the string is complete)
*/
int avail = mySDI12.available();
if (avail < 0)
{
mySDI12.clearBuffer(); // Buffer is full,clear.
}
else if (avail > 0)
{
for (int a = 0; a < avail; a++)
{
char inByte2 = mySDI12.read();
if (inByte2 == '\n')
{
sdiMsgReady = true;
}
else if (inByte2 == '!')
{
sdiMsgStr += "!";
sdiMsgReady = true;
}
else
{
sdiMsgStr += String(inByte2);
}
}
}
if (sdiMsgReady) // Report completed SDI-12 messages back to serial interface.
{
Serial.println(sdiMsgStr);
sdiMsgReady = false; // Reset String for next SDI-12 message.
sdiMsgStr = "";
}
if (serialMsgReady) // Send completed Serial message as SDI-12 command.
{
Serial.println();
String lowerMsgStr = serialMsgStr; // Check if the serial message is a known command to the SDI-12 interface program.
lowerMsgStr.toLowerCase();
if (lowerMsgStr == "mode v")
{
verbatim = true;
Serial.println("Verbatim mode; exact text will be sent. Enter \"mode s\" for "
"SDI-12 command mode.");
}
else if (lowerMsgStr == "mode s")
{
verbatim = false;
Serial.println("SDI-12 command mode; uppercase and ! suffix optional. Enter "
"\"mode v\" for verbatim mode.");
}
else if (lowerMsgStr == "help")
{
Serial.println(HELPTEXT);
}
else if (lowerMsgStr == "fb off")
{
feedback = false;
Serial.println("Feedback off; typed commands will not be visible. Enter \"fb "
"on\" to enable feedback.");
}
else if (lowerMsgStr == "fb on")
{
feedback = true;
Serial.println("Feedback on; typed commands will be visible. Enter \"fb off\" "
"to disable feedback.");
}
else // If not a known command to the SDI-12 interface program, send out on SDI-12 data.
{
if (verbatim)
{
mySDI12.sendCommand(serialMsgStr);
}
else
{
serialMsgStr.toUpperCase();
mySDI12.sendCommand(serialMsgStr + "!");
}
}
serialMsgReady = false; // Reset String for next serial message.
serialMsgStr = "";
}
}