How to detect green grass for robot mower?

I have been trying to get a TCS34725 color sensor to detect the presence or absence of grass. Indoors the sensor easily detects green color on a laptop screen (by using the MS Paint program). But outdoors in sunlight or shade the red, green and blue data values vary but keep in the same ratio relative to each other whatever color I point the sensor at. I have tried optics to focus the light but it does not seem to help. The sensor is not saturated outside and I have tried all the available sensor gain and integration time settings. Any suggestions? My eyes can easily detect green anywhere so why can't a sensor do it? Am I missing something?

When I saw your title the first thing that came to mind is what do you want to distinguish the grass from - is it grass vs concrete, or is it, (more complicated) cut grass vs uncut grass.

Assuming there is a big contrast (at least to the human eye) I would use my Arduino to record (or display on the serial monitor) the values it detects from the alternatives. They may not be the values you expect, but they may be sufficiently different to work.

I would be very surprised if a simple colour sensor could detect the difference between cut and uncut grass unless the grass was very long to start with so that the cut ends are nearly white.

...R

Thanks Robin. I want to detect between grass and other surfaces such as soil or concrete to keep the mower in the lawn. I've tried the invisible pet fence but I had problems with broken buried wire and noise from the drive motors limited sensitivity. The red, green and blue color signals and even the ratios between the color signals seem to be all over the place when outside that I could not get repeatable reliable data.

This is not a very easy problem to solve - I once found a research paper on detecting vegetation using a neural network, to give you an idea of where things could go...

Have you tried to instead detect "non-grass" stuff?

I've thought of many potential solutions to the issue - but I haven't tried any (life gets in my way - ugh); I own an old Friendly Robotics mower, and I am loathe to place a buried wire.

One method I thought about involved placing a perimeter of permanent magnets around the edge, and detecting them with hall-effect sensors. The magnets would be mounted onto the ends of plastic golf tees; if you could find a source of very tiny rare-earth magnets (such as those used in hard-drives for the head-arm locking mechanism - they measure about 2 x 2 mm ), drilling and press-fitting the magnets into the tees wouldn't be too difficult. Done right, they would likely be nearly invisible below the surface level of the grass (over time, they might disappear into the soil).

On a similar note, you could instead place the magnet holders "randomly" in the grass - then use the hall-effect sensors (perhaps several arranged around the perimeter of the machine) and use a SLAM algorithm to determine approximate position and orientation of the robot (in this way, you could also track where the robot has been, and only cut uncut areas of grass). Of course, such a system lies far outside the capabilities of a standard Arduino (even a Mega).

Most likely, you will need to adopt a variety of solutions to solve this problem; there might not be a "one-size-fits-all" solution - at least not one that is easy to implement.

The red, green and blue color signals and even the ratios between the color signals seem to be all over the place when outside that I could not get repeatable reliable data.

I presume this is true whether you are trying to detect grass or concrete - if so colour detection seems to have ruled itself out.

Our eyes, or more accurately our brains, make huge colour compensations for changing light conditions without us being conscious of it. Try a camera with the white-balance switched off just to see the real world that your sensor has to deal with.

Could you use something like a very light hinged flap that is pushed by the grass but which won't touch the soil or concrete.

...R

Chlorophyll fluorescence is a sensitive method to distinguish growing vegetation from other stuff, but that would be difficult to implement in a lawn mower.

You want to detect "green" in the shade, full sun, cloudy days etc? Then don't look at RGB values. Convert RGB to HSV and detect the hue. You can easily pick a range of hues that are "close enough" to green. You may also need to detect saturation - green-ish concrete will have low saturation compared to grass.

Plant leaves are also highly reflective to IR so maybe IR illumination under the mower can work.

Or buy a Pixy sensor and use that to do your colour detection.