LED is dim while in PID loop

I am balancing a ball on a plate with a PID loop

the position of the ball is changed with an IR remote using an ISR

there are 5 positions with a corresponding LED that will light when the ball is stable in the desired position

the position and lighting the LED is working, but the LED is very dim. I don’t have a scope and home but I am guessing it may be a duty cycle issue.

here is the code, any thought on why the LEDs are dimmed?

void loop() {
  while (Stable < 125) //REGULATION LOOP
  {
    TSPoint p = ts.getPoint();   //measure pressure on plate
    if (p.z > ts.pressureThreshhold) //ball is on plate
    {
      servo1.attach(ServoX); //connect servos
      servo2.attach(ServoY);
      setTrajectory();
      noTouchCount = 0;  //timer value for ball not present
      TSPoint p = ts.getPoint(); // measure actual position
      Input = (p.x * convertX); // read and convert X coordinate
      Input1 = (p.y * convertY); // read and convert Y coordinate
      if ((Input > Setpoint - 2 && Input < Setpoint + 2 && Input1 > Setpoint1 - 2 && Input1 < Setpoint1 + 2)) //if ball is close to setpoint
      {
        Stable = Stable + 1; //increment STABLE
        digitalWrite(LedID, HIGH); // if its stable lights led 9
      }
      else
      {
        digitalWrite(LedID, LOW);  //if not stable turns off led 9
      }
      myPID.Compute();  //action control X compute
      myPID1.Compute(); //   action control  Y compute
    }
    else //if there is no ball on plate
    {
      noTouchCount++; //increment no touch count
      if (noTouchCount == 75)
      {
        noTouchCount++;
        Output = 95; //make plate flat
        Output = 95;
        servo1.write(Output + AdjustXservo);
        servo2.write(Output1 + AdjustYservo);
        digitalWrite(LedID, HIGH);
      }
      if (noTouchCount == 150) //if there is no ball on plate longer
      {
        servo1.detach(); //detach servos
        servo2.detach();
      }
    }
    servo1.write(Output + AdjustXservo);//control
    servo2.write(Output1 + AdjustYservo);//control
    //  Serial.print(Setpoint);   Serial.print(",");  Serial.print(Setpoint1);  Serial.print(",");  Serial.print(Input);Serial.print(","); Serial.println(Input1);
    //   Serial.println(CHButtonCounter);     // turn off and on to print value for trouble shooting, plot output to see representation of control
  }
  ////END OF REGULATION LOOP///

  servo1.detach();//detach servos
  servo2.detach();
  ///KONTROLA STABILITY////
  while (Stable == 125) //if is stable
  { //still measure actual postiion
    setTrajectory();
    TSPoint p = ts.getPoint();
    Input = (p.x * convertX); //read X
    Input1 = (p.y * convertY); //read Y
    if (Input < Setpoint - 2 || Input > Setpoint + 2 || Input1 > Setpoint1 + 2 || Input1 < Setpoint1 - 2  ) //if ball isnt close to setpoint
    {
      servo1.attach(ServoX); //again attach servos/      servo2.attach(ServoY);
      digitalWrite(LedID, LOW);
      Stable = 0; //change STABLE state
    }
  }//end of STABLE LOOP
}//loop end

so you can see the difference, here are the LEDs being lit by a test program.

LED Test

and here they are when the ball is being repositioned

LED's while running

Why constantly re-attach the servos inside your loop? That's just a waste of time.

You re-declare p in several different scopes. Just grab a "good copy" of it once at the top of the loop and then always use that one. The sub-loop at the bottom should be incorporated into the main loop via an if() or it should be deleted entirely.

Please post the complete program with the variable declarations and #includes. Those don't seem important to you but often the error is in that part which you're not looking at.

I did try the program with the servos always enabled, they buzz and are quite annoying. I like it much better when they turn off after the ball is stable.

I will look at the sub-loop combination, that portion was “working” so I am hesitant to mess with it until I get to the optimization stage. If it is causing the LED dim issue though, it will be broached.

I tried to post the entire program but I run into the max character constraint, it is attached as a text file

BKK ball and plate 23NOV17.txt (11.2 KB)

Yes, perfectly fine to turn them off when you don’t need them but you are re-attaching them every time around the “regulation” loop. You are also attempting to write to them when they may be detached.

Instead of posting a large program that none of us want to read, try to trim it down to the shortest possible example which shows the problem. Usually that’s going to show you where the problem is for yourself.

And what’s with myPID1? Give it a real name which describes what it does. It’s the y axis isn’t it? Any time you have numbers in variable names, you are doing something wrong.

I don’t really know what the problem is?

I run the LEDs with a simple LED program and they are bright as I want. In the PID they are not.

I posted the PID portion where the LED on and off commands reside, then the full program as requested.

I think it is a duty cycle issue in the PID loop that is turning the LEDs on and off very fast, and it is off more than on.

I don’t really understand what speed the PID loop is actually executing and how long relative to that speed that the LEDs are on.

Since they are not very bright I am assuming they are off more than on, but since I don’t understand the loop timing, Im not sure at all if this is even a valid concern

I just don’t understand the time frame for the on and off cycles and how to change that.

Once I get my scope from work I can at least see the timing, I just thought it might be an obvious mistake. the other stuff will get cleaned up later, I understand it is not all perfect in form

this is my second large program, sorry for the simple issues.

I commented out the occurrences of “digitalWrite(LedID, LOW);” and it just stayed on, but no brighter.

It seems to have dimmed when I added the ISR for the ir remote control

MorganS:
Why constantly re-attach the servos inside your loop? That's just a waste of time.

You re-declare p in several different scopes. Just grab a "good copy" of it once at the top of the loop and then always use that one. The sub-loop at the bottom should be incorporated into the main loop via an if() or it should be deleted entirely.

Please post the complete program with the variable declarations and #includes. Those don't seem important to you but often the error is in that part which you're not looking at.

i think the reason it gets "p" multiple times is because the ball is constantly moving. It grabs the current location and does calculations, then grabs it again at its new point a recalculates.

What are you trying to do with the led. I see it set HIGH and LOW all over the place.

If you are trying to flash the LED then you should be aware that the PID.compute() function is very slow and you call it twice. Maybe you are calling compute() while the LED is off?

I have a much faster version of PID calculations in this EasyPID thread - but only if you are sufficiently experienced to know how to convert your existing code to the simpler version.

...R

Hi, no it is not meant to flash. the two different scenarios in the loop for balance are for when it is not balanced (dynamic changes) and when it finds the balance (static)

when it finds balance, with no other input you can shut off power and it remains, so no need for any inputs.

the LED should be off when it is not at the setpoint and on when it is at the set point, that is all.

the ir remote changes the setpoint and changes the LED to the one corresponding to that set point, but the function of the LED in each of the positions is the same.

BKK:
the LED should be off when it is not at the setpoint and on when it is at the set point, that is all.

Perhaps it is oscillating slightly so that it is on and off the setpoint but not enough for the human to notice.

If that is the problem maybe you need a deadband within which the LED is on.

...R

Are you sure this makes all 5 LED pins output?

  pinMode(LedID, OUTPUT);  //these LEDS are to show searching and stable 8 and 9 are on the arduino

oqibidipo:
Are you sure this makes all 5 LED pins output?

  pinMode(LedID, OUTPUT);  //these LEDS are to show searching and stable 8 and 9 are on the arduino

Well spotted.

...R

oqibidipo:
Are you sure this makes all 5 LED pins output?

  pinMode(LedID, OUTPUT);  //these LEDS are to show searching and stable 8 and 9 are on the arduino

you are correct, awesome thanx :slight_smile:

 //INIT PINS
  pinMode(BlueLed1, OUTPUT);  //these LEDS are to show searching and stable on the arduino
  pinMode(BlueLed3, OUTPUT);
  pinMode(BlueLed5, OUTPUT);
  pinMode(BlueLed7, OUTPUT);
  pinMode(BlueLed9, OUTPUT);

with corrected pin initialization

BKK Ball and Plate, corrected initialization

thanx again everyone :slight_smile: