Pages: [1]   Go Down
Author Topic: PING)) Sensors.. Communication Help  (Read 935 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So I have 3 Ping)) sensors... I have 2 set up as receivers and 1 as a transmitter. I'm trying to get the distance(inches) for both of them on the serial monitor, but I keep receiving only 1 of the distances and not the other, but when I turn off one of them the other works. The problem seems to be when I need to read the signal from the PINGS))) it only reads one, what am I doing wrong?

Here is my code:

Code:
const int pingPin = 7;
const int pingPin1= 4;
const int pingPin2=2;

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
}

void loop()
{
  // establish variables for duration of the ping,
  // and the distance result in inches and centimeters:
  long duration, duration1, inches1, inches;
 
  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);
  pinMode(pingPin1, OUTPUT);
  pinMode(pingPin2, OUTPUT);
  digitalWrite(pingPin, LOW);
  digitalWrite(pingPin1, LOW);
  digitalWrite(pingPin2, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  digitalWrite(pingPin1, HIGH);
  digitalWrite(pingPin2, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  digitalWrite(pingPin1, LOW);
  digitalWrite(pingPin2, LOW);

  // The same pin is used to read the signal from the PING))): a HIGH
  // pulse whose duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(pingPin, INPUT);
  pinMode(pingPin2, INPUT);
  duration1 = pulseIn(pingPin2, HIGH);          //THE PROBLEM SEEMS TO BE HERE
  duration = pulseIn(pingPin, HIGH);             //THE PROBLEM SEEMS TO BE HERE
 
  // convert the time into a distance
  inches = microsecondsToInches(duration);
  delay(50);
  inches1 = microsecondsToInches(duration1);
  delay(50);
 
  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(inches1);
  Serial.print("in2, ");
  Serial.println();
 
  delay(100);
}

long microsecondsToInches(long microseconds)
{
  // According to Parallax's datasheet for the PING))), there are
  // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
  // second).  This gives the distance travelled by the ping, outbound
  // and return, so we divide by 2 to get the distance of the obstacle.
  // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
  return microseconds / 74 / 2;
}


Moderator edit: [code] [/code] tags added.
« Last Edit: December 27, 2012, 10:20:22 pm by Coding Badly » Logged

Queens, New York
Offline Offline
Faraday Member
**
Karma: 101
Posts: 3651
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

try this:

(duration1, duration) = pulseIn((pingPin2,pingPin), HIGH);         
Logged

Created Libraries:
TFT_Extension, OneWireKeypad, SerialServo, (UPD)WiiClassicController, VWID

Queens, New York
Offline Offline
Faraday Member
**
Karma: 101
Posts: 3651
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

please use code tags.

Quote
So I figured it out, I did it like this:....... But now I'm trying to figure out how I can run a motor when the transmitter is in a certain direction, does anyone know a certain calculation that will allow me to dictate what the direction the transmitter is, so it can drive to it?
For that, you can try which ever signal is the closest.
Logged

Created Libraries:
TFT_Extension, OneWireKeypad, SerialServo, (UPD)WiiClassicController, VWID

Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

please use code tags.

Quote
So I figured it out, I did it like this:....... But now I'm trying to figure out how I can run a motor when the transmitter is in a certain direction, does anyone know a certain calculation that will allow me to dictate what the direction the transmitter is, so it can drive to it?
For that, you can try which ever signal is the closest.

The main problem is that the pings)) signal is very narrow, so the receivers have to be close.

So what do you mean? how would it know which one is closer? for an example, receiver 1 is at 12 inch and receiver 2 is at 20 inch.. How would I know how far the robot has to drive or turn?
Logged

Queens, New York
Offline Offline
Faraday Member
**
Karma: 101
Posts: 3651
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't think there is an actual way, because all motors/servos are not the same. Unless you code it yourself with set ranges (between 5 - 12 inches, turn this much) that's what I did for my robot.
Logged

Created Libraries:
TFT_Extension, OneWireKeypad, SerialServo, (UPD)WiiClassicController, VWID

Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't think there is an actual way, because all motors/servos are not the same. Unless you code it yourself with set ranges (between 5 - 12 inches, turn this much) that's what I did for my robot.

Did you do a similar project?... But how will it know how much to turn, for example if its 5 inches or 50 inches?

And, I did not figure out how to use both sensors at once, going back to my first question, it didnt work, it only shows me one sensor!
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

