/* * peripherals_ir_sensors.hpp * * Created on: Apr 10, 2021 * Author: erki */ #ifndef SKULLC_PERIPHERALS_IR_SENSORS_HPP_ #define SKULLC_PERIPHERALS_IR_SENSORS_HPP_ #include #include #include #include namespace Peripherals { template class IrSensors { public: using gpio = G; Adc adc; IrSensors() = delete; template explicit IrSensors(ADC_HandleTypeDef* hadc, const std::array& channels, Args&&... gpios) : adc(hadc), channels_(channels), gpios_{std::forward(gpios)...} { static_assert(sizeof...(Args) == N, "Not enough GPIOs passed."); } void startReading() { for (auto& gpio : gpios_) gpio.set(true); adc.startDma(); } void stopReading() { for (auto& gpio : gpios_) gpio.set(false); adc.stopDma(); } void updateReadings() { for (std::size_t i = 0; i < N; i++) { averages_[i] -= averages_[i] / Average; averages_[i] += adc.readings[i] / Average; } } std::array, N> getDistanceData() { std::array, N> data; for (std::size_t i = 0; i < N; i++) { const float interim = averages_[i] - offsets_[i]; data[i].first = multipliers_[i] * std::pow(interim, exponents_[i]); data[i].second = data[i].first < wall_thresholds_[i]; } return data; } void calibrate(const std::uint32_t samples, const std::uint32_t sample_time) { std::array measurements; for (std::uint32_t i = 0; i < samples; i++) { for (std::uint32_t ch = 0; ch < channels_.size(); ch++) measurements[ch] += adc.read(channels_[ch], sample_time, 100); } for (std::uint32_t ch = 0; ch < channels_.size(); ch++) offsets_[ch] = std::uint16_t(measurements[ch] / samples); } void setExponents(const std::array& e) { exponents_ = e; } void setMultipliers(const std::array& m) { multipliers_ = m; } void setWallThresholds(const std::array& t) { wall_thresholds_ = t; } private: std::array channels_; std::array gpios_; std::array averages_; std::array offsets_; std::array exponents_; std::array multipliers_; std::array wall_thresholds_; }; }// namespace Peripherals #endif /* SKULLC_PERIPHERALS_IR_SENSORS_HPP_ */