More Sensors, and Finally Feedback & Control!
We have moved into feedback & control! Though my break felt sadly short, I’m back to ENGR160!
One more Arduino-associated project ahead before we finally finish the feedback
& control projects. Before starting
this segment however, Amy wanted us to run through three more available sensors and their
codes. Below are the three sensors and their respective sample codes that we
tried out.
The Three Sensors
1) Encoders
Inside the Lego motors are these sensors called encoders, and they allow the motor to transmit how many times the shaft has rotated. We were asked to review and understand the sample code. As mentioned in the screenshot below, in comment form, the starting value for the encoder should be, and is, 0, as well should be the ending value, but isn’t. The encoder starts at 0 because the code calls motor m, the motor being measured, to start at 0 using m.set_pos(0);. In order to measure the shaft rotations per loop, the encoder should also end in 0. The value does not end in 0 however, because motor m is simply asked to stop after finishing the loop, and the motor m’s position isn’t set back to 0. After motor m has finished the loop, it has already performed many rotations, which the encoders recognize as a nonzero value. It is important to note that in the forward direction (of positive speed values set for motor m), the encoder measures the number of shaft rotations with increasing negative values. The opposite holds true for when the speed is set in the reverse direction (negative speed), as the encoder will then measure the number of shaft rotations with increasing positive values.
At the front of our SciBorg is a touch switch that has been integrated into one big arm, allowing the SciBorg the capability to sense when it hits an object. For this sensor to the functional, we attached the wires of the touch switch to the breadboard which we then attached to the shield. In the original sample code we were given, the LED light stays on forever after the switch is pushed because there is no command that tells the LED to switch back to dim. We were asked to modify the code so that the LED light would be brighter when the switch is pushed, but back to dim when the switch was not. We added one line to the code, accomplishing the small task.
![]() |
| Touch Switch Original |
![]() |
| Touch Switch Modified |
3) Ultrasonic Sensor
The ultrasonic sensor was also already attached to our SciBorg, and are used to detect objects without contact. It uses high frequency sound to detect and localize objects in different settings. We practiced with the sample ultrasonic sensor code to not only understand, but to also get a sense of the range of this sensor. It was very sensitive to its environment, and even the sides of its vision could interfere with the detected numeric distance of the object. We noticed that the closer we were to the sensor, the less it could detect objects in its periphery vision, but the farther away we held it, the sensor could possibly detect an object that is not within its direct vision.
Yay! This is where we finally started getting into feedback & control activities. As I made my way through the first few programs, I thought they were a bit difficult to understand, but I'm glad I am able to understand and produce these lines of code!
A) Fixed Distance, Bang-Bang Control
Task: Use our old sketch to document how close we were to our 10 feet goal.
As you can see the video from my last blog, our SciBorg made it to the 10 feet line almost every time. Running the code several times, the distance of the SciBorg from the finish line could be as much as +/- 7cm, and could be as close as +/- 2. We took into account the wheels' imperfections and the possibility of the slight curving to reach the finish line. The only times where it did not make it to the finish line were when the SciBorg steered very harshly to the right or left at the start line, running in the completely wrong direction.
Task: Integrate the encoder sensor code to measure the distance traveled by the SciBorg as it travels 10 feet.
We decided that we would base our code off of the encoder sensor sample code given to us, and used the trial and error process to find the correct number of shaft rotations before the SciBorg reached 10 feet. The line, while(current_position > -13000), was fiddled with in order to accomplish the 10 feet goal, and -13000 represents the number of shaft rotations necessary in the forward direction. Using the code below, our SciBorg hit the 10 feet line in most of our runs, missing exactly 10 feet on average by - 3 cm.
As a small reflection, I now realize that we could have used our original 10 feet challenge program, run by time, as a program that allows the encoders to measure shaft rotations. The program did not necessarily have to be driven by the measure of shaft rotations, but could have been time. Our goal was to measure the distance traveled by the SciBorg. Just including lines to initialize and use the encoder, and to print out the current position, would have been enough.
Task: Incorporate the touch sensor so that the SciBorg stops when the switch is pressed
For this task, we looked back at the touch switch code and used it as a guide to help us create this program. As displayed through the video below, the object (my hand) would need to be directly pressing on the switch lightly for the motors to stop (0 cm between SciBorg and object).
Task: Incorporate the ultrasonic sensor so that the SciBorg stops when it hits an object.
Using trial and error, we were able to map out an appropriate distance for the ultrasonic sensor so that it would stop in front of an object. We did not want it to hit the object directly and press firmly on the touch switch. We fumbled around with the distance, which was we set in the line if (value < 15). Value was the distance that the ultrasonic sensor was reading at the moment, and 15 or less meant that when the reading value were within the appropriate range, the motors, would stop. As you can see in the video below, my hand, the "object", is considerably close to the sensor, but does not touch. Running the SciBorg on the ground using this code and measuring from the front of the Sciborg, it stopped an average of around 3 or 4 cm away from the object.
B) Fixed Distance, Proportional Control
Task: Write a sketch that uses proportional control to go exactly 10 feet
This task was quite the challenge, because we went through many trial and error runs in order for the SciBorg to reach 10 feet.
Just to note: on the third line of the code, it says const int kPin_ultra = A0;, which is an extraneous line of code that will be used later.

