SNS - Time-of-flight Sensor - #25
Conversation
DylanCavers
left a comment
There was a problem hiding this comment.
A few changes, mostly to do with formatting and code style, make sure to change the tof file to tof.cpp
TomLonergan03
left a comment
There was a problem hiding this comment.
also, run clang-format over this
TomLonergan03
left a comment
There was a problem hiding this comment.
Rename this PR also
|
Implemented with reference to STMicroelectronics application note AN4545 Task list moved to top of PR |
|
|
||
| private: | ||
| // TODOLater - Confirm these addresses are correct | ||
| // Register addresses/values taken from the VL6180X datasheet |
There was a problem hiding this comment.
Not sure where exactly they've been taken from, or what they all mean - Are these needed?
| static constexpr std::uint16_t kReadoutSamplingPeriod = 0x010a; | ||
| static constexpr std::uint8_t kSysAlsAnalogueGain = 0x03f; | ||
| static constexpr std::uint8_t kSysRangeVhvRepeatRate = 0x031; | ||
| // TODOLater - Confirm SYSALS__INTEGRATION_PERIOD (application note vs datasheet) |
There was a problem hiding this comment.
The datasheet gives this register an address of 0x040, but the application note AN4545 gives this register an address of 0x0041 on page 24
There was a problem hiding this comment.
lmfao of course it does
engineers write a useful datasheet challenge (impossible)
TomLonergan03
left a comment
There was a problem hiding this comment.
ik it's a wip, but here's critique anyway lol
| std::optional<std::uint8_t> TimeOfFlight::getRangeSingleShot() | ||
| { | ||
| if (checkSensorMode(kModeSingleShot) == core::Result::kFailure) { return std::nullopt; } | ||
| return getRange(); | ||
| }; | ||
|
|
||
| std::optional<std::uint8_t> TimeOfFlight::getRangeContinuous() | ||
| { | ||
| if (checkSensorMode(kModeContinuous) == core::Result::kFailure) { return std::nullopt; } | ||
| return getRange(); | ||
| }; |
There was a problem hiding this comment.
The sensor has two modes of operation: Single shot, and continuous. Single shot is a single measurement, while continuous will repeatedly measure the range with a time interval based on the value of kSysRangeIntermeasurementPeriod. Before reading in a given mode, register kSysRangeStart has to be set to either 1 or 3
Because the code to check that kSysRangeStart has the correct value is the same whether its checking for continuous or single-shot, and because the register to read the range from is the same in both cases if kSysRangeStart has the correct value (kResultRangeVal), getRangeSingleShot() and getRangeContinuous() call these separate functions to retrieve the range
As for which value will be wanted, single shot or continous, that's yet to be decided
| auto range_status = *status & 0b111; | ||
|
|
||
| // Wait for new measurement ready status | ||
| while (range_status != 0x04) { |
There was a problem hiding this comment.
this is scary, we need to be able to guarantee that it can't get stuck in this loop
| i2c_->writeByteToRegister(device_address_, array_return_addresses[15], 0x3c); | ||
| i2c_->writeByteToRegister(device_address_, array_return_addresses[16], 0x09); | ||
| i2c_->writeByteToRegister(device_address_, array_return_addresses[17], 0x09); | ||
| // i2c_->writeByteToRegister(device_address_, 0x0198, 0x01); |
There was a problem hiding this comment.
These registers were not commented out because they should be removed. They were commented out because at the time this code was written, #58 hadn't been merged yet. As such, the 16-bit registers being written to would cause build failure.
These registers should be added back in. Refer to the application note in the PR's header
| while (range_status != 0x04) { | ||
| status = i2c_->readByte(device_address_, kResultInterruptStatusGpio); | ||
| if (!status) { | ||
| const auto statuss = i2c_->readByte(device_address_, kResultInterruptStatusGpio); |
There was a problem hiding this comment.
statuss is quite the variable name.
| auto range_status = *status & 0b111; | ||
|
|
||
| // Wait for new measurement ready status | ||
| uint8_t timeout = 0; |
| range_status = *status & 0b111; | ||
| range_status = *statuss & 0b111; | ||
| timeout++; | ||
| if (timeout > 1000000) { |
There was a problem hiding this comment.
Comparing a uint8_t variable to 1,000,000 will always return false
| range_status = *status & 0b111; | ||
| range_status = *statuss & 0b111; | ||
| timeout++; | ||
| if (timeout > 1000000) { |
There was a problem hiding this comment.
Is 1,000,000 sensible? It seems quite large.
|
|
||
| // Recommended : Public registers | ||
| i2c_->writeByteToRegister(device_address_, kSystemModeGpioOne, 0x10); | ||
| // i2c_->writeByteToRegister(device_address_, kReadoutSamplingPeriod, 0x30); |
There was a problem hiding this comment.
Again, this was a 16-bit register which would cause build failure, not a line which needed to be removed. It should be added back in
| // i2c_->writeByteToRegister(device_address_, 0x01a7, 0x1f); | ||
| i2c_->writeByteToRegister(device_address_, array_return_addresses[19], 0x00); | ||
|
|
||
| constexpr std::uint8_t data[] = {0xfd, |
There was a problem hiding this comment.
Add entries to this for the values to be written to the 16-bit registers
| @@ -1,4 +1,4 @@ | |||
| #include "time_of_flight.hpp" | |||
| #include "tof.hpp" | |||
There was a problem hiding this comment.
Make array_return_addresses a std::uint16_t array, and add the 16-bit registers. Then you can itterate through all the registers
(AN4545, p20)
There was a problem hiding this comment.
You should delete these tof.cpp/hpp files.
|
|
||
| // Wait for new measurement ready status | ||
| std::uint8_t timeout = 0; | ||
| std::uint8_t threshold = 10000; |
There was a problem hiding this comment.
std::unit8_t has a max value of 255. If you want to use 10,000 here, you'll need std::uint16_t, and you'll also need timeout to be std::uint16_t for the comparison to work
|
|
||
| // Wait for new measurement ready status | ||
| std::uint8_t timeout = 0; | ||
| std::uint8_t threshold = 10000; |
There was a problem hiding this comment.
Where has the value of 10,000 come from? What's the rationale for choosing that value?
Implemented with reference to STMicroelectronics application note AN4545