Sunday, May 9, 2010

iPad for School?

What I need



As you may or may not know of me, I am finishing up my junior year in high school and will soon be moving into my senior year and then college. For my career path, which will be Electronics Engineering or Computer Science, computing will be essential. I will have to make a decision in the very near future regarding purchasing a computer that will likely have to last throughout my high school and college career (5 years) and allow me to take notes, write papers, and give presentations. I'm posting some of my ideas in order to hopefully illicit discussion regarding my choices, and maybe gain some further ideas into my situation. If you have any ideas for me or anything that I missed, please comment or tweet me @kersny.



What I've got



Right now, I am running on a Dell Inspiron 600m laptop with a broken and removed screen on either a 17" or 23" monitor. This has a 1.6Ghz processor, 512mb of RAM, and a 60gb hard drive... so yeah, its pretty weak. Seriously though, I dual boot XP and Ubuntu 10.04 and it manages to handle many tasks well, such as Visual Studio 2010 Express, but it has its problems and slows considerably for other common tasks or any sort of multitasking.



Options



1. MacBook



Purchasing a MacBook was my first thought when I considered buying a computer. I have always wanted one, and they offer many advantages. I'm sure that a MacBook would be plenty durable to last 5+ years, and I know that I could run OSX, Windows 7, and Linux to handle anything required of me in college The 8-10 hour battery life would also be great for note-taking and college classes. The only problems I see with this options are price and power. Obviously, a Macbook is not cheap and would require a considerable chunk of change. The other downside, power, is not so concrete. I was quite disappointed in the latest refresh of the MacBook line by Apple, and although I have read many of the reasons and justifications for doing so (one such), I don't really want to buy a $1200 laptop with a Core 2 Duo chip to last my entire college career. I just think that this would be too underpowered for the things that I could be doing throughout college. The next step up, a 15", is too expensive now but would have the lowest specs that I would probably consider purchasing.



tl;dr: I'd love to get a Macbook, but the power of the 13" model and the price of the 15" model are whats holding me back.



2. Regular Laptop



It's hard for me to look at the MacBook and not see the huge "Mac Tax" imposed on such an item. I could buy an i7 laptop with 4 Gigs of RAM from any number of PC companies for much less than even the low end MacBook. I know that this should be plenty powerful to handle most anything I would throw at it throughout my college years, but it has its own set of cons. The first of such would be durability, which is important for something that has to last 5 years. I've seen many a laptop fail hardware or case wise, and that could be a huge problem for a college kid. Another smaller concern is the fact that it is not a Mac, meaning that I could not develop apps for the iPhone or iPad.



tl;dr: A Windows Laptop would be plenty powerful but I'm scared about durability and I couldn't do iPhone development.



3. The iPad/Mac Mini power combo



This is an interesting option that I have been looking into over the last couple of weeks. For much less than the price that I would have to spend on a sufficiently powerful MacBook, I could get both an iPad and a Mac Mini. I would buy an iPad now, and use it through my senior year and onto college. I could write papers (with an external keyboard of course), give presentations, and do all the research required of me in my senior year. Add to this the ease of note taking and portability in college, and it could make a great platform. I would, however, have to buy a complementary Mac Mini in order to support coding and other programs that won't run on an iPad. This could be pushed into college, after a refresh or two, and give me a powerful box to anything not supported on an iPad. The only problems in this situation would be the known issues with content creation on the iPad and any labs or such in college that would require real programs to be run in the classroom, such as maybe an IDE or Compiler. I do believe, however, that a college cannot force you to have a computer if that don't provide you with one, and will likely have them available in any such lab situations.



tl;dr: An iPad + Mac Mini combo should let me do everything I need throughout high school and college, unless I am required to run special programs during class.



So that is my situation and those are the options that I am currently considering. If you have any experience, advice, opinion, or idea, please let me know.

Friday, January 1, 2010

iTunes & Music code Redux

It has been brought to my attention on my first iTunes COM API post that some of my information in that post is currently invalid:
  1. Lyrics: LyricWiki decided to cut off their API because of copywright concerns, so that function will no longer work. Link
  2. Album Art: Amazon has implemented authentication in their album art API, if you would still like to use this service, I recommend this post


Wednesday, August 26, 2009

My Segway Works!

Its not 100% yet, but I got my Segway ride-able. Here are some videos:

Riding my Segway! from Kerry Snyder on Vimeo.


