Finding a good distance sensor & best way to implement it

Hi, i need help finding a good distance sensor, right now im using a cheaper model http://dx.com/p/ultrasonic-sensor-distance-measuring-module-138563 but it’s not as accurate/powerful as I need.
Now when my construction comes to an end i also found that the idea of implementing the sensor might not work . If one looks at the image (no 1) the sensor is attached to the frame, i want to measure the distance between people in the room and the sensor. But with the angle of the sensor it will only catch people who’s within that angle (no1 in image 1), id like to cover bigger parts of the room see no2 in image 1. Would a separate sensor which communicates (ir, wireless?) with the arduino be the best solution? See image 2.

are there sensors with a wide spread?

Are there better sensors than the distance sensor?

Best
G

No one has ansered yet, because it is not easy to anser you question.

Ultrasonic is one of the many ways to detect a distance. There is no “good” method, it depends on what you want.

Detecting motion/distance: ultrasonic, PIR, doppler radar, remote temperature sensing, laser, kinect, magneto-electric field disturbance, and many more.

You could use a few ultrasonic sensors, but I don’t know if the library supports that.
If you want to detect something around a corner, you could try a second Arduino with a wireless communication.

Hi, thanks for your answer.

would any of these suggestions of yours be better than the other? I need to start somewhere, and the ultrasonic one i have only measure straight, are there any which measures in a wider angle?

Put your rangefinder on a servo. You can then scan over 180°.

Servo! Brilliant! :P

Perhaps some guidance with the concept.

Ill mount the range finder on a servo which scans 180°. Would the best be to 'lock' the servo when an object is found (with in range)? and when the object disappears it starts to rotate again!?

I picture this as a separate construction where the sensor transmits the data to the arduino wireless, how would this be don in the best/easiest way, what are the wireless transmission range?

Scan the ranges into an initial array. Save that array to oldRanges. After the next scan, newRanges, you can compare the arrays for changes. Be aware that you can't scan very fast. Look at the servo specs and they should have a time to slew 60°. Usually on the order of 200mS so 180° is a minimum of 600mS without time to stop and get a range, ideally. I can't really speak on wireless as i have little experience.

Hmm, i've been thinking of this now, do i understand it right if id do it like this:

  1. Use the ping-library with the sensor.
  2. when the sensor starts to scan the servo will rotate 180°, scanning results will be put into the array oldRanges
  3. when reaching 180° the sensor will start scan to the newRanges array and the servo rotates back.
  4. oldRanges is compared with newRanges all the time in relation to the position of the servo
  5. if oldRanges and newRanges are different at the servo pos of 100° the servo will stop at that position
  6. when the object is gone (without range) it will start scan again

Hmm In my head it sounds as a good plan!? Will it work?

Seems good. Scan from 0 to 180 for oldRanges and return to 0 and go to 180 collecting newRanges so the array indexes match. Before the next scan, copy the newRanges to oldRanges (overwrite the old oldRanges) and collect a new set of newRanges.

Great, would this be possible, instead of returning to 0 — can I start again from 180, but before starting reverse the oldRanges array? then id have a continious scan

Great, would this be possible, instead of returning to 0 — can I start again from 180, but before starting reverse the oldRanges array? then id have a continuous scan, from 0 to 180 from 180 to 0 ?!


Edit, i posted a new thread in the programming part


Hi,

so i started to construct this, at least trying. I quite fast discovered that I have now idea how to make a ‘dynamic’ array which is reversed and compared … Would you have a sample? As you see, I output the distance to sonarValue.

Another thing is when i try to speed the servo up it doesnt go further than 150°.

    #include <NewPing.h>
    #include <VarSpeedServo.h>
 
    VarSpeedServo MyServo;        // servo objects

    #define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.
    #define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
    #define MAX_DISTANCE 500 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
    NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

// Declare variables
    const unsigned long distansInterval = 50;
    const unsigned long distansTracker = 10;
    const unsigned long servoTracker = 1;

    int sonarValue;
    int uS;
 
    int servoSpeeds = 30; // sweep speed, 1 is slowest, 255 fastest)
    int servoMinPosition = 0; // the minumum servo angle
    int servoMaxPosition = 180; // the maximum servo angle
 
    unsigned long distansTimer;
    unsigned long distansTrackerTimer;
    unsigned long servoTimer;



// End vars 
 
  void setup() {  
    Serial.begin(115200);    
     distansTimer = millis ();
     distansTrackerTimer = millis ();
     MyServo.attach(9);       
     MyServo.slowmove(servoMinPosition,servoSpeeds) ; // start sweeping from min position
  }

  void runServo(){
    if( MyServo.read() == servoMinPosition){
      MyServo.slowmove(servoMaxPosition,servoSpeeds) ; 
    }       
    else if( MyServo.read() == servoMaxPosition){
      MyServo.slowmove(servoMinPosition,servoSpeeds) ; 
    }    

  }
  
/* //////////////
Void Update sensor 
*//////////////
  void distansIntervalFunction (){
    unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
    sonarValue = uS / US_ROUNDTRIP_CM;
    distansTimer = millis ();  
  }

/* //////////////
Send to exbee
*//////////////

  void distansTrackerFunction (){
  
  }
 
/* //////////////
Void LOOOOP 
*/  void loop (){                 
    Serial.println("MILLIS");
    if ( (millis () - distansTimer) >= distansInterval){
      distansIntervalFunction ();
    }
/*    if ( (millis () - distansTrackerTimer) >= distansTracker){  
      distansTrackerFunction ();
    }*/
    if ( (millis () - servoTimer) >= servoTracker){  
      runServo ();
    }    
  }

I was interested in your project so I set up a servo and HC-SR04. Here is the code that I came up with. Not pretty but it works. It scans from 0 to 180 degree to collect an initial set of data. Then scans 180 to 0 degrees, comparing the new range to the last at that angular position, at each step and stops for 3 seconds if the range has changed. It then continues scanning. I used the servo library (comes with IDE) that i am familiar with and my own code for the rangefinder. It shows how to use arrays the way that I described. Be aware that Servo.read does not return the position of the servo, but the value last sent to it. You need to give the servo time to move to position.

#include <Servo.h>
Servo rngServo;

int initPin = 4;
int echoPin = 5;
byte inches;
byte oldRanges[10];
byte newRanges[10];

void setup() {
  Serial.begin(115200);
  pinMode(initPin, OUTPUT);
  pinMode(echoPin, INPUT);
  rngServo.attach(3);
  rngServo.write(0);
  delay(1000);
  initScan();  // initial left to right scan to fill oldRanges
}

void loop() {
  for(int n=9; n>=0; n--) {  // scan right to left
    byte angle = n*20;  // 20 degree steps
    rngServo.write(angle);
    delay(250);  // wait for servo to get in position
    newRanges[n] = Rng();	//PING
    unsigned long  time = millis();  //start wiat clock
    if(abs(newRanges[n] - oldRanges[n]) > 2) {  // if range has changed by more than 2"
      while(millis()-time < 3000);  // hang here for 3 seconds
    }
  }
  for(int n=0; n<10; n++) {  // copy new data to oldRanges
    oldRanges[n] = newRanges[n];
  }
  delay(250);
  for(int n=0; n<10; n++) {  // scan left to right
    byte angle = n*20;
    rngServo.write(angle);
    delay(250);
    newRanges[n] = Rng();
    unsigned long  time = millis();
    if(abs(newRanges[n] - oldRanges[n]) > 2) {
      while(millis()-time < 3000);
    }
  }
  for(int n=0; n<10; n++) {
    oldRanges[n] = newRanges[n];
  }
  delay(250);
}

byte Rng () {
  byte rngByte;
  boolean cond;
  boolean timeOut;
  unsigned long time = 0;
  //digitalWrite(13, HIGH);
  digitalWrite(initPin,LOW);
  delayMicroseconds(8);
  digitalWrite(initPin, HIGH);
  delayMicroseconds(8);
  digitalWrite(initPin, LOW);
  //while(digitalRead(echoPin)==HIGH);
  while(digitalRead(echoPin)== LOW);
  time = micros();
  timeOut = LOW;
  do {
    cond = digitalRead(echoPin);
    if(micros() - time > 40000) {
      cond = LOW;
      timeOut = HIGH;
      //Serial.println("Timeout");
    }
  }
  while(cond == HIGH);
  unsigned long xtime = micros()-time;
  float rng = xtime/148.00;
  rngByte= byte(rng);
  if(timeOut == HIGH) {
    rngByte = 255;
  }
  return(rngByte);
}



void initScan() {
  byte angle;
  for(int n=0; n<10; n++) {
    angle = n*20;
    rngServo.write(angle);
    delay(300);
    oldRanges[n]= Rng();
  }
}