The power supplied to the motors, as written in the code, is a product of a constant gain factor and the average of the shaft-encode variables, (ideal - actual). Because we were asked to use this product to reduce the speed of the SciBorg as it nears 10 feet, we had to experiment with the gain factor and the ideal value to achieve the results we want. In the trial run shown above, the SciBorg hasn't quite reached 10 feet yet, but it was slowly improving. In the final run shown below, the SciBorg reaches exactly 10 feet, from a combination of changing the ideal shaft rotations and the gain factor. On average, the SciBorg was about - 7cm away from exactly 10 feet, and as close as -2 cm off. Although our results would not reproduce precise measurements on our own SciBorg, it is still close to 10 feet. The results would not be reproducible on another SciBorg; we modified the gain values to suit our own SciBorg’s imperfections. I realized as I was playing around with the gain factor in (17000-current_position)*(-.015), or (ideal - actual)*gain, or error x gain, that the increasing the gain to above a certain value would cause the motors to stop. In the first few trials with the proportional control, I nudged the SciBorg to get the wheels turning. Changing the gain many, many times over, we realized that the gain factor was very picky; if it was too high, the motors stopped working, but when it was too low, the SciBorg will not go far overall. We were trying to hit the sweet point where the speed is the highest as it starts, and slowly decreases speed. The problem with achieving this idea was that although a higher gain meant the SciBorg's initial speed was faster, the current_position of the motor would have increased significantly, which meant a lower overall speed value sooner. A lower gain, on the other hand, meant that the current_position would increase more steadily, allowing for a slower transition to a lower speed. However, the SciBorg's speed initial speed would decline, and since the initial speed is its peak, the motors will only come to rotate slower.
By playing around with the gain factor as well as the "ideal" value, we managed to accomplish the task. I realized that as we increased the ideal value, we were also increasing the travel of the SciBorg.
Task: Use "Nudge" to inch closer to the 10 feet line after the Sciborg's speed has decreased too much to overcome friction
For nudge, besides fiddling with the gain and ideal value, we also had the play with the timing of the nudge and when it would appear. We initially had trouble with the code because we were confused about where the nudge would take place. Changing the while loop to an if statement, we allowed ourselves to be more flexible with the shaft rotations, and so that we could cut off the last part of proportional control to add in nudges. It scared us a little when one wheel started going faster than another, but we soon discovered that friction against the jutted axle had decreased the speed of the wheel. After more trial and error, we reached our goal! The SciBorg was within +/- 1cm from exactly 10 feet.
C) Conga Line
Task: Use the ultrasonic sensor to allow the SciBorg to follow something in front of it (Bang-Bang Control)
We started the Bang Bang Congo Line task thinking to ourselves what needed to be implemented. A turn? Going straightforward? How would the SciBorg be able to recognize that there is an object in front of it? How would move only with the object in front? Implementing turns were a bit difficult, but adjusting speeds so that the SciBorg would go straight was even more so. We finished the Bang Bang Controlled Congo Line using the code below, and I made a few modifications to make Version 2. In Version 1, the SciBorg is moving as told; there is an object in front of it moving in a straight line, and the SciBorg will follow. If there is nothing in front of the SciBorg however, it will stop, until another object passes by.
Task: Use the ultrasonic sensor to allow the SciBorg to follow something in front of it (Proportional Control)
Below, although both of them are titled "Proportional Congo Line Version 1", the first screenshot is only one of the many trials, and the second screenshot is our final draft of the code.
In this trial, we played around with the loop to see if we could decrease the speed using the encoder and the gain product. What we weren't able to accomplish, however, was resetting the shaft rotation count to 0 again without asking the wheels to reverse their directions. We ran into the issue of the awkward backup, where the SciBorg would go forward, but would stop and back away from the object that it was supposed to follow. In addition to this issue, because we couldn't reset the shaft rotation count back to 0, current_position became too large, and eventually would stop the car at the read values of 16 to 100.
![]() |
| A Trial at the Beginning |
![]() |
| Final Draft of Proportionally Controlled Congo Line Code |




.png)










Great detailed work! I was wondering for the touch switch you made it go brighter when the switch was pushed or whether it was going on and off. Even though the code is using LOW/HIGH I am wondering why the LED is not turning off like it would in a bang bang control
ReplyDelete