Change between functions with buttons

Hi all,

I am creating a heliostat user interface with pushbuttons. The code has different functions (). I want to control each of the functions with pushbuttons, so when user presses button 1 execute HeliostatTracking() function, button 2 CaptureTarget. Could you please assist as to how to write that code. With the HeliostatTracking function, I want the code to run infinately until the user presses any other button. How do I do that.

/*
Update from Code V3 is that this code has the limits of the sun position because we don't want the heliostat to be turned on throughout the night.
Use of functions to move the linear actuators.
We only want it on when the sun elevation is greater than 5 and azimuth must be from dawn to dusk.
*/

#include <SolarPosition.h>    //Sun position library to get sun azimuth and elevation angle
#include <DS3232RTC.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>


Adafruit_BNO055 myIMU = Adafruit_BNO055(-1, 0x28);

// number of decimal digits to print
uint8_t digits = 3;


//Linear actuator variable declaration
int speedLA = 150;
const int ENA_PIN = 6; // the Arduino pin connected to the EN1 pin L298N
const int IN1_PIN = 7; // the Arduino pin connected to the IN1 pin L298N
const int IN2_PIN = 8; // the Arduino pin connected to the IN2 pin L298N

const int ENB_PIN = 11; // the Arduino pin connected to the EN1 pin L298N
const int IN3_PIN = 9; // the Arduino pin connected to the IN3 pin L298N
const int IN4_PIN = 10; // the Arduino pin connected to the IN4 pin L298N

int LedAzt = 3;
int LedEle = 5;

volatile float sunEle;
volatile float sunAzt;

float TargetAzimuth;
float TargetElevation;
//these need to be calculated from the sun and target azimuth and elevation angles
float DN_Azimuth;   //destination normal azimuth angle
float DN_Elevation; //destination normal elevation angle

SolarPosition Loughborough(52.76336662631451, -1.2481144519918814);  // Loughborough, UK

void setup() {
 
  Serial.begin(115200);
  pinMode(LedAzt, OUTPUT);
  pinMode(LedEle, OUTPUT);
  SolarPosition::setTimeProvider(RTC.get);      //Using the RTC to get the current time

//********LINEAR ACTUATOR SET UP*********
  pinMode(ENA_PIN, OUTPUT);
  pinMode(IN1_PIN, OUTPUT);
  pinMode(IN2_PIN, OUTPUT);

  pinMode(IN3_PIN, OUTPUT);
  pinMode(IN4_PIN, OUTPUT);
  pinMode(ENB_PIN, OUTPUT);
  
  analogWrite(ENA_PIN, speedLA);
  analogWrite(ENB_PIN, speedLA);
 
//*******IMU SETUP CODE********************************
  Serial.println("Starting IMU....."); Serial.println("");

  /* Initialise the sensor */
  if(!myIMU.begin())
  {
    /* There was a problem detecting the BNO055 ... check your connections */
    Serial.print("Ooops, no IMU detected ... Check your wiring or I2C ADDR!");
    while(1);
  }

  delay(1000);
  myIMU.setExtCrystalUse(true);
  Serial.println("Calibration status values: 0=uncalibrated, 3=fully calibrated");
//**********************************************************
}

void loop() {
  
  //*******IMU calibration***************
  uint8_t system, gyro, accel, mag = 0;
  myIMU.getCalibration(&system, &gyro, &accel, &mag);
  Serial.println("");
  Serial.print("CALIBRATION: Sys=");
  Serial.print(system, DEC);
  Serial.print(" Gyro=");
  Serial.print(gyro, DEC);
  Serial.print(" Accel=");
  Serial.print(accel, DEC);
  Serial.print(" Mag=");
  Serial.println(mag, DEC);
  
  MoveHeliostat(); 

  CaptureTarget(TargetAzimuth, TargetElevation);
  
  SolarPosition(Loughborough.getSolarPosition(), digits);       //Get the Sun Azimuth and Elevation angles and return the destination normal angles
  HeliostatTracking();
}

