diff --git a/example/IMU/Upside_Downside_Detection/Upside_Downside_Detection.ino b/example/IMU/Upside_Downside_Detection/Upside_Downside_Detection.ino new file mode 100644 index 0000000..e1aa2aa --- /dev/null +++ b/example/IMU/Upside_Downside_Detection/Upside_Downside_Detection.ino @@ -0,0 +1,27 @@ +#include "Dezibot.h" +Dezibot dezibot = Dezibot(); +void setup() { + // put your setup code here, to run once: + dezibot.begin(); + Serial.begin(115200); +} + +int indices = 0; +void loop() { + // put your main code here, to run repeatedly: + + + int zvalue = 0; + for(int i = 0; i<30;i++){ + zvalue += dezibot.motionDetection.getAcceleration().z; + } + zvalue = zvalue/30; + if(zvalue < -1700){ + dezibot.multiColorLight.setLed(ALL,0x00FF00); + } else if(zvalue > 1700){ + dezibot.multiColorLight.setLed(ALL,0xFF0000); + } else { + dezibot.multiColorLight.turnOffLed(); + } + } + diff --git a/example/Led/ColorCycle/ColorCycle/ColorCycle.ino b/example/Led/ColorCycle/ColorCycle/ColorCycle.ino new file mode 100644 index 0000000..28fe930 --- /dev/null +++ b/example/Led/ColorCycle/ColorCycle/ColorCycle.ino @@ -0,0 +1,26 @@ +#include "Dezibot.h" + + +Dezibot dezibot = Dezibot(); +void setup() { + // put your setup code here, to run once: +dezibot.begin(); +} + +void loop() { + // put your main code here, to run repeatedly: + for (int d = 0; d < 255; d++) { + dezibot.multiColorLight.setLed(ALL,dezibot.multiColorLight.color(d,0,255-d)); + delay(2); + } + + for (int d = 0; d < 255; d++) { + dezibot.multiColorLight.setLed(ALL, dezibot.multiColorLight.color(255-d, d, 0)); + delay(2); + } + + for (int d = 0; d < 255; d++) { + dezibot.multiColorLight.setLed(ALL, dezibot.multiColorLight.color(0, 255-d, d)); + delay(2); + } +} diff --git a/example/example.ino b/example/example.ino new file mode 100644 index 0000000..bf5898c --- /dev/null +++ b/example/example.ino @@ -0,0 +1,20 @@ +#include "Dezibot.h" +Dezibot dezibot; +void setup() { + + dezibot.begin(); + dezibot.motionDetection.begin(); + //dezibot.motionDetection.end(); + // put your setup code here, to run once: + Serial.begin(115200); +} + +void loop() { + // put your main code here, to run repeatedly: + + //Serial.println(dezibot.motionDetection.getTemperature()); + Serial.println(dezibot.motionDetection.getAcceleration().z); + //Serial.println(dezibot.motionDetection.getRotation().x); + Serial.println(dezibot.motionDetection.getWhoAmI()); + delay(5000); +} diff --git a/src/Dezibot.cpp b/src/Dezibot.cpp index 4e95ddb..54295e0 100644 --- a/src/Dezibot.cpp +++ b/src/Dezibot.cpp @@ -12,7 +12,7 @@ #include "Dezibot.h" -Dezibot::Dezibot():multiColorLight(){ +Dezibot::Dezibot():multiColorLight(),motionDetection(){ }; @@ -20,4 +20,5 @@ void Dezibot::begin(void) { motion.begin(); multiColorLight.begin(); lightDetection.begin(); + motionDetection.begin(); }; diff --git a/src/motionDetection/MotionDetection.cpp b/src/motionDetection/MotionDetection.cpp new file mode 100644 index 0000000..b675e28 --- /dev/null +++ b/src/motionDetection/MotionDetection.cpp @@ -0,0 +1,77 @@ +#include "MotionDetection.h" + +MotionDetection::MotionDetection(){//:handler(FSPI){ + handler = new SPIClass(FSPI); +}; + +void MotionDetection::begin(void){ + pinMode(34,OUTPUT); + digitalWrite(34,HIGH); + handler->begin(36,37,35,34); + + handler->beginTransaction(SPISettings(frequency,SPI_MSBFIRST,SPI_MODE0)); + digitalWrite(34,LOW); + // set Accel and Gyroscop to Low Noise + handler->transfer(0x1F); + handler->transfer(0x0F); + //busy Wait for startup + delayMicroseconds(200); + digitalWrite(34,HIGH); + handler->endTransaction(); +}; +void MotionDetection::end(void){ + handler->beginTransaction(SPISettings(frequency,SPI_MSBFIRST,SPI_MODE0)); + digitalWrite(34,LOW); + handler->transfer(cmdWrite(PWR_MGMT0)); + //turn Accel and Gyroscope off + handler->transfer(0x00); + digitalWrite(34,HIGH); + handler->end(); +}; +IMUResult MotionDetection::getAcceleration(){ + IMUResult result; + result.x = readRegister(ACCEL_DATA_X_HIGH)<<8; + result.x |= readRegister(ACCEL_DATA_X_LOW); + result.y = readRegister(ACCEL_DATA_Y_HIGH)<<8; + result.y |= readRegister(ACCEL_DATA_Y_LOW); + result.z = readRegister(ACCEL_DATA_Z_HIGH)<<8; + result.z |= readRegister(ACCEL_DATA_Z_LOW); + return result; +}; +IMUResult MotionDetection::getRotation(){ + IMUResult result; + result.x = readRegister(GYRO_DATA_X_HIGH) <<8; + result.x |= readRegister(GYRO_DATA_X_LOW); + result.y = readRegister(GYRO_DATA_Y_HIGH)<<8; + result.y |= readRegister(GYRO_DATA_Y_LOW); + result.z = readRegister(GYRO_DATA_Z_HIGH)<<8; + result.z |= readRegister(GYRO_DATA_Z_LOW); + return result; +}; +float MotionDetection::getTemperature(){ + int16_t raw_temperatur = readRegister(REG_TEMP_HIGH)<<8; + raw_temperatur |= readRegister(REG_TEMP_LOW); + return raw_temperatur/128 +25; +}; + +int8_t MotionDetection::getWhoAmI(){ + return readRegister(WHO_AM_I); +}; + +uint8_t MotionDetection::cmdRead(uint8_t reg){ + return (CMD_READ | (reg & ADDR_MASK)); +}; +uint8_t MotionDetection::cmdWrite(uint8_t reg){ + return (CMD_WRITE | (reg & ADDR_MASK)); +}; + +int8_t MotionDetection::readRegister(uint8_t reg){ + handler->beginTransaction(SPISettings(frequency,SPI_MSBFIRST,SPI_MODE0)); + digitalWrite(34,LOW); + uint8_t result; + result = handler->transfer(cmdRead(reg)); + result = handler->transfer(0x00); + digitalWrite(34,HIGH); + handler->endTransaction(); + return result; +}; \ No newline at end of file diff --git a/src/motionDetection/MotionDetection.h b/src/motionDetection/MotionDetection.h index c01d0bb..6d9bd5a 100644 --- a/src/motionDetection/MotionDetection.h +++ b/src/motionDetection/MotionDetection.h @@ -1,6 +1,110 @@ +/** + * @file MotionDetection.h + * @author Hans Haupt + * @brief This component controls the IMU (Accelerometer & Gyroscope) ICM-42670-P + * @version 0.1 + * @date 2023-12-15 + * + * @copyright Copyright (c) 2023 + * + */ #ifndef MotionDetection_h #define MotionDetection_h -class MotionDetection{ +#include +#include +struct IMUResult{ + int16_t x; + int16_t y; + int16_t z; +}; + +class MotionDetection{ +protected: + + static const uint8_t CMD_READ = 0x80; + static const uint8_t CMD_WRITE = 0x00; + static const uint8_t ADDR_MASK = 0x7F; + + //Registers + static const uint8_t REG_TEMP_LOW = 0x0A; + static const uint8_t REG_TEMP_HIGH = 0X09; + + static const uint8_t ACCEL_DATA_X_HIGH = 0x0B; + static const uint8_t ACCEL_DATA_X_LOW = 0x0C; + static const uint8_t ACCEL_DATA_Y_HIGH = 0x0D; + static const uint8_t ACCEL_DATA_Y_LOW = 0x0E; + static const uint8_t ACCEL_DATA_Z_HIGH = 0x0F; + static const uint8_t ACCEL_DATA_Z_LOW = 0x10; + + static const uint8_t GYRO_DATA_X_HIGH = 0x11; + static const uint8_t GYRO_DATA_X_LOW = 0x12; + static const uint8_t GYRO_DATA_Y_HIGH = 0x13; + static const uint8_t GYRO_DATA_Y_LOW = 0x14; + static const uint8_t GYRO_DATA_Z_HIGH = 0x15; + static const uint8_t GYRO_DATA_Z_LOW = 0x16; + + static const uint8_t PWR_MGMT0 = 0x1F; + static const uint8_t WHO_AM_I = 0x75; + + static const uint frequency = 10000000; + + uint16_t cmdRead(uint8_t regHigh,uint8_t regLow); + uint16_t cmdWrite(uint8_t regHigh,uint8_t regLow); + uint8_t cmdRead(uint8_t reg); + uint8_t cmdWrite(uint8_t reg); + + int8_t readRegister(uint8_t reg); + int16_t readDoubleRegister(uint8_t lowerReg); + + SPIClass * handler = NULL; + + +public: + MotionDetection(); + + /** + * @brief initialized the IMU Component. + * Wakes the IMU from Standby + * Set configuration + * + */ + void begin(void); + + /** + * @brief stops the component + * Sets the IMU to Low-Power-Mode + * + */ + void end(void); + + /** + * @brief Triggers a new Reading of the accelerationvalues and reads them from the IMU + * + * @return IMUResult that contains the new read values + */ + IMUResult getAcceleration(); + + /** + * @brief Triggers a new reading of the gyroscope and reads the values from the imu + * + * @return IMUResult + */ + IMUResult getRotation(); + + /** + * @brief Reads the current On Chip temperature of the IMU + * + * @return normalized temperature in degree Centigrade + */ + float getTemperature(); + + /** + * @brief Returns the value of reading the whoAmI register + * When IMU working correctly, value should be 0x67 + * + * @return the value of the whoami register of the ICM-42670 + */ + int8_t getWhoAmI(); }; #endif //MotionDetection \ No newline at end of file