

The if ((wLeft != wLeftOld) & (wRight != wRightOld)) statement also has an else condition with a block that sets counter to zero if the whisker values are not opposite from those of the previous contact. Notice that its code block ending brace is just below the one for the if(counter=4) block. The second level if statement compares the old and new wLeft and wRight values with if ((wLeft != wLeftOld) & (wRight != wRightOld)). If it turns out that wLeft is equal to wRight, the Arduino skips to whatever code follows that last closing brace }. In this picture, the if(wLeft != wRight) statement’s code block contains all the rest of the decision-making code. But sometimes, printing out the code and simply drawing lines to connect opening and closing braces helps to see all the blocks at once, which is useful for finding bugs in deeply nested code. In the Arduino editor, you can double-click on a brace to highlight its code block. The picture below shows some nested if statements from the last sketch. One thing that can be tricky about nested if statements is keeping track of opening and closing braces for each statement’s code block. In that case, the counter variable is set to zero so that it can start counting again when it really does find a corner. WLeft = 0 // Set up whisker states for U-turnĬounter = 0 // Clear alternate corner countīut, if the conditions in if((wLeft != wLeftOld) & (wRight != wRightOld)) are not all true, it means that this is not a sequence of alternating whisker contacts anymore, so the BOE Shield-Bot must not be stuck in a corner. This makes the whisker navigation routine think both whiskers are pressed, so it makes a U-turn. How does it do that? It sets both wLeft and wRight to zero. When the if(counter = 4) statement is true, its code block tricks the whisker navigation routine into thinking both whiskers are pressed. If this is the fourth consecutive alternate whisker contact, then it’s time to reset the counter variable to 0 and execute a U-turn. WLeftOld = wLeft // Record current for next rep if((wLeft != wLeftOld) & (wRight != wRightOld)) It’s also time to remember the current whisker pattern by setting wLeftOld equal to the current wLeft and wRightOld equal to the current wRight. If both conditions are true, it’s time to add 1 to the counter variable that tracks alternate whisker contacts. That’s if( (wLeft != wLeftOld) & (wRight != wRightOld)). To do that, a nested if statement checks if the current wLeft value is different from the previous one and if the current wRight value is different from the previous one. If they are not equal it means one whisker is pressed, and the sketch has to check whether it’s the opposite pattern as the previous whisker contact. If(wLeft != wRight) // One whisker pressed? In English, if(wLeft != wRight) means “if the wLeft variable is not equal to the wRight variable…” // Corner Escape A simple way to do this is to use the not-equal operator ( != ) in an if statement. The first thing the code below // Corner Escape has to do is check if one or the other whisker is pressed. wLeftOld = 0 // Initialize previous whisker So, wLeftOld and wRightOld are assigned initial values in the setup function before the loop function starts checking and modifying their values. Since the routine for detecting corners always looks for an alternating pattern, and compares it to the previous alternating pattern, there has to be an initial alternate pattern to start with. The counter variable can start with zero, but one of the “old” variables has to be set to 1. These variables are initialized in the setup function. byte wLeftOld // Previous loop whisker valuesīyte counter // For counting alternate corners Then counter is used to track the number of consecutive, alternate contacts.

The wLeftOld and wRightOld variables store the whisker states from a previous whisker contact so that they can be compared with the states of the current contact. This sketch is a modified version of RoamingWithWhiskers, so we’ll just look at the new code for detecting and escaping corners.įirst, three global byte variables are added: wLeftOld, wRightOld, and counter.
