Exercise: OneWire Sensor Class¶
Download Monolithic Sensor Implementation¶
Download
onewire-temperature-monolithic.cpp
to your programs directoryAdd it to
CMakeLists.txt
Test Monolithic Implementation¶
Setup toolchain (if not yet done): Cross Toolchain Setup
Build as described in CMake: Cross Build
In short (please supply the paths from your situation -
/tmp/build
and~/source
are only placeholders),$ mkdir /tmp/build/ # <--- create build directory $ cd /tmp/build/ # <--- cd into it $ cmake -DCMAKE_TOOLCHAIN_FILE=/home/jfasch/armv8-rpi4-linux-gnueabihf.cmake ~/source/ ... roedel ... $ make
Transfer to Raspberry,
$ scp -P 2020 /tmp/build/path/to/your/programs/onewire-temperature firstname.lastname@jfasch.bounceme.net:
Test it
$ ssh -p 2020 firstname.lastname@jfasch.bounceme.net ./onewire-temperature ./onewire-temperature <filename> <interval> $ ssh -p 2020 firstname.lastname@jfasch.bounceme.net ./onewire-temperature /sys/bus/w1/devices/28-02131d959eaa/temperature 1 20687 20687 ...
class W1Sensor
¶
Add the following test to your test suite (i.e., register it a another source file in
CMakeLists.txt
)To make it run, create a pair of files (
sensor-w1.{h,cpp}
) in your library directory (again,CMakeLists.txt
)Fix test failures until green
Note
The sensor implementation is in no way tied to the Raspberry. All it does is read a file, and that can be done on the development machine (a PC likely) just as well.
#include <gtest/gtest.h>
#include <sensor-w1.h>
#include <cstdlib>
#include <unistd.h>
#include <stdexcept>
using namespace std;
// fixture class: supply a temporary file, plus a method
// write_temperature() thaht derived classes can call
struct w1_sensor_suite : public ::testing::Test
{
void SetUp() override
{
char filename_pattern[] = "w1_sensor_suite-XXXXXX";
fd = mkstemp(filename_pattern);
if (fd == -1)
throw runtime_error("nix mkstemp()");
filename = filename_pattern;
}
void TearDown() override
{
if (fd != -1) {
close(fd);
unlink(filename.c_str());
}
}
void change_temperature(double temperature)
{
unsigned temp_milli = temperature * 1000;
string content = to_string(temp_milli);
off_t pos = ::lseek(fd, 0, SEEK_SET);
ASSERT_EQ(pos, 0);
ssize_t nwritten = ::write(fd, content.c_str(), content.size());
ASSERT_EQ(nwritten, content.size());
}
int fd;
string filename;
};
TEST_F(w1_sensor_suite, test_read_sensor)
{
W1Sensor sensor(filename); // <--- using filename from w1_sensor_suite fixture
double temperature;
change_temperature(42.666); // <--- change temperature
temperature = sensor.get_temperature(); // <--- read temperature
ASSERT_FLOAT_EQ(temperature, 42.666);
change_temperature(36.5); // <--- change temperature
temperature = sensor.get_temperature(); // <--- read temperature
ASSERT_FLOAT_EQ(temperature, 36.5);
}
Refactoring¶
Modify onewire-temperature.cpp
to not use any file
operations. Rather, #include <sensor-w1.h>
and use that instead.
Testing
When done, test it on the Pi like above