Library for Si114x optical sensors. Currently intended for the Si1146, although it will work also for the Si1145, and without full functionality for the Si1147
Dependents: Si114x_HelloWorld Hello-Uzuki-sensor-shield
Si114x.cpp@0:971d705818e7, 2015-08-23 (annotated)
- Committer:
- Sissors
- Date:
- Sun Aug 23 16:58:36 2015 +0000
- Revision:
- 0:971d705818e7
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Sissors | 0:971d705818e7 | 1 | #include "Si114x.h" |
Sissors | 0:971d705818e7 | 2 | #include "Si114x_defs.h" |
Sissors | 0:971d705818e7 | 3 | |
Sissors | 0:971d705818e7 | 4 | #define PS_ADC_GAIN 0x02 |
Sissors | 0:971d705818e7 | 5 | |
Sissors | 0:971d705818e7 | 6 | |
Sissors | 0:971d705818e7 | 7 | Si114x::Si114x(PinName sda, PinName scl) : i2c(sda,scl) { |
Sissors | 0:971d705818e7 | 8 | //Wait startup time and enable the device |
Sissors | 0:971d705818e7 | 9 | i2c.frequency(400000); |
Sissors | 0:971d705818e7 | 10 | wait_ms(30); |
Sissors | 0:971d705818e7 | 11 | write_byte(REG_MEAS_RATE0, 0x00); |
Sissors | 0:971d705818e7 | 12 | write_byte(REG_MEAS_RATE1, 0x00); |
Sissors | 0:971d705818e7 | 13 | |
Sissors | 0:971d705818e7 | 14 | write_cmd(CMD_RESET); |
Sissors | 0:971d705818e7 | 15 | wait_ms(10); |
Sissors | 0:971d705818e7 | 16 | write_byte(REG_HW_KEY, 0x17); |
Sissors | 0:971d705818e7 | 17 | |
Sissors | 0:971d705818e7 | 18 | //Set UV coefficients |
Sissors | 0:971d705818e7 | 19 | write_byte(REG_UCOEF0, 0x29); |
Sissors | 0:971d705818e7 | 20 | write_byte(REG_UCOEF1, 0x89); |
Sissors | 0:971d705818e7 | 21 | write_byte(REG_UCOEF2, 0x02); |
Sissors | 0:971d705818e7 | 22 | write_byte(REG_UCOEF3, 0x00); |
Sissors | 0:971d705818e7 | 23 | |
Sissors | 0:971d705818e7 | 24 | //Set LED current (max, which apparantly is not going to destroy anything) |
Sissors | 0:971d705818e7 | 25 | write_byte(REG_PS_LED21, 0xFF); |
Sissors | 0:971d705818e7 | 26 | |
Sissors | 0:971d705818e7 | 27 | //Set default LED channels |
Sissors | 0:971d705818e7 | 28 | setPSLEDs(1, 0x01); |
Sissors | 0:971d705818e7 | 29 | setPSLEDs(2, 0x02); |
Sissors | 0:971d705818e7 | 30 | |
Sissors | 0:971d705818e7 | 31 | continious = false; |
Sissors | 0:971d705818e7 | 32 | |
Sissors | 0:971d705818e7 | 33 | } |
Sissors | 0:971d705818e7 | 34 | |
Sissors | 0:971d705818e7 | 35 | bool Si114x::verifyConnection(void) { |
Sissors | 0:971d705818e7 | 36 | uint8_t part_id = read_byte(REG_PART_ID); |
Sissors | 0:971d705818e7 | 37 | if ((part_id == 0x45) || (part_id == 0x46) || (part_id == 0x47)) |
Sissors | 0:971d705818e7 | 38 | return true; |
Sissors | 0:971d705818e7 | 39 | return false; |
Sissors | 0:971d705818e7 | 40 | } |
Sissors | 0:971d705818e7 | 41 | |
Sissors | 0:971d705818e7 | 42 | //-------------------Get light functions--------------------------- |
Sissors | 0:971d705818e7 | 43 | |
Sissors | 0:971d705818e7 | 44 | unsigned short Si114x::getVisibleLight(void) { |
Sissors | 0:971d705818e7 | 45 | if (continious == false) { |
Sissors | 0:971d705818e7 | 46 | //Enable visible light measurement, clear current interrupt, start conversion, wait until done |
Sissors | 0:971d705818e7 | 47 | write_byte(REG_IRQ_STATUS, 0x01); |
Sissors | 0:971d705818e7 | 48 | param_set(RAM_CHLIST, (1<<4)); |
Sissors | 0:971d705818e7 | 49 | write_cmd(CMD_ALS_FORCE); |
Sissors | 0:971d705818e7 | 50 | while(read_byte(REG_IRQ_STATUS) & 0x01 != 0x01); |
Sissors | 0:971d705818e7 | 51 | } |
Sissors | 0:971d705818e7 | 52 | return read_word(REG_ALS_VIS_DATA0); |
Sissors | 0:971d705818e7 | 53 | } |
Sissors | 0:971d705818e7 | 54 | |
Sissors | 0:971d705818e7 | 55 | unsigned short Si114x::getIRLight(void) { |
Sissors | 0:971d705818e7 | 56 | if (continious == false) { |
Sissors | 0:971d705818e7 | 57 | //Enable IR light measurement, clear current interrupt, start conversion, wait until done |
Sissors | 0:971d705818e7 | 58 | write_byte(REG_IRQ_STATUS, 0x01); |
Sissors | 0:971d705818e7 | 59 | param_set(RAM_CHLIST, (1<<5)); |
Sissors | 0:971d705818e7 | 60 | write_cmd(CMD_ALS_FORCE); |
Sissors | 0:971d705818e7 | 61 | while(read_byte(REG_IRQ_STATUS) & 0x01 != 0x01); |
Sissors | 0:971d705818e7 | 62 | } |
Sissors | 0:971d705818e7 | 63 | return read_word(REG_ALS_IR_DATA0); |
Sissors | 0:971d705818e7 | 64 | } |
Sissors | 0:971d705818e7 | 65 | |
Sissors | 0:971d705818e7 | 66 | unsigned short Si114x::getUVIndex(void) { |
Sissors | 0:971d705818e7 | 67 | if (continious == false) { |
Sissors | 0:971d705818e7 | 68 | //Enable IR light measurement, clear current interrupt, start conversion, wait until done |
Sissors | 0:971d705818e7 | 69 | write_byte(REG_IRQ_STATUS, 0x01); |
Sissors | 0:971d705818e7 | 70 | param_set(RAM_CHLIST, (1<<7)); |
Sissors | 0:971d705818e7 | 71 | write_cmd(CMD_ALS_FORCE); |
Sissors | 0:971d705818e7 | 72 | while(read_byte(REG_IRQ_STATUS) & 0x01 != 0x01); |
Sissors | 0:971d705818e7 | 73 | } |
Sissors | 0:971d705818e7 | 74 | return read_word(REG_UV_INDEX0); |
Sissors | 0:971d705818e7 | 75 | } |
Sissors | 0:971d705818e7 | 76 | |
Sissors | 0:971d705818e7 | 77 | //---------------------------------- Proximity ----------------------------------------------------- |
Sissors | 0:971d705818e7 | 78 | unsigned short Si114x::getProximity(char pschannel) { |
Sissors | 0:971d705818e7 | 79 | if (continious == false) { |
Sissors | 0:971d705818e7 | 80 | //Enable IR light measurement, clear current interrupt, start conversion, wait until done |
Sissors | 0:971d705818e7 | 81 | write_byte(REG_IRQ_STATUS, 0x04); |
Sissors | 0:971d705818e7 | 82 | param_set(RAM_CHLIST, (1<<(pschannel-1))); |
Sissors | 0:971d705818e7 | 83 | write_cmd(CMD_PS_FORCE); |
Sissors | 0:971d705818e7 | 84 | while(read_byte(REG_IRQ_STATUS) & 0x04 != 0x04); |
Sissors | 0:971d705818e7 | 85 | } |
Sissors | 0:971d705818e7 | 86 | return read_word(REG_PS1_DATA0 + (pschannel - 1)* 2); |
Sissors | 0:971d705818e7 | 87 | } |
Sissors | 0:971d705818e7 | 88 | |
Sissors | 0:971d705818e7 | 89 | void Si114x::setPSLEDs(char pschannel, char ledmask) { |
Sissors | 0:971d705818e7 | 90 | char psled12 = param_query(RAM_PSLED12_SELECT); |
Sissors | 0:971d705818e7 | 91 | if (pschannel == 1) { |
Sissors | 0:971d705818e7 | 92 | psled12 = (psled12 & ~0x0F) | ledmask; |
Sissors | 0:971d705818e7 | 93 | } |
Sissors | 0:971d705818e7 | 94 | else { |
Sissors | 0:971d705818e7 | 95 | psled12 = (psled12 & ~0xF0) | (ledmask << 4); |
Sissors | 0:971d705818e7 | 96 | } |
Sissors | 0:971d705818e7 | 97 | param_set(RAM_PSLED12_SELECT, psled12); |
Sissors | 0:971d705818e7 | 98 | } |
Sissors | 0:971d705818e7 | 99 | |
Sissors | 0:971d705818e7 | 100 | |
Sissors | 0:971d705818e7 | 101 | //---------------------------------- Read/Write functions --------------------------------------------- |
Sissors | 0:971d705818e7 | 102 | |
Sissors | 0:971d705818e7 | 103 | char Si114x::read_byte(const char reg) { |
Sissors | 0:971d705818e7 | 104 | char retval; |
Sissors | 0:971d705818e7 | 105 | i2c.write(SI114x_ADDRESS, ®, 1, true); |
Sissors | 0:971d705818e7 | 106 | i2c.read(SI114x_ADDRESS, &retval, 1); |
Sissors | 0:971d705818e7 | 107 | return retval; |
Sissors | 0:971d705818e7 | 108 | } |
Sissors | 0:971d705818e7 | 109 | |
Sissors | 0:971d705818e7 | 110 | unsigned short Si114x::read_word(const char reg) { |
Sissors | 0:971d705818e7 | 111 | unsigned short retval; |
Sissors | 0:971d705818e7 | 112 | i2c.write(SI114x_ADDRESS, ®, 1, true); |
Sissors | 0:971d705818e7 | 113 | i2c.read(SI114x_ADDRESS, (char*)&retval, 2); //This actually seems to put them in correct order |
Sissors | 0:971d705818e7 | 114 | return retval; |
Sissors | 0:971d705818e7 | 115 | } |
Sissors | 0:971d705818e7 | 116 | |
Sissors | 0:971d705818e7 | 117 | void Si114x::write_byte(const char reg, const char byte) { |
Sissors | 0:971d705818e7 | 118 | char data[] = {reg, byte}; |
Sissors | 0:971d705818e7 | 119 | i2c.write(SI114x_ADDRESS, data, 2); |
Sissors | 0:971d705818e7 | 120 | } |
Sissors | 0:971d705818e7 | 121 | |
Sissors | 0:971d705818e7 | 122 | void Si114x::param_set(const char param, const char value) { |
Sissors | 0:971d705818e7 | 123 | write_byte(REG_PARAM_WR, value); |
Sissors | 0:971d705818e7 | 124 | write_cmd(CMD_PARAM_SET | param); |
Sissors | 0:971d705818e7 | 125 | } |
Sissors | 0:971d705818e7 | 126 | |
Sissors | 0:971d705818e7 | 127 | char Si114x::param_query(const char param) { |
Sissors | 0:971d705818e7 | 128 | write_cmd(CMD_PARAM_QUERY | param); |
Sissors | 0:971d705818e7 | 129 | return read_byte(REG_PARAM_RD); |
Sissors | 0:971d705818e7 | 130 | } |
Sissors | 0:971d705818e7 | 131 | |
Sissors | 0:971d705818e7 | 132 | void Si114x::write_cmd(const char cmd) { |
Sissors | 0:971d705818e7 | 133 | uint8_t old_value = read_byte(REG_RESPONSE); |
Sissors | 0:971d705818e7 | 134 | |
Sissors | 0:971d705818e7 | 135 | write_byte(REG_COMMAND, cmd); |
Sissors | 0:971d705818e7 | 136 | |
Sissors | 0:971d705818e7 | 137 | if (cmd == CMD_RESET) { |
Sissors | 0:971d705818e7 | 138 | return; |
Sissors | 0:971d705818e7 | 139 | } |
Sissors | 0:971d705818e7 | 140 | |
Sissors | 0:971d705818e7 | 141 | char i = 0; |
Sissors | 0:971d705818e7 | 142 | while(read_byte(REG_RESPONSE) == old_value) { |
Sissors | 0:971d705818e7 | 143 | wait_ms(1); |
Sissors | 0:971d705818e7 | 144 | if (i > 25) { |
Sissors | 0:971d705818e7 | 145 | break; |
Sissors | 0:971d705818e7 | 146 | } |
Sissors | 0:971d705818e7 | 147 | i++; |
Sissors | 0:971d705818e7 | 148 | } |
Sissors | 0:971d705818e7 | 149 | } |