Making Things Interactive

May 10, 2008

Digital Book Reader

Filed under: Final Project,Nadeem Haidary — nhaidary @ 6:05 pm
Tags:

This simulation of an electronic book reader promotes active reading by harnessing the computing and human power. It uses page-turning gestures to generate the power necessary to update an electronic paper screen. Using gestures provides cognitive, mechanical and digital feedback to the person using the device.

In these demonstrations, rotating the page generates power (as indicated by the LEDs) and displays a new page after a 180 degree rotation.

The second prototype provides an alternative method of turning pages.

And if anyone is interested:

Bibliofile – poster

Bibliofile – presentation

Arduino code:


/*
 *   Digital Book Reader
 *   Final Project
 *   Spring 2008
 *
 *   Nadeem Haidary
 */

//LIBRARIES

//GLOBAL VARIABLES
//pins
int motorPin = 0;                   // motor is connected to pin 0
int mDirectionPin = 1;              // motor is also connected to pin 1
int potPin = 2;                     // potentiometer is connected to pin 2
int rotatePin = 8;                  // the rotation reading switch is connected to pin 8
int LEDPin1 = 9;                    // LED is connected to pin 9
int LEDPin2 = 10;                   // LED is connected to pin 10
int LEDPin3 = 11;                   // LED is connected to pin 11

int potValue;                       // the value read from the potentiometer
int motorValue;                     // the value read from the motor
int tiltValue;                      // the value read from the tilt switch
int currentFlip;                    // the current tilt value
int previousFlip;                   // the state of the tilt switch
int motorDirection;                 // the direction of the motor read without a diode bridge

//---SETUP-------------------------------------------------------------->

void setup() {
  pinMode(motorPin, INPUT);         // Set the motor pin as an input
  pinMode(mDirectionPin, INPUT);    // Set the motor direction pin as an input
  pinMode(LEDPin1, OUTPUT);         // Set the LED pin as an output
  pinMode(LEDPin2, OUTPUT);         // Set the LED pin as an output
  pinMode(LEDPin3, OUTPUT);         // Set the LED pin as an output
  pinMode(rotatePin, INPUT);        // Set the rotate switch pin as an input

  previousFlip = HIGH;   // Read the original state of rotation

    Serial.begin(9600);             // Start serial communications
}

//---LOOP--------------------------------------------------------------->

void loop(){

  //READING THE MOTOR TO GENERATE POWER
  motorValue = analogRead(motorPin);      // Read the motor pin as an analog input
  //Serial.println(motorValue);           // Print motor value

  potValue = analogRead(potPin) / 6.71;   // Read the potentiometer pin and scale from 0-100
  //Serial.println(potValue);               // Print it

  motorDirection = analogRead(mDirectionPin);
  //Serial.println(motorDirection);

  if (motorDirection > 0) {
    if (motorDirection < 10) {                  // Three LED's turn on in sequence depending
      digitalWrite(LEDPin1, HIGH);           // on how much power is being delivered by the motor
      digitalWrite(LEDPin2, LOW);
      digitalWrite(LEDPin3, LOW);
    }
    else if (motorDirection < 50) {
      digitalWrite(LEDPin1, HIGH);
      digitalWrite(LEDPin2, HIGH);
      digitalWrite(LEDPin3, LOW);
    }
    else {
      digitalWrite(LEDPin1, HIGH);
      digitalWrite(LEDPin2, HIGH);
      digitalWrite(LEDPin3, HIGH);
    }
  }
  else {
    digitalWrite(LEDPin1, LOW);
    digitalWrite(LEDPin2, LOW);
    digitalWrite(LEDPin3, LOW);
  }

  flipper();

}

//---FUNCTIONS----------------------------------------------------------->

void flipper() {

  //USING A MOTOR AND SWITCH TO CHANGE PAGES
  currentFlip = digitalRead(rotatePin);   // Read the state of rotation
  //Serial.println(currentFlip);

  if (currentFlip != previousFlip) {
    if (currentFlip == HIGH) {
      if (potValue > 90) {
        Serial.print(2, BYTE);
      }
      else if (potValue <= 90 && potValue > 15) {
        Serial.print(3, BYTE);
      }
      else {
      //Serial.println("hello");
      Serial.print(1, BYTE);
      }
    }
  }

  previousFlip = currentFlip;
}

Processing code:

/*
* Digital Book Reader
* Final Project
* Spring 2008
*
* Nadeem Haidary
*/

//LIBRARIES
import processing.serial.*;

//GLOBAL VARIABLES
PFont title; // title font
PFont font; // text font
Serial port; // Create object from Serial class
int val; // Data received from the serial port
int x = 0; // stores nothing important right now
int page = 0; // page number
int spacer = 0; // tracks line number within loop
int lineStart = -46; // line that page starts at
int lineEnd = 0; // line that page ends at
int linesPerPage = 46; // the total amount of lines dispalyed up until a certain page
boolean saveImage = false; // for saving a frame

void setup() {
size (700, 800);
frameRate(10);

println(Serial.list()); // Set up the serial communication
port = new Serial(this, Serial.list()[1], 9600); // Open the port that the board is connected to (in this case COM4 = [1])
// and use the same speed (9600 bps)

font = loadFont(“BookAntiqua-10.vlw”);
title = loadFont(“BookAntiqua-BoldItalic-48.vlw”);
String lines[] = loadStrings(“ulysses_text only.txt”); // Loads the book from a text file and seperates each line into a String in an array
println(“there are ” + lines.length + ” lines”); // prints the number of lines
}

void draw() {
background (250); // sets the background color
fill (0); // sets the text color
smooth(); // anti-aliasing
String lines[] = loadStrings(“ulysses_text only.txt”); // for some reason, the only way I can get this to work is by reloading the strings every frame

if (0 < port.available()) { // If data is available, val = port.read(); // read it and store it in val } println(val); if (val == 1) { delay(40); page ++; lineStart += linesPerPage; lineEnd += linesPerPage; } if (val == 2) { delay(40); page = page + 50; lineStart += (linesPerPage * 50); lineEnd += (linesPerPage * 50); } if (val == 3) { delay(40); page = page + 10; lineStart += (linesPerPage * 10); lineEnd += (linesPerPage * 10); } if (val == 1 || val == 2 || val == 3) { val = 0; } /* // NAVIGATION if (keyPressed == true){ if (key == '.') { // press the > key to advance a page
delay(40);
page ++;
lineStart += linesPerPage;
lineEnd += linesPerPage;
}
if (key == ‘,’ && page > 0) { // press the < key to go back a page delay(40); page--; lineStart -= linesPerPage; lineEnd -= linesPerPage; } if (key == 's') { // press the s key to save a frame saveImage = true; } //println(lineStart + " " + lineEnd); } */ if (page == 0) { // display title page textFont(title, 48); // sets the type to be used text("Ulysses", 250, 522); textFont(title, 18); text("James Joyce", 255, 480); } else { // display text pages textFont(font, 10); spacer = 0; for (int i=lineStart; i < lineEnd; i++) { // display all the lines for this page text(lines[i], 20, 30 + (spacer*12)); // starting corner and spaces between lines spacer++; // count the lines } textFont(title, 24); text(page, 400, 20); // display page number } if (saveImage == true) { // save a frame save("page.tif"); } } [/sourcecode]

April 30, 2008

What is worth interacting with?

Filed under: Final Writing Assignment,Nadeem Haidary — nhaidary @ 1:37 am

Given the opportunity to apply the technology and techniques we learned to anything, for some reason I chose to work in the same problem space I have been in my design classes. With projects like the pushpin and especially the electronic book reader, I have already been applying what we’ve learned to what I currently imagine I’ll be doing for a living.

What I think I need is for my work with sensor technology to not apply to industrial design. In the future, I’d like to apply what I’ve learned to more pointless creations. There is a great opportunity to explore and play with the technology. Having more open-ended goals for what the ‘thing’ might be could result in learning a lot more about the possibilities that a little circuit board, some programming, and a few electrical devices can bring. I’ve made a few finished* products, but what I think I need is less making and more hacking, less finishing and more playing. It’s something I find hard to do at school, and I feel like this class didn’t do enough to promote the process either. Nevertheless, by exploring both extremes of creative problem solving, the conceptual and the technical, I hope there is a lot more meaning that can be brought to the middle, where design can change the world.

Next semester I will be taking a furniture design class where I hope to explore how technology can enhance or change the meaning of objects we sit on, work upon, sleep on, etc.

Having reached the level of accomplishment we have now gotten to, I think more discussion on the merits and demerits of technology-based interaction should be continued. Right now, interactive/smart products and buildings seem to be very attractive. Objects that can adapt to people will last longer and gain more importance in our lives. But still, I wonder how future saturation of these objects might change our perceptions of interaction. Given our biological and cognitive limitations, and the limited resources we have on this planet, what will be worth interacting with?

*hardly

April 3, 2008

digital book – text display

Filed under: Assignments,Final Project,Nadeem Haidary — nhaidary @ 12:04 am

I have been doing research on electronic ink displays and exploring gestures for generating electricity. I have been working on the Processing end of things and figured out how to load, format and display a whole lot of text. For now, I’m using the < and > keys to navigate, but eventually it will be done tangibly. Here is a screenshot:

page example

And the code:

/*
* Digital Book Reader
* State Machine
* Spring 2008
*
* Nadeem Haidary
*/

//LIBRARIES
import processing.serial.*;

//GLOBAL VARIABLES
PFont title; // title font
PFont font; // text font
Serial port; // Create object from Serial class
int val; // Data received from the serial port
int x = 0; // stores nothing important right now
int page = 0; // page number
int spacer = 0; // tracks line number within loop
int lineStart = -46; // line that page starts at
int lineEnd = 0; // line that page ends at
int linesPerPage = 46; // the total amount of lines dispalyed up until a certain page
boolean saveImage = false; // for saving a frame

void setup() {
size (450, 600);
frameRate(10);
/*
println(Serial.list()); // Set up the serial communication
port = new Serial(this, Serial.list()[1], 9600); // Open the port that the board is connected to (in this case COM4 = [1])
// and use the same speed (9600 bps)
*/
font = loadFont(“BookAntiqua-10.vlw”);
title = loadFont(“BookAntiqua-BoldItalic-48.vlw”);
String lines[] = loadStrings(“ulysses_text only.txt”); // Loads the book from a text file and seperates each line into a String in an array
println(“there are ” + lines.length + ” lines”); // prints the number of lines
}

void draw() {
background (250); // sets the background color
fill (0); // sets the text color
smooth(); // anti-aliasing
String lines[] = loadStrings(“ulysses_text only.txt”); // for some reason, the only way I can get this to work is by reloading the strings every frame

// NAVIGATION
if (keyPressed == true){
if (key == ‘.’) { // press the > key to advance a page
delay(40);
page ++;
lineStart += linesPerPage;
lineEnd += linesPerPage;
}
if (key == ‘,’ && page > 0) { // press the < key to go back a page delay(40); page--; lineStart -= linesPerPage; lineEnd -= linesPerPage; } if (key == 's') { // press the s key to save a frame saveImage = true; } //println(lineStart + " " + lineEnd); } if (page == 0) { // display title page textFont(title, 48); // sets the type to be used text("Ulysses", 250, 522); textFont(title, 18); text("James Joyce", 255, 480); } else { // display text pages textFont(font, 10); spacer = 0; for (int i=lineStart; i < lineEnd; i++) { // display all the lines for this page text(lines[i], 20, 30 + (spacer*12)); // starting corner and spaces between lines spacer++; // count the lines } textFont(title, 10); text(page, 400, 20); // display page number } if (saveImage == true) { // save a frame save("page.tif"); } /* if (0 < port.available()) { // If data is available, val = port.read(); // read it and store it in val } if (val == 1) { x++; } */ } [/sourcecode]

March 27, 2008

digital book machine

Filed under: 8: State Machine,Assignments,Nadeem Haidary — nhaidary @ 5:00 pm

Was working better earlier but the tilt switch sometimes refuses to work without me flicking it angrily. This is a concept for a digital book that powers an electronic paper screen with each turn of the page (in this case an LED). Pages are refreshed with a combination of a tilt switch and motor input. The Processing display has been edited out of the video because of inconsistencies. Arduino:

 
/*
 *   Digital Book Reader
 *   State Machine 
 *   Spring 2008
 *
 *   Nadeem Haidary 
 */

//LIBRARIES

//GLOBAL VARIABLES
//pins
int motorPin = 0;                   // motor is connected to pin 0
int LEDPin = 9;                     // LED is connected to pin 9
int tiltPin = 8;                    // tilt switch is connected to pin 8

int motorValue;                     // the value read from the motor
int tiltValue;                      // the value read from the tilt switch
int currentTilt;                    // the current tilt value
int previousTilt;                   // the state of the tilt switch
int x = 0;

//---SETUP-------------------------------------------------------------->

void setup() {
  pinMode(motorPin, INPUT);         // Set the motor pin as an input
  pinMode(LEDPin, OUTPUT);          // Set the LED pin as an output
  pinMode(tiltPin, INPUT);          // Set the tilt pin as an input

  //currentTilt = digitalRead(tiltPin);
  previousTilt = digitalRead(tiltPin);

  Serial.begin(9600);               // Start serial communications
}

//---LOOP--------------------------------------------------------------->

void loop(){
  motorValue = analogRead(motorPin);      // Read the motor pin as an analog input 
  //Serial.println(motorValue);
  analogWrite(LEDPin, motorValue);

  currentTilt = digitalRead(tiltPin);
  //Serial.println(currentTilt);
  //delay(100);
  //Serial.println(0);

  if (motorValue > 30) {
    Serial.println ("Page" + x);
    //Serial.print(1, BYTE);                   // send 1 to Processing
    previousTilt = currentTilt;  
    x++;
  }

  else {                                     // If the switch is not ON,
    //Serial.print(0, BYTE);                   // send 0 to Processing
  }

}

Processing:

/*
* Digital Book Reader
* State Machine
* Spring 2008
*
* Nadeem Haidary
*/

import processing.serial.*;

PFont font;
Serial port; // Create object from Serial class
int val; // Data received from the serial port
int x = 0;

void setup() {

size (400, 600);
background (200);
fill (0);
frameRate(10);
println(Serial.list()); // Set up the serial communication
port = new Serial(this, Serial.list()[1], 9600); // Open the port that the board is connected to (in this case COM4 = [1])
// and use the same speed (9600 bps)
font = loadFont(“BookAntiqua-BoldItalic-48.vlw”);

}
void draw() {
textFont(font, 48);
text(x, 100, 100);

if (0 < port.available()) { // If data is available, val = port.read(); // read it and store it in val } if (val == 1) { x++; background (200); } } [/sourcecode]

March 25, 2008

digital book reader

Filed under: Assignments,Nadeem Haidary — nhaidary @ 1:56 pm

pdf:

Digital book proposal

March 20, 2008

Digital Book state diagram

Filed under: 8: State Machine,Assignments,Nadeem Haidary — nhaidary @ 1:56 pm

This is a digital book reader. When the front cover is opened, a photosensor reads HIGH to display the title page. The page is attached to a motor, which in this case is used backwards as a generator and switch. When the page is turned, it rotates the motor, causing an input pin to read HIGH and provide electricity to generate the next page’s text on a digital ink display. Everytime you turn the page 360 degrees, you generate a new page, so it simulates turning the pages of an analog book. The text (which in my case will be displayed in Processing) has a feature to save a section of the page as an image in the margin by drawing a box around it. You can view that image full-screen by clicking on it in the margin.

book state diagram

March 6, 2008

Mid-Term Project: Pushpin

Filed under: 7: Mid-Term Project,Assignments,Nadeem Haidary — nhaidary @ 12:11 am

The pushpin is fully assembled and working. A button on the front changes the color of an LED on the back of the pushpin, reflecting the light onto the wall. When you tilt the pushpin 90 degrees, a black square turns red, indicating that you can record audio. Tilting the pushpin back stops the recording and plays back the audio (as proof that it was recorded). Finally, when you click on the screen, it stores those audio files as .wav on to your computer. The device uses both Arduino and Processing software.

Labels
pushpin-solo_web.jpg
pushpin-on-_web.jpg
pushpinwiring_revised.jpg

Arduino:

 /*
 *   PUSHPINS
 *   Midterm project
 *   Spring 2008
 *
 *   Nadeem Haidary
 */

//LIBRARIES

//GLOBAL VARIABLES
//pins
int switchPin = 3;               // switch is connected to pin 3
int tiltPin = 2;                 // tilt sensor is connected to pin 2
int ledPin1 = 12;                // red LED is connected to pin 12
int ledPin2 = 11;                // green LED is connected to pin 11
int ledPin3 = 10;                // blue LED is connected to pin 10 ???

//reading the LED switch
int Sval;                        // variable for reading the switchPin status
int Sval2;                       // variable for reading the delayed switchPin status
int SbuttonState;                // variable to hold the swithcPin button state

//reading the tilt switch
int Tval;                        // variable for reading the tiltPin status
int Tval2;                       // variable for reading the delayed tiltPin status
int TbuttonState;                // variable to hold the tiltPin button state 

int lightMode = 0;               // What mode is the LED in?

//---SETUP-------------------------------------------------------------->

void setup() {
  pinMode(switchPin, INPUT);     // Set the switch pin as input
  pinMode(tiltPin, INPUT);       // Set the tilt switch as input

  pinMode(ledPin1, OUTPUT);      // Set the red LED pin as output
  pinMode(ledPin2, OUTPUT);      // Set the green LED pin as output
  pinMode(ledPin3, OUTPUT);      // Set the blue LED pin as output

  Serial.begin(9600);            // Set up serial communication at 9600bps

  SbuttonState = digitalRead(switchPin);     // read the initial state of the LED switch
  TbuttonState = digitalRead(tiltPin);       // read the initial state of the tilt switch
}

//---LOOP--------------------------------------------------------------->

void loop(){
  LEDchanger();                              // Function: reads switch to change LED color
  tiltRecorder();                            // Function: reads tilt, data to Processing
}

//---FUNCTIONS----------------------------------------------------------->

void LEDchanger() {
  Sval = digitalRead(switchPin);             // Read input value and store it in val
  delay(10);                                 // Wait before double-checking
  Sval2 = digitalRead(switchPin);            // Read the input again to check for bounces
  if (Sval == Sval2) {                       // If there readings are the same
    if (Sval != SbuttonState) {              // and the button state has changed
      if (Sval == LOW) {                     // check if the button is pressed
        if (lightMode == 0) {                // if LED is off
          lightMode = 1;                     // turn red LED on
        }
        else {
          if (lightMode == 1) {              // if red LED is on
            lightMode = 2;                   // switch to yellow LED
          }
          else {
            if (lightMode == 2) {            // if yellow LED is on
              lightMode = 3;                 // switch to green LED
            }
            else {
              if (lightMode == 3) {          // if green LED is on
                lightMode = 0;               // turn LED off
              }
            }
          }
        }
      }
    }
    SbuttonState = Sval;                     // save the new state of the switch
  }
  // Now do whatever the lightMode indicates
  if (lightMode == 0) {                      // LED is off
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, LOW);
  }
  if (lightMode == 1) {                      // red
    digitalWrite(ledPin1, HIGH);
    digitalWrite(ledPin2, LOW);
  }
  if (lightMode == 2) {                      // yellow
    digitalWrite(ledPin1, HIGH);
    digitalWrite(ledPin2, HIGH);
  }
  if (lightMode == 3)  {                     // green
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, HIGH);
  }
}  

void tiltRecorder() {

  Tval = digitalRead(tiltPin);               // Reads tilt sensor
    //Serial.println(Tval);
  if (Tval == 1) {                           // If switch is ON
    Serial.print(1, BYTE);                   // send 1 to Processing
  }
  else {                                     // If the switch is not ON,
    Serial.print(0, BYTE);                   // send 0 to Processing
  }
  delay(100);                                // Wait 100 milliseconds
}

Processing:

/**
*
* PUSHPINS
* Nadeem Haidary
* uses the serial and sonia Processing libraries
*
*/

//LIBRARIES
import pitaru.sonia_v2_9.*; // Import the Sonia sound library for recording, playing, and saving audio
import processing.serial.*; // Import the Serial library to communicate with Arduino

//GLOBAL VARIABLES & OBJECTS
//serial
Serial port; // Create object from Serial class
int val; // Data received from the serial port

//audio
int sampleCounter = 0; // the current sample we are recording/playing
int numSamples = 100; // the total number of samples we can use
Sample[] mySampleObj = new Sample[numSamples]; // The Sonia Sample object which we’ll record into
int startRecord = 0; // used to stop the loop from rerecording every frame
int startPlay = 1; // used to stop the loop from replaying every frame

//—SETUP————————————————————–>

void setup()
{
size(600, 600);
frameRate(10);
println(Serial.list()); // Set up the serial communication
port = new Serial(this, Serial.list()[1], 9600); // Open the port that the board is connected to (in this case COM4 = [1])
// and use the same speed (9600 bps)
Sonia.start(this); // Set up sound library
LiveInput.start(); // set up audio recording
int recTimeSec = 10; // Maximum recordable time
for (int i = 0; i < numSamples; i++) { // create 100 samples to record mySampleObj[i] = new Sample (44100*recTimeSec); } } //---LOOP--------------------------------------------------------------->

void draw() {
smooth();
noStroke();

if (0 < port.available()) { // If data is available, val = port.read(); // read it and store it in val } //println(val); background(255); // Set background to white if (val == 0) { // If the serial value is 0, fill(0); // set fill for rectangle to black if (startPlay == 0) { // Start playing (but prevent looping) LiveInput.stopRec(mySampleObj[sampleCounter]); // stop recording mySampleObj[sampleCounter].play(); // play back last recording println("PLAY"); // print PLAY sampleCounter++; // increment to next available sample startRecord = 0; // enable recording startPlay = 1; // disable playing (for loop) } } else { // If the serial value is not 0, fill(255, 30, 30); // set fill to red if (startRecord == 0) { // Start recording (but prevent looping) LiveInput.startRec(mySampleObj[sampleCounter]); // Record LiveInput data into the Sample object. // The recording will automatically end when all of the Sample's frames are filled with data. println("RECORD"); // print RECORD startPlay = 0; // enable playing startRecord = 1; // disable recording (for loop) } } rect(100, 100, 400, 400); // draw square } //---FUNCTIONS----------------------------------------------------------->

void mousePressed() { // If the mouse is clicked

for (int i = 0; i < sampleCounter; i++){ // go through all the samples that have been recorded mySampleObj[i].saveFile("test" + (i + 1)); // and save them (takes some time) println("saving file" + (i + 1)); // let us know when you saved each one } LiveInput.stop(); // stop audio recording Sonia.stop(); // stop Sonia exit(); // quit the Processing applet } [/sourcecode]

February 28, 2008

Midterm Project Proposal: PUSHPINS

Filed under: Nadeem Haidary — nhaidary @ 12:00 am

Pushpin Proposal

(pdf)

Nadeem Haidary

February 19, 2008

Rotational Forms

Filed under: 6: More Motion,Assignments,Nadeem Haidary — nhaidary @ 2:09 pm

I’m using the potentiometer to control a DC motor. I made this as a tool to experiment with rotational forms. You can put a profile on the disc and the motor will spin it to give the illusion of a 3-dimensional form. I was looking at how fast the disc needs to be spinning to create the illusion. I was trying to see how fast the disc needs to be moving for an LED to look stable even though it is actually only seen once per revolution (through the hole).

I am having problems with the power to the motor dying periodically if I crank it up high. I reverted to thick paper after experimenting with foamcore-but the motor is not powerful enough to spin it quickly.


/*
ROTATIONAL FORM
by Nadeem Haidary

with help from ITP Physical Computing tutorials
*/

int transistorPin = 9;              // connected to the base of the transistor
int transistorValue = 180;          // initial value for motor speed (through transistor)

int potentiometerValue = 0;         // the value returned from the potentiometer
int potentiometerPin = 0;           // the analog pin reading the potentiometer
int motorSpeed = 0;

//-------------------------------------------------------------------

void setup() {
pinMode(transistorPin, OUTPUT);   // Set transistor pin as an output pin
Serial.begin(9600);
}

//-------------------------------------------------------------------

void loop() {

//-----DC MOTOR-----
potentiometerValue = analogRead(potentiometerPin);     // read the analog input
motorSpeed = potentiometerValue/4;                     // converts the potentiometer value (0-1023)
// to a range between 0 - 255 for the motor
transistorValue = motorSpeed;                           // Transfer windspeed to motor
Serial.println(transistorValue);
analogWrite(9, transistorValue);                       // Turn the DC motor on

}

February 12, 2008

Don Quixote

Filed under: 5: Making Motion,Assignments,Nadeem Haidary — nhaidary @ 4:01 am

For my MakingMotion project I decided to recreate the scene of Don Quixote charging into the windmill. The motor runs a windmill and our hero, Don Quixote, charges on a servo controlled by a potentiometer. I tried to modify the rotational speed of the windmill with a sin wave to give a more natural wind, but the numbers don’t seem to be accurately controlling the motor.


/*
 DON QUIXOTE
 by Nadeem Haidary

 with code from
 "Servo control from an analog input"
 by Tom Igoe
 additions by Carlyn Maw
 */

int transistorPin = 9;              // connected to the base of the transistor
int transistorValue = 180;          // initial value for motor speed (through transistor)
float angle = 0.0;                    // angle for sin-value that modifies windmill speed

int servoPin = 2;                   // Control pin for servo motor
int minPulse = 500;                 // Minimum servo position
int maxPulse = 2500;                // Maximum servo position
int pulse = 0;                      // Amount to pulse the servo

long lastPulse = 0;                 // the time in milliseconds of the last pulse
int refreshTime = 25;               // the time needed in between pulses

int potentiometerValue = 0;         // the value returned from the potentiometer
int potentiometerPin = 0;           // the analog pin reading the potentiometer

//-------------------------------------------------------------------

void setup() {
  pinMode(transistorPin, OUTPUT);   // Set transistor pin as an output pin
  pinMode(servoPin, OUTPUT);        // Set servo pin as an output pin
  pulse = minPulse;                 // Set the motor position value to the minimum
  Serial.begin(9600);
}

//-------------------------------------------------------------------

void loop() {

  //-----DC MOTOR-----
  angle += 0.001;                                        // Modify how quickly the windspeed changes
  float sinval = sin(angle);                             // Use sin to vary windspeed
  int windSpeed = (int)(255 + (sinval * 255))/2;         // Convert sin to motor speed (0-255)
  transistorValue = windSpeed;                           // Transfer windspeed to motor
  Serial.println(transistorValue);
  analogWrite(9, transistorValue);                       // Turn the DC motor on

  //-----SERVO-----
  potentiometerValue = analogRead(potentiometerPin);     // read the analog input
  pulse = (potentiometerValue * 19) / 10 + minPulse;     // convert the potentiometer value (0-1023)
                                                         // to a range between minPulse and maxPulse. 

  // pulse the servo again if rhe refresh time has passed:
  if (millis() - lastPulse >= refreshTime) {
    digitalWrite(servoPin, HIGH);                        // Turn the Servo on
    delayMicroseconds(pulse);                            // Length of the pulse sets the motor position
    digitalWrite(servoPin, LOW);                         // Turn the Servo off
    lastPulse = millis();                                // save the time of the last pulse
  }
}
Next Page »

Blog at WordPress.com.