Trolley Car Simulation Project

Hi everyone.
I’m still very new to arduino and I’ve been set a task to simulate a small trolley car traveling back and forth between two stations. Unfortunately the loop i have written doesn’t get past the first line, simply printing on the serial monitor “Initialised”. I have tried changing every instance of where this word appears to other words to attempt to find out where it crashes, but this hasn’t done anything, it still prints “initialised” no matter what.
Any suggestions?
Thanks

int interruptPin = 2; 
int interruptNo = 0; 
long prevInterruptTime = 0; 
int motorPinForward = 10; 
int motorPinBackward = 11; 
int enablePin = 12;

long prevCycleTime = 0; 
float deltaTime = 0.05;

float rfDistance = 0.2; 
float rfTarget = 0.2; 
float rfStation1 = 0.2; 
float rfStation2 = 2.9;

float pidKp = 2.35;
float pidKi = 0.01; 
float pidKd = 2.40; 
float pidPrevError = 0; 
float pidErrorSum = 0;

// -------------------------------------------------------
// Interrupt Event Handler
// -------------------------------------------------------

void interruptPinChange()
{
  long interruptTime;
  float distance;
  
  // Log the time of the interrupt
  interruptTime = micros(); 
  
  // Is this the start of the pulse or the end of the pulse
  if (digitalRead(interruptPin) == HIGH) 
  {
    interruptTime = prevInterruptTime; 
  }
  
  if (digitalRead(interruptPin) == LOW) 
  {
    distance = (interruptTime - prevInterruptTime)/5800;
  }
  
  // Does the calculation make sense, if not return
  if (distance < 0.15 or distance > 6) 
  {
    return;
  }
  
  // Set the Range Finder Distance
  rfDistance = distance;
  
  Serial.println("Initialised");  
  Serial.print("rfDistance = ");
  Serial.println(rfDistance, DEC);
  Serial.print("rfTarget = ");
  Serial.println(rfTarget, DEC);
  
}
// -------------------------------------------------------
// Set Motor Speed
// -------------------------------------------------------

void setMotorSpeed(float pidValue) 
{
  int pmwDutyCycle;
  
  // Calculate the duty cycle based on the PID function: PID(+1) = +100%, PID(-1) = -100%
  pmwDutyCycle = pidValue * 255;
  
  // Make sure it is a valid duty cycle
  if (pmwDutyCycle > 255);
  {
    pmwDutyCycle = 255;
  }
  
  if(pmwDutyCycle < -255) 
  {
    pmwDutyCycle = -255;
  }
  
  // Set the motor speed
  if(pmwDutyCycle > 0) 
  {
    analogWrite(motorPinBackward,0);
    analogWrite(motorPinForward,pmwDutyCycle);
  }
  
  if(pmwDutyCycle < 0) 
  {
    analogWrite(motorPinBackward, pmwDutyCycle);
    analogWrite(motorPinForward, 0);
  }
  
  Serial.print("pmwDutyCycle = ");
  Serial.println(pmwDutyCycle, DEC);
}
  
// -------------------------------------------------------
// PID
// -------------------------------------------------------

float PID(float target, float actual, float deltaTime) 
{
  float pidError;
  float pidErrorSlope;
  float pidValue;
  
  // Calculate the Error function Error(t) = Target(t) - Actual(t)
  pidError = target - actual;
  
  // Calculate the PID component values
  pidErrorSum = pidErrorSum + pidError * deltaTime;
  
  pidErrorSlope = (pidError - pidPrevError)/ deltaTime;
  
  // Calculate the PID function value
  pidValue = pidKp * pidError + pidKi * pidErrorSum + pidKd * pidErrorSlope;
  
  return pidValue;
  
  Serial.print("pidError = ");
  Serial.println(pidError, DEC);
  Serial.print("pidErrorSlope = ");
  Serial.println(pidErrorSlope, DEC);
  Serial.print("pidValue = ");
  Serial.println(pidValue, DEC);
  
}
// -------------------------------------------------------
// Check Destination
// -------------------------------------------------------

void checkDestination()
{
  // Have we arrived at our destination: Station 1
  if (rfTarget == rfStation1 and rfDistance == rfStation1)
  {
    rfTarget = rfStation2;
    
    // Reset pidErrorSum for next trip
    pidErrorSum = 0;
    
    Serial.println("rfTarget changed to rfStation2");
  }
 
  // Have we arrived at our destination: Station 2
  if(rfTarget == rfStation2 && rfDistance == rfStation2);
   {
    rfTarget = rfStation1; 
    
    // Reset pidErrorSum for next trip
    pidErrorSum = 0;
    
    Serial.println("rfTarget changed to rfStation1");
   } 
}
  
