Encoders is not working when pwm.analog write is lower value

I have encoders attached to my MKR WIFI 1010 Arduino, which are connected to servo motors. The problem arises when I use pwm.analogWrite(TorqueRefPinA, 140); . In this scenario, the encoders don't seem to be working properly. Specifically, when the analog write value is set to 140 or lower, I cannot observe encoder rotations. However, when the analog write value exceeds 140, the encoders function as expected. Any insights or suggestions on resolving this issue would be greatly appreciated.

#include <ArduinoBLE.h>
#include <SAMD21turboPWM.h>
#include <ArduinoJson.h>

DynamicJsonDocument doc(1024);
StaticJsonDocument<200> responseDocument;

//Set the ble name here
const String bleName = "BLE_NAME";

#define TorqueRefPinA 5
#define TorqueRefPinB 2

// Rotary Encoder Inputs
#define encoder_reference_A_1_CLK 4
#define encoder_reference_B_1_DT 3

#define encoder_reference_A_2_CLK 1
#define encoder_reference_B_2_DT 0

const int remoteButtonPin = 6;

int motorState = 0;
int PWMwriter = 0;
float c = 14.8;
int cases = 0;
int state = 1;
int flag = 0;
int concentric = 0;
int eccentric = 0;
int plateWeight = 0;
float it = 1.5;
unsigned long tim = 0;
unsigned long lastButtonPressTime = 0;
unsigned long delayDuration = 2000;  // Delay duration in milliseconds
double a = 0;
float counter = 0;
float cableCounter = 0;
float loop_counter = 0;
long currentStateCLK;
long previousStateCLK;

float displacement = 0;
float velocity = 0;
float power = 0;

int previousRemoteButtonStatus = HIGH;

bool deviceConnected = false;

// Scaling factor used to match the input weight and the output resistance of the motor
float weightScalingConstant = 4.65;

TurboPWM pwm;

BLEService arduinoService("19B10010-E8F2-537E-4F6C-D104768A1214");  // Service

