URGENT in need of help with processing code SRF10 ultrasonic sensor

edited November 2016 in Arduino

``Hello, im in need of help with my project using SRF10 ultrasonic sensor. Im and using arduino + processing for our project but our coding is not strong. I have 2 ultrasonic which use to track moving object. I need help in showing the object location and showing it change when the object changes location. I currently able to show a printed value but only for one sensor displayed on processing. Any kind soul able to help :)

Here is our processing code:

import processing.serial.*;
//import cc.arduino.*;
//println(Arduino.list());
 String val;
Serial myPort;

float Distance1 = 0, Distance2 = 0;
float LocationX=0; // Assumed location of an object (X,Y)
float LocationY=0;
float SRF1_x=300;  // location of SRF1 (x,y)
float SRF1_y=100;
float SRF2_x=500;  // location of SRF2 (x,y)
float SRF2_y=100;
float AngularRes=PI/180*10; //   Angle change step size
int xPos = 1;      // horizontal position of the graph

void setup()
{
  size(1000, 700);
  String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
myPort = new Serial(this, portName, 9600); 
  background(200);
  smooth();
  myPort.bufferUntil('\n');
  DrawGrid();
}

void draw()
{
      if( myPort.available() > 0) 
      {  // If data is available,
        val = myPort.readStringUntil('\n');  
      }
  println(val);
     FindLocation();
//     background(300, 300, 300);
     fill(300);
     ellipse(SRF1_x,SRF1_y,25,25); // location of SRF1
     fill(100);
     ellipse(SRF2_x,SRF2_y,25,25); // location of SRF2
     fill(400);
     ellipse(LocationX,LocationY,10,10); // actual location of an object


}

void serialEvent(Serial myPort)
{
  String str = myPort.readStringUntil('\n');
  if (str != null )
  {
      str = trim(str); //remove whitespace around our values
      float  DistanceArr[]=float (split(str, ','));
      Distance1= map( DistanceArr[0], 0, 540, 0, 3000); // map distance of SRF1 to another range
      Distance2= map( DistanceArr[1], 0, 540, 0, 3000); // map distance of SRF2 to another range
  }
}

void FindLocation(){
     float MinimumDist = 50000;
     float x_CL_SRF1, y_CL_SRF1, x_CL_SRF2, y_CL_SRF2,Cal_MinimumDist; // x-y coordinates along two circles
     for (float theta1 = 0; theta1 < PI; theta1 = theta1+AngularRes) {
         x_CL_SRF1=SRF1_x +Distance1*cos(theta1);   // get x-y coordinates along circle for SRF1
         y_CL_SRF1=SRF1_y +Distance1*sin(theta1);
         ellipse(x_CL_SRF1,y_CL_SRF1,10,10);
         for (float theta2 = 0; theta2 < PI; theta2 = theta2+AngularRes) {
              x_CL_SRF2=SRF2_x +Distance2*cos(theta2);  // get x-y coordinates along circle for SRF2
              y_CL_SRF2=SRF2_y +Distance2*sin(theta2);
              ellipse(x_CL_SRF2,y_CL_SRF2,10,10);
              Cal_MinimumDist=sqrt(sq(x_CL_SRF1- x_CL_SRF2)+sq(y_CL_SRF1- y_CL_SRF2));
              if (Cal_MinimumDist<MinimumDist){
                  MinimumDist=Cal_MinimumDist;
                  LocationX=x_CL_SRF1;
                  LocationY=y_CL_SRF1;
               }

         }
    }     
}

void DrawGrid() {
    for (int i = 0; i < 700; i = i+100) {
        line(0, i, 990, i);
        }

        for (int i = 0; i < 1000; i = i+100) {
             line(i, 0, i, 690 );
        }
}

Here is the arduino code: /* * * rosserial srf02 Ultrasonic Ranger Example * * This example is calibrated for the srf02 Ultrasonic Ranger. * * By Poh Hou Shun 24 September 2015 */

//#include <Sonar_srf02.h> //srf02 specific library
#include <Wire.h>
//#include <ros.h>
//#include <std_msgs/Float32.h>


//Set up the ros node and publisher
//std_msgs::Float32 sonar_msg;
//ros::Publisher pub_sonar("sonar", &sonar_msg);
//ros::NodeHandle nh;

//Sonar_srf02 MySonar; //create MySonar object

#define COMMANDREGISTER 0x00
#define RESULTREGISTER  0x02

#define CENTIMETERS 0x51
// use 0x50 for inches
// use 0x51 for centimeters
// use 0x52 for ping microseconds

#define NO_OF_SENSORS 2

