Archive for the ‘Teaching’ category

3D Printing in the Classroom

September 29th, 2011

I spent the summer helping Makerbot Industries develop educational curriculum. The start of this ambitious project can be found at http://curricum.makerbot.com. This is just the beginning, and I would love for other educators to contribute their ideas and lesson plans so that there is a community of teachers that can explore 3D printing in their classrooms and inspire their students to create, invent and engage in the engineering process.

I currently have two Thing-O-Matics in my classroom and my students are using a variety of software to create their own models: 3dtin.com, tinkercad.com, sketchup, blender and openscad. Yesterday I came across local-guru.net‘s CookieCutter-editor and I can’t wait to make NY State, some tessellations and maybe even symbolic representations of poetry and narratives. Anyone want an Edger Allen Poe Raven cookie?

Don’t know about 3D printing, or think it would be difficult to incorporate in your curriculum? Then check out last night’s Make Live episode.

Tinkercad Demonstration

Recent readings

July 4th, 2011

Just finished reading Dan Ariely’s The Upside of Irrationality. Significant chapters in terms of teaching were Chapters 1, 2 and 3: Paying More for Less: Why Big Bonuses Don’t Always Work, The Meaning of Labor: What Legos Can Teach Us about the Joy of Work, and The IKEA Effect: Why We Overvalue What We Make.

Some of the take-aways include:

  • Encourage students on their efforts. Everyone works better if their work is appreciated
  • Students enjoy work if they can see a purpose and perhaps even get an opportunity to show off their efforts
  • Students enjoy the act of creativity and making. Even if they are following instructions, the fact that they are part of the process creates a stronger relationship with the product.

Day 2: Junk Guitars and Amps

June 28th, 2011

Inspired by David Erik Nelson’s book Snip, Burn, Solder, Shred and NYCResistor’s Ranjit Bhatnagar, workshop attendees made piezo pick ups, junk guitars and mini-amps.

Xbee and the ConnectPort

March 27th, 2011

Inspired by Rob Faludi’s book, Building Wireless Sensor Networks, my students and I have recently been working with Series 1 Xbee radios and the ConnectPort. While the book covers XBee Series 2 (ZB) radios, we just had Series 1 radios laying around, so that’s what we used.

After completing a few exercises that demonstrated how to send data from radio to radio, we plugged the ConnectPort in and controlled a light remotely through a web page. For most of the class, this was the first time writing PHP. This exercise was based on Rob’s example in the book and works just like Make magazine’s Matt Richardson’s Networked On Air Light example, except that our light was a bit smaller—we used a pink 3mm LED.

Once we could control the LED through the form, I challenged the students to control the light both locally and remotely. This turned out to be a bit more complicated than we expected. After several hours of debugging and with some much appreciated help from Rob, it turned out that

  • The connectPort couldn’t handle a url request that returned nothing.
  • We needed to do a little handshaking
  • We needed to be able to resend a request if it failed

The Basic PHP Form

The Second PHP Script

The Arduino Code

The First PHP Script

<html>
<head>
<title>LightingState</title>
<meta http-equiv="refresh" content="5";url="lighting_state_form.php" />
<meta name="viewport" content="width=device-width; initial-scale=1.0;" /> <!-- for iphone size -->
</head>
<body>
<div>
<?php
// define a variable for the data file
$myFile = "lightingState.txt";
// open the data file
$fh = fopen($myFile, 'r') or die("can't open file");

// read the current light setting from the data file

$contents = fread($fh, filesize($myFile));

// close the data file
fclose($fh);
if(!isset($_POST['send'])){
//statements
if ($contents==1){
$contents="On";
}else{
$contents="Off";
}
echo "Light was last: ".$contents;
} else {
$value =$_POST['light'];
if ($value==1){
echo "Light is now: On";
}else{
echo "Light is now: Off";
}
$fh = fopen($myFile, 'w') or die("can't open file");
fwrite($fh,$value);
fclose($fh);
}
echo"<form action=".$_SERVER['PHP_SELF']." method='post'>";
echo "<input type='radio' name='light' value='1' /> On<br />";
echo "<input type='radio' name='light' value='0' /> Off<br />";
echo"</label><br />";
echo"<input type='submit' value='Submit' name='send' />";
echo"</form>";
?>
</div>
</body>
</html>

