PulseIn Doesn't work?

Hi!
I'm using a sonar sensor to trigger a nerf gun which i modified to be turned on by a relay. It worked fine, until I lost the source code and now I wanted to re-write it.

Here's the code:

class RangeFinder {
  public:
    long pulse();
    int pulsein = 4;
    int pulseout = 3;
  private:
    long microsecondsToCentimeters(long microseconds);
};

long RangeFinder::microsecondsToCentimeters(long microseconds) {
  return microseconds / 29 / 2;
}

long RangeFinder::pulse() {
  long duration, cm;
  digitalWrite(pulseout, LOW);
  delayMicroseconds(2);
  digitalWrite(pulseout, HIGH);
  delayMicroseconds(5);
  digitalWrite(pulseout, LOW);
 
  duration = pulseIn(pulsein, HIGH);
  cm = microsecondsToCentimeters(duration);
  return cm;
}

class Nerf {
  public:
    void fire();
    int pin = 11;
};

RangeFinder rf;
Nerf n;

void Nerf::fire() {
  digitalWrite(pin,HIGH);
  delay(250);
  digitalWrite(pin,LOW);
}

//MAIN
void setup() {
  pinMode(rf.pulseout,OUTPUT);
  pinMode(rf.pulsein,INPUT);
  pinMode(n.pin,OUTPUT);
  Serial.begin(9600);
  pinMode(5,OUTPUT);
}

void loop() {
  long distance = pulseIn(rf.pulsein,HIGH);
  Serial.println(distance);
  if (distance < 70 && distance != 0) {
    n.fire();
  }
}

On the serial monitor, the only value of distance is always 0, and the ultrasound sensor doesn't even emit any sound (I have a bat detector).

I have checked that the pins are wired up correctly, why is it not working?

Why do you never call the RangeFinder::pulse() method? Just calling pulseIn() on the pin, when you have never sent a pulse out doesn't make sense.

instead of blindly allocating GPIO's you should have a member function (i.e. begin()) to have the programmer select the pins:

void RangeFinder::begin(int inPin, int outPin)
{
  pulsein = inPin;
  pinMode(pulsein, INPUT);
  pulseout = outPin;
  pinMode(pulseout, OUTPUT);
}

you created a method to return the distance, but you didn't use it.

something like this (untested):

class RangeFinder{
  public:
    void begin(const int inPin, const int outPin);
    long pulse();
    int pulsein;
    int pulseout;
  private:
    long microsecondsToCentimeters(long microseconds);
};
void RangeFinder::begin(int inPin, int outPin)
{
  pulsein = inPin;
  pinMode(pulsein, INPUT);
  pulseout = outPin;
  pinMode(pulseout, OUTPUT);
}
long RangeFinder::microsecondsToCentimeters(long microseconds) {
  return microseconds / 29 / 2;
}

long RangeFinder::pulse() {
  long duration, cm;
  digitalWrite(pulseout, LOW);
  delayMicroseconds(2);
  digitalWrite(pulseout, HIGH);
  delayMicroseconds(5);
  digitalWrite(pulseout, LOW);
 
  duration = pulseIn(pulsein, HIGH);
  cm = microsecondsToCentimeters(duration);
  return cm;
}

class Nerf {
  public:
    void fire();
    int pin = 11;
};

RangeFinder rf;
Nerf n;

void Nerf::fire() {
  digitalWrite(pin,HIGH);
  delay(250);
  digitalWrite(pin,LOW);
}

//MAIN
void setup() 
{
  Serial.begin(9600);
  rf.begin(4,3);
//  pinMode(n.pin,OUTPUT);
//  pinMode(5,OUTPUT);
}

void loop() 
{
  long distance = rf.pulse();
  Serial.println(distance);
  if (distance < 70 && distance != 0) 
  {
    n.fire();
  }
}

you should definitely re-name pulse() to something that better describes what the function is doing (e.g. getDistanceCM())

PaulS:
Why do you never call the RangeFinder::pulse() method? Just calling pulseIn() on the pin, when you have never sent a pulse out doesn't make sense.

Thanks!

I didn't spot that, and I knew it would be a dumb mistake such as that.

It always helps when someone who is unfamiliar with the code has a read. Anyway, thanks for the reply :slight_smile: