Millis Function Problem

Hi there;

In my project, I measure the rotation torque with the hx711 and a torque sensor. I connected a 6V brushless DC motor to one side of the torque sensor, and on the other side is the material whose torque I want to measure. I have calibrated the torque sensor and I can get the correct measurement. I am sharing the code I wrote below with you.

#include "HX711.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define startButton 3
#define motorSpeedPin 6
#define motorInputPin_1 7
#define motorInputPin_2 8

byte pinData = 4;
byte pinClk = 5;

HX711 scale;
float calibration_factor = 424956.0;
float torqueValue;
int startButtonState = 0;
int testCounter = 0;
bool startTest = false;
bool idleTest = false;
bool motorTest = false;
unsigned long waitTime;
unsigned long currentMillis;

LiquidCrystal_I2C lcd(0x27, 16, 2);

void TORQUE_SENSE();
void PAUSE();
void MOTOR();
void LCD_DISPLAY();

void setup()
{
  Serial.begin(9600);
  lcd.begin();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("SAYAC:");
  lcd.setCursor(6, 0);
  lcd.print(testCounter);
  lcd.setCursor(0, 1);
  lcd.print("TORK:");
  lcd.setCursor(5, 1);
  lcd.print(torqueValue);
  pinMode(startButton, INPUT);
  pinMode(motorInputPin_1, OUTPUT);
  pinMode(motorInputPin_2, OUTPUT);
  pinMode(motorSpeedPin, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(2), PAUSE, RISING);
  scale.begin(pinData, pinClk);
  scale.set_scale();
  scale.tare();
  long zero_factor = scale.read_average();
  Serial.print("Zero factor: ");
  Serial.println(zero_factor);
  digitalWrite(motorSpeedPin, LOW);
  digitalWrite(motorInputPin_1, LOW);
  digitalWrite(motorInputPin_2, LOW);
}

void loop()
{
  currentMillis = millis();
  startButtonState = digitalRead(startButton);

  if (startButtonState == 1)
  {
    startTest = true;
  }

  if ((startButtonState == 0) && (idleTest == true))
  {
    torqueValue = 0;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("SAYAC:");
    lcd.setCursor(6, 0);
    lcd.print(testCounter);
    lcd.setCursor(0, 1);
    lcd.print("TORK:");
    lcd.setCursor(5, 1);
    lcd.print(torqueValue);
    idleTest = false;
  }

  while (startTest == true)
  {
    TORQUE_SENSE();
    MOTOR();
    LCD_DISPLAY();
  }
}

void TORQUE_SENSE()
{
  scale.set_scale(calibration_factor);
  torqueValue = scale.get_units(10);
  Serial.print("Reading: ");
  Serial.print(torqueValue, 2);
  Serial.print(" Nm");
  Serial.println();
  lcd.setCursor(5, 1);
  lcd.print(torqueValue, 2);
  delay(10);
}

void MOTOR()
{
  bool motorIdle = false;

  if (torqueValue < 0.3)
  {
    analogWrite(motorSpeedPin, 255);
    digitalWrite(motorInputPin_1, HIGH);
    digitalWrite(motorInputPin_2, LOW);
    waitTime = currentMillis;
    motorTest = true;
  }

  else if ((motorTest == true) && (motorIdle == false))
  {

    analogWrite(motorSpeedPin, 150);
    digitalWrite(motorInputPin_1, HIGH);
    digitalWrite(motorInputPin_2, LOW);
    if (currentMillis - waitTime > 500)
    {
      motorIdle = true;
      motorTest = false;
    }
  }

  else if (motorIdle == true)
  {
    digitalWrite(motorInputPin_1, LOW);
    digitalWrite(motorInputPin_2, LOW);
    delay(3000);
    analogWrite(motorSpeedPin, 255);
    digitalWrite(motorInputPin_1, LOW);
    digitalWrite(motorInputPin_2, HIGH);
    delay(3000);
    digitalWrite(motorInputPin_1, LOW);
    digitalWrite(motorInputPin_2, LOW);
    testCounter++;
    motorTest = false;
    motorIdle = false;
  }
}
void LCD_DISPLAY()
{
  lcd.setCursor(0, 0);
  lcd.print("SAYAC:");
  lcd.setCursor(6, 0);
  lcd.print(testCounter);
}

void PAUSE()
{
  startTest = false;
  idleTest = true;
  motorTest = false;
}

The part I want to ask you is that I measure time with millis in the code block below and when the time is completed, I want to exit that if statement.

else if ((motorTest == true) && (motorIdle == false))
  {

    analogWrite(motorSpeedPin, 150);
    digitalWrite(motorInputPin_1, HIGH);
    digitalWrite(motorInputPin_2, LOW);
    if (currentMillis - waitTime > 500)
    {
      motorIdle = true;
      motorTest = false;
    }
  }

When I run the code, the motor turns with a 255 PWM signal and when the torque reaches the desired value, it continues to rotate with a 150PWM signal and hangs there. I used the millis function to get it out, normally after 500 milliseconds, I want the code to exit that statement.

I couldn't find which part of the code I made a mistake. Can you help me with this?

You dont't renew the value of currentMillis inside the while loop:

so your timeout condition will never match

1 Like

I try your suggest but doesnt work I change the code like this but it still stuck if statement

 while (startTest == true)
  {
    currentMillis = millis();
    TORQUE_SENSE();
    MOTOR();
    LCD_DISPLAY();
  }

Your while condition is

so you need change startTest for stop the loop:

I want it to loop. I'm using 2 buttons, one start and one pause, when I press the start button, the test will start. The motor will rotate clockwise, when the torque I have determined reaches, its speed will decrease for 500ms, then it will stop for 3 seconds and turn counterclockwise for 3 seconds, then this process will be repeated. I defined the pause button as an interrupt. I want the system to exit the loop when I press it. How can I do it without removing it from the loop?

In your case this while loop should be controlled by another flag, unless you want that it runs until you press the Stop knob

It's your loop. If the while should be looping on a different condition, it should use the different condition.

You could put something like @b707's code in to the loop that sets startTest to false when the time runs out.

The way your code is, you could also replace the while with an if and rely on loop() to do the looping.

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