EBB Notes 2

From Noisebridge
Jump to: navigation, search

Rachel & Mike, March 30(?); Rachel April 1 - 5

Next we tried the MaxSonar-EZ1 device. Someone else has hooked it up to an arduino and posted code: http://www.flatline.net/journal/2007/12/02/arduino-reading-the-maxbotix-ultrasonic-rangefinder/ which was a useful reference.

This appears to work slightly better than the PING))) but still shows false negatives at more than about 3 feet. Here's some functional code that pwm's an LED, where the closer the object the brighter the LED. Tweaking would be good as the flashing is fairly noticable, but since this will drive a motor eventually I don't see the point in making it too tiny of a cycle length. EZ-1's analog pin hooked to Arduino's A0 pin & its +5 and ground pins connected to the Arduino 5V and grounds. The LED's + leg is connected, with a 33ohm resistor, to pin D11; - leg is connected to pin D13 (and I don't quite get this, why not to ground? maybe that would work too? haven't tried)

/*
 */

int analogPin = 0;
int ledPin = 11;
int serialPin = 2;
double fullCycle = 50; // cycle time in millis

void setup()                    // run once, when the sketch starts
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(analogPin, INPUT);
}

void loop()                     // run over and over again
{
  // read the voltage
  int something = analogRead(analogPin);
  double volts = something * .0049;

  // convert voltage into distance
  double VperInch = 9.8 / 1000;
  double inches = volts / VperInch;
  
  Serial.print(volts);
  Serial.print("V; ");
  Serial.print(inches);
  Serial.print("in");
  Serial.println();
  
  delay(1);

  double dutyCycle = generateDutyCycle(inches);
  Serial.print(dutyCycle);
  Serial.println("% on");

  pwm(dutyCycle);
}

double generateDutyCycle(double inches) {
  // 6 inches, the closest distance this sensor can read, defined as full power
  // 10 feet, our supposed max distance, defined as no power
  int minDist = 6;
  int maxDist = 120;
  
  // limit values to our defined range
  if( inches > maxDist ) {
    inches = maxDist;
  }
  if( inches < minDist ) {
    inches = minDist;
  }

  // translate the passed value to a percentage, accounting for the fact that
  // the range does not start at 0.  we don't really care EXACTLY where it ends, though
  double adjustedInches = inches - minDist;
  int totalRange = maxDist - minDist;
  return (totalRange - adjustedInches) / totalRange;
}

void pwm(double onCycle)
{
  double offCycle = 1 - onCycle;
  Serial.print("onCycle ");
  Serial.print(onCycle);
  Serial.print("; offCycle ");
  Serial.print(offCycle);
  Serial.println();

  // fullCycle is the full cycle time in millis (what is this called again?)
  long onTime = onCycle * fullCycle;
  long offTime = offCycle * fullCycle;

  Serial.print("on for ");
  Serial.print(onTime);
  Serial.print("; off for ");
  Serial.print(offTime);
  Serial.println();

  if( onTime > 0 ) {
    digitalWrite(ledPin, HIGH);
    delay(onTime);
  }
  if( offTime > 0 ) {
    digitalWrite(ledPin, LOW);
    delay(offTime);
  }
}

This is the serial attempt, with several different read methods, none of which do what is expected. It is possible that the sensor is fried; I didn't get analog readings after giving up on serial, and then swapped it out for the other, which I could read. I haven't tried the serial code on the other EZ-1.

// based on code by:
//Created August 15 2006
//Heather Dewey-Hagborg
//http://www.arduino.cc

#include <ctype.h>

#define bit9600Delay 84  
#define halfBit9600Delay 42
#define bit4800Delay 188 
#define halfBit4800Delay 94 

//byte rx = 3;
//byte tx = 2;
byte rx = 2;
byte tx = 3;
byte SWval;

void setup() {
  Serial.begin(9600);
  Serial.print("hi");  //debugging hello
  pinMode(rx,INPUT);
  pinMode(tx,OUTPUT);
  digitalWrite(tx,LOW);
  delay(2);
//  digitalWrite(13,HIGH); //turn on debugging LED
}

void loop()
{
  Serial.print("> ");
  // first poke it to get a reading
  digitalWrite(tx,HIGH);
  delayMicroseconds(50);
  digitalWrite(tx,LOW);

  // next read the value
  SWval = SWread();

  // print out the value
  Serial.print(SWval);
  Serial.print(" ");
  Serial.println((int)SWval);
    
  // delay a tenth of a second
//  delay(100);
}

int SWreadWithInversion()
{
  byte val = 0;
  while (digitalReadInv(rx));
  //wait for start bit
  if (digitalReadInv(rx) == LOW) {
    delayMicroseconds(halfBit9600Delay);
    for (int offset = 0; offset < 8; offset++) {
      delayMicroseconds(bit9600Delay);
      val |= digitalReadInv(rx) << offset;
    }
    //wait for stop bit + extra
    delayMicroseconds(bit9600Delay); 
    delayMicroseconds(bit9600Delay);
    return val;
  }
}

int SWreadNotInverted()
{
  byte val = 0;
  while (digitalRead(rx));
  //wait for start bit
  if (digitalRead(rx) == HIGH) {
    delayMicroseconds(halfBit9600Delay);
    for (int offset = 0; offset < 8; offset++) {
      delayMicroseconds(bit9600Delay);
      val |= digitalRead(rx) << offset;
    }
    //wait for stop bit + extra
    delayMicroseconds(bit9600Delay); 
    delayMicroseconds(bit9600Delay);
    return val;
  }
}

byte digitalReadInv(byte port)
{
   switch(digitalRead(port))
   {
   case LOW:
       return HIGH;

   case HIGH: default:
       return LOW;
   }
}

int SWread()
{
  byte val = 0;
  while (digitalRead(rx));
  //wait for start bit
  if (digitalRead(rx) == LOW) {
    delayMicroseconds(halfBit9600Delay);
    for (int offset = 0; offset < 8; offset++) {
      delayMicroseconds(bit9600Delay);
      val |= digitalRead(rx) << offset;
    }
    //wait for stop bit + extra
    delayMicroseconds(bit9600Delay); 
    delayMicroseconds(bit9600Delay);
    return val;
  }
}

void SWprint(int data)
{
  byte mask;
  //startbit
  digitalWrite(tx,LOW);
  delayMicroseconds(bit9600Delay);
  for (mask = 0x01; mask>0; mask <<= 1) {
    if (data & mask){ // choose bit
     digitalWrite(tx,HIGH); // send 1
    }
    else{
     digitalWrite(tx,LOW); // send 0
    }
    delayMicroseconds(bit9600Delay);
  }
  //stop bit
  digitalWrite(tx, HIGH);
  delayMicroseconds(bit9600Delay);
}
Personal tools