Ultrasonic Sensor Slow Reacting

Hi,

I am using an ultrasonic sensor to sense when something crosses its path. When a button is pressed via python script over serial the arduino receives the signal via serial the motors start a pully and when the ultrasonic sensor senses a distance change it reverses the motor until it reaches an enstop. It all works fine but I cannot figure out why when something crosses the ultrasonic sensor it sometimes is instant sometimes I have to hold my hand in front of the sensor and it can take a few seconds to react. Is this my coding not sure where to start to figure it out. I think its my codeing as I am new. Any help would be great.

#include <NewPing.h>

#define CW 8 //CW is defined as pin #7//
#define CCW 7 //CCW is defined as pin #8//
#define M1Speed 9  //Pin Controls Motor Speed

//BUTTONS/SWITCHES

const int LS2 = 4; //  Home Endstop

int buttonState2 = 0;// LS2 Limit Swith
int startVend = 0;// Start Vend Button

//MOTOR SPEED CONTROL
#define M1Speed 9  //Pin Controls Motor Speed


//UltraSonic Sensor
#define trigPin 12 // Trigger pin for sonar sensor
#define echoPin 11 // Echo pin for sonar sensor
#define trigPower 10  //  Ultrasonc Trig Power Pin
//boolean sonarOn = false;
//boolean sonarSwitchLast = false;

void setup() { //Setup runs once//

  //Controls Motor
  pinMode(CW, OUTPUT); //Set CW as an output//
  pinMode(CCW, OUTPUT); //Set CCW as an output//
  pinMode(M1Speed , OUTPUT );  //Set M1Speed - Motor Speed

  //Controls Endstop
  //  pinMode(LS, INPUT_PULLUP);
  pinMode(LS2, INPUT_PULLUP);
  // pinMode(VD, INPUT_PULLUP);

  //ULTRASONIC SENSOR
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
  pinMode(trigPower, OUTPUT);
  //digitalWrite(trigPower, LOW);   //ultrasonic sensor pin control

  Serial.begin (250000);
}


void loop() { //Loop runs forever//


  //ULTRASONIC SENSOR

  long duration, distance;

  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);

  // Calculating the distance
  distance = duration * 0.034 / 2;

  Serial.print("Distance: ");
  Serial.println(distance);



  startVend = int(Serial.read());

  startVend = digitalRead(startVend);
  if (startVend == LOW) {
    digitalWrite(trigPower, HIGH);
    digitalWrite(CW, HIGH);
    digitalWrite(CCW, LOW);
    analogWrite(M1Speed, 200);

  }

  if (distance > 26) {
    digitalWrite(CW, LOW);
    digitalWrite(CCW, HIGH);
    analogWrite(M1Speed, 200);  // Run in half speed

  }

  buttonState2 = digitalRead(LS2);  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState2 == LOW) {

    digitalWrite(CW, HIGH);
    digitalWrite(CCW, LOW);
    delay(100);
    digitalWrite(CW, HIGH);
    digitalWrite(CCW, HIGH);
    digitalWrite(trigPower, LOW);
    analogWrite(M1Speed, 100);

  }
}

What is this supposed to do? Is startVend always a valid pin number?

startVend = int(Serial.read());

  startVend = digitalRead(startVend);

  if (startVend == LOW)...

Yes the startVend is the trigger used to set everything in motion. So when I click on the button on my computer it triggers the startVend process that starts the dc motor and ultrasonic sensor. Then once the sensor reads 26cm or less it reverses the motor until it hits the end stop and it then moves the belt forward to release the end stop and then shuts off motor and sensor power. Then repeats when button is pushed. Works perfect except it does not always work when the ultrasonic is supposed to trigger the motor to go in reverse. Sometimes I can do it 10 times and it works perfectly and then sometimes it can take up to 4 seconds for it to work. Its really random.

DaveEvans sorry forgot to really answer your question, startVend I do not have a pin number for as its being controlled over serial port. So its just waiting for a 1 or a 0 as far as my limited knowledge figures. I would assume no pin would be required as it would not be connected to anything?

