Go Down

Topic: Simple optical trigger (Need help!) (Read 1 time) previous topic - next topic

MustangChris429

I've been working on this project off and on for 2 years now and have really had a lot of trouble.

About myself:
  I'm a mechanical engineer who recently graduated so I've had some basic background in electronics and programming
  My parents own a tree nursery in which they grow deciduous trees for landscaping.

The problem:
-Nursery trees should be fertilized at least twice a year.
  -Fertilizing the trees with granular fertilizer is expensive and labor intensive.  Typically 5 people are needed and it takes all day to do the whole nursery.
  -The trees are planted in rows: http://margolisco.com/margolisco/wp-content/uploads/2011/04/Screen-shot-2011-05-04-at-5.13.08-PM.png

The solution:
  -Adapt a corn planter: http://www.purplewaveauction.com/i/a/2012/20120425ag/B6521.JPG to apply fertilizer in individual doses to trees.

Operation:
1. The tractor will drive down a row of trees (rows on both sides).
2. The optical sensors located near the front of the implement, on either side, will detect that a tree is present.
3. The sensors will send this information to an Arduino controller located on the tractor.
4. The Arduino will delay a specified amount, then trigger a digital output for a specified duration.

Needs:
  The sensors must be able to be weatherproofed.
  The Arduino must handle two separate channels.
  The sensors must be located 10-15 feet from the Arduino.
  The Arduino must have user inputs for the delay and duration of the event
  The Arduino should probably have user input for min and max distance measured (if using measuring sensor)

I started by trying to measure the distance with Sharp IR sensors but for some reason I could not get good readings.  I connected the IR sensor's output directly to an analog input pin on the Arduino.  I also tried supplying the +5V to the sensor with a 7805 voltage regulator to minimize power spikes.  I did tie the Arduino and sensor grounds together.  I also struggled with the timing of things because I need to handle two channels at once.

My handheld Arduino controller has a 16x2 LCD display as well as 10 input buttons.  These buttons send their inputs to two of the analog inputs--I have 5 unique resistors to handle this.

I ended up giving up on the Sharp IR sensors when I came across this project: http://trackroamer.com/Sensors/parkingsensor

I bought one of these parking sensor kits off of Amazon but unfortunately it is not talking to my Arduino.  I'm not sure what the problem is.  I contacted the guy who did the Trackroamer project and he gave me a few basic things to try but without an oscilloscope or logic analyzer, there's not much I can do.  I also don't understand much of the Trackroamer code.

Can someone please help me communicate with this parking sensor?  This would be a great help.
If not, could someone please point me in the direction of another sensor to use?
I also need help handling the timing of events on two channels.

Thank you!
Chris

joshuabardwell

I take it you want to use the distance sensor to detect the presence of the tree, right? So as the tractor is driving between the trees, you would read infinite (or very large) distance, and when the tractor passed a tree, you would read a closer distance. And you would also expect that nothing else would cause false-positive by being in place where a tree might be?

For something like this, I would look into an ultrasonic distance sensor such as this one:

http://www.maxbotix.com/Ultrasonic_Sensors/MB7047.htm

It is nicely compact and already weatherproof. I hoped to find you one that had analog voltage output, to save you the hassle of dealing with I2C bus, but they don't offer an outdoor sensor with analog output. Anyway, I2C is not too bad to deal with, but it's just one more thing for a beginner to learn. Unfortunately, the unit is not cheap, at around $100 each, but it'll do the trick.

I assume you're using two sensors--one for each side of the tractor. If the trees are planted in a grid, do you need two sensors? Or can you assume that if you're passing a tree on one side, there's also one on the other side?

That unit can detect a 3.5" wide dowel at a distance of 10'. If we assume your trees are at least 3.5" in diameter, that seems like a workable distance. If necessary, the sensor could be extended on a beam to get it closer to the trees.

For inputting the delay time, duration, and min/max distance, the simplest thing to do is install potentiometers. The pot provides input from 0-1023 depending on its position, and you then map that value to whatever range of values you desire. So, for example, you might decide that duration would range from 2 seconds to 20 seconds, depending on the tractor's speed. You would simply write:

Code: [Select]
int a = analogRead(durationPotPin);
unsigned long durationMillis = map(a, 0, 1023, 2000, 20000);


Honestly, the programming and wiring part of this project is pretty simple. The real trick will be the actual implementation--turning it into a product that won't fall apart in the field. I strongly suggest working it out on the bench before trying to implement it in real life. In other words, hook an LED up to the digital pin that you will be driving high, and hook a button up to two digital inputs to simulate passing a tree. Now get your code working perfectly so that when you push a button to simulate passing a tree, the LED lights up at the right delay and duration. Okay... now add the IR sensors and make it work based on actual distances. Once that is working, then start interfacing it with the actual planter.

Here is a quick stab at some code that may put you in the right direction. I have completely left out the I2C functionality, as that's not something I have worked with before, so I can't just whip it off from the top of my head. This code compiles, but I obviously haven't fully debugged it by building out a circuit or anything. Hopefully it will get you started in the right direction, though.

Code: [Select]
const byte delayPotPin       = A0;    // potentiometer to input delay value
const byte durationPotPin    = A1;    // potentiometer to input duration value
const byte minDistancePotPin = A2;    // potentiometer to input min-distance value
const byte rangePotPin       = A3;    // potentiometer to input range value
const byte planterPin        = 12;    // pin to drive HIGH to dump fertilizer

const int minDelay           = 2000;  // minimum delay between sensor detect and fertilizer dump, in milliseconds
const int maxDelay           = 20000; // maximum delay between sensor detect and fertilizer dump, in milliseconds
const int minDuration        = 1000;  // minimum length of time to activate fertilizer dump, in milliseconds
const int maxDuration        = 10000; // maximum length of time to activate fertilizer dump, in milliseconds
const int maxMinDistance     = 60;    // maximum allowable value for minDistance parameter, in inches (pardon the terrible variable name)
const int maxRange           = 60;    // maximum allowable range for tree detection, in inches

#define LEFT 1
#define RIGHT 2

void setup()
{
  pinMode(planterPin, OUTPUT);
}

int readDistanceSensor(byte whichSensor)
{
  // use I2C to read distance from the appropriate sensor--LEFT or RIGHT depending on the value of whichSensor
  // convert the distance to inches and return that value
  return 0;
}

unsigned long leftSensorTriggerTime;
unsigned long rightSensorTriggerTime;

void loop()
{
  // read parameters from potentiometers
  int delayMillis = map(analogRead(delayPotPin), 0, 1023, minDelay, maxDelay);
  int durationMillis = map(analogRead(durationPotPin), 0, 1023, minDuration, maxDuration);
  int minDistance = map(analogRead(minDistancePotPin), 0, 1023, 0, maxMinDistance);
  int range = map(analogRead(rangePotPin), 0, 1023, 0, maxRange);

  // read distance sensors
  int distanceLeft = readDistanceSensor(LEFT);
  int distanceRight = readDistanceSensor(RIGHT);

  unsigned long now = millis();

  if (distanceLeft > minDistance && distanceLeft < minDistance + range)
    leftSensorTriggerTime = now + delayMillis;

  if (distanceRight > minDistance && distanceRight < minDistance + range)
    rightSensorTriggerTime = now + delayMillis;

  if ((now > leftSensorTriggerTime && now < leftSensorTriggerTime + durationMillis) || (now > rightSensorTriggerTime && now < rightSensorTriggerTime + durationMillis))
    digitalWrite(planterPin, HIGH);
  else
    digitalWrite(planterPin, LOW);
}

joshuabardwell

BTW, the way I wrote the code was not to have a maxDistance and minDistance, because that would leave us dealing with the case where maxDistance < minDistance, and who wants that? So instead, I base the sensing on minDistance and range, where the sensor will respond to objects in between minDistance and minDistance + range. So range is basically the depth of field, and minDistance moves the depth of field in and out. Hope that makes sense...

PeterH

It's not answering your question, but I would have thought it would be much easier to get reliable detection using a wand/switch setup rather than trying to detect it optically or using ultrasonics.

joshuabardwell

Incidentally, I would strongly recommend installing some kind of an LED onto the unit, to indicate when the unit is detecting a tree. This will help you dial in the distances correctly and will allow you to detect false positives and negatives without dumping fertilizer all over the ground. You could easily put in a toggle switch that allows you to switch the unit between "testing" and "active" mode. In test mode, the unit would simply light the LED; in active mode, it would actually dump the fertilizer. Feedback mechanisms like this are key to making the product usable in the real world, vs. simply on the bench.

MustangChris429


Here's a rough drawing of the situation.  The sensor is probably about 36 inches from the trees, on average.  The trunk diameter will range from 1.5" to 8".

joshuabardwell - I'm afraid of spending another $200 on sensors, only to not be able to communicate with them.  I actually saw those MaxBotix sensors and decided that the learning curve might be too steep for me.

"I take it you want to use the distance sensor to detect the presence of the tree, right? So as the tractor is driving between the trees, you would read infinite (or very large) distance, and when the tractor passed a tree, you would read a closer distance. And you would also expect that nothing else would cause false-positive by being in place where a tree might be?"
You are spot-on here.

Your code looks similar to what I had but a bit more polished.  I will definitely adopt some of your methodology.

I guess I'm most worried about getting good data to work with.  I've really struggled here.  I'm not sure that spending $200 on more sensors that would rely on I2C would be the answer, since I've never dealt with I2C before.


I think your idea of a range that follows the minDistance is a very good one.

PeterH - I shied away from a wand/switch setup because I was worried about the whip bouncing back and forth.  Also, some of the trees are clumps, with more than one stem and I was afraid of entanglement or other unwanted behavior.



joshuabardwell

#7
Nov 01, 2013, 06:43 pm Last Edit: Nov 01, 2013, 06:46 pm by joshuabardwell Reason: 1

I guess I'm most worried about getting good data to work with.  I've really struggled here.  I'm not sure that spending $200 on more sensors that would rely on I2C would be the answer, since I've never dealt with I2C before.


Don't be afraid of I2C. It has a learning curve, but at the end of the day, it's nothing too esoteric, and there are Arduino libraries and tutorials to help make it easier for you. You could start learning with a cheap I2C peripheral and then, once you felt confident, you could invest some money in the sensors.

Here's a good tutorial on I2C itself:
https://learn.sparkfun.com/tutorials/i2c

When you get to the point where they're talking about the I2C protocol, don't freak out. The Arduino libraries make a lot of that stuff automatic and you just have to make a function call.

Here is a tutorial on using I2C to interface with a temperature sensor. It would be a good place to get started:
https://learn.sparkfun.com/tutorials/tmp006-hookup-guide

The sensor itself will run you about $15 plus shipping. If you tried, you could probably find something cheaper, but since there's a ready-made tutorial, it may be worth it.

IMO, the bottom line is that if you can make this work, you will save so much money in labor fertilizing those trees that a few hundred here or there won't even matter. Just be confident that the sensor can detect the trees--and at a distance of 36", it seems like it would, but you might want to call the manufacturer to be sure. My experience is that, on projects like this, they always cost five times as much as they seem like they should; at least three ideas fail completely and require total re-thinking; and you want to throw the whole thing in the trash and give up forever at least a few times. But if you stick it out and don't give up, there's nothing so rewarding as finally seeing it work!

PeterH


PeterH - I shied away from a wand/switch setup because I was worried about the whip bouncing back and forth.  Also, some of the trees are clumps, with more than one stem and I was afraid of entanglement or other unwanted behavior.


From a mechanical point of view it would be very simple and you could deal with 'bouncing back and forth' very easily by adding some mechanical damping. I don't see how any entanglement could occur. You would position the wand so that it sticks straight out at 90 degree to the direction of travel. If it hits a trunk it will be deflected back which means it will inherently slide past whatever it has hit. If you think your driver if going to be moving back and forth and wiggle the wand into a clump of trees then make the wand out of something flexible such as a fiberglass rod as used for kite spars. The issues here are all simple mechanical ones and much easier to deal with than getting an electronic sensor to detect tree trunks reliably.

joshuabardwell


The issues here are all simple mechanical ones and much easier to deal with than getting an electronic sensor to detect tree trunks reliably.


As much as I love the sexy ultrasonic distance sensors, he's totally right.

Go Up