AS7265x functions for setting integration time, LEDs, collecting/reading data
Dependents: IntegratingSphereController LaunchDay
Diff: AS7265xfunctions.cpp
- Revision:
- 0:3699cacb5a93
- Child:
- 1:4d4e07dcc694
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AS7265xfunctions.cpp Thu Jan 24 01:27:45 2019 +0000 @@ -0,0 +1,184 @@ +#include "AS7265xfunctions.h" +#define REG_ADDR_STATUS 0x00 +#define REG_ADDR_WRITE 0x01 +#define REG_ADDR_READ 0x02 +#define STATUS_TX_VALID 0x02 +#define STATUS_RX_VALID 0x01 +#define REG_DEV_SEL 0x4F +#define REG_LED_CONFIG 0x07 +#define REG_INTEG_TIME 0x05 + +AS7265x::AS7265x(I2C i2c, int addr) : _i2c(i2c) { + _addr = addr; +} + +void AS7265x::collectData(void){ + int k; + for (int i = 0; i < 3; i++) { //goes through all 3 sensors + selectDevice(i); + for (int j = 0; j < 6; j++) { //goes through all 6 channels on each sensor + uint16_t data = getData(j); + k = 6*i + j; //gives the channel currently being read for data out of all 18 channels + switch (k) { //assigns values to the array of data for all 18 channels + case 0: _channels[8] = data; break; + case 1: _channels[10] = data; break; + case 2: _channels[12] = data; break; + case 3: _channels[13] = data; break; + case 4: _channels[14] = data; break; + case 5: _channels [15] = data; break; + case 6: _channels [6] = data; break; + case 7: _channels [7] = data; break; + case 8: _channels [9] = data; break; + case 9: _channels [11] = data; break; + case 10: _channels [16] = data; break; + case 11: _channels [17] = data; break; + case 12: _channels [0] = data; break; + case 13: _channels [1] = data; break; + case 14: _channels [2] = data; break; + case 15: _channels [3] = data; break; + case 16: _channels [4] = data; break; + case 17: _channels [5] = data; break; + default: _channels [0] = 0; + } + } + } +} + +uint16_t AS7265x::readData(int i) { + i--; //so that the user can put in a number 1 to 18 for which channel they want, but the readData function reads from channels 0 to 17 + return _channels[i]; +} + +void AS7265x::regWrite(char reg, char data) { + char status; + char buff[3]; + bool writeBuffReady = false; + while (!writeBuffReady) { + // Read slave I²C status to see if the write buffer is ready. + buff[0] = REG_ADDR_STATUS; + _i2c.write(_addr, buff, 1, true); //true at the end to not send a stop signal before the next start signal because our sensor doesn't need it + _i2c.read(_addr, buff, 1); + status = buff[0]; + if ((status & STATUS_TX_VALID) == 0) + // No inbound TX pending at slave. Okay to write now. + writeBuffReady = true; + + } + // Send the virtual register address (enabling bit 7 to indicate a write). + buff[0] = REG_ADDR_WRITE; + buff[1] = reg | 0x80; + _i2c.write(_addr, buff, 2); + writeBuffReady = false; + while (!writeBuffReady) { + // Read the slave I²C status to see if the write buffer is ready. + buff [0] = REG_ADDR_STATUS; + _i2c.write(_addr, buff, 1, true); + _i2c.read(_addr, buff, 1); + status = buff[0]; + if ((status & STATUS_TX_VALID) == 0) + // No inbound TX pending at slave. Okay to write data now. + writeBuffReady = true; + } + // Send the data to complete the operation. + buff [0] = REG_ADDR_WRITE; + buff [1] = data; + _i2c.write(_addr, buff, 2); +} + +char AS7265x::regRead(char reg) { + char buff [3]; + char status; + bool writeBuffReady = false; + while (!writeBuffReady) { + // Read slave I²C status to see if the read buffer is ready. + buff [0] = REG_ADDR_STATUS; + _i2c.write(_addr, buff, 1, true); + _i2c.read(_addr, buff, 1); + status = buff[0]; + if ((status & STATUS_TX_VALID) == 0) + // No inbound TX pending at slave. Okay to write now. + writeBuffReady = true; + } + // Send the virtual register address (disabling bit 7 to indicate a read). + buff [0] = REG_ADDR_WRITE; + buff [1] = reg; + _i2c.write(_addr, buff, 2); + bool readBuffReady = false; + while (!readBuffReady) { + // Read the slave I²C status to see if our read data is available. + buff [0] = REG_ADDR_STATUS; + _i2c.write(_addr, buff, 1, true); + _i2c.read(_addr, buff, 1); + status = buff[0]; + if ((status & STATUS_RX_VALID) != 0) + // Read data is ready. + readBuffReady = true; + } + // Read the data to complete the operation. + buff [0] = REG_ADDR_READ; + _i2c.write(_addr, buff, 1, true); + _i2c.read(_addr, buff, 1) ; + return buff[0]; +} + +uint16_t AS7265x::getData(int channel){ + int channel_addr; + uint16_t high, low; + switch(channel) { //based on the channel number put into the function, converts to the address of that channel + case 0: channel_addr = 0x08; break; + case 1: channel_addr = 0x0A; break; + case 2: channel_addr = 0x0C; break; + case 3: channel_addr = 0x0E; break; + case 4: channel_addr = 0x10; break; + case 5: channel_addr = 0x12; break; + default: channel_addr = 0x08; + } + high = regRead(channel_addr)<<8; //reads the highest 8 bits of data, and shifts them over by 8, leaving 8 zeroes + low = regRead(channel_addr + 1); //reads the lowest 8 bits of data + return high | low; //lowest 8 bits of data fill in the 8 zeroes left by the highest 8 bits being shifted, created a 16 bit number + +} + +void AS7265x::selectDevice(int dev) { + switch(dev) { //based on the value put into the function, converts to the address of the corresponding sensor and selects it + case 0: regWrite(REG_DEV_SEL, 0x00); break; + case 1: regWrite(REG_DEV_SEL, 0x01); break; + case 2: regWrite(REG_DEV_SEL, 0x02); break; + default: regWrite(REG_DEV_SEL, 0x00); + } +} + +void AS7265x::ledSwitch(int dev, int set) { + char setting; + selectDevice(dev); + setting = regRead(REG_LED_CONFIG); //configures the bits necessary to control the LED, now bit 3 will turn it on or off + if(set) { + setting = setting | 0x08; //turns bit 3 on + } + else { + setting = setting & (0xFF - 0x08); //turns bit 3 off + } + regWrite(REG_LED_CONFIG, setting); +} + +void AS7265x::setAllLeds(int set) { + for (int i = 0; i < 3; i++) { + ledSwitch(i, set); //goes through every sensor, turning the corresponding LED on or off one at a time + } +} + +char AS7265x::getDeviceType() { + return regRead(0x00); +} + +char AS7265x::getHardwareVersion() { + return regRead(0x01); +} + +void AS7265x::setIntegTime(int integTime) { + char setting; + setting = integTime/2.8; + /* divides by 2.8 because the sensor takes the value put into the function and multiplies it by 2.8 to get the integration + time in ms. This way, the user can input how many ms they want the integration time to be */ + regWrite(REG_INTEG_TIME, setting); +} \ No newline at end of file