void MoveHeliostat(){
  
    while(Serial.available()>0) // if there is data comming
   {
    int motion = Serial.parseInt(); //Serial.parseInt() for serial monitor interface, Serial.read() for bluetooth
    Serial.print("data received ");
    Serial.println(motion);
    
    if(motion == 1){
      // extend the azimuth actuator
      digitalWrite(IN1_PIN, HIGH);
      digitalWrite(IN2_PIN, LOW);   
      Serial.println("Extending Azimuth"); 
      
    }
    if (motion == 2){
      // retract the azimuth actuator
      digitalWrite(IN1_PIN, LOW);
      digitalWrite(IN2_PIN, HIGH); 
      Serial.println("Retracting Azimuth");  
      
    }
    if (motion == 3){
      // stop the azimuth actuator
      digitalWrite(IN1_PIN, LOW);
      digitalWrite(IN2_PIN, LOW);
      Serial.println("Stopped Azimuth");
      
    }
    if(motion == 6){
      // extend the ELEVATION actuator
      digitalWrite(IN3_PIN, HIGH);
      digitalWrite(IN4_PIN, LOW);
      Serial.println("Extending Elevation");
      
    }
    if (motion == 7){
      // retract the ELEVATION actuator
      digitalWrite(IN3_PIN, LOW);
      digitalWrite(IN4_PIN, HIGH);
      Serial.println("Retracting Elevation");
      
    }
    if (motion == 8){
      // stop the ELEVATION actuator
      digitalWrite(IN3_PIN, LOW);
      digitalWrite(IN4_PIN, LOW);
      Serial.println("Stopped Elevation");
    }
   } 
}

void CaptureTarget(float tazt, float tele){
  
  imu::Vector<3> TargetEulerAngle = myIMU.getVector(Adafruit_BNO055::VECTOR_EULER);
  
  Serial.print("Angle x, y, z are ");
  Serial.print(tazt = TargetEulerAngle.x());
  Serial.print(", ");
  Serial.print(tele = 90 - TargetEulerAngle.z());
  Serial.println(" respectively.");

  return tazt, tele;
} 
void HeliostatTracking(){

  //******CODE to find the CURRENT Azimuth and Elevation angles of the mirror********
  float CN_Azimuth, CN_Elevation;     //euler degrees of current normal 
  imu::Vector<3> CurrentNormal = myIMU.getVector(Adafruit_BNO055::VECTOR_EULER);
  
  Serial.print("Current Azimuth ");
  Serial.print(CN_Azimuth = CurrentNormal.x());     //Current Normal Azimuth angle, x euler angle in degress
  Serial.print("\t\tCurrent Elevation ");
  Serial.println(CN_Elevation = 90 - CurrentNormal.z());     //Current Normal Elevation angle, z euler angle in degress; (90 - Current Normal ) because we are changing the elevation angle plane to be the plane of the mirror

   
  //*******Now we need to move the linear actuators accordingly***************************

  if (sunEle >4 && sunAzt > 110 && sunAzt < 250){ //perform the following code only when the sun position is high enough in the sky
    
      //the reason the angles are rounded is because it is very difficult for the Destination normal value (till 2 decimal places) to be equal to the Current Normal Value
      //this gives us an error +/- 1 degree.
      if(round(DN_Azimuth) > round(CN_Azimuth)){    //if the Destination Azimuth is greater than Current Azimuth retract the azimuth linear actuator
         //retract Azimuth linear actuator
         RetractAzimuth();
         digitalWrite(LedAzt, HIGH);     //LED is lit up to indicate that the destination azimuth is greater than the current azimuth
          
      }
      else if (round(DN_Azimuth) < round(CN_Azimuth)){
          //extend Azimuth linear actuator
          ExtendAzimuth();
          analogWrite(LedAzt, 50);         //LED brightness reduces to indicate that the destination azimuth is less than the current azimuth
      }
      else{
        //stop azimuth linear actuator and pause program for 2 seconds for example. Experimentally determine later if you want to increase the time. THis causes the sun to move enough for the next reading.
        StopAzimuth();
        digitalWrite(LedAzt, LOW);            //LED is turned off indicate that the destination azimuth is equal to the current azimuth and hence the mirror has reached the correct orientation
        delay(200);
      }
    
      //Now, we need to move the elevation linear actuator accordingly
      if(round(DN_Elevation) > round(CN_Elevation)){    //if the Destination Elevation is greater than Current Elevation retract the elevation linear actuator
          //retract elevation linear actuator
          RetractElevation();          
          digitalWrite(LedEle, HIGH);          //LED is lit up to indicate that the destination elevation is greater than the current elevation
      }
      else if (round(DN_Elevation) < round(CN_Elevation)){
        //extend elevation linear actuator
        ExtendElevation();
        analogWrite(LedEle, 50);      //LED brightness reduces to indicate that the destination elevation is less than the current elevation
      }
      else{
        //stop elevation linear actuator and pause program for 2 milliseconds for example. Experimentally determine later if you want to increase the time. THis causes the sun to move enough for the next reading.
        StopElevation();
        digitalWrite(LedEle, LOW);      //LED is turned off indicating that the destination elevation is equal to the current elevation and hence the mirror has reached the correct elevation angle
        delay(200);
      }
      if(round(DN_Azimuth) == round(CN_Azimuth) && round(DN_Elevation) == round(CN_Elevation)){
        Serial.print("Error Azimuth = "); Serial.print(abs(DN_Azimuth-CN_Azimuth));
        Serial.print("\t  Error Elevation = "); Serial.println(abs(DN_Elevation-CN_Elevation));
        delay(60000);
      }   
     delay(100);
  }
}
  
