Stepper motor and DS18B20

Hi,

I am currently working on a small project. I have a Stepper Motor, push button, A4988 driver for motor, MOSFET module, potentiometer, DS18B20 sensor module, incremental rotary encoder and for controller Arduino UNO.

I am having an issue when I try to read temperature from DS18B20 it interrupts stepper motor for a fraction of a second. It is not such a big issue but I am wondering if can I fix it.

Thanks in Advance.

This is my code:

#include <Rotary.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 10
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress tempDeviceAddress;

Rotary rotary = Rotary(2, 3);

int pushButton = 6;
int buttonState, speedVar, counter, startTime, endTime, x, delayInMillis;
int stepPin = 5;
int dirPin = 4; 
int speedPin = A0;
int enablePin = 7; 
int MOSFETpin = 8;
int MOSFETpin2 = 9;
int spMeja = 150;
int zgMeja = 250; 
float razlika, temperature;
unsigned long lastTempRequest = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(pushButton, INPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT); 
  pinMode(speedPin, INPUT); 
  pinMode(enablePin, OUTPUT); 
  pinMode(MOSFETpin, OUTPUT); 
  pinMode(MOSFETpin2, OUTPUT); 
  
  digitalWrite(enablePin, HIGH); 
  digitalWrite(dirPin,HIGH);
  
  attachInterrupt(0, rotate, CHANGE);
  attachInterrupt(1, rotate, CHANGE);
  
  sensors.begin();
  sensors.setResolution(0,9);
  sensors.setWaitForConversion(false);
  sensors.requestTemperatures(); 
  
  delayInMillis = 5000; 
  lastTempRequest = millis(); 
  
  Serial.begin(2000000);
}

void loop() {

  if(digitalRead(pushButton) == 1){
    
    counter = 0;
    buttonState = 1; 
    digitalWrite(enablePin, LOW); 
    
  }

  while (buttonState == 1){
    
    if (millis() - lastTempRequest >= delayInMillis){

      temperature = sensors.getTempCByIndex(0);
      Serial.println(temperature, 1);     
        
      sensors.requestTemperatures(); 
      lastTempRequest = millis(); 
  }

    for(x = 0; x < 200; x++) {
      
      speedVar = map(analogRead(speedPin), 0, 1023, 700, 16000);
      
      if (x == 0) {
        
        startTime = millis(); 
      }
      digitalWrite(stepPin,HIGH);
      delayMicroseconds(speedVar); 
      digitalWrite(stepPin,LOW);
      delayMicroseconds(speedVar);
      
      if (x == 199){

        endTime = millis(); 
        razlika = endTime - startTime; 
        float seconds = razlika / 1000;
        float minutes = seconds / 60;
        long int rpm = 1/minutes;
        Serial.println(rpm); 
      }
    }
  }
}

void rotate() {
  
  unsigned char result = rotary.process();
  
  if (result == DIR_CW) {
    counter++;
    //Serial.println(counter);
  } else if (result == DIR_CCW) {
    counter--;
    //Serial.println(counter);
  }
  
  if (counter > spMeja && counter < zgMeja) {
    
   digitalWrite(MOSFETpin, HIGH);
   //digitalWrite(MOSFETpin2, HIGH);     
   }
    
  else {
    
   digitalWrite(MOSFETpin, LOW); 
   //digitalWrite(MOSFETpin2, LOW); 
 }

 if (counter == 600){
    
    counter = 0;
  
 }
}

It's a long time since I looked at the DS18B20 library, but I have a vague recollection that getTempCByIndex is slow because it has to query the bus and figure out which the zeroth sensor is (in this case).

It might be worth using the sensor id instead, which I'd probably try first and then read the library if it didn't help.

Yes , depending on the resolution it can take up to around 1/2 sec or so to respond , your program is held up whilst this happens . The library works this way and hence the delay.
There is a method where by you can initiate a “ conversion” and then go back later to pickup the result and so not hold up your sketch .
Can’t be more specific from where I am at the moment , but google might help you “ read 18b20 no delay “ or similar .

hammy:
Yes , depending on the resolution it can take up to around 1/2 sec or so to respond , your program is held up whilst this happens . The library works this way and hence the delay.
There is a method where by you can initiate a “ conversion” and then go back later to pickup the result and so not hold up your sketch .

That was my stance too, this'll be easy I thought. Then I saw this in the code:

sensors.setWaitForConversion(false);

You’ll have to look at the code and the data sheet for the Ds18b20 to see what’s happening . You start a conversion and a signal is next available to let you know that the conversion is complete( or not) and a new temperature value is available ( so you need not wait for it)
There are explanations out there and you’ll learn lots of stuff , which can’t be bad.
You may find some code that you can copy and then study it to see how it works .

The code in the OP already does asynchronous reads.

Thanks for your help, I tried with getting temperature by Address I still hear a click when controller reads it's value. It dosen't stop the motor but you hear a little click.

Here is a short video: (Listen carefully)

I assume that the click is caused by the longer delay between steps after the 200th. Both because of the calculations and serial printing as well as the Ds18b20, if it's being read on this iteration.

I'd be inclined to prove it by commenting those bits out and if they are the culprit, perhaps you can fix it by measuring the time they take and reducing the final delay accordingly.

Key to the problem is no doubt related to your use of delayMicroseconds() to time the steps. After the 200th step you do other things: print the rpm, read the sensor, and of course loop() itself looping around which also adds some Arduino system overhead. All those things make your 200th step longer than the other 199 steps.

One solution to this is to use a timer interrupt, then set the stepper in the ISR. That's also the point where you can update when you get the next interrupt, and with it the speed of rotation, and a counter to keep track of the number of steps taken. It'll make your whole code more responsive, as you can do other things in the meantime without worrying about the stepper having to make its steps.

I am only calculating RPM at the last step not reading DS18B20. As I recall from previus testing, calculating RPM didn't have an effect on the motor, only reading DS18B20.

How long does it take to read the sensor?

I didn't measure it, for now it reads every 5 seconds.