The Second PHP Script

<?php
$value =$_GET['light'];
$myFile = "lightingState.txt";
$fh = fopen($myFile, 'r') or die("can't open file");
$oldValue=fread($fh, filesize($myFile));
fclose($fh);
$fh = fopen($myFile, 'w') or die("can't open file");
if(($value==0 ||$value==1) && ($value!=NULL)){
fwrite($fh,$value);
}else{
fwrite($fh,$oldValue);
}
fclose($fh);
echo "A";
?>

Arduino Code

#include <Tone.h>
#include <Button.h>
/*
* *********ZigBee Internet Gateway Light Example********
* by Rob Faludi http://faludi.com
*/
#define NAME "ZIG Light Example"
#define VERSION "1.00"
#define LED_PIN 13
Button btn=Button(5,PULLDOWN);
int outputLight = 12;
int lightState;
int light;
unsigned long pt;
unsigned long pt2;
boolean lightOn=false;
Tone speaker;
String urlRequest;
boolean received=false;
void setup() {
pinMode(LED_PIN,OUTPUT);
pinMode(outputLight,OUTPUT);
blinkLED(LED_PIN,2,100);
blinkLED(outputLight,2,100);
////////////////////////////////
// faster is better for ZIG, but with Series 1
// this seemed to be the best speed
Serial.begin(57600);
////////////////////////////////
delay(2000);
received=true;
////////////////////////////////
speaker.begin(7);
}
void loop() {
if(btn.uniquePress()){
if(lightOn) {
speaker.play(NOTE_C3,200);
urlRequest="my_url/lighting_state_form2.php?light=0";
speaker.play(NOTE_C3,200);
}else if(!lightOn){
speaker.play(NOTE_C5,200);
urlRequest="my_url/lighting_state_form2.php?light=1";
speaker.play(NOTE_C5,200);
}
received=false;
}
if(!received){
if(millis()-pt2>250){
pt2=millis();
Serial.println(urlRequest);
}
}

if(millis()-pt>1000){
pt=millis();
if(received){
Serial.println("my_url/lightingState.txt");
}
}
////////////////////////////////
// if there's a byte waiting
if (Serial.available() > 0) {
////////////////////////////////
// read the ASCII numeral byte
lightState = Serial.read();
////////////////////////////////
//do a little handshaking
if(lightState=='A'){
//run a timer if false, if it waits too long resend it
received=true;
digitalWrite(13,HIGH);
delay(250);
}else{
digitalWrite(13,LOW);
}
////////////////////////////////
if (lightState == '0' || lightState=='1') {
lightState=lightState-48;
if(lightState==1){
lightOn=true;
light=1;
} else if(lightState==0){
lightOn=false;
light=0;
}
}
}
digitalWrite(outputLight, light);
}

////////////////// UTILITIES //////////////////
// this function blinks the an LED light as many times as requested, at the requested blinking rate
void blinkLED(byte targetPin, int numBlinks, int blinkRate) {
for (int i=0; i<numBlinks; i++) {
digitalWrite(targetPin, HIGH); // sets the LED on
delay(blinkRate); // waits for blinkRate milliseconds
digitalWrite(targetPin, LOW); // sets the LED off
delay(blinkRate);
}
}

Twitter Lamp

March 9th, 2011

Twitter Lamp from SACC-PC on Vimeo.

This assignment began as a challenge to use Physical Computing to solve a problem at school. The initial problem the students selected dealt with entering the school in the morning. Rather than typing a password or swiping a card, the students decided that those entering the building should be able to walk by a reader that records their id from a tag on their bag.

From the initial proposal, the students decided to use the RFID reader in a more interactive way. At the same time, the students were introduced to ThingM’s BlinkM, a smart RGB LED.

The project that evolved associated ID tags with colors and allowed a person to mix the primary colors by using two to three cards sequentially. The RGB LED reflected the colors chosen. In addition to creating a RFID controlled lamp, a randomly generated color poem matching the selected color would be tweeted. This way one person could enjoy the lamp locally while others could enjoy the selection remotely.

See the details

The students also created an Instructable

Instruments

March 9th, 2011

Here’s a sample of recent student work using Arduino and the Tone Library

 

Some Soft Circuit Projects

March 8th, 2011

A Short Week

October 16th, 2009

I finished my soft circuit. Now when you pet it it purrs and flashes its eyes. I added a homemade capacitance sensor and a vibrating motor. I started with this information, but ended up using Paul Badger’s CapacitiveSense003 library which worked great. My circuit uses a 2.2MΩ resistor to connect pins 2 and 5 and the sensor itself is made of conductive frabric from LessEMF. The piece came from the Fabric Sample Set (Cat. #SAMPLER) and I cut in in half and connected it to pin 2 through conductive thread and a 22 AWG hookup wire.

Here’s the code:

#include
const int purr = 9; // pin that the LED is attached to
const int led = 3; // pin that the LED is attached to
const int eye1=10;
const int eye2=11;
const int mouth=4;
boolean purring=false;
boolean openEyes=false;
CapSense cs_1_2 = CapSense(1,2);

void setup(){
pinMode(purr, OUTPUT);
pinMode(led, OUTPUT);
pinMode(eye1, OUTPUT);
pinMode(eye2, OUTPUT);
pinMode(mouth, INPUT);
pinMode(led,OUTPUT);

pinMode(purr,OUTPUT);
digitalWrite(purr, LOW);
Serial.begin(9600);
}

int touch_sensor(){
long start = millis();
long total1 = cs_1_2.capSense(30);
if (total1<02){
return 1;
}else{
return 0;
}

/*Serial.print(millis() - start); // check on performance in milliseconds
Serial.print("\t"); // tab character for debug windown spacing

Serial.print(total1); // print sensor output 1
// print sensor output 3

delay(10); */
}

void loop(){
int touch=touch_sensor();
if (digitalRead(mouth)){
openEyes=true;
}
else{
openEyes=false;
}

if(!touch){
if(purring){
for(int i=255;i> 0;i-=10){
analogWrite(purr,i);
delay(20);
}

purring=false;
}
else{
analogWrite(purr,0);
openEyes=false;
}
digitalWrite(led,LOW);

}
else{
purring=true;
digitalWrite(led,HIGH);

analogWrite(purr,200);
openEyes=true;

}
if (openEyes){
for(int i=65;i<255;i+=10){
analogWrite(eye1,i);
analogWrite(eye2,i);
delay(10);
}
for(int i=255;i>65;i-=10){
analogWrite(eye1,i);
analogWrite(eye2,i);
delay(10);
}}else{
analogWrite(eye1,0);
analogWrite(eye2,0);
}
}


Students worked on their own soft circuits this week with different enthusiasm levels. Students used to working through labs, but not producing pieces, enjoyed this assignment far less than those who like to make crafts. Still, I believe introducing students to conductive thread and conductive fabrics will help them construct later projects.

We did run into a few glitches this week as well. One student plugged 12V into the freeduino. The 12V plug was used in our first experiments, and I had mentioned that the freeduino could be powered by the USB or a battery. I had extra Atmega chips and, apart from the chip, the board seemed fine.

Another student had trouble finding the usbserial port. At first I thought that the FTDI Drivers for Intel Macs was not installed, but then he moved to another computer with the same problem. His circuit seemed fine. In the end, it turned out that the USB cable was to blame. As soon as we switched cables, everything worked. It was a brand new cable and it surprised both of us that this was the source of the problems.

IPhone programming is going a bit slower than I anticipated. The class was still working on the second version of the Browser assignment this week. In the meantime, I came up with a way for students to create web pages to document their work:


Background-color:

Application name:


Notes:


File Name:


Code:

 

The Blender class is going well. Students have started working with armatures and materials. They have made short quicktime movies of the experiments and everyone is still engaged in the process.

A cute soft circuit project

October 6th, 2009

Here’s a soft circuit with 2 LEDs and a button. It is basically an electronic sock puppet.

I used a sock covered in a knitted bag. The button is a sewing snap. When the mouth closes, the button returns a 1 and the LEDs flicker.

height="850" codebase='http://www.apple.com/qtactivex/qtplugin.cab'> controller="true" loop="false" pluginspage='http://www.apple.com/quicktime/download/'>

Here’s the code

#define btn 4
#define led1 3
#define led2 9
int btnState;

void setup(){
pinMode(led1,OUTPUT);
pinMode(led2,OUTPUT);
pinMode(btn,INPUT);

}

void loop(){
btnState=digitalRead(btn);
if(btnState){
for(int i=50;i<255;i+=5){
analogWrite(led1,i);
analogWrite(led2,i);
delay(10);
}
for(int i=255;i>100;i-=5){
analogWrite(led1,i);
analogWrite(led2,i);
delay(10);
}
}else{
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
}
Serial.println(digitalRead(btn));
}

iPhone Browser

October 6th, 2009

Perhaps the most typical network task performed by many network
applications is to load a web page.

The functionality of
Safari’s WebKit engine is available to you in the form of the UIWebView.

What we did

Created an application that loaded web pages.

  1. Open Xcode:

  2. Create a new Project (⌘+⇧+N). Make it a View-based
    Application

    view_based

  3. Name it Browser

  4. Open BrowserViewController.h and add pointers for IBOutlets
    for urlField (a UITextField) and webView (a UIWebView).

  5. This application brings up the keyboard. You will
    be managing a text field and you will want to dismiss the keyboard when the user either clicks a done button or presses return.

    To dismiss the keyboard, you need to tell the text field to give up its role
    as the first responder, meaning the component that initially receives
    the user input.
    [nameField resignFirstResponder];

    If you look up the documentation for UITextField, you’ll see that it has a delegate property
    that is defined by the UITextFieldDelegate protocol, a defined group of
    related methods.
    UItextFieldDelegate_doc

    Look up this protocol and you’ll see it has numerous
    methods that alert the delegate of events relating to the text field. One
    of them is textFieldShouldReturn, which looks like what you need in order
    to know when the user has tapped return.

    Add
    the UITextFieldDelegate protocol declaration too.


    @interface BrowserViewController : UIViewController <UITextFieldDelegate>{

  6. Add an instance
    method to handle the clicking of the go button. It will be of type IBAction Name it handleGoTapped.Pass it (id)sender

    Instance methods follow the closed curly brace and precede the @end

  7. Open the BrowserViewController nib in IB and create the User Interface.
    • A textField
    • A webView
    • A GO button

    Add a Placeholder in the textField so that the user knows to type http:// and set the keyboard to URL (⌘+1)

  8. Make the connections.
    (control-click the text field to expose its outlets, and connect
    its Delegate to File’s Owner.)

  9. Open up BrowserViewController.m. You’ll need to define the method to get the URL from
    the text field and have the web view load that site; this method will be
    called when the user clicks the Go button or when they hit Return
    on the pop-up keyboard.

    When the go button is pressed:

    1. Close the keyboard by calling resignFirstResponder on
      urlField

    2. Call loadURL on self

  10. To create the loadURL method
    1. Create a pointer named url of type NSURL and set it to:

      [[NSURL alloc] initWithString: urlField.text]

    2. Create a pointer named request
      of type NSURLRequest and set it to
      [[NSURLRequest alloc] initWithURL: url]

    3. Call loadRequest on webView and pass it request
    4. Release request
    5. Release url

  11. Add the following method:
    -(BOOL)textFieldShouldReturn:(UITextField *)textField {

    }

  12. Inside the method:
    1. Test if the textField equals the urlField

    2. Close the keyboard with resignFirstResponder
    3. Call loadURL on self
    4. Outside of the conditional, return YES

  13. Implement autoroatation
    -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return ((interfaceOrientation == UIInterfaceOrientationPortrait) ||
    (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
    (interfaceOrientation == UIInterfaceOrientationLandscapeRight) ||
    (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown));
    }

  14. Save, Build and Run

  15. Enter a url to test

  16. The most obvious thing lacking from
    the example is the usual forward and back buttons. You can
    implement them with the UIWebView‘s goForward and goBack methods. Provide a delegate that implements the UIWebViewDelegate.

Part 2

All the substantial work in this application is done
by the UIWebView. Once you’ve loaded the page, this view — backed
by the WebKit engine for rendering HTML, interpreting JavaScript, and
handling the network communication — does all the work for handling your web interactions, including submitting forms, navigating to new
pages, running client-side browser apps, etc.

Even if you’re not planning on developing a browser, the UIWebView
has other compelling uses. While UIKit doesn’t provide a styled text
component for iPhone apps, you can style HTML to your heart’s content
with CSS, and put that styled HTML into a UIWebView. In fact, this is
an excellent way to provide an about screen for your application, as
you can provide links to your application’s home page, e-mails for tech
support, or even dialable phone number links, all by just authoring
HTML.
To do this, instead of loading a page from the web, you can include
your HTML, CSS, and images in the application bundle, and then find
them inside the bundle. Making a URL from a path in the bundle is just
a matter of converting the path string to an NSURL:

  1. Create a web page named mywebpage.html or use index.html

  2. In the
    <head></head> section add the following:
    <meta name="viewport" content="width=device-width; initial-scale=1.0;" />
    <meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
    <meta name="apple-mobile-web-app-capable" content="yes" />

  3. Set css body margin to zero

  4. Add the web page to your project. CTRL+click on Resources. Copy the file to your project.

  5. Create an application like you made in part 1, Name it Browser2.

  6. This application is the same as the previous except for the loadURLmethod. Create the IBOutlets and IBAction in the header file

  7. Open Browser2ViewController.xib create a text filed, web view and button. Make connections and CTRL+click on the textField and link it to the FIle Owner’s delegate.

  8. Open the Inspector and in the Text Field set the Text to webpage:

  9. This application is the same as the previous except for the loadURLmethod. Open Browser2ViewController.m file and define the IBAction method and then create the loadURLmethod

    //fill in the blank with a keyword to show your page
    //I did webpage:
    NSRange range = [urlField.text rangeOfString: @"______:"];
    NSURL *url = NULL;
    if (range.location == 0) {
    // find the about page in bundle

    NSString *myPath =
    //fill in the blank with the name of your page
    [[NSBundle mainBundle] pathForResource:@"______"
    ofType:@"html"];
    url = [[NSURL alloc] initFileURLWithPath: myPath];
    } else {
    url = [[NSURL alloc] initWithString: urlField.text];
    }
    if (url != NULL) {
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
    [webView loadRequest: request];
    [request release];
    [url release];

    }

  10. Add the following method:
    - (BOOL)textFieldShouldReturn:(UITextField *)textField {

    }

  11. Inside the method:
    1. Test if the textField equals the urlField

    2. Close the keyboard with resignFirstResponder
    3. Call loadURL on self
    4. Outside of the conditional, return YES

  12. Implement autoroatation
    -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return ((interfaceOrientation == UIInterfaceOrientationPortrait) ||
    (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
    (interfaceOrientation == UIInterfaceOrientationLandscapeRight) ||
    (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown));
    }

  13. Save, Build and Run

  14. Modify the loadURL method so that if the urlField is empty or if the urlField contains the text webpage:, your page gets loaded.

  15. Add the ability to go forward and back