Copying a sensor value.

Im building an autopilot steering control and want to implement a switch that when “on” copies the current compass heading and uses it as the set point for the PID code.

Something like:

X= compass heading;
Setpoint= Y;

If (switch ==1){Y== copy current X value}
Else {Y==Encoder value}

Sounds good, carry on. But remember that C++ is case sensitive. It's "if" and "else", not "IF" and "Else". Also, make sure you understand the difference between the assignment operator (=) and the comparison operator (==).

Yep I put extra = in there.

How would i "copy current X value" at the instant the switch is closed?

How would i "copy current X value" at the instant the switch is closed?

State change detection for the instant the switch is closed. Compare past state to current state. Read the switch in loop() with no use of delay()

Pseudo code

lastSwitchReading =  switchReading;
switchReading = new value of switchReading;

if(switchReading == closed && lastSwitchReading == open)
{
  Y = copyCurrentXValue;
}

//alternative position for assignment of lastSwitchReading =  switchReading;

Having issues getting
copyCurrentXValue to work. Its just producing a “0”

How would I declare it correctly?

Post some minimal code which compiles and demonstrates your problem. Be sure to use auto format, and post within the code tags found on the upper tool bar </>

here it is. using the Virtuino app for bluetooth control. highly recommend it.

the first if statement produces a “0”
the second one works as written

#include "BluetoothSerial.h"
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

BluetoothSerial SerialBT;
#include "VirtuinoCM.h"
VirtuinoCM virtuino;
#define V_memory_count 32          // the size of V memory. You can change it to a number <=255)
float V[V_memory_count];           // This array is synchronized with Virtuino V memory. You can change the type to int, long etc.
boolean debug = true;
void setup() {

  if (debug) {
    Serial.begin(115200);
    while (!Serial) continue;
  }
  Serial.println("setup start");
  SerialBT.begin("APtest"); //Bluetooth device name
  SerialBT.setTimeout(50);
  virtuino.begin(onReceived, onRequested, 256);
  Serial.println(" setup end");// put your setup code here, to run once:

}

void loop() {
  virtuinoRun();
  int copyCurrentAValue;
  int A = V[2];
  V[2] = random(1, 359);
  V[3] = random(1500, 4500);


  if (V[0] == 1) {
    V[2] = copyCurrentAValue;
  }

  if (V[1] == 1) {  ///*****this part works well****
    V[3] = 1000;
  }


}


//============================================================== onCommandReceived
//==============================================================
/* This function is called every time Virtuino app sends a request to server to change a Pin value
   The 'variableType' can be a character like V, T, O  V=Virtual pin  T=Text Pin    O=PWM Pin
   The 'variableIndex' is the pin number index of Virtuino app
   The 'valueAsText' is the value that has sent from the app   */
void onReceived(char variableType, uint8_t variableIndex, String valueAsText) {
  if (variableType == 'V') {
    float value = valueAsText.toFloat();        // convert the value to float. The valueAsText have to be numerical
    if (variableIndex < V_memory_count) V[variableIndex] = value;          // copy the received value to arduino V memory array
  }
}

//==============================================================
/* This function is called every time Virtuino app requests to read a pin value*/
String onRequested(char variableType, uint8_t variableIndex) {
  if (variableType == 'V') {
    if (variableIndex < V_memory_count) return  String(V[variableIndex]); // return the value of the arduino V memory array
  }
  return "";
}

//============================================================== virtuinoRun
void virtuinoRun() {
  while (SerialBT.available()) {
    char tempChar = SerialBT.read();
    if (tempChar == CM_START_CHAR) {             // a new command is starting...
      virtuino.readBuffer = CM_START_CHAR;   // copy the new command to the virtuino readBuffer
      virtuino.readBuffer += SerialBT.readStringUntil(CM_END_CHAR);
      virtuino.readBuffer += CM_END_CHAR;
      if (debug) Serial.println("\nCommand= " + virtuino.readBuffer);
      String* response = virtuino.getResponse();   // get the text that has to be sent to Virtuino as reply. The library will check the inptuBuffer and it will create the response text
      if (debug) Serial.println("Response : " + *response);
      SerialBT.print(*response);
      break;
    }
  }
}


//============================================================== vDelay
void vDelay(int delayInMillis) {
  long t = millis() + delayInMillis;
  while (millis() < t) virtuinoRun();
}

I have no experience with Virtuino or the ESP32. I don't think I can be of much help.

However I see that when you do this, copyCurrentValue does not have any value other than the declaration in loop int copyCurrentAValue; which as a local variable may not have a defined value, and it certainly could be 0.

if (V[0] == 1) {
    V[2] = copyCurrentAValue;
  }

If you put a delay after this statement do you see the correct random value on the phone?

V[2] = random(1, 359);

I solved the issue by changing the Virtuino switch to a button. When pressed = 1 when released = 0.
Seems to do the trick