Smartcar Shield
Loading...
Searching...
No Matches
SRF08.cpp
Go to the documentation of this file.
1#include "SRF08.hpp"
2#include "../../../../utilities/Utilities.hpp"
3
4namespace
5{
6// For documentation on addressing, please refer to:
7// http://www.robot-electronics.co.uk/htm/srf08tech.html
8const uint8_t kFirstAddress = 112;
9const uint8_t kLastAddress = 127;
10const uint8_t kRangingCommandRegister = 0x00;
11const uint8_t kRangingInCm = 0x51;
12} // namespace
13
14using namespace smartcarlib::constants::srf08;
16using namespace smartcarlib::utils;
17
18SRF08::SRF08(Runtime& runtime, uint8_t address)
19 : mAddress{ address }
20 , mRuntime{ runtime }
21{
22}
23
24void SRF08::attach()
25{
26 if (!mAttached)
27 {
28 mRuntime.i2cInit();
29 mAttached = true;
30 }
31}
32
33unsigned int SRF08::getDistance()
34{
35 attach();
36
37 static const uint8_t kFirstEchoHighByte = 0x02;
38 static const uint8_t kNumberOfBytesToRequest = 2;
39
40 measureDistance();
41
42 mRuntime.i2cBeginTransmission(mAddress);
43 mRuntime.i2cWrite(kFirstEchoHighByte);
44 mRuntime.i2cEndTransmission();
45
46 mRuntime.i2cRequestFrom(mAddress, kNumberOfBytesToRequest);
47 if (mRuntime.i2cAvailable() == 0)
48 {
49 return static_cast<unsigned int>(-1); // Return a large error-like value
50 }
51 auto high = mRuntime.i2cRead();
52 auto low = mRuntime.i2cRead();
53
54 static constexpr auto kBitsInByte = 8;
55
56 return static_cast<uint16_t>((high << kBitsInByte) + low);
57}
58
59unsigned int SRF08::getMedianDistance(uint8_t iterations)
60{
61 if (iterations == 0 || iterations > kMaxMedianMeasurements)
62 {
63 return static_cast<unsigned int>(-1); // Return a large number to indicate error
64 }
65
66 unsigned int measurements[kMaxMedianMeasurements];
67 for (auto i = 0; i < iterations; i++)
68 {
69 measurements[i] = getDistance();
70 mRuntime.delayMillis(mPingDelay);
71 }
72
73 return getMedian(measurements, iterations);
74}
75
76void SRF08::setGain(uint8_t gainValue)
77{
78 attach();
79
80 static const uint8_t kGainRegister = 0x01;
81 static const uint8_t kMinGain = 0;
82 static const uint8_t kMaxGain = 31;
83
84 mRuntime.i2cBeginTransmission(mAddress);
85 mRuntime.i2cWrite(kGainRegister);
86 mRuntime.i2cWrite(getConstrain(gainValue, kMinGain, kMaxGain));
87 mRuntime.i2cEndTransmission();
88}
89
90void SRF08::setRange(uint8_t range)
91{
92 attach();
93
94 static const uint8_t kRangeRegister = 0x02;
95
96 mRuntime.i2cBeginTransmission(mAddress);
97 mRuntime.i2cWrite(kRangeRegister);
98 // Max_Range = (range * 3.4) + 3.4 in centimeters
99 mRuntime.i2cWrite(range);
100 mRuntime.i2cEndTransmission();
101}
102
103unsigned long SRF08::setPingDelay(unsigned long milliseconds)
104{
105 mPingDelay = milliseconds;
106 return mPingDelay;
107}
108
110{
111 attach();
112
113 static const uint8_t kLightSensorByte = 0x01;
114 static const uint8_t kNumberOfBytesToRequest = 1;
115
116 // Start a ranging
117 measureDistance();
118
119 // Get only the light reading byte
120 mRuntime.i2cBeginTransmission(mAddress);
121 mRuntime.i2cWrite(kLightSensorByte);
122 mRuntime.i2cEndTransmission();
123 mRuntime.i2cRequestFrom(mAddress, kNumberOfBytesToRequest);
124 mRuntime.delayMillis(mPingDelay);
125
126 return mRuntime.i2cAvailable() != 0 ? static_cast<uint8_t>(mRuntime.i2cRead())
127 : static_cast<uint8_t>(-1);
128}
129
130uint8_t SRF08::changeAddress(uint8_t newAddress)
131{
132 attach();
133
134 static const uint8_t kFirstInChangeAddressSequence = 0xA0;
135 static const uint8_t kSecondInChangeAddressSequence = 0xAA;
136 static const uint8_t kThirdInChangeAddressSequence = 0xA5;
137
138 newAddress = getConstrain(newAddress, kFirstAddress, kLastAddress);
139
140 mRuntime.i2cBeginTransmission(mAddress);
141 mRuntime.i2cWrite(kRangingCommandRegister);
142 mRuntime.i2cWrite(kFirstInChangeAddressSequence);
143 mRuntime.i2cEndTransmission();
144
145 mRuntime.i2cBeginTransmission(mAddress);
146 mRuntime.i2cWrite(kRangingCommandRegister);
147 mRuntime.i2cWrite(kSecondInChangeAddressSequence);
148 mRuntime.i2cEndTransmission();
149
150 mRuntime.i2cBeginTransmission(mAddress);
151 mRuntime.i2cWrite(kRangingCommandRegister);
152 mRuntime.i2cWrite(kThirdInChangeAddressSequence);
153 mRuntime.i2cEndTransmission();
154
155 mRuntime.i2cBeginTransmission(mAddress);
156 mRuntime.i2cWrite(kRangingCommandRegister);
157 mRuntime.i2cWrite(static_cast<uint8_t>(newAddress << 0x01));
158 mRuntime.i2cEndTransmission();
159
160 mAddress = newAddress;
161
162 return mAddress;
163}
164
165void SRF08::measureDistance()
166{
167 mRuntime.i2cBeginTransmission(mAddress);
168 mRuntime.i2cWrite(kRangingCommandRegister);
169 mRuntime.i2cWrite(kRangingInCm);
170 mRuntime.i2cEndTransmission();
171 mRuntime.delayMillis(mPingDelay);
172}
An interface to serve as a wrapper for the native runtime environment, greatly inspired by the Arduin...
Definition Runtime.hpp:36
virtual size_t i2cWrite(uint8_t value)=0
Send the specified byte via i2c, equivalent of Wire.write in Arduino.
virtual void delayMillis(unsigned long milliseconds)=0
Block the execution for the specified number of milliseconds, equivalent of delay in Arduino.
virtual void i2cBeginTransmission(uint8_t address)=0
Initiate a transmission to the specified I2C slave device, equivalent of Wire.beginTransmission in Ar...
virtual uint8_t i2cEndTransmission()=0
Ends a transmission to an I2C device equivalent of Wire.endTransmission in Arduino.
virtual int i2cAvailable()=0
Gets the number of bytes available to be retrieved, equivalent of Wire.availableO in Arduino.
virtual int i2cRead()=0
Reads a byte from I2C bus, equivalent of Wire.read in Arduino.
virtual void i2cInit()=0
Initialize I2C bus as master, equivalent of Wire.begin in Arduino.
virtual uint8_t i2cRequestFrom(uint8_t address, uint8_t numberOfBytes)=0
Request a number of bytes from the specified I2C slave, equivalent of Wire.requestFrom in Arduino.
unsigned long setPingDelay(unsigned long milliseconds=smartcarlib::constants::srf08::kDefaultPingDelay)
Delay between ranging measurements.
Definition SRF08.cpp:103
SRF08(Runtime &runtime, uint8_t address)
Constructs an SRF08 sensor that communicates over I2C.
Definition SRF08.cpp:18
void setRange(uint8_t range)
Combined with the gain setting affects how much time each measurement will last as well as the maximu...
Definition SRF08.cpp:90
unsigned int getMedianDistance(uint8_t iterations=smartcarlib::constants::srf08::kDefaultIterations) override
Gets the median distance from the specified number of measurements.
Definition SRF08.cpp:59
unsigned int getDistance() override
Gets the distance measured by the sensor in centimeters.
Definition SRF08.cpp:33
uint8_t changeAddress(uint8_t newAddress)
Changes the address of the specific SRF08 sensor.
Definition SRF08.cpp:130
uint8_t getLightReading()
Conducts a measurement from the on-board light sensor.
Definition SRF08.cpp:109
void setGain(uint8_t gain)
Combined with the range setting affects how much time each measurement will last as well as the maxim...
Definition SRF08.cpp:76
AnyNumber getMedian(AnyNumber unsortedNumbers[], const unsigned int &arraySize)
Gets the median value out of the supplied number array.
Definition Utilities.hpp:66
constexpr AnyNumber getConstrain(AnyNumber number, AnyNumber min, AnyNumber max)
Limit the number between a range.
Definition Utilities.hpp:46