void SolarPosition(SolarPosition_t pos, int numDigits){
  
  //*******Calculating the SUN azimuth and elevation angle********
  sunEle = pos.elevation;  //Sun Elevation Angle in Degrees
  sunAzt = pos.azimuth;     //Sun Azimuth Angle in Degrees
  Serial.println("Loughborough ");
  Serial.print("Sun Azimuth: ");
  Serial.print(sunAzt, numDigits);
  Serial.print(" deg");
  Serial.print("\tSun Elevation: ");
  Serial.print(sunEle, numDigits);
  Serial.println(" deg   ");

 //********CODE to calculate the Destination Azimuth and Elevation******************
  DN_Azimuth = (sunAzt + TargetAzimuth ) / 2 ;          //Midpoint azimuth
  DN_Elevation =(sunEle + TargetElevation) / 2 ;        //Midpoint Elevation

  Serial.print("Destination Azimuth ");
  Serial.print(DN_Azimuth);
  Serial.print("\tDestination Elevation ");
  Serial.println(DN_Elevation);
}

//Useful Functions

void ExtendAzimuth(){
  digitalWrite(IN1_PIN, HIGH);
  digitalWrite(IN2_PIN, LOW);
}

void RetractAzimuth(){
  digitalWrite(IN1_PIN, LOW);
  digitalWrite(IN2_PIN, HIGH);
}

void StopAzimuth(){
  digitalWrite(IN1_PIN, LOW);
  digitalWrite(IN2_PIN, LOW);
}

void ExtendElevation(){
  digitalWrite(IN3_PIN, HIGH);
  digitalWrite(IN4_PIN, LOW);
}

void RetractElevation(){
  digitalWrite(IN3_PIN, LOW);
  digitalWrite(IN4_PIN, HIGH);
}

void StopElevation(){
  digitalWrite(IN3_PIN, LOW);
  digitalWrite(IN4_PIN, LOW);
}

Not helping.

You can not return two values from a function like you do with

  return tazt, tele;

Further the function that uses it is declared as void indicating that it will not return anything.
Use references or pointers; below uses references which is slightly easier.

