Home › Forums › Environmental Sensors › MayFly Capability with Northern Widget Walrus Sensor › Reply To: MayFly Capability with Northern Widget Walrus Sensor
2020-10-29 at 1:50 PM
#14748
Ok, here’s new code for the Mayfly. This should be much more verbose and show more clearly if the sensor’s responding.
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
#include <Arduino.h> #include <Wire.h> #define DEVICE_I2C_ADDRESS \ 0x4D // I *think* this is the address it's using for itself // https://github.com/NorthernWidget-Skunkworks/Project-Walrus/blob/b5d9cc1fdfe2cf16fb5048a1f9ff0b27253c3a94/Firmware/Walrus_I2C_5BA/Walrus_I2C_5BA.ino#L155 // A helpful union for flipping between bytes to longs typedef union leFrame { byte Byte[4]; // 4 bytes will occupy 4 bytes uint32_t uInt32; // a single float occupies 4 bytes } leFrame; void setup() { Wire.begin(); // join i2c bus (address optional for master) Serial.begin(9600); // start serial for output // NOTE: Something may have to happen here to "start the thing up" // I can't tell if they intend that or not } void loop() { // The control register (0x00) has the bottom two bits as the update rate // and the top bit as the ready flag // update rate options appear to be: // 0x00 - 5s // 0x01 - 10s // 0x02 - 60s // 0x03 - 300s (5 min) // As far as I can tell, if not set it *should* be on 5s uint8_t attempts = 1; byte control_flag = 0; while (control_flag == 0 && attempts <= 10) { Wire.beginTransmission( DEVICE_I2C_ADDRESS); // select device with "beginTransmission()" Wire.write(0x00); // select starting register with "write()" Wire.write(0x01); // write the bottom bit to the fastest update rate Wire.endTransmission(); // end write operation, as we just wanted to // select the starting register Wire.requestFrom(DEVICE_I2C_ADDRESS, 1); // select number of bytes to get from the device // give it half-a-second to respond (this is WAY overkill for the I2C // specs) uint32_t start = millis(); while (!Wire.available() && millis() - start < 500) {} if (Wire.available()) { byte control_reg = Wire.read(); control_flag = bitRead(control_flag, 7); Serial.print("Got response from Walrus. Current state: "); Serial.println(control_flag); } else { Serial.print("Attempt "); Serial.print(attempts); Serial.println(" got no response from Walrus."); attempts++; } } if (attempts == 10) { Serial.println("Got now response from Walrus after 10 attempts."); Serial.println("Is the sensor powered at 3.3V?"); Serial.println("Are the I2C pins connected correctly? Try reversing " "them if you're not sure."); Serial.println("Retrying in 30 seconds."); delay(30000L); return; } // We'll try reading all the registers at once sequentially instead of // reading one after the other // the registers are loaded starting on line 242: // https://github.com/NorthernWidget-Skunkworks/Project-Walrus/blob/master/Firmware/Walrus_I2C_5BA/Walrus_I2C_5BA.ino#L242 Wire.beginTransmission( DEVICE_I2C_ADDRESS); // select device with "beginTransmission()" Wire.write(0x02); // select starting register with "write()" // the first data register is pressure starting in register 0x02 Wire.endTransmission(); // end write operation, as we just wanted to select // the starting register // select number of bytes to get from the device // + 4 for pressure in microbars (ie mbar*1000) // + 4 for temp0 - This is the temperature from the MCP9808 (*10000.0) // + 4 for temp1 - This is the temperature from the MS5803 (*10000.0) Wire.requestFrom(DEVICE_I2C_ADDRESS, 12); // We won't bother to read the next 8 bytes of unchanging sensor // information: // + 2 for model (uint16_t) // + 2 for group id (uint16_t) // + 2 for "INDID" ?dummy? (uint16_t) // + 2 for firmware id (uint16_t)) // my helpful union leFrame fram; // NOTE: may need to flop endinaness for the values. // if getting garbage, try switching all for loops to // 'for (int8_t i = 0; i<4; i++)' // get pressure from the first 4 bytes, reversing order/endianness Serial.println("\nreading pressure..."); fram.uInt32 = 0; for (int8_t i = 4; i; i--) { fram.Byte[i] = Wire.read(); Serial.print("Byte "); Serial.print(i); Serial.print(": "); Serial.println(fram.Byte[i]); } Serial.print("uint32_t: "); Serial.println(fram.uInt32); float pressure = fram.uInt32 / 1000; Serial.println(); // get MCP9808 temp from the next 4 bytes, reversing order/endianness Serial.println("reading pressure..."); fram.uInt32 = 0; for (int8_t i = 4; i; i--) { fram.Byte[i] = Wire.read(); Serial.print("Byte "); Serial.print(i); Serial.print(": "); Serial.println(fram.Byte[i]); } Serial.print("uint32_t: "); Serial.println(fram.uInt32); float temp_mcp9808 = fram.uInt32 / 10000; Serial.println(); // get MS5803 temp from the last 4 bytes, reversing order/endianness Serial.println("reading pressure..."); fram.uInt32 = 0; for (int8_t i = 4; i; i--) { fram.Byte[i] = Wire.read(); Serial.print("Byte "); Serial.print(i); Serial.print(": "); Serial.println(fram.Byte[i]); } Serial.print("uint32_t: "); Serial.println(fram.uInt32); float temp_ms5803 = fram.uInt32 / 10000; Serial.println(); // Serial.print the results Serial.print("MS5803 Pressure: "); Serial.print(pressure); Serial.println(" mbar"); Serial.print("MCP9808 Temperature: "); Serial.print(temp_mcp9808); Serial.println(" °C"); Serial.print("MS5803 Temperature: "); Serial.print(temp_ms5803); Serial.println(" °C"); // wait 5s and then repeat Serial.println("---"); delay(5000); } |