Putting Sim Project Help

Hi All,

I'm currently working on a project with a few people for a golf putting sim to practice and to possibly connect it to a few golf sim software's.

Here is a bit of information on my project:

I'm currently using two SharpIR 10-80cm sensors to calculate inputs for the golf software. These sensors would be set at a known distance apart from each other and the sensors would be pointing across the putting mat. You calculate the speed of the ball by the time it takes to roll past both sensors.

You would calculate the horizontal launch angle or path of the ball by drawing an imaginary triangle and solving the angles. The sensors are constantly reporting distance to an object. So I might place a piece of wood at a constant distance or create a limit in the code such that the sensors will always report the same distance unless an object passes them. The thought would be to detect a change in the data stream whenever the ball rolls by and use those values to solve the whole equation. The setup would look like my drawing.

Now, the path of the ball is solved by finding the arctan of the distance between the actual sensors (x) and the difference between the reported values from the sensors (S2-S1=y) so we have atan(y,x). This works just fine.

I'm having issues calculating speed of the ball. I have a velocity equation in the code to calculate speed however it's not doing this correctly. We tried to create a trigger or timer once the ball rolls past the first sensor and then obviously its stopped when the second sensor is triggered. When I open the serial monitor I get this reported for speed "inf". So there is some kind of issue here. Another issue is that it doesn't seem to wait for the second sensor, meaning if you trigger sensor one it complete the loop and says "Sensor One Triggered" "Sensor Two Triggered" "Speed inf" and "HLA xx". So I'm not sure why its not waiting for the second sensor.

Could you guys take a look at my code and let me know what you think the issues are?

#include <SharpIR.h>

#define IR1 A1 // define signal pin
#define IR2 A2 // define signal pin
#define model1 1080 // for GP2Y0A21YK0F  used 1080
#define model2 1080 // for GP2Y0A21YK0F  used 1080

#define defaultDistance 200 // distance from wood in mm
#define allowedVariance .05 // percentage variance

// Sharp IR code for Robojax.com
// ir: the pin where your sensor is attached
/*
  2 to 15 cm GP2Y0A51SK0F  use 215
  4 to 30 cm GP2Y0A41SK0F / GP2Y0AF30 series  use 430
  10 to 80 cm GP2Y0A21YK0F  use 1080
  10 to 150 cm GP2Y0A60SZLF use 10150
  20 to 150 cm GP2Y0A02YK0F use 20150
  100 to 550 cm GP2Y0A710K0F  use 100550
*/
SharpIR SharpIR1(1, IR1);
SharpIR SharpIR2(1, IR2);

unsigned long timeSensorOne=0;
unsigned long timeSensorTwo=0;
double velocity;
double angleDegree;

double calculateVelocity (unsigned long startTime, unsigned long endTime) {
  return 609.6/((endTime-startTime)/1000);
}

double calculateHLA (float distSensorOne, float distSensorTwo) {
    //Find the HLA using Arctan of y,x
    double x = 609.6; //distance between sensors in mm
    double y = distSensorTwo-distSensorOne;
    double angleRadian;
    angleRadian = atan2(y,x);
    return angleRadian*180/3.14159265;
}

void setup() 
{  
  Serial.begin(9600);
  Serial.println("Putting SIM  ");

  // extra pin for 5V if needed
  pinMode(3, OUTPUT); // define pin x as output
  digitalWrite(3, HIGH);// set pin x HIGH so it always have 5V 
 }

void loop() 
{
  // Wait 10 milliseconds
  delay(100);

  // Get distance from sensor one;
  float distSensorOne = (SharpIR1.getDistance()*10.);

  // Get time of sensor one distance;
  timeSensorOne = millis();
 
//Serial.println((String)"Sensor One Distance: "+distSensorOne+"mm"); 
  
  // if sensor one detects change and is more than allowed variance
  if (distSensorOne < defaultDistance * (1 - allowedVariance)){
    Serial.println("Sensor One Triggered!");

    //for the next 50 milseconds, lets see if sensor two is triggered
    while (millis() - timeSensorOne <= 50) {

      // Get distance from sensor two;
      float distSensorTwo = (SharpIR2.getDistance()*10.);

      // Get time of sensor one distance;
      timeSensorTwo = millis();

      // if sensor two detects change and is more than allowed variance
      if (distSensorTwo < defaultDistance * (1 - allowedVariance)){
        Serial.println("Sensor Two Triggered!");
        
        //Calculate and Print Speed
        velocity = calculateVelocity(timeSensorOne, timeSensorTwo);
        Serial.print("Speed  ");
        Serial.print(velocity);
        Serial.println(" mph");

        //Calculate and Print value for HLA
        angleDegree = calculateHLA(distSensorOne, distSensorTwo);
        Serial.print("HLA: ");
        Serial.println(angleDegree);
        
      }
   break; } 
  } 
}

hi @natterman12 welcome to the community.

I’m about to go down for my nap, but the very first thing I and anyone will see in your code are those honking delay() calls.

If you are serious about gathering real time information, analyzing and reacting to it, you will severely compromise your ability to do if you “go blind” for eternities like 100 and even 10 milliseconds. In the world of microporocessors those truly are looooong times, too long to waste doing. Absolutely. Nothing.

Investigate “blink without delay”, google

  arduino blink without delay

Structure your software using FSM “finite state machines”, google

  arduino finite state machines

and

  arduino traffic lights

and

arduino two things at once

Spend some time poking around amongst the many hits you will get.

Sry to send you off to google, but trust me when I say if you use the techniques you will see, this will all work much better.

a7

Hmm, either don’t comment or don’t lie. :wink:

a7

First, thank you for your suggestions. I've only taken one C/C++ course over 10 years ago so it's hard to remember things, and the things that I do remember are basic at best. I'll take a look at your recommendations.

Secondly, what is the point of your second comment... It's clearly a typo/simple mistake, the code comment was actually correct until I change the delay to 100 to see if that changed anything. I was reluctant to even submitting this and asking for help because these are the types of comments I always see around here. I'll put it plain and simple, your snarky comments don't help.

OK, batting 0.500, I'd like to do better.

Let me offer a sincere and abject apology for being less than gentle when snarking on your typography.

My point(s), lost perhaps because my words caused you pain, for which I am truly sorry and take responsibility for which, were two.

There is no need to comment that line at all. Like

  i++;     // add 1 to i

When there are comments, they should be true

  theta = asin(omega);    //  convert omega to radians

Just page [low page number] of any style book.

As I read code placed here by ppl seeking help, I rarely read the comments, mostly for the above examples.

But let's stick with part one: FSMs, which irrespective of how you come to know or learn about or are encouraged to explore, are the bomb, srsly, they can really make things go.

In case you are tempted to interpret my apology as a classic non-apology, please do not. I won't make any excuses other than to state honestly that I get this from my mother, who nevertheless would be less than proud of me if she wasn't sleeping in the dirt.

a7

have you tried debugging the 2nd sensor measurement? printing the raw value, both distance and timestamps.

also probably not a good idea to have prints in between measurements

why conditionally check for the 2nd sensor measurement within a while loop? why not simply a flag