Sonar Sensor Trouble incorporating millis

I have been reading through the suggested articles on this subject, but can't seem to make it work for HC-SR04 Sonar Sensors. The idea is to make the 4 motors go backwards once the Sonar sensor is within 30cm. The program cannot have any delays in it, and for some reason, the code is not causing the motors to go full backwards, rather it sort of tries to go backwards. Something is interfering. What am I doing wrong? It would be nice to start with getting millis working.

void sonarSensors() {                                            /* HC-SR04 Sonar Sensors (x3) */
  const int echoPinG = 24;
  const int trigPinG = 25;
  long sonarDuration;
  int sonarDistance;
  int trigState = LOW;
  unsigned long timeBeforeSonar = 0;
  const long millisDelaySonar = 10;

  unsigned long currentTimeSonar = millis();
  if (currentTimeSonar - timeBeforeSonar >= millisDelaySonar) {
    timeBeforeSonar = currentTimeSonar;
    if (trigState == HIGH) {
      digitalWrite(trigState, HIGH);
    } else {
      digitalWrite(trigState, LOW);
    }
    digitalWrite(trigPinG, trigState);
  }
  // these three lines work if above is commented out
  //digitalWrite(trigPinG, HIGH);
  //delayMicroseconds(100);
  //digitalWrite(trigPinG, LOW);

  sonarDuration = pulseIn(echoPinG, HIGH);
  sonarDistance = sonarDuration * 0.034 / 2;
  if (sonarDistance  <= 30) {  //this and below acts very sluggish
    Serial.println(sonarDistance);
    digitalWrite (in1, HIGH);
    digitalWrite (in2, LOW);
    digitalWrite (in3, HIGH);
    digitalWrite (in4, LOW);            /* go backwards until the obstruction cannot be seen */
    digitalWrite (in5, HIGH);
    digitalWrite (in6, LOW);
    digitalWrite (in7, HIGH);
    digitalWrite (in8, LOW);
    analogWrite (enableA_RR, motorASpeedMax);
    analogWrite (enableB_LR, motorBSpeedMax);
    analogWrite (enableC_RF, motorCSpeedMax);
    analogWrite (enableD_LF, motorDSpeedMax);
  }
}

a quick look

sonarDistance does integer truncating in this line
sonarDistance = sonarDuration * 0.034 / 2;

Make it a float and retry.

Good catch, but no, same. It repeats 0.00 over and over in the Serial Monitor regardless of the distance. I am not getting the millis section right.

Please add

Serial.println(sonarDuration);

right after

sonarDuration = pulseIn(echoPinG, HIGH);

to see if it gets a proper value.

Why have you got code for operating motors in a function for reading a sonar?

If you keep the activities in short single purpose functions it makes a program much easier to develop and debug. You can test each function separately. Have a look at Planning and Implementing a Program

Also, post your complete program.

...R

Lets do it this way then... in any case, distance and duration are not printing because the MILLIS isnt working properly. I wish I could send the whole code here. The forum wont take a program that long. What is happening with my millis code that is incorrect? The three lines that have arrows fix the problem, so it has to be the millis code.

void sonarSensors() {                                           
  const int echoPinG = 24;
  const int trigPinG = 25;
  long sonarDuration;
  float sonarDistance;
  int trigState = LOW;
  unsigned long timeBeforeSonar = 0;
  const long millisDelaySonar = 10;

  unsigned long currentTimeSonar = millis();
  if (currentTimeSonar - timeBeforeSonar >= millisDelaySonar) {
    timeBeforeSonar = currentTimeSonar;
    if (trigState == HIGH) {
      digitalWrite(trigState, HIGH);
    } else {
      digitalWrite(trigState, LOW);
    }
    digitalWrite(trigPinG, trigState);
  }
  // these three lines work if above is commented out
  //digitalWrite(trigPinG, HIGH);           <-----------------------------------------------
  //delayMicroseconds(10);                  <-----------------------------------------------
  //digitalWrite(trigPinG, LOW);            <-----------------------------------------------

  sonarDuration = pulseIn(echoPinG, HIGH);
  Serial.println(sonarDuration);
  sonarDistance = sonarDuration * 0.034 / 2;
  if (sonarDistance  <= 30) {  
    Serial.println(sonarDistance);
   
  }
}

Deve:
I wish I could send the whole code here. The forum wont take a program that long.

You can post it as an attachment.

