Different delays in a loop

Hi, me and a couple of classmates are trying to build a sun tracking system for a sun reflector. We've bought a few photo diodes and a Arduino Mega 1280 and hooked it up to a series of relays, via transistors, to power two electric motors. Allowing the reflector to turn and tilt towards the sun.

We've managed to get the circuit to react to light, and we are getting close to a full scale test outdoors.:slight_smile:

But I'm wondering if there is any way to have separate delays in a "if" loop?
e.g.

if (situation a)
{
do this
delay(100)
}
else
{
do that
delay(1000)
}

We are all fairly green using microcontrollers, but the idea is to let the sun reflector "rest" when it has found the sun, and not go on wasting power driving the motors back and forwards. :slight_smile:

Thank you

void loop ()
{
digitalRead(Value);
if (value == HIGH)
{
code here
}
else
{
(value == LOW)
code here
}
}

Okay, here's a piece of the code

void motor1loop()
{
int lightLevel1 = analogRead(photodiod1);
lightLevel1 = map(lightLevel1, 0, 1, 0, 255);
int lightLevel2 = analogRead(photodiod2);
lightLevel2 = map(lightLevel2, 0, 1, 0, 255);
int x = lightLevel1 - lightLevel2;
{
if (x < -200)
{
digitalWrite(motor1fwd, HIGH);
digitalWrite(motor1rev, LOW);
delay(500);
}
else if (x >200)
{
digitalWrite (motor1fwd, LOW);
digitalWrite(motor1rev, HIGH);
delay(500);
}
else
{
digitalWrite (motor1fwd, LOW);
digitalWrite(motor1rev, LOW);
delay(5000);
}
}
}
But for some reason it seems like it's always a 5000ms delay no matter which condition us fulfilled :frowning:

Any suggestions?

lightLevel1 = map(lightLevel1, 0, 1, 0, 255);

lightLevel1 was in the range from 0 to 1023. I think you should add a Serial.print statement, to see what the mapped value is now. I don't think it is going to be what you think it is.

Do the same for lightLevel2 and x.

Okay, thanks I'll try that:). But do you think it will make any difference when it comes to the delay problem?

We have tried changing lightlevel1 from 0 to 1023, and we where planning on changing x once we mounted everything outside, as a way of calibrating the sensitivity of the system.

