Jon Freeman / Mbed 2 deprecated Alternator2020_06

Dependencies:   mbed BufferedSerial Servo2 PCT2075 I2CEeprom FastPWM

Committer:
JonFreeman
Date:
Sat Dec 05 12:40:17 2020 +0000
Revision:
5:6ca3e7ffc553
Parent:
3:43cb067ecd00
Code for 'Smart Regulator' to August 2020, published as is. Basic low-level functions all thoroughly tested and debugged, top level algorithms have scope for further development - over to you! For help contact jon @ jons-workshop[.com

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JonFreeman 3:43cb067ecd00 1 #ifdef INC_BARO
JonFreeman 3:43cb067ecd00 2
JonFreeman 3:43cb067ecd00 3 #include "mbed.h"
JonFreeman 3:43cb067ecd00 4 #include "baro.h"
JonFreeman 3:43cb067ecd00 5 #include "BufferedSerial.h"
JonFreeman 3:43cb067ecd00 6
JonFreeman 3:43cb067ecd00 7 //BufferedSerial pc (PA_2, PA_3, 512, 4, NULL); // Pins 16, 17 tx, rx to pc via usb lead
JonFreeman 3:43cb067ecd00 8 //I2C i2c (PB_7, PB_6); // Pins 58, 59 For 24LC64 eeprom
JonFreeman 3:43cb067ecd00 9 extern BufferedSerial pc;
JonFreeman 3:43cb067ecd00 10 extern I2C i2c;
JonFreeman 3:43cb067ecd00 11 const int ACK = 1;
JonFreeman 3:43cb067ecd00 12 const int NAK = 0;
JonFreeman 3:43cb067ecd00 13 const int NOM_PASCALS = 100000;
JonFreeman 3:43cb067ecd00 14 const int HYSTERESIS_PASCALS = 50;
JonFreeman 3:43cb067ecd00 15
JonFreeman 3:43cb067ecd00 16 MPL3115A2::MPL3115A2 () { // Constructor
JonFreeman 3:43cb067ecd00 17 good = true;
JonFreeman 3:43cb067ecd00 18 // mode = 0x39; // continuous convert
JonFreeman 3:43cb067ecd00 19 mode = 0x38; // one shot
JonFreeman 3:43cb067ecd00 20 Temp = Pres = Alti = Adju = 0.0;
JonFreeman 3:43cb067ecd00 21 if (!RegRd (0x0c, 1, dest))
JonFreeman 3:43cb067ecd00 22 good = false;
JonFreeman 3:43cb067ecd00 23 else if (dest[0] != 196)
JonFreeman 3:43cb067ecd00 24 good = false;
JonFreeman 3:43cb067ecd00 25 }
JonFreeman 3:43cb067ecd00 26
JonFreeman 3:43cb067ecd00 27 bool MPL3115A2::busy_check () {
JonFreeman 3:43cb067ecd00 28 char c;
JonFreeman 3:43cb067ecd00 29 RegRd (0x26, 1, &c);
JonFreeman 3:43cb067ecd00 30 c &= 2;
JonFreeman 3:43cb067ecd00 31 if (c == 0)
JonFreeman 3:43cb067ecd00 32 return false; // free, i.e. not busy
JonFreeman 3:43cb067ecd00 33 return true; // busy, conversion in progress
JonFreeman 3:43cb067ecd00 34 }
JonFreeman 3:43cb067ecd00 35
JonFreeman 3:43cb067ecd00 36 void MPL3115A2::reset_zero_inHg () {
JonFreeman 3:43cb067ecd00 37 double tmp;
JonFreeman 3:43cb067ecd00 38 Adju = 0.0;
JonFreeman 3:43cb067ecd00 39 tmp = inHg_vacuum (); // sets Adju
JonFreeman 3:43cb067ecd00 40 Adju = tmp;
JonFreeman 3:43cb067ecd00 41 }
JonFreeman 3:43cb067ecd00 42 double MPL3115A2::Temperature () { return Temp; }
JonFreeman 3:43cb067ecd00 43 double MPL3115A2::Pressure () { return Pres; }
JonFreeman 3:43cb067ecd00 44 double MPL3115A2::Altitude () { return Alti; }
JonFreeman 3:43cb067ecd00 45 double MPL3115A2::inHg_vacuum () {
JonFreeman 3:43cb067ecd00 46 double inHg = 0.0 - Pres; // one atmospheres worth of Pascals. Note 1 bar is not the same, 1 bar = 100000 Pa
JonFreeman 3:43cb067ecd00 47 inHg *= 0.000295299833;
JonFreeman 3:43cb067ecd00 48 return inHg - Adju;
JonFreeman 3:43cb067ecd00 49 }
JonFreeman 3:43cb067ecd00 50 void MPL3115A2::mode_alti () {
JonFreeman 3:43cb067ecd00 51 // mode = 0xb9;
JonFreeman 3:43cb067ecd00 52 mode = 0xb8;
JonFreeman 3:43cb067ecd00 53 }
JonFreeman 3:43cb067ecd00 54 void MPL3115A2::mode_pres () {
JonFreeman 3:43cb067ecd00 55 // mode = 0x39;
JonFreeman 3:43cb067ecd00 56 mode = 0x38;
JonFreeman 3:43cb067ecd00 57 }
JonFreeman 3:43cb067ecd00 58 /*********************************************************\
JonFreeman 3:43cb067ecd00 59 * IIC Write Register
JonFreeman 3:43cb067ecd00 60 \*********************************************************/
JonFreeman 3:43cb067ecd00 61 bool MPL3115A2::RegWr (int reg, char val)
JonFreeman 3:43cb067ecd00 62 {
JonFreeman 3:43cb067ecd00 63 bool rv = true;
JonFreeman 3:43cb067ecd00 64 i2c.start ();
JonFreeman 3:43cb067ecd00 65 if (i2c.write (0xc0) != ACK) rv = false; // Returns '0' - NAK was received '1' - ACK was received, '2' - timeout
JonFreeman 3:43cb067ecd00 66 if (i2c.write (reg) != ACK) rv = false;
JonFreeman 3:43cb067ecd00 67 if (i2c.write (val) != ACK) rv = false;
JonFreeman 3:43cb067ecd00 68 i2c.stop ();
JonFreeman 3:43cb067ecd00 69 return rv;
JonFreeman 3:43cb067ecd00 70 }
JonFreeman 3:43cb067ecd00 71
JonFreeman 3:43cb067ecd00 72 /*********************************************************\
JonFreeman 3:43cb067ecd00 73 * IIC Read One Or More Registers into array
JonFreeman 3:43cb067ecd00 74 \*********************************************************/
JonFreeman 3:43cb067ecd00 75 bool MPL3115A2::RegRd (int reg1, int len, char *array)
JonFreeman 3:43cb067ecd00 76 {
JonFreeman 3:43cb067ecd00 77 int acknak;
JonFreeman 3:43cb067ecd00 78 bool rv = true;
JonFreeman 3:43cb067ecd00 79 i2c.start ();
JonFreeman 3:43cb067ecd00 80 if (i2c.write (0xc0) != ACK) rv = false; // Returns '0' - NAK was received '1' - ACK was received, '2' - timeout
JonFreeman 3:43cb067ecd00 81 if (i2c.write (reg1) != ACK) rv = false;
JonFreeman 3:43cb067ecd00 82 i2c.start (); // Send Repeat Start
JonFreeman 3:43cb067ecd00 83 if (i2c.write (0xc1) != ACK) rv = false;
JonFreeman 3:43cb067ecd00 84 acknak = ACK;
JonFreeman 3:43cb067ecd00 85 while (len > 0) { // Read Register Values
JonFreeman 3:43cb067ecd00 86 len--;
JonFreeman 3:43cb067ecd00 87 if (len == 0) acknak = NAK;
JonFreeman 3:43cb067ecd00 88 *array++ = i2c.read (acknak);
JonFreeman 3:43cb067ecd00 89 }
JonFreeman 3:43cb067ecd00 90 i2c.stop ();
JonFreeman 3:43cb067ecd00 91 return rv;
JonFreeman 3:43cb067ecd00 92 }
JonFreeman 3:43cb067ecd00 93
JonFreeman 3:43cb067ecd00 94 bool MPL3115A2::Update () { // Returns true on apparent success
JonFreeman 3:43cb067ecd00 95 bool rv = true;
JonFreeman 3:43cb067ecd00 96 int32_t ta;
JonFreeman 3:43cb067ecd00 97 if (busy_check()) { // "User shall read the value of the OST bit before writing to this bit again." - done here.
JonFreeman 3:43cb067ecd00 98 pc.printf ("Call to Barometer Update while busy error\r\n");
JonFreeman 3:43cb067ecd00 99 return false; // Can not initiate new conversion, will not update Temp, Pres, Alti
JonFreeman 3:43cb067ecd00 100 }
JonFreeman 3:43cb067ecd00 101 Pres = Alti = -1.0; // Gives added clue if call to Update fails
JonFreeman 3:43cb067ecd00 102 if (!RegRd (1, 5, dest)) rv = false; // Read 3 pressure + 2 temperature registers, then kick-start new conversion
JonFreeman 3:43cb067ecd00 103 if (!RegWr (0x26, mode | 2)) rv = false; // bit 1 is OST one shot mode, bits 3-5 are 128x oversampling. This starts new conversion
JonFreeman 3:43cb067ecd00 104 if (!rv)
JonFreeman 3:43cb067ecd00 105 return false; // register read or write failed, Pres and Alti = -1.0 also
JonFreeman 3:43cb067ecd00 106 Temp = ((double) ((dest[3] << 4) | (dest[4] >> 4))) / 16.0; // Temperature
JonFreeman 3:43cb067ecd00 107 if (mode & 0x80) { // Altimeter mode
JonFreeman 3:43cb067ecd00 108 ta = (dest[0] << 24) | (dest[1] << 16) | ((dest[2] & 0xf0) << 8); // preserve sign bit
JonFreeman 3:43cb067ecd00 109 ta /= (1 << 12);
JonFreeman 3:43cb067ecd00 110 Alti = ((double) ta) / 16.0;
JonFreeman 3:43cb067ecd00 111 Pres = 0.0;
JonFreeman 3:43cb067ecd00 112 }
JonFreeman 3:43cb067ecd00 113 else { // Pressure mode
JonFreeman 3:43cb067ecd00 114 Pres = ((double) ((dest[0] << 12) | (dest[1] << 4) | (dest[2] >> 4))) / 4.0;
JonFreeman 3:43cb067ecd00 115 Alti = 0.0;
JonFreeman 3:43cb067ecd00 116 }
JonFreeman 3:43cb067ecd00 117 return true;
JonFreeman 3:43cb067ecd00 118 }
JonFreeman 3:43cb067ecd00 119
JonFreeman 3:43cb067ecd00 120
JonFreeman 3:43cb067ecd00 121 /*
JonFreeman 3:43cb067ecd00 122 int main()
JonFreeman 3:43cb067ecd00 123 {
JonFreeman 3:43cb067ecd00 124 double Pres, Alt, inHg, Heat;
JonFreeman 3:43cb067ecd00 125 i2c.frequency(400000); // Speed 400000 max.
JonFreeman 3:43cb067ecd00 126 class MPL3115A2 baro ;
JonFreeman 3:43cb067ecd00 127 int q; // Note address bits 3-1 to match addr pins on 24LC16 memory device
JonFreeman 3:43cb067ecd00 128 for (int i = 0; i < 255; i += 2) { // Search for devices at all possible i2c addresses
JonFreeman 3:43cb067ecd00 129 i2c.start();
JonFreeman 3:43cb067ecd00 130 wait_ms (1);
JonFreeman 3:43cb067ecd00 131 q = i2c.write(i); // may return error code 2 when no start issued
JonFreeman 3:43cb067ecd00 132 switch (q) {
JonFreeman 3:43cb067ecd00 133 case ACK:
JonFreeman 3:43cb067ecd00 134 pc.printf ("I2C device found at 0x%x\r\n", i);
JonFreeman 3:43cb067ecd00 135 case NAK: // Device not seen at this address
JonFreeman 3:43cb067ecd00 136 break;
JonFreeman 3:43cb067ecd00 137 case 2: // write reports timeout
JonFreeman 3:43cb067ecd00 138 pc.printf ("I2C Timeout at addr %2x\r\n", i);
JonFreeman 3:43cb067ecd00 139 break;
JonFreeman 3:43cb067ecd00 140 default:
JonFreeman 3:43cb067ecd00 141 pc.printf ("Unknown error %d in check_24LC64\r\n", q);
JonFreeman 3:43cb067ecd00 142 break;
JonFreeman 3:43cb067ecd00 143 }
JonFreeman 3:43cb067ecd00 144 }
JonFreeman 3:43cb067ecd00 145 i2c.stop();
JonFreeman 3:43cb067ecd00 146 baro.mode_pres ();
JonFreeman 3:43cb067ecd00 147 pc.printf ("baro good flag %s\r\n", baro.good ? "true":"false");
JonFreeman 3:43cb067ecd00 148 bool rv;
JonFreeman 3:43cb067ecd00 149 q = -3;
JonFreeman 3:43cb067ecd00 150 while(1) {
JonFreeman 3:43cb067ecd00 151 q++;
JonFreeman 3:43cb067ecd00 152 if (q == 0) baro.reset_zero_inHg();
JonFreeman 3:43cb067ecd00 153 myled = 1; // LED is ON
JonFreeman 3:43cb067ecd00 154 wait(0.3); // 200 ms
JonFreeman 3:43cb067ecd00 155 // pc.printf ("busy_check %s\r\n", baro.busy_check() ? "true":"false");
JonFreeman 3:43cb067ecd00 156 myled = 0; // LED is OFF
JonFreeman 3:43cb067ecd00 157 wait(0.8); // 1 sec
JonFreeman 3:43cb067ecd00 158 // pc.printf ("busy_check %s\r\n", baro.busy_check() ? "true":"false");
JonFreeman 3:43cb067ecd00 159 rv = baro.Update ();
JonFreeman 3:43cb067ecd00 160 Pres = baro.Pressure();
JonFreeman 3:43cb067ecd00 161 Alt = baro.Altitude();
JonFreeman 3:43cb067ecd00 162 inHg = baro.inHg_vacuum();
JonFreeman 3:43cb067ecd00 163 Heat = baro.Temperature();
JonFreeman 3:43cb067ecd00 164 const int NOM_PASCALS = 100000;
JonFreeman 3:43cb067ecd00 165 const int HYSTERESIS_PASCALS = 50;
JonFreeman 3:43cb067ecd00 166 if (Pres > (NOM_PASCALS + HYSTERESIS_PASCALS))
JonFreeman 3:43cb067ecd00 167 pump = 1;
JonFreeman 3:43cb067ecd00 168 if (Pres < (NOM_PASCALS - HYSTERESIS_PASCALS))
JonFreeman 3:43cb067ecd00 169 pump = 0;
JonFreeman 3:43cb067ecd00 170 // pc.printf ("Pres\t%.2f Pa\tAlt\t%.1f m\t%+000.1f inHg\tTemp\t%.1f C, %s\r\n", baro.Pressure(), baro.Altitude(), baro.inHg_vacuum (), baro.Temperature(), rv ? "true":"false");
JonFreeman 3:43cb067ecd00 171 pc.printf ("Pres\t%.2f Pa\tAlt\t%.1f m\t%+000.1f inHg\tTemp\t%.1f C, %s\r\n", Pres, Alt, inHg, Heat, rv ? "true":"false");
JonFreeman 3:43cb067ecd00 172 // rv = baro.Update ();
JonFreeman 3:43cb067ecd00 173 }
JonFreeman 3:43cb067ecd00 174 }
JonFreeman 3:43cb067ecd00 175 */
JonFreeman 3:43cb067ecd00 176 #endif