int SEQUENCE[] = {115, 116};

int reading = 0;
String stringData;

void setup()
{

  Wire.begin();                // join i2c bus (address optional for master)
  Serial.begin(9600);          // start serial communication at 9600bps

  //nh.initNode();
  //nh.advertise(pub_sonar);

}


long publisher_timer;

void loop()
{

  if (millis() > publisher_timer || 1) {

    for (int i = 0; i < NO_OF_SENSORS; i++) {
      takeData(SEQUENCE[i]);
    }

    // step 2: wait for readings to happen
    delay(70);                   // datasheet suggests at least 65 milliseconds

    readData(SEQUENCE[0]);

    stringData = String(reading);
    Serial.print(reading);

    for (int i = 1; i < NO_OF_SENSORS; i++) {
      readData(SEQUENCE[i]);
      stringData = ' ' + String(reading);
      Serial.print(' ');
      Serial.print(reading);    
    }

    //stringData = stringData + '\0';

    //sonar_msg.data = stringData;
    //pub_sonar.publish(&sonar_msg);

    publisher_timer = millis() + 4000; //publish once a second
    //Serial.println(sensorReading);
    Serial.println('\0');

  }

  //Serial.println(stringData);   // print the reading
  //nh.spinOnce();

}

void takeData(int address) {

  // step 1: instruct sensor to read echoes
  Wire.beginTransmission(address); // transmit to device #112 (0x70)

  // the address specified in the datasheet is 224 (0xE0)
  // but i2c adressing uses the high 7 bits so it's 112
  Wire.write(byte(COMMANDREGISTER));      // sets register pointer to the command register (0x00)
  Wire.write(byte(CENTIMETERS));      // command sensor to measure in "centimeters" (0x51)

  Wire.endTransmission();      // stop transmitting

}

void readData(int address) {

  // step 3: instruct sensor to return a particular echo reading
  Wire.beginTransmission(address); // transmit to device #112
  Wire.write(byte(RESULTREGISTER));      // sets register pointer to echo #1 register (0x02)
  Wire.endTransmission();      // stop transmitting

  // step 4: request reading from sensor
  Wire.requestFrom(address, 2);    // request 2 bytes from slave device #112

  // step 5: receive reading from sensor
  if (2 <= Wire.available()) { // if two bytes were received
    reading = Wire.read();  // receive high byte (overwrites previous reading)
    reading = reading << 8;    // shift high byte to be high 8 bits
    reading |= Wire.read(); // receive low byte as lower 8 bits
  }

  delay(250);
  //Serial.println(reading);

}