try this:

(duration1, duration) = pulseIn((pingPin2,pingPin), HIGH);         

It didn't work!
Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

try this:

(duration1, duration) = pulseIn((pingPin2,pingPin), HIGH);          

It didn't work!

Well of course it didn't work! It was complete nonsense.

I don't understand what you're trying to achieve or how multiple ping sensors helps you achieve it. Are you trying to detect obstacles in multiple directions, or something? If so, the easiest way to read from multiple receivers is to pretend you have one sender and one receiver and do one 'ping' in the usual way, then do exactly the same thing with the sender and the other receiver. This means you will send out a separate ping for each receiver, but I don't see any harm in that.

The alternative is to use a completely different method to get the response from the receiver, which enables you to receive from two inputs simultaneously. That's going to be much harder to do, and is not the approach I'd recommend. But if you have a remote sender and you're trying to use stereo receivers to determine the direction to the source, then you will need to read them both simultaneously to see which one receives the pulse first. In this case the exact timing might not matter (you can't determine range unless you know when the pulse was sent) and all you'd care about was which receiver picked the pulse up first. I suspect you could do that using interrupts and direct port access to grab the state of both inputs with minimal latency, but it's going to need an approach that's very different to the conventional ping range finder.
« Last Edit: December 28, 2012, 05:51:01 am by PeterH » Logged

I only provide help via the forum - please do not contact me for private consultancy.

Queens, New York
Offline Offline
Faraday Member
**
Karma: 101
Posts: 3651
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry about that I kinda figured it would work being that arduino has port manipulation. I thought it would be able to read and write to multiple pins that way, but NO. Yea go with normal method of just getting the data from one at a time.

It should be made into a new feature. It would be so much easier access multiple pins, if it were possible.
Logged

Created Libraries:
TFT_Extension, OneWireKeypad, SerialServo, (UPD)WiiClassicController, VWID

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry about that I kinda figured it would work being that arduino has port manipulation. I thought it would be able to read and write to multiple pins that way, but NO. Yea go with normal method of just getting the data from one at a time.

It should be made into a new feature. It would be so much easier access multiple pins, if it were possible.
It is possible to read and write to multiple ports simultaneously, but it requires direct access to the port registers rather than inventing a new language syntax. When you access the port registers directly you lose the benefits of the high level functions provided by Arduino, so it's the sort of thing you only want to do when really necessary. Trying to detect very small timing differences between inputs on different pins might be one of those situations where it was necessary.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

try this:

(duration1, duration) = pulseIn((pingPin2,pingPin), HIGH);          

It didn't work!

Well of course it didn't work! It was complete nonsense.

I don't understand what you're trying to achieve or how multiple ping sensors helps you achieve it. Are you trying to detect obstacles in multiple directions, or something? If so, the easiest way to read from multiple receivers is to pretend you have one sender and one receiver and do one 'ping' in the usual way, then do exactly the same thing with the sender and the other receiver. This means you will send out a separate ping for each receiver, but I don't see any harm in that.

The alternative is to use a completely different method to get the response from the receiver, which enables you to receive from two inputs simultaneously. That's going to be much harder to do, and is not the approach I'd recommend. But if you have a remote sender and you're trying to use stereo receivers to determine the direction to the source, then you will need to read them both simultaneously to see which one receives the pulse first. In this case the exact timing might not matter (you can't determine range unless you know when the pulse was sent) and all you'd care about was which receiver picked the pulse up first. I suspect you could do that using interrupts and direct port access to grab the state of both inputs with minimal latency, but it's going to need an approach that's very different to the conventional ping range finder.

I'm not an expert at Arduino(how do you do direct port access), can you please help me figure out how to do that? Are you referring to something like this:(code)

The main goal is, I'm trying to figure out what's the distance(or time) difference of the 2 receivers that are located on the robot, so I can adjust the motors and drive.

Code:
pinMode(ultraSoundSignal1, INPUT); // Switch signalpin to input
pinMode(ultraSoundSignal2, INPUT); // Switch signalpin to input
val1 = digitalRead(ultraSoundSignal1); // Append signal value to val
val2 = digitalRead(ultraSoundSignal2); // Append signal value to val