// -------------------------------------------------------
// The setup() method runs once, when the sketch starts
// -------------------------------------------------------

void setup()
{  
  // Set up the enable pins
  pinMode(enablePin, INPUT);
  
  // Set up the motor speed pins
  pinMode(motorPinForward, OUTPUT);
  pinMode(motorPinBackward, OUTPUT);
  
  // Set up the interupt
  pinMode(interruptPin, INPUT);
  attachInterrupt(interruptNo, interruptPinChange, CHANGE);
  
  // initialize the serial communications
  Serial.begin(9600); 
  Serial.println("Initialised"); 
}
// -------------------------------------------------------
// The loop() method runs over and over again
// -------------------------------------------------------

void loop()
{
  long cycleTime;
  float pidValue = 0;
  float trolleyPosition;
  long rfPulseWidth;
  
  // Log the time for this cycle of the loop()
  cycleTime = micros();
  deltaTime = (float)(cycleTime - prevCycleTime) / 1000000.0;
  prevCycleTime = cycleTime;
  
  // Is the Trolley Car enabled to move
  if (true) 
    {
      // Calculte the PID function value
      pidValue = PID(rfTarget, rfDistance, deltaTime);
    
      // Set the motor speed
      setMotorSpeed(pidValue);
      
      // Check for arrival at the destination, and change of direction
      checkDestination();
    }
    
  // Calculate the trolley position to simulate the range finder
  trolleyPosition = rfDistance + constrain(pidValue, -1, 1) * 0.1;
  
  // Calculate the Range Finder pulse width
  rfPulseWidth = (long)(trolleyPosition * 5800.0);
  
  // Simulate the Range finder pulse
  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);
  delayMicroseconds(rfPulseWidth);
  digitalWrite(3, LOW);
  
  // Delay for 1 sec to give time for the range finder to update
  delay(1000);
}

put your code in side code tags for a start read the sticky at the top of the forum

Don't do serial output inside an interrupt handler.

All time values should be held as [u]unsigned[/u] long values.

It seems to me that it would make more sense for the following code to be an if/else statement:

  if (digitalRead(interruptPin) == HIGH)
  {
    interruptTime = prevInterruptTime;
  }

  if (digitalRead(interruptPin) == LOW)
  {
    distance = (interruptTime - prevInterruptTime)/5800;
  }

There is an awful lot of code in there for a sketch that doesn't get past the first line. Rather than write the whole thing and then try to get it working, I recommend that you start with one small feature and code and test that and get it working, then add another small feature to that, and so on until everything works.

I think your use of floating point calculations will prove to be problematic because most of the intermediate calculations will be done as integer values which would introduce rounding issues. I suggest you minimise the use of floating point arithmetic, and where it's necessary to calculate float values from ints cast the values to float first.

Do you really need to use interrupts? They introduce a lot of issues and should be avoided unless/until absolutely necessary. For example, rfDistance needs to be declared as volatile and you probably need to suspend interrupts while reading it since it is a multi-byte value. I don't know what sort of signals are driving the interrupts, but I suggest you look long and hard for ways to read them without using interrupts.

OK thanks for the advice! Sorry about not posting properly.

you can always edit it and put in the code tags :)

Wait, this wouldn't happen to be https://wiki.cse.unsw.edu.au/en1000/13s2/ENGG1000/Lab6 would it? I believe what OP is asking for is help completing his task, as s/he may not have as much as a thorough understanding of the code as some of you.

I believe what OP is asking for is help completing his task, as s/he may not have as much as a thorough understanding of the code as some of you.

Then, OP should have been having regular meetings with the instructor, and gained a thorough understanding of the code from the previous exercise. This isn't the do-my-homework-for-me hotline.

What happens if we help OP with his homework, and he/she doesn't understand it. How will he/she complete project 7? Suppose that we help with that, and the rest of the homework for the rest of the time OP is in school. When OP graduates, he/she will have a piece of paper that says that he/she is a competent programmer, which will not be the case.

OP needs to learn programming now, or change majors now.

PaulS:
Then, OP should have been having regular meetings with the instructor, and gained a thorough understanding of the code from the previous exercise. This isn’t the do-my-homework-for-me hotline.

What is an absolute scream, is that my daughter has been a tutor/ sometime lecturer at UTS (given that she, like myself, graduated from UNSW) and knows the landscape of these institutions only too well. She really appreciated being pointed to this thread last evening.