-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
372 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Leka - LekaOS | ||
# Copyright 2022 APF France handicap | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
add_library(TouchSensorKit STATIC) | ||
|
||
target_include_directories(TouchSensorKit | ||
PUBLIC | ||
include | ||
) | ||
|
||
target_sources(TouchSensorKit | ||
PRIVATE | ||
source/TouchSensorKit.cpp | ||
) | ||
|
||
target_link_libraries(TouchSensorKit | ||
mbed-os | ||
IOKit | ||
CoreI2C | ||
CoreIOExpander | ||
CoreDACTouch | ||
) | ||
|
||
if (${CMAKE_PROJECT_NAME} STREQUAL "LekaOSUnitTests") | ||
|
||
leka_unit_tests_sources( | ||
tests/TouchSensorKit_test.cpp | ||
) | ||
|
||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Leka - LekaOS | ||
// Copyright 2022 APF France handicap | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#pragma once | ||
|
||
#include "CoreDACTouch.h" | ||
#include "CoreI2C.h" | ||
#include "CoreIOExpander.h" | ||
#include "DigitalOut.h" | ||
#include "IOKit/DigitalIn.h" | ||
#include "IOKit/DigitalOut.h" | ||
#include "LogKit.h" | ||
#include "internal/TouchSensorSystem.h" | ||
|
||
namespace leka { | ||
|
||
class TouchSensorKit | ||
{ | ||
public: | ||
explicit TouchSensorKit() = default; | ||
void setup(); | ||
|
||
void updateState(); | ||
void printState(); | ||
|
||
void resetByPowerMode(); | ||
|
||
void adjust_sensivity(uint16_t value); | ||
void calibration(); | ||
|
||
private: | ||
void setPullMode(PinMode mode); | ||
|
||
void setPowerMode(int power_mode); | ||
|
||
void initDACTouch(); | ||
|
||
void calibrateTwoSensors(bool &sensor_left, bool &sensor_right, uint8_t channel); | ||
void calibrateEars(); | ||
void calibrateBeltLBRF(); | ||
void calibrateBeltRBLF(); | ||
|
||
CoreI2C corei2c {PinName::SENSOR_PROXIMITY_MUX_I2C_SDA, PinName::SENSOR_PROXIMITY_MUX_I2C_SCL}; | ||
mbed::DigitalOut io_expander_reset {PinName::SENSOR_PROXIMITY_MUX_RESET, 0}; | ||
CoreIOExpanderMCP23017 io_expander {corei2c, io_expander_reset}; | ||
CoreDACTouchMCP4728 dac_touch_left {corei2c, 0xC0}; | ||
CoreDACTouchMCP4728 dac_touch_right {corei2c, 0xC2}; | ||
|
||
leka::io::expanded::DigitalIn<> _ear_left_input {io_expander, touch::pin::ear_left_input}; | ||
leka::io::expanded::DigitalIn<> _ear_right_input {io_expander, touch::pin::ear_right_input}; | ||
leka::io::expanded::DigitalIn<> _belt_left_back_input {io_expander, touch::pin::belt_left_back_input}; | ||
leka::io::expanded::DigitalIn<> _belt_left_front_input {io_expander, touch::pin::belt_left_front_input}; | ||
leka::io::expanded::DigitalIn<> _belt_right_back_input {io_expander, touch::pin::belt_right_back_input}; | ||
leka::io::expanded::DigitalIn<> _belt_right_front_input {io_expander, touch::pin::belt_right_front_input}; | ||
|
||
leka::io::expanded::DigitalOut<> _ear_left_pm {io_expander, touch::pin::ear_left_power_mode}; | ||
leka::io::expanded::DigitalOut<> _ear_right_pm {io_expander, touch::pin::ear_right_power_mode}; | ||
leka::io::expanded::DigitalOut<> _belt_left_back_pm {io_expander, touch::pin::belt_left_back_power_mode}; | ||
leka::io::expanded::DigitalOut<> _belt_left_front_pm {io_expander, touch::pin::belt_left_front_power_mode}; | ||
leka::io::expanded::DigitalOut<> _belt_right_back_pm {io_expander, touch::pin::belt_right_back_power_mode}; | ||
leka::io::expanded::DigitalOut<> _belt_right_front_pm {io_expander, touch::pin::belt_right_front_power_mode}; | ||
|
||
bool _ear_left_touched {false}; | ||
bool _ear_right_touched {false}; | ||
bool _belt_left_back_touched {false}; | ||
bool _belt_left_front_touched {false}; | ||
bool _belt_right_back_touched {false}; | ||
bool _belt_right_front_touched {false}; | ||
|
||
uint16_t default_max_value_calib {0x0FFF}; | ||
uint16_t default_min_value_calib {0x0000}; | ||
}; | ||
} // namespace leka |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Leka - LekaOS | ||
// Copyright 2022 APF France handicap | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#pragma once | ||
|
||
#include "CoreIOExpander.h" | ||
|
||
namespace leka::touch { | ||
|
||
namespace pin { | ||
inline constexpr auto ear_left_input = uint16_t {leka::mcp23017::pin::PB5}; | ||
inline constexpr auto ear_right_input = uint16_t {leka::mcp23017::pin::PB4}; | ||
inline constexpr auto belt_left_back_input = uint16_t {leka::mcp23017::pin::PB3}; | ||
inline constexpr auto belt_left_front_input = uint16_t {leka::mcp23017::pin::PB2}; | ||
inline constexpr auto belt_right_back_input = uint16_t {leka::mcp23017::pin::PB1}; | ||
inline constexpr auto belt_right_front_input = uint16_t {leka::mcp23017::pin::PB0}; | ||
|
||
inline constexpr auto ear_left_power_mode = uint16_t {leka::mcp23017::pin::PA5}; | ||
inline constexpr auto ear_right_power_mode = uint16_t {leka::mcp23017::pin::PA4}; | ||
inline constexpr auto belt_left_back_power_mode = uint16_t {leka::mcp23017::pin::PA3}; | ||
inline constexpr auto belt_left_front_power_mode = uint16_t {leka::mcp23017::pin::PA2}; | ||
inline constexpr auto belt_right_back_power_mode = uint16_t {leka::mcp23017::pin::PA1}; | ||
inline constexpr auto belt_right_front_power_mode = uint16_t {leka::mcp23017::pin::PA0}; | ||
} // namespace pin | ||
|
||
namespace power_mode { | ||
inline constexpr auto low = uint16_t {0x00}; | ||
inline constexpr auto normal = uint16_t {0x01}; | ||
|
||
} // namespace power_mode | ||
|
||
} // namespace leka::touch |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
// Leka - LekaOS | ||
// Copyright 2022 APF France handicap | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include "TouchSensorKit.h" | ||
|
||
#include "rtos/ThisThread.h" | ||
|
||
using namespace leka; | ||
using namespace std::chrono_literals; | ||
|
||
void TouchSensorKit::setup() | ||
{ | ||
setPullMode(PinMode::PullUp); | ||
setPowerMode(touch::power_mode::normal); | ||
initDACTouch(); | ||
} | ||
|
||
void TouchSensorKit::updateState() | ||
{ | ||
_ear_left_touched = (0 == _ear_left_input.read()); | ||
_ear_right_touched = (0 == _ear_right_input.read()); | ||
_belt_left_back_touched = (0 == _belt_left_back_input.read()); | ||
_belt_left_front_touched = (0 == _belt_left_front_input.read()); | ||
_belt_right_back_touched = (0 == _belt_right_back_input.read()); | ||
_belt_right_front_touched = (0 == _belt_right_front_input.read()); | ||
} | ||
|
||
void TouchSensorKit::printState() | ||
{ | ||
log_info("Ear left touched: %s", _ear_left_touched ? "true" : "false"); | ||
log_info("Ear right touched: %s", _ear_right_touched ? "true" : "false"); | ||
log_info("Belt left front touched: %s", _belt_left_front_touched ? "true" : "false"); | ||
log_info("Belt left back touched: %s", _belt_left_back_touched ? "true" : "false"); | ||
log_info("Belt right front touched: %s", _belt_right_front_touched ? "true" : "false"); | ||
log_info("Belt right back touched: %s", _belt_right_back_touched ? "true" : "false"); | ||
} | ||
|
||
void TouchSensorKit::resetByPowerMode() | ||
{ | ||
setPowerMode(touch::power_mode::low); | ||
rtos::ThisThread::sleep_for(5ms); | ||
setPowerMode(touch::power_mode::normal); | ||
rtos::ThisThread::sleep_for(5ms); | ||
} | ||
|
||
void TouchSensorKit::setPullMode(PinMode mode) | ||
{ | ||
_ear_left_input.mode(mode); | ||
_ear_right_input.mode(mode); | ||
_belt_left_back_input.mode(mode); | ||
_belt_left_front_input.mode(mode); | ||
_belt_right_back_input.mode(mode); | ||
_belt_right_front_input.mode(mode); | ||
} | ||
|
||
void TouchSensorKit::setPowerMode(int power_mode) | ||
{ | ||
_ear_left_pm.write(power_mode); | ||
_ear_right_pm.write(power_mode); | ||
_belt_left_back_pm.write(power_mode); | ||
_belt_left_front_pm.write(power_mode); | ||
_belt_right_back_pm.write(power_mode); | ||
_belt_right_front_pm.write(power_mode); | ||
} | ||
|
||
void TouchSensorKit::initDACTouch() | ||
{ | ||
dac_touch_left.writeVoltageReference(0x00); | ||
dac_touch_left.writePowerMode(0x00); | ||
dac_touch_left.writeGain(0x00); | ||
dac_touch_right.writeVoltageReference(0x00); | ||
dac_touch_right.writePowerMode(0x00); | ||
dac_touch_right.writeGain(0x00); | ||
} | ||
|
||
void TouchSensorKit::adjust_sensivity(uint16_t value) | ||
{ | ||
auto buffer = std::array<uint8_t, 2> {}; | ||
|
||
buffer.at(0) = static_cast<uint8_t>((0x0F00 & value) >> 8); | ||
buffer.at(1) = static_cast<uint8_t>(0x00FF & value); | ||
|
||
dac_touch_left.writeToSpecificInputRegister(0, buffer); | ||
dac_touch_right.writeToSpecificInputRegister(0, buffer); | ||
|
||
dac_touch_left.writeToSpecificInputRegister(1, buffer); | ||
dac_touch_right.writeToSpecificInputRegister(1, buffer); | ||
|
||
dac_touch_left.writeToSpecificInputRegister(2, buffer); | ||
dac_touch_right.writeToSpecificInputRegister(2, buffer); | ||
rtos::ThisThread::sleep_for(1ms); | ||
} | ||
|
||
void TouchSensorKit::calibrateTwoSensors(bool &sensor_left, bool &sensor_right, uint8_t channel) | ||
{ | ||
auto buffer_left = std::array<uint8_t, 2> {}; | ||
auto buffer_right = std::array<uint8_t, 2> {}; | ||
|
||
dac_touch_left.writeToSpecificInputRegister(channel, buffer_left); | ||
dac_touch_right.writeToSpecificInputRegister(channel, buffer_right); | ||
rtos::ThisThread::sleep_for(1ms); | ||
|
||
auto value_left_calib = uint16_t {default_max_value_calib}; | ||
auto value_right_calib = uint16_t {default_max_value_calib}; | ||
auto step = uint8_t {0x00FF}; | ||
|
||
updateState(); | ||
|
||
while (!((sensor_left || value_left_calib <= value_left_calib % step) && | ||
(sensor_right || value_right_calib <= value_right_calib % step))) { | ||
if (!sensor_left) { | ||
if (value_left_calib - step > default_max_value_calib) { | ||
value_left_calib = default_max_value_calib; | ||
} else { | ||
value_left_calib -= step; | ||
} | ||
} | ||
if (!sensor_right) { | ||
if (value_right_calib - step > default_max_value_calib) { | ||
value_right_calib = default_max_value_calib; | ||
} else { | ||
value_right_calib -= step; | ||
} | ||
} | ||
|
||
buffer_left.at(0) = static_cast<uint8_t>((0x0F00 & value_left_calib) >> 8); | ||
buffer_left.at(1) = static_cast<uint8_t>(0x00FF & value_left_calib); | ||
dac_touch_left.writeToSpecificInputRegister(channel, buffer_left); | ||
rtos::ThisThread::sleep_for(1ms); | ||
|
||
buffer_right.at(0) = static_cast<uint8_t>((0x0F00 & value_right_calib) >> 8); | ||
buffer_right.at(1) = static_cast<uint8_t>(0x00FF & value_right_calib); | ||
dac_touch_right.writeToSpecificInputRegister(channel, buffer_right); | ||
rtos::ThisThread::sleep_for(1ms); | ||
|
||
updateState(); | ||
rtos::ThisThread::sleep_for(500ms); | ||
} | ||
|
||
dac_touch_left.writeToSpecificMemoryRegister(channel, buffer_left); | ||
dac_touch_right.writeToSpecificMemoryRegister(channel, buffer_right); | ||
rtos::ThisThread::sleep_for(1ms); | ||
log_info("Value Left Calibration : %d", value_left_calib); | ||
log_info("Value Right Calibration : %d", value_right_calib); | ||
log_info("CALIBRATED!"); | ||
rtos::ThisThread::sleep_for(1ms); | ||
} | ||
|
||
void TouchSensorKit::calibrateEars() | ||
{ | ||
log_info("Place hands on EAR LEFT and EAR RIGHT"); | ||
log_info("Calibration will start in 5 seconds"); | ||
rtos::ThisThread::sleep_for(5s); | ||
calibrateTwoSensors(_ear_left_touched, _ear_right_touched, 2); | ||
} | ||
|
||
void TouchSensorKit::calibrateBeltLBRF() | ||
{ | ||
log_info("Place hands on BELT LEFT BACK and BELT RIGHT FRONT"); | ||
log_info("Calibration will start in 5 seconds"); | ||
rtos::ThisThread::sleep_for(5s); | ||
calibrateTwoSensors(_belt_left_back_touched, _belt_right_front_touched, 1); | ||
} | ||
|
||
void TouchSensorKit::calibrateBeltRBLF() | ||
{ | ||
log_info("Place hands on BELT LEFT FRONT and BELT RIGHT BACK"); | ||
log_info("Calibration will start in 5 seconds"); | ||
rtos::ThisThread::sleep_for(5s); | ||
calibrateTwoSensors(_belt_left_front_touched, _belt_right_back_touched, 0); | ||
} | ||
|
||
void TouchSensorKit::calibration() | ||
{ | ||
log_info("Touch calibration"); | ||
log_info("For each of 6 touch sensors, value of sensibility will change"); | ||
log_info("Please keep your hands on 2 sensors until \"CALIBRATED !\" appears.\n"); | ||
rtos::ThisThread::sleep_for(5s); | ||
|
||
calibrateEars(); | ||
calibrateBeltLBRF(); | ||
calibrateBeltRBLF(); | ||
rtos::ThisThread::sleep_for(1s); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Leka - LekaOS | ||
// Copyright 2022 APF France handicap | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include "TouchSensorKit.h" | ||
|
||
#include "gtest/gtest.h" | ||
|
||
using namespace leka; | ||
// using ::testing::_; | ||
|
||
class TouchSensorTest : public ::testing::Test | ||
{ | ||
protected: | ||
// void SetUp() override {} | ||
// void TearDown() override {} | ||
|
||
TouchSensorKit touch_sensor_kit = TouchSensorKit(); | ||
}; | ||
|
||
TEST_F(TouchSensorTest, initializationDefault) | ||
{ | ||
ASSERT_NE(&touch_sensor_kit, nullptr); | ||
} | ||
|
||
TEST_F(TouchSensorTest, setup) | ||
{ | ||
touch_sensor_kit.setup(); | ||
} | ||
|
||
TEST_F(TouchSensorTest, updateState) | ||
{ | ||
touch_sensor_kit.updateState(); | ||
} | ||
|
||
TEST_F(TouchSensorTest, printState) | ||
{ | ||
touch_sensor_kit.printState(); | ||
} | ||
|
||
TEST_F(TouchSensorTest, resetByPowerMode) | ||
{ | ||
touch_sensor_kit.resetByPowerMode(); | ||
} | ||
|
||
TEST_F(TouchSensorTest, calibration) | ||
{ | ||
touch_sensor_kit.caliration(); | ||
} |