Kim GiJeong
/
try7_i2c
I2C example
main.cpp@0:98e1e23e4a54, 2019-08-12 (annotated)
- Committer:
- GiJeongKim
- Date:
- Mon Aug 12 09:03:49 2019 +0000
- Revision:
- 0:98e1e23e4a54
I2C example;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
GiJeongKim | 0:98e1e23e4a54 | 1 | #include "mbed.h" |
GiJeongKim | 0:98e1e23e4a54 | 2 | ////////////////////////////////////////////////// |
GiJeongKim | 0:98e1e23e4a54 | 3 | // Testing AS5510 sensor with K22F // |
GiJeongKim | 0:98e1e23e4a54 | 4 | // test results are sent to Tera Term // |
GiJeongKim | 0:98e1e23e4a54 | 5 | // I2C frequency set @ 400kHz // |
GiJeongKim | 0:98e1e23e4a54 | 6 | // // |
GiJeongKim | 0:98e1e23e4a54 | 7 | // Note 1) // |
GiJeongKim | 0:98e1e23e4a54 | 8 | // I2C address 0x1C is used by FXOS8700CQ // |
GiJeongKim | 0:98e1e23e4a54 | 9 | // 3-axis accelerometer and 3-axis magetometer // |
GiJeongKim | 0:98e1e23e4a54 | 10 | // // |
GiJeongKim | 0:98e1e23e4a54 | 11 | // Note 2) // |
GiJeongKim | 0:98e1e23e4a54 | 12 | // Without magnet present the AS5510 sensor is // |
GiJeongKim | 0:98e1e23e4a54 | 13 | // expected to output a value of approx 511 // |
GiJeongKim | 0:98e1e23e4a54 | 14 | // (1023/2= 511 // |
GiJeongKim | 0:98e1e23e4a54 | 15 | // // |
GiJeongKim | 0:98e1e23e4a54 | 16 | // Note 3) // |
GiJeongKim | 0:98e1e23e4a54 | 17 | // Lateral Movement of a simple 2-pole magnet. // |
GiJeongKim | 0:98e1e23e4a54 | 18 | // Magnet size diameter 1mm length 2mm // |
GiJeongKim | 0:98e1e23e4a54 | 19 | // Distance to sensor approx 0.8mm // |
GiJeongKim | 0:98e1e23e4a54 | 20 | // Output 10bit resolution // |
GiJeongKim | 0:98e1e23e4a54 | 21 | ////////////////////////////////////////////////// |
GiJeongKim | 0:98e1e23e4a54 | 22 | |
GiJeongKim | 0:98e1e23e4a54 | 23 | Serial pc(USBTX, USBRX); // tx, rx |
GiJeongKim | 0:98e1e23e4a54 | 24 | I2C i2c(PC_9,PA_8); // SDA, SCL (for K22F) |
GiJeongKim | 0:98e1e23e4a54 | 25 | AnalogOut dac(PA_4); |
GiJeongKim | 0:98e1e23e4a54 | 26 | unsigned int value; |
GiJeongKim | 0:98e1e23e4a54 | 27 | |
GiJeongKim | 0:98e1e23e4a54 | 28 | const int i2c_slave_addr1 = 0x56; // sensor AS5510 number 1 (7 bits), 0x56 or 0x57 |
GiJeongKim | 0:98e1e23e4a54 | 29 | DigitalOut check(PC_3); |
GiJeongKim | 0:98e1e23e4a54 | 30 | |
GiJeongKim | 0:98e1e23e4a54 | 31 | //--- public functions--- |
GiJeongKim | 0:98e1e23e4a54 | 32 | void init_as5510(int); |
GiJeongKim | 0:98e1e23e4a54 | 33 | void read_field(int); |
GiJeongKim | 0:98e1e23e4a54 | 34 | int offset_comp(int); |
GiJeongKim | 0:98e1e23e4a54 | 35 | void look_for_hardware_i2c(void); |
GiJeongKim | 0:98e1e23e4a54 | 36 | |
GiJeongKim | 0:98e1e23e4a54 | 37 | |
GiJeongKim | 0:98e1e23e4a54 | 38 | int main() |
GiJeongKim | 0:98e1e23e4a54 | 39 | { |
GiJeongKim | 0:98e1e23e4a54 | 40 | i2c.frequency(400 * 1000); // 0.4 mHz |
GiJeongKim | 0:98e1e23e4a54 | 41 | wait_ms(2); // Power Up wait |
GiJeongKim | 0:98e1e23e4a54 | 42 | |
GiJeongKim | 0:98e1e23e4a54 | 43 | look_for_hardware_i2c(); // Hardware present ? |
GiJeongKim | 0:98e1e23e4a54 | 44 | init_as5510(i2c_slave_addr1); // Initialize |
GiJeongKim | 0:98e1e23e4a54 | 45 | // //----------Setup register---------------------- |
GiJeongKim | 0:98e1e23e4a54 | 46 | // while (!offset_comp(i2c_slave_addr1)); |
GiJeongKim | 0:98e1e23e4a54 | 47 | // while (!offset_comp(i2c_slave_addr2)); |
GiJeongKim | 0:98e1e23e4a54 | 48 | // pc.printf("Offset compensation process is completed \r\n"); |
GiJeongKim | 0:98e1e23e4a54 | 49 | |
GiJeongKim | 0:98e1e23e4a54 | 50 | //----------Get the results---------------------- |
GiJeongKim | 0:98e1e23e4a54 | 51 | // flipper.attach(&flip, 0.0002f); |
GiJeongKim | 0:98e1e23e4a54 | 52 | while (true) { |
GiJeongKim | 0:98e1e23e4a54 | 53 | check=1; |
GiJeongKim | 0:98e1e23e4a54 | 54 | read_field(i2c_slave_addr1); // Read magnetic Field sensor #1 |
GiJeongKim | 0:98e1e23e4a54 | 55 | check=0; |
GiJeongKim | 0:98e1e23e4a54 | 56 | wait(0.005f); |
GiJeongKim | 0:98e1e23e4a54 | 57 | dac=(float) value/1024.0; |
GiJeongKim | 0:98e1e23e4a54 | 58 | pc.printf("%d\n",value); |
GiJeongKim | 0:98e1e23e4a54 | 59 | } |
GiJeongKim | 0:98e1e23e4a54 | 60 | } |
GiJeongKim | 0:98e1e23e4a54 | 61 | |
GiJeongKim | 0:98e1e23e4a54 | 62 | |
GiJeongKim | 0:98e1e23e4a54 | 63 | void look_for_hardware_i2c() |
GiJeongKim | 0:98e1e23e4a54 | 64 | { |
GiJeongKim | 0:98e1e23e4a54 | 65 | pc.printf("\r\n\n\n"); |
GiJeongKim | 0:98e1e23e4a54 | 66 | pc.printf("Note I2C address 0x1C used by FXOS8700CQ 3-axis accelerometer and 3-axis magetometer\r\n"); |
GiJeongKim | 0:98e1e23e4a54 | 67 | pc.printf("Start hardware search..... \r\n"); |
GiJeongKim | 0:98e1e23e4a54 | 68 | |
GiJeongKim | 0:98e1e23e4a54 | 69 | int count = 0; |
GiJeongKim | 0:98e1e23e4a54 | 70 | for (int address=12; address<256; address+=2) { |
GiJeongKim | 0:98e1e23e4a54 | 71 | if (!i2c.write(address, NULL, 0)) { // 0 returned is OK |
GiJeongKim | 0:98e1e23e4a54 | 72 | pc.printf(" - I2C device found at address 0x%02X\n\r", address >>1); |
GiJeongKim | 0:98e1e23e4a54 | 73 | count++; |
GiJeongKim | 0:98e1e23e4a54 | 74 | } |
GiJeongKim | 0:98e1e23e4a54 | 75 | } |
GiJeongKim | 0:98e1e23e4a54 | 76 | pc.printf("%d devices found \n\r", count); |
GiJeongKim | 0:98e1e23e4a54 | 77 | } |
GiJeongKim | 0:98e1e23e4a54 | 78 | |
GiJeongKim | 0:98e1e23e4a54 | 79 | void init_as5510(int i2c_address) |
GiJeongKim | 0:98e1e23e4a54 | 80 | { |
GiJeongKim | 0:98e1e23e4a54 | 81 | int i2c_adrs=0; |
GiJeongKim | 0:98e1e23e4a54 | 82 | char idata[2]; |
GiJeongKim | 0:98e1e23e4a54 | 83 | int result=0; |
GiJeongKim | 0:98e1e23e4a54 | 84 | |
GiJeongKim | 0:98e1e23e4a54 | 85 | pc.printf("\r\n"); |
GiJeongKim | 0:98e1e23e4a54 | 86 | pc.printf("Start AS5510 init.. \r\n"); |
GiJeongKim | 0:98e1e23e4a54 | 87 | |
GiJeongKim | 0:98e1e23e4a54 | 88 | i2c_adrs= (i2c_address << 1); // AS5510 Slave address lsb= 0 for write |
GiJeongKim | 0:98e1e23e4a54 | 89 | |
GiJeongKim | 0:98e1e23e4a54 | 90 | //---------- Magnet selection -------------------------------- |
GiJeongKim | 0:98e1e23e4a54 | 91 | //----0x00= <50mT-----------Strong magnet |
GiJeongKim | 0:98e1e23e4a54 | 92 | //----0x01= <25mT |
GiJeongKim | 0:98e1e23e4a54 | 93 | //----0x02= <18.7mT |
GiJeongKim | 0:98e1e23e4a54 | 94 | //----0x03= <12.5mT---------Weak magnet |
GiJeongKim | 0:98e1e23e4a54 | 95 | //----------------------------------------------------------- |
GiJeongKim | 0:98e1e23e4a54 | 96 | idata[0]=0x0B; // Register for Sensitivity |
GiJeongKim | 0:98e1e23e4a54 | 97 | idata[1]=0x00; // Byte |
GiJeongKim | 0:98e1e23e4a54 | 98 | result= i2c.write(i2c_adrs, idata, 2, 0); // Now write_sensitivity |
GiJeongKim | 0:98e1e23e4a54 | 99 | if (result != 0) pc.printf("No ACK bit! (09)\n\r"); |
GiJeongKim | 0:98e1e23e4a54 | 100 | |
GiJeongKim | 0:98e1e23e4a54 | 101 | //----------- Operation mode selection------------------------ |
GiJeongKim | 0:98e1e23e4a54 | 102 | idata[0]=0x02; // 0x02 address setup register for operation, speed, polarity |
GiJeongKim | 0:98e1e23e4a54 | 103 | idata[1]=0x04; // Normal Operation, Slow mode (1), NORMAL Polarity (0), Power Up (0) |
GiJeongKim | 0:98e1e23e4a54 | 104 | result= i2c.write(i2c_adrs, idata, 2, 0); // Now write_operation |
GiJeongKim | 0:98e1e23e4a54 | 105 | if (result != 0) pc.printf("No ACK bit! (11)\n\r"); |
GiJeongKim | 0:98e1e23e4a54 | 106 | |
GiJeongKim | 0:98e1e23e4a54 | 107 | pc.printf("AS5510 init done\r\n"); |
GiJeongKim | 0:98e1e23e4a54 | 108 | } |
GiJeongKim | 0:98e1e23e4a54 | 109 | |
GiJeongKim | 0:98e1e23e4a54 | 110 | |
GiJeongKim | 0:98e1e23e4a54 | 111 | int offset_comp(int i2c_address) |
GiJeongKim | 0:98e1e23e4a54 | 112 | { |
GiJeongKim | 0:98e1e23e4a54 | 113 | int adrss=0; |
GiJeongKim | 0:98e1e23e4a54 | 114 | int oresult=0; |
GiJeongKim | 0:98e1e23e4a54 | 115 | char off_data[2]; |
GiJeongKim | 0:98e1e23e4a54 | 116 | int ocf_done=0; |
GiJeongKim | 0:98e1e23e4a54 | 117 | |
GiJeongKim | 0:98e1e23e4a54 | 118 | // First, now Write pointer to register 0x00---------------------------- |
GiJeongKim | 0:98e1e23e4a54 | 119 | adrss= (i2c_address << 1); // AS5510 Slave address lsb= 0 for write |
GiJeongKim | 0:98e1e23e4a54 | 120 | oresult= i2c.write(adrss, 0x00, 1, 0); // write one byte |
GiJeongKim | 0:98e1e23e4a54 | 121 | if (oresult != 0) pc.printf("No ACK bit! (33)\n\r"); |
GiJeongKim | 0:98e1e23e4a54 | 122 | |
GiJeongKim | 0:98e1e23e4a54 | 123 | // Second, now Read register 0x00 and 0x01-------------------------------- |
GiJeongKim | 0:98e1e23e4a54 | 124 | memset(off_data, 0, sizeof(off_data)); |
GiJeongKim | 0:98e1e23e4a54 | 125 | adrss= (i2c_address << 1) | 0x01; // AS5510 address lsb= 1 for read |
GiJeongKim | 0:98e1e23e4a54 | 126 | oresult= i2c.read(adrss, off_data, 2, 0); // read two bytes |
GiJeongKim | 0:98e1e23e4a54 | 127 | |
GiJeongKim | 0:98e1e23e4a54 | 128 | // Now analyse register 0x01 ---------------------------------------------- |
GiJeongKim | 0:98e1e23e4a54 | 129 | ocf_done= off_data[1] & 0x08; // mask off bits, 1= done |
GiJeongKim | 0:98e1e23e4a54 | 130 | if (ocf_done== 0) return(0); // return(0)= compensation process is pending |
GiJeongKim | 0:98e1e23e4a54 | 131 | else return(1); // return(1)= compensation process is completed |
GiJeongKim | 0:98e1e23e4a54 | 132 | } |
GiJeongKim | 0:98e1e23e4a54 | 133 | |
GiJeongKim | 0:98e1e23e4a54 | 134 | |
GiJeongKim | 0:98e1e23e4a54 | 135 | void read_field(int i2c_address) |
GiJeongKim | 0:98e1e23e4a54 | 136 | { |
GiJeongKim | 0:98e1e23e4a54 | 137 | int adr=0; |
GiJeongKim | 0:98e1e23e4a54 | 138 | char rx_data[2]; |
GiJeongKim | 0:98e1e23e4a54 | 139 | int rresult=0; |
GiJeongKim | 0:98e1e23e4a54 | 140 | char lsb, msb; |
GiJeongKim | 0:98e1e23e4a54 | 141 | |
GiJeongKim | 0:98e1e23e4a54 | 142 | // First, now Write pointer to register 0x00---------------------------- |
GiJeongKim | 0:98e1e23e4a54 | 143 | adr= (i2c_address << 1); // AS5510 address lsb= 0 for write |
GiJeongKim | 0:98e1e23e4a54 | 144 | rresult= i2c.write(adr, 0x00, 1, 0); // write one byte to register 0x00 for magnetic field strength |
GiJeongKim | 0:98e1e23e4a54 | 145 | // if (rresult != 0) pc.printf("No ACK bit! (22)\n\r"); |
GiJeongKim | 0:98e1e23e4a54 | 146 | |
GiJeongKim | 0:98e1e23e4a54 | 147 | // Second, now Read register 0x00 and 0x01-------------------------------- |
GiJeongKim | 0:98e1e23e4a54 | 148 | // memset(rx_data, 0, sizeof(rx_data)); |
GiJeongKim | 0:98e1e23e4a54 | 149 | adr= (i2c_address << 1) | 0x01; // AS5510 address lsb= 1 for read |
GiJeongKim | 0:98e1e23e4a54 | 150 | rresult= i2c.read(adr, rx_data, 2, 0); // read two bytes |
GiJeongKim | 0:98e1e23e4a54 | 151 | |
GiJeongKim | 0:98e1e23e4a54 | 152 | |
GiJeongKim | 0:98e1e23e4a54 | 153 | // Now analyse register 0x01 ---------------------------------------------- |
GiJeongKim | 0:98e1e23e4a54 | 154 | lsb= rx_data[0]; // get LSB |
GiJeongKim | 0:98e1e23e4a54 | 155 | msb= rx_data[1]&0x03; // need only 2 low bits og MSB |
GiJeongKim | 0:98e1e23e4a54 | 156 | value = ((msb & 0x03)<<8) + lsb; |
GiJeongKim | 0:98e1e23e4a54 | 157 | // pc.printf("I2C adres= 0x%02X, Magnetic Field => msb= 0x%02X, lsb= 0x%02X, decimal 10-bit value = %u \r\n ", i2c_address, rx_data[0],rx_data[1], value); |
GiJeongKim | 0:98e1e23e4a54 | 158 | } |
GiJeongKim | 0:98e1e23e4a54 | 159 | |
GiJeongKim | 0:98e1e23e4a54 | 160 |