Monday, March 30, 2015

Encoder, Touch Switch, and Ultrasonic Sensor

Most recently we've been working with three new sensors which are really useful tools in feedback & control engineering: encoders, touch switches, and ultrasonic sensors. To really understand each of these sensors my partner and I completed tasks based around each one, which I will detail below.

Encoder

The encoder counts the number of rotations of the shaft on the sciborg. This is a useful way to control how far your sciborg drives or for how long. Especially if you don't want to use other tools like Millis or delay. Because we set x to equal zero, the starting value will be zero, where x is the number of rotations. The end value should also be zero, since it goes forward and backwards the same amount. However our end value never quite reached zero. I think this is because of the time it takes for the motor to speed up and slow down; it is not instantaneous either way.

Touch Switch

The touch switch is a small switch on the front of our sciborg that senses when the sciborg hits something, as it gets pressed. We first wrote a sample code onto Arduino and connected an LED light to test the switch. We had a little trouble getting the LED to react with the touch switch at first. The first time we tried our LED lit automatically and turned off once we pressed the touch switch. Then, as expected, after we modified the code our LED started in the off position and stayed lit after pressing the touch sensor. To fix this, we added a second part to our code that said that if the button was "HIGH" or released, then the LED would be "LOW" or off.

Ultrasonic Sensor

The ultrasonic sensor senses objects in the area within a specific range. This range can be tested and viewed on the Arduino software. We first wrote a sample code for our sciborg and tested its range to get a feel for the numbers. Then we got to do some fun tasks using all three of these sensors!

Feedback and Control Activities

Earlier we tried to make our sciborg go ten feet and then stop using the Millis function. Now we'll use an encoder to do the same thing. My partner and I ran into a few problems with this task, namely we never know where to put the stop function so that our sciborg will actually stop. Also, we had the delay in the wrong place, so the encoder would only count to about 2 after going ten feet. This is what our first try looked like:
After we corrected our mistakes, our sciborg was able to easily go ten feet and then stop. At first we measured the encoder to be 10300 at ten feet, which is what is shown in the picture below. But after trying to implement it into proportional control, we went back and found the correct number to be 11200. Here is our (almost) final code:



With this code we got almost exactly to the 10 foot mark, witth the front of our sciborg being maybe an inch or two from the white line. This method was more precise than using Millis, where our closest was a few inches past the 10 foot mark.

Now we wanted to get our sciborg to stop when it hit an obstacle. To do this we used our touch switch. We wrote a code that indicated that when the switch is released the car will move at the speed specified. Then, when the sensor is pressed because of hitting the obstacle, the motors will shut off. This code worked on our first trial and we were very excited.
Slightly more challenging was using the ultrasonic sensor to stop the sciborg when it sensed it was close to an obstacle. To do this, we took note of the numbers when something got really close to the sensor, then we wrote it onto our sample code as a starting point. Slowly we were able to lower this number, which started out at 20, to 15, which got our sciborg a few inches away from the wall before stopping.

Now, our challenge was to make our sciborg run ten feet and then stop using proportional control, not bang bang. I'd like to note that the proportional part of this task only shows up at the very end of the program because we set a maximum speed value of 255. So while the output would normally be much greater than 255 for most of the run, and decreasing proportionally according to the error value, this does not show up until the very end of running our program when the output value drops below 255.
To implement proportional control, we calculated a reasonable gain factor using the fact that output=gain*error where error is your goal position minus your current position. We settled on a gain factor of 2, which stopped us about a foot and a half away from the line. This is to be expected, even with the correct goal value of 11200, because proportional control is asymptotic and at some point the output will be too low to continue. To cover the extra distance we implemented a function called "nudge" which runs the motors at a low speed for a short period of time. Originally, the regular sketch and nudge would run once and then nudge would repeat after every ten seconds, our original delay. This is because we didn't set a maximum current position in our if statement about nudge. once we did that, our nudge ran once for two seconds, and then the program stopped. We managed to get within 2 inches of our goal. We also used this function to not just run the motors for a long stretch of time until it reaches the goal, but to inch forward slowly. Here is what the code for that looks like:



This was able to get us about an inch closer to our goal, although we did find that it ran more crooked when it was inching forward.

Finally, we were asked to make our sciborg run in a "conga line" or to basically be able to follow a moving object in front of it for a short period of time. To do this, we used our ultrasonic sensor and make specifications through if and if else statements to tell it when to slow down, speed up, run at it's normal set speed, or stop. In order to do this, we measured the values of the ultrasonic sensor at different distances from a box top to get a correct range. Here is our code:
Here are videos of our sciborg running nudge without inching forward, and with inching forward.



Sunday, March 15, 2015

Continuing with Arduino

Within the past week my partner and I have completed several more tasks using Arduino, which I will detail below.

Task: Attach a photocell to your Arduino and adjust the code to get the correct readings.

My partner and I attached a photocell to our Arduino and loaded one of the example codes hat we would then manipulate. It turned out that on our first test of the photocell, the numbers given happened to correspond with the amount of light it was being exposed to. We were lucky that the readings came out so well, although they did vary some from trial to trial.

Task: Attach an LED and Servo to your Arduino and use the photocell to control them.

For this task, we originally tried to attach both the servo and the LED at once and incorporate their commands into the code we already had for the photocell. However this did not work so we worked backwards, deconstructing the different pieces until we got to a place that worked. This meant just attaching the LED and the photocell. Below is our code, a series of "if/else" statements that controlled the LED based on the photocell reading.

Next, we added on the servo. This required several iteration of our code in order to get both to work simultaneously. Below is a screen shot of our first code for LED/Servo combo:

For this, we tried directly incorporating the Servo code into what we already had with the photocell/LED code. However, the Servo still wouldn't move as a function of the photocell reading. For our second try, below, we took out the "map" command which converted values into a degree signal for the Servo. Yet again, it did not work correctly.


Finally, we decided to take the servo out of the "if/else" statements entirely and write the servo code beneath it. This way, we could have the LED/photocell code inside the "if/else" statements, which we knew worked, and try to get the servo to function separately.

 here you can see that the photocell controls the LED and the Servo separately, which ultimately worked. Below is a video of our photocell manipulating the blinking speed of the LED and the position of the Servo. The servo position may be difficult to see in the video but you can hear it move when the light reading changes.



Task: Write morse code for SOS to translate to blinking LED light

Below is a photo of the code we wrote. This task was to teach us how to use functions, such as the "dot()" and "dash()" function to simplify code writing. This allows us to define the function once and then just write in the function wherever it is needed instead of redefining it each time we want to use it. Under the "void loop" section is our code and below that are the individual dot and dash functions that we defined once. This code was successful and caused the LED built into the Arduino to blink in morse code.


Task: Set up sciborg

Moving forward with Arduino, we were challenged to assemble (partially) a sciborg to be independently controlled. Some of the things required for assembly were to solder the wires of the battery pack (which was so much fun!) and attach it onto the sciborg. We also had to screw in the Arduino and Bricktronics pack to the top and connect all the necessary cords. 
We then installed some of the Bricktronics example codes onto our Arduino software. Then, we were all set up to test various applications and functions of our sciborg.

Task: Run Single Motor test, then modify for two wheels

We then loaded the Single Motor example and tested it to make sure everything worked thus far. Then, we added a second motor, m2, which was connected to the other back wheel. We also modified our code to test several different speeds, both forwards and in reverse. We also manipulated the delay to see how it affected the motor.





 We also tried the speed at zero, and the program wouldn't upload, I assume because it does not support a zero speed command. Then we tried running the code with a speed of 1. This uploaded, but the wheels did not turn. This is because the motors did not have enough torque to run at such a slow speed. This implies that there is a minimum speed at which the sciborg will move. After a lot of guesswork and trials, we found the minimum speed to be 20. However, this was just running in the air, not on the ground. In hindsight, the maximum ground speed is probably higher.

Task: Write codes for sharp and gentle turns.

Below is a photo of our codes for both sharp and gentle turns. We did this by setting the motors m1 and m2 to opposite speeds, meaning one was negative. For the gentler turn, we reduced the speed of one wheel, which made the arc of the turn wider and the net speed of the car slower.
 Here is a video of the gentler turn:

Task: Write a code so your sciborg travels 10 ft. and then stops.

This task was actually the most difficult for me and my partner. Because we had the code running in a loop, it was difficult for us to figure out how to get the sciborg to eventually stop. We first tried using the currentMillis() function without a stop function and the sciborg just kept running. Then we tried adding the stop function, but ti was in the wrong place so the sciborg wouldn't move at all. We finally figured out the right formatting, which meant understanding that the stop function had to be placed as the "else" statement, and used a time estimate to run the sciborg. We ran into many issues when dealing with time intervals. Firstly, we did not account for the time it would take to unplug our sciborg and set it up on the start line. This accounts for the 10000 milliseconds where the sciborg is stopped before we give it an speed. Our second issue was that we greatly overestimated the time we might need to run 10 feet. This ended up being thirteen seconds. Below is our final code.
Below is a video of our sciborg running approximately 10 feet. The sciborg runs pretty straight in this video because we had already adjusted the motors to correct the crooked path of our sciborg, but originally it curved dramatically to the right.

Task: Adjust your code so that the sciborg runs straight

This is the task my partner and I completed just before the 10 feet task. Our sciborg originally curved to the right, especially at high speeds. To fix this, we increased the speed of the second motor. Originally, we increased its speed by 50 which then made it curve left. After many trials and errors we figured out that if the first motor was set at 200, the second should be at 211 for a straight run. However, we also learned that how you set the motor down affects its initial direction a lot, so often our sciborg needed some initial hand guiding to get on a straight path. We also set the default speed to be in the negative direction, which helped our sciborg move in a straight line. Below is a video of our adjusted sciborg.

Task: Attach a touch sensor to your sciborg and run the "motor button" sketch.

For this task, we had to remove some of the lego parts on the front of our sciborg and add new ones to properly attach the Lego sensor. We also used tape to keep it parallel with the floor, as it had a tendency to droop down. This would have made it difficult for the sensor to be pushed against a vertical surface. We then successfully ran the motor button sketch which stopped or started the wheels based on the state of the sensor (pressed or released).
In the loop section of the code, there are two delays. These are to give the wheels time to slow down before running the next command and to "debounce" or to double-check within a short amount of time that the command within the sketch was completed.

Task: Write a code so that your sciborg will travel forward at moderate speed, hit a wall, turn in reverse and continue on its way.

I had the most fun writing this code, because I felt that all the skills I have learned up until now were being combined into a cool and useful task. I also felt the results were the most rewarding. T write the code, we started off with our initial sketch of the sciborg traveling forward. Then, we added in the touch sensor sketch so that the speed could be controlled by the sensor. After our initial sketch of traveling forward, we wrote that while the button is pressed, there will be a delay for half a second and the the wheels will reverse, one with a greater speed than the other (the *2 in our sketch) so that the sciborg will change direction. This will happen for 2 seconds, so as to make a large enough turn, and then the direction with switch again so that the sciborg will travel forward in its new direction. Notice the +5 in the sketch. This was added to keep the sciborg driving straight throughout the process.

Below is a video showing our sciborg running the sketch:

This completes all the tasks thus far. Now my partner and I are working with encoders, touch switches, and ultrasonic sensors on the sciborg, which I will post about soon!



Lecture by Robert Wood

This past Thursday I attended a lecture by Robert Wood from the Harvard School of Engineering and Applied Sciences. Mr. Wood has developed methods of designing and creating robotic "insects" on the nano scale. While the idea of robotic insects itself is interesting, it is truly a feat of design to be able to mass produce these tiny products. Mr. Wood discussed the design process, the manufacturing process and the function and uses of his product. I'm particularly interested in product design, so I found it really fascinating to learn that his ideas for the robotic insects came from origami and his son's pop-up books. It was very cool to see these concepts translated into a self-folding "body", which simplified the manufacturing of the product lot. I was also curious about all of the different wing shapes he showed us that were tested on the body of the insect. I found it interesting that small adjustments in wing shape produced such different air patterns that really affected its ability to fly. Although he sped through the possible uses for his product such as agricultural use or national security, it was reassuring to know of practical uses for a product made on a scale that can seem trivial. Overall I enjoyed the talk and it opened me up to many new possibilities in engineering.

Monday, March 9, 2015

Arduino: Days 1 & 2

Blink
When first learning Arduino, we were tasked to try something simple like making an LED light blink for different intervals. For this, we started with the example Blink and modified the program to perform how we wanted it to. First we needed it to blink for one second on, one second off. Then we needed to change it to two seconds on, half a second off. Both of these tasks involved changing the delay time for each setting of HIGH and LOW. We also saw what it looked like with no delay (The LED stayed on HIGH). Next we needed to make a fun blinking pattern fo our light. It was helpful to see and manipulate this simple program to learn the basics of coding on Arduino. Here is our blink program.
Below is a photo of our blinking LED light:


 Blink Without Delay
Our next task was to manipulate the blinking of the LED without using delay. This way we would be able to control multiple functions at one time without pausing the entire program. For this, we decided our pattern would be for the lights to start at the off position and blink one at a time in a row. To do this we used if/else statements and && statements to tell our program how to behave. This is what our program looked like:


And here is a video of our blinking pattern:


Servo
Next, we connected a Servo to our Arduino and protoboard to see how we could manipulate that. Modifying another example program, it was easy to understand the way the coding worked for the Servo. We used intervals to specify when the Servo should turn and integers between 0 and 180 degrees to specify where it should turn to. We also played around with the delay to make it turn faster or slower.

Potentiometer
Next, we had to figure out how to control the speed of the blinking using a potentiometer. A potentiometer controls the amount of resistance let through the resistor attached to the LED light. This task was a little more difficult for my partner and me. We were able to control the brightness/dimness of the light, but not the blinking speed. On our program, we had the code directing to the Servo, which was not connected. After this had been resolved we had no trouble controlling the speed of the blinks. Often the hardest part is ensuring all the wiring is correct.
              
Above are two pictures of our setup for the potentiometer. This was the final arrangement after several trials (and errors).

On Friday we began to work with photocells and how we can manipulate LED lights and the Servo with photocell readings. A post on that and more Arduino findings to come...





Sunday, March 1, 2015

Lego Car

For this project we were required to build a vehicle out of legos that could move sustaining a 1kg weight with a single PicoCricket motor. We were then required to race our car across a 4 meter track to see whose was the fastest.

Torque vs. Speed and Gear Trains

We first experimented with the relationship between torque and speed. We knew that the two have an inverse correlation, but we wanted to see how that applied to actual Legos. To do so we made a small gear train where the driver was an 8-tooth gear. We then added on some 40-tooth gears and ended with a 16-tooth gear as our follower. You can see the varying speeds of each gear as it runs on a motor.
The Motor and First Iteration

Because the motor we were using had a large speed and a small torque, we knew that we needed to somehow increase the torque enough so that the car could move with the weight. However, we did not want to to make our car too slow so that it wouldn't win the race. Because of this we started our first model with only two gears, going from small to large in order to increase the torque. We also knew that less gears meant less friction, which is good to maintain the speed.



Second Iteration

Sadly, two gears were not nearly enough to support the weight we needed to carry, and our car was larger than it needed to be, adding unnecessary weight and slowing it down. Additionally, the front wheel did not need to be so large because it was not attached to any gear. We decided that it would be best to implement a small gear train to increase the torque. Several different arrangements of gears were tried, one pictured below:



However, the optimal gear ratio we found used only 16-tooth and 40-tooth gears.

Final Iteration
Our final gear ratio ended up being 16:40 16:40 16:40= 8:125= 1:15.625. We also made our car much smaller and narrower to increase speed and exchanged the front wheel for a smaller one. We used shorter axels running horizontally so that we we're able to push the wheels closer to the car. This way, the friction on the axels would be reduced because the weight put on it was closer to the center. This made the gears easier to turn.



Time
Between our many trials, we clocked 8.7 to 9.7 seconds for the 4 meter course. We noticed however that our car ran ever so slightly to the left when it was turned on, so to remedy this we shifted the battery over to the right side of the car hoping that would create balance. However, when we did this we noticed that our time was reduced by several seconds. So we decided finally to choose the lesser of two evils and replace the battery in the center. Our final time was officially 9.63 seconds, coming in as one of the top 3 fastest cars in the race.