while((val1 == LOW) || (val2 == LOW) ) { // Loop until pin reads a high value
 if (val1 == LOW){
   val1 = digitalRead(ultraSoundSignal1);
   }
 if (val2 == LOW){
   val2 = digitalRead(ultraSoundSignal2);
  }
}

while((val1 == HIGH) || (val2 == HIGH)) { // Loop until pin reads a high value
 if (val1 == HIGH){
   val1 = digitalRead(ultraSoundSignal1);
   timecount1 = timecount1 + 1;
 }
 if (val2 == HIGH){
   val2 = digitalRead(ultraSoundSignal2);
   timecount2 = timecount2 + 1;
 }
}

 
//  val1 = digitalRead(ultraSoundSignal1);
 // val2 = digitalRead(ultraSoundSignal2);
//  timecount1 = timecount1 +1;            // Count echo pulse time
//}


/* Writing out values to the serial port
 * -------------------------------------------------------------------
 */

ultrasoundValue1 = timecount1; // Append echo pulse time to ultrasoundValue
ultrasoundValue2 = timecount2;
//ultrasoundValuee = timecountt; // Append echo pulse time to ultrasoundValue
serialWrite('S'); // Example identifier for the sensor
printInteger(ultrasoundValue2 - ultrasoundValue1);
serialWrite(10);
serialWrite(13);
Logged

Queens, New York
Offline Offline
Faraday Member
**
Karma: 101
Posts: 3651
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

you could try

difference = time1 - time2;

if(difference > 0) {
 //go left so many degrees. (You need to map that out yourself based on your motors, driver, and motor speed, over a lenght of time.)
}

else {
// go right so many degrees
}
Logged

Created Libraries:
TFT_Extension, OneWireKeypad, SerialServo, (UPD)WiiClassicController, VWID

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The main goal is, I'm trying to figure out what's the distance(or time) difference of the 2 receivers that are located on the robot, so I can adjust the motors and drive.

So the sender itself is not being controlled by the robot, you're only trying to detect the timing difference between the pings being received by two receivers?

Perhaps just knowing which receiver was triggered first would be enough and you may not need to know the precise timing difference between the two receivers. In that case I guess your best bet would be to try to get the receivers to trigger a pin change interrupt, and in each ISR register which receiver was triggered and what time it was triggered at. The time value would enable you to ignore subsequent signals from the 'other' receiver which would presumably be caused by the same incoming ping. I don't know how reliable this would be and you may need to be smarter about how you treat the inputs from the two receivers (for example you might require both receivers to have detected the signal before you pay any attention to which one was first) but that would take more effort - I'd try the simplest approaches first.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The main goal is, I'm trying to figure out what's the distance(or time) difference of the 2 receivers that are located on the robot, so I can adjust the motors and drive.

So the sender itself is not being controlled by the robot, you're only trying to detect the timing difference between the pings being received by two receivers?

Perhaps just knowing which receiver was triggered first would be enough and you may not need to know the precise timing difference between the two receivers. In that case I guess your best bet would be to try to get the receivers to trigger a pin change interrupt, and in each ISR register which receiver was triggered and what time it was triggered at. The time value would enable you to ignore subsequent signals from the 'other' receiver which would presumably be caused by the same incoming ping. I don't know how reliable this would be and you may need to be smarter about how you treat the inputs from the two receivers (for example you might require both receivers to have detected the signal before you pay any attention to which one was first) but that would take more effort - I'd try the simplest approaches first.

I have 3 ping)) sensors... I detached the transmitter from 2, making them receivers. And detached the receiver from one making it a transmitter. So I have 2 receivers on the robot and I'm holding a transmitter I signal a ping to the transmitter and the receivers "think" they also sent out a ping, but in reality it's the transmitters. Then both receivers will wait for the echo, Im trying to configure it so both receivers receive something, that way I can calculate in what direction the transmitter is in.

For example: Ping request sent
receiver 1 10 inches
receiver 2 15 inches
now I know the transmitter is to the right and i can adjust the motors.

But the problem I'm facing is with my code shown earlier in the first post, I'm only getting one reading of receiver 1 and nothing for receiver 2 (and I think its because receiver 1 is getting called up first, because when I interchange and make receiver 2 read first it works and receiver 1 doesnt)
Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you're trying to detect which of the receivers has responded first, you can't use pulseIn() because this will only wait for a response on one input at a time. I suggest you follow the interrupt based approach I outlined earlier.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Pages: [1]   Go Up
Jump to: