Thursday, March 31, 2011

"The Speed Stick"


Our project idea is essentially a walking stick for the blind that gives the user haptic feedback about their surroundings.  It would do this by detecting surroundings within a 20-feet range using an ultrasound sensor that is planted halfway up the walking stick.  The sensor would be attached to an interfacing microprocessor that communicates with a vibrator.  The vibrator would motion at a frequency dependent upon the relative distance of objects. 

There are some competing technologies that incorporate some form of this functionality (see below).  However, we are adding the wrinkle that our device would be able to interpret the speed of surrounding objects.  This would be useful for situations in which the user needs to be aware of moving objects, such as when they are trying to cross a busy street.  At a cross walk, the user could point the stick both left and right to see if there are moving cars on the street within a 20-foot range.  This could be accomplished by notifying the user with specific objects moving at a speed greater than a certain threshold.  This gives the user the same advantage as people who have vision and look both ways before crossing.

Devices that we would need would be the following:
  • Walking stick
  • Cell phone vibrators
  • Ultrasound transceiver
  • Microprocessor

Competing Technology
  • Retinal implants
    • http://www.midwestlens.com/blogger/2010/11/new-advance-in-medical-technology-enables-blind-people-to-see-shapes-and-objects/
  • Walking stick
    • Kuchenbecker’s lab (publication pending)

Thursday, March 17, 2011

Lab #4 - Servo motors!

There were two main parts to this lab.  The first involved data storage, while the second involved manipulating a servo motor to perform various tasks.

The first portion of the lab was data storage.  In essence, we were tasked with saving data into our microcontroller's very limited memory, and then recalling it to prove that we were successful.  To write data into the microcontroller, the write() function was used.

Since the microcontroller's memory can only be rewritten about 100,000 times before it breaks, we had to add measures into the code to prevent infinite looping.  We did this by making the microcontroller only record numbers when the letter "W" was entered into the Serial Monitor.  The microcontroller outputted the information saved into its memory only when the letter "R" was entered into the Serial Monitor.  The code that handles this process is below.

void loop()
{
  if(Serial.available()>0)
  {
    input = Serial.read();
  }
  if(input==87) //for writing must press W
  {
    EEPROM.write(i,dummy);
    i=i+1;
    dummy=dummy+2;
  }
  else if(input==82) //for reading press R
  {
    while(k<i)
    {
      value=EEPROM.read(k);
      Serial.println(value);
      k=k+1;
    }
    k=0;
  }
  input=0;
}

The second part of this lab concerned the maniuplation of a servo motor.  We first learned how to simply tell the servo motor how far to rotate.  We did this by changing the amount of time that pulses were sent to the servo motor.  This was enacted with the digitalWrite(pin,HIGH) function, then the delayMicroseconds() function, and finally the digitalWrite(pin,LOW) function.  It was noted that the longer the pulses were left on, the more that the servo motor would rotate.  If the pulse widths did not fall approximately within the 1-2 ms range, the servo motor did not function.  Also, pulses had to be sent every 20 ms.

The next part of the lab was to make the servo motor rotate between two positions.  This was performed with two "for" loops that counted to certain values.  The method used is below.

  for(i=200;i>2500;i++)
  {
    digitalWrite(pin,HIGH);
    delayMicroseconds(i);
    digitalWrite(pin,LOW);
    delayMicroseconds(19000-i);
    //delayMicroseconds(1);
  }
  for(i=2500;i>200;i--)
  {
    digitalWrite(pin,HIGH);
    delayMicroseconds(i);
    digitalWrite(pin,LOW);
    delayMicroseconds(19000-i);
    //delayMicroseconds(1);
  }

As can be seen in this method, one counted up to a value, and the other counted down to a value.  This effectively rotated the servo motor back and forth.

The next step in the lab was to manipulate the speed with which the servo motor rotated between the two positions.  This was enacted with a "stepSize" variable that was inputted from the user.  The code can be seen below.

void loop()
{
  int degree = 180;
  final=13.89*degree;
  if(Serial.available()>0)
  {
    int inputChar=Serial.read();
    int stepSize = inputChar;
    i=200;
    if(stepSize==70)
    {
      stepSize=2;
    }
    else if(stepSize==77)
    {
      stepSize=1.5;
    }
    else if(stepSize==83)
    {
      stepSize=1;
    }
    while(i<final)
    {
      digitalWrite(pin,HIGH);
      delayMicroseconds(i);
      digitalWrite(pin,LOW);
      delayMicroseconds(19000-i);
      //delayMicroseconds(1);
      i=i+stepSize;
    }
  }
}

In this way, if the user entered "F" for fast, the step size would be 2.  If they entered "M" for medium, the step size would be 1.5.  Likewise, if they entered "S" for slow, the step size would be 1.  This functionality accounted for the user-interactivity required by the lab.

The next part of the lab was to place a cardboard disk with holes in it and controlling where the holes are placed by manipulating the servo.  The setup used can be seen below.  The picture is for the "multiple holes" portion of the experiment, but the concept is the same for both "single hole" and "multiple holes."


The code  for this portion of the experiment can be seen below. 

void loop()
{
  int degree = 90;
  final=13.89*degree;
  if(Serial.available()>0)
  {
    int inputChar=Serial.read();
    int stepSize = inputChar;
    i=200;
    if(stepSize==70)
    {
      stepSize=2;
    }
    else if(stepSize==77)
    {
      stepSize=1.5;
    }
    else if(stepSize==83)
    {
      stepSize=1;
    }
    while(i<final)
    {
      digitalWrite(pin,HIGH);
      delayMicroseconds(i);
      digitalWrite(pin,LOW);
      delayMicroseconds(19000-i);
      //delayMicroseconds(1);
      i=i+stepSize;
      Serial.println(RCtime(6));
    }
  }
  Serial.println(RCtime(6));
}

long RCtime(int sensPin)
{
   long result = 0;
   pinMode(sensPin, OUTPUT);       // make pin OUTPUT
   digitalWrite(sensPin, HIGH);    // make pin HIGH to discharge capacitor - study the schematic
   delay(1);                       // wait a  ms to make sure cap is discharged
   pinMode(sensPin, INPUT);        // turn pin into an input and time till pin goes low
   digitalWrite(sensPin, LOW);     // turn pullups off - or it won't work
   while(digitalRead(sensPin)){    // wait for pin to go low
      result++;
   }
   return result;                   // report results  

The same basic setup that was used for servo motor manipulation is used, except the "degree" variable was changed.  After some calibration, a multiplying constant is multiplied by the "degree" variable to yield a "final" variable.  The result is that the degree can easily be coded into the program to place the holes wherever one pleases.

It is also worth noting that the voltage running through a photoresistor was monitored using the "RCtime()" function.  This enabled us to determine quantitatively when a hole was successfully placed over a photoresistor.