I'd really rather not. Its HUGE and incorporates many sensors, motors, servos, and all having nothing to do with the problem. I will though.. if you guys feel there is not enough information here to solve the problem.

all having nothing to do with the problem.

I wish I had a fiver for every time that turned out not to be the case. :smiley:

Deve:
I'd really rather not. Its HUGE and incorporates many sensors, motors, servos, and all having nothing to do with the problem

Can you create a cut-down program that is complete and illustrates the problem.

It is almost impossible to debug a problem when all we can see is a small part of a program. The problem is most often in some place that you did not think it would be - that's why you haven't found it :slight_smile:

...R

so what you guys are saying is, there is nothing apparently wrong with the millis delay code presented? That helps a lot if that's true. Way too much involved and a waste of everyones time to upload all the radio, sensor, motor, servo code that works perfectly. Since only that code is commented out, it HAS to be there. No?

THIS looks okay?

unsigned long currentTimeSonar = millis();
  if (currentTimeSonar - timeBeforeSonar >= millisDelaySonar) {
    timeBeforeSonar = currentTimeSonar;
    if (trigState == HIGH) {
      digitalWrite(trigState, HIGH);
    } else {
      digitalWrite(trigState, LOW);
    }
    digitalWrite(trigPinG, trigState);
  }
  // these three lines work if above is commented out
  //digitalWrite(trigPinG, HIGH);           <-----------------------------------------------
  //delayMicroseconds(10);                  <-----------------------------------------------
  //digitalWrite(trigPinG, LOW);            <-----------------------------------------------

so what you guys are saying is, there is nothing apparently wrong with the millis delay code presented?

No, I think what we're saying is that keyhole-surgery on software is hard.

    if (trigState == HIGH) {
      digitalWrite(trigState, HIGH);

Is trigState a pin number? :slight_smile:

No. these are the variables..

const int echoPinG = 24;
const int trigPinG = 25;
long sonarDuration;
float sonarDistance;
int trigState = LOW;
unsigned long timeBeforeSonar = 0;
const long millisDelaySonar = 10;

I am trying to get millis to work the same way the single LED that I have on the car works that tells me when the radios are talking to each other...

const int ledPin = 9;                            /* the Digital PWM pin the LED is attached to */
int ledState = LOW;                                           /* Start with the LED turned off */
unsigned long timeBefore = 0;           /* Time since the last reset or reload (used for delay)*/
const long millisDelay = 30;                                /* LED Blink Interval for liteItUp */


void liteItUp() {  // this works fine
  unsigned long currentTime = millis();
  if (currentTime - timeBefore >= millisDelay) {
    timeBefore = currentTime;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
}

not having any luck getting the sonar sensors to work the same way.

Have another careful read of reply#12 and reply #10

10 is mine, 12 asks if trigState is a pin, which I replied with the variables involved which show that no, trigState is a condition. Its very odd this isnt working since the LED code works. And, if I disable the LED code so there is no possibility of a millis conflict, no change. The serial println just repeats 0 about every second. even though its only supposed to print if distance is less than 30 cm. Does it at all distances.

Ok, read reply#12 ( all of it) very carefully

I see.. but I changed that HIGH to a LOW and it made no difference. (that is why it was HIGH). I am really shooting blanks here! :slight_smile:

Not carefully enough.

I see what I did, but with it fixed like below, I get a 0 in the serial monitor about every second.

const int echoPinG = 24;
const int trigPinG = 25;

long sonarDuration;
int sonarDistance;

int trigState = HIGH;
unsigned long timeBeforeSonar = 0;
const long millisDelaySonar = .00001;

void sonarSensors() {                                            /* HC-SR04 Sonar Sensors (x3) */
  unsigned long currentTimeSonar = millis();
  if (currentTimeSonar - timeBeforeSonar >= millisDelaySonar) {
    timeBeforeSonar = currentTimeSonar;
    if (trigState == LOW) {
      trigState = HIGH;
    } else {
      trigState = LOW;
    }
    digitalWrite(trigPinG, trigState);
  }
  // these three lines work if above is commented out
  //digitalWrite(trigPinG, HIGH);
  //delayMicroseconds(10);
  //digitalWrite(trigPinG, LOW);

  sonarDuration = pulseIn(echoPinG, HIGH);  
  sonarDistance = sonarDuration * 0.034 / 2;
  if (sonarDistance  <= 30) {  //this and below acts very sluggish
    Serial.println(sonarDistance);

(doesnt seem to matter what you put in millisDelaySonar) Am I still missing something?