Nespresso RGB Sensor / GroveColourSensor

Dependents:   ColorDetector ColorDetectorV2 offline_sync_k64f

Fork of GroveColourSensor by Brian Daniels

Committer:
bridadan
Date:
Wed Apr 15 19:13:11 2015 +0000
Revision:
2:50cb56828ab9
Child:
3:a401a082d57e
Broke apart source file

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bridadan 2:50cb56828ab9 1 /*
bridadan 2:50cb56828ab9 2 * Copyright (c) 2006-2013 ARM Limited
bridadan 2:50cb56828ab9 3 *
bridadan 2:50cb56828ab9 4 * Licensed under the Apache License, Version 2.0 (the "License");
bridadan 2:50cb56828ab9 5 * you may not use this file except in compliance with the License.
bridadan 2:50cb56828ab9 6 * You may obtain a copy of the License at
bridadan 2:50cb56828ab9 7 *
bridadan 2:50cb56828ab9 8 * http://www.apache.org/licenses/LICENSE-2.0
bridadan 2:50cb56828ab9 9 *
bridadan 2:50cb56828ab9 10 * Unless required by applicable law or agreed to in writing, software
bridadan 2:50cb56828ab9 11 * distributed under the License is distributed on an "AS IS" BASIS,
bridadan 2:50cb56828ab9 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bridadan 2:50cb56828ab9 13 * See the License for the specific language governing permissions and
bridadan 2:50cb56828ab9 14 * limitations under the License.
bridadan 2:50cb56828ab9 15 */
bridadan 2:50cb56828ab9 16
bridadan 2:50cb56828ab9 17
bridadan 2:50cb56828ab9 18 #include "GroveColourSensor.h"
bridadan 2:50cb56828ab9 19
bridadan 2:50cb56828ab9 20 /**
bridadan 2:50cb56828ab9 21 * Constructor, doesn't affect the device at all.
bridadan 2:50cb56828ab9 22 *
bridadan 2:50cb56828ab9 23 * @param i2c A pointer to the initialized I2C instance.
bridadan 2:50cb56828ab9 24 *
bridadan 2:50cb56828ab9 25 */
bridadan 2:50cb56828ab9 26 GroveColourSensor::GroveColourSensor(I2C *i2c) : i2c(i2c) {
bridadan 2:50cb56828ab9 27 /* empty*/
bridadan 2:50cb56828ab9 28 }
bridadan 2:50cb56828ab9 29
bridadan 2:50cb56828ab9 30 /**
bridadan 2:50cb56828ab9 31 * Powers up the color sensor.
bridadan 2:50cb56828ab9 32 *
bridadan 2:50cb56828ab9 33 */
bridadan 2:50cb56828ab9 34 bool GroveColourSensor::powerUp(void) {
bridadan 2:50cb56828ab9 35 static const char powerUpCommand[] = {0x80, 0x03};
bridadan 2:50cb56828ab9 36 /* turn on the color sensor */
bridadan 2:50cb56828ab9 37 return i2c->write((SEVEN_BIT_ADDRESS << 1), powerUpCommand, sizeof(powerUpCommand)) == 0;
bridadan 2:50cb56828ab9 38 }
bridadan 2:50cb56828ab9 39
bridadan 2:50cb56828ab9 40 /**
bridadan 2:50cb56828ab9 41 * Powers down the color sensor.
bridadan 2:50cb56828ab9 42 *
bridadan 2:50cb56828ab9 43 */
bridadan 2:50cb56828ab9 44 void GroveColourSensor::powerDown(void) {
bridadan 2:50cb56828ab9 45 static const char powerDownCommand[] = {0x80, 0x00};
bridadan 2:50cb56828ab9 46 /* turn on the color sensor */
bridadan 2:50cb56828ab9 47 if (i2c->write((SEVEN_BIT_ADDRESS << 1), powerDownCommand, sizeof(powerDownCommand)) != 0) {
bridadan 2:50cb56828ab9 48 error("failed to power down the sensor");
bridadan 2:50cb56828ab9 49 }
bridadan 2:50cb56828ab9 50 }
bridadan 2:50cb56828ab9 51
bridadan 2:50cb56828ab9 52 /**
bridadan 2:50cb56828ab9 53 * Set the gain of the color sensor.
bridadan 2:50cb56828ab9 54 *
bridadan 2:50cb56828ab9 55 * The following are valid gain values:
bridadan 2:50cb56828ab9 56 *
bridadan 2:50cb56828ab9 57 * 0 - 1X gain
bridadan 2:50cb56828ab9 58 * 1 - 4X gain
bridadan 2:50cb56828ab9 59 * 2 - 16X gain
bridadan 2:50cb56828ab9 60 * 3 - 64X gain
bridadan 2:50cb56828ab9 61 *
bridadan 2:50cb56828ab9 62 * @param gain The gain value specified above.
bridadan 2:50cb56828ab9 63 */
bridadan 2:50cb56828ab9 64 void GroveColourSensor::setGain(uint8_t gain) {
bridadan 2:50cb56828ab9 65 // Set gain (0 Prescale)
bridadan 2:50cb56828ab9 66 char gainRegValue = 0x00 | (gain << 4);
bridadan 2:50cb56828ab9 67
bridadan 2:50cb56828ab9 68 char gainCommand[] = {0x87, gainRegValue};
bridadan 2:50cb56828ab9 69 i2c->write((SEVEN_BIT_ADDRESS << 1), gainCommand, sizeof(gainCommand));
bridadan 2:50cb56828ab9 70 }
bridadan 2:50cb56828ab9 71
bridadan 2:50cb56828ab9 72 /**
bridadan 2:50cb56828ab9 73 * Read a specific color.
bridadan 2:50cb56828ab9 74 *
bridadan 2:50cb56828ab9 75 * @param colour The color to red (RED, GREEN, BLUE, or CLEAR).
bridadan 2:50cb56828ab9 76 */
bridadan 2:50cb56828ab9 77 uint16_t GroveColourSensor::readColour(Colour_t colour) {
bridadan 2:50cb56828ab9 78 char readColorRegistersCommand = 0xb0 + (2 * static_cast<unsigned>(colour));
bridadan 2:50cb56828ab9 79 i2c->write((SEVEN_BIT_ADDRESS << 1), &readColorRegistersCommand, 1 /* size */);
bridadan 2:50cb56828ab9 80
bridadan 2:50cb56828ab9 81 uint16_t colourValue;
bridadan 2:50cb56828ab9 82 i2c->read((SEVEN_BIT_ADDRESS << 1), reinterpret_cast<char *>(&colourValue), sizeof(uint16_t));
bridadan 2:50cb56828ab9 83 return colourValue;
bridadan 2:50cb56828ab9 84 }
bridadan 2:50cb56828ab9 85
bridadan 2:50cb56828ab9 86 /**
bridadan 2:50cb56828ab9 87 * Configures the color sensor to expect block reads.
bridadan 2:50cb56828ab9 88 *
bridadan 2:50cb56828ab9 89 */
bridadan 2:50cb56828ab9 90 void GroveColourSensor::setBlockRead() {
bridadan 2:50cb56828ab9 91 char blockReadCommand = 0xD0;
bridadan 2:50cb56828ab9 92 i2c->write((SEVEN_BIT_ADDRESS << 1), &blockReadCommand, 1);
bridadan 2:50cb56828ab9 93 }
bridadan 2:50cb56828ab9 94
bridadan 2:50cb56828ab9 95 /**
bridadan 2:50cb56828ab9 96 * Read the red, green, blue, and clear channels in one transaction. You must call setBlockRead() before calling this function.
bridadan 2:50cb56828ab9 97 *
bridadan 2:50cb56828ab9 98 * @param sample A pointer to the RGBC instance you wish to populate.
bridadan 2:50cb56828ab9 99 */
bridadan 2:50cb56828ab9 100 void GroveColourSensor::readBlock(RGBC *sample) {
bridadan 2:50cb56828ab9 101 char tmpColours[8] = {0};
bridadan 2:50cb56828ab9 102
bridadan 2:50cb56828ab9 103 if (!i2c->read((SEVEN_BIT_ADDRESS << 1), tmpColours, sizeof(tmpColours))) {
bridadan 2:50cb56828ab9 104 sample->ch.green = bytesTo16bit(tmpColours[0], tmpColours[1] << 8);
bridadan 2:50cb56828ab9 105 sample->ch.red = bytesTo16bit(tmpColours[2], tmpColours[3] << 8);
bridadan 2:50cb56828ab9 106 sample->ch.blue = bytesTo16bit(tmpColours[4], tmpColours[5] << 8);
bridadan 2:50cb56828ab9 107 sample->ch.clear = bytesTo16bit(tmpColours[6], tmpColours[7] << 8);
bridadan 2:50cb56828ab9 108 } else {
bridadan 2:50cb56828ab9 109 printf("I2C Read error\r\n");
bridadan 2:50cb56828ab9 110 }
bridadan 2:50cb56828ab9 111 }
bridadan 2:50cb56828ab9 112
bridadan 2:50cb56828ab9 113 /**
bridadan 2:50cb56828ab9 114 * Non enum version of readColour()
bridadan 2:50cb56828ab9 115 *
bridadan 2:50cb56828ab9 116 * @param colour The integer corresponding to the color you wish to read.
bridadan 2:50cb56828ab9 117 */
bridadan 2:50cb56828ab9 118 uint16_t GroveColourSensor::readColour(unsigned colour) {
bridadan 2:50cb56828ab9 119 if (colour >= NUM_COLORS) {
bridadan 2:50cb56828ab9 120 return 0;
bridadan 2:50cb56828ab9 121 }
bridadan 2:50cb56828ab9 122
bridadan 2:50cb56828ab9 123 return readColour(static_cast<Colour_t>(colour));
bridadan 2:50cb56828ab9 124 }
bridadan 2:50cb56828ab9 125
bridadan 2:50cb56828ab9 126 /**
bridadan 2:50cb56828ab9 127 * Helper function to convert two bytes into a uint16_t.
bridadan 2:50cb56828ab9 128 *
bridadan 2:50cb56828ab9 129 * @param lowByte Least signficant byte.
bridadan 2:50cb56828ab9 130 * @param highByte Most signficant byte.
bridadan 2:50cb56828ab9 131 */
bridadan 2:50cb56828ab9 132 uint16_t GroveColourSensor::bytesTo16bit(char lowByte, char highByte) {
bridadan 2:50cb56828ab9 133 uint16_t res = 0;
bridadan 2:50cb56828ab9 134 res |= lowByte;
bridadan 2:50cb56828ab9 135 res |= highByte << 8;
bridadan 2:50cb56828ab9 136 return res;
bridadan 2:50cb56828ab9 137 }