personal range finder

Personal range finder
With this project I focused on making an affordable personal range finder as an assistive device.

The goal was to create a portable device that could help in physically navigating different environments. There are many concerns when dealing with alternative navigation (not using your given sense for what it is commonly used for), the largest challenge is to make a usable translation from one experience to another. In making this translation it is important to consider the normative motion and logic that goes into that particular sense. If you are successful you can trigger the logical actuations that are normally linked for that sense, giving the user a much quicker learning curve. In making a device that encompasses the logic of physical space, perceived time was a important focus. I wanted to make a device that would output a specific building sensation. This sensation is akin to a surface overtaking your visual field or walking into a wall with your arm as a buffer. When doing this you calculate physically the steady bend of your arm as you move in closer to the wall or the steady relation of your size to the visual plane. Both these methods involved a constant linear progression. Information that jumps a point in perception would be no good in transferring information, every new sensation had to be fixed in terms of its previous and post-sensation.
I decided to use a small stepper motor to actuate the physical information, this gave me great accuracy in terms of knowing where and how much the interface is outputting. My goal was to have the output strap to the forearm of the user. After trouble shooting many methods of sensation, I came to the conclusion that the simplest and most effective force transfer was with a single point of pressure that varies according to a object distance. The closer you are to a object the more pressure is applied the farther away the less the pressure. This system works fairly reliably, but because of the lack of sensitivity of the forearm it only can describe about ten feet of space accurately. After that the rate of movement through a space is greater than the increment of information that is applied to the arm.
I tried to use an approach that could be versatile as possible leaving room for easy changes of use. That translated in to trying to keep the cost of production (not development!) to fewer than fifty dollars retail and have the power source as a common nine-volt battery. Also the design was for maximum simplicity and scale ability so instead of a arm mount it could easily be front mounted and could clip to a shirt and be used for crowd navigation. I am also thinking of developing a glove that would be used for small distance (6 inch or less) that could be used in industry (car mechanics, fabrication, ect.) or as assistive technology so you would always have a sense of where your hands are. Needless to say it is not a perfect interface and the resolution is not enough to use it as a sole tool of navigation but I think it does supply fifty dollars worth of help that people could use.
This is the code it works realy well for having many steppers:
int rangeRead();
int averager();
void step();
void step1();
void step2();
void step3();
void step4();
void blink(int howManyTimes);
int speed = 20;
int button = 0; ////////////option of button
int count =0;
int F1 = 0;//////////////flags in the step function to say when it is done
int F2 = 0;
int F3 = 0;
int F4 = 0;
int distance = 0;
int stepperPos = 0;
int buffer = 2;
int RXPin = 2;
int AnalogOutPut = 0;
int offset = 6;
int sIn[10];
int reading[2];///////numbers to be averaged
int loopNumber; // a counter
int aveNumber; ///////////number to be averaged starts with zero if two then say 1
int avDistance;
int avDistance1;
boolean loopFlag =0;
//////////////////////////////////////////////////////
void setup() {
Serial.begin(9600);
pinMode(RXPin,OUTPUT);
pinMode(2,INPUT);
pinMode(8,OUTPUT);//////////first stepper motors out
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);////////end first stepper
pinMode(4,OUTPUT);//////////second stepper motors out
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);////////end second stepper
avDistance = 0;
count=0;
loopNumber = 0; // a counter how many times the programs excuted
aveNumber=2; ///////////number to be averaged starts with zero if two then say 1
// start program with a half-second delay:
delay(500);
//stepperPos = 119;
// blink the reset LED 3 times:
blink(3);
}
////////////////loop///////////////////////////////////////
void loop() {
if (loopFlag == 1){ //////////////tells if a averaging "if" statment occured
loopNumber = 0;
loopFlag=0; //////// resets flag
}
// Serial.println(avDistance1);
stepperPos = count;
distance = rangeRead();
//Serial.println(distance);
reading[loopNumber] = distance; /////////// analog value getting put in an array
// Serial.println( reading[loopNumber]);
avDistance1 =( averager() / 2); /////////////divide by three to get a 80 step movment
Serial.println(avDistance1); // button = digitalRead(2); //////////////// button if you want to use
if (avDistance1 - buffer > stepperPos) { //Step the motor forward one step: to braket say and stepperPos is less than somthing then...
forwardStep(8,9,10,11); //first stepper // change all the range numbers in the if statments
//Serial.println(count);
}
if( avDistance1 + buffer < stepperPos){ ////////// buffer gives inbetween area of no movment(gets rid of jerkyness)
backwardStep(8,9,10,11); //first stepper
}
if (avDistance1 - buffer > stepperPos) { //Step the motor forward one step: to braket say and stepperPos is less than somthing then...
forwardStep(4,5,6,7); //first stepper // change all the range numbers in the if statments
//Serial.println(count);
}
if( avDistance1 + buffer < stepperPos){ ////////// buffer gives inbetween area of no movment(gets rid of jerkyness)
backwardStep(4,5,6,7); //first stepper
}
}
//////////////////////averager/////////////////////////
int averager(){
//Serial.println( reading[4]);
if (loopNumber == aveNumber){ ////////////if its taken the amount of readings we want to average
int num = 0;
for (int x = 0; x < aveNumber; x++){
num = num + reading[x];
// Serial.println(reading[x]);
} /////////// adds analog num
//Serial.println(num);
avDistance = num / aveNumber; ////////////////averages out added analog value by how many we looked at
loopFlag = 1; /////////////// resets loop number to 0
}
loopNumber++; /////////////////////how many times this loops gone
return avDistance;
}
//////////////////////////backward step////////////////////////////////
void backwardStep(int _w,int _x, int _y, int _z){
_w=_w;
_x=_x;
_y=_y;
_z=_z;
step4( _w, _x, _y, _z);
count--;
distance = analogRead(0);
stepperPos = count ;
delay(speed);
step3( _w, _x, _y, _z);
count--;
distance = analogRead(0);
stepperPos = count ;
delay(speed);
step2( _w, _x, _y, _z);
count--;
distance = analogRead(0);
stepperPos = count ;
delay(speed);
step1( _w, _x, _y, _z);
count--;
distance = analogRead(0);
stepperPos = count ;
delay(speed);
//Serial.println (distance);
//Serial.println (count);
}
//////////////////// Blink the reset LED://///////////////////////////
void blink(int howManyTimes) {
int i;
for (i=0; i< howManyTimes; i++) {
digitalWrite(13, HIGH);
delay(200);
digitalWrite(13, LOW);
delay(200);
}
}
////////////////////ez range function/////////////////////////////////
int rangeRead() {
// Reads the Analog output of the MAXSonar® EZ1™ (AN Pin) and returns the target range as a Byte
int RangeA = 0;
digitalWrite (RXPin, 0); //' Turn off the EZ1™ just in case we started with it on
digitalWrite (RXPin, 1); // ' Turn on the EZ1™
delay(50); // ' Wait about 50 ms
RangeA = (analogRead(0) - offset); //' Read the ADC -6 to give a "zero" reading
return RangeA;
}
////////////////////////forward step////////////////////////////////////////////////////////
void forwardStep(int _w,int _x, int _y, int _z){
_w=_w;
_x=_x;
_y=_y;
_z=_z;
step1( _w, _x, _y, _z);
count++;
distance = analogRead(0);
stepperPos = count ;
delay(speed);
step2( _w, _x, _y, _z);
count++;
distance = analogRead(0);
stepperPos = count ;
delay(speed);
step3( _w, _x, _y, _z);
count++;
distance = analogRead(0);
stepperPos = count ;
delay(speed);
step4( _w, _x, _y, _z);
count++;
distance = analogRead(0);
stepperPos = count ;
delay(speed);
// Serial.println (distance);
// Serial.println (stepperPos);
}
///////////////stepper coil set step////////////////////
void step(int _w,int _x, int _y, int _z){ // clear step
digitalWrite (_w, LOW);
digitalWrite (_x, LOW);
digitalWrite (_y, LOW);
digitalWrite (11, LOW);
}
void step1(int _w,int _x, int _y, int _z){
if( F4= 1){
digitalWrite (_w, HIGH);
digitalWrite (_x, HIGH);
digitalWrite (_y, LOW);
digitalWrite (_z, LOW);
F4 = 0;
F1 = 1;
}
}
void step2(int _w,int _x, int _y, int _z){
if( F1= 1){
digitalWrite (_w, LOW);
digitalWrite (_x, HIGH);
digitalWrite (_y, HIGH);
digitalWrite (_z, LOW);
F1 = 0;
F2 = 1;
}
}
void step3(int _w,int _x, int _y, int _z){
if( F2= 1){
digitalWrite (_w, LOW);
digitalWrite (_x, LOW);
digitalWrite (_y, HIGH);
digitalWrite (_z, HIGH);
F2 = 0;
F3 = 1;
}
}
void step4(int _w,int _x, int _y, int _z){
if( F3= 1){
digitalWrite (_w, HIGH);
digitalWrite (_x, LOW);
digitalWrite (_y, LOW);
digitalWrite (_z, HIGH);
F3 = 0;
F4 = 1;
}
}
/////////////////////////end steps/////////////////////////////////