BLEByteCharacteristic stateChar("19B10011-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
BLEByteCharacteristic concentricChar("19B10017-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
BLEByteCharacteristic eccentricChar("19B10018-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);

// Characteristics for data plotting
BLEFloatCharacteristic displacementChar("19B10014-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify);
BLEFloatCharacteristic powerChar("19B10012-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify);
BLEFloatCharacteristic velocityChar("19B10013-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify);
BLEFloatCharacteristic cableCounterChar("19B10015-E8F2-537E-4F6C-D104768A1214", BLERead | BLENotify);

void onConnect(BLEDevice central) {
  // Code to be executed when a central device is connected
  Log("----- BLE Connected to central device. Client address: ");
  Log(central.address());

  deviceConnected = true;

  // Once connected we don't need to advertise or else another mobile device can connect
  // BLE.advertise();
}

void onDisconnect(BLEDevice central) {
  // Code to be executed when a central device is disconnected
  Log("XXXXXX BLE  Disconnected from central device. Client address: ");
  Log(central.address());

  deviceConnected = false;

  BLE.advertise();

  Log("<-----BLE Advertising started----->");
}

volatile int lastCLKState = LOW;  // Variable to hold last state of CLK pin

void encoderInterrupt() {


  int CLKState = digitalRead(encoder_reference_A_1_CLK);  // Read current state of CLK pin
  int DTState = digitalRead(encoder_reference_B_1_DT);    // Read current state of DT pin

  // Check if the CLK pin has changed
  if (CLKState != lastCLKState) {
    // If CLK and DT are in different states, it's a valid change
    if (CLKState != DTState) {

      cableCounter++;
      counter++;
      flag = 2;
    } else {

      cableCounter--;
      counter++;
      flag = 1;
    }
  }

  // Update lastCLKState with current CLK state
  lastCLKState = CLKState;
}

void setup() {

  delay(2000);
  Serial.begin(115200);
  Log("Serial Comm Via USB UART");
  Serial.flush();

  pinMode(TorqueRefPinA, OUTPUT);
  pinMode(TorqueRefPinB, OUTPUT);

  pinMode(remoteButtonPin, INPUT_PULLUP);

  pinMode(encoder_reference_A_1_CLK, INPUT_PULLDOWN);
  pinMode(encoder_reference_B_1_DT, INPUT_PULLDOWN);

  attachInterrupt(digitalPinToInterrupt(encoder_reference_A_1_CLK), encoderInterrupt, CHANGE);

  pwm.setClockDivider(20, false);  // Main clock divided by 20 => 2400KHz
  pwm.timer(1, 1, 80, true);       // Use timer 2 for pin 13, divide clock by 4, resolution 60000, dual-slope PWM
  pwm.timer(0, 1, 80, true);

  if (!BLE.begin()) {
    Log("BLE initialization failed!");
    while (1)
      ;
  }


  // Set local name for peripheral advertising
  BLE.setLocalName(bleName.c_str());

  // Set the UUID for service
  BLE.setAdvertisedService(arduinoService);

  arduinoService.addCharacteristic(stateChar);
  arduinoService.addCharacteristic(concentricChar);
  arduinoService.addCharacteristic(eccentricChar);
  arduinoService.addCharacteristic(displacementChar);
  arduinoService.addCharacteristic(velocityChar);
  arduinoService.addCharacteristic(powerChar);
  arduinoService.addCharacteristic(cableCounterChar);

  BLE.addService(arduinoService);
  // Set connection callbacks
  BLE.setEventHandler(BLEConnected, onConnect);
  BLE.setEventHandler(BLEDisconnected, onDisconnect);
  BLE.advertise();

  Log("Device is active, waiting for connections...");
}

void loop() {

  // Poll for BLE events
  BLE.poll();

  //Gets the data from mobile
  String strFromMobile;
  if (Serial.available() > 0) {
    while (Serial.available() > 0) {
      uint8_t byteFromSerial = Serial.read();
      uint8_t buff[100] = { byteFromSerial };
      strFromMobile = strFromMobile + (char *)buff;
    }

    processJsonData(strFromMobile);
  }


  int currentRemoteButtonStatus = digitalRead(remoteButtonPin);

  //Serial.print("currentRemoteButtonStatus-> ");
  //Serial.println(currentRemoteButtonStatus);
  //if (currentRemoteButtonStatus == LOW) {
  //    Serial.println("Button is ON");
  //} else {
  //    Serial.println("Button is OFF");
  //}
  //Serial.println("=====================================");

  if (currentRemoteButtonStatus == LOW && previousRemoteButtonStatus == HIGH) {
    // Button goes from high to low
    lastButtonPressTime = millis();
  }

  previousRemoteButtonStatus = currentRemoteButtonStatus;

  unsigned long currentTime = millis();

  bool isButtonDelayElapsed = currentTime - lastButtonPressTime >= delayDuration;


  if (currentRemoteButtonStatus == LOW) {


    // PWMstaging
    if (concentricChar.written() || eccentricChar.written()) {
      concentric = concentricChar.value();
      eccentric = eccentricChar.value();

      //Serial.print("Written eccentric weight-> ");
      //Serial.println(eccentric);

      //Serial.print("Written concentric weight-> ");
      //Serial.println(concentric);
    }




    int engagedWeight = 0;
    switch (state) {

      case 0:  //
        PWMwriter = round(weightScalingConstant * concentric);
        break;

      case 1:

        if (flag == 2) {
          engagedWeight = concentric;
          if (concentric != 0) {
            PWMwriter = round(weightScalingConstant * concentric);
          } else {
            PWMwriter = 79;
          }
        } else {
          engagedWeight = eccentric;

          if (engagedWeight != 0) {
            PWMwriter = round(weightScalingConstant * eccentric);
          } else {
            PWMwriter = 15;
          }
        }
        break;

      case 2:
        PWMwriter = 79;
        break;

      default:
        PWMwriter = 79;
        break;
    }
  }

  if (millis() - tim > 100) {


    if (currentRemoteButtonStatus == LOW && PWMwriter >= c) {

      if (isButtonDelayElapsed) {
        pwm.analogWrite(TorqueRefPinA, PWMwriter);
        pwm.analogWrite(TorqueRefPinB, PWMwriter);


        //Serial.print("Flag rotation");
        //Serial.println(flag);

        if (flag == 1) {
          //Serial.println("Rotating anti clockwise");
        } else {
          //Serial.println("Rotating clockwise");
        }

        //Serial.print("Eccentric weight-> ");
        //Serial.println(eccentric);

        //Serial.print("Concentric weight-> ");
        //Serial.println(concentric);

        //Serial.print("PWMwriter-> ");
        //Serial.println(PWMwriter);
      } else {

        unsigned long elapsedTime = currentTime - lastButtonPressTime;
        int graduallyIncreasedPWM = round((float)PWMwriter / delayDuration * elapsedTime);

        pwm.analogWrite(TorqueRefPinA, graduallyIncreasedPWM);
        pwm.analogWrite(TorqueRefPinB, graduallyIncreasedPWM);

        //Serial.print("graduallyIncreasedPWM-> ");
        //Serial.println(graduallyIncreasedPWM);
      }


      if (isButtonDelayElapsed) {
        // Calculate the displacement in meters
        displacement = counter;

        // Calculate velocity in m/s
        velocity = displacement / (millis() - tim);

        // Calculate power in watts
        power = flag;

        powerChar.writeValue(power);
        displacementChar.writeValue(displacement);
        velocityChar.writeValue(velocity);
        cableCounterChar.writeValue(cableCounter);

        sendDataToMobileApp(power, displacement, velocity, cableCounter);

        //Serial.print("Writing velocity->");
        //Serial.println(velocity);
      }

      counter = 0;

      loop_counter++;
      //Serial.print("Loop number running->");
      //Serial.println(loop_counter);
    } else {
      pwm.analogWrite(TorqueRefPinA, 79);
      pwm.analogWrite(TorqueRefPinB, 79);

      //Serial.println("Motor is in minimal speed");
    }


    tim = millis();
  }
}

void processJsonData(String jsonData) {

  // try {
  responseDocument.clear();

  Log("Raw json from mobile-> ", jsonData);

  DeserializationError error = deserializeJson(doc, jsonData);
  if (error) {
    Serial.print(F("Log:Error parsing JSON: "));
    Serial.println(error.c_str());

    // Build and send an error response
    responseDocument["error_message"] = error.c_str();
  } else {
    Log("Log:deserializeJson success");
    String message = doc["message"];
    int value = doc["eccentricWeight"];

    // Process the data and create a response JSON
    eccentric = doc["eccentricWeight"];
    concentric = doc["concentricWeight"];

    Log("concentric from json-> ", concentric);
    Log("eccentric from json-> ", eccentric);

    responseDocument["eccentricWeight"] = eccentric;
    responseDocument["concentricWeight"] = concentric;
    responseDocument["response_message"] = "Received Successfully and Processed";

    Log("value set successfully");
  }
  // } catch (const std::exception &e) {
  //   // Catch any exceptions that might occur during processing
  //   Serial.print(F("Log:Exception occurred: "));
  //   Serial.println(e.what());

  //   // Build and send an error response
  //   responseDocument["error_message"] = e.what();
  // }


  String jsonResponse;
  serializeJson(responseDocument, jsonResponse);
  SendJsonToMobile(jsonResponse);
  Log("Success");
}


void sendDataToMobileApp(float power, float displacement, float velocity, float cableCounter) {

  //try {
  responseDocument.clear();
  Log("Sending started");


  Log("direction-> ", power);
  Log("displacement-> ", displacement);
  Log("velocity-> ", velocity);
  Log("cableCounter-> ", cableCounter);


  // Process the data and create a response JSON
  responseDocument["rotation"] = power;
  responseDocument["displacement"] = displacement;
  responseDocument["velocity"] = velocity;
  responseDocument["cableCounter"] = cableCounter;


  String jsonResponse;
  serializeJson(responseDocument, jsonResponse);
  SendJsonToMobile(jsonResponse);
  Log("Sending successful");
  // } catch (const std::exception &e) {
  //   // Catch any exceptions that might occur during processing
  //   Serial.print(F("Log:Exception occurred: "));
  //   Serial.println(e.what());

  //   // Build and send an error response
  //   responseDocument["error_message"] = e.what();
  // }
}


//New way to log message, dont use serial
void Log(String message) {
  String logMessage = "Log: " + message;
  //Serial.println(logMessage);
}
void Log(String message, String value) {

  String logMessage = "Log: " + message;

  //Serial.print(logMessage);
  //Serial.println(value);
}
void Log(String message, int value) {

  String logMessage = "Log: " + message;

  //Serial.print(logMessage);
  //Serial.println(value);
}
void Log(String message, float value) {

  String logMessage = "Log: " + message;

  //Serial.print(logMessage);
  //Serial.println(value);
}


void SendJsonToMobile(String message) {
  Serial.println(message);
}

I moved your topic to an appropriate forum category @heroickunal.

In the future, please take some time to pick the forum category that best suits the subject of your topic. There is an "About the _____ category" topic at the top of each category that explains its purpose.

This is an important part of responsible forum usage, as explained in the "How to get the best out of this forum" guide. The guide contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.