Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
main.cpp@0:503735f92bfb, 2014-02-09 (annotated)
- Committer:
- Kir
- Date:
- Sun Feb 09 06:56:37 2014 +0000
- Revision:
- 0:503735f92bfb
- Child:
- 1:f2050723c26f
The auPower board testing program
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| Kir | 0:503735f92bfb | 1 | /* |
| Kir | 0:503735f92bfb | 2 | Copyright (c) 2014 Aurobo Pty Ltd |
| Kir | 0:503735f92bfb | 3 | |
| Kir | 0:503735f92bfb | 4 | === A test program for the auPower integrated power supply board === |
| Kir | 0:503735f92bfb | 5 | |
| Kir | 0:503735f92bfb | 6 | The auPower power fusion board is a highly integrated complete power |
| Kir | 0:503735f92bfb | 7 | solution designed specifically for micro-UAV / RC applications. |
| Kir | 0:503735f92bfb | 8 | |
| Kir | 0:503735f92bfb | 9 | The board's i2c interface need to be connected to the PTE0 and PTE1 ports |
| Kir | 0:503735f92bfb | 10 | of the Freescale device |
| Kir | 0:503735f92bfb | 11 | |
| Kir | 0:503735f92bfb | 12 | For more information, please visit our web-site: |
| Kir | 0:503735f92bfb | 13 | ***************************** |
| Kir | 0:503735f92bfb | 14 | * http://aupilot.com.au * |
| Kir | 0:503735f92bfb | 15 | ***************************** |
| Kir | 0:503735f92bfb | 16 | |
| Kir | 0:503735f92bfb | 17 | License: |
| Kir | 0:503735f92bfb | 18 | |
| Kir | 0:503735f92bfb | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy |
| Kir | 0:503735f92bfb | 20 | of this software and associated documentation files (the "Software"), to deal |
| Kir | 0:503735f92bfb | 21 | in the Software without restriction, including without limitation the rights |
| Kir | 0:503735f92bfb | 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| Kir | 0:503735f92bfb | 23 | copies of the Software, and to permit persons to whom the Software is |
| Kir | 0:503735f92bfb | 24 | furnished to do so, subject to the following conditions: |
| Kir | 0:503735f92bfb | 25 | |
| Kir | 0:503735f92bfb | 26 | The above copyright notice and this permission notice shall be included in |
| Kir | 0:503735f92bfb | 27 | all copies or substantial portions of the Software. |
| Kir | 0:503735f92bfb | 28 | |
| Kir | 0:503735f92bfb | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| Kir | 0:503735f92bfb | 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| Kir | 0:503735f92bfb | 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| Kir | 0:503735f92bfb | 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| Kir | 0:503735f92bfb | 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| Kir | 0:503735f92bfb | 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| Kir | 0:503735f92bfb | 35 | THE SOFTWARE. |
| Kir | 0:503735f92bfb | 36 | */ |
| Kir | 0:503735f92bfb | 37 | |
| Kir | 0:503735f92bfb | 38 | #include "mbed.h" |
| Kir | 0:503735f92bfb | 39 | |
| Kir | 0:503735f92bfb | 40 | // device i2c address |
| Kir | 0:503735f92bfb | 41 | #define AUPOWER_I2C_ADDRESS 0xE6 |
| Kir | 0:503735f92bfb | 42 | |
| Kir | 0:503735f92bfb | 43 | // registers |
| Kir | 0:503735f92bfb | 44 | #define AUPOWER_REG_CTL1 0x0A |
| Kir | 0:503735f92bfb | 45 | #define AUPOWER_REG_CURRENT 0x00 |
| Kir | 0:503735f92bfb | 46 | #define AUPOWER_REG_VMAIN 0x02 |
| Kir | 0:503735f92bfb | 47 | #define AUPOWER_REG_VSPARE 0x06 |
| Kir | 0:503735f92bfb | 48 | #define AUPOWER_REG_TEMP 0x08 |
| Kir | 0:503735f92bfb | 49 | |
| Kir | 0:503735f92bfb | 50 | #define AUPOWER_LOW_SENS_MODE 0x01 // Low sensitivity mode (amlifier gain = 4x) |
| Kir | 0:503735f92bfb | 51 | #define AUPOWER_HIGH_SENS_MODE 0x02 // High sensitivity mode (amplifier gain = 8x) |
| Kir | 0:503735f92bfb | 52 | #define AUPOWER_RUN 0x07 // Start all sensors in fast-read mode, |
| Kir | 0:503735f92bfb | 53 | // sequentially updating every 2ms. |
| Kir | 0:503735f92bfb | 54 | |
| Kir | 0:503735f92bfb | 55 | /* |
| Kir | 0:503735f92bfb | 56 | There are two current sensing modes - low and high sensitivity. |
| Kir | 0:503735f92bfb | 57 | In the low sens. mode, the board can measure baypass current |
| Kir | 0:503735f92bfb | 58 | up to 220A, while in the high sensitivity mode, the max current |
| Kir | 0:503735f92bfb | 59 | is limited by 110A |
| Kir | 0:503735f92bfb | 60 | */ |
| Kir | 0:503735f92bfb | 61 | |
| Kir | 0:503735f92bfb | 62 | //#define AUPOWER_HIGH_SENS |
| Kir | 0:503735f92bfb | 63 | #undef AUPOWER_HIGH_SENS |
| Kir | 0:503735f92bfb | 64 | |
| Kir | 0:503735f92bfb | 65 | DigitalOut myled(LED1); |
| Kir | 0:503735f92bfb | 66 | Serial pc(USBTX, USBRX); |
| Kir | 0:503735f92bfb | 67 | I2C i2c(PTE0, PTE1); |
| Kir | 0:503735f92bfb | 68 | |
| Kir | 0:503735f92bfb | 69 | // protos |
| Kir | 0:503735f92bfb | 70 | int aupower_init(void); |
| Kir | 0:503735f92bfb | 71 | int aupower_read_sensors(uint8_t reg, float* fValue); |
| Kir | 0:503735f92bfb | 72 | int aupower_read_temperature(float* fValue); |
| Kir | 0:503735f92bfb | 73 | |
| Kir | 0:503735f92bfb | 74 | int main() |
| Kir | 0:503735f92bfb | 75 | { |
| Kir | 0:503735f92bfb | 76 | float temperature; |
| Kir | 0:503735f92bfb | 77 | float voltageMainBattery; |
| Kir | 0:503735f92bfb | 78 | float voltageSpareBattery; |
| Kir | 0:503735f92bfb | 79 | float bypassCurrent; |
| Kir | 0:503735f92bfb | 80 | |
| Kir | 0:503735f92bfb | 81 | #ifdef AUPOWER_HIGH_SENS |
| Kir | 0:503735f92bfb | 82 | pc.printf("\n\r\n\rTest program for auPower board, high sensitivity mode\n\r"); |
| Kir | 0:503735f92bfb | 83 | #else |
| Kir | 0:503735f92bfb | 84 | pc.printf("\n\r\n\rTest program for auPower board, low sensitivity mode\n\r"); |
| Kir | 0:503735f92bfb | 85 | #endif |
| Kir | 0:503735f92bfb | 86 | |
| Kir | 0:503735f92bfb | 87 | if (aupower_init() != 0 ) { |
| Kir | 0:503735f92bfb | 88 | pc.printf("\n\rInit Error!"); |
| Kir | 0:503735f92bfb | 89 | for(;;); // halt |
| Kir | 0:503735f92bfb | 90 | } |
| Kir | 0:503735f92bfb | 91 | |
| Kir | 0:503735f92bfb | 92 | while(1) { |
| Kir | 0:503735f92bfb | 93 | myled = 0; |
| Kir | 0:503735f92bfb | 94 | wait(0.1); |
| Kir | 0:503735f92bfb | 95 | myled = 1; |
| Kir | 0:503735f92bfb | 96 | |
| Kir | 0:503735f92bfb | 97 | // read temperature |
| Kir | 0:503735f92bfb | 98 | if (aupower_read_temperature(&temperature) != 0 ) |
| Kir | 0:503735f92bfb | 99 | pc.printf("\n\rError reading temperature"); |
| Kir | 0:503735f92bfb | 100 | |
| Kir | 0:503735f92bfb | 101 | if (aupower_read_sensors(AUPOWER_REG_VMAIN, &voltageMainBattery) != 0 ) |
| Kir | 0:503735f92bfb | 102 | pc.printf("\n\rError reading Main Battery Voltage"); |
| Kir | 0:503735f92bfb | 103 | |
| Kir | 0:503735f92bfb | 104 | if (aupower_read_sensors(AUPOWER_REG_VSPARE, &voltageSpareBattery) != 0 ) |
| Kir | 0:503735f92bfb | 105 | pc.printf("\n\rError reading Spare Battery Voltage"); |
| Kir | 0:503735f92bfb | 106 | |
| Kir | 0:503735f92bfb | 107 | if (aupower_read_sensors(AUPOWER_REG_CURRENT, &bypassCurrent) != 0 ) |
| Kir | 0:503735f92bfb | 108 | pc.printf("\n\rError reading Bypass Current"); |
| Kir | 0:503735f92bfb | 109 | |
| Kir | 0:503735f92bfb | 110 | |
| Kir | 0:503735f92bfb | 111 | pc.printf("\n\rTemper (deg C): %.2f, Main Bat (V): %.2f, Spare Bat (V): %.2f, Current (mA): %.0f", |
| Kir | 0:503735f92bfb | 112 | temperature, |
| Kir | 0:503735f92bfb | 113 | voltageMainBattery, |
| Kir | 0:503735f92bfb | 114 | voltageSpareBattery, |
| Kir | 0:503735f92bfb | 115 | bypassCurrent); |
| Kir | 0:503735f92bfb | 116 | wait(2.0); |
| Kir | 0:503735f92bfb | 117 | |
| Kir | 0:503735f92bfb | 118 | } |
| Kir | 0:503735f92bfb | 119 | } |
| Kir | 0:503735f92bfb | 120 | |
| Kir | 0:503735f92bfb | 121 | // reads 2 bytes from a register of an i2c device |
| Kir | 0:503735f92bfb | 122 | // return: rd[2] data read from register |
| Kir | 0:503735f92bfb | 123 | // return: 0 if OK, -1 otherwise |
| Kir | 0:503735f92bfb | 124 | int i2c_reg16_read(int i2c_address, char reg, char* rd) |
| Kir | 0:503735f92bfb | 125 | { |
| Kir | 0:503735f92bfb | 126 | if (i2c.write(i2c_address, ®, 1, true) == 0) // "true" means don't send stop condition |
| Kir | 0:503735f92bfb | 127 | if (i2c.read(i2c_address, rd, 2) == 0) |
| Kir | 0:503735f92bfb | 128 | return 0; |
| Kir | 0:503735f92bfb | 129 | return -1; |
| Kir | 0:503735f92bfb | 130 | } |
| Kir | 0:503735f92bfb | 131 | |
| Kir | 0:503735f92bfb | 132 | // writes 1 byte to a register on a i2c device |
| Kir | 0:503735f92bfb | 133 | // return: 0 if OK, -1 otherwise |
| Kir | 0:503735f92bfb | 134 | int i2c_reg8_write(int i2c_address, char reg, const char wd) |
| Kir | 0:503735f92bfb | 135 | { |
| Kir | 0:503735f92bfb | 136 | char data[2]; |
| Kir | 0:503735f92bfb | 137 | data[0] = reg; |
| Kir | 0:503735f92bfb | 138 | data[1] = wd; |
| Kir | 0:503735f92bfb | 139 | if (i2c.write(i2c_address, &data[0], 2, false) == 0) |
| Kir | 0:503735f92bfb | 140 | return 0; |
| Kir | 0:503735f92bfb | 141 | return -1; |
| Kir | 0:503735f92bfb | 142 | } |
| Kir | 0:503735f92bfb | 143 | |
| Kir | 0:503735f92bfb | 144 | // start the monitor unit (continiusly reading all sensors) |
| Kir | 0:503735f92bfb | 145 | int aupower_init(void) |
| Kir | 0:503735f92bfb | 146 | { |
| Kir | 0:503735f92bfb | 147 | // we can use the initial value of the temperature as a whoami - must be 0x80 on power-on reset before |
| Kir | 0:503735f92bfb | 148 | // initialisation, but could be arbitary after init |
| Kir | 0:503735f92bfb | 149 | |
| Kir | 0:503735f92bfb | 150 | /* |
| Kir | 0:503735f92bfb | 151 | char data[2]; |
| Kir | 0:503735f92bfb | 152 | if (i2c_reg16_read(AUPOWER_I2C_ADDRESS, AUPOWER_REG_TEMP, data) !=0 ) |
| Kir | 0:503735f92bfb | 153 | return -1; |
| Kir | 0:503735f92bfb | 154 | if (data[0] != 0x80) |
| Kir | 0:503735f92bfb | 155 | return -2; // wrong monitor unit |
| Kir | 0:503735f92bfb | 156 | */ |
| Kir | 0:503735f92bfb | 157 | |
| Kir | 0:503735f92bfb | 158 | // initialise the measurement unit |
| Kir | 0:503735f92bfb | 159 | |
| Kir | 0:503735f92bfb | 160 | #ifdef AUPOWER_HIGH_SENS |
| Kir | 0:503735f92bfb | 161 | // high sensitivity, 80A max |
| Kir | 0:503735f92bfb | 162 | if (i2c_reg8_write(AUPOWER_I2C_ADDRESS,AUPOWER_REG_CTL1,AUPOWER_HIGH_SENS_MODE) != 0) |
| Kir | 0:503735f92bfb | 163 | return -1; |
| Kir | 0:503735f92bfb | 164 | #else |
| Kir | 0:503735f92bfb | 165 | // OR low sensitivity, 120A max |
| Kir | 0:503735f92bfb | 166 | if (i2c_reg8_write(AUPOWER_I2C_ADDRESS,AUPOWER_REG_CTL1,AUPOWER_LOW_SENS_MODE) != 0) |
| Kir | 0:503735f92bfb | 167 | return -1; |
| Kir | 0:503735f92bfb | 168 | #endif |
| Kir | 0:503735f92bfb | 169 | |
| Kir | 0:503735f92bfb | 170 | // start ADC fast-read mode |
| Kir | 0:503735f92bfb | 171 | return i2c_reg8_write(AUPOWER_I2C_ADDRESS,AUPOWER_REG_CTL1,AUPOWER_RUN); |
| Kir | 0:503735f92bfb | 172 | } |
| Kir | 0:503735f92bfb | 173 | |
| Kir | 0:503735f92bfb | 174 | // read the sensors and convert ADC units to si |
| Kir | 0:503735f92bfb | 175 | int aupower_read_sensors(uint8_t sensor, float* fValue) |
| Kir | 0:503735f92bfb | 176 | { |
| Kir | 0:503735f92bfb | 177 | int16_t tmp1, tmp2; |
| Kir | 0:503735f92bfb | 178 | char data[2]; |
| Kir | 0:503735f92bfb | 179 | float tmp3; |
| Kir | 0:503735f92bfb | 180 | |
| Kir | 0:503735f92bfb | 181 | if (i2c_reg16_read(AUPOWER_I2C_ADDRESS, sensor, data) !=0 ) |
| Kir | 0:503735f92bfb | 182 | return -1; |
| Kir | 0:503735f92bfb | 183 | |
| Kir | 0:503735f92bfb | 184 | tmp1 = (int16_t)data[0]<<4; |
| Kir | 0:503735f92bfb | 185 | tmp2 = (int16_t)(data[1]&0xf0)>>4; |
| Kir | 0:503735f92bfb | 186 | tmp3 = (float)(tmp1+tmp2); |
| Kir | 0:503735f92bfb | 187 | |
| Kir | 0:503735f92bfb | 188 | if (sensor == AUPOWER_REG_CURRENT) |
| Kir | 0:503735f92bfb | 189 | #ifdef AUPOWER_HIGH_SENS |
| Kir | 0:503735f92bfb | 190 | *fValue = (tmp3-38)*24.69; |
| Kir | 0:503735f92bfb | 191 | #else |
| Kir | 0:503735f92bfb | 192 | *fValue = (tmp3-18)*49.37; |
| Kir | 0:503735f92bfb | 193 | #endif |
| Kir | 0:503735f92bfb | 194 | if (sensor == AUPOWER_REG_VMAIN) |
| Kir | 0:503735f92bfb | 195 | *fValue = tmp3*0.01427; |
| Kir | 0:503735f92bfb | 196 | if (sensor == AUPOWER_REG_VSPARE) |
| Kir | 0:503735f92bfb | 197 | *fValue = tmp3*0.005404; |
| Kir | 0:503735f92bfb | 198 | |
| Kir | 0:503735f92bfb | 199 | return 0; |
| Kir | 0:503735f92bfb | 200 | } |
| Kir | 0:503735f92bfb | 201 | |
| Kir | 0:503735f92bfb | 202 | // read the temperature sensor and convert to degrees C |
| Kir | 0:503735f92bfb | 203 | int aupower_read_temperature(float* fValue) |
| Kir | 0:503735f92bfb | 204 | { |
| Kir | 0:503735f92bfb | 205 | int16_t tmp1, tmp2; |
| Kir | 0:503735f92bfb | 206 | char data[2]; |
| Kir | 0:503735f92bfb | 207 | |
| Kir | 0:503735f92bfb | 208 | if (i2c_reg16_read(AUPOWER_I2C_ADDRESS, AUPOWER_REG_TEMP, data) !=0 ) |
| Kir | 0:503735f92bfb | 209 | return -1; |
| Kir | 0:503735f92bfb | 210 | |
| Kir | 0:503735f92bfb | 211 | tmp1 = (int16_t)data[0]<<1; |
| Kir | 0:503735f92bfb | 212 | tmp2 = (int16_t)(data[1]&0x80)>>7; |
| Kir | 0:503735f92bfb | 213 | *fValue = (tmp1+tmp2) * 0.48; |
| Kir | 0:503735f92bfb | 214 | |
| Kir | 0:503735f92bfb | 215 | return 0; |
| Kir | 0:503735f92bfb | 216 | } |
| Kir | 0:503735f92bfb | 217 |