Answers

  • Well, your code is talking to a single serial connection myPort. How are the two sensors hooked up to the Arduino, and are they both sending data on the same connection? Or are they hooked up to two different arduinos (in which case you might need two connections)?

  • It will help if you post your arduino code.

    Kf

  • I have attach the arduino code as well above . And i am using only one arduino board to run both of the sensor

  • Answer ✓

    @karipuff

    REMARK: This is untested code meaning that I did not run it. It might contain bugs or typos.

    Is this sensor using OneWire technology or is it under the same family?

    I have changed your processing code for testing purposes. Two circles are output in the sketch placed symmetrically off center of your sketch area. The diameter of the circle is related to the distance measured by the sensors.

    import processing.serial.*;
    String val;
    Serial myPort;
    
    float Distance1 = 0, Distance2 = 0;
    float  DistanceArr[];
    
    void setup()
    {
      size(1000, 700);
      String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
      myPort = new Serial(this, portName, 9600);
      background(0);
      smooth();
      stroke(255);
      myPort.bufferUntil('\n');
      DistanceArr = new float[2];
    }
    
    //NOTE: Color scale goes from 0 to 255 unless you change the color's default range
    
    void draw()
    {
      background(0);
    
      fill(255,0,0); //RED
      ellipse(width*0.25, height*0.5, Distance1,Distance1); //Sensor one
      text("Val 1="+DistanceArr[0],width*0.25, height*0.80);
      fill(0,0,255); //BLUE
      ellipse(width*0.75, height*0.5, Distance2,Distance2); //Sensor two
      text("Val 2="+DistanceArr[1],width*0.75, height*0.80);
    }
    
    void serialEvent(Serial myPort)
    {
      String str = myPort.readStringUntil('\n');
      if (str != null )
      {
        str = trim(str); //remove whitespace around our values
        DistanceArr=float (split(str, ' '));
        Distance1= map( DistanceArr[0], 0, 540, 0, width*0.25); // map distance of SRF1 to another range
        Distance2= map( DistanceArr[1], 0, 540, 0, width*0.25); // map distance of SRF2 to another range
      }
    }
    

    This is the Arduino code. Again, this is untested code:

    /*
    * * rosserial srf02 Ultrasonic Ranger Example
    * * This example is calibrated for the srf02 Ultrasonic Ranger.
    * * By Poh Hou Shun 24 September 2015 
    */
    
    //#include <Sonar_srf02.h> //srf02 specific library
    #include <Wire.h>
    //#include <ros.h>
    //#include <std_msgs/Float32.h>
    
    
    //Set up the ros node and publisher
    //std_msgs::Float32 sonar_msg;
    //ros::Publisher pub_sonar("sonar", &sonar_msg);
    //ros::NodeHandle nh;
    
    //Sonar_srf02 MySonar; //create MySonar object
    
    #define COMMANDREGISTER 0x00
    #define RESULTREGISTER  0x02
    
    #define CENTIMETERS 0x51
    // use 0x50 for inches
    // use 0x51 for centimeters
    // use 0x52 for ping microseconds
    
    #define NO_OF_SENSORS 2
    
    int SEQUENCE[] = {115, 116};
    
    //int reading = 0;   // *** CHANGED
    String stringData;
    
    void setup()
    {
    
      Wire.begin();                // join i2c bus (address optional for master)
      Serial.begin(9600);          // start serial communication at 9600bps
    
      //nh.initNode();
      //nh.advertise(pub_sonar);
    
    }
    
    
    long publisher_timer;
    
    void loop()
    {
    
      //if (millis() > publisher_timer || 1) {  // *** CHANGED 
     if (millis() > publisher_timer){
    
        for (int i = 0; i < NO_OF_SENSORS; i++) {
          takeData(SEQUENCE[i]);
        }
    
        // step 2: wait for readings to happen
        delay(70);                   // datasheet suggests at least 65 milliseconds
    
        stringData = ' '; // *** CHANGED
        for (int i = 1; i < NO_OF_SENSORS; i++) {
          int readVal = readData(SEQUENCE[i]); // *** CHANGED      
          stringData += String(readVal);       // *** CHANGED
          Serial.print(' ');         
        }
        Serial.println(stringData);  //FORMAT: space + sensor1 + space + sensor2 + space + returnChar
    
        //stringData = stringData + '\0';
    
        //sonar_msg.data = stringData;
        //pub_sonar.publish(&sonar_msg);
    
        publisher_timer = millis() + 4000; //publish once a second
        //Serial.println(sensorReading);
        //Serial.println('\0');     // *** CHANGED
    
      }
    
      //Serial.println(stringData);   // print the reading
      //nh.spinOnce();
    
    }
    
    void takeData(int address) {
    
      // step 1: instruct sensor to read echoes
      Wire.beginTransmission(address); // transmit to device #112 (0x70)
    
      // the address specified in the datasheet is 224 (0xE0)
      // but i2c adressing uses the high 7 bits so it's 112
      Wire.write(byte(COMMANDREGISTER));      // sets register pointer to the command register (0x00)
      Wire.write(byte(CENTIMETERS));      // command sensor to measure in "centimeters" (0x51)
    
      Wire.endTransmission();      // stop transmitting
    
    }
    
    int readData(int address) { // *** CHANGED
    
      int reading = 0;   // *** CHANGED
    
      // step 3: instruct sensor to return a particular echo reading
      Wire.beginTransmission(address); // transmit to device #112
      Wire.write(byte(RESULTREGISTER));      // sets register pointer to echo #1 register (0x02)
      Wire.endTransmission();      // stop transmitting
    
      // step 4: request reading from sensor
      Wire.requestFrom(address, 2);    // request 2 bytes from slave device #112
    
      // step 5: receive reading from sensor
      if (2 <= Wire.available()) { // if two bytes were received
        reading = Wire.read();  // receive high byte (overwrites previous reading)
        reading = reading << 8;    // shift high byte to be high 8 bits
        reading |= Wire.read(); // receive low byte as lower 8 bits
      }
    
      delay(250);
      //Serial.println(reading);
    
      return reading; // *** CHANGED
    
    }    
    

    if this doesn't work beside simple errors, I would suggest to make a simpler program running one sensor first, then the other one (to ensure they are working and you can access them through their assigned addresses) and then combine them together. Doing a search on the forum could provide you access through other arduino/processing code from other forum users:

    https://forum.processing.org/two/search?Page=p2&Search=arduino

    Or you could check the arduino section in the forum:

    https://forum.processing.org/two/categories/arduino

    I hope this helps,

    Kf

Sign In or Register to comment.