void CaptureTarget(float &tazt, float &tele) {
  ...
  ...
  // do not return anything
  return;

If you want your code to be responsive, you will have to get rid of delay in favour of a millis() based approach.

Ok thank you. I've self taught myself programming so I struggle writing code sometimes. How could I Go about solving the problem using millis()?

the basic concept of a program like you have described it above is to have one big loop running
- all the time checking if a button is pressed
- all the time checking what function is activated

and depending on what function is activated to execute that function
in your case
if tracking is activated execute HeliostatTracking() in a jump**-in** / jump**-out** manner

if capture target is activated execute CaptureTarget() in a jump**-in** / jump**-out** manner

The jump**-in** / jump**-out** enables to do the checking for the button-presses in parallel to the all other functions.

delay() is a blocking timing. As long as a delay() is executed no other code can be executed
timing has to be done in a non-blocking way by

- all the time checking: how much time has passed by since a startingTime

The startingTime is a snapshot of time realised by storing the actual "daily" time in a variable

On microcontrollers there is no daily time. On microcontrollers you use a "clock" that counts milliseconds since power-on. This function is the function millis().

and then the timing works similar to this explanation:
pizza-example
as an everyday example with easy to follow numbers
delay() is blocking. As long as the delay is "delaying" nothing else of the code can be executed.
Now there is a technique of non-blocking timing.
The basic principle of non-blocking timing is fundamental different from using delay()

You have to understand the difference first and then look into the code.

otherwise you might try to "see" a "delay-analog-thing" in the millis()-code which it really isn't
Trying to see a "delay-analog-thing" in millis() makes it hard to understand millis()
Having understood the basic principle of non-blocking timing based on millis() makes it easy to understand.

imagine baking a frosted pizza
the cover says for preparation heat up oven to 200°C
then put pizza in.
Baking time 10 minutes

You are estimating heating up needs 3 minutes
You take a look onto your watch it is 13:02 (snapshot of time)
You start reading the newspaper and from time to time looking onto your watch
watch shows 13:02. 13:02 - 13:02 = 0 minutes passed by not yet time
watch shows 13:03. 13:03 - 13:02 = 1 minute passed by not yet time
watch shows 13:04. 13:04 - 13:02 = 2 minutes passed by not yet time

watch shows 13:05 when did I start 13:02? OK 13:05 - 13:02 = 3 minutes time to put pizza into the oven

New basetime 13:05 (the snapshot of time)
watch 13:06 not yet time
watch 13:07 not yet time
watch 13:08 not yet time (13:08 - 13:05 = 3 minutes is less than 10 minutes
watch 13:09 not yet time
watch 13:10 not yet time
watch 13:11 not yet time
watch 13:12 not yet time
watch 13:13 not yet time
watch 13:14 not yet time (13:14 - 13:05 = 9 minutes is less than 10 minutes
watch 13:15 when did I start 13:05 OK 13:15 - 13:05 = 10 minutes time to eat pizza (yum yum)

You did a repeated comparing how much time has passed by
This is what non-blocking timing does

In the code looking at "How much time has passed by" is done

currentTime - startTime >= bakingTime

bakingTime is 10 minutes

13:06 - 13:05 = 1 minute >= bakingTime is false
13:07 - 13:05 = 2 minutes >= bakingTime is false
...
13:14 - 13:05 = 9 minutes >= bakingTime is false
13:15 - 13:05 = 10 minutes >= bakingTime is TRUE time for timed action!!

As you can see quite a lot things to learn. But you want to have a much more complex functionlaity than switching on/off an LED once per second.

The functionality of executing multiple functions (almost) in parallel in a jump-in / jump-out manner is to use a state-machine. Another concept that needs some time to learn.
Once you have understood how state-machines work I promise you that you never want to go back to not use them.

best regards Stefan

Thank you very much Stefan. I'll start reading about state-machines

You can write a return statment like this:

 return x + y, x - y;

but it isn't doing what you might think.

What you shouldn't do is return anything from a function declared void, as has been pointed out.

The compiler knows this, but lets you anyway.

Haha, it lets you (off) with a warning, viz:

/var/folders/gz/t92bgl156gdf2066kn0xpc7w0000gq/T/arduino_modified_sketch_190482/sketch_feb12a.ino:6:20: warning: return-statement with a value, in function returning 'void' [-fpermissive]
  return x + y, x - y;
                    ^

Go the the IDE preferences and turn up/on all compiler warnings. Always scan through the compiler output: warnings are in red.

Strive to eliminate all warnings. Experts can get away with some problems that are "just" warnings, don't try this at home. :expressionless:

a7

I've updated the code. Could you please check. It compiles properly

/*
Update from Code V3 is that this code has the limits of the sun position because we don't want the heliostat to be turned on throughout the night.
Use of functions to move the linear actuators.
We only want it on when the sun elevation is greater than 5 and azimuth must be from dawn to dusk.
*/

#include <SolarPosition.h>    //Sun position library to get sun azimuth and elevation angle
#include <DS3232RTC.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>


Adafruit_BNO055 myIMU = Adafruit_BNO055(-1, 0x28);

// number of decimal digits to print
uint8_t digits = 3;
int ButtonSelected;


//Linear actuator variable declaration
int speedLA = 150;
const int ENA_PIN = 6; // the Arduino pin connected to the EN1 pin L298N
const int IN1_PIN = 7; // the Arduino pin connected to the IN1 pin L298N
const int IN2_PIN = 8; // the Arduino pin connected to the IN2 pin L298N

const int ENB_PIN = 11; // the Arduino pin connected to the EN1 pin L298N
const int IN3_PIN = 9; // the Arduino pin connected to the IN3 pin L298N
const int IN4_PIN = 10; // the Arduino pin connected to the IN4 pin L298N

int LedAzt = 3;
int LedEle = 5;

volatile float sunEle;
volatile float sunAzt;

float TargetAzimuth;
float TargetElevation;
//these need to be calculated from the sun and target azimuth and elevation angles
float DN_Azimuth;   //destination normal azimuth angle
float DN_Elevation; //destination normal elevation angle

SolarPosition Loughborough(52.76336662631451, -1.2481144519918814);  // Loughborough, UK

void setup() {
 
  Serial.begin(115200);
  pinMode(LedAzt, OUTPUT);
  pinMode(LedEle, OUTPUT);
  SolarPosition::setTimeProvider(RTC.get);      //Using the RTC to get the current time

//********LINEAR ACTUATOR SET UP*********
  pinMode(ENA_PIN, OUTPUT);
  pinMode(IN1_PIN, OUTPUT);
  pinMode(IN2_PIN, OUTPUT);

  pinMode(IN3_PIN, OUTPUT);
  pinMode(IN4_PIN, OUTPUT);
  pinMode(ENB_PIN, OUTPUT);
  
  analogWrite(ENA_PIN, speedLA);
  analogWrite(ENB_PIN, speedLA);
 
//*******IMU SETUP CODE********************************
  Serial.println("Starting IMU....."); Serial.println("");

  /* Initialise the sensor */
  if(!myIMU.begin())
  {
    /* There was a problem detecting the BNO055 ... check your connections */
    Serial.print("Ooops, no IMU detected ... Check your wiring or I2C ADDR!");
    while(1);
  }

  delay(1000);
  myIMU.setExtCrystalUse(true);
  Serial.println("Calibration status values: 0=uncalibrated, 3=fully calibrated");
//**********************************************************
}

void ButtonSelection(){
  
int setTargetButton;
int captureTargetButton;
int startTrackingButton;

setTargetButton = digitalRead(4);
captureTargetButton = digitalRead(5);
startTrackingButton = digitalRead(6);

 if(setTargetButton == LOW){
    //start the program to move the heliostat mount manually aka SetTarget()
    ButtonSelected = 1;
  }

  if(captureTargetButton == LOW){
    //save the result from the IMU and store it in target azimuth and elevation
    ButtonSelected = 2;
  }
  if(startTrackingButton == LOW){
    //start the sun tracking and set teh heliostat to move automatically
     ButtonSelected = 3;
  }   
}


void MoveHeliostat(){
  
    while(Serial.available()>0) // if there is data comming
   {
    int motion = Serial.parseInt(); //Serial.parseInt() for serial monitor interface, Serial.read() for bluetooth
    Serial.print("data received ");
    Serial.println(motion);
    
    if(motion == 1){
      // extend the azimuth actuator
      digitalWrite(IN1_PIN, HIGH);
      digitalWrite(IN2_PIN, LOW);   
      Serial.println("Extending Azimuth"); 
      
    }
    if (motion == 2){
      // retract the azimuth actuator
      digitalWrite(IN1_PIN, LOW);
      digitalWrite(IN2_PIN, HIGH); 
      Serial.println("Retracting Azimuth");  
      
    }
    if (motion == 3){
      // stop the azimuth actuator
      digitalWrite(IN1_PIN, LOW);
      digitalWrite(IN2_PIN, LOW);
      Serial.println("Stopped Azimuth");
      
    }
    if(motion == 6){
      // extend the ELEVATION actuator
      digitalWrite(IN3_PIN, HIGH);
      digitalWrite(IN4_PIN, LOW);
      Serial.println("Extending Elevation");
      
    }
    if (motion == 7){
      // retract the ELEVATION actuator
      digitalWrite(IN3_PIN, LOW);
      digitalWrite(IN4_PIN, HIGH);
      Serial.println("Retracting Elevation");
      
    }
    if (motion == 8){
      // stop the ELEVATION actuator
      digitalWrite(IN3_PIN, LOW);
      digitalWrite(IN4_PIN, LOW);
      Serial.println("Stopped Elevation");
    }
   } 
}

void CaptureTarget(float &tazt, float &tele){
  
  imu::Vector<3> TargetEulerAngle = myIMU.getVector(Adafruit_BNO055::VECTOR_EULER);
  
  Serial.print("Angle x, y, z are ");
  Serial.print(tazt = TargetEulerAngle.x());
  Serial.print(", ");
  Serial.print(tele = 90 - TargetEulerAngle.z());
  Serial.println(" respectively.");

  return;
} 
void HeliostatTracking(){

  //******CODE to find the CURRENT Azimuth and Elevation angles of the mirror********
  float CN_Azimuth, CN_Elevation;     //euler degrees of current normal 
  imu::Vector<3> CurrentNormal = myIMU.getVector(Adafruit_BNO055::VECTOR_EULER);
  
  Serial.print("Current Azimuth ");
  Serial.print(CN_Azimuth = CurrentNormal.x());     //Current Normal Azimuth angle, x euler angle in degress
  Serial.print("\t\tCurrent Elevation ");
  Serial.println(CN_Elevation = 90 - CurrentNormal.z());     //Current Normal Elevation angle, z euler angle in degress; (90 - Current Normal ) because we are changing the elevation angle plane to be the plane of the mirror

   
  //*******Now we need to move the linear actuators accordingly***************************

  if (sunEle >4 && sunAzt > 110 && sunAzt < 250){ //perform the following code only when the sun position is high enough in the sky
    
      //the reason the angles are rounded is because it is very difficult for the Destination normal value (till 2 decimal places) to be equal to the Current Normal Value
      //this gives us an error +/- 1 degree.
      if(round(DN_Azimuth) > round(CN_Azimuth)){    //if the Destination Azimuth is greater than Current Azimuth retract the azimuth linear actuator
         //retract Azimuth linear actuator
         RetractAzimuth();
         digitalWrite(LedAzt, HIGH);     //LED is lit up to indicate that the destination azimuth is greater than the current azimuth
          
      }
      else if (round(DN_Azimuth) < round(CN_Azimuth)){
          //extend Azimuth linear actuator
          ExtendAzimuth();
          analogWrite(LedAzt, 50);         //LED brightness reduces to indicate that the destination azimuth is less than the current azimuth
      }
      else{
        //stop azimuth linear actuator and pause program for 2 seconds for example. Experimentally determine later if you want to increase the time. THis causes the sun to move enough for the next reading.
        StopAzimuth();
        digitalWrite(LedAzt, LOW);            //LED is turned off indicate that the destination azimuth is equal to the current azimuth and hence the mirror has reached the correct orientation
        delay(200);
      }
    
      //Now, we need to move the elevation linear actuator accordingly
      if(round(DN_Elevation) > round(CN_Elevation)){    //if the Destination Elevation is greater than Current Elevation retract the elevation linear actuator
          //retract elevation linear actuator
          RetractElevation();          
          digitalWrite(LedEle, HIGH);          //LED is lit up to indicate that the destination elevation is greater than the current elevation
      }
      else if (round(DN_Elevation) < round(CN_Elevation)){
        //extend elevation linear actuator
        ExtendElevation();
        analogWrite(LedEle, 50);      //LED brightness reduces to indicate that the destination elevation is less than the current elevation
      }
      else{
        //stop elevation linear actuator and pause program for 2 milliseconds for example. Experimentally determine later if you want to increase the time. THis causes the sun to move enough for the next reading.
        StopElevation();
        digitalWrite(LedEle, LOW);      //LED is turned off indicating that the destination elevation is equal to the current elevation and hence the mirror has reached the correct elevation angle
        delay(200);
      }
      if(round(DN_Azimuth) == round(CN_Azimuth) && round(DN_Elevation) == round(CN_Elevation)){
        Serial.print("Error Azimuth = "); Serial.print(abs(DN_Azimuth-CN_Azimuth));
        Serial.print("\t  Error Elevation = "); Serial.println(abs(DN_Elevation-CN_Elevation));
        delay(60000);
      }   
     delay(100);
  }
}
  
void SolarPosition(SolarPosition_t pos, int numDigits){
  
  //*******Calculating the SUN azimuth and elevation angle********
  sunEle = pos.elevation;  //Sun Elevation Angle in Degrees
  sunAzt = pos.azimuth;     //Sun Azimuth Angle in Degrees
  Serial.println("Loughborough ");
  Serial.print("Sun Azimuth: ");
  Serial.print(sunAzt, numDigits);
  Serial.print(" deg");
  Serial.print("\tSun Elevation: ");
  Serial.print(sunEle, numDigits);
  Serial.println(" deg   ");

 //********CODE to calculate the Destination Azimuth and Elevation******************
  DN_Azimuth = (sunAzt + TargetAzimuth ) / 2 ;          //Midpoint azimuth
  DN_Elevation =(sunEle + TargetElevation) / 2 ;        //Midpoint Elevation

  Serial.print("Destination Azimuth ");
  Serial.print(DN_Azimuth);
  Serial.print("\tDestination Elevation ");
  Serial.println(DN_Elevation);
}


//Useful Functions

void ExtendAzimuth(){
  digitalWrite(IN1_PIN, HIGH);
  digitalWrite(IN2_PIN, LOW);
}

void RetractAzimuth(){
  digitalWrite(IN1_PIN, LOW);
  digitalWrite(IN2_PIN, HIGH);
}

void StopAzimuth(){
  digitalWrite(IN1_PIN, LOW);
  digitalWrite(IN2_PIN, LOW);
}

void ExtendElevation(){
  digitalWrite(IN3_PIN, HIGH);
  digitalWrite(IN4_PIN, LOW);
}

void RetractElevation(){
  digitalWrite(IN3_PIN, LOW);
  digitalWrite(IN4_PIN, HIGH);
}

void StopElevation(){
  digitalWrite(IN3_PIN, LOW);
  digitalWrite(IN4_PIN, LOW);
}

void loop() {
  
  //*******IMU calibration***************
  uint8_t system, gyro, accel, mag = 0;
  myIMU.getCalibration(&system, &gyro, &accel, &mag);
  Serial.println("");
  Serial.print("CALIBRATION: Sys=");
  Serial.print(system, DEC);
  Serial.print(" Gyro=");
  Serial.print(gyro, DEC);
  Serial.print(" Accel=");
  Serial.print(accel, DEC);
  Serial.print(" Mag=");
  Serial.println(mag, DEC);
  //*****************************************

  ButtonSelection();

  if(ButtonSelected = 1){
    while(1)
    {
      MoveHeliostat();
      ButtonSelection();
    }
  } 
  if(ButtonSelected = 2){
      CaptureTarget(TargetAzimuth, TargetElevation);
      ButtonSelection();
  }
  if(ButtonSelected = 3){
  SolarPosition(Loughborough.getSolarPosition(), digits);       //Get the Sun Azimuth and Elevation angles and return the destination normal angles
  while(1)
  {
    HeliostatTracking();
    ButtonSelection();
  }
  }    
}

So should I just remove the void?

No, you should not return anything or declare the function to return a float

float CaptureTarget(float tazt, float tele) {

  ...
  ...
  return tazt; // you can't return two values
}

The better approach was given in post #2.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.