But this

startVend = digitalRead(startVend);

is reading a pin and returning High or Low.

If you converted data:

startVend = int(Serial.read());

and read in '0' to '9' with startVend = byte (Serial.read() - 0x30); // convert ASCII to decimal

then the digitalRead could read a pin from 0 to 9.

CrossRoads: But this

startVend = digitalRead(startVend);

is reading a pin and returning High or Low.

If you converted data:

startVend = int(Serial.read());

and read in '0' to '9' with startVend = byte (Serial.read() - 0x30); // convert ASCII to decimal

then the digitalRead could read a pin from 0 to 9.

Thanks for the reply. Forgive me as I don't know a bunch about this stuff and am learning, what would be benefit be to doing it your way? Would it allow more pins to be controlled in the long run? Is the code I used limiting me or just simiply wrong?

I think the code is simply wrong.

digitalRead() should always access some well defined pin number and not 0 or 1, because those are used for uploading programs and communicating with the serial monitor.

At the moment, it isn't clear to me what that pin might be.

jremington: I think the code is simply wrong.

digitalRead() should always access some well defined pin number and not 0 or 1, because those are used for uploading programs and communicating with the serial monitor.

At the moment, it isn't clear to me what that pin might be.

Could very well be, problem is its working. Not asking you to write me the correct code but could you explain why it would work? Below is the code for python on my computer I am using, just demo code that got me what I wanted so if its wrong thats ok as I will be working on it later. It made it call the arduino startVend.

import serial
import time
from tkinter import *


def led_on():
    arduinostartVend.write(b'1')


#     arduinoStartVend.write(b'0')


led_control_window= Tk()
btn=Button(led_control_window,text="led on",command=led_on)
#btn2=Button(led_control_window,text="led off",command=led_off)
btn.pack()
#btn2.pack()
arduinostartVend = serial.Serial('/dev/cu.usbmodem141111',115200)

So not sure why its working.

You still haven't explained what the following is supposed to do, and we certainly have no clue.

What ARE the values of startVend? Those may or may not correspond to valid pins.

  startVend = int(Serial.read());

  startVend = digitalRead(startVend);

jremington: You still haven't explained what the following is supposed to do, and we certainly have no clue.

All the clues are there, OP provided it all. It's elemental, my dear Watson. All that's needed is some sleuthing as OP is not exactly forthcoming with information.

  startVend = int(Serial.read());
  startVend = digitalRead(startVend);

Based on the Python snippet: sometimes the value 1 (or 0, but it's commented out) can be sent over the Serial to the Arduino (as in the actual value, not the ascii character). So if there's a value on the Serial buffer, that's going to be a 1, and if there is no character the value of startVend will be -1 (there is no checking whether there's anything available in the first place!). So most of the time this value will be -1. This value is then used to read that exact pin: possibilities are -1, 0 and 1. The first is an invalid number (I don't know what is done with that - I assume it's ignored), the other two are are Rx and Tx, as in the very Serial connection you read the value from, definitely not connected to a switch or anything else that makes sense to digitalRead(). Then there's of course the lesser problem (technically correct but very bad practice, something you would expected in the Obfuscated C Contest rather than in an Arduino sketch which is meant to be human readable) to reuse the variable that contains the pin number to hold the pin status.

Hi, Youhave the NewPing library loaded yet use this code.

//ULTRASONIC SENSOR

  long duration, distance;

  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);

  // Calculating the distance
  distance = duration * 0.034 / 2;

  Serial.print("Distance: ");
  Serial.println(distance);

Why? You are not using any of the NewPing functions. Have you tried NewPing and its examples? What happens if you ditch the Python and serial comms and us a button, does it work every time then. Also connect a LED to one of the Arduino controllers outputs and get it to come on and off depending on the state of startVend. You need to add some diagnostics, to show various variable states. Tom... :)