Riding My Segway - With Steering from Kerry Snyder on Vimeo.



I should be able to post more details and code soon.

Saturday, August 8, 2009

Segway Video and TI Pong

Yes, its been over a month, but I have made quite a it of progress on my Segway, and, without further adieu:
Item #1:

Initial Segway Test from Kerry Snyder on Vimeo.


It balances itself! Now all I need to do is adjust the PID constants. And put in a big red E-Stop switch.


Item #2: TI calculator Pong

I made this while I was bored in math class last year, all by myself, programmed in a BASIC-like language on our school's graphing calculators, which I believe are TI-83+'s.

Here is the calculator manual, with programming information: Chapter 16

And here is the code:

Lbl F
ClrHome
Menu("PLAY PONG","PLAY",Z,"HIGH SCORE",K,"QUIT",S)
Pause
Lbl Z
1»B
0»G
1»O
1»P
0»J
Lbl U
getKey»A
If A=34
Then
B+1»B
Then
8»B
End
ClrHome
Output(B,1,"[")
End
If A=25
Then
B-1»B
If B<1
Then
1»B
End ClrHome
Output(B,1,"[")
End
If G=0
Then
randInt(3,6)»X
randInt(6,10)»Y
Output(X,Y,"+")
G+1»G
Else
Output(X,Y,"+")
If P=1
Then
X+1»X
Else
X-1»X
End
If O=1
Then
Y+1»Y
Else
Y-1»Y
End
If X>8
Then
8»X
0»P
End
If X,1
Then
1»X
1»P
End
If Y>16
Then
16»Y
0»O
End
If Y<2
Then
If X=B or B-1=X or B+1=X
Then
2»Y
1»O
J+1=J
Else
ClrHome
Disp "GAME OVER"
Pause
Output(5,4,"SCORE:")
Output(5,11,J)
Pause
If J>E
Then
J»E
ClrHome
Output(5,2,"NEW HIGH SCORE")
Pause
End
Pause
Menu("GAME OVER","PLAY AGAIN",H,"QUIT",S)
End
End
ClrHome
Output(B,1,"[")
Output(X,Y,"+")
End
Goto U
Lbl H
1»B
0»G
1»O
1»P
0»J
Goto F
Lbl S
0»J
ClrHome
Stop
Lbl K
Output(5,2,"HIGH SCORE:")
Output(5,14,E)
Pause
Goto F




Saturday, June 27, 2009

iTunes COM API C#: Playlists

After a comment on my original iTunes COM API post inquiring about Playlists, I decided to revisit that part of the project. I had originally intended to include this in the first post, but it was more difficult than I had first though. Here are some code snippets to get you started:

1. Create a ComboBox listing the names of all the playlists:

foreach (IITPlaylist pl in app.LibrarySource.Playlists)
            {
                comboBox1.Items.Add(pl.Name);
            }
Notes:
Retrieves all playlists in iTunes

2. Playing One:
private void button1_Click(object sender, EventArgs e)
        {
            IITPlaylist pl = app.LibrarySource.Playlists[comboBox1.SelectedIndex + 1];
            pl.PlayFirstTrack();
        }
Notes:
Could also be done on ComboBox1.SelectedIndexChanged()
+1 Accounts for differences in indexes


This is just some basic examples, for tons more information, check out this link. You have to login in with your iTunes account, but look for "iTunes COM for Windows SDK (ZIP)" If you have trouble locating this file, email me and I can get it to you. It includes iTunesCOM.chm, which is the de-facto resource for all of this information. Between my example code (Here and here), you should be able to preform many of the iTunes functions. As always, comment if you have any troubles.


Tuesday, June 16, 2009

Getting an Angle

So probably the biggest part of constructing a balancing robot, or scooter, is knowing what angle it is in relation to the ground. From this, you can determine how much you need to compensate. The balancing system in my Segway consists of two sensors:

ADXRS614 Gyro 50 °/s

ADXL203CE Accelerometer +/- 1.5g

As I have explained in a previous post, both of these sensors are required to determine an accurate angle measurement. In my code so far, these are combined using a Complementary Filter. A great resource for coding a complementary filter on the Arduino can be found here. The hardest part that I found using this code is the Coefficients, which are not explained. I have determined, however, how to calculate these and get a working angle output. The 2 Coefficients in the program are 28.783 for the Gyro and 10.78 for the Accelerometer.

To calculate this for the Gyro:
1. Get the mv/°/s value for your Gyro from the Datasheet
-----25
2. Divide by 1000 (Milli volts in a volt)
-----0.025
3. Divide by 5 (Voltage of the Analog Reference)
-----.005
4. Divide by .0174532925 (Radians in a Degree)
-----0.2864789
5. Take the Inverse of that (1/x)
-----3.49
And there is your answer, 3.49. You would replace the 28.783 in the formula for this.

To calculate this for the Accelerometer:
1. Get the mv/g value for your Accelerometer from the Datasheet
-----1000
2. Divide by 1000 (Milli volts in a volt)
-----1
3. Divide by 5 (Voltage of the Analog Reference)
-----0.2
4. Take the Inverse
-----5
I'm not so sure on this one, but it seems to work. You would replace the 10.78 with this.

You can also replace the Voltage, in this case 5v, or the 1024 in the Formula, depending on your supply voltage or Analog Port Resolution.

When I put this all together in my test code, I get a solid, seemingly accurate angle measurement.

Next up - PID!

Thursday, April 2, 2009

iTunes COM API in C#

I decided that I would post a little guide to some of the things that I have learned in using the iTunes COM API in C#. It's not very well documented, and I though I could help.

Initialization:
First, you have to add a Reference and Using
Right click on References, and click "Add Refrence"
Switch to the COM tab and find "iTunes *.** Type Library, and click add.
At the top of your code, add "Using iTunesLib"
Finally, add these two lines of code under the class of the form, outside of any function:

delegate void Router(object arg);
iTunesApp app = new iTunesAppClass();


The Router helps in handling the iTunes Events, and "app" is what you will use to do anything with iTunes.

Events:
You'll need to attach at least one event for a program that controls iTunes, to see when something changes in iTunes, and here is some code for that:

app.OnPlayerPlayEvent += new _IiTunesEvents_OnPlayerPlayEventEventHandler(delegate(object o)
                {
                    this.Invoke(new Router(app_OnPlayerPlayEvent), o);
                });

This should be put under InitializeComponent(), and will call app_OnPlayerPlayEvent when it is activated.

Controls:
These are pretty simple, just call them to control iTunes:

app.Play();
app.Pause();
app.NextTrack();
app.PreviousTrack();
app.Stop():


There are a few others, but these are the big ones.

Track Information:
iTunes provides pretty much all of the information about a playing track, there is a lot more than I mention here, I reccomend experimentation.

IITTrack track = app.CurrentTrack;
Albumlbl.Text = track.Album;
Artistlbl.Text = track.Artist;
Tracklbl.Text = track.Name;

These will populate the labels with the track (at the time) that is playing or paused. It must be refreshed to update the information.

IITArtworkCollection Art1 = track.Artwork;
IITArtwork Art2 = Art1[1];
Art2.SaveArtworkToFile("c:\\temp\\Album.jpg");
Stream r = File.Open("c:\\temp\\Album.jpg", FileMode.Open);
Image temp = Image.FromStream(r);
r.Close();
pictureBox1.Image = temp;
SetImage(pictureBox1);


This is a big one, it will allow you to put the Album Art of the currently playing track in a Picture Box. I recommend checking the Art1[] or doing this in a Try...Catch to avoid errors when a song does not have art. You will also need these, also, for resizing:

Original Link

public Size GenerateImageDimensions(int currW, int currH, int destW, int destH)
        {
            //double to hold the final multiplier to use when scaling the image
            double multiplier = 0;

            //string for holding layout
            string layout;

            //determine if it's Portrait or Landscape
            if (currH > currW) layout = "portrait";
            else layout = "landscape";

            switch (layout.ToLower())
            {
                case "portrait":
                    //calculate multiplier on heights
                    if (destH > destW)
                    {
                        multiplier = (double)destW / (double)currW;
                    }

                    else
                    {
                        multiplier = (double)destH / (double)currH;
                    }
                    break;
                case "landscape":
                    //calculate multiplier on widths
                    if (destH > destW)
                    {
                        multiplier = (double)destW / (double)currW;
                    }

                    else
                    {
                        multiplier = (double)destH / (double)currH;
                    }
                    break;
            }

            //return the new image dimensions
            return new Size((int)(currW * multiplier), (int)(currH * multiplier));
        }

        //Resize the image
        private void SetImage(PictureBox pb)
        {
            try
            {
                //create a temp image
                Image img = pb.Image;

                //calculate the size of the image
                Size imgSize = GenerateImageDimensions(img.Width, img.Height, this.pictureBox1.Width, this.pictureBox1.Height);

                //create a new Bitmap with the proper dimensions
                Bitmap finalImg = new Bitmap(img, imgSize.Width, imgSize.Height);

                //create a new Graphics object from the image
                Graphics gfx = Graphics.FromImage(img);

                //clean up the image (take care of any image loss from resizing)
                gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;

                //empty the PictureBox
                pb.Image = null;

                //center the new image
                pb.SizeMode = PictureBoxSizeMode.CenterImage;

                //set the new image
                pb.Image = finalImg;
            }
            catch (System.Exception e)
            {
                //MessageBox.Show(e.Message);
            }
        }


Another thing that you can do is a progress bar for Track Time. I have Timer1 set for 1 second intervals. This is not totally tested, your mileage may vary:

void Timer1Tick(object sender, EventArgs e)
        {
            IITTrack track = app.CurrentTrack;
            progress.Maximum = track.Duration;
            progress.Value = app.PlayerPosition;
            if (track.Duration != oldtrack)
            {
                if (track.Name != oldname)
                {
                    NewSong();
                }
                else
                {
                    oldname = track.Name;
                }
            }
            else
            {
                oldtrack = track.Duration;
            }
        }


REST Album Art and Lyrics
Finally, I have these few functions that will use Amazon and LyricWiki to find Album Art and Lyrics of a playing song.
I would recommend running them in a BackgroundWorker, to prevent a program from locking up.

Lyrics:

private static string GetLyrics(string Artist, string Title)
        {
            StringBuilder lyric = new StringBuilder();  //Build a new string
            lyric.Append("http://lyricwiki.org/api.php?func=getSong&artist=");   //Add base URL
            lyric.Append(Artist);
            lyric.Append("&song=");
            lyric.Append(Title);
            lyric.Append("&fmt=xml");
            WebRequest requestlyr = WebRequest.Create(lyric.ToString()); //prepare web request
            StreamReader responseStreamlyr = new StreamReader(requestlyr.GetResponse().GetResponseStream()); //prepare responese holder
            string responselyr = responseStreamlyr.ReadToEnd(); //fill up response
            responseStreamlyr.Close(); //Close stream
            string lyrics = XmlParse_general(responselyr.ToString(), "lyrics"); //parse the XML
            return lyrics;
        }

private static string XmlParse_general(string Url, string type)    //XML parse Function
        {

            XmlTextReader xmlrt1 = new XmlTextReader(new StringReader(Url));
            while (xmlrt1.Read())
            {
                //Trace.Write("Node Type", xmlrt1.NodeType.ToString());
                string strNodeType = xmlrt1.NodeType.ToString();
                string strName = xmlrt1.Name;

                if (strNodeType == "Element" && strName == type)
                {
                    xmlrt1.Read();
                    return xmlrt1.Value; //Return output
                } // end if
            } return "";// end while
        }

Album Art
:

private string AlbumURL(string artist, string album)
        {
            StringBuilder art = new StringBuilder();  //Build a new string
            art.Append("http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&Version=2005-03-23&Operation=ItemSearch&ContentType=text%2Fxml&SubscriptionId=09XAA8GD0PQVCC8KR5G2&SearchIndex=Music&Artist=");   //Add base URL
            art.Append(artist);
            art.Append("&Keywords=");
            art.Append(album);
            art.Append("&ResponseGroup=Images");
            WebRequest requestart = WebRequest.Create(art.ToString()); //prepare web request
            StreamReader responseStreamart = new StreamReader(requestart.GetResponse().GetResponseStream()); //prepare responese holder
            string responseart = responseStreamart.ReadToEnd(); //fill up response
            responseStreamart.Close(); //Close stream
            string url = XML_image(responseart.ToString()); //parse the XML
            return url;
        }

private static string XML_image(string xml)
        {
            XmlTextReader reader = new XmlTextReader(new StringReader(xml));
            reader.ReadToFollowing("LargeImage");
            reader.ReadToFollowing("URL");
            reader.Read();
            return reader.Value;
        }

If anyone has any questions or needs help getting these going, especially the REST functions, or has any suggested improvements, contact me, I'd be glad to help.

Goodbye, and Good Luck!