Home › Forums › Environmental Sensors › MayFly Capability with Northern Widget Walrus Sensor
Tagged: MS5803-02BA
- This topic has 39 replies, 2 voices, and was last updated 2020-11-02 at 12:22 PM by Tom Schanandore.
-
AuthorPosts
-
-
2020-10-28 at 3:46 PM #14726
Hello,
I have been working a company called Northern Widget out of St. Paul Minnesota regarding their water pressure sensor named the Walrus. It is connected via. a I2C port and they say it should work on any basic Arduino based board at 3.3 to 5.5 volts. We had so much trouble getting it to work that we had to abandon using it. The sensor works when connected to the MayFly directly, but does not work when connected by the 3m cable.
I have connected a MPL115A pressure sensor and that works both directly connected and connected via. the 3m cable.
Has there been anyone else that has worked with Northern Widget on utilizing their sensors?
-
2020-10-28 at 4:47 PM #14727
Bobby Shultz or Northern Widget did some of the work to incorporate the MPL115A into ModularSensors, but I haven’t followed what they’ve been doing.
It looks like this Walrus thing has an on-board processor that in between the Mayfly and the MPL115A. So you need to use whatever protocol they’ve developed for themselves not the MPL’s I2C protocol. It looks like they have both I2C and RS485 firmware available and some instructions on how to upload the firmware to said on-board processor. Do you know which you have? Their demo code, true to it’s warning, is based on a library that doesn’t yet exist. Have you tried contacting Northern Widget directly to ask for help?
-
2020-10-28 at 4:56 PM #14728
Thanks Sara,
I have been working with Bobby and Andy Wickert over there on this and they gave me sensors with the appropriate firmware installed already. I did not have to install any firmware. It was just suppose to be hooked up and ready to work. I didn’t know if anyone in the community here was able to get a walrus sensor to work on the MayFly?
Honestly they have been unwilling to work that in depth with me on this and we are currently parting ways on the venture.
-
2020-10-29 at 8:21 AM #14729
Someone has to dig through their firmware file and reverse engineer the communication protocol.
-
2020-10-29 at 8:52 AM #14730
Honestly my understanding of all this is pretty basic, but I understand that the firmware is very important. I left it up to Northern Widget to upload the appropriate firmware to the sensor before they sent the sensors, so that that process would be streamlined. I did read through their documentation on the firmware and, as you stated before, they have two; I2C and RS485. I am pretty sure the one that is uploaded is the I2C. I am curious to see if the RS485 would work or if there would need to be some revision of the firmware somehow. They didn’t talk about trying different firmware.
Yes maybe someone else has tried this also and can comment.
Thanks Sara,
-
2020-10-29 at 9:50 AM #14731
I2C and RS485 are two different communication protocols. They specify what change marks a 1 or a 0 when transferring information. I2C also (mostly) specifies the question-and-answer format. So knowing you have I2C firmware gets you some of the way there, but not very far. You need to know what question to ask the board and what it’s response will be.
I’m guessing this is the firmware they gave you: https://github.com/NorthernWidget-Skunkworks/Project-Walrus/blob/master/Firmware/Walrus_I2C_5BA/Walrus_I2C_5BA.ino. That would be the program the microcontroller on the Walrus itself is running, not what the Mayfly needs to run to talk to it.
-
2020-10-29 at 9:55 AM #14732
I am assuming that the firmware also has something to do with making the sensor signal work over the length of the 3m cable? The sensor does work when attached directing to the I2C port (via. grove cable) on the Mayfly at 3.3v. That’s great, but as you know, I need to run that sensor into the stream.
-
2020-10-29 at 10:07 AM #14733
WRT to the wire distance, yes and no.
RS485 is a two-wire protocol where 0’s and 1’s are differentiated by the difference in voltage between the two wires. Electrically, this means it can be used over long distances (ie, up to 4,000 feet). To use RS485 the processors that are talking each need to have their own internal clocks and each separately need to be told the speed at which they will send the bits and how many bits make up one letter. The processors also need to agree on a way to determine whose turn it is to talk and whose turn it is to listen. Modbus is a common choice, but there are many others.
I2C is also a two-wire protocol, but the 0’s and 1’s are based on the voltage of a single wire and the second wire works as the clock. This configuration does not lend itself to long wires; I2C is usually used between chips on the same circuit board. It’s theoretical limit is only about 1m, but, as you’ve seen when using the MPL directly, 3m can sometimes be managed.
-
2020-10-29 at 10:19 AM #14734
I’m sorry, I’m looking through their firmware and trying to figure something out for you. I hate half-answering a question.
-
2020-10-29 at 10:26 AM #14735
post deleted
-
2020-10-29 at 10:27 AM #14736
Much appreciated. There are a few trouble shooting things that I did that may be difficult to explain over the forum. If you would like to discuss my phone is 701-390-2040. These trouble shooting thing did show some interesting results. Any help to get them to work would be great, since I have four ready to go that they sent and I was planning to deploy in the field this November. Been trouble shooting the sensor since August.
Thanks Sara,
-
2020-10-29 at 10:31 AM #14737
I only paid for the one, which was not housed. That one I will keep. The other four they just sent, without first figuring out the problem. If they don’t work I will simply send the four back. Yes, frustrating. Two months of not getting anywhere and now I need to make the decision to figure this out on my own or switch to a different sensor. Maybe something raw that I can house/encapsulate myself.
-
2020-10-29 at 11:28 AM #14739
Alright, here’s something. I can’t promise it *works*, but I’d like to see the results.
C++1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798#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 longstypedef union leFrame {byte Byte[4]; // 4 bytes will occupy 4 bytesuint32_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() {// It looks like the control register (0x00) is being set to 0x7F// (0b1111111) when values are being written (ie, values aren't ready) and// to 0x80 (0b10000000) when it's ready.// https://github.com/NorthernWidget-Skunkworks/Project-Walrus/blob/b5d9cc1fdfe2cf16fb5048a1f9ff0b27253c3a94/Firmware/Walrus_I2C_5BA/Walrus_I2C_5BA.ino#L242byte control_flag = 0x7f;while (control_flag == 0x7f) {Wire.beginTransmission(DEVICE_I2C_ADDRESS); // select device with "beginTransmission()"Wire.write(0x00); // select starting register with "write()"Wire.endTransmission(); // end write operation, as we just wanted to// select the starting registerWire.requestFrom(DEVICE_I2C_ADDRESS,1); // select number of bytes to get from the device// (1 byte in this case)control_flag = Wire.read(); // read from the starting register}// 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#L242Wire.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 0x02Wire.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 unionleFrame 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/endiannessfor (int8_t i = 4; i; i--) { fram.Byte[i] = Wire.read(); }float pressure = fram.uInt32 / 1000;// get MCP9808 temp from the next 4 bytes, reversing order/endiannessfor (int8_t i = 4; i; i--) { fram.Byte[i] = Wire.read(); }float temp_mcp9808 = fram.uInt32 / 10000;// get MS5803 temp from the last 4 bytes, reversing order/endiannessfor (int8_t i = 4; i; i--) { fram.Byte[i] = Wire.read(); }float temp_ms5803 = fram.uInt32 / 10000;// print the resultsSerial.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 repeatSerial.println("---");delay(5000);} -
2020-10-29 at 11:43 AM #14740
I am assuming that this is a firmware to be uploaded to the sensor?
-
2020-10-29 at 12:17 PM #14741
No, no, that’s for a Mayfly talking to a sensor with the firmware Northern Widget posted on GitHub.
-
2020-10-29 at 12:23 PM #14742
I see. Do I simply upload to the mayfly with the sensor attached? Or is this code to be added in somewhere in my overall code (PlatformIO)?
-
2020-10-29 at 12:25 PM #14743
That’s the full code, you should upload it to the mayfly with the sensor powered and attached to the I2C on the Mayfly. Then start a serial terminal at 9600 and you should see output.
-
2020-10-29 at 1:23 PM #14744
-
2020-10-29 at 1:25 PM #14746
It’s reading something, which is a lot better than before, as it read nothing before.
-
2020-10-29 at 1:47 PM #14747
No, it’s just *printing* something. I don’t think the sensor’s responding.
-
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++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159#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 longstypedef union leFrame {byte Byte[4]; // 4 bytes will occupy 4 bytesuint32_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 5suint8_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 rateWire.endTransmission(); // end write operation, as we just wanted to// select the starting registerWire.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#L242Wire.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 0x02Wire.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 unionleFrame 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/endiannessSerial.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/endiannessSerial.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/endiannessSerial.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 resultsSerial.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 repeatSerial.println("---");delay(5000);} -
2020-10-29 at 2:03 PM #14749
If (when) that fails, you can try an I2C scanner program on the Mayfly to see if the sensor has a different address.
-
2020-10-29 at 2:19 PM #14750
Also try flipping the SCL and SDA pins if you’re getting nothing. Some versions of the Mayfly had them labeled backwards.
Also on a Mayfly you should always be finding a device at 0x48 and at 0x68. Those are the clock and the extra ADC. If the Walrus is responding, it should show up as a third device.
Scanner code for the Mayfly:
Arduino12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152// This sketch tests the standard 7-bit addresses// Devices with higher bit address might not be seen properly.//#include <Arduino.h>#include <Wire.h>void scan() {byte error, address;int nDevices;nDevices = 0;for (address = 1; address < 127; address++) {// The i2c_scanner uses the return value of// the Write.endTransmisstion to see if// a device did acknowledge to the address.Wire.beginTransmission(address);error = Wire.endTransmission();if (error == 0) {Serial.print(" I2C device found at address 0x");if (address < 16) Serial.print("0");Serial.print(address, HEX);Serial.println(" !");nDevices++;} else if (error == 4) {Serial.print(" Unknown error at address 0x");if (address < 16) Serial.print("0");Serial.println(address, HEX);}}if (nDevices == 0) Serial.println("No I2C devices found");}void setup() {pinMode(22, OUTPUT);Serial.begin(9600);Serial.println("\nI2C Scanner");digitalWrite(22, HIGH);Wire.begin();}void loop() {Serial.println("Hardware I2C Objects:");scan();delay(5000); // wait 5 seconds for next scan} -
2020-10-29 at 3:04 PM #14751
Ran the second bit of code and the scanner code. The scanner codes serial output is at the end.
See attached
Attachments:
-
2020-10-29 at 5:31 PM #14754
So it is there and responding, but there’s something wrong with my code because it’s not giving data. Do you know if the firmware on your device *is* that code on github? Otherwise, I don’t see in that code what I have to do to get it to start reporting values.
-
2020-10-30 at 9:27 AM #14758
I’m sorry; I’ve spent a lot of time reading through that firmware and if there’s something you have to do to get it to start taking readings, I don’t know what it is. So either I’m just not understanding the firmware or that’s not the firmware that’s actually on your device. I don’t think there’s any other way I can help you if you cannot get a summary of the commands and registers from Northern Widget. The problem is definitely NOT your Mayfly.
-
2020-10-30 at 9:34 AM #14759
I will contact Northern Widget to see if they will send the firmware that they uploaded for verification on this end.
-
2020-10-30 at 10:35 AM #14760
You don’t need the whole firmware; actually I’d prefer not to get the firmware, but instead to get a short breakdown of the required I2C registers and commands. All I would be doing with the full firmware is trying to decode what the registers are anyway.
-
2020-11-02 at 8:00 AM #14762
See the link below to the firmware that they say is on the sensor. It is probably the same firmware you are looking at. I am requesting also the I2C registers and commands.
https://github.com/NorthernWidget-Skunkworks/Project-Walrus/tree/master/Firmware/Walrus_I2C_5BA
-
2020-11-02 at 10:44 AM #14763
That’s the firmware I’ve been looking at.
You know what, I don’t think this firmware even functional. It won’t ever take a sample. Well, it should sample 1 time at the beginning, and then never again. Ugh. I wasted a lot of time parsing the I2C bits of the firmware and writing code for you and didn’t ever question that that sampling part of the firmware worked. I’m pretty sure it doesn’t.
I created an issue on GitHub for them: https://github.com/NorthernWidget-Skunkworks/Project-Walrus/issues/14. Basically, every 100ms the firmware sets a timeout value and then immediately after setting the value, checks if the same value is more than 5 seconds old. But, obviously, since it just set that value, the value will never be more than a few ticks old and the “start sampling” flag will never, ever be set to true.
So.. yeah, you need them to write and give you new firmware. And, then you need to figure out how to write said firmware onto your sensor. They have instructions on how to do that here: https://github.com/NorthernWidget-Skunkworks/Project-Walrus#upload-the-firmware, but you need an ISP of some sort. I don’t even have one of those.
It’s still not clear to me why it’s not sampling exactly one time when first booted up, but I don’t think it’s worth anyone spending any more time with it until you’ve been given new firmware and a way to program it.
-
2020-11-02 at 11:02 AM #14764
Is there anything strange about the fact that the walrus sensor does output good values when I have it connected directly (via grove connector) to the MayFly? And of course it is only when I connect it via the 3m cable that the values do not output.
It sounds as if Northern Widget is not willing at this time to do any more trouble shooting with me, so this may be the end of the line with the sensor. It’s just to bad, since I was ready to deploy these and the MayFly is working great with the barometric sensor I was deploying as well.
Thank you for all the help and I’ll let you know what happens on this.
-
2020-11-02 at 11:12 AM #14765
Does it output good value*S* or one single good value over and over? If the former, then..I just don’t know how to read this firmware. If the latter, then, no that’s what I expect.
3m is beyond the maximum expected transmission length for I2C, so, no, it’s not at all strange that it wouldn’t work over that long a distance. If you need that distance, you need to use RS485 or some other protocol. I2C is only really intended to work across very short distances. The limitation is based on the voltage ranges and the amount of signal loss over real wires. You might get lucky with some cables and configurations, but you shouldn’t expect it. RS485 can travel much farther because the voltage differences between the wires is much larger.
-
-
2020-11-02 at 11:17 AM #14766
They are good values and slightly vary. I have verified the output with the MPL115A2 sensor that I have and the values are the same.
They said that the 3m cable works great with their data loggers on I2C protocol, but yes it would make sense to use an RS485 to just be sure that the signal won’t be lost over the length.
-
2020-11-02 at 11:26 AM #14768
What code are you running to get the values? The results you shared with me based on the code I gave you didn’t have any good values at all. I thought you didn’t have any working code for communication.
-
2020-11-02 at 11:33 AM #147691234567891011121314151617181920212223242526// Include the Walrus library#include "Walrus_I2C.h"// Declare variables -- just as stringsString header;String data;// Instantiate classWalrus myWalrus;void setup(){// Begin Serial connection to computer at 38400 baudSerial.begin(38400);// Obtain the header just onceheader = myWalrus.getHeader();// Print the header to the serial monitorSerial.println(header);}void loop(){// Take one reading every (10 + time to take reading) secondsdata = myWalrus.getString();// and print it to the screenSerial.println(data);delay(10000); // Wait 10 seconds before the next reading, inefficiently}
-
2020-11-02 at 11:35 AM #14770
The previous is the code that they gave me to begin with. It does work when directly connected to the MayFly and Arduino Uno. IT does also work on the Arduino Uno (5v) when using the 3m cable.
-
2020-11-02 at 11:46 AM #14772
You had a working library and code this whole time.
?!?
Well I feel really, really stupid.
-
2020-11-02 at 12:02 PM #14773
I apologize for not saying that from the get go. My knowledge with all of this is rather limited, to be honest. I thought you were just trying to talk between the Sensor and the MayFly. The current library that I am using is on GitHub at <https://github.com/NorthernWidget-Skunkworks/Walrus_Library>
-
2020-11-02 at 12:17 PM #14774
<!–more–>Yeah, so 99.99% of what I’ve said on this thread can be completely disregarded. Obviously the sensor and firmware work just fine and there never was any problem with them. The biggest problem was my understanding of the problem.
If everything is perfect except the 3m cable, then it’s just the 3m length that is the problem. It’s apparently too far for I2C at 3.3V. Signal doesn’t travel forever over real wires. Larger voltage differences can help signals to travel farther. An Uno or other 5V Arduino has an extra 1.7V range the Mayfly doesn’t have. The operating voltage of the Mayfly cannot be changed.
-
2020-11-02 at 12:22 PM #14775
So I think that I’m out of luck on this sensor, based upon what you just said. I’ll have to abandon this sensor.
thank you for all your help and sorry again for the miscommunication.
-
-
AuthorPosts
- You must be logged in to reply to this topic.