We are able to get motor1 to run both forward and backwards, but if we have a long delay under "else" it seems to use the same delay everywhere in the loop, even when for example; x > 200 and
motor1fwd = LOW
motor1rev = HIGH :S
Which makes the system very slow to respond when the signal changes:(

But do you think it will make any difference when it comes to the delay problem?

I'm having a hard time accepting that lightLevel1 and lightLevel2 have values in them that make sense. That's why you need to print them.

Since the value of x is based on the values in lightLevel1 and lightLevel2, it is difficult to know what value x will have without knowing what values lightLevel1 and lightLevel2 have.

Therefore it is difficult to see which of the three options in the if/else if/else block will be executed. Therefore, it is difficult to predict how long it should delay.

Not knowing how long it should delay means that you can not complain that it is delaying too long.

So, I think that you do need to print lightLevel1, lightLevel2, and x (with descriptive text), and show us that output. Printing lightLeveln before and after mapping would be good.

Yes but I can se which way the motors are turning, and I can se when they stop turning. But I'll give it a go and see what values that are returned :slight_smile:

And I can write som descriptive text. I had written some in Swedish but I had a feeling it wouldn't be much use to most ;). So i removed it when I posted.

The two photodiodes are placed on each side on the sun reflector, pointing outwards from each other. When the sun moves across the sky, the difference in strength between the signals from the diodes tells the arduino which way to turn the motors. When the difference in signal strength is small (in this case between -200 and 200) the motors are turned off and the reflector stops turning.
At least this is the idea.

Code:
void motor1loop()
{
int lightLevel1 = analogRead(fotodiod1); //defines lightlevel 1 as the value from photodiode 2
lightLevel1 = map(lightLevel1, 0, 1, 0, 255
int lightLevel2 = analogRead(fotodiod2); //defines lightlevel 2 as the value from photodiode 2
lightLevel2 = map(lightLevel2, 0, 1, 0, 255);
int x = lightLevel1 - lightLevel2; // defines x as the difference between the signal from the two photodiodes
{
if (x < -200) // if x is smaller than -200 then motor1 is told to turn forward.
{
digitalWrite(motor1fwd, HIGH);
digitalWrite(motor1rev, LOW);
delay(500); // if this happens we want a relatively short delay, because we don't want the reflector to turn to far and miss the sun
}
else if (x > 200) // If x is larger than 200 then motor1 is told to turn backwards.
{
digitalWrite (motor1fwd, LOW);
digitalWrite(motor1rev, HIGH);
delay(500); // if this happens we want a relatively short delay, because we don't want the reflector to turn to far and miss the sun

}
else //if the difference in signal strength between the diodes is weak it hopefully means the reflector is facing the sun and motor 1 is turned of completely,
{
digitalWrite (motor1fwd, LOW);
digitalWrite(motor1rev, LOW);
delay(5000); //Once the sun reflector has found the sun we want it to "sleep" for a period of time to conserve power
}
}
}

What I meant by descriptive text was to label the output. Output like this:

102
48
67
192
118

doesn't mean anything. Output like this:

lightLevel1: 102
lightLevel1: 48
lightLevel2: 67
lightLevel2: 192
x: 118

does.

After running the motors a short while, don't you need to turn them off?

  digitalWrite(motor1fwd, HIGH);
  digitalWrite(motor1rev, LOW);
  delay(500);            // if this happens we want a relatively short delay, because we don't want the reflector to turn to far and miss the sun

This sets one motor running, and the other off, and then waits. It never shuts the motor off, though.

But doesn't it return to the beginning of the loop after it has run the motor for 500ms, and then takes a new reading of x, sees which condition is fulfilled and so on?

then turns the motors off once -200<x<200?

Forgive me if it's a stupid question, but before we started with this I hadn't done any programming other then matlab :stuck_out_tongue:

We've made a short video from a early testing. it's a bit difficult to see what's happening but I can post it anyway. (This is before we started worrying about delays :slight_smile:

It does return to the start of loop, where it takes another set of readings. Since it will keep moving, reading, moving, etc. until the readings are nearly equal, and then wait for a longer period of time, I confess that I no longer understand what your problem is.

You were complaining that it always seems to wait for a long time...

Yes, It always waits as long as the longest delay, even when x is for example larger than 200. Where it should wait for 500ms, it instead waits for 5000ms, telling motor 1 to continue to turn forward a long time after x has changed and no longer is larger than 200.

This perhaps does not sound like a big problem, but we where hoping to have a delay under "else" in the range of 10 minutes when both motors are set to LOW.:stuck_out_tongue:
But if the delay is 10 minutes when the engines are set to HIGH we will have a massive failure, once the sun reflector has turned more than 360 degrees :stuck_out_tongue:

Yes, It always waits as long as the longest delay,

It should. But, it should only wait that long time after turning the motors off.

So, where is that serial output, so we can see what is happening?

I currently don't have access to the microcontroller, but I'm working on it :slight_smile:

Okay I've collected some data. the first row's I didn't do anything, then I tried covering one of the diodes slightly, then I put my finger on it covering it completely, finally I tried covering the other diode.

code:

x=0
lightLevel1=1530
lightLevel2=1530
x=-255
lightLevel1=1530
lightLevel2=1785
x=-1530
lightLevel1=0
lightLevel2=1530
x=255
lightLevel1=1785
lightLevel2=1530

The diodes where placed fairly close to each other, so when I tried covering one, I accidently might have covered the other slightly. But I can't see why this would affect the outcome. :slight_smile:

Are the values for lightLeveln before or after mapping?

after

Is your from range in the map call still 0,1?

What values do lightLevel1 and lightLevel2 have before mapping?

Yes it's still 0,1. Sorry I forgot to print them before mapping, I'll get right to that as well as changing the range in the morning. :slight_smile: