Sunday, March 15, 2015

Arduino Day 3 & 4

Day 2

When I walked in class on Tuesday, I was certainly impressed by the Sciborgs in our classroom. I was, again, very excited, to transform the codes what we have learned from last week into something more visible and practical.

Before we started with Sciborg, we learned another language for coding more concisely, which is function. Function stores a certain set of commands in a function and thus shortens the code when the set of commands needs to be repeated in loop. Here is the code for making SOS signal from LED's.

In this case, we avoided writing "dot()" and "dash()" repeatedly in void loop().

Before we started programming for Sciborg, we had to learn how to solder. Soldering is essentially connecting wires with an alloy wire containing mostly lead, which has a low melting point. We soldered the two wires from the battery box to a plug for the Arduino shield. One of the wires was covered by a plastic tube that shrinks from the heat. (The material expand axially so that it shrinks radially.) This is to prevent that two unseparated wires would cause a short in the circuit. The screws in the battery box were also taped to prevent shorts.

The first program we ran in Arduino was a single motor code. This allows one motor of the Sciborg to start working. Since the Sciborg has two wheels powered by two motors, we then modified the code to allow both motors to work at the same time.
Double motor, same speed
We did a test on the motor to see the minimum speed it requires to get the Sciborg moving. The results vary, but overall the Sciborg would start moving when the speed is above 50. The next step was to make the Sciborg turn. This is not hard to implement. The Sciborg would turn if the two wheels are moving at different speeds, because this implies that the wheels will travel for a different amount of distance in the same time period (d=v*t). We made the left wheel move at speed 255 and the right move at speed -255. In general, the smaller the difference between the speeds of the two wheels is, the gentler the turn.

At this point, it was clear that the Sciborg does not drive straight. I suspect that there are multiple reasons. First is that the free wheel is not completely frictionless. As a result, a slightly different positioning of the front wheel will cause the Sciborg to deviate from the original route. The center of weight of the lego structure is also not aligned at the center of the structure, causing the car not to move straight. I suspect that the motor may also differ slightly. The best we could do was to adjust the speed to 235 in the left wheel and 255 in the right wheel. We also made the motored wheels the back wheels. However, the Sciborg still shifts variously each time we let it run.

Anyhow, since the Sciborg does not move in a certain direction consistently, it was rather hard to estimate a time for which the Sciborg would stop after 10 ft. We made the time at around 10 seconds, and the Sciborg would stop near the finish line within +/- .5 ft.

The next step is to use a touch sensor. We have a touch sensor at the end of the motored wheels. As a result, the motored wheels must be in the front. In the program for touch sensor, there are two delays. This is to allow the program to debounce. Normally, the metal in the sensor may send multiple signals if there is a slight change. However, having the delay allows the program to debounce, which receives and processes the very first signal as opposed to all sequential signals. Here is our code which makes the Sciborg back off and turn and then continue when the touch sensor is activated.



Note that we have been through some modifications. We wanted the Sciborg to only turn slightly, so we initially used speed1*=-1.5 and speed2*=-1 as our turning speed. It turned out that as the loop goes through over and over, the speeds would multiply itself and thus the Sciborg did not act consistently. It turned out that the "=" updates the speed to the new result, which is something we were not aware of. We thus changed the modification to -1 and 1 but make the delay time shorter, so that the Sciborg would not turn as much. Here is the result.


Day 4

Today we started with Encoders. The encoder is a sensor in the motor that records how many times the shaft has rotated. Here is the code.
This basically makes the car go forward for 200 counts and backward for 400 counts, and records the turn of shaft at the same time. Note that we only used one motor in this case, which means that only one wheel was motored. The recording starts at 0, because the shaft does not turn. If physics worked perfectly, the recording should also end at 0. However, this was not true in our case. I suspect that the Sciborg starts in a still state, but when the Sciborg changes the direction it moves, it starts in a moving state. As a result, the momentum and speed would be different, causing the distance traveled to be different. The friction and other elements that control how much and how easily the Sciborg moves may also differ when the motored wheels change from the back wheels to the front wheels.

The second project requires us to use the sensor at the end of the free wheel. The sensor controls the LED light attached to the Arduino. We wrote a code so that the LED would turn on when the sensor is pressed down and would be off otherwise.
If the else statement was deleted, the LED would stay on forever after the sensor is pressed. This is because there is no command that tells the LED to turn off.

Now the last project we worked with was the Ultrasonic sensor. Here is the code.
Note that here, the sensor detects the object every half second. The closer the object is, the smaller the Analog reading is.



Monday, March 9, 2015

Arduino Day 1 & 2

It sounds like I talk about this at the beginning of each blog, but I must say that this is another super exciting projects for me! I'm really enjoying this class and wish that I had access to these opportunities earlier in my life.

Day 1


Anyhow, we are now learning Arduino, which would help us understand the control and response process. It also exposes us to computer programming.

Our very first task was to understand the program that makes the LED light blink. We connected out Arduino Uno to the computer, and the LED light on the board that is connected to port 13 started blinking on an 1-second interval. To further our understanding, we deleted the delay in the code, later finding out that to human eyes, the LED would look like it remains on the whole time, even though it was in fact blinking at an extremely high speed that is undetectable.We also altered delay into a few different values, to see how the timing changes.
Code for Blink
Here, int led = 13 refers to the port that the information is uploaded to. The HIGH and LOW represents the voltage at the port, with HIGH representing on and LOW representing off. The void loop function allows the program to run over and over again. The Arduino program runs in milli-seconds. Thus a delay of 1000 milli-seconds is in fact only 1 second.

As we understood the use of delay and the general idea of setting up Arduino programs, my partner, Meredith, and I started working on a program that controls four LED's with delay. Here is our COOL pattern. The second part looks like a little bug made of two lights is running through the row of LED's!
While the pattern looks cool, the program is actually nothing more than an elaboration of the blink program with changes in delays and ports for outputs. We used port 12, 8, 7, and 4. Here is the code for the second part of the pattern, i.e. the part where only two lights are on at the same time.

  void setup () {
    pinMode(12, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(4, OUTPUT);
  }

  void loop () {
    digitalWrite(12, HIGH);
    delay(500);
    digitalWrite(8, HIGH);
    delay(500);
    digitalWrite(7, HIGH);
    digitalWrite(12, LOW);
    delay(500);
    digitalWrite(4, HIGH);
    digitalWrite(8, LOW);
    delay(500);
    digitalWrite(7, LOW);
    delay(500);
    digitalWrite(4, LOW);
    delay(500);
  }

After understanding the delay function, we then moved onto a different way to achieve blinking without delay but with interval. It is necessary to do so, because sometimes the program must command other parts connected to Arduino, but having delay in the code will delay/affect other commands made to other parts.

The interval function is much harder to understand, since it incorporates variables that the computer would compute, as opposed to constants that we just plug in like in delay. It basically allows the program to check the status of the lights after each interval, and update the status of parts connected and other variables based on the code.

Blink without Delay


We wanted to do a similar pattern we did before, which required different patterns. However, we could not find a way to make the pattern go back to the loop. We tried
      if(currentMillis > 3000)
        currentMillis = 0
and
      if(currentMillis = 3000)
        currentMillis = 0
However, it turned out that the first one makes each milli-second after 3000 become the 0th milli-second, and the latter one makes only the 3000th milli-second become the 0th milli-second. Neither code resets the timer. We may be using the wrong code to say what we want.

We ended up with only one pattern, alternating the lights on and off.
We would like to go back and revisit our code to see if there is a better way to return the loop back to the beginning and have multiple patterns loop.

Day 2

As I said before, the main point of studying Arduino is to understand response and control. In the previous class we were able to control the LED's, but we did not get to the response stage. In our second day with Arduino, we worked with the servo motor, the potentiometer and the photocell.

We first started with the servo motor. This is much more precise than PicoCricket, which we used for our Lego racer. We can control the servo by commanding it to move to certain positions. We may make it stop or move continuously. The example "Sweep" familiarizes us with controlling the motor. We changed the position and the rate at which the motor moves to understand the language better.
Modified "Sweep"
Note that the program does not automatically run servo, so we must specify at the beginning. We also learnt the "for" statement here. Another thing I noticed was that I wanted to see if the servo would turn clock-wise for 90 degrees and counter clock-wise for 180 degrees and repeat the process. It turned out that if I simply change the number, the servo would only turn quickly to the position written as the start.

The servo is in fact used to demonstrate as an output. We then started attaching the potentiometer on the proto-board and the potentiometer would be our first instrument to receive signals and ask the servo to respond. The first example was "Knob". The program uses the "map()" function to correspond the potentiometer's setting with the position of the servo. We then combined this with the flashing LED, which also became part of the response.

In general, when the potentiometer has a lower value, the interval where the LED blink becomes smaller and thus the LED blinks faster. The coding for this program is quite straight-forward, and combines with other languages we learned in previous examples.

The second input control device we used was the Photocell. It detects the brightness of light and the Arduino program and read it and also produce a result as commanded by the program. Here, to detect the data, we used the following code.
Note that in this case, the photocell would check the brightness every second.

To use the reading to control the servo and the LED, we used similar functions as we did in "Blink" and "Knob". Here is the code.
When we were running the initial program to look at the reading, we noticed that the highest value we got by shining a phone flashlight to the photocell was in the 900's. We thus set the value of the photocell as 0-1000. We also used a "for()" statement here to let the LED light blinks three times before the next time the photocell detects again. The LED blinks faster when the light is brighter and slower when the light it dimmer.

Sunday, March 1, 2015

Lego Racer

Compared to the previous assignments, I must admit that this lego racer project is completely unfamiliar to me. Growing up in a community with deeply rooted gender roles, a girl could either play with Barbie dolls or read many books and study very hard. I chose the latter and I never thought that one day I would play with lego, something that only boys are supposed to play with. This experience overall was very empowering and exciting for me, since I absolutely enjoyed being able to control and construct everything with my own hands.

Brainstorm

To be honest, we completely forgot about the basic brainstorming process as we did for previous projects. For previous projects, I had in mind a general shape of the products we were about to make. However, for a lego car, it was first hard to draw sketches by hand, since it has so many layers to it inside and outside of the car. Second, we had so many small pieces in our hands that I definitely felt overwhelmed and did not know where to start. I would love to read others' posts to see how they visually organized their thoughts!

Obviously, we eventually started and finished the project. Now that I think back through the thinking process, here are some main points that we considered before we started building the racer. Please keep in mind that our ideas have changed as we started building and testing the racer.
  1. We wanted to power the back wheels of the car as opposed to the front wheels, as many cars are designed this way.
  2. We wanted to use as few gears as possible, since more gears = more friction.
  3. We somehow thought that we should put the weight closer to the back wheels.
  4. We wanted to use bigger wheels in the back, because with the same angular velocity, the bigger wheels will have larger linear velocity.
  5. However, we only wanted one wheel in the front to minimize friction and weight.
  6. Last but not least, the motor has high speed but very low torque, so the gear reduction must be large (or the gear ratio must be small)** enough to provide enough torque to move the car, but not too high that the car moves too slowly.
** gear reduction = # of teeth of the driven gear : # of teeth of the driving gear
gear ratio = # of teeth of the driving gear : # of teeth of the driven gear

Building the Racer

Our first try was to build a structure with a working gear train. Since we wanted the weight to be as close to the back wheels as possible, the motor was put in the front. We did not worry much about the gear ratio in this iteration, because we wanted to find out the best way to connect the motor to the back wheels. It turned out that an 8-tooth gear and a 36-tooth gear can transfer the movement from above the beam where the motor sits to the beam level where the wheels are secured with an axle.
First iteration
This structure does not have a big gear reduction (36:8*16:36*36:16*40:36=5:1) and has gears that cancel each other out. This certainly creates unnecessary friction. We then decided that we will shorten the gear train. As a trade-off, the motor had to be closer to the back and the weight has to go to the front. Here is our second iteration.
Second iteration
In this iteration, the motor had some pieces at the bottom as support, but the gear box in the back was completely exposed. We put a platform in the from of the car for the weight. We did not want out car to be extremely long, because it seemed awkward and would bend rather easily with weight. As a result, we decided to put the battery on top of our motor, and we used a smaller wheel in the front, since the front wheel only serves as a support in the front to convert sliding friction to rolling friction. The gear ratio of this model is not much different from the first iteration: 16:40*24:40=1:4.17. Testing showed that it was clearly not enough to create a torque large enough to move the racer with an 1kg weight on it. As a result, out next step is to build a gear box with a larger torque.

At this point, what definitely worked was the gears used to transfer the movement from above the beam to the beam level, so we conserved that part in our next iteration. However, we were not very satisfied with the way that the battery was placed, since it was unstable, and the exposed gear box seems to be a waste of length in the car. As a result, we made some adjustments to the racer.

First of all, in terms of structure and layout, we built walls on the beams supporting the gears, so that there would be a platform for the weight. Now that the front part of the racer was empty, we moved the battery to the front, since it was much lighter than the weight and would be more secure staying at a lower position with more pegs from the lego pieces holding it to the car.
Following iterations took on a similar layout with varying gear boxes and dimensions.
As for the gear box, we decided to start with a very high gear reduction. We started with 40:16*40:8*40:8=62.5:1. It turned out to work but moved very slowing, taking 24.84 seconds to finish the 4m course. We then took out one pair of the 40:8 gear, making the new ration 12.5:1. It worked, but took 18.46 seconds, making it still much slower than the reference time (9s) we heard in class. (It's interesting to note that eventually we learned that 15:1 seems to be the best gear reduction, and reduction lower than that seemed not to work. However, with a 12.5:1 reduction, this racer moved, though strenuously.) The third try was 40:16*24:8=7.5:1, which did not work with weight on it either. At this point, we were fairly sure that the right ratio is in the interval between 10 and 20, so we decided to first calculate on paper the possible gear reduction we could get with gears available.
Gear reduction calculation with different gear combinations
With the given ratio calculation, I did a few more test runs, and finally settled down with a 40:16*40:16*40:16=15.63 gear reduction.

Testings and Changes on Structures

As we were trying to figure out the right gear reduction, we also tweaked a few things on the structure to figure out how each element would affect the speed of the racer. We consider that the impact is significant if it changes the time by at least 0.5 second.

Here are our findings:
  1. Switching the front wheel from a big wheel to a small wheel does not make a huge difference on speed. However, we do prefer a smaller wheel to shorten the racer.
  2. Having the motored wheels being in the front or back does not make a huge difference in our case (difference was less than half a second), but we still chose to motor the back wheels since it does make a small difference.
  3. Having the wheels closer to each other makes the car move faster, because a large inter-wheel distance causes bending on the supporting axle, creating more friction. As a result, our racer changed from 7FLU wide to 5FLU wide.
  4. We were concerned that the weight may fall off when the car moves, but it turned out (after a few tests) that there is enough static friction between the lego and the weight to keep it still with respect to the racer when the racer accelerates. We then did not put protecting lego pieces around the platform to support the weight, so that we would not need a bigger supporting piece or more pieces as protection and can thus reduce the weight of our racer. (Even though the weight does not have an impact on the speed significant enough in our case, we still preferred a more simplistic design.)
  5. Bushings are SUPER important! I have a new understanding of the importance of bushing compared to the windlass assignment, since my ex-partner and I used none on our windlass. The appropriate bushing should use the least amount possible to secure axles in place, so that gears will work as they should when the racer moves, but not so many bushings that they would create unnecessary friction when axles spin.

Final Product and Engineering Analysis


Note that the racers are slightly different in color, but they have the same design and structure.

The fundamental physics of this project is simple. With the same power, the bigger the torque, the slower the speed. Our goal is to have just enough torque to carry the racer and an 1kg weight, so that our speed will be maximized. The greater the gear reduction, the greater the torque. Note that the actual gear reduction should also count the size of the motored wheels, since they work as gears as well. A few factors that will affect the efficiency of the structure includes friction and weight. This means that we want to use as little material as possible, and be mindful of anything that rubs against each other.

Our final racer has a gear reduction of 15.63 (40:16*40:16*40:16). The motor connects to a 16-tooth gear, which directly meshes with a 40-tooth gear. The 40-tooth gear shares the same axle as another 16-tooth gear, which meshes with another 40-tooth gear. The second 40-tooth gear shares the same axle as the third 16-tooth gear, which meshes with the third 40-tooth gear. This final 40-tooth gear shares the same axle with and thus motorizes the two back wheels.

In terms of material, our racer's body has the width of 5FLU and the length of 16FLU. The back, motorized wheels are the largest in size, and the front wheel is smaller and positioned under the battery, to reduce length and weight of the racer (does not change much on friction, since it has about the same width and patter as the bigger wheels). During the test runs before the class race, the racer finishes the 4m course at around 9 seconds on average. In class, it finished in 9.63 seconds. We suspect that a light change in the battery position shifted the center of weight and caused the racer to run side way as opposed to straight, extending the time needed to finish the course. There is also probably some variation with the person calculating the time and the reaction time of the person starting the racer.

While our racer was not the fastest in class, I am certain that it is undoubtedly the smallest and uses the least amount of lego pieces. (Simplicity is something I appreciate! This means it is easy to reconstruct and requires less material.) It finished close to the fastest racers and has the gear reduction close to the optimal reduction ratio. The gear arrangement was simple and straight forward to understand, and the gear box can be easily altered.

However, it was not perfect! I would definitely love to have had more time to figure out the balance of weight to make sure that the racer runs straight. I also noticed that because we wanted to make the racer as narrow as possible, the gears inside the racer's body had to turn against each other and the walls supporting them. This probably created friction and slowed down the racer as well. I should have found a good tradeoff between wheels close together but less friction between gears.

Final Reflection

This was not only a great process for me to learn how to work with lego, but also a great chance to learn about myself, how I think, and how I work. I have noticed that I (and probably many other people) have hands that work slower than my brain. As a result, when I start brainstorming, things spin quickly in my brain and sometimes become jammed together. Alternatively, having a more hardworking hand to write down ideas can be a great way to organize my thoughts, so that I do not miss all the ideas that my brain generate.

I also realized that I should always remember to ask for help. I stayed in the lab for 8 hours straight one day and actually spent most of my time trying to figure out a problem that I could not solve. My motor would not work consistently, causing the gears fail to spin and function. I spent a lot of time testing individual parts of the design to make sure that nothing in the connection was wrong. I also tried designs that worked before. I could not find the problem and eventually decided to email Professor Banzaert. It turned out that it was because our motor did not have enough support, so the inside of the motor did not line up well to function properly. While it was a good practice to examine each part separately and not to give up, I could have asked for help earlier. I spent a lot of time turning the motor on and off and felling after I made sure that all connections worked fine. Next time, after I try everything I can, I will make sure to remember all the resource around me. After all, there is no shame to step on the giant's shoulder!

Last but not least, here is a video of our racer running.