From b77d9db09ac73acfcf54e728e6f296eb78e60159 Mon Sep 17 00:00:00 2001 From: Bruno Herfst Date: Sat, 28 Sep 2024 03:49:24 +1000 Subject: [PATCH 1/9] Formatting --- src/gpio.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/gpio.h b/src/gpio.h index a152d67..dc12df8 100644 --- a/src/gpio.h +++ b/src/gpio.h @@ -6,18 +6,18 @@ using namespace std; enum GPIO_MAP_PIN { - GPIO2 = 2, GPIO14 = 14, - GPIO3 = 3, GPIO15 = 15, + GPIO2 = 2, GPIO14 = 14, + GPIO3 = 3, GPIO15 = 15, GPIO4 = 4, GPIO18 = 18, - GPIO17 = 17, GPIO23 = 23, - GPIO27 = 27, GPIO24 = 24, - GPIO22 = 22, GPIO25 = 25, - GPIO10 = 10, GPIO8 = 8, - GPIO9 = 9, GPIO7 = 7, - GPIO11 = 11, GPIO12 = 12, - GPIO5 = 5, GPIO16 = 16, - GPIO6 = 6, GPIO20 = 20, - GPIO13 = 13, GPIO21 = 21, + GPIO17 = 17, GPIO23 = 23, + GPIO27 = 27, GPIO24 = 24, + GPIO22 = 22, GPIO25 = 25, + GPIO10 = 10, GPIO8 = 8, + GPIO9 = 9, GPIO7 = 7, + GPIO11 = 11, GPIO12 = 12, + GPIO5 = 5, GPIO16 = 16, + GPIO6 = 6, GPIO20 = 20, + GPIO13 = 13, GPIO21 = 21, GPIO19 = 19, GPIO26 = 26, }; From 3be13f973f249d52d47f5df5d3ca5cbd528edb73 Mon Sep 17 00:00:00 2001 From: Bruno Herfst Date: Mon, 30 Sep 2024 10:45:15 +1000 Subject: [PATCH 2/9] Add DfRobotC4001 --- example-DfRobotC4001/Makefile | 13 + example-DfRobotC4001/addons.make | 1 + example-DfRobotC4001/config.make | 141 ++++++ example-DfRobotC4001/src/main.cpp | 40 ++ src/DFRobot_C4001.cpp | 814 ++++++++++++++++++++++++++++++ src/DFRobot_C4001.h | 423 ++++++++++++++++ src/ofxGPIO.h | 2 + 7 files changed, 1434 insertions(+) create mode 100644 example-DfRobotC4001/Makefile create mode 100644 example-DfRobotC4001/addons.make create mode 100644 example-DfRobotC4001/config.make create mode 100644 example-DfRobotC4001/src/main.cpp create mode 100644 src/DFRobot_C4001.cpp create mode 100644 src/DFRobot_C4001.h diff --git a/example-DfRobotC4001/Makefile b/example-DfRobotC4001/Makefile new file mode 100644 index 0000000..8d8e4c0 --- /dev/null +++ b/example-DfRobotC4001/Makefile @@ -0,0 +1,13 @@ +# Attempt to load a config.make file. +# If none is found, project defaults in config.project.make will be used. +ifneq ($(wildcard config.make),) + include config.make +endif + +# make sure the the OF_ROOT location is defined +ifndef OF_ROOT + OF_ROOT=$(realpath ../../..) +endif + +# call the project makefile! +include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk diff --git a/example-DfRobotC4001/addons.make b/example-DfRobotC4001/addons.make new file mode 100644 index 0000000..8300d55 --- /dev/null +++ b/example-DfRobotC4001/addons.make @@ -0,0 +1 @@ +ofxGPIO diff --git a/example-DfRobotC4001/config.make b/example-DfRobotC4001/config.make new file mode 100644 index 0000000..836fce7 --- /dev/null +++ b/example-DfRobotC4001/config.make @@ -0,0 +1,141 @@ +################################################################################ +# CONFIGURE PROJECT MAKEFILE (optional) +# This file is where we make project specific configurations. +################################################################################ + +################################################################################ +# OF ROOT +# The location of your root openFrameworks installation +# (default) OF_ROOT = ../../.. +################################################################################ +# OF_ROOT = ../../.. + +################################################################################ +# PROJECT ROOT +# The location of the project - a starting place for searching for files +# (default) PROJECT_ROOT = . (this directory) +# +################################################################################ +# PROJECT_ROOT = . + +################################################################################ +# PROJECT SPECIFIC CHECKS +# This is a project defined section to create internal makefile flags to +# conditionally enable or disable the addition of various features within +# this makefile. For instance, if you want to make changes based on whether +# GTK is installed, one might test that here and create a variable to check. +################################################################################ +# None + +################################################################################ +# PROJECT EXTERNAL SOURCE PATHS +# These are fully qualified paths that are not within the PROJECT_ROOT folder. +# Like source folders in the PROJECT_ROOT, these paths are subject to +# exlclusion via the PROJECT_EXLCUSIONS list. +# +# (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank) +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ +# PROJECT_EXTERNAL_SOURCE_PATHS = + +################################################################################ +# PROJECT EXCLUSIONS +# These makefiles assume that all folders in your current project directory +# and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations +# to look for source code. The any folders or files that match any of the +# items in the PROJECT_EXCLUSIONS list below will be ignored. +# +# Each item in the PROJECT_EXCLUSIONS list will be treated as a complete +# string unless teh user adds a wildcard (%) operator to match subdirectories. +# GNU make only allows one wildcard for matching. The second wildcard (%) is +# treated literally. +# +# (default) PROJECT_EXCLUSIONS = (blank) +# +# Will automatically exclude the following: +# +# $(PROJECT_ROOT)/bin% +# $(PROJECT_ROOT)/obj% +# $(PROJECT_ROOT)/%.xcodeproj +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ +# PROJECT_EXCLUSIONS = + +################################################################################ +# PROJECT LINKER FLAGS +# These flags will be sent to the linker when compiling the executable. +# +# (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs +# +# Note: Leave a leading space when adding list items with the += operator +# +# Currently, shared libraries that are needed are copied to the +# $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to +# add a runtime path to search for those shared libraries, since they aren't +# incorporated directly into the final executable application binary. +################################################################################ +# PROJECT_LDFLAGS=-Wl,-rpath=./libs + +################################################################################ +# PROJECT DEFINES +# Create a space-delimited list of DEFINES. The list will be converted into +# CFLAGS with the "-D" flag later in the makefile. +# +# (default) PROJECT_DEFINES = (blank) +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ +# PROJECT_DEFINES = + +################################################################################ +# PROJECT CFLAGS +# This is a list of fully qualified CFLAGS required when compiling for this +# project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS +# defined in your platform specific core configuration files. These flags are +# presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below. +# +# (default) PROJECT_CFLAGS = (blank) +# +# Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in +# your platform specific configuration file will be applied by default and +# further flags here may not be needed. +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ +# PROJECT_CFLAGS = + +################################################################################ +# PROJECT OPTIMIZATION CFLAGS +# These are lists of CFLAGS that are target-specific. While any flags could +# be conditionally added, they are usually limited to optimization flags. +# These flags are added BEFORE the PROJECT_CFLAGS. +# +# PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets. +# +# (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank) +# +# PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets. +# +# (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank) +# +# Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the +# PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration +# file will be applied by default and further optimization flags here may not +# be needed. +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ +# PROJECT_OPTIMIZATION_CFLAGS_RELEASE = +# PROJECT_OPTIMIZATION_CFLAGS_DEBUG = + +################################################################################ +# PROJECT COMPILERS +# Custom compilers can be set for CC and CXX +# (default) PROJECT_CXX = (blank) +# (default) PROJECT_CC = (blank) +# Note: Leave a leading space when adding list items with the += operator +################################################################################ +# PROJECT_CXX = +# PROJECT_CC = diff --git a/example-DfRobotC4001/src/main.cpp b/example-DfRobotC4001/src/main.cpp new file mode 100644 index 0000000..44ec0e9 --- /dev/null +++ b/example-DfRobotC4001/src/main.cpp @@ -0,0 +1,40 @@ +#include "ofMain.h" +#include "ofAppNoWindow.h" +#include "DFRobot_C4001.h" + +class ofApp : public ofBaseApp +{ + public: + DFRobot_C4001 MmSensor; + + void setup() + { + /* + * The Df Robot sensor has a switch + * for address selection a maximum + * of two sensors on I2C: address = 0x2A || 0x2B + */ + + mmSensor = new DFRobot_C4001_I2C("/dev/i2c-1", 0x2A); + mmSensor.begin(); + mmSensor.setSensorMode(eSpeedMode); + mmSensor.setDetectThres(30, 600, 10); + mmSensor.setFrettingDetection(eON); + } + + void update(){ + if(mmSensor.getTargetNumber() > 0) { + ofLog() << MmSensor.getTargetRange(); + } + } + + void exit(){ + ofExit(0); + } +}; + +int main( ){ + ofAppNoWindow w; + ofSetupOpenGL(&w,0,0, OF_WINDOW); + ofRunApp( new ofApp() ); +} diff --git a/src/DFRobot_C4001.cpp b/src/DFRobot_C4001.cpp new file mode 100644 index 0000000..76d11f3 --- /dev/null +++ b/src/DFRobot_C4001.cpp @@ -0,0 +1,814 @@ +/*! + * @file DFRobot_C4001.cpp + * @brief Define the basic structure of the DFRobot_C4001 class, the implementation of the basic methods + * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com) + * @license The MIT License (MIT) + * @author [ZhixinLiu](zhixin.liu@dfrobot.com) + * @version V1.0 + * @date 2024-02-02 + * @url https://github.com/DFRobot/DFRobot_C4001 + */ +#include "DFRobot_C4001.h" + +DFRobot_C4001::DFRobot_C4001() {} +DFRobot_C4001::~DFRobot_C4001() {} + +sSensorStatus_t DFRobot_C4001::getStatus(void) +{ + sSensorStatus_t data; + uint8_t temp[100] = { 0 }; + uint8_t len = 0; + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp = 0; + readReg(REG_STATUS, &temp, (uint8_t)1); + data.workStatus = (temp & 0x01); + data.workMode = (temp & 0x02) >> 1; + data.initStatus = (temp & 0x80) >> 7; + } + else { + sAllData_t allData; + readReg(0, temp, 100); + writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); + while (len == 0) { + usleep(1000); + len = readReg(0, temp, 100); + allData = anaysisData(temp, len); + } + data.workStatus = allData.sta.workStatus; + data.workMode = allData.sta.workMode; + data.initStatus = allData.sta.initStatus; + } + return data; +} + +bool DFRobot_C4001::motionDetection(void) +{ + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp = 0; + readReg(REG_RESULT_STATUS, &temp, (uint8_t)1); + if (temp & 0x01) { + return true; + } + return false; + } + else { + static bool old = false; + uint8_t status = 0; + uint8_t len = 0; + uint8_t temp[100] = { 0 }; + sAllData_t data; + len = readReg(0, temp, 100); + data = anaysisData(temp, len); + if (data.exist) { + old = (bool)status; + return (bool)data.exist; + } + else { + return (bool)old; + } + } +} + +void DFRobot_C4001::setSensor(eSetMode_t mode) +{ + uint8_t temp = mode; + if (uartI2CFlag == I2C_FLAG) { + if (mode == eStartSen) { + writeReg(REG_CTRL0, &temp, (uint8_t)1); + usleep(200); // must timer + } + else if (mode == eStopSen) { + writeReg(REG_CTRL0, &temp, (uint8_t)1); + usleep(200); // must timer + } + else if (mode == eResetSen) { + writeReg(REG_CTRL0, &temp, (uint8_t)1); + usleep(1500); // must timer + } + else if (mode == eSaveParams) { + writeReg(REG_CTRL1, &temp, (uint8_t)1); + usleep(500); // must timer + } + else if (mode == eRecoverSen) { + writeReg(REG_CTRL1, &temp, (uint8_t)1); + usleep(800); // must timer + } + else if (mode == eChangeMode) { + writeReg(REG_CTRL1, &temp, (uint8_t)1); + usleep(1500); // must timer + } + } + else { + if (mode == eStartSen) { + writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); + usleep(200); // must timer + } + else if (mode == eStopSen) { + writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); + usleep(200); // must timer + } + else if (mode == eResetSen) { + writeReg(0, (uint8_t*)RESET_SENSOR, strlen(RESET_SENSOR)); + usleep(1500); // must timer + } + else if (mode == eSaveParams) { + writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); + usleep(200); // must timer + writeReg(0, (uint8_t*)SAVE_CONFIG, strlen(SAVE_CONFIG)); + usleep(800); // must timer + writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); + } + else if (mode == eRecoverSen) { + writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); + usleep(200); + writeReg(0, (uint8_t*)RECOVER_SENSOR, strlen(RECOVER_SENSOR)); + usleep(800); // must timer + writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); + usleep(500); + } + } +} + +bool DFRobot_C4001::setSensorMode(eMode_t mode) +{ + if (uartI2CFlag == I2C_FLAG) { + sSensorStatus_t data; + data = getStatus(); + if (data.workMode == mode) { + return true; + } + else { + setSensor(eChangeMode); + data = getStatus(); + if (data.workMode == mode) { + return true; + } + else { + return false; + } + } + } + else { + sensorStop(); + if (mode == eExitMode) { + writeReg(0, (uint8_t*)EXIST_MODE, strlen(EXIST_MODE)); + usleep(50); + } + else { + writeReg(0, (uint8_t*)SPEED_MODE, strlen(SPEED_MODE)); + usleep(50); + } + usleep(50); + writeReg(0, (uint8_t*)SAVE_CONFIG, strlen(SAVE_CONFIG)); + usleep(500); + writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); + usleep(100); + return true; + } +} + +bool DFRobot_C4001::setTrigSensitivity(uint8_t sensitivity) +{ + uint8_t temp = sensitivity; + if (sensitivity > 9) { + return false; + } + if (uartI2CFlag == I2C_FLAG) { + writeReg(REG_TRIG_SENSITIVITY, &temp, (uint8_t)1); + setSensor(eSaveParams); + return true; + } + else { + std::string data = "setSensitivity 255 1"; + data[19] = sensitivity + 0x30; + writeCMD(data, data, (uint8_t)1); + return true; + } +} + +uint8_t DFRobot_C4001::getTrigSensitivity(void) +{ + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp = 0; + readReg(REG_TRIG_SENSITIVITY, &temp, (uint8_t)1); + return temp; + } + else { + sResponseData_t responseData; + uint8_t temp[100] = { 0 }; + readReg(0, temp, 100); + std::string data = "getSensitivity"; + responseData = wRCMD(data, (uint8_t)1); + if (responseData.status) { + return responseData.response1; + } + return 0; + } +} + +bool DFRobot_C4001::setKeepSensitivity(uint8_t sensitivity) +{ + uint8_t temp = sensitivity; + if (sensitivity > 9) { + return false; + } + if (uartI2CFlag == I2C_FLAG) { + writeReg(REG_KEEP_SENSITIVITY, &temp, (uint8_t)1); + setSensor(eSaveParams); + return true; + } + else { + std::string data = "setSensitivity 1 255"; + data[15] = sensitivity + 0x30; + writeCMD(data, data, (uint8_t)1); + return true; + } +} + +uint8_t DFRobot_C4001::getKeepSensitivity(void) +{ + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp = 0; + readReg(REG_KEEP_SENSITIVITY, &temp, (uint8_t)1); + return temp; + } + else { + sResponseData_t responseData; + uint8_t temp[100] = { 0 }; + readReg(0, temp, 100); + std::string data = "getSensitivity"; + responseData = wRCMD(data, (uint8_t)1); + if (responseData.status) { + return responseData.response2; + } + return 0; + } +} + +bool DFRobot_C4001::setDelay(uint8_t trig, uint16_t keep) +{ + if (trig > 200) { + return false; + } + if (keep < 4 || keep > 3000) { + return false; + } + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp[3] = { 0 }; + temp[0] = trig; + temp[1] = keep; + temp[2] = keep >> 8; + writeReg(REG_TRIG_DELAY, temp, (uint8_t)3); + setSensor(eSaveParams); + return true; + } + else { + std::string data = "setLatency "; + data += std::string((float)trig * 0.01, 1); + data += " "; + data += std::string((float)keep * 0.5, 1); + writeCMD(data, data, (uint8_t)1); + return true; + } +} + +uint8_t DFRobot_C4001::getTrigDelay(void) +{ + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp = 0; + readReg(REG_TRIG_DELAY, &temp, (uint8_t)1); + return temp; + } + else { + sResponseData_t responseData; + std::string data = "getLatency"; + responseData = wRCMD(data, (uint8_t)1); + if (responseData.status) { + return responseData.response1 * 100; + } + return 0; + } +} + +uint16_t DFRobot_C4001::getKeepTimerout(void) +{ + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp[2] = { 0 }; + readReg(REG_KEEP_TIMEOUT_L, temp, (uint8_t)2); + return (((uint16_t)temp[1]) << 8) | temp[0]; + } + else { + sResponseData_t responseData; + std::string data = "getLatency"; + responseData = wRCMD(data, (uint8_t)2); + if (responseData.status) { + return responseData.response2 * 2; + } + return 0; + } +} + +bool DFRobot_C4001::setDetectionRange(uint16_t min, uint16_t max, uint16_t trig) +{ + if (max < 240 || max > 2000) { + return false; + } + if (min < 30 || min > max) { + return false; + } + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp[10] = { 0 }; + temp[0] = (uint8_t)(min); + temp[1] = (uint8_t)(min >> 8); + temp[2] = (uint8_t)(max); + temp[3] = (uint8_t)(max >> 8); + temp[4] = (uint8_t)(trig); + temp[5] = (uint8_t)(trig >> 8); + writeReg(REG_E_MIN_RANGE_L, temp, (uint8_t)6); + setSensor(eSaveParams); + return true; + } + else { + std::string data1 = "setRange "; + std::string data2 = "setTrigRange "; + data1 += std::string(((float)min) / 100.0, 1); + data1 += " "; + data1 += std::string(((float)max) / 100.0, 1); + data2 += std::string(((float)trig) / 100.0, 1); + writeCMD(data1, data2, (uint8_t)2); + return true; + } +} + +uint16_t DFRobot_C4001::getTrigRange(void) +{ + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp[4] = { 0 }; + readReg(REG_E_TRIG_RANGE_L, temp, (uint8_t)2); + return (uint16_t)(temp[0] | ((uint16_t)temp[1]) << 8); + } + else { + sResponseData_t responseData; + std::string data = "getTrigRange"; + responseData = wRCMD(data, (uint8_t)1); + if (responseData.status) { + return responseData.response1 * 100; + } + return 0; + } +} + +uint16_t DFRobot_C4001::getMaxRange(void) +{ + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp[4] = { 0 }; + readReg(REG_E_MAX_RANGE_L, temp, (uint8_t)2); + return (uint16_t)(temp[0] | ((uint16_t)temp[1]) << 8); + } + else { + sResponseData_t responseData; + std::string data = "getRange"; + responseData = wRCMD(data, (uint8_t)2); + if (responseData.status) { + return responseData.response2 * 100; + } + return 0; + } +} + +uint16_t DFRobot_C4001::getMinRange(void) +{ + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp[4] = { 0 }; + readReg(REG_E_MIN_RANGE_L, temp, (uint8_t)2); + return (uint16_t)(temp[0] | ((uint16_t)temp[1]) << 8); + } + else { + sResponseData_t responseData; + std::string data = "getRange"; + responseData = wRCMD(data, (uint8_t)2); + if (responseData.status) { + return responseData.response1 * 100; + } + return 0; + } +} + +uint8_t DFRobot_C4001::getTargetNumber(void) +{ + static uint8_t flash_number = 0; + uint8_t temp[10] = { 0 }; + if (uartI2CFlag == I2C_FLAG) { + readReg(REG_RESULT_OBJ_MUN, temp, (uint8_t)7); + if (temp[0] == 1) { + flash_number = 0; + _buffer.number = 1; + _buffer.range = (float)(int16_t((uint16_t)(temp[1] | ((uint16_t)temp[2]) << 8))) / 100.0; + _buffer.speed = (float)(int16_t((uint16_t)(temp[3] | ((uint16_t)temp[4]) << 8))) / 100.0; + _buffer.energy = (uint16_t)(temp[5] | ((uint16_t)temp[6]) << 8); + } + else { + if (flash_number++ > 10) { + _buffer.number = 0; + _buffer.range = 0; + _buffer.speed = 0; + _buffer.energy = 0; + } + } + return _buffer.number; + } + else { + uint8_t len = 0; + uint8_t temp[100] = { 0 }; + sAllData_t data; + len = readReg(0, temp, 100); + data = anaysisData(temp, len); + if (data.target.number != 0) { + flash_number = 0; + _buffer.number = data.target.number; + _buffer.range = data.target.range / 100.0; + _buffer.speed = data.target.speed / 100.0; + _buffer.energy = data.target.energy; + } + else { + _buffer.number = 1; + if (flash_number++ > 10) { + _buffer.number = 0; + _buffer.range = 0; + _buffer.speed = 0; + _buffer.energy = 0; + } + } + return data.target.number; + } +} + +float DFRobot_C4001::getTargetSpeed(void) +{ + return _buffer.speed; +} + +float DFRobot_C4001::getTargetRange(void) +{ + return _buffer.range; +} + +uint32_t DFRobot_C4001::getTargetEnergy(void) +{ + return _buffer.energy; +} + +bool DFRobot_C4001::setDetectThres(uint16_t min, uint16_t max, uint16_t thres) +{ + if (max > 2500) { + return false; + } + if (min > max) { + return false; + } + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp[10] = { 0 }; + temp[0] = (uint8_t)(thres); + temp[1] = (uint8_t)(thres >> 8); + temp[2] = (uint8_t)(min); + temp[3] = (uint8_t)(min >> 8); + temp[4] = (uint8_t)(max); + temp[5] = (uint8_t)(max >> 8); + writeReg(REG_CFAR_THR_L, temp, (uint8_t)6); + setSensor(eSaveParams); + return true; + } + else { + std::string data1 = "setRange "; + std::string data2 = "setThrFactor "; + data1 += std::string(((float)min) / 100.0, 1); + data1 += " "; + data1 += std::string(((float)max) / 100.0, 1); + data2 += thres; + writeCMD(data1, data2, (uint8_t)2); + return true; + } +} + +bool DFRobot_C4001::setIoPolaity(uint8_t value) +{ + if (value > 1) { + return false; + } + if (uartI2CFlag == I2C_FLAG) { + return true; + } + else { + std::string data = "setGpioMode 1 "; + data += value; + writeCMD(data, data, (uint8_t)1); + return true; + } +} + +uint8_t DFRobot_C4001::getIoPolaity(void) +{ + if (uartI2CFlag == I2C_FLAG) { + return 0; + } + else { + sResponseData_t responseData; + std::string data = "getGpioMode 1"; + responseData = wRCMD(data, (uint8_t)2); + if (responseData.status) { + return responseData.response2; + } + return 0; + } +} + +bool DFRobot_C4001::setPwm(uint8_t pwm1, uint8_t pwm2, uint8_t timer) +{ + if (pwm1 > 100 || pwm2 > 100) { + return false; + } + if (uartI2CFlag == I2C_FLAG) { + return true; + } + else { + std::string data = "setPwm "; + data += pwm1; + data += " "; + data += pwm2; + data += " "; + data += timer; + writeCMD(data, data, (uint8_t)1); + return true; + } +} + +sPwmData_t DFRobot_C4001::getPwm(void) +{ + sPwmData_t pwmData; + memset(&pwmData, 0, sizeof(sPwmData_t)); + if (uartI2CFlag == I2C_FLAG) { + return pwmData; + } + else { + sResponseData_t responseData; + std::string data = "getPwm"; + responseData = wRCMD(data, (uint8_t)3); + if (responseData.status) { + pwmData.pwm1 = responseData.response1; + pwmData.pwm2 = responseData.response2; + pwmData.timer = responseData.response3; + } + return pwmData; + } +} + +uint16_t DFRobot_C4001::getTMinRange(void) +{ + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp[4] = { 0 }; + readReg(REG_T_MIN_RANGE_L, temp, (uint8_t)2); + return (uint16_t)(temp[0] | ((uint16_t)temp[1]) << 8); + } + else { + sResponseData_t responseData; + std::string data = "getRange"; + responseData = wRCMD(data, (uint8_t)1); + if (responseData.status) { + return responseData.response1 * 100; + } + return 0; + } +} + +uint16_t DFRobot_C4001::getTMaxRange(void) +{ + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp[4] = { 0 }; + readReg(REG_T_MAX_RANGE_L, temp, (uint8_t)2); + return (uint16_t)(temp[0] | ((uint16_t)temp[1]) << 8); + } + else { + sResponseData_t responseData; + std::string data = "getRange"; + responseData = wRCMD(data, (uint8_t)2); + if (responseData.status) { + return responseData.response2 * 100; + } + return 0; + } +} + +uint16_t DFRobot_C4001::getThresRange(void) +{ + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp[4] = { 0 }; + readReg(REG_CFAR_THR_L, temp, (uint8_t)2); + return (uint16_t)(temp[0] | ((uint16_t)temp[1]) << 8); + } + else { + sResponseData_t responseData; + std::string data = "getThrFactor"; + responseData = wRCMD(data, (uint8_t)1); + if (responseData.status) { + return responseData.response1; + } + return 0; + } +} + +void DFRobot_C4001::setFrettingDetection(eSwitch_t sta) +{ + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp = sta; + writeReg(REG_MICRO_MOTION, &temp, (uint8_t)1); + setSensor(eSaveParams); + } + else { + std::string data = "setMicroMotion "; + data += sta; + writeCMD(data, data, (uint8_t)1); + } +} + +eSwitch_t DFRobot_C4001::getFrettingDetection(void) +{ + if (uartI2CFlag == I2C_FLAG) { + uint8_t temp = 0; + readReg(REG_MICRO_MOTION, &temp, (uint8_t)1); + return (eSwitch_t)temp; + } + else { + sResponseData_t responseData; + std::string data = "getMicroMotion"; + responseData = wRCMD(data, (uint8_t)1); + if (responseData.status) { + return (eSwitch_t)responseData.response1; + } + return (eSwitch_t)0; + } +} + +sResponseData_t DFRobot_C4001::anaysisResponse(uint8_t* data, uint8_t len, uint8_t count) +{ + sResponseData_t responseData; + uint8_t space[5] = { 0 }; + uint8_t i = 0; + uint8_t j = 0; + for (i = 0; i < len; i++) { + if (data[i] == 'R' && data[i + 1] == 'e' && data[i + 2] == 's') { + break; + } + } + if (i == len || i == 0) { + responseData.status = false; + } + else { + responseData.status = true; + for (j = 0; i < len; i++) { + if (data[i] == ' ') { + space[j++] = i + 1; + } + } + if (j != 0) { + responseData.response1 = atof((const char*)(data + space[0])); + if (j >= 2) { + responseData.response2 = atof((const char*)(data + space[1])); + } + if (count == 3) { + responseData.response3 = atof((const char*)(data + space[2])); + } + } + else { + responseData.response1 = 0.0; + responseData.response2 = 0.0; + } + } + return responseData; +} + +sAllData_t DFRobot_C4001::anaysisData(uint8_t* data, uint8_t len) +{ + sAllData_t allData; + uint8_t location = 0; + memset(&allData, 0, sizeof(sAllData_t)); + for (uint8_t i = 0; i < len; i++) { + if (data[i] == '$') { + location = i; + break; + } + } + if (location == len) { + return allData; + } + if (0 == strncmp((const char*)(data + location), "$DFHPD", strlen("$DFHPD"))) { + allData.sta.workMode = eExitMode; + allData.sta.workStatus = 1; + allData.sta.initStatus = 1; + if (data[location + 7] == '1') { + allData.exist = 1; + } + else { + allData.exist = 0; + } + } + else if (0 == strncmp((const char*)(data + location), "$DFDMD", strlen("$DFDMD"))) { + // $DFDMD,par1,par2,par3,par4,par5,par6,par7* + allData.sta.workMode = eSpeedMode; + allData.sta.workStatus = 1; + allData.sta.initStatus = 1; + char* token; + char* parts[10]; // Let's say there are at most 10 parts + int index = 0; // Used to track the number of parts stored + token = strtok((char*)(data + location), ","); + while (token != NULL) { + parts[index] = token; // Stores partial Pointers in an array + if (index++ > 8) { + break; + } + token = strtok(NULL, ","); // Continue to extract the next section + } + allData.target.number = atoi(parts[1]); + allData.target.range = atof(parts[3]) * 100; + allData.target.speed = atof(parts[4]) * 100; + allData.target.energy = atof(parts[5]); + } + else { + } + return allData; +} + +sResponseData_t DFRobot_C4001::wRCMD(std::string cmd1, uint8_t count) +{ + uint8_t len = 0; + uint8_t temp[200] = { 0 }; + sResponseData_t responseData; + sensorStop(); + writeReg(0, (uint8_t*)cmd1.c_str(), cmd1.length()); + usleep(100); + len = readReg(0, temp, 200); + responseData = anaysisResponse(temp, len, count); + usleep(100); + writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); + usleep(100); + return responseData; +} + +void DFRobot_C4001::writeCMD(std::string cmd1, std::string cmd2, uint8_t count) +{ + sensorStop(); + writeReg(0, (uint8_t*)cmd1.c_str(), cmd1.length()); + usleep(100); + if (count > 1) { + usleep(100); + writeReg(0, (uint8_t*)cmd2.c_str(), cmd2.length()); + usleep(100); + } + writeReg(0, (uint8_t*)SAVE_CONFIG, strlen(SAVE_CONFIG)); + usleep(100); + writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); + usleep(100); +} + +bool DFRobot_C4001::sensorStop(void) +{ + uint8_t len = 0; + uint8_t temp[200] = { 0 }; + writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); + usleep(1000); + len = readReg(0, temp, 200); + while (1) { + if (len != 0) { + if (strstr((const char*)temp, "sensorStop") != NULL) { + return true; + } + } + memset(temp, 0, 200); + usleep(400); + writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); + len = readReg(0, temp, 200); + + } +} + +DFRobot_C4001_I2C::DFRobot_C4001_I2C(const char* deviceName, uint8_t addr) +{ + path = deviceName; + _addr = addr; + uartI2CFlag = I2C_FLAG; +} + +bool DFRobot_C4001_I2C::begin() +{ + i2c = new I2c(path.c_str()); + return (i2c->addressSet(_addr) > 0) ? true : false; +} + +void DFRobot_C4001_I2C::writeReg(uint8_t reg, uint8_t* data, uint8_t len) +{ + i2c->writeBlockData(reg, len, data); +} + +int16_t DFRobot_C4001_I2C::readReg(uint8_t reg, uint8_t* data, uint8_t len) +{ + return i2c->readBlock(reg, len, data); +} diff --git a/src/DFRobot_C4001.h b/src/DFRobot_C4001.h new file mode 100644 index 0000000..0d24d43 --- /dev/null +++ b/src/DFRobot_C4001.h @@ -0,0 +1,423 @@ +/*! + * @file DFRobot_C4001.h + * @brief Define the basic structure of the DFRobot_C4001 class, the implementation of the basic methods + * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com) + * @license The MIT License (MIT) + * @author [ZhixinLiu](zhixin.liu@dfrobot.com) + * @version V1.0 + * @date 2023-02-02 + * @url https://github.com/DFRobot/DFRobot_C4001 + */ +#ifndef __DFROBOT_C4001_H__ +#define __DFROBOT_C4001_H__ +#include +#include +#include +#include +#include "i2c.h" +#endif + + /** + * @struct sSensorStatus_t + * @brief sensor status + * @note sensor status + */ +typedef struct { + uint8_t workStatus; + uint8_t workMode; + uint8_t initStatus; +}sSensorStatus_t; + + +/** + * @struct sPrivateData_t + * @brief speed mode data + */ +typedef struct { + uint8_t number; + float speed; + float range; + uint32_t energy; +}sPrivateData_t; + +/** + * @struct sResponseData_t + * @brief response data + */ +typedef struct { + bool status; + float response1; + float response2; + float response3; +}sResponseData_t; + + +/** + * @struct sPwmData_t + * @brief config pwm data param + */ +typedef struct { + uint8_t pwm1; + uint8_t pwm2; + uint8_t timer; +}sPwmData_t; + +/** + * @struct sAllData_t + * @brief sensor return data + */ +typedef struct { + uint8_t exist; + sSensorStatus_t sta; + sPrivateData_t target; +}sAllData_t; + +/** + * @enum eMode_t + * @brief sensor work mode + */ +typedef enum { + eExitMode = 0x00, + eSpeedMode = 0x01, +}eMode_t; + +/** + * @enum eSwitch_t + * @brief Micromotion detection switch + */ +typedef enum { + eON = 0x01, + eOFF = 0x00, +}eSwitch_t; + +/** + * @enum eSetMode_t + * @brief Set parameters for the sensor working status + */ +typedef enum { + eStartSen = 0x55, + eStopSen = 0x33, + eResetSen = 0xCC, + eRecoverSen = 0xAA, + eSaveParams = 0x5C, + eChangeMode = 0x3B, +}eSetMode_t; + +class DFRobot_C4001 { +public: +#define DEVICE_ADDR_0 0x2A +#define DEVICE_ADDR_1 0x2B +#define TIME_OUT 0x64 ///< time out +#define I2C_FLAG 0x01 +#define UART_FLAG 0x02 + +#define REG_STATUS 0x00 +#define REG_CTRL0 0x01 +#define REG_CTRL1 0x02 +#define REG_SOFT_VERSION 0x03 +#define REG_RESULT_STATUS 0x10 +#define REG_TRIG_SENSITIVITY 0x20 +#define REG_KEEP_SENSITIVITY 0x21 +#define REG_TRIG_DELAY 0x22 +#define REG_KEEP_TIMEOUT_L 0x23 +#define REG_KEEP_TIMEOUT_H 0x24 +#define REG_E_MIN_RANGE_L 0x25 +#define REG_E_MIN_RANGE_H 0x26 +#define REG_E_MAX_RANGE_L 0x27 +#define REG_E_MAX_RANGE_H 0x28 +#define REG_E_TRIG_RANGE_L 0x29 +#define REG_E_TRIG_RANGE_H 0x2A + +#define REG_RESULT_OBJ_MUN 0x10 +#define REG_RESULT_RANGE_L 0x11 +#define REG_RESULT_RANGE_H 0x12 +#define REG_RESULT_SPEED_L 0x13 +#define REG_RESULT_SPEED_H 0x14 +#define REG_RESULT_ENERGY_L 0x15 +#define REG_RESULT_ENERGY_H 0x16 +#define REG_CFAR_THR_L 0x20 +#define REG_CFAR_THR_H 0x21 +#define REG_T_MIN_RANGE_L 0x22 +#define REG_T_MIN_RANGE_H 0x23 +#define REG_T_MAX_RANGE_L 0x24 +#define REG_T_MAX_RANGE_H 0x25 +#define REG_MICRO_MOTION 0x26 + +#define START_SENSOR "sensorStart" +#define STOP_SENSOR "sensorStop" +#define SAVE_CONFIG "saveConfig" +#define RECOVER_SENSOR "resetCfg" ///< factory data reset +#define RESET_SENSOR "resetSystem" ///< RESET_SENSOR +#define SPEED_MODE "setRunApp 1" +#define EXIST_MODE "setRunApp 0" + + DFRobot_C4001(); + ~DFRobot_C4001(); + uint8_t uartI2CFlag = 0; + /** + * @fn motionDetection + * @brief motion Detection + * @return true or false + */ + bool motionDetection(void); + + /** + * @fn setSensor + * @brief Set the Sensor object + * @param mode + * @n eStartSen start collect + * @n eStopSen stop collect + * @n eResetSen reset sensor + * @n eRecoverSen recover params + * @n eSaveParams save config + * @n eChangeMode chagne mode + */ + void setSensor(eSetMode_t mode); + + /** + * @fn setDelay + * @brief Set the Delay object + * @param trig Trigger delay, unit 0.01s, range 0~2s (0~200) + * @param keep Maintain the detection timeout, unit 0.5s, range 2~1500 seconds (4~3000) + * @return true or false + */ + bool setDelay(uint8_t trig, uint16_t keep); + + /** + * @fn getTrigDelay + * @brief Get the Trig Delay object + * @return uint8_t + */ + uint8_t getTrigDelay(void); + + /** + * @fn getKeepTimerout + * @brief get keep timer out + * @return uint16_t + */ + uint16_t getKeepTimerout(void); + + /** + * @fn getTrigRange + * @brief Get the Trig Range object + * @n The triggering distance, in cm, ranges from 2.4 to 20m (240 to 2000). + * @n The actual configuration range does not exceed the maximum and minimum detection distance. + * @return uint16_t + */ + uint16_t getTrigRange(void); + + /** + * @fn getMaxRange + * @brief Get the Max Range object + * @return uint16_t + */ + uint16_t getMaxRange(void); + + /** + * @fn getMinRange + * @brief Get the Min Range object + * @return uint16_t + */ + uint16_t getMinRange(void); + + /** + * @fn setDetectionRange + * @brief Set the Detection Range object + * @param min Detection range Minimum distance, unit cm, range 0.3~20m (30~2000), not exceeding max, otherwise the function is abnormal. + * @param max Detection range Maximum distance, unit cm, range 2.4~20m (240~2000) + * @param trig The trigger distance (unit: cm) ranges from 2.4 to 20m (240 to 2000). The actual configuration range does not exceed the maximum and minimum detection distance. + * @return true or false + */ + bool setDetectionRange(uint16_t min, uint16_t max, uint16_t trig); + + /** + * @fn setTrigSensitivity + * @brief Set trigger sensitivity, 0~9 + * @param sensitivity + * @return true or false + */ + bool setTrigSensitivity(uint8_t sensitivity); + + /** + * @fn setKeepSensitivity + * @brief Set the Keep Sensitivity object,0~9 + * @param sensitivity + * @return true or false + */ + bool setKeepSensitivity(uint8_t sensitivity); + + /** + * @fn getTrigSensitivity + * @brief Get the Trig Sensitivity object + * @return uint8_t + */ + uint8_t getTrigSensitivity(void); + + /** + * @fn getKeepSensitivity + * @brief Get the Keep Sensitivity object + * @return uint8_t + */ + uint8_t getKeepSensitivity(void); + + /** + * @fn getStatus + * @brief Get the Status object + * @return sSensorStatus_t + * @n workStatus + * @n 0 stop + * @n 1 start + * @n workMode + * @n 0 indicates presence detection + * @n 1 is speed measurement and ranging + * @n initStatus + * @n 0 not init + * @n 1 init success + */ + sSensorStatus_t getStatus(void); + + /** + * @fn setIoPolaity + * @brief Set the Io Polaity object + * @param value + * @n 0:Output low level when there is a target, output high level when there is no target + * @n 1: Output high level when there is a target, output low level when there is no target (default) + * @return true or false + */ + bool setIoPolaity(uint8_t value); + + /** + * @fn getIoPolaity + * @brief Get the Io Polaity object + * @return uint8_t The level of the signal output by the pin after the configured I/O port detects the target + */ + uint8_t getIoPolaity(void); + + /** + * @fn setPwm + * @brief Set the Pwm object + * @param pwm1 When no target is detected, the duty cycle of the output signal of the OUT pin ranges from 0 to 100 + * @param pwm2 After the target is detected, the duty cycle of the output signal of the OUT pin ranges from 0 to 100 + * @param timer timer The value ranges from 0 to 255, corresponding to timer x 64ms + * @n For example, timer=20, it takes 20*64ms=1.28s for the duty cycle to change from pwm1 to pwm2. + * @return true or false + */ + bool setPwm(uint8_t pwm1, uint8_t pwm2, uint8_t timer); + + + /** + * @fn getPwm + * @brief Get the Pwm object + * @return sPwmData_t + * @retval pwm1 When no target is detected, the duty cycle of the output signal of the OUT pin ranges from 0 to 100 + * @retval pwm2 After the target is detected, the duty cycle of the output signal of the OUT pin ranges from 0 to 100 + * @retval timer The value ranges from 0 to 255, corresponding to timer x 64ms + * @n For example, timer=20, it takes 20*64ms=1.28s for the duty cycle to change from pwm1 to pwm2. + */ + sPwmData_t getPwm(void); + + /** + * @fn setSensorMode + * @brief Set the Sensor Mode object + * @param mode + * @return true or false + */ + bool setSensorMode(eMode_t mode); + + /** + * @fn getTargetNumber + * @brief Get the Target Number object + * @return uint8_t + */ + uint8_t getTargetNumber(void); + + /** + * @fn getTargetSpeed + * @brief Get the Target Speed object + * @return float + */ + float getTargetSpeed(void); + + /** + * @fn getTargetRange + * @brief Get the Target Range object + * @return float + */ + float getTargetRange(void); + + /** + * @fn getTargetEnergy + * @brief Get the Target Energy object + * @return uint32_t + */ + uint32_t getTargetEnergy(void); + + /** + * @fn setDetectThres + * @brief Set the Detect Thres object + * @param min Detection range Minimum distance, unit cm, range 0.3~20m (30~2000), not exceeding max, otherwise the function is abnormal. + * @param max Detection range Maximum distance, unit cm, range 2.4~20m (240~2000) + * @param thres Target detection threshold, dimensionless unit 0.1, range 0~6553.5 (0~65535) + * @return true or false + */ + bool setDetectThres(uint16_t min, uint16_t max, uint16_t thres); + + /** + * @fn getTMinRange + * @brief get speed Min Range + * @return uint16_t + */ + uint16_t getTMinRange(void); + + /** + * @fn getTMaxRange + * @brief get speed Max Range + * @return uint16_t + */ + uint16_t getTMaxRange(void); + + /** + * @fn getThresRange + * @brief Get the Thres Range object + * @return uint16_t + */ + uint16_t getThresRange(void); + + /** + * @fn setFrettingDetection + * @brief Set the Fretting Detection object + * @param sta + */ + void setFrettingDetection(eSwitch_t sta); + + /** + * @fn getFrettingDetection + * @brief Get the Fretting Detection object + * @return eSwitch_t + */ + eSwitch_t getFrettingDetection(void); +protected: + sResponseData_t wRCMD(std::string cmd1, uint8_t count); + void writeCMD(std::string cmd1, std::string cmd2, uint8_t count); + sAllData_t anaysisData(uint8_t* data, uint8_t len); + sResponseData_t anaysisResponse(uint8_t* data, uint8_t len, uint8_t count); + bool sensorStop(void); + uint8_t _addr; +private: + uint8_t _M_Flag = 0; + sPrivateData_t _buffer; + virtual void writeReg(uint8_t reg, uint8_t* data, uint8_t len) = 0; + virtual int16_t readReg(uint8_t reg, uint8_t* data, uint8_t len) = 0; +}; + +class DFRobot_C4001_I2C :public DFRobot_C4001 { +public: + DFRobot_C4001_I2C(const char* deviceName, uint8_t addr = DEVICE_ADDR_0); + bool begin(void); +protected: + virtual void writeReg(uint8_t reg, uint8_t* data, uint8_t len); + virtual int16_t readReg(uint8_t reg, uint8_t* data, uint8_t len); +private: + I2c* i2c; + std::string path; +}; diff --git a/src/ofxGPIO.h b/src/ofxGPIO.h index 467dc03..3dcee60 100644 --- a/src/ofxGPIO.h +++ b/src/ofxGPIO.h @@ -47,12 +47,14 @@ using namespace LogHighLight; #include "mcp.h" #include "font.h" #include "readata.h" + /* only openframeworks */ #ifndef COMPILE_WITHOUT_OPENFRAMEWORKS #include "google_image.h" #include "gpio_state.h" #endif /* end OF */ + /* core high level */ #include "led.h" #include "oled.h" From f7424300cb234604321342b0ff07ef6f79b7a82e Mon Sep 17 00:00:00 2001 From: Bruno Herfst Date: Mon, 30 Sep 2024 11:10:02 +1000 Subject: [PATCH 3/9] Fixes #32 using reference instead of copy --- src/led.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/led.h b/src/led.h index 572bada..6e77d74 100644 --- a/src/led.h +++ b/src/led.h @@ -53,7 +53,7 @@ class LED { 215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 }; } - void setWS2801(int numLed, vector colors, int BRIGHTNESS){ + void setWS2801(int numLed, vector& colors, int BRIGHTNESS){ int a; uint8_t buffer0[1], buffer1[4]; srand(time(NULL)); @@ -105,7 +105,7 @@ class LED { } } - void setAPA102(int numLed, vector colors, int BRIGHTNESS){ + void setAPA102(int numLed, vector& colors, int BRIGHTNESS){ int a; uint8_t buffer0[1], buffer1[4]; srand(time(NULL)); From ac3574f94cf07452acbb5d41dcf18a1129375549 Mon Sep 17 00:00:00 2001 From: Bruno Herfst Date: Wed, 16 Oct 2024 18:32:02 +1100 Subject: [PATCH 4/9] Update main.cpp --- example-DfRobotC4001/src/main.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/example-DfRobotC4001/src/main.cpp b/example-DfRobotC4001/src/main.cpp index 44ec0e9..c8e8d60 100644 --- a/example-DfRobotC4001/src/main.cpp +++ b/example-DfRobotC4001/src/main.cpp @@ -5,7 +5,7 @@ class ofApp : public ofBaseApp { public: - DFRobot_C4001 MmSensor; + DFRobot_C4001* mmSensor; void setup() { @@ -16,15 +16,15 @@ class ofApp : public ofBaseApp */ mmSensor = new DFRobot_C4001_I2C("/dev/i2c-1", 0x2A); - mmSensor.begin(); - mmSensor.setSensorMode(eSpeedMode); - mmSensor.setDetectThres(30, 600, 10); - mmSensor.setFrettingDetection(eON); + mmSensor->begin(); + mmSensor->setSensorMode(eSpeedMode); + mmSensor->setDetectThres(30, 600, 10); + mmSensor->setFrettingDetection(eON); } void update(){ - if(mmSensor.getTargetNumber() > 0) { - ofLog() << MmSensor.getTargetRange(); + if(mmSensor->getTargetNumber() > 0) { + ofLog() << mmSensor->getTargetRange(); } } From 41eb203067db9d29d204e8c81393544eed65650d Mon Sep 17 00:00:00 2001 From: Bruno Herfst Date: Wed, 16 Oct 2024 18:41:09 +1100 Subject: [PATCH 5/9] OK done --- example-DfRobotC4001/src/main.cpp | 2 +- src/DFRobot_C4001.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example-DfRobotC4001/src/main.cpp b/example-DfRobotC4001/src/main.cpp index c8e8d60..422386d 100644 --- a/example-DfRobotC4001/src/main.cpp +++ b/example-DfRobotC4001/src/main.cpp @@ -5,7 +5,7 @@ class ofApp : public ofBaseApp { public: - DFRobot_C4001* mmSensor; + DFRobot_C4001_I2C* mmSensor; void setup() { diff --git a/src/DFRobot_C4001.h b/src/DFRobot_C4001.h index 0d24d43..27a126c 100644 --- a/src/DFRobot_C4001.h +++ b/src/DFRobot_C4001.h @@ -410,7 +410,7 @@ class DFRobot_C4001 { virtual int16_t readReg(uint8_t reg, uint8_t* data, uint8_t len) = 0; }; -class DFRobot_C4001_I2C :public DFRobot_C4001 { +class DFRobot_C4001_I2C : public DFRobot_C4001 { public: DFRobot_C4001_I2C(const char* deviceName, uint8_t addr = DEVICE_ADDR_0); bool begin(void); From c7952d8b7c592a4e93acc2d24ae110211715c365 Mon Sep 17 00:00:00 2001 From: Bruno Herfst Date: Thu, 17 Oct 2024 11:17:06 +1100 Subject: [PATCH 6/9] Fix DfRobot C4001 comms timing --- example-DfRobotC4001/src/main.cpp | 30 +++++++++-- src/DFRobot_C4001.cpp | 90 +++++++++++++++++++------------ src/DFRobot_C4001.h | 1 + 3 files changed, 85 insertions(+), 36 deletions(-) diff --git a/example-DfRobotC4001/src/main.cpp b/example-DfRobotC4001/src/main.cpp index 422386d..ef4b636 100644 --- a/example-DfRobotC4001/src/main.cpp +++ b/example-DfRobotC4001/src/main.cpp @@ -16,13 +16,37 @@ class ofApp : public ofBaseApp */ mmSensor = new DFRobot_C4001_I2C("/dev/i2c-1", 0x2A); - mmSensor->begin(); - mmSensor->setSensorMode(eSpeedMode); - mmSensor->setDetectThres(30, 600, 10); + while (!mmSensor->begin()){ + ofLog() << "Waiting to connect to sensor ..."; + usleep(1000); + } + + usleep(1000); + ofLog() << "setSensorMode..."; + + if (!mmSensor->setSensorMode(eSpeedMode)) + { + ofLog() << "Failed to setSensorMode"; + } + + usleep(1000); + ofLog() << "setDetectThres..."; + + if (!mmSensor->setDetectThres(30, 600, 10)) + { + ofLog() << "Failed to setDetectThres"; + } + + usleep(1000); + ofLog() << "setFrettingDetection..."; + mmSensor->setFrettingDetection(eON); + } void update(){ + usleep(1000); + ofLog() << "Getting Data..."; if(mmSensor->getTargetNumber() > 0) { ofLog() << mmSensor->getTargetRange(); } diff --git a/src/DFRobot_C4001.cpp b/src/DFRobot_C4001.cpp index 76d11f3..ea00233 100644 --- a/src/DFRobot_C4001.cpp +++ b/src/DFRobot_C4001.cpp @@ -10,8 +10,10 @@ */ #include "DFRobot_C4001.h" -DFRobot_C4001::DFRobot_C4001() {} -DFRobot_C4001::~DFRobot_C4001() {} +#define sleep(x) usleep(1000 * x) + +DFRobot_C4001::DFRobot_C4001() {}; +DFRobot_C4001::~DFRobot_C4001() {}; sSensorStatus_t DFRobot_C4001::getStatus(void) { @@ -75,56 +77,56 @@ void DFRobot_C4001::setSensor(eSetMode_t mode) if (uartI2CFlag == I2C_FLAG) { if (mode == eStartSen) { writeReg(REG_CTRL0, &temp, (uint8_t)1); - usleep(200); // must timer + sleep(200); // must timer } else if (mode == eStopSen) { writeReg(REG_CTRL0, &temp, (uint8_t)1); - usleep(200); // must timer + sleep(200); // must timer } else if (mode == eResetSen) { writeReg(REG_CTRL0, &temp, (uint8_t)1); - usleep(1500); // must timer + sleep(1500); // must timer } else if (mode == eSaveParams) { writeReg(REG_CTRL1, &temp, (uint8_t)1); - usleep(500); // must timer + sleep(500); // must timer } else if (mode == eRecoverSen) { writeReg(REG_CTRL1, &temp, (uint8_t)1); - usleep(800); // must timer + sleep(800); // must timer } else if (mode == eChangeMode) { writeReg(REG_CTRL1, &temp, (uint8_t)1); - usleep(1500); // must timer + sleep(1500); // must timer } } else { if (mode == eStartSen) { writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); - usleep(200); // must timer + sleep(200); // must timer } else if (mode == eStopSen) { writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); - usleep(200); // must timer + sleep(200); // must timer } else if (mode == eResetSen) { writeReg(0, (uint8_t*)RESET_SENSOR, strlen(RESET_SENSOR)); - usleep(1500); // must timer + sleep(1500); // must timer } else if (mode == eSaveParams) { writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); - usleep(200); // must timer + sleep(200); // must timer writeReg(0, (uint8_t*)SAVE_CONFIG, strlen(SAVE_CONFIG)); - usleep(800); // must timer + sleep(800); // must timer writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); } else if (mode == eRecoverSen) { writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); - usleep(200); + sleep(200); writeReg(0, (uint8_t*)RECOVER_SENSOR, strlen(RECOVER_SENSOR)); - usleep(800); // must timer + sleep(800); // must timer writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); - usleep(500); + sleep(500); } } } @@ -152,17 +154,17 @@ bool DFRobot_C4001::setSensorMode(eMode_t mode) sensorStop(); if (mode == eExitMode) { writeReg(0, (uint8_t*)EXIST_MODE, strlen(EXIST_MODE)); - usleep(50); + sleep(50); } else { writeReg(0, (uint8_t*)SPEED_MODE, strlen(SPEED_MODE)); - usleep(50); + sleep(50); } - usleep(50); + sleep(50); writeReg(0, (uint8_t*)SAVE_CONFIG, strlen(SAVE_CONFIG)); - usleep(500); + sleep(500); writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); - usleep(100); + sleep(100); return true; } } @@ -744,29 +746,30 @@ sResponseData_t DFRobot_C4001::wRCMD(std::string cmd1, uint8_t count) sResponseData_t responseData; sensorStop(); writeReg(0, (uint8_t*)cmd1.c_str(), cmd1.length()); - usleep(100); + sleep(100); len = readReg(0, temp, 200); responseData = anaysisResponse(temp, len, count); - usleep(100); + sleep(100); writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); - usleep(100); + sleep(100); return responseData; } void DFRobot_C4001::writeCMD(std::string cmd1, std::string cmd2, uint8_t count) { + ofLog() << cmd1 << " " << cmd2; sensorStop(); writeReg(0, (uint8_t*)cmd1.c_str(), cmd1.length()); - usleep(100); + sleep(100); if (count > 1) { - usleep(100); + sleep(100); writeReg(0, (uint8_t*)cmd2.c_str(), cmd2.length()); - usleep(100); + sleep(100); } writeReg(0, (uint8_t*)SAVE_CONFIG, strlen(SAVE_CONFIG)); - usleep(100); + sleep(100); writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); - usleep(100); + sleep(100); } bool DFRobot_C4001::sensorStop(void) @@ -774,7 +777,7 @@ bool DFRobot_C4001::sensorStop(void) uint8_t len = 0; uint8_t temp[200] = { 0 }; writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); - usleep(1000); + sleep(1000); len = readReg(0, temp, 200); while (1) { if (len != 0) { @@ -783,7 +786,7 @@ bool DFRobot_C4001::sensorStop(void) } } memset(temp, 0, 200); - usleep(400); + sleep(400); writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); len = readReg(0, temp, 200); @@ -792,15 +795,36 @@ bool DFRobot_C4001::sensorStop(void) DFRobot_C4001_I2C::DFRobot_C4001_I2C(const char* deviceName, uint8_t addr) { + i2c = nullptr; path = deviceName; _addr = addr; uartI2CFlag = I2C_FLAG; } +DFRobot_C4001_I2C::~DFRobot_C4001_I2C() +{ + if(i2c != nullptr) delete i2c; +} + bool DFRobot_C4001_I2C::begin() { - i2c = new I2c(path.c_str()); - return (i2c->addressSet(_addr) > 0) ? true : false; + ofLog() << "Creating Device: "<< path.c_str(); + if(i2c == nullptr) + i2c = new I2c(path.c_str()); + + if (i2c == nullptr) + { + ofLog() << "Failed to create the i2c device:" << path.c_str() << std::endl; + return false; + } + + bool bRes = (i2c->addressSet(_addr) > 0) ? true:false; + if(bRes == false) + { + ofLog() << "Failed to set the address " << _addr <<" of the i2c device" << std::endl; + delete i2c; + } + return bRes; } void DFRobot_C4001_I2C::writeReg(uint8_t reg, uint8_t* data, uint8_t len) diff --git a/src/DFRobot_C4001.h b/src/DFRobot_C4001.h index 27a126c..835bbbb 100644 --- a/src/DFRobot_C4001.h +++ b/src/DFRobot_C4001.h @@ -413,6 +413,7 @@ class DFRobot_C4001 { class DFRobot_C4001_I2C : public DFRobot_C4001 { public: DFRobot_C4001_I2C(const char* deviceName, uint8_t addr = DEVICE_ADDR_0); + ~DFRobot_C4001_I2C(); bool begin(void); protected: virtual void writeReg(uint8_t reg, uint8_t* data, uint8_t len); From 2f516d3b7fca84f2bb4ebd5dda7363d386e4033b Mon Sep 17 00:00:00 2001 From: Bruno Herfst Date: Thu, 17 Oct 2024 16:45:56 +1100 Subject: [PATCH 7/9] Better values --- example-DfRobotC4001/src/main.cpp | 7 ++++--- src/DFRobot_C4001.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/example-DfRobotC4001/src/main.cpp b/example-DfRobotC4001/src/main.cpp index ef4b636..7940b57 100644 --- a/example-DfRobotC4001/src/main.cpp +++ b/example-DfRobotC4001/src/main.cpp @@ -9,7 +9,7 @@ class ofApp : public ofBaseApp void setup() { - /* + /* * The Df Robot sensor has a switch * for address selection a maximum * of two sensors on I2C: address = 0x2A || 0x2B @@ -48,6 +48,7 @@ class ofApp : public ofBaseApp usleep(1000); ofLog() << "Getting Data..."; if(mmSensor->getTargetNumber() > 0) { + ofLog() << (int)mmSensor->getTargetNumber(); ofLog() << mmSensor->getTargetRange(); } } @@ -59,6 +60,6 @@ class ofApp : public ofBaseApp int main( ){ ofAppNoWindow w; - ofSetupOpenGL(&w,0,0, OF_WINDOW); - ofRunApp( new ofApp() ); + ofSetupOpenGL(&w,0,0, OF_WINDOW); + ofRunApp( new ofApp() ); } diff --git a/src/DFRobot_C4001.h b/src/DFRobot_C4001.h index 835bbbb..b6a135a 100644 --- a/src/DFRobot_C4001.h +++ b/src/DFRobot_C4001.h @@ -152,7 +152,7 @@ class DFRobot_C4001 { #define EXIST_MODE "setRunApp 0" DFRobot_C4001(); - ~DFRobot_C4001(); + virtual ~DFRobot_C4001(); uint8_t uartI2CFlag = 0; /** * @fn motionDetection From 93805e342e0728c2daa5c20bcad5f56e94f80663 Mon Sep 17 00:00:00 2001 From: Bruno Herfst Date: Tue, 22 Oct 2024 19:40:55 +1100 Subject: [PATCH 8/9] Add I2C tool to detect devices --- src/DFRobot_C4001.cpp | 11 ++++++----- src/i2c.cpp | 26 ++++++++++++++++++++++++++ src/i2c.h | 3 +++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/DFRobot_C4001.cpp b/src/DFRobot_C4001.cpp index ea00233..9bbfcbd 100644 --- a/src/DFRobot_C4001.cpp +++ b/src/DFRobot_C4001.cpp @@ -808,20 +808,21 @@ DFRobot_C4001_I2C::~DFRobot_C4001_I2C() bool DFRobot_C4001_I2C::begin() { - ofLog() << "Creating Device: "<< path.c_str(); - if(i2c == nullptr) + ofLog(OF_LOG_VERBOSE) << "Creating Device: "<< path.c_str(); + if(i2c == nullptr){ i2c = new I2c(path.c_str()); - + } + if (i2c == nullptr) { - ofLog() << "Failed to create the i2c device:" << path.c_str() << std::endl; + ofLog(OF_LOG_WARNING) << "Failed to create the i2c device:" << path.c_str() << std::endl; return false; } bool bRes = (i2c->addressSet(_addr) > 0) ? true:false; if(bRes == false) { - ofLog() << "Failed to set the address " << _addr <<" of the i2c device" << std::endl; + ofLog(OF_LOG_WARNING) << "Failed to set the address " << _addr <<" of the i2c device" << std::endl; delete i2c; } return bRes; diff --git a/src/i2c.cpp b/src/i2c.cpp index 46fc240..5e2fff2 100644 --- a/src/i2c.cpp +++ b/src/i2c.cpp @@ -4,6 +4,8 @@ #include #include #include "i2c.h" +#include +#include I2c::I2c(const char * deviceName) { @@ -129,3 +131,27 @@ uint16_t I2c::readBlock(uint8_t command, uint8_t size, uint8_t * data) return result; } +std::vector> I2c::getDevices(uint8_t start /*=0*/, uint8_t end /*128*/) +{ + std::vector> i2cDevices; + std::regex i2cPattern("/dev/i2c-\\d+"); + for (const auto& entry : std::filesystem::directory_iterator("/dev")) { + std::string path = entry.path().string(); + if (std::regex_match(path, i2cPattern)) { + int f = open(path.c_str(), O_RDWR); + if(f == -1) continue; + for(uint8_t address = 0; address <= end; ++address) { + int result = ioctl(f, I2C_SLAVE, address); + if(result == 0) { + int res = i2c_smbus_read_byte(f); + if (res >0) + { + i2cDevices.push_back(std::make_pair(path, address)); + } + } + } + close(f); + } + } + return i2cDevices; +} diff --git a/src/i2c.h b/src/i2c.h index 02ff786..ba73842 100644 --- a/src/i2c.h +++ b/src/i2c.h @@ -48,6 +48,9 @@ class I2c { addressSet(address); return tryReadByte(command); } + + static std::vector> getDevices(uint8_t start = 0, u_int8_t end = 128); + private: int fd; }; From bca863b59813fd3ff50b472befc8e1652efa54bf Mon Sep 17 00:00:00 2001 From: Vairn Date: Thu, 31 Oct 2024 11:10:11 +1100 Subject: [PATCH 9/9] Removed DFRobot_C4001 since it has it's own addon. --- example-DfRobotC4001/Makefile | 13 - example-DfRobotC4001/addons.make | 1 - example-DfRobotC4001/config.make | 141 ----- example-DfRobotC4001/src/main.cpp | 65 --- src/DFRobot_C4001.cpp | 839 ------------------------------ src/DFRobot_C4001.h | 424 --------------- 6 files changed, 1483 deletions(-) delete mode 100644 example-DfRobotC4001/Makefile delete mode 100644 example-DfRobotC4001/addons.make delete mode 100644 example-DfRobotC4001/config.make delete mode 100644 example-DfRobotC4001/src/main.cpp delete mode 100644 src/DFRobot_C4001.cpp delete mode 100644 src/DFRobot_C4001.h diff --git a/example-DfRobotC4001/Makefile b/example-DfRobotC4001/Makefile deleted file mode 100644 index 8d8e4c0..0000000 --- a/example-DfRobotC4001/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# Attempt to load a config.make file. -# If none is found, project defaults in config.project.make will be used. -ifneq ($(wildcard config.make),) - include config.make -endif - -# make sure the the OF_ROOT location is defined -ifndef OF_ROOT - OF_ROOT=$(realpath ../../..) -endif - -# call the project makefile! -include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk diff --git a/example-DfRobotC4001/addons.make b/example-DfRobotC4001/addons.make deleted file mode 100644 index 8300d55..0000000 --- a/example-DfRobotC4001/addons.make +++ /dev/null @@ -1 +0,0 @@ -ofxGPIO diff --git a/example-DfRobotC4001/config.make b/example-DfRobotC4001/config.make deleted file mode 100644 index 836fce7..0000000 --- a/example-DfRobotC4001/config.make +++ /dev/null @@ -1,141 +0,0 @@ -################################################################################ -# CONFIGURE PROJECT MAKEFILE (optional) -# This file is where we make project specific configurations. -################################################################################ - -################################################################################ -# OF ROOT -# The location of your root openFrameworks installation -# (default) OF_ROOT = ../../.. -################################################################################ -# OF_ROOT = ../../.. - -################################################################################ -# PROJECT ROOT -# The location of the project - a starting place for searching for files -# (default) PROJECT_ROOT = . (this directory) -# -################################################################################ -# PROJECT_ROOT = . - -################################################################################ -# PROJECT SPECIFIC CHECKS -# This is a project defined section to create internal makefile flags to -# conditionally enable or disable the addition of various features within -# this makefile. For instance, if you want to make changes based on whether -# GTK is installed, one might test that here and create a variable to check. -################################################################################ -# None - -################################################################################ -# PROJECT EXTERNAL SOURCE PATHS -# These are fully qualified paths that are not within the PROJECT_ROOT folder. -# Like source folders in the PROJECT_ROOT, these paths are subject to -# exlclusion via the PROJECT_EXLCUSIONS list. -# -# (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank) -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ -# PROJECT_EXTERNAL_SOURCE_PATHS = - -################################################################################ -# PROJECT EXCLUSIONS -# These makefiles assume that all folders in your current project directory -# and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations -# to look for source code. The any folders or files that match any of the -# items in the PROJECT_EXCLUSIONS list below will be ignored. -# -# Each item in the PROJECT_EXCLUSIONS list will be treated as a complete -# string unless teh user adds a wildcard (%) operator to match subdirectories. -# GNU make only allows one wildcard for matching. The second wildcard (%) is -# treated literally. -# -# (default) PROJECT_EXCLUSIONS = (blank) -# -# Will automatically exclude the following: -# -# $(PROJECT_ROOT)/bin% -# $(PROJECT_ROOT)/obj% -# $(PROJECT_ROOT)/%.xcodeproj -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ -# PROJECT_EXCLUSIONS = - -################################################################################ -# PROJECT LINKER FLAGS -# These flags will be sent to the linker when compiling the executable. -# -# (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs -# -# Note: Leave a leading space when adding list items with the += operator -# -# Currently, shared libraries that are needed are copied to the -# $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to -# add a runtime path to search for those shared libraries, since they aren't -# incorporated directly into the final executable application binary. -################################################################################ -# PROJECT_LDFLAGS=-Wl,-rpath=./libs - -################################################################################ -# PROJECT DEFINES -# Create a space-delimited list of DEFINES. The list will be converted into -# CFLAGS with the "-D" flag later in the makefile. -# -# (default) PROJECT_DEFINES = (blank) -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ -# PROJECT_DEFINES = - -################################################################################ -# PROJECT CFLAGS -# This is a list of fully qualified CFLAGS required when compiling for this -# project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS -# defined in your platform specific core configuration files. These flags are -# presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below. -# -# (default) PROJECT_CFLAGS = (blank) -# -# Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in -# your platform specific configuration file will be applied by default and -# further flags here may not be needed. -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ -# PROJECT_CFLAGS = - -################################################################################ -# PROJECT OPTIMIZATION CFLAGS -# These are lists of CFLAGS that are target-specific. While any flags could -# be conditionally added, they are usually limited to optimization flags. -# These flags are added BEFORE the PROJECT_CFLAGS. -# -# PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets. -# -# (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank) -# -# PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets. -# -# (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank) -# -# Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the -# PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration -# file will be applied by default and further optimization flags here may not -# be needed. -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ -# PROJECT_OPTIMIZATION_CFLAGS_RELEASE = -# PROJECT_OPTIMIZATION_CFLAGS_DEBUG = - -################################################################################ -# PROJECT COMPILERS -# Custom compilers can be set for CC and CXX -# (default) PROJECT_CXX = (blank) -# (default) PROJECT_CC = (blank) -# Note: Leave a leading space when adding list items with the += operator -################################################################################ -# PROJECT_CXX = -# PROJECT_CC = diff --git a/example-DfRobotC4001/src/main.cpp b/example-DfRobotC4001/src/main.cpp deleted file mode 100644 index 7940b57..0000000 --- a/example-DfRobotC4001/src/main.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "ofMain.h" -#include "ofAppNoWindow.h" -#include "DFRobot_C4001.h" - -class ofApp : public ofBaseApp -{ - public: - DFRobot_C4001_I2C* mmSensor; - - void setup() - { - /* - * The Df Robot sensor has a switch - * for address selection a maximum - * of two sensors on I2C: address = 0x2A || 0x2B - */ - - mmSensor = new DFRobot_C4001_I2C("/dev/i2c-1", 0x2A); - while (!mmSensor->begin()){ - ofLog() << "Waiting to connect to sensor ..."; - usleep(1000); - } - - usleep(1000); - ofLog() << "setSensorMode..."; - - if (!mmSensor->setSensorMode(eSpeedMode)) - { - ofLog() << "Failed to setSensorMode"; - } - - usleep(1000); - ofLog() << "setDetectThres..."; - - if (!mmSensor->setDetectThres(30, 600, 10)) - { - ofLog() << "Failed to setDetectThres"; - } - - usleep(1000); - ofLog() << "setFrettingDetection..."; - - mmSensor->setFrettingDetection(eON); - - } - - void update(){ - usleep(1000); - ofLog() << "Getting Data..."; - if(mmSensor->getTargetNumber() > 0) { - ofLog() << (int)mmSensor->getTargetNumber(); - ofLog() << mmSensor->getTargetRange(); - } - } - - void exit(){ - ofExit(0); - } -}; - -int main( ){ - ofAppNoWindow w; - ofSetupOpenGL(&w,0,0, OF_WINDOW); - ofRunApp( new ofApp() ); -} diff --git a/src/DFRobot_C4001.cpp b/src/DFRobot_C4001.cpp deleted file mode 100644 index 9bbfcbd..0000000 --- a/src/DFRobot_C4001.cpp +++ /dev/null @@ -1,839 +0,0 @@ -/*! - * @file DFRobot_C4001.cpp - * @brief Define the basic structure of the DFRobot_C4001 class, the implementation of the basic methods - * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com) - * @license The MIT License (MIT) - * @author [ZhixinLiu](zhixin.liu@dfrobot.com) - * @version V1.0 - * @date 2024-02-02 - * @url https://github.com/DFRobot/DFRobot_C4001 - */ -#include "DFRobot_C4001.h" - -#define sleep(x) usleep(1000 * x) - -DFRobot_C4001::DFRobot_C4001() {}; -DFRobot_C4001::~DFRobot_C4001() {}; - -sSensorStatus_t DFRobot_C4001::getStatus(void) -{ - sSensorStatus_t data; - uint8_t temp[100] = { 0 }; - uint8_t len = 0; - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp = 0; - readReg(REG_STATUS, &temp, (uint8_t)1); - data.workStatus = (temp & 0x01); - data.workMode = (temp & 0x02) >> 1; - data.initStatus = (temp & 0x80) >> 7; - } - else { - sAllData_t allData; - readReg(0, temp, 100); - writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); - while (len == 0) { - usleep(1000); - len = readReg(0, temp, 100); - allData = anaysisData(temp, len); - } - data.workStatus = allData.sta.workStatus; - data.workMode = allData.sta.workMode; - data.initStatus = allData.sta.initStatus; - } - return data; -} - -bool DFRobot_C4001::motionDetection(void) -{ - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp = 0; - readReg(REG_RESULT_STATUS, &temp, (uint8_t)1); - if (temp & 0x01) { - return true; - } - return false; - } - else { - static bool old = false; - uint8_t status = 0; - uint8_t len = 0; - uint8_t temp[100] = { 0 }; - sAllData_t data; - len = readReg(0, temp, 100); - data = anaysisData(temp, len); - if (data.exist) { - old = (bool)status; - return (bool)data.exist; - } - else { - return (bool)old; - } - } -} - -void DFRobot_C4001::setSensor(eSetMode_t mode) -{ - uint8_t temp = mode; - if (uartI2CFlag == I2C_FLAG) { - if (mode == eStartSen) { - writeReg(REG_CTRL0, &temp, (uint8_t)1); - sleep(200); // must timer - } - else if (mode == eStopSen) { - writeReg(REG_CTRL0, &temp, (uint8_t)1); - sleep(200); // must timer - } - else if (mode == eResetSen) { - writeReg(REG_CTRL0, &temp, (uint8_t)1); - sleep(1500); // must timer - } - else if (mode == eSaveParams) { - writeReg(REG_CTRL1, &temp, (uint8_t)1); - sleep(500); // must timer - } - else if (mode == eRecoverSen) { - writeReg(REG_CTRL1, &temp, (uint8_t)1); - sleep(800); // must timer - } - else if (mode == eChangeMode) { - writeReg(REG_CTRL1, &temp, (uint8_t)1); - sleep(1500); // must timer - } - } - else { - if (mode == eStartSen) { - writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); - sleep(200); // must timer - } - else if (mode == eStopSen) { - writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); - sleep(200); // must timer - } - else if (mode == eResetSen) { - writeReg(0, (uint8_t*)RESET_SENSOR, strlen(RESET_SENSOR)); - sleep(1500); // must timer - } - else if (mode == eSaveParams) { - writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); - sleep(200); // must timer - writeReg(0, (uint8_t*)SAVE_CONFIG, strlen(SAVE_CONFIG)); - sleep(800); // must timer - writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); - } - else if (mode == eRecoverSen) { - writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); - sleep(200); - writeReg(0, (uint8_t*)RECOVER_SENSOR, strlen(RECOVER_SENSOR)); - sleep(800); // must timer - writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); - sleep(500); - } - } -} - -bool DFRobot_C4001::setSensorMode(eMode_t mode) -{ - if (uartI2CFlag == I2C_FLAG) { - sSensorStatus_t data; - data = getStatus(); - if (data.workMode == mode) { - return true; - } - else { - setSensor(eChangeMode); - data = getStatus(); - if (data.workMode == mode) { - return true; - } - else { - return false; - } - } - } - else { - sensorStop(); - if (mode == eExitMode) { - writeReg(0, (uint8_t*)EXIST_MODE, strlen(EXIST_MODE)); - sleep(50); - } - else { - writeReg(0, (uint8_t*)SPEED_MODE, strlen(SPEED_MODE)); - sleep(50); - } - sleep(50); - writeReg(0, (uint8_t*)SAVE_CONFIG, strlen(SAVE_CONFIG)); - sleep(500); - writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); - sleep(100); - return true; - } -} - -bool DFRobot_C4001::setTrigSensitivity(uint8_t sensitivity) -{ - uint8_t temp = sensitivity; - if (sensitivity > 9) { - return false; - } - if (uartI2CFlag == I2C_FLAG) { - writeReg(REG_TRIG_SENSITIVITY, &temp, (uint8_t)1); - setSensor(eSaveParams); - return true; - } - else { - std::string data = "setSensitivity 255 1"; - data[19] = sensitivity + 0x30; - writeCMD(data, data, (uint8_t)1); - return true; - } -} - -uint8_t DFRobot_C4001::getTrigSensitivity(void) -{ - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp = 0; - readReg(REG_TRIG_SENSITIVITY, &temp, (uint8_t)1); - return temp; - } - else { - sResponseData_t responseData; - uint8_t temp[100] = { 0 }; - readReg(0, temp, 100); - std::string data = "getSensitivity"; - responseData = wRCMD(data, (uint8_t)1); - if (responseData.status) { - return responseData.response1; - } - return 0; - } -} - -bool DFRobot_C4001::setKeepSensitivity(uint8_t sensitivity) -{ - uint8_t temp = sensitivity; - if (sensitivity > 9) { - return false; - } - if (uartI2CFlag == I2C_FLAG) { - writeReg(REG_KEEP_SENSITIVITY, &temp, (uint8_t)1); - setSensor(eSaveParams); - return true; - } - else { - std::string data = "setSensitivity 1 255"; - data[15] = sensitivity + 0x30; - writeCMD(data, data, (uint8_t)1); - return true; - } -} - -uint8_t DFRobot_C4001::getKeepSensitivity(void) -{ - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp = 0; - readReg(REG_KEEP_SENSITIVITY, &temp, (uint8_t)1); - return temp; - } - else { - sResponseData_t responseData; - uint8_t temp[100] = { 0 }; - readReg(0, temp, 100); - std::string data = "getSensitivity"; - responseData = wRCMD(data, (uint8_t)1); - if (responseData.status) { - return responseData.response2; - } - return 0; - } -} - -bool DFRobot_C4001::setDelay(uint8_t trig, uint16_t keep) -{ - if (trig > 200) { - return false; - } - if (keep < 4 || keep > 3000) { - return false; - } - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp[3] = { 0 }; - temp[0] = trig; - temp[1] = keep; - temp[2] = keep >> 8; - writeReg(REG_TRIG_DELAY, temp, (uint8_t)3); - setSensor(eSaveParams); - return true; - } - else { - std::string data = "setLatency "; - data += std::string((float)trig * 0.01, 1); - data += " "; - data += std::string((float)keep * 0.5, 1); - writeCMD(data, data, (uint8_t)1); - return true; - } -} - -uint8_t DFRobot_C4001::getTrigDelay(void) -{ - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp = 0; - readReg(REG_TRIG_DELAY, &temp, (uint8_t)1); - return temp; - } - else { - sResponseData_t responseData; - std::string data = "getLatency"; - responseData = wRCMD(data, (uint8_t)1); - if (responseData.status) { - return responseData.response1 * 100; - } - return 0; - } -} - -uint16_t DFRobot_C4001::getKeepTimerout(void) -{ - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp[2] = { 0 }; - readReg(REG_KEEP_TIMEOUT_L, temp, (uint8_t)2); - return (((uint16_t)temp[1]) << 8) | temp[0]; - } - else { - sResponseData_t responseData; - std::string data = "getLatency"; - responseData = wRCMD(data, (uint8_t)2); - if (responseData.status) { - return responseData.response2 * 2; - } - return 0; - } -} - -bool DFRobot_C4001::setDetectionRange(uint16_t min, uint16_t max, uint16_t trig) -{ - if (max < 240 || max > 2000) { - return false; - } - if (min < 30 || min > max) { - return false; - } - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp[10] = { 0 }; - temp[0] = (uint8_t)(min); - temp[1] = (uint8_t)(min >> 8); - temp[2] = (uint8_t)(max); - temp[3] = (uint8_t)(max >> 8); - temp[4] = (uint8_t)(trig); - temp[5] = (uint8_t)(trig >> 8); - writeReg(REG_E_MIN_RANGE_L, temp, (uint8_t)6); - setSensor(eSaveParams); - return true; - } - else { - std::string data1 = "setRange "; - std::string data2 = "setTrigRange "; - data1 += std::string(((float)min) / 100.0, 1); - data1 += " "; - data1 += std::string(((float)max) / 100.0, 1); - data2 += std::string(((float)trig) / 100.0, 1); - writeCMD(data1, data2, (uint8_t)2); - return true; - } -} - -uint16_t DFRobot_C4001::getTrigRange(void) -{ - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp[4] = { 0 }; - readReg(REG_E_TRIG_RANGE_L, temp, (uint8_t)2); - return (uint16_t)(temp[0] | ((uint16_t)temp[1]) << 8); - } - else { - sResponseData_t responseData; - std::string data = "getTrigRange"; - responseData = wRCMD(data, (uint8_t)1); - if (responseData.status) { - return responseData.response1 * 100; - } - return 0; - } -} - -uint16_t DFRobot_C4001::getMaxRange(void) -{ - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp[4] = { 0 }; - readReg(REG_E_MAX_RANGE_L, temp, (uint8_t)2); - return (uint16_t)(temp[0] | ((uint16_t)temp[1]) << 8); - } - else { - sResponseData_t responseData; - std::string data = "getRange"; - responseData = wRCMD(data, (uint8_t)2); - if (responseData.status) { - return responseData.response2 * 100; - } - return 0; - } -} - -uint16_t DFRobot_C4001::getMinRange(void) -{ - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp[4] = { 0 }; - readReg(REG_E_MIN_RANGE_L, temp, (uint8_t)2); - return (uint16_t)(temp[0] | ((uint16_t)temp[1]) << 8); - } - else { - sResponseData_t responseData; - std::string data = "getRange"; - responseData = wRCMD(data, (uint8_t)2); - if (responseData.status) { - return responseData.response1 * 100; - } - return 0; - } -} - -uint8_t DFRobot_C4001::getTargetNumber(void) -{ - static uint8_t flash_number = 0; - uint8_t temp[10] = { 0 }; - if (uartI2CFlag == I2C_FLAG) { - readReg(REG_RESULT_OBJ_MUN, temp, (uint8_t)7); - if (temp[0] == 1) { - flash_number = 0; - _buffer.number = 1; - _buffer.range = (float)(int16_t((uint16_t)(temp[1] | ((uint16_t)temp[2]) << 8))) / 100.0; - _buffer.speed = (float)(int16_t((uint16_t)(temp[3] | ((uint16_t)temp[4]) << 8))) / 100.0; - _buffer.energy = (uint16_t)(temp[5] | ((uint16_t)temp[6]) << 8); - } - else { - if (flash_number++ > 10) { - _buffer.number = 0; - _buffer.range = 0; - _buffer.speed = 0; - _buffer.energy = 0; - } - } - return _buffer.number; - } - else { - uint8_t len = 0; - uint8_t temp[100] = { 0 }; - sAllData_t data; - len = readReg(0, temp, 100); - data = anaysisData(temp, len); - if (data.target.number != 0) { - flash_number = 0; - _buffer.number = data.target.number; - _buffer.range = data.target.range / 100.0; - _buffer.speed = data.target.speed / 100.0; - _buffer.energy = data.target.energy; - } - else { - _buffer.number = 1; - if (flash_number++ > 10) { - _buffer.number = 0; - _buffer.range = 0; - _buffer.speed = 0; - _buffer.energy = 0; - } - } - return data.target.number; - } -} - -float DFRobot_C4001::getTargetSpeed(void) -{ - return _buffer.speed; -} - -float DFRobot_C4001::getTargetRange(void) -{ - return _buffer.range; -} - -uint32_t DFRobot_C4001::getTargetEnergy(void) -{ - return _buffer.energy; -} - -bool DFRobot_C4001::setDetectThres(uint16_t min, uint16_t max, uint16_t thres) -{ - if (max > 2500) { - return false; - } - if (min > max) { - return false; - } - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp[10] = { 0 }; - temp[0] = (uint8_t)(thres); - temp[1] = (uint8_t)(thres >> 8); - temp[2] = (uint8_t)(min); - temp[3] = (uint8_t)(min >> 8); - temp[4] = (uint8_t)(max); - temp[5] = (uint8_t)(max >> 8); - writeReg(REG_CFAR_THR_L, temp, (uint8_t)6); - setSensor(eSaveParams); - return true; - } - else { - std::string data1 = "setRange "; - std::string data2 = "setThrFactor "; - data1 += std::string(((float)min) / 100.0, 1); - data1 += " "; - data1 += std::string(((float)max) / 100.0, 1); - data2 += thres; - writeCMD(data1, data2, (uint8_t)2); - return true; - } -} - -bool DFRobot_C4001::setIoPolaity(uint8_t value) -{ - if (value > 1) { - return false; - } - if (uartI2CFlag == I2C_FLAG) { - return true; - } - else { - std::string data = "setGpioMode 1 "; - data += value; - writeCMD(data, data, (uint8_t)1); - return true; - } -} - -uint8_t DFRobot_C4001::getIoPolaity(void) -{ - if (uartI2CFlag == I2C_FLAG) { - return 0; - } - else { - sResponseData_t responseData; - std::string data = "getGpioMode 1"; - responseData = wRCMD(data, (uint8_t)2); - if (responseData.status) { - return responseData.response2; - } - return 0; - } -} - -bool DFRobot_C4001::setPwm(uint8_t pwm1, uint8_t pwm2, uint8_t timer) -{ - if (pwm1 > 100 || pwm2 > 100) { - return false; - } - if (uartI2CFlag == I2C_FLAG) { - return true; - } - else { - std::string data = "setPwm "; - data += pwm1; - data += " "; - data += pwm2; - data += " "; - data += timer; - writeCMD(data, data, (uint8_t)1); - return true; - } -} - -sPwmData_t DFRobot_C4001::getPwm(void) -{ - sPwmData_t pwmData; - memset(&pwmData, 0, sizeof(sPwmData_t)); - if (uartI2CFlag == I2C_FLAG) { - return pwmData; - } - else { - sResponseData_t responseData; - std::string data = "getPwm"; - responseData = wRCMD(data, (uint8_t)3); - if (responseData.status) { - pwmData.pwm1 = responseData.response1; - pwmData.pwm2 = responseData.response2; - pwmData.timer = responseData.response3; - } - return pwmData; - } -} - -uint16_t DFRobot_C4001::getTMinRange(void) -{ - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp[4] = { 0 }; - readReg(REG_T_MIN_RANGE_L, temp, (uint8_t)2); - return (uint16_t)(temp[0] | ((uint16_t)temp[1]) << 8); - } - else { - sResponseData_t responseData; - std::string data = "getRange"; - responseData = wRCMD(data, (uint8_t)1); - if (responseData.status) { - return responseData.response1 * 100; - } - return 0; - } -} - -uint16_t DFRobot_C4001::getTMaxRange(void) -{ - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp[4] = { 0 }; - readReg(REG_T_MAX_RANGE_L, temp, (uint8_t)2); - return (uint16_t)(temp[0] | ((uint16_t)temp[1]) << 8); - } - else { - sResponseData_t responseData; - std::string data = "getRange"; - responseData = wRCMD(data, (uint8_t)2); - if (responseData.status) { - return responseData.response2 * 100; - } - return 0; - } -} - -uint16_t DFRobot_C4001::getThresRange(void) -{ - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp[4] = { 0 }; - readReg(REG_CFAR_THR_L, temp, (uint8_t)2); - return (uint16_t)(temp[0] | ((uint16_t)temp[1]) << 8); - } - else { - sResponseData_t responseData; - std::string data = "getThrFactor"; - responseData = wRCMD(data, (uint8_t)1); - if (responseData.status) { - return responseData.response1; - } - return 0; - } -} - -void DFRobot_C4001::setFrettingDetection(eSwitch_t sta) -{ - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp = sta; - writeReg(REG_MICRO_MOTION, &temp, (uint8_t)1); - setSensor(eSaveParams); - } - else { - std::string data = "setMicroMotion "; - data += sta; - writeCMD(data, data, (uint8_t)1); - } -} - -eSwitch_t DFRobot_C4001::getFrettingDetection(void) -{ - if (uartI2CFlag == I2C_FLAG) { - uint8_t temp = 0; - readReg(REG_MICRO_MOTION, &temp, (uint8_t)1); - return (eSwitch_t)temp; - } - else { - sResponseData_t responseData; - std::string data = "getMicroMotion"; - responseData = wRCMD(data, (uint8_t)1); - if (responseData.status) { - return (eSwitch_t)responseData.response1; - } - return (eSwitch_t)0; - } -} - -sResponseData_t DFRobot_C4001::anaysisResponse(uint8_t* data, uint8_t len, uint8_t count) -{ - sResponseData_t responseData; - uint8_t space[5] = { 0 }; - uint8_t i = 0; - uint8_t j = 0; - for (i = 0; i < len; i++) { - if (data[i] == 'R' && data[i + 1] == 'e' && data[i + 2] == 's') { - break; - } - } - if (i == len || i == 0) { - responseData.status = false; - } - else { - responseData.status = true; - for (j = 0; i < len; i++) { - if (data[i] == ' ') { - space[j++] = i + 1; - } - } - if (j != 0) { - responseData.response1 = atof((const char*)(data + space[0])); - if (j >= 2) { - responseData.response2 = atof((const char*)(data + space[1])); - } - if (count == 3) { - responseData.response3 = atof((const char*)(data + space[2])); - } - } - else { - responseData.response1 = 0.0; - responseData.response2 = 0.0; - } - } - return responseData; -} - -sAllData_t DFRobot_C4001::anaysisData(uint8_t* data, uint8_t len) -{ - sAllData_t allData; - uint8_t location = 0; - memset(&allData, 0, sizeof(sAllData_t)); - for (uint8_t i = 0; i < len; i++) { - if (data[i] == '$') { - location = i; - break; - } - } - if (location == len) { - return allData; - } - if (0 == strncmp((const char*)(data + location), "$DFHPD", strlen("$DFHPD"))) { - allData.sta.workMode = eExitMode; - allData.sta.workStatus = 1; - allData.sta.initStatus = 1; - if (data[location + 7] == '1') { - allData.exist = 1; - } - else { - allData.exist = 0; - } - } - else if (0 == strncmp((const char*)(data + location), "$DFDMD", strlen("$DFDMD"))) { - // $DFDMD,par1,par2,par3,par4,par5,par6,par7* - allData.sta.workMode = eSpeedMode; - allData.sta.workStatus = 1; - allData.sta.initStatus = 1; - char* token; - char* parts[10]; // Let's say there are at most 10 parts - int index = 0; // Used to track the number of parts stored - token = strtok((char*)(data + location), ","); - while (token != NULL) { - parts[index] = token; // Stores partial Pointers in an array - if (index++ > 8) { - break; - } - token = strtok(NULL, ","); // Continue to extract the next section - } - allData.target.number = atoi(parts[1]); - allData.target.range = atof(parts[3]) * 100; - allData.target.speed = atof(parts[4]) * 100; - allData.target.energy = atof(parts[5]); - } - else { - } - return allData; -} - -sResponseData_t DFRobot_C4001::wRCMD(std::string cmd1, uint8_t count) -{ - uint8_t len = 0; - uint8_t temp[200] = { 0 }; - sResponseData_t responseData; - sensorStop(); - writeReg(0, (uint8_t*)cmd1.c_str(), cmd1.length()); - sleep(100); - len = readReg(0, temp, 200); - responseData = anaysisResponse(temp, len, count); - sleep(100); - writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); - sleep(100); - return responseData; -} - -void DFRobot_C4001::writeCMD(std::string cmd1, std::string cmd2, uint8_t count) -{ - ofLog() << cmd1 << " " << cmd2; - sensorStop(); - writeReg(0, (uint8_t*)cmd1.c_str(), cmd1.length()); - sleep(100); - if (count > 1) { - sleep(100); - writeReg(0, (uint8_t*)cmd2.c_str(), cmd2.length()); - sleep(100); - } - writeReg(0, (uint8_t*)SAVE_CONFIG, strlen(SAVE_CONFIG)); - sleep(100); - writeReg(0, (uint8_t*)START_SENSOR, strlen(START_SENSOR)); - sleep(100); -} - -bool DFRobot_C4001::sensorStop(void) -{ - uint8_t len = 0; - uint8_t temp[200] = { 0 }; - writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); - sleep(1000); - len = readReg(0, temp, 200); - while (1) { - if (len != 0) { - if (strstr((const char*)temp, "sensorStop") != NULL) { - return true; - } - } - memset(temp, 0, 200); - sleep(400); - writeReg(0, (uint8_t*)STOP_SENSOR, strlen(STOP_SENSOR)); - len = readReg(0, temp, 200); - - } -} - -DFRobot_C4001_I2C::DFRobot_C4001_I2C(const char* deviceName, uint8_t addr) -{ - i2c = nullptr; - path = deviceName; - _addr = addr; - uartI2CFlag = I2C_FLAG; -} - -DFRobot_C4001_I2C::~DFRobot_C4001_I2C() -{ - if(i2c != nullptr) delete i2c; -} - -bool DFRobot_C4001_I2C::begin() -{ - ofLog(OF_LOG_VERBOSE) << "Creating Device: "<< path.c_str(); - if(i2c == nullptr){ - i2c = new I2c(path.c_str()); - } - - if (i2c == nullptr) - { - ofLog(OF_LOG_WARNING) << "Failed to create the i2c device:" << path.c_str() << std::endl; - return false; - } - - bool bRes = (i2c->addressSet(_addr) > 0) ? true:false; - if(bRes == false) - { - ofLog(OF_LOG_WARNING) << "Failed to set the address " << _addr <<" of the i2c device" << std::endl; - delete i2c; - } - return bRes; -} - -void DFRobot_C4001_I2C::writeReg(uint8_t reg, uint8_t* data, uint8_t len) -{ - i2c->writeBlockData(reg, len, data); -} - -int16_t DFRobot_C4001_I2C::readReg(uint8_t reg, uint8_t* data, uint8_t len) -{ - return i2c->readBlock(reg, len, data); -} diff --git a/src/DFRobot_C4001.h b/src/DFRobot_C4001.h deleted file mode 100644 index b6a135a..0000000 --- a/src/DFRobot_C4001.h +++ /dev/null @@ -1,424 +0,0 @@ -/*! - * @file DFRobot_C4001.h - * @brief Define the basic structure of the DFRobot_C4001 class, the implementation of the basic methods - * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com) - * @license The MIT License (MIT) - * @author [ZhixinLiu](zhixin.liu@dfrobot.com) - * @version V1.0 - * @date 2023-02-02 - * @url https://github.com/DFRobot/DFRobot_C4001 - */ -#ifndef __DFROBOT_C4001_H__ -#define __DFROBOT_C4001_H__ -#include -#include -#include -#include -#include "i2c.h" -#endif - - /** - * @struct sSensorStatus_t - * @brief sensor status - * @note sensor status - */ -typedef struct { - uint8_t workStatus; - uint8_t workMode; - uint8_t initStatus; -}sSensorStatus_t; - - -/** - * @struct sPrivateData_t - * @brief speed mode data - */ -typedef struct { - uint8_t number; - float speed; - float range; - uint32_t energy; -}sPrivateData_t; - -/** - * @struct sResponseData_t - * @brief response data - */ -typedef struct { - bool status; - float response1; - float response2; - float response3; -}sResponseData_t; - - -/** - * @struct sPwmData_t - * @brief config pwm data param - */ -typedef struct { - uint8_t pwm1; - uint8_t pwm2; - uint8_t timer; -}sPwmData_t; - -/** - * @struct sAllData_t - * @brief sensor return data - */ -typedef struct { - uint8_t exist; - sSensorStatus_t sta; - sPrivateData_t target; -}sAllData_t; - -/** - * @enum eMode_t - * @brief sensor work mode - */ -typedef enum { - eExitMode = 0x00, - eSpeedMode = 0x01, -}eMode_t; - -/** - * @enum eSwitch_t - * @brief Micromotion detection switch - */ -typedef enum { - eON = 0x01, - eOFF = 0x00, -}eSwitch_t; - -/** - * @enum eSetMode_t - * @brief Set parameters for the sensor working status - */ -typedef enum { - eStartSen = 0x55, - eStopSen = 0x33, - eResetSen = 0xCC, - eRecoverSen = 0xAA, - eSaveParams = 0x5C, - eChangeMode = 0x3B, -}eSetMode_t; - -class DFRobot_C4001 { -public: -#define DEVICE_ADDR_0 0x2A -#define DEVICE_ADDR_1 0x2B -#define TIME_OUT 0x64 ///< time out -#define I2C_FLAG 0x01 -#define UART_FLAG 0x02 - -#define REG_STATUS 0x00 -#define REG_CTRL0 0x01 -#define REG_CTRL1 0x02 -#define REG_SOFT_VERSION 0x03 -#define REG_RESULT_STATUS 0x10 -#define REG_TRIG_SENSITIVITY 0x20 -#define REG_KEEP_SENSITIVITY 0x21 -#define REG_TRIG_DELAY 0x22 -#define REG_KEEP_TIMEOUT_L 0x23 -#define REG_KEEP_TIMEOUT_H 0x24 -#define REG_E_MIN_RANGE_L 0x25 -#define REG_E_MIN_RANGE_H 0x26 -#define REG_E_MAX_RANGE_L 0x27 -#define REG_E_MAX_RANGE_H 0x28 -#define REG_E_TRIG_RANGE_L 0x29 -#define REG_E_TRIG_RANGE_H 0x2A - -#define REG_RESULT_OBJ_MUN 0x10 -#define REG_RESULT_RANGE_L 0x11 -#define REG_RESULT_RANGE_H 0x12 -#define REG_RESULT_SPEED_L 0x13 -#define REG_RESULT_SPEED_H 0x14 -#define REG_RESULT_ENERGY_L 0x15 -#define REG_RESULT_ENERGY_H 0x16 -#define REG_CFAR_THR_L 0x20 -#define REG_CFAR_THR_H 0x21 -#define REG_T_MIN_RANGE_L 0x22 -#define REG_T_MIN_RANGE_H 0x23 -#define REG_T_MAX_RANGE_L 0x24 -#define REG_T_MAX_RANGE_H 0x25 -#define REG_MICRO_MOTION 0x26 - -#define START_SENSOR "sensorStart" -#define STOP_SENSOR "sensorStop" -#define SAVE_CONFIG "saveConfig" -#define RECOVER_SENSOR "resetCfg" ///< factory data reset -#define RESET_SENSOR "resetSystem" ///< RESET_SENSOR -#define SPEED_MODE "setRunApp 1" -#define EXIST_MODE "setRunApp 0" - - DFRobot_C4001(); - virtual ~DFRobot_C4001(); - uint8_t uartI2CFlag = 0; - /** - * @fn motionDetection - * @brief motion Detection - * @return true or false - */ - bool motionDetection(void); - - /** - * @fn setSensor - * @brief Set the Sensor object - * @param mode - * @n eStartSen start collect - * @n eStopSen stop collect - * @n eResetSen reset sensor - * @n eRecoverSen recover params - * @n eSaveParams save config - * @n eChangeMode chagne mode - */ - void setSensor(eSetMode_t mode); - - /** - * @fn setDelay - * @brief Set the Delay object - * @param trig Trigger delay, unit 0.01s, range 0~2s (0~200) - * @param keep Maintain the detection timeout, unit 0.5s, range 2~1500 seconds (4~3000) - * @return true or false - */ - bool setDelay(uint8_t trig, uint16_t keep); - - /** - * @fn getTrigDelay - * @brief Get the Trig Delay object - * @return uint8_t - */ - uint8_t getTrigDelay(void); - - /** - * @fn getKeepTimerout - * @brief get keep timer out - * @return uint16_t - */ - uint16_t getKeepTimerout(void); - - /** - * @fn getTrigRange - * @brief Get the Trig Range object - * @n The triggering distance, in cm, ranges from 2.4 to 20m (240 to 2000). - * @n The actual configuration range does not exceed the maximum and minimum detection distance. - * @return uint16_t - */ - uint16_t getTrigRange(void); - - /** - * @fn getMaxRange - * @brief Get the Max Range object - * @return uint16_t - */ - uint16_t getMaxRange(void); - - /** - * @fn getMinRange - * @brief Get the Min Range object - * @return uint16_t - */ - uint16_t getMinRange(void); - - /** - * @fn setDetectionRange - * @brief Set the Detection Range object - * @param min Detection range Minimum distance, unit cm, range 0.3~20m (30~2000), not exceeding max, otherwise the function is abnormal. - * @param max Detection range Maximum distance, unit cm, range 2.4~20m (240~2000) - * @param trig The trigger distance (unit: cm) ranges from 2.4 to 20m (240 to 2000). The actual configuration range does not exceed the maximum and minimum detection distance. - * @return true or false - */ - bool setDetectionRange(uint16_t min, uint16_t max, uint16_t trig); - - /** - * @fn setTrigSensitivity - * @brief Set trigger sensitivity, 0~9 - * @param sensitivity - * @return true or false - */ - bool setTrigSensitivity(uint8_t sensitivity); - - /** - * @fn setKeepSensitivity - * @brief Set the Keep Sensitivity object,0~9 - * @param sensitivity - * @return true or false - */ - bool setKeepSensitivity(uint8_t sensitivity); - - /** - * @fn getTrigSensitivity - * @brief Get the Trig Sensitivity object - * @return uint8_t - */ - uint8_t getTrigSensitivity(void); - - /** - * @fn getKeepSensitivity - * @brief Get the Keep Sensitivity object - * @return uint8_t - */ - uint8_t getKeepSensitivity(void); - - /** - * @fn getStatus - * @brief Get the Status object - * @return sSensorStatus_t - * @n workStatus - * @n 0 stop - * @n 1 start - * @n workMode - * @n 0 indicates presence detection - * @n 1 is speed measurement and ranging - * @n initStatus - * @n 0 not init - * @n 1 init success - */ - sSensorStatus_t getStatus(void); - - /** - * @fn setIoPolaity - * @brief Set the Io Polaity object - * @param value - * @n 0:Output low level when there is a target, output high level when there is no target - * @n 1: Output high level when there is a target, output low level when there is no target (default) - * @return true or false - */ - bool setIoPolaity(uint8_t value); - - /** - * @fn getIoPolaity - * @brief Get the Io Polaity object - * @return uint8_t The level of the signal output by the pin after the configured I/O port detects the target - */ - uint8_t getIoPolaity(void); - - /** - * @fn setPwm - * @brief Set the Pwm object - * @param pwm1 When no target is detected, the duty cycle of the output signal of the OUT pin ranges from 0 to 100 - * @param pwm2 After the target is detected, the duty cycle of the output signal of the OUT pin ranges from 0 to 100 - * @param timer timer The value ranges from 0 to 255, corresponding to timer x 64ms - * @n For example, timer=20, it takes 20*64ms=1.28s for the duty cycle to change from pwm1 to pwm2. - * @return true or false - */ - bool setPwm(uint8_t pwm1, uint8_t pwm2, uint8_t timer); - - - /** - * @fn getPwm - * @brief Get the Pwm object - * @return sPwmData_t - * @retval pwm1 When no target is detected, the duty cycle of the output signal of the OUT pin ranges from 0 to 100 - * @retval pwm2 After the target is detected, the duty cycle of the output signal of the OUT pin ranges from 0 to 100 - * @retval timer The value ranges from 0 to 255, corresponding to timer x 64ms - * @n For example, timer=20, it takes 20*64ms=1.28s for the duty cycle to change from pwm1 to pwm2. - */ - sPwmData_t getPwm(void); - - /** - * @fn setSensorMode - * @brief Set the Sensor Mode object - * @param mode - * @return true or false - */ - bool setSensorMode(eMode_t mode); - - /** - * @fn getTargetNumber - * @brief Get the Target Number object - * @return uint8_t - */ - uint8_t getTargetNumber(void); - - /** - * @fn getTargetSpeed - * @brief Get the Target Speed object - * @return float - */ - float getTargetSpeed(void); - - /** - * @fn getTargetRange - * @brief Get the Target Range object - * @return float - */ - float getTargetRange(void); - - /** - * @fn getTargetEnergy - * @brief Get the Target Energy object - * @return uint32_t - */ - uint32_t getTargetEnergy(void); - - /** - * @fn setDetectThres - * @brief Set the Detect Thres object - * @param min Detection range Minimum distance, unit cm, range 0.3~20m (30~2000), not exceeding max, otherwise the function is abnormal. - * @param max Detection range Maximum distance, unit cm, range 2.4~20m (240~2000) - * @param thres Target detection threshold, dimensionless unit 0.1, range 0~6553.5 (0~65535) - * @return true or false - */ - bool setDetectThres(uint16_t min, uint16_t max, uint16_t thres); - - /** - * @fn getTMinRange - * @brief get speed Min Range - * @return uint16_t - */ - uint16_t getTMinRange(void); - - /** - * @fn getTMaxRange - * @brief get speed Max Range - * @return uint16_t - */ - uint16_t getTMaxRange(void); - - /** - * @fn getThresRange - * @brief Get the Thres Range object - * @return uint16_t - */ - uint16_t getThresRange(void); - - /** - * @fn setFrettingDetection - * @brief Set the Fretting Detection object - * @param sta - */ - void setFrettingDetection(eSwitch_t sta); - - /** - * @fn getFrettingDetection - * @brief Get the Fretting Detection object - * @return eSwitch_t - */ - eSwitch_t getFrettingDetection(void); -protected: - sResponseData_t wRCMD(std::string cmd1, uint8_t count); - void writeCMD(std::string cmd1, std::string cmd2, uint8_t count); - sAllData_t anaysisData(uint8_t* data, uint8_t len); - sResponseData_t anaysisResponse(uint8_t* data, uint8_t len, uint8_t count); - bool sensorStop(void); - uint8_t _addr; -private: - uint8_t _M_Flag = 0; - sPrivateData_t _buffer; - virtual void writeReg(uint8_t reg, uint8_t* data, uint8_t len) = 0; - virtual int16_t readReg(uint8_t reg, uint8_t* data, uint8_t len) = 0; -}; - -class DFRobot_C4001_I2C : public DFRobot_C4001 { -public: - DFRobot_C4001_I2C(const char* deviceName, uint8_t addr = DEVICE_ADDR_0); - ~DFRobot_C4001_I2C(); - bool begin(void); -protected: - virtual void writeReg(uint8_t reg, uint8_t* data, uint8_t len); - virtual int16_t readReg(uint8_t reg, uint8_t* data, uint8_t len); -private: - I2c* i2c; - std::string path; -};