2

The issue: In the following example even though complexManoeuvre == 3, Serial.print(CTA5: "); ... is executed.

void loop()  {
  if(complexManoeuvre == 0) {
    if(timeisup == true && goingForwards == 1)  {   // If time is up while going forward, assume it's stuck
      goingForwards = 0;
      Serial.print("CTA4: "); stuck(stk);
    }
    if(timeisup == true && goingForwards != 1)  {   
      Serial.print("CTA5: "); Serial.print(complexManoeuvre); forward(fwd);
    }
  }
}

However, if I include the first condition within the other if() statments two then it works:

if(complexManoeuvre == 0 && (deltaBegan >= manoeuvreFor) && goingForwards == 1) {
  goingForwards = 0;
  Serial.print("CTA4: "); Serial.print(complexManoeuvre); stuck(stk);
}
if(complexManoeuvre == 0 && (deltaBegan >= manoeuvreFor) && goingForwards != 1) {
  //Serial.print("complexManoeuvre == "); Serial.println(complexManoeuvre);
  Serial.print("CTA5: "); Serial.print(complexManoeuvre); forward(fwd);
}

Being completely stumped, I suspected compiler issue so I reinstalled Arduino to clear Meguno-link avrdude wrapper but the problem remains.

The full code (for a robot hoover) is as follows, slimmed down as much as possible to simplify reading:

const int fwd = 12000;            // ms duration
const int stk = 1600;
unsigned long beganManoeuvre;     // millis time when manoeuvre began
int manoeuvreFor;                 // Duration
unsigned long lastStuck;
byte goingForwards;               // Yes or no
byte complexManoeuvre;            // 0 = none, 1 = center, 2 = stuck, 3 = doubleStuck
byte progress;                    // complexManoeuvre progress

void setup() { Serial.begin(9600); Serial.print(F("CTA0: ")); spinR(4800); // Spin through 360 degrees }

void loop() {
bool timeisup = false; if((millis() - beganManoeuvre) >= manoeuvreFor) { timeisup = true; }

if(complexManoeuvre != 0 && timeisup == true) { // If part way through a in a complex switch(complexManoeuvre) { // ..manoeuvre (eg; stuck) case 1: // do other() break; case 2: Serial.print(F("CTA2: ")); stuck(manoeuvreFor); // return to the complex manoeuvre break; } }

// if(complexManoeuvre == 0 && timeisup == true && goingForwards == 1) { // goingForwards = 0; // Serial.print("CTA4: "); Serial.print(complexManoeuvre); stuck(stk); // } // if(complexManoeuvre == 0 && timeisup == true && goingForwards != 1) { // //Serial.print("complexManoeuvre == "); Serial.println(complexManoeuvre); // Serial.print("CTA5: "); Serial.print(complexManoeuvre); forward(fwd); // } if(complexManoeuvre == 0) { if(timeisup == true && goingForwards == 1) { // If timeisup while going forward, assume stuck goingForwards = 0; Serial.print("CTA4: "); stuck(stk); } if(timeisup == true && goingForwards != 1) { // If finished another manoeuvre, go forwards if(complexManoeuvre != 0) Serial.println("What the?!"); Serial.print("CTA5: "); Serial.print(complexManoeuvre); forward(fwd); } } }

void stuck(int dur) { Serial.print(F("void stuck(int dur == ")); Serial.println(dur); switch(progress) {
case 0: Serial.print(F("CTA26: ")); complexManoeuvre = 2; reverse(dur); progress = 1; break; case 1: Serial.print(F("CTA27: ")); spinR(dur); progress = 2; break; case 2: // Reset progress = 0; complexManoeuvre = 0; lastStuck = millis(); break; } }

void forward(int dur) { Serial.print(F("void forward(int ")); Serial.print(dur); if(goingForwards != 1) { Serial.print(F(") >> if(goingForwards != 1) then do")); goingForwards = 1; beganManoeuvre = millis(); manoeuvreFor = dur; digitalWrite(9, HIGH); digitalWrite(10, LOW); digitalWrite(11, HIGH); digitalWrite(12, LOW); } Serial.println(); }

void reverse(int dur) { Serial.print(F("void reverse(int dur == ")); Serial.println(dur); beganManoeuvre = millis(); manoeuvreFor = dur; digitalWrite(9, LOW); digitalWrite(10, HIGH); digitalWrite(11, LOW); digitalWrite(12, HIGH); }

void spinR(int dur) { Serial.print(F("void spinR(int dur == ")); Serial.println(dur); beganManoeuvre = millis(); manoeuvreFor = dur; digitalWrite(9, LOW); digitalWrite(10, HIGH); digitalWrite(11, HIGH); digitalWrite(12, LOW); }

The questionable Serial output is:

1) 19:59:31.964 -> CTA0: void spinR(int dur == 4800
2) 19:59:36.765 -> CTA5: 0void forward(int 12000) >> if(goingForwards != 1) then do
3) 19:59:48.771 -> CTA4: void stuck(int dur == 1600
4) 19:59:48.811 -> CTA26: void reverse(int dur == 1600
5) 20:11:12.695 -> What the?!
6) 19:59:48.851 -> CTA5: 2void forward(int 12000) >> if(goingForwards != 1) then do
7) 20:00:00.854 -> CTA2: void stuck(int dur == 12000
8) 20:00:00.894 -> CTA27: void spinR(int dur == 12000
9) 20:00:12.860 -> CTA2: void stuck(int dur == 12000
10) 20:00:12.900 -> CTA4: void stuck(int dur == 1600
...

Edit to add: Arduino version 1.8.13, Win7, tested on Nano Atmega168PA and Mega2560

lsbyte
  • 21
  • 2
  • if(timeisup == true) is equivalent to if(true == true) which is redundant ... if(timeisup) is the same – jsotola Nov 04 '20 at 21:52

1 Answers1

1

Your void Stuck() { ... }, which is called inside the first if (timeisup == true && goingForwards == 1) { ... } can set complexManoeuvre to a non-zero value, before reaching the second if (timeisup == true && goingForwards != 1) { ... } (the one with "What the?!").

StarCat
  • 1,641
  • 1
  • 6
  • 14
  • exactly Serial.print(F("CTA26: ")); complexManoeuvre = 2; recerse(dur); – Juraj Nov 04 '20 at 20:55
  • But, if I'm not mistaken, it needs to do that in order for the process to return to stuck() to continue through the switch(progress). – lsbyte Nov 04 '20 at 20:55
  • 1
    It's not exactly "can set", it will set it to 2 – KIIV Nov 04 '20 at 20:58
  • Change the if() statements to the second version and everything works as it should. But... that's what I don't understand. – lsbyte Nov 04 '20 at 21:02
  • @lsbyte Maybe it needs to do that, but after the struck call ends, it'll continue processing commands after that call. That means it goes out of the first nested if block {} and guess what, another nested if is right after that first one. – KIIV Nov 04 '20 at 21:02
  • But shouldn't the progress only increment once each time the process visits stuck()? I don't understand how changing the if() statements in loop could effect the behaviour of the switch(progress) – lsbyte Nov 04 '20 at 21:07
  • @lsbyte You are doing pretty much this int a = 0; if (a == 0) { a = 2; } if (a != 0) { Serial.println("but why?"); } and you are asking why is the a not zero, after you changed it to 2. The stuck has "side effects" and one of them is changing complexManeuvre. – KIIV Nov 04 '20 at 21:15