Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
Sensor System
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Institut für Informatik
QE Research Group
FORTE
Sensor System
Commits
05607066
Commit
05607066
authored
2 years ago
by
amedvedova
Browse files
Options
Downloads
Patches
Plain Diff
Added a working example of for a soil moisture sensor.
parent
29cb498a
No related branches found
No related tags found
1 merge request
!18
Power management satellite
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
code-snippets/client/soil_sensor_sentec/main.cpp
+172
-0
172 additions, 0 deletions
code-snippets/client/soil_sensor_sentec/main.cpp
code-snippets/client/soil_sensor_sentec/platformio.ini
+19
-0
19 additions, 0 deletions
code-snippets/client/soil_sensor_sentec/platformio.ini
with
191 additions
and
0 deletions
code-snippets/client/soil_sensor_sentec/main.cpp
0 → 100644
+
172
−
0
View file @
05607066
#include
"Arduino.h"
#include
<SoftwareSerial.h>
// RS485 setup with ESP32
// THIS SNIPPET APPLIES ONLY TO SOIL SENSORS!!!
// Other RS485 sensors will have to use other commands as well
/*
TODO It would be better to have one class for ALL RS485 sensors since they
all send/receive data in the same way, and then specific classes for individual
sensors (soil moisture, rain gauge, radiation) with sensor-specific commands.
*/
/* TODO The address of the sensor (first byte of the query frame) is
hard-coded now - it should be passed as an argument instead since
we have three sensors with different addresses now.
The last two values of the queryFrame don't matter, they will be changed
later to confrom to the CRC check.
The length of the sent message will always be 8 bytes.
*/
const
byte
bufferSize
=
6
;
byte
queryFrame
[
bufferSize
+
2
]
=
{
0x05
,
0x03
,
0x00
,
0x00
,
0x00
,
0x02
,
0x00
,
0x00
};
// 0: sensor address (differs per sensor)
// 1: function code (03 = get data for all sensors)
// 2+3: register start (0x00 0x00 for all sensors)
// 4+5: register length (0x01 for radiation+rain, 0x02 for soil)
// 6+7: CRC check (calculated later per sensor and message)
/*
TODO the length of the answer frame should NOT be hard-coded, it's going to be either
8 bytes (radiation, rain) or 9 bytes (soil)
*/
byte
answerFrame
[
9
];
#define RXPin 4 // Serial Receive pin
#define TXPin 5 // Serial Transmit pin
// RS485 control
// this will change once we get different hardware
#define SERIAL_COMMUNICATION_CONTROL_PIN 6 // Transmission set pin
#define RS485_TX_PIN_VALUE HIGH
#define RS485_RX_PIN_VALUE LOW
SoftwareSerial
RS485Serial
(
RXPin
,
TXPin
);
// RX, TX
unsigned
int
calculateCRC
()
// TODO pass the query/answer frame into this and return the changed frame
// to make things neater maybe? Apparently there are also libraries for this...
// Change the last two bytes of the queryFrame to conform to a CRC check
// Yes, this is necessary. No, I don't know exactly what it does.
{
unsigned
int
tmp1
,
tmp2
,
flag
;
tmp1
=
0xFFFF
;
for
(
unsigned
char
i
=
0
;
i
<
bufferSize
;
i
++
)
{
tmp1
=
tmp1
^
queryFrame
[
i
];
for
(
unsigned
char
j
=
1
;
j
<=
8
;
j
++
)
{
flag
=
tmp1
&
0x0001
;
tmp1
>>=
1
;
if
(
flag
)
tmp1
^=
0xA001
;
}
}
// Reverse byte order.
tmp2
=
tmp1
>>
8
;
tmp1
=
(
tmp1
<<
8
)
|
tmp2
;
tmp1
&=
0xFFFF
;
queryFrame
[
bufferSize
+
1
]
=
tmp1
;
queryFrame
[
bufferSize
]
=
tmp1
>>
8
;
return
tmp1
;
// the returned value is already swapped - CRC_L byte is first & CRC_H byte is last
}
void
setup
()
{
// configure the pin to be output only
pinMode
(
SERIAL_COMMUNICATION_CONTROL_PIN
,
OUTPUT
);
// Set data rates: Serial baud rate has to be WAY HIGHER than RS485Serial!
Serial
.
begin
(
115200
);
RS485Serial
.
begin
(
4800
);
// Calculate the check bytes: changes the last two bytes of queryFrame
calculateCRC
();
// Print the message that's sent to the sensor
Serial
.
println
(
"Query bytes:"
);
for
(
int
i
=
0
;
i
<
sizeof
(
queryFrame
);
i
++
){
Serial
.
print
(
queryFrame
[
i
],
HEX
);
Serial
.
print
(
" "
);
}
Serial
.
println
();
Serial
.
println
();
}
void
loop
()
{
// Index for the readout while loop
int
idx
=
0
;
int
byteReceived
;
float
vwc
;
// volumetric waetr content, i.e. soil moisture
float
temp
;
// soil temperature
// Initialize the transmitter
Serial
.
println
(
"Sending data"
);
digitalWrite
(
SERIAL_COMMUNICATION_CONTROL_PIN
,
RS485_TX_PIN_VALUE
);
// Send message: request a reading from the sensor
RS485Serial
.
write
(
queryFrame
,
sizeof
(
queryFrame
));
// Initialize the receiver
digitalWrite
(
SERIAL_COMMUNICATION_CONTROL_PIN
,
RS485_RX_PIN_VALUE
);
// Read out data: this works ONLY when the Serial baud rate >> RS485Serial baud rate
// TODO add some logic for when there's no data and we get a timeout
while
(
idx
<
sizeof
(
answerFrame
))
{
if
(
RS485Serial
.
available
())
{
byteReceived
=
RS485Serial
.
read
();
// Serial.println(byteReceived, HEX);
answerFrame
[
idx
]
=
byteReceived
;
idx
++
;
}
}
// Print out answer bytes
/*
Byte 0: sensor address
Byte 1: Function code
Byte 2: valid bytes (2 valid bytes per read variable)
Byte 3+4: 1st read variable
Byte 5+6: 2nd read variable
Byte n-1 + n: CRC checks
*/
Serial
.
println
(
" "
);
Serial
.
println
(
"Answer bytes:"
);
for
(
int
i
=
0
;
i
<
sizeof
(
answerFrame
);
i
++
){
Serial
.
print
(
answerFrame
[
i
],
HEX
);
Serial
.
print
(
" "
);
}
Serial
.
println
();
Serial
.
println
();
Serial
.
print
(
"Sensor number: "
);
Serial
.
println
(
answerFrame
[
0
],
HEX
);
Serial
.
print
(
"Number of read variables: "
);
Serial
.
println
(
answerFrame
[
2
]
/
2
,
DEC
);
vwc
=
word
(
answerFrame
[
3
],
answerFrame
[
4
]);
// word = 2 bytes, high byte first
Serial
.
print
(
"vwc: "
);
Serial
.
println
(
vwc
/
10
,
DEC
);
temp
=
word
(
answerFrame
[
5
],
answerFrame
[
6
]);
Serial
.
print
(
"soil T: "
);
Serial
.
println
(
temp
/
10
,
DEC
);
Serial
.
println
(
" "
);
// Get reading every 5 seconds
delay
(
5000
);
/* TODO add a CRC check for the received data, i.e. take n-2 bytes of the answer,
calculate CRC, and then compare if it fist with the CRC bytes that were received.
*/
}
This diff is collapsed.
Click to expand it.
code-snippets/client/soil_sensor_sentec/platformio.ini
0 → 100644
+
19
−
0
View file @
05607066
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32-c3-devkitm-1]
platform
=
espressif32
board
=
esp32-c3-devkitm-1
framework
=
arduino
monitor_speed
=
115000
lib_deps
=
EspSoftwareSerial
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment