Saturday, December 14, 2013
Wednesday, December 11, 2013
Putting The Boat Together + IR Code
Today, all three group members met in order to put our 2D cutouts together.
We are still waiting for our 3D parts so not everything can be put together today. Nonetheless, this was a good step of progress in finally putting our pieces together.
I also worked on code for the IR remote since we still don't know if using Bluetooth is viable. However I do think the IR remote is the best way to go. With this code (assuming it works perfect), all that needs to be added are the hexadecimal codes for each button [a quick test solves this] and the light code we already have working.
The basic premis of the code is that buttons 0-9 on the remote will represent different speeds and the left/right arrows will indicate direction. All of our other ideas can be implemented (boat path patterns, adjusting light brightness, etc.) once we get this to work properly and get it in water!
- Mike Igoe
I also worked on code for the IR remote since we still don't know if using Bluetooth is viable. However I do think the IR remote is the best way to go. With this code (assuming it works perfect), all that needs to be added are the hexadecimal codes for each button [a quick test solves this] and the light code we already have working.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Mike Igoe | |
//IR Test Code | |
//Preparing for using the IR remote | |
#include <IRremote.h> //IR | |
#include <Servo.h> // servo library | |
//Assigning IR to pin 11 | |
int RECV_PIN = 11; | |
IRrecv irrecv(RECV_PIN); | |
//Store IR results | |
decode_results results; | |
/* | |
Holding place for when we can test what each button does! | |
//These are the speed buttons (0-9) | |
long button1 = 0xFF728D; | |
long button2 = 0xFF52AD; | |
long button3 = 0xFF929D; | |
long button4 = 0xFFB24D; | |
long button5 = ; | |
long button6 = ; | |
long button7 = ; | |
long button8 = ; | |
long button9 = ; | |
long button0 = ; | |
//These are the direction buttons (left/right) | |
long buttonLeft = ; | |
long buttonRight = ; | |
*/ | |
const int motorPin = 9; //motor | |
int speed; | |
Servo servo1; // servo control object | |
int angle = 90; // initial angle that will then be changed for direction | |
void setup() | |
{ | |
Serial.begin(9600); | |
irrecv.enableIRIn(); // Start the receiver | |
pinMode(motorPin, OUTPUT); //setup motor | |
servo1.attach(9); //servo to pin 9 | |
servo1.write(angle); //Start servo at 90 degrees | |
} | |
void loop() | |
{ | |
if (irrecv.decode(&results)) | |
{ | |
if (results.value == button1) //Speed One | |
{ | |
speed = 255/9; | |
analogWrite(motorPin, speed); | |
} | |
if (results.value == button2) //Speed Two | |
{ | |
speed = 255/8; | |
analogWrite(motorPin, speed); | |
} | |
if (results.value == button3) //Speed Three | |
{ | |
speed = 255/7; | |
analogWrite(motorPin, speed); | |
} | |
if (results.value == button4) //Speed Four | |
{ | |
speed = 255/6; | |
analogWrite(motorPin, speed); | |
} | |
if (results.value == button5) //Speed Five | |
{ | |
speed = 255/5; | |
analogWrite(motorPin, speed); | |
} | |
if (results.value == button6) //Speed Six | |
{ | |
speed = 255/4; | |
analogWrite(motorPin, speed); | |
} | |
if (results.value == button7) //Speed Seven | |
{ | |
speed = 255/3; | |
analogWrite(motorPin, speed); | |
} | |
if (results.value == button8) //Speed Eight | |
{ | |
speed = 255/2; | |
analogWrite(motorPin, speed); | |
} | |
if (results.value == button9) //Speed Nine | |
{ | |
speed = 255; | |
analogWrite(motorPin, speed); | |
} | |
if (results.value == button0) //Stop | |
{ | |
speed = 0; | |
analogWrite(motorPin, speed); | |
} | |
if (results.value == buttonLeft) //Rudder left, Boat right | |
{ | |
angle = angle - 10; | |
servo1.write(angle); | |
} | |
if (results.value == buttonRight) //Rudder right, Boat left | |
{ | |
angle = angle + 10; | |
servo1.write(angle); | |
} | |
} | |
} | |
The basic premis of the code is that buttons 0-9 on the remote will represent different speeds and the left/right arrows will indicate direction. All of our other ideas can be implemented (boat path patterns, adjusting light brightness, etc.) once we get this to work properly and get it in water!
- Mike Igoe
Tuesday, December 10, 2013
Meeting to Finish Things Up
Today Bobby and I met in the computer lab in a meeting that is about finishing up the project. First, we discussed the laser cut parts we received and the various problems that were discovered with them.
For the most part, our meeting was based on what needed to be done next since there wasn't much that can be done at the moment. First what we want to do is assemble all our laser cut pieces together. We are meeting with William tomorrow morning and doing this with the Marine Epoxy mentioned in the previous post. This will keep our vessel together as well as water proof.
Next we are still waiting for our 3D printed parts that will complete our assembly and final word if Professor Sullivan is able to get the Bluetooth to work. The 3D parts should be done soon. If the Bluetooth doesn't work, we will have to revert to using IR controllers instead.
So at the moment we are still just waiting for most of the work to be done and have our code to be tested and debugged. Here is my code for the servo motor that we talked about in our meeting. Bobby mentioned how two pins could be utilized, however thinking about it, if we initialize the position to be at 90 degrees in the setup, do we really need to use two pins for 0-90 and 90-180 degrees?
All our parts thus far
All the problems can be solved with relative ease; one problem requires the piece to be filed whilst another requires being cut again to make the hole larger. Many pieces came out perfectly however so it was a large success. We also picked out the propeller from three choices, with the victor being the one with bigger blades.For the most part, our meeting was based on what needed to be done next since there wasn't much that can be done at the moment. First what we want to do is assemble all our laser cut pieces together. We are meeting with William tomorrow morning and doing this with the Marine Epoxy mentioned in the previous post. This will keep our vessel together as well as water proof.
Next we are still waiting for our 3D printed parts that will complete our assembly and final word if Professor Sullivan is able to get the Bluetooth to work. The 3D parts should be done soon. If the Bluetooth doesn't work, we will have to revert to using IR controllers instead.
So at the moment we are still just waiting for most of the work to be done and have our code to be tested and debugged. Here is my code for the servo motor that we talked about in our meeting. Bobby mentioned how two pins could be utilized, however thinking about it, if we initialize the position to be at 90 degrees in the setup, do we really need to use two pins for 0-90 and 90-180 degrees?
Monday, December 9, 2013
In regards to how to construct a model boat hull the same considerations must be processed as if you were building a full size boat. But the best solutions to how to make it are quite different due to size. This points that must be considered are shape, assembly, and sealing.
The options available for shape include making the hull out of one piece, constructing out of multiple shaped pieces, or construction out of multiple flat pieces. For the size we are working in the ultimately superior method would be to make a single piece that is exactly the size a shape we need. This bypasses the need for assembly and sealing entirely. However we could not use this method because we did not have the proper resources to make a piece to the specifications that we needed, so, since we could abundantly make flat pieces that was the method we were somewhat forced into.
Now the real challenges of boat building: assembly and sealing. Assembly is perhaps the part of construction that has the most options, and those options have many sub-options. Speaking of acrylic alone there is bolting, welding, taping, locking, and gluing. Let’s look at each of these and why I choose to use or not use each.
Bolting: the principle of bolting is to connect two pieces by putting a nail or such through them. This is perhaps the sturdiest option but was ultimately not even under considerations because since the pieces we were connecting were small and at angles with each other this would maximize the stress concentrations and would like likely break the pieces with no time to fabricate new ones. Also who wants to punch holes in the bottom of a boat? Not me.
Welding: plastic welding is a great way to connect pieces of acrylic together. A strip of plastic is placed in the interconnecting crevice and a large amount of heat is applied to melt the strip to the pieces. This forms a strong permanent bond that is smooth and easily seal-able. It is, however, relatively dangerous because of burns. But I am fairly experienced in this so that is not likely to be an issue. We were going to be using this method, but we were not able to procure a heat gun in time for construction so we had to switch.
Taping: the principle of taping is very simple; a thin strip of polymer is applied with an adhesive. This strip is then placed across the crevice attaching the pieces together. This method has numerous shortcomings however. The seal is very hard to make tight and is also prone to deterioration in a matter of days. This is great for temporarily and quickly attaching things but not for the work we are doing.
Locking: locking requires no eternal attachment to construct; the geometry of the bodies is simply designed to interconnect. This method generally makes loose connections that are still quite sturdy. However complicating geometry both makes sealing impossible and fabrication a complex endeavor.
Gluing: an adhesive is applied to the surfaces which will attach them. This method is extremely simple mechanically. There are thousands of glues available that can do anything from drying in seconds to holding literally multiple tons of weight. We chose this method because it caused the least complication with sealing and could create a very strong bond.
Sealing our hull is important because we a holding quite a lot of expensive electronics in it. The simply best way of sealing a crevice is to apply a silicone based gel that expands to fill the crack to form a water proof bond. The glue that we will be using is a marine epoxy rated for underwater use, however we will still be applying silicone because you are better safe than sorry.
package of epoxy
William Cooper
Wednesday, December 4, 2013
Coding
After a long time struggling with GitHub and the alien
terminology (forking, committing, bashing, etc.) that goes with it, I finally
found out how to put my code on there. First to tackle was the problem of
implementing the LED lights to blink without using a 2 second delay that would
disrupt all other functionality. My code focused on using iterations of the
loop function as a counter that would go up to two seconds and, upon reaching
that count, execute the light turning on/off. This is seen here:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Blinking Light/ Solid Light | |
//Mike Igoe | |
//Code to make a one light blink at a rate of 2 seconds whilst another remains on. | |
//Pins | |
int redLED = 1; | |
int yellowLED = 2; | |
//Counter to act as the delay | |
int counter = 0; | |
void setup() | |
{ | |
pinMode(redLED, OUTPUT); | |
pinMode(yellowLED, OUTPUT); | |
} | |
void loop() | |
{ | |
//Red LED stays on. | |
digitalWrite(redLED, HIGH); | |
//increment counter to add time | |
//this assumes a loop is 1 millisecond - testing the program can change this | |
counter++; | |
//by the above assumption, this means two seconds passes by | |
if(counter>2000) | |
{ | |
//turn on yellow | |
digitalWrite(yellowLED, HIGH); | |
if(counter > 4000) | |
{ | |
//turn off yellow | |
digitalWrite(yellowLED, LOW); | |
//start over by making counter 0 | |
counter=0; | |
} | |
} | |
} | |
} |
The issue with this was that you needed to know just how
long it takes for a loop function to execute – I estimated on the low side and
figured I could raise the counter limit until it equated to 2 seconds. Bobby
figured out a way that would both avoid multiple tests as well as the loops:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Two Light, Single Blink Boat Code | |
//Robert Fisher | |
//Design Lab 1 Fall 2013 | |
// This code produces a blinking light with out having a delay that would interupt | |
// other functions and processes. Simple and easy. | |
int ledPin = 9; // Red LED pin | |
int ledYel = 10; // Yello LED pin | |
int i = 0; // Variable to contain time stamp 1; begin at 0 | |
int i2 = 0; // Variable to contain time stamp 2; begin at 0 | |
int j = 0; // Variable to count change; begin at 0 | |
void setup() | |
{ | |
pinMode(ledPin, OUTPUT);// Red LED is OUTPUT | |
pinMode(ledYel, OUTPUT);// Yellow LED is OUTPUt | |
Serial.begin(9600); // Begin Serial Com | |
} | |
void loop() | |
{ | |
digitalWrite(ledPin, HIGH); // Red LED remains on constantly | |
i = (millis())/2000; // Set time stamp 1 | |
delay(50); // delay between Timestamps to be tested | |
i2 = (millis())/2000; // Set time stamp 2 | |
if (i != i2) // if time stamps do not match: | |
{ | |
j++; // increment j by one | |
} | |
if (j == 0) // while j is 0, true: | |
{ | |
digitalWrite(ledYel, LOW); // Yellow LED is off | |
Serial.println("Light is off, and current run time is:"); // Serial print light is off | |
Serial.println((millis())/1000); | |
Serial.println("sec"); | |
} | |
if (j == 1) | |
{ | |
digitalWrite(ledYel, HIGH); // Yellow LED is on | |
Serial.println("Light is on, and current run time is:");// Serial print light is on | |
Serial.println((millis())/1000); | |
Serial.println("sec"); | |
} | |
if (j > 1) // if j is larger than 1: | |
{ | |
j = 0; // set j back to 0 | |
} | |
} |
I also worked on coding the servo motor and ac motor so that
their movements would respond to a potentiometer. This was a test that prepare
us for integrating the motors with the iPhone interface – since the adjustment
of the potentiometer is similar to that of the app. Each is shown below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Mike Igoe | |
//Using a potentiometer to control AC motor speed | |
//Pins | |
int sensorPin = 0; | |
int motorPin = 9; | |
void setup() | |
{ | |
pinMode(motorPin, OUTPUT); | |
} | |
void loop() | |
{ | |
int sensorValue = analogRead(sensorPin); | |
//to convert the potentiometer to the ac motor, i make a relation to | |
//the max motor speed (255) and max potentiometer reading (1023) | |
//so, poten/4.01176470588 = max ----since we deal with integers I'll simplify it to 4 | |
int speed = sensorValue/4; | |
analogWrite(motorPin, speed); | |
} | |
// |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Mike Igoe | |
//controlling servo motor with potentiometer | |
#include <Servo.h> | |
Servo serv1; | |
int sensorPin = 0; | |
void setup() | |
{ | |
//attach servo to digital pin 9 | |
servo.attach(9); | |
} | |
void loop() | |
{ | |
int sensorValue = analogRead(sensorPin); | |
//As with the AC motor, the sensorvalue must be converted into terms relating to the servo | |
//Max angle = 180, max potentiometer reading = 1023 | |
//so, poten / 5.68333 = angle --- by reducing the number to 5, we are in fact reducing | |
//the maximum possible angle that can be rotated; for this demonstration this should be negligble. | |
int position = sensorValue/5; | |
servo.write(position); | |
} | |
/* Note, with the iPhone app grid setup, this wouldn't work since it only moves in one direction. | |
To fix this, I'm wondering if negative values can go into "servo.write" to reverse the servo direction. | |
If so, I can change the formula converting potentiometer to servo where a reading 511.5 is zero degrees and readings of 0 and 1023 are -180 and 180 degrees, respectfully. | |
*/ |
Bobby then put the blinking light code together with the
servo code so it was all in one. All that would be needed now is to add the
motor in this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Servo.h> | |
//Two Light, Single Blink Boat Code | |
//Robert Fisher | |
//Design Lab 1 Fall 2013 | |
// This code produces a blinking light with out having a delay that would interupt | |
// other functions and processes. Simple and easy. | |
int ledPin = 8; // Red LED pin | |
int ledYel = 7; // Yello LED pin | |
int i = 0; // Variable to contain time stamp 1; begin at 0 | |
int i2 = 0; // Variable to contain time stamp 2; begin at 0 | |
int j = 0; // Variable to count change; begin at 0 | |
Servo myservo; // create servo object to control a servo | |
int potpin = 0; // analog pin used to connect the potentiometer | |
int val; // variable to read the value from the analog pin | |
void setup() | |
{ | |
myservo.attach(9); // attaches the servo on pin 9 to the servo object | |
pinMode(ledPin, OUTPUT);// Red LED is OUTPUT | |
pinMode(ledYel, OUTPUT);// Yellow LED is OUTPUt | |
Serial.begin(9600); // Begin Serial Com | |
} | |
void loop() | |
{ | |
digitalWrite(ledPin, HIGH); // Red LED remains on constantly | |
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023) | |
val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180) | |
myservo.write(val); // sets the servo position according to the scaled value | |
i = (millis())/2000; // Set time stamp 1 | |
delay(50); // delay between Timestamps to be tested | |
i2 = (millis())/2000; // Set time stamp 2 | |
if (i != i2) // if time stamps do not match: | |
{ | |
j++; // increment j by one | |
} | |
if (j == 0) // while j is 0, true: | |
{ | |
digitalWrite(ledYel, LOW); // Yellow LED is off | |
//Serial.println("Light is off, and current run time is:"); // Serial print light is off | |
//Serial.println((millis())/1000); | |
//Serial.println("sec"); | |
if ((analogRead(potpin))/5 < 90) | |
{ | |
Serial.println("Left Turn Initiated"); | |
} | |
} | |
if (j == 1) | |
{ | |
digitalWrite(ledYel, HIGH); // Yellow LED is on | |
//Serial.println("Light is on, and current run time is:");// Serial print light is on | |
//Serial.println((millis())/1000); | |
//Serial.println("sec"); | |
if ((analogRead(potpin))/5 > 90) | |
{ | |
Serial.println("Right Turn Initiated"); | |
} | |
} | |
if (j > 1) // if j is larger than 1: | |
{ | |
j = 0; // set j back to 0 | |
} | |
} |
Finally Bobby introduced a unique idea to use the light
sensor for the LED in place of the potentiometer – that way, the screen would
adjust itself according to the amount of light around it:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Robert Fisher | |
//Design Lab 1 Boat Project | |
//LCD Screen with Light Sensor | |
//You may have to replace this library call. To do that | |
//go to sketch>>import library>>Liquid Crystal. The | |
//"#include seen below will be placed at the top of your sketch. | |
//Erase the one below and the sketch should be okay to be loaded. | |
#include <LiquidCrystal.h> | |
const int contrastSensor = 0; // Light Sensor pin | |
const int contrastPin = 6; // PWM Output to LCD screen [j28] | |
//see SIK Guide>>circuit 15, page 78 in the component section | |
int contrast, high = 0, low = 1023; // set int contrast to read | |
// multiple levels | |
LiquidCrystal lcd(12,11,5,4,3,2); // Pins for LCD | |
void setup() | |
{ | |
lcd.begin(16, 2); // Sets LCD rows and columns | |
lcd.clear(); | |
lcd.print("hello, world!"); // This will eventually be | |
//turning status. | |
Serial.begin(9600);// so we can see it on th ecomputer as well. | |
} | |
void loop() | |
{ | |
contrast = analogRead(contrastSensor); // read sensor | |
if (contrast < low)// Compound reading | |
{ | |
low = contrast; | |
} | |
if (contrast > high) | |
{ | |
high = contrast; | |
} | |
contrast = map(contrast, low+100, high-100, 0, 250); | |
//Maps values of sensor and also makes the ranges smaller. | |
//I did this because the sensor is not like the potentiometer. | |
contrast = constrain(contrast, 100, 150); | |
//Constrains the values between 100 and 150 | |
analogWrite(contrastPin, contrast); // sets LCD contrast. | |
Serial.println(contrast); // just to print the output for testing | |
lcd.setCursor(0,1);//set cursor position, column 0 and bottom row | |
lcd.print(millis()/1000); // print second count | |
lcd.setCursor(13,1); // sets cursor position to 13th column | |
// and the bottom row. | |
lcd.print(contrast); // print contrast reading at set position. | |
} |
With this code we still have the trouble of connecting it to
the iPhone app, however. More work will need to be done before any of this can
be tested and debugged, but so far it looks good.
- Mike
- Mike
-
Subscribe to:
Posts (Atom)