Quad RGB sensor with SPI output drive, I2C display interface & analogue inputs / UI for various LED types
Dependencies: MCP23S17 PCF8574 TextLCD eeprom mbed-dev
main.cpp
- Committer:
- jolyon
- Date:
- 2016-08-16
- Revision:
- 3:b8218b61b0e2
- Parent:
- 2:4a8eacbb3657
- Child:
- 4:dce5fc58abe9
File content as of revision 3:b8218b61b0e2:
#include "mbed.h" #include "TextLCD.h" #include "MCP23S17.h" #define FACTOR 1 #define SENSOR_ADDR (41 << 1) #define SENSOR_WHITE_REG 148 #define SENSOR_RED_REG 150 #define SENSOR_GREEN_REG 152 #define SENSOR_BLUE_REG 154 #define WHITE_THRESHOLD 15 //-------------------------------------- //each LED type is defined here #define NOTUSED 0 #define STD_RED 1 #define STD_GREEN 2 #define STD_BLUE 3 #define STD_YELLOW 4 #define GREEN_YELLOW 5 #define RGB 6 //-------------------------------------- //Current LED Colour Definitions #define ERROR 0 //off or wrong #define RED 1 #define GREEN 2 #define BLUE 3 #define YELLOW 4 //-------------------------------------- //------------------------------------------------------------------------------- //----------- LED's ------------------------------------------------------------- //------------------------------------------------------------------------------- // Detection LED's use the onboard MBED LED's // These are all blue on the MBED but on DSE PCB they areas follows // LED1 = GREEN // LED2 = BLUE // LED3 = RED // LED4 = YELLOW DigitalOut GreenLed(LED1); DigitalOut BlueLed(LED2); DigitalOut RedLed(LED3); DigitalOut YellowLed(LED4); //------------------------------------------------------------------------------- //------------------------------------------------------------------------------- //----------- Analogue Inputs --------------------------------------------------- //------------------------------------------------------------------------------- //Analogue inputs are used to set thresholds for detector levels //AnalogIn RedTrimmer(p15); //AnalogIn GreenTrimmer(p16); //AnalogIn BlueTrimmer(p17); //AnalogIn HysTrimmer(p18); //------------------------------------------------------------------------------- //------------------------------------------------------------------------------- //------------ Text display ----------------------------------------------------- //------------------------------------------------------------------------------- //debug display. Standard display driver set up in 4 bit mode //final version uses I2C port TextLCD lcd(p14, p16, p17, p18, p19, p20, TextLCD::LCD16x2); // rs, e, d4-d7 //set up I2C Communication to LCD //I2C i2c_lcd(p9,p10); // SDA, SCL //I2C Portexpander PCF8574 for LCD //TextLCD_I2C lcd(&i2c_lcd, 0x42, TextLCD::LCD16x2); // I2C bus, PCF8574 Slaveaddress, LCD Type ok //------------------------------------------------------------------------------- //------------------------------------------------------------------------------- //------------ Create SPI bus ----------------------------------------------------- //------------------------------------------------------------------------------- //set up the SPI port for use as output driver SPI spi(p5, p6, p7); char Opcode = 0x40; // Next create a MCP23S17 // mbed p20 is connected to ~chipSelect on the MCP23S17 MCP23S17 chip = MCP23S17(spi, p20, Opcode); //------------------------------------------------------------------------------- //------------------------------------------------------------------------------- //------------ colour sensor Comms Pins ----------------------------------------- //------------------------------------------------------------------------------- //TMC Sensor: this is the raw I2C Port, the clock like is muxed I2C i2c(p28, p27); //pins for I2C communication (SDA, SCL) typedef struct{ uint16_t White; uint16_t Red; uint16_t Green; uint16_t Blue; }Colour; Colour SensorData; //------------------------------------------------------------------------------- //The system looks up the type of LED that is being detected for Each sensor and will fill in the result table & update the associated Output list //outputs start at 0 torough to 15 char Config[32]={ RGB, 0, //sensor 0 , uses 3 outputs - 0,1,2 NOTUSED,3, //sensor 1 NOTUSED,4, //sensor 2 NOTUSED,5, //sensor 3 NOTUSED,6, //sensor 4 NOTUSED,7, //sensor 5 NOTUSED,8, //sensor 6 NOTUSED,9, //sensor 7 NOTUSED,10, //sensor 8 NOTUSED,11, //sensor 9 NOTUSED,12, //sensor 10 NOTUSED,13, //sensor 11 NOTUSED,14, //sensor 12 NOTUSED,15, //sensor 13 NOTUSED,15, //sensor 14 NOTUSED,15, //sensor 15 }; char LEDState[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //current detected LED states uint16_t OutputData = 0; //word containing the current output states of the board uint8_t SensorNumber = 0; //current sensor number char SensorResult = 0; //detected colour //------------TSC Stuff---------------- int sensor_addr = 41 << 1; char TempReg[1] = {0}; char TempData[2] = {0,0}; //------------TSC Stuff---------------- uint16_t Red = 1; uint16_t Green = 2; uint16_t Blue = 3; uint16_t White = 4; uint16_t Yellow = 0; uint32_t AvgRed = 0; uint32_t AvgGreen = 0; uint32_t AvgBlue = 0; uint32_t AvgWhite = 0; uint32_t Temp = 0; uint32_t TempR = 0; uint32_t TempG = 0; uint32_t TempB = 0; uint16_t RedProp = 0; uint16_t GreenProp = 0; uint16_t BlueProp = 0; uint16_t myMix = 0; float MyCCT; float MyCCTi; uint8_t DisplayIndex = 0; uint8_t SensorConfig = 0x30; // bit description setting // 0 SD, 0 = enabled 0 // 1 AF, 0 = Automode 0 // 2 TRIG, 0 = no trigrer 0 // 3 N/F, 0 0 // 4 IT0 0 0 // 5 IT1 1 = 160ms 1 // 6 IT2 0 0 // 7 N/F 0 0 uint16_t MyPort = 1; //working thresholds from pot inputs, scaled 0-100 uint16_t RedThreshold = 0; uint16_t GreenThreshold = 0; uint16_t BlueThreshold = 0; uint16_t Hysteresis = 0; uint16_t Filter(uint32_t *Acc,uint16_t NewData, uint8_t factor) { uint32_t Temp = 0; Temp = *Acc >> factor ; Temp = *Acc - Temp + NewData; *Acc = Temp; return *Acc >> factor; } void ConfigureTSC(uint8_t Address) { I2C i2c(p28, p27); //pins for I2C communication (SDA, SCL) i2c.frequency(200000); char id_regval[1] = {146}; char data[1] = {0}; i2c.write(sensor_addr,id_regval,1, true); i2c.read(sensor_addr,data,1,false); if (data[0]==68) { GreenLed = 0; wait (2); GreenLed = 1; } else { GreenLed = 1; } // Initialize color sensor char enable_register[2] = {128,3}; //enable the sensor i2c.write(sensor_addr,enable_register,2,false); char timing_register[2] = {0x81,0xC0}; //approx 100ms i2c.write(sensor_addr,timing_register,2,false); char control_register[2] = {0x8F,2}; //gain = x16 i2c.write(sensor_addr,control_register,2,false); // Read data from color sensor (Clear/Red/Green/Blue) //led = 1; } Colour GetSensorData(char SensorNumber) { Colour NewData; char AddrReg[1] = {0}; char DataReg[5] ={0,0,0,0,0}; NewData.White = 0; NewData.Red = 0; NewData.Green = 0; NewData.Blue = 0; AddrReg[0] = SENSOR_WHITE_REG; i2c.write(SENSOR_ADDR, AddrReg,1, true); i2c.read(SENSOR_ADDR,DataReg,2, false); NewData.White = ((int)DataReg[1] << 8) | DataReg[0]; AddrReg[0] = SENSOR_RED_REG; i2c.write(SENSOR_ADDR, AddrReg,1, true); i2c.read(SENSOR_ADDR,DataReg,2, false); NewData.Red = ((int)DataReg[1] << 8) | DataReg[0]; AddrReg[0] = SENSOR_GREEN_REG; i2c.write(SENSOR_ADDR, AddrReg,1, true); i2c.read(SENSOR_ADDR,DataReg,2, false); NewData.Green = ((int)DataReg[1] << 8) | DataReg[0]; AddrReg[0] = SENSOR_BLUE_REG; i2c.write(SENSOR_ADDR, AddrReg,1, true); i2c.read(SENSOR_ADDR,DataReg,2, false); NewData.Blue = ((int)DataReg[1] << 8) | DataReg[0]; return NewData; } void InitOutputs(void) { // Set all 8 Port A bits to output direction chip.direction(PORT_A, 0x00); // Set all 8 Port B bits to output direction chip.direction(PORT_B, 0x00); } void SetOutputBit(char bit) { uint16_t OutputWord = 1; char BitA, BitB, PortA, PortB; OutputWord <<= bit; BitA = OutputWord & 0xFF; BitB = OutputWord >> 8; PortA = chip.read(PORT_A); PortA |=BitA; chip.write(PORT_A, PortA); PortB = chip.read(PORT_B); PortB |=BitB; chip.write(PORT_B, PortB); } void ClearOutputBit(char bit) { uint16_t OutputWord = 1; char BitA, BitB, PortA, PortB; OutputWord <<= bit; OutputWord = ~OutputWord; BitA = OutputWord & 0xFF; BitB = OutputWord >> 8; PortA = chip.read(PORT_A); PortA &=BitA; chip.write(PORT_A, PortA); PortB = chip.read(PORT_B); PortB &=BitB; chip.write(PORT_B, PortB); } void WriteOutputPort(uint16_t FullPort) { chip.write(PORT_A, FullPort & 0xFF); chip.write(PORT_B, FullPort >> 8); } void GetThresholds(void) { //Load the pot values ant make 0 to 100% value /* RedThreshold = RedTrimmer.read_u16() * 100 >> 11; GreenThreshold = GreenTrimmer.read_u16() * 100 >> 11; BlueThreshold = BlueTrimmer.read_u16() * 100 >> 11; Hysteresis = HysTrimmer.read_u16() * 100 >> 11; */ RedThreshold = 45; GreenThreshold = 35; BlueThreshold = 10; Hysteresis = 5; } void UpdateDisplay(void) { //make 12 bit only (display) Red >>=4; Green >>=4; Blue >>=4; White >>=4; lcd.locate(0, 0); lcd.printf("R%02i G%02i B%02i W%04i",RedProp,GreenProp,BlueProp,White); lcd.locate(0, 1); lcd.printf("R%02i G%02i B%02i H%02i ",RedThreshold, GreenThreshold, BlueThreshold, Hysteresis); } char GetResults(uint8_t ThisSensor) { char LEDColour = ERROR; if(White > WHITE_THRESHOLD) //looking at intensity somthing is on! { switch(Config[(ThisSensor << 1)]) { case STD_RED: { if((RedProp - GreenProp > 30) && (RedProp - BlueProp > 30)) { LEDColour = RED; } } break; case STD_GREEN: { if((GreenProp - RedProp > 30) && (GreenProp - BlueProp > 30)) { LEDColour = GREEN; } } break; case STD_BLUE: { if((BlueProp - RedProp > 30) && (BlueProp - GreenProp > 30)) { LEDColour = BLUE; } } break; case STD_YELLOW: { if( (GreenProp <= (GreenThreshold-Hysteresis)) && (RedProp >=(RedThreshold+Hysteresis)) ) { LEDColour = YELLOW; } } break; case GREEN_YELLOW: { if( (GreenProp <= (GreenThreshold-Hysteresis)) && (RedProp >=(RedThreshold+Hysteresis)) ) { //pretty sure it's Yellow LEDColour = YELLOW; } else { if( (GreenProp > (GreenThreshold+Hysteresis)) && (RedProp <=(RedThreshold-Hysteresis)) ) { //pretty sure it's green LEDColour = GREEN; } } } break; case RGB: { if((RedProp - GreenProp > 30) && (RedProp - BlueProp > 30)) { LEDColour = RED; } else { if((GreenProp - RedProp > 30) && (GreenProp - BlueProp > 30)) { LEDColour = GREEN; } else { if((BlueProp - RedProp > 30) && (BlueProp - GreenProp > 30)) { LEDColour = BLUE; } } } } break; case NOTUSED: default: { LEDColour = ERROR; } break; } } return LEDColour; } int main() { InitOutputs(); //----------------------Initialise My TCS3472-------------------- ConfigureTSC(0); //---------------------- My TCS3472 -------------------- while(1) { //WriteOutputPort(MyPort); ClearOutputBit(MyPort); MyPort++; if (MyPort == 16) { MyPort = 0; } SetOutputBit(MyPort); GetThresholds(); DisplayIndex++; if(DisplayIndex >= 20) { DisplayIndex = 0; } wait(0.1); //----------------------My TCS3472-------------------- for(SensorNumber = 0; SensorNumber < 16; SensorNumber++) { if(Config[((SensorNumber << 1) + 1)] != NOTUSED) //check to see if the sensor is being used { SensorData = GetSensorData(SensorNumber); White = SensorData.White; Red = SensorData.Red; Green = SensorData.Green; Blue = SensorData.Blue; UpdateDisplay(); // work out % of colour mix Temp = (Red+Blue+Green); RedProp = (Red* 100) / Temp ; GreenProp = (Green* 100) / Temp ; BlueProp = (Blue* 100) / Temp ; SensorResult = GetResults(SensorNumber); //good LED so turn on Outputs switch (Config[(SensorNumber << 1)]) { case STD_RED: case STD_GREEN: case STD_BLUE: case STD_YELLOW: { if (SensorResult == Config[(SensorNumber << 1)]) { SetOutputBit(Config[((SensorNumber << 1)+1)]); } else { ClearOutputBit(Config[((SensorNumber << 1)+1)]); } } break; case GREEN_YELLOW: { if (SensorResult == YELLOW) { SetOutputBit(Config[((SensorNumber << 1)+1)]); //base output ClearOutputBit( Config[((SensorNumber << 1)+1)] +1);//next output } else { if (SensorResult == GREEN) { ClearOutputBit(Config[((SensorNumber << 1)+1)]); //base output SetOutputBit( Config[((SensorNumber << 1)+1)] +1);//next output } else { ClearOutputBit(Config[((SensorNumber << 1)+1)]); //base output ClearOutputBit( Config[((SensorNumber << 1)+1)] +1);//next output } } } break; case RGB: { if (SensorResult == RED) { SetOutputBit(Config[((SensorNumber << 1)+1)]); //base output ClearOutputBit(Config[((SensorNumber << 1)+1)] +1); //next output ClearOutputBit(Config[((SensorNumber << 1)+1)] +2); //next output } else { if (SensorResult == GREEN) { ClearOutputBit(Config[((SensorNumber << 1)+1)]); //base output SetOutputBit(Config[((SensorNumber << 1)+1)] +1); //next output ClearOutputBit(Config[((SensorNumber << 1)+1)] +2); //next output } else { if (SensorResult == BLUE) { ClearOutputBit(Config[((SensorNumber << 1)+1)]); //base output ClearOutputBit(Config[((SensorNumber << 1)+1)] +1); //next output SetOutputBit(Config[((SensorNumber << 1)+1)] +2); //next output } else { ClearOutputBit(Config[((SensorNumber << 1)+1)]); //base output ClearOutputBit(Config[((SensorNumber << 1)+1)] +1); //next output ClearOutputBit(Config[((SensorNumber << 1)+1)] +2); //next output } } } } break; default: { ClearOutputBit(Config[((SensorNumber << 1)+1)]); //base output } break; } //end switch } //end if } //end for //guess the colour if(White > WHITE_THRESHOLD) //looking at intensity somthing is on! { /* if((GreenProp <= 30) && (RedProp >=50)) { //pretty sure it's Yellow YellowLed = 1; GreenLed = 0; } else { YellowLed = 0; if((GreenProp > 40) && (RedProp <=40)) { //pretty sure it's green GreenLed = 1; } else { GreenLed = 1; YellowLed = 1; } } */ //------------------------CHECK red----------------------------------------- if((RedProp - GreenProp > 30) && (RedProp - BlueProp > 30)) { RedLed = 1; GreenLed = 0; BlueLed = 0; YellowLed = 0; } else { if((GreenProp - RedProp > 30) && (GreenProp - BlueProp > 30)) { RedLed = 0; GreenLed = 1; BlueLed = 0; YellowLed = 0; } else { if((BlueProp - RedProp > 30) && (BlueProp - GreenProp > 30)) { RedLed = 0; GreenLed = 0; BlueLed = 1; YellowLed = 0; } else { if( (GreenProp <= (GreenThreshold-Hysteresis)) && (RedProp >=(RedThreshold+Hysteresis)) ) { //pretty sure it's Yellow //YellowLed = 1; //GreenLed = 0; RedLed = 0; GreenLed = 0; BlueLed = 0; YellowLed = 1;; } else { RedLed = 0; GreenLed = 0; BlueLed = 0; YellowLed = 0; } } } } } else { RedLed = 0; GreenLed = 0; BlueLed = 0; YellowLed = 0; } /* //------------------------------------------------------------------------------------------------------------------- if( (GreenProp <= (GreenThreshold-Hysteresis)) && (RedProp >=(RedThreshold+Hysteresis)) ) { //pretty sure it's Yellow YellowLed = 1; GreenLed = 0; } else { YellowLed = 0; if( (GreenProp > (GreenThreshold+Hysteresis)) && (RedProp <=(RedThreshold-Hysteresis)) ) { //pretty sure it's green GreenLed = 1; } else { GreenLed = 1; YellowLed = 1; } } } else { //not enough intensity to determine GreenLed = 0; YellowLed = 0; } */ //---------------------------------------------------------------------------------------------------------------- } //while(1) }//main /* --------------------------------------------------------------------------------------------- //SPI SampleCode #include "mbed.h" #include "MCP23S17.h" // Create SPI bus SPI spi(p5, p6, p7); // char Opcode = 0x40; // Next create a MCP23S17 // mbed p20 is connected to ~chipSelect on the MCP23S17 MCP23S17 chip = MCP23S17(spi, p20, Opcode); DigitalOut led1(LED1); // mbed LED1 is used for test status display int main() { // // Set all 8 Port A bits to output direction chip.direction(PORT_A, 0x00); // Set all 8 Port B bits to input direction chip.direction(PORT_B, 0xFF); led1=0; // Start Loopback test sending out and reading back values // loopback test uses A0 and B0 pins - so use a wire to jumper those two pins on MCP23S17 together while (1) { // write 0xAA to MCP23S17 Port A chip.write(PORT_A, 0xAA); wait(.5); // read back value from MCP23S17 Port B and display B0 on mbed led1 led1 = chip.read(PORT_B)& 0x01; // write 0x55 to MCP23S17 Port A chip.write(PORT_A, 0x55); wait(.5); // read back value from MCP23S17 Port B and display B0 on mbed led1 led1 = chip.read(PORT_B)& 0x01; // led1 should blink slowly when it is all working } } */ //--------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------