From a1ae50dec3999362ab13488e8adbe39cda783b2b Mon Sep 17 00:00:00 2001 From: samuk Date: Thu, 23 Oct 2025 13:45:53 +0100 Subject: [PATCH 01/12] Enhance DEMIR motor controller with I2C support Updated application entry point for DEMIR motor controller to include I2C support and improved documentation. --- src/main.cpp | 108 ++++++++++++++++++++++----------------------------- 1 file changed, 46 insertions(+), 62 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 05a15ee..261ccdd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,15 +1,15 @@ /** * @file main.cpp - * @brief Main application entry point for DEMIR motor controller + * @brief Main application entry point for DEMIR motor controller with I2C support * @author Muhammet Şükrü Demir - * @date 2020 - * @version 1.1.1 - * @details This is the main application file that initializes the DEMIR motor control - * system and implements the main control loop with serial command processing, - * motor control execution, and data logging capabilities. + * @date 2025 + * @version 1.1.2 + * @details Initializes DEMIR motor control system, implements main control loop, + * handles serial and I2C commands, motor control execution, and data logging. */ #include +#include #include "Motion.h" #include "MotorDriver.h" @@ -18,84 +18,69 @@ #include "com_def.h" #include "conf.h" #include "controller.h" +#include "i2c_comm.h" // I2C interface header /// @brief Main control loop rate in milliseconds uint8_t loopRate = 3; /** * @brief Arduino setup function - system initialization - * @details Initializes serial communication, motor drivers, and status LEDs. - * Performs LED test sequence to verify hardware functionality. */ void setup() { - // Initialize serial communication - Serial.begin( BAUDRATE ); - while ( !Serial ) { - // Wait for serial port to initialize - } - Serial.setTimeout( TIMEOUT ); + Serial.begin(BAUDRATE); + while (!Serial) {} + Serial.setTimeout(TIMEOUT); + + Serial.println(F("DEMIR v1.1.2")); - // Print system identification - Serial.println( F( "DEMIR v1.1.1" ) ); - - // Initialize motor driver subsystem Driver.init(); - Serial.println( F( "ok!" ) ); + Serial.println(F("ok!")); + + pinMode(STATUS_LED_BLUE, OUTPUT); + pinMode(STATUS_LED_RED, OUTPUT); - // Initialize status LEDs - pinMode( STATUS_LED_BLUE, OUTPUT ); - pinMode( STATUS_LED_RED, OUTPUT ); + digitalWrite(STATUS_LED_BLUE, HIGH); + delay(300); + digitalWrite(STATUS_LED_BLUE, LOW); - // LED startup test sequence - digitalWrite( STATUS_LED_BLUE, HIGH ); - delay( 300 ); - digitalWrite( STATUS_LED_BLUE, LOW ); + digitalWrite(STATUS_LED_RED, HIGH); + delay(300); + digitalWrite(STATUS_LED_RED, LOW); - digitalWrite( STATUS_LED_RED, HIGH ); - delay( 300 ); - digitalWrite( STATUS_LED_RED, LOW ); + // Initialize I2C interface + Wire.begin(DEMIR_I2C_ADDR); + Wire.onReceive(receiveI2CCommand); + Wire.onRequest(sendI2CResponse); } /** * @brief Arduino main loop function - * @details Implements the main control loop with timing control, motor driver execution, - * data logging, and serial command processing. Runs continuously at specified - * loop rate for real-time motor control. */ void loop() { - // Update timing for control loop - Controller.currentTime = millis(); ///< Current timestamp - Controller.deltaT - = Controller.currentTime - Controller.oldTime; ///< Time since last control update - - // Execute control loop at specified rate - if ( Controller.deltaT >= loopRate ) // Execute when deltaT exceeds loopRate - { + Controller.currentTime = millis(); + Controller.deltaT = Controller.currentTime - Controller.oldTime; + + if (Controller.deltaT >= loopRate) { Controller.oldTime = Controller.currentTime; - + // Execute motor control algorithms Driver.run(); // Handle data logging if enabled - if ( Solver.logEnable ) // Check if logging is enabled - { - switch ( Solver.logWhat ) // Determine what to log - { + if (Solver.logEnable) { + switch (Solver.logWhat) { case LOG_POSITION: - /// Log current motor position - Solver.logForMatlab[ Solver.logCounter ] = ( unsigned long ) Motor.getPosition( MOTOR_1 ); + Solver.logForMatlab[Solver.logCounter] = (unsigned long)Motor.getPosition(MOTOR_1); break; case LOG_CURRENT: - /// Log current sensor data (not implemented) - // unsigned long tempHex = *( unsigned long* ) &totalCurrent; - // logForMatlab[ Solver.logCounter ] = tempHex; + // unsigned long tempHex = *(unsigned long*)&totalCurrent; + // Solver.logForMatlab[Solver.logCounter] = tempHex; break; } - - // Check if log buffer is full - if ( ++Solver.logCounter == Solver.logSize ) { - Solver.logEnable = false; // Disable logging - Solver.logCounter = 0; // Reset counter + + if (++Solver.logCounter == Solver.logSize) { + Solver.logEnable = false; + Solver.logCounter = 0; } } } @@ -104,15 +89,14 @@ void loop() { Solver.proccessCommands(); // Send logged data to MATLAB if requested - if ( Solver.sendLogToMatlab ) { + if (Solver.sendLogToMatlab) { Solver.sendLogToMatlab = false; - // Transmit logged data as 4-byte values - for ( uint16_t j = 0; j < Solver.logSize; j++ ) { - Serial.write( Solver.logForMatlab[ j ] ); ///< LSB - Serial.write( Solver.logForMatlab[ j ] >> 8 ); ///< Byte 1 - Serial.write( Solver.logForMatlab[ j ] >> 16 ); ///< Byte 2 - Serial.write( Solver.logForMatlab[ j ] >> 24 ); ///< MSB + for (uint16_t j = 0; j < Solver.logSize; j++) { + Serial.write(Solver.logForMatlab[j]); // LSB + Serial.write(Solver.logForMatlab[j] >> 8); // Byte 1 + Serial.write(Solver.logForMatlab[j] >> 16); // Byte 2 + Serial.write(Solver.logForMatlab[j] >> 24); // MSB } } } From 4c67c923b225d6fbe3149d5e2c82f0c656c499fa Mon Sep 17 00:00:00 2001 From: samuk Date: Thu, 23 Oct 2025 13:47:11 +0100 Subject: [PATCH 02/12] Implement I2C command handling for DEMIR controller --- src/SerialSolver_i2c.cpp | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/SerialSolver_i2c.cpp diff --git a/src/SerialSolver_i2c.cpp b/src/SerialSolver_i2c.cpp new file mode 100644 index 0000000..7d00b56 --- /dev/null +++ b/src/SerialSolver_i2c.cpp @@ -0,0 +1,42 @@ +/** + * @file SerialSolver_i2c.cpp + * @brief I2C command handling for DEMIR controller + * @author Muhammet Şükrü Demir + * @date 2025 + */ + +#include "SerialSolver.h" +#include "motor.h" +#include "controller.h" + +void SerialSolver::proccessI2CCommand(uint8_t* data, uint8_t length) { + if (length < 2) return; + + uint8_t motorIndex = data[0]; + uint8_t command = data[1]; + int16_t param = 0; + + if (length >= 4) { + param = (data[2] << 8) | data[3]; + } + + switch (command) { + case 0x01: // set motor speed + Controller.set_uManuel(param, motorIndex); + break; + case 0x02: // enable motor + Motor.enable(motorIndex); + break; + case 0x03: // disable motor + Motor.disable(motorIndex); + break; + case 0x04: // reset encoder + Motor.resetPosition(motorIndex); + break; + case 0x05: // set position reference + Controller.setPositionReference(param, motorIndex); + break; + default: + break; + } +} From 2e1a46f9d6347e8de07f4005a9d295fbf00307bb Mon Sep 17 00:00:00 2001 From: samuk Date: Thu, 23 Oct 2025 13:48:00 +0100 Subject: [PATCH 03/12] Add I2C communication functions and buffer Implement I2C communication interface for DEMIR controller. --- src/i2c_comm.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/i2c_comm.cpp diff --git a/src/i2c_comm.cpp b/src/i2c_comm.cpp new file mode 100644 index 0000000..dd65436 --- /dev/null +++ b/src/i2c_comm.cpp @@ -0,0 +1,26 @@ +/** + * @file i2c_comm.cpp + * @brief I2C communication interface implementation for DEMIR controller + * @author Muhammet Şükrü Demir + * @date 2025 + */ + +#include "i2c_comm.h" + +uint8_t i2cCmdBuffer[I2C_CMD_BUF_SIZE]; +uint8_t i2cCmdIndex = 0; + +void receiveI2CCommand(int byteCount) { + while (Wire.available() && i2cCmdIndex < I2C_CMD_BUF_SIZE) { + i2cCmdBuffer[i2cCmdIndex++] = Wire.read(); + } + if (i2cCmdIndex > 0) { + Solver.proccessI2CCommand(i2cCmdBuffer, i2cCmdIndex); + i2cCmdIndex = 0; + } +} + +void sendI2CResponse() { + uint32_t pos = Motor.getPosition(MOTOR_1); + Wire.write((uint8_t*)&pos, sizeof(pos)); +} From 1d56d01cef65700de6758391fc2e8934d2f36db9 Mon Sep 17 00:00:00 2001 From: samuk Date: Thu, 23 Oct 2025 13:49:10 +0100 Subject: [PATCH 04/12] Update author name in i2c_comm.h --- i2c_comm.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 i2c_comm.h diff --git a/i2c_comm.h b/i2c_comm.h new file mode 100644 index 0000000..b1da60f --- /dev/null +++ b/i2c_comm.h @@ -0,0 +1,22 @@ +/** + * @file i2c_comm.h + * @brief I2C communication interface for DEMIR motor controller + * @author Sam Rossiter + * @date 2025 + * @details Handles receiving commands and sending responses over I2C. + */ + +#pragma once +#include +#include "controller.h" +#include "motor.h" +#include "SerialSolver.h" + +#define DEMIR_I2C_ADDR 0x10 +#define I2C_CMD_BUF_SIZE 8 + +extern uint8_t i2cCmdBuffer[I2C_CMD_BUF_SIZE]; +extern uint8_t i2cCmdIndex; + +void receiveI2CCommand(int byteCount); +void sendI2CResponse(); From 12ea2da3140cbb4b367e63fe00a7f1a2bdcfd175 Mon Sep 17 00:00:00 2001 From: samuk Date: Thu, 23 Oct 2025 13:50:14 +0100 Subject: [PATCH 05/12] Update author name in SerialSolver_i2c.cpp --- src/SerialSolver_i2c.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SerialSolver_i2c.cpp b/src/SerialSolver_i2c.cpp index 7d00b56..bc06cea 100644 --- a/src/SerialSolver_i2c.cpp +++ b/src/SerialSolver_i2c.cpp @@ -1,7 +1,7 @@ /** * @file SerialSolver_i2c.cpp * @brief I2C command handling for DEMIR controller - * @author Muhammet Şükrü Demir + * @author Muhammet Şam Rossiter * @date 2025 */ From a15750916f2e10f25947d7b2a114e04086c0b367 Mon Sep 17 00:00:00 2001 From: samuk Date: Thu, 23 Oct 2025 13:50:49 +0100 Subject: [PATCH 06/12] Update author name in i2c_comm.cpp file --- src/i2c_comm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i2c_comm.cpp b/src/i2c_comm.cpp index dd65436..c42a644 100644 --- a/src/i2c_comm.cpp +++ b/src/i2c_comm.cpp @@ -1,7 +1,7 @@ /** * @file i2c_comm.cpp * @brief I2C communication interface implementation for DEMIR controller - * @author Muhammet Şükrü Demir + * @author Muhammet Şam Rossiter * @date 2025 */ From f23b965e5827c80ead55901d2085af8499d8c969 Mon Sep 17 00:00:00 2001 From: samuk Date: Thu, 23 Oct 2025 13:52:37 +0100 Subject: [PATCH 07/12] Delete i2c_comm.h --- i2c_comm.h | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 i2c_comm.h diff --git a/i2c_comm.h b/i2c_comm.h deleted file mode 100644 index b1da60f..0000000 --- a/i2c_comm.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @file i2c_comm.h - * @brief I2C communication interface for DEMIR motor controller - * @author Sam Rossiter - * @date 2025 - * @details Handles receiving commands and sending responses over I2C. - */ - -#pragma once -#include -#include "controller.h" -#include "motor.h" -#include "SerialSolver.h" - -#define DEMIR_I2C_ADDR 0x10 -#define I2C_CMD_BUF_SIZE 8 - -extern uint8_t i2cCmdBuffer[I2C_CMD_BUF_SIZE]; -extern uint8_t i2cCmdIndex; - -void receiveI2CCommand(int byteCount); -void sendI2CResponse(); From 6d411223249fd273df050e6ad44166319ba3fc38 Mon Sep 17 00:00:00 2001 From: samuk Date: Thu, 23 Oct 2025 13:53:10 +0100 Subject: [PATCH 08/12] Add I2C communication interface header file --- src/i2c_comm.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/i2c_comm.h diff --git a/src/i2c_comm.h b/src/i2c_comm.h new file mode 100644 index 0000000..b1da60f --- /dev/null +++ b/src/i2c_comm.h @@ -0,0 +1,22 @@ +/** + * @file i2c_comm.h + * @brief I2C communication interface for DEMIR motor controller + * @author Sam Rossiter + * @date 2025 + * @details Handles receiving commands and sending responses over I2C. + */ + +#pragma once +#include +#include "controller.h" +#include "motor.h" +#include "SerialSolver.h" + +#define DEMIR_I2C_ADDR 0x10 +#define I2C_CMD_BUF_SIZE 8 + +extern uint8_t i2cCmdBuffer[I2C_CMD_BUF_SIZE]; +extern uint8_t i2cCmdIndex; + +void receiveI2CCommand(int byteCount); +void sendI2CResponse(); From a215ffcb49f195a4ac44a5b300caa7232459f3fc Mon Sep 17 00:00:00 2001 From: samuk Date: Thu, 23 Oct 2025 14:48:59 +0100 Subject: [PATCH 09/12] Add configuration header for serial and motor settings --- src/conf.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/conf.h diff --git a/src/conf.h b/src/conf.h new file mode 100644 index 0000000..2bb5fbe --- /dev/null +++ b/src/conf.h @@ -0,0 +1,20 @@ +#ifndef CONF_H +#define CONF_H + +// Serial configuration +#define BAUDRATE 115200 +#define TIMEOUT 100 // Serial timeout in ms + +// Number of motors +#define MOTORS 4 + +// I2C configuration - multiple controllers +#define MOTOR_CONTROLLER_ADDR_1 0x08 +#define MOTOR_CONTROLLER_ADDR_2 0x09 +#define MOTOR_CONTROLLER_ADDR_3 0x0A +#define MOTOR_CONTROLLER_ADDR_4 0x0B + +// Control loop timing +#define LOOP_RATE_MS 3 // Main control loop rate + +#endif // CONF_H From 58f80a1454ab70ec42c66b4be5d771ad3d0d3d2d Mon Sep 17 00:00:00 2001 From: samuk Date: Thu, 23 Oct 2025 14:51:37 +0100 Subject: [PATCH 10/12] Refactor I2C communication implementation Updated author name and added detailed comments for I2C communication functions. --- src/i2c_comm.cpp | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/i2c_comm.cpp b/src/i2c_comm.cpp index c42a644..3d57bad 100644 --- a/src/i2c_comm.cpp +++ b/src/i2c_comm.cpp @@ -1,15 +1,28 @@ /** * @file i2c_comm.cpp * @brief I2C communication interface implementation for DEMIR controller - * @author Muhammet Şam Rossiter + * @author Şam Rossiter * @date 2025 + * @details Implements I2C master/slave routines for sending commands to + * the DEMIR motor controller. References controller I2C addresses + * defined in conf.h */ +#include #include "i2c_comm.h" +#include "conf.h" // for I2C addresses +#include "controller.h" // for Solver +#include "motor.h" // for Motor uint8_t i2cCmdBuffer[I2C_CMD_BUF_SIZE]; uint8_t i2cCmdIndex = 0; +/** + * @brief I2C receive event callback + * @param byteCount Number of bytes received + * @details Called when I2C master writes data to this controller. + * Buffers incoming command and triggers Solver for processing. + */ void receiveI2CCommand(int byteCount) { while (Wire.available() && i2cCmdIndex < I2C_CMD_BUF_SIZE) { i2cCmdBuffer[i2cCmdIndex++] = Wire.read(); @@ -20,7 +33,23 @@ void receiveI2CCommand(int byteCount) { } } +/** + * @brief I2C request event callback + * @details Called when I2C master requests data from this controller. + * Sends the current motor position (MOTOR_1) as a 4-byte response. + */ void sendI2CResponse() { uint32_t pos = Motor.getPosition(MOTOR_1); Wire.write((uint8_t*)&pos, sizeof(pos)); } + +/** + * @brief Initialize I2C interface + * @param slaveAddress I2C address of this controller + * @details Configures Wire library in slave mode and attaches receive/request callbacks. + */ +void initI2C(uint8_t slaveAddress) { + Wire.begin(slaveAddress); // join I2C bus with defined address + Wire.onReceive(receiveI2CCommand); // attach receive handler + Wire.onRequest(sendI2CResponse); // attach request handler +} From 2af9dd5bb80e19180a4b6377219178e4d273568a Mon Sep 17 00:00:00 2001 From: samuk Date: Thu, 23 Oct 2025 14:55:36 +0100 Subject: [PATCH 11/12] Clean up logging code in main.cpp Removed commented-out code for logging total current. --- src/main.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 261ccdd..40d1299 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -73,8 +73,6 @@ void loop() { Solver.logForMatlab[Solver.logCounter] = (unsigned long)Motor.getPosition(MOTOR_1); break; case LOG_CURRENT: - // unsigned long tempHex = *(unsigned long*)&totalCurrent; - // Solver.logForMatlab[Solver.logCounter] = tempHex; break; } @@ -91,12 +89,11 @@ void loop() { // Send logged data to MATLAB if requested if (Solver.sendLogToMatlab) { Solver.sendLogToMatlab = false; - for (uint16_t j = 0; j < Solver.logSize; j++) { - Serial.write(Solver.logForMatlab[j]); // LSB - Serial.write(Solver.logForMatlab[j] >> 8); // Byte 1 - Serial.write(Solver.logForMatlab[j] >> 16); // Byte 2 - Serial.write(Solver.logForMatlab[j] >> 24); // MSB + Serial.write(Solver.logForMatlab[j]); + Serial.write(Solver.logForMatlab[j] >> 8); + Serial.write(Solver.logForMatlab[j] >> 16); + Serial.write(Solver.logForMatlab[j] >> 24); } } } From 55f91872356cb9822818f1aaf20fd831a190ed53 Mon Sep 17 00:00:00 2001 From: samuk Date: Thu, 23 Oct 2025 16:32:53 +0100 Subject: [PATCH 12/12] Remove motor count and I2C controller addresses Removed motor configuration definitions. --- src/conf.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/conf.h b/src/conf.h index 2bb5fbe..cae197a 100644 --- a/src/conf.h +++ b/src/conf.h @@ -5,14 +5,8 @@ #define BAUDRATE 115200 #define TIMEOUT 100 // Serial timeout in ms -// Number of motors -#define MOTORS 4 - -// I2C configuration - multiple controllers +// I2C configuration - #define MOTOR_CONTROLLER_ADDR_1 0x08 -#define MOTOR_CONTROLLER_ADDR_2 0x09 -#define MOTOR_CONTROLLER_ADDR_3 0x0A -#define MOTOR_CONTROLLER_ADDR_4 0x0B // Control loop timing #define LOOP_RATE_MS 3 // Main control loop rate