Idea without using while

I am designing a solar tracking system. The system compares the analog input of two small solar cells, if one is higher than the other, the sun is in that direction and it moves a motor until they are close to equal. There is one set for up and down and one set for left and right. The program works fine but there is one problem I am trying to fix. The simple line of code, to move the motor down (engage the relay) is:

if ((up)-(down)>20)
digitalWrite (downpin, LOW);

If the difference from the up/down cells are greater than 20 everything if fine. Since the motors move the device slowly, it can stop exactly with the difference at 20. The next time the program runs through, it may be 20, the next time the difference can be 19.9. when this happens, the relays start to chatter because the value is so close to 20. My idea was to use something like:

if((up)-(down)>30)
{while ((up)-(down)>20
digitalWrite (downpin, LOW);}

When the difference is >30, it would adjust until the difference is <20. This would stop the chattering.
The problem is I need the up/down and the left/right working at the same time. the "while" keeps both from working at the same time.
Any ideas?

Thanks,
Harry - Orlando

Just use a small hysteresis (google it). It's the most effective function for this kind of problem.

The post says that everything is fine if the difference is greater than 20, and then suggests that if the difference were greater than 30 it would be a good idea to move things until it's less than 20. I'm not sure which way you're going.

So, I'll presume that you want to drive the motor until the difference is less than 20, but that you don't want to start driving it until the difference is 30 or more. Here's how I'd start, in pseudocode:

 if (((up - down) > 30) && (downMotorIsOff) {
    turnDownMotorOn;  // When the difference is > 30, turn the motor on
  }
  if ((up - down) < 20) {
    turnDownMotorOff;  // When the difference is less than 20, we want the motor to be off
  }

The system will leave the motor in its current state if the difference is between 20 and 30 - if it's off, it stays off; if it's on, it stays on. It will turn the motor on when the difference is greater than 30, and it will turn it off if the difference is less than 20.

Note that there's no requirement to repeatedly execute digitalWrite()'s. The pin will hold its state until the program changes it.

If there is a possibility of "down" being greater than "up" you should use

if abs(up - down) > 20) {

...R

Robin2:
If there is a possibility of "down" being greater than "up" ...

I think, but don't know, that the OP will use separate motors to move the [Edit: clarify this] photovoltaic array up and down, if that's what he's doing this for. His code references a "downPin," so presumably there's an upPin somewhere. If that's so, he won't want to use the absolute value of the difference. If the number goes negative, it still doesn't need more downPin.

I think. Maybe the OP can tell us whether that's what he's really doing.

I think, but don't know, that the OP will use separate motors to move the array up and down.

It would certainly be interesting to know how you think one could use a motor to move an array.

PaulS:
It would certainly be interesting to know how you think one could use a motor to move an array.

Well, one could if it were an array of photovoltaic cells. Looking back, I see that the OP doesn't mention a solar array - he says only that he uses a couple of small solar cells for detection. Maybe he's pointing something else at the sun.

Referenced post edited for clarity.