Mares Nemo - Iris Serial Protocol
Warning! This is not official page for obtaining info about Mares Nemo. You may want to leave this site and go to
Mares own
Nemo page to obtain that information.
For you who have some problems syncing Nemo with their computers Mares has released revisited instructions how to do this. They can be obtained from
Here.
But just to mention, make sure that the infrared port of your computer is either disabled or is not visible for I.R.I.S Reader. This made a great deal to me. I haven't got a single failed download since. I just roll the strap to its shortest position put the Nemo under reader and press OK. :)
I (Teemu) created this page to share the knowledge that I have obtained by crawling around the bits and bytes that are transmitted between Nemo and Iris software.
Most of the bits have found their places and I know the reason why they are in there, but there are still some unknown bits to get it complete.
So if there are someone who is willing to donate me bits from their Nemo via Iris I'm pleased.
Don't ask Mares about this document, cause they are not in any way responsible of filling the missing spaces or correct errors in this document. This is merely my view of bits and what they mean. It took a lot of dives to get this far.
So someone might ask why..
The reason behind this page is a pure intrest into the serial protocol that is used to read divelog records from Mares Nemo using I.R.I.S reader.
I'm also a little frustrated with the usability of Iris software among with the bugs that it has.
I have done a simple program with java to help me in this byte hunt. Sample output of it can be obtained from
here.
I also played little bit with graphics and made my java based reader to output a simple dive graph form each dive, sample chart from
wreck of coolaroo and with safetystop
wreck of alca.
Also a small program capable of outputting UDDF file with dive porfile and computer settings is done but not anyway finalized cause my germany is quite rusty.
I have also made Mares Nemo extension to
JDiveLog but testing of it is lacking time. I'm still able to import dives from my Nemo. I tred to email this info to developer of JDivelog but my mails still keep bouncing back, dunno why.
Some whys
Freedive - Al depth interval bug
I dont know if this bug is in certain version of Nemo or in all, but I have adressed Mares directly and via our local Mares represenative to get the fix. Still waiting infr can my nemo be pached or something. At least in Nemo Wide there is no bug in here since there is no freedive mode.
I dont want to put instruction in here how to produce this faulty state or how to return Your Nemo back to basics in this case. Send me mail if you really want to know.
Missing Logbook
In quite recent history: After a dive my computer decided that I dont need to browse my logbook via Nemo anymore. I could see only the last dive.
How ever these logs could still be able to be retrieved via infrared connection; in my case they were. So if this happens to you dont get frustrated, the data may still be there.
Your dive computer just dont work properly :). Dives after this dive seem to be browsable via Nemo.
Port settings
The data between iris readers and computer is transmitted with settings 9600 8-N-1, hardware flow control (no flow control seems to work just ok also.)
The Data
Before the before the real computer data starts there is a 'separation' header. It is basically set of bytes 0x11 in row followed by another set of 0xEEs.
In the beginning of stream there can be some random bytes from I.R.I.S reader, these should be discarded.
The pure data length transmitted form Nemo via iris is 35 232 bytes.
Data Heading Bytes
Location | Values | Explanation |
0x0000 - 0x058b | [ 0x11 ] | Among these bytes the can be some errors (seen 0x13 and 0x02), but they dont seem to cause any problems. |
0x058c - 0x05a0 | [ 0xEE ] | Some separator again |
After these heading bytes starts the 'real' computer data. The data format is:
data = *repeat-chunk
repeat-chunk = 2*chunk
chunk = 32* byte checksum
checksum = 1 * byte
The checksum is sum of those 32 bytes and than take the low byte of this sum. Chunks are repeated for error correction reasons.
Simple logic for reading I.R.I.S. stream would be. (No double error check, i.e. comparing successful sections to each other.)
read header 0x11s and 0xEEs.
while (have more bytes){
Read next 33 bytes.
Sum first 32 bytes.
if ( (byte)sum == checksum byte 33){
// we have good section,
store these 32 bytes for later use..
skip next 33 bytes.
} else {
Read next 33 bytes.
Sum first 32 bytes.
if ( (byte)sum == checksum byte 33){
store these 32 bytes for later use..
} else {
// we've got corrupted data from I.R.I.S.
handle sync error.
}
}
}
After this location 0x0, that I use in following tables, refers to the beginning of this "cleaned" data.
So what we have here is
NemoData = [ Header | Current settings | log history | log book entries section | freedive profile data section ]
Header
I don't know much about this, but it looks like that it is 20 bytes long and starts after separation [0xEE] s. On My Nemo these bytes look like:
Header Bytes
Location | Values | Explanation |
0x0000 - 0x0013 | [ 06 00 00 00 00 47 0c 00 5d 09 0a 54 1d 09 04 ff 00 00 60 bc ] | Header of some sort. |
Current settings
This section contains the settings in Nemo at the moment of sync.
Current Settings Bytes
Location | Explanation | Values |
0x0014 | Time format 12-24 | 00 | 01 |
0x0015 | Alarm off-on | 00 | 01 |
0x0016 | Alarm hour | |
0x0017 | Alarm minute | |
0x0018 | 2nd Time off-on | (00-01) |
0x0019 | Hourbeep off-on | (00-01) |
0x001A | Units type C-F | (00-01) |
0x001B | Audible alarms | (00-01) ** See also free dive |
0x001C | Type of water S-F | (00-01) |
0x001D | Altitude Program | (00-03) |
0x001E | Personal Factor | (00-02) |
0x001F | Dive Mode | (00 Air | 01 EAN | 02 free | 03 b-t ) |
0x0020 | Fast ascend alarm | (00-01) |
0x0021 | O2 persentage | ? |
0x0022 | PPo setting | (140 = 1,4) ** Iris gets this wrong |
0x0023 | Freedive - Max dive time alarm | (00-01) |
0x0024 | Freedive - Max dive time alarm seconds | |
0x0025 | Freedive - Max dive time alarm minutes | |
0x0026 | Freedive - Max depth alarm | (00-01) |
0x0027-0x0028 | Freedive - Max depth alarm depth | LE_WORD |
0x0029 | Freedive - Surface time alarm | (00-01) |
0x002A | Freedive - Surface time alarm seconds | |
0x002B | Freedive - Surface time alarm minutes | |
0x002C | Freedive - Al depth, depth interval alarm | (00-01) |
0x002D | Freedive - Al depth interval | ( tens of meter ) ** Bug in nemo **!! |
0x002E-0x003f | Unknown | 00 c6 00 dd 00 e3 00 00 00 00 00 00 00 00 00 00 00 |
0x0040 | Unknown, has changed once during my debug, Battery was changed before this dive (2nd battery in machine. Go Figure ??) | 01 - 02 |
0x0021-0x004f | Unknown | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
Log History
Current settings are followed by history settings
Log History Bytes
Location | Explanation | Values |
0x0050-0x0051 | Total number of dives done with this computer ( MSB is not verified) | LE_WORD |
0x0052-0x0055 | Total Divetime in seconds (0x0055 not verfied) | LE 32 Bit Integer |
0x0056 | Scuba - Lowest logged temperature | |
0x0057-0x0058 | Scuba - Deepest logged depth | LE_WORD |
0x0059-0x005E | Unknown | |
0x005F | Unknown, but seems to correlate with total dives - x between syncs. | |
0x0060 | Freedive - Longest dive seconds | |
0x0061 | Freedive - Longest dive minutes | |
0x0062-0x0065 | Unknown | |
0x0066 | Freedive - Lowest logged temperature | |
0x0067-0x0068 | Freedive Deepest logged depth ( LE_WORD ), MSB not verified | |
0x0069-0x006a | Freedive - total number of freedives (LSB matches, MSB not verified) Or is this, how many there is in current profile? | |
0x006b-0x006c | Start location of next dive ** | |
0x006d-0x006f | Unknown | |
0x0070-0x33FF | Divelogbook section | |
0x3400-0x3FFF | Freedive profile section | |
Most of freedive stuff is still unknown but I hope I can get that data form somewhere. Also the total number of dive hours is not found yet; I expect it to be in the history section.
Dive Logbook
Dive logs can start at any point of data section, the "Start location of next dive" tells where Nemo is about to write the next dive. So rolling backwards form here might just do the work.
The data section is "cyclic", if dive profile data reaches the location 0x33ff next byte is written into 0x0070. Fredive profile data starts at 0x3400.
The tissue data (10 tissues in Nemo.) is still a little bit mystery to me, Ill try to figure out what those two bytes really mean.
Dive log itself is like this. The location 0x0000 refers to the starting point.
To fined the start point of dive you must take into accout what type of dive this is and roll back from location pointing to the end of dive.
The formula is simple and it also addresses the problem when data "rolls" from start of datasection to the end of data section.
start-location = next-dive start - amount-of-fixed-fields - ( profile-data-amount * profile-data-size ) - dive-size-bytes;
if (start-location < 0x70){
start-location = (0x3400 - ( 0x70 - start-location ))
}
- dive-size-bytes is allways 2
- profile-data-amount is a LE_WORD that can be read from location ( next-dive start-3 )
- In Freedive mode
- amount-of-fixed-fields = 28 bytes
- profile-data-size = 6 bytes
- In Nitrox,Air and Bottom-timer modeS
- amount-of-fixed-fields = 53 bytes
- profile-data-size = 2 bytes
Dive Log Entry
Location | Explanation | Values |
0x0000 - 0x0001 | The length this dive logs section in bytes, including these 2 bytes | LE_WORD |
start + lenght -1 | Type of dive log entry | (00 Air | 01 EAN | 02 free | 03 b-t ) |
Dive entry
Scuba dive logs are started with depth entries followed by other dive data.
Scuba log depth entry (Air, EAN, b-t)
Scuba log profile entries are Litte-Endian words where 4 Most Significant Bits are used for indicating ascend speed and deco stops and deco stop violations. These entries are written in 20 seconds interval. If this is a b-t dive you should ignore most deco information since they are just "something".
Profile-Entry = Depth-LSB Data
Data = Asc_Rate Deco DEPTH-MSB
Asc_Rate = 2*bit (Ascending speed steps, 0(descending)-3(slow))
Deco = Deco_Violation Deco_Stop
Deco_Violation = 1 bit boolean
Deco_Stop = 1 bit boolean
Depth-MSB = 4*bit
Depth-LSB = 8*bit
Depth = DEPTH-MSB DEPTH-LSB (12 bit word)
So the maximum depth recordable into profile entry is 12 bit integer in tenth of meters (409,5 meters). Amount of dive log entries is told in the second last byte pair of this divelog.
Scuba Dive Log Entry Revisited
Location | Explanation | Values |
0x0000 - 0x0001 | The length this dive log section in bytes, including these 2 bytes | LE_WORD |
0x0002 - 0x0003 | profile log entry | Profile-Entry |
.. | profile log entry | Profile-Entry |
.. (amount of profile entries * 2) | profile log entry | |
-53 | Max Ascend Rate | Meters per minute .. |
-52 | Altitude Program | 0 - 4 |
-51 | Personal Factor | 0 - 3 |
-50 | Uncontrolled ascent alarm | 00/01 |
-49 | Audible Alarms ( Sound alarm ) | 00/01 |
-48 | Fast Ascend Alarm ( Stop ) | 00/01 |
-47 | Uncontrolled Ascent | 00/01 |
-46 | Omited Deco stop | 00/01 |
-45 | Deco Depth Error | 00/01 |
-44 | Decompression Stop Dive | 00/01 |
-43 | O2 persentage | |
-42 | PPo setting | (140 -> 1,4) |
-41 | Start CNS persentage | |
-40 | End CNS persentage | |
-39 | Depth M Prec ? | 0 |
-38 | ? Average depth in meters ? | |
-37 | Dive Days - what ever means | 00 |
-36 | DeepStop 1 and 2 | 4-bit DS 2 LSB , 4-bit DS 1 LSB |
-35 | DeepStop 1 and 2 | 4-bit DS 1 MSB , 4-bit DS 2 MSB |
-34 | ? Tissue 1 | |
-33 | Tissue 1 | |
-32 | ? Tissue 2 | |
-31 | Tissue 2 | |
-30 | ? Tissue 3 | |
-29 | Tissue 3 | |
-28 | ? Tissue 4 | |
-27 | Tissue 4 | |
-26 | ? Tissue 5 | |
-25 | Tissue 5 | |
-24 | ? Tissue 6 | |
-23 | Tissue 6 | |
-22 | ? Tissue 7 | |
-21 | Tissue 7 | |
-20 | ? Tissue 8 | |
-19 | Tissue 8 | |
-18 | ? Tissue 9 | |
-17 | Tissue 9 | |
-16 | ? Tissue 10 | |
-15 | Tissue 10 | |
-14 | Unknown | |
-13 | Unknown | |
-12 | Water mode | (salt-fresh) |
-11 | Lowest Temperature | |
-10 - -9 | Max depth | LE_WORD |
-8 | Dive start date - year | |
-7 | Dive start date - month | |
-6 | Dive start date - day | |
-5 | Dive start time - hour | |
-4 | Dive start time - minute | |
-3 - -2 | Amount of profile entries in this dive | LE_WORD, This can be '0' for dive with no profile. |
start + lenght -1 | Type of dive log entry | 00 Air | 01 EAN | 02 free | 03 b-t |
In Bottomtime mode most of settings are inherited from last non-b-t scuba entry. So ignore those.
Freedive log entry
On Logbook side the freedive contains dive depths and lengths, surface time between those dives and some settings data.
Profile data is in its own section starting at 0x3400.
This is the reason why Nemo cannot store more that 1 "day" of freediving profiles.
Free Dive Log Entry
Location | Explanation | Values |
0x0000 - 0x0001 | The length this dive log section in bytes, including these 2 bytes | LE_WORD |
0x0002 - 0x0003 | Max depth of first dive | LE_WORD * 10cm |
0x0004 | Dive Time seconds | |
0x0005 | Dive Time Minutes | |
0x0006 | Surface time before this dive, seconds | |
0x0007 | Surface time before this dive, minutes | |
repeat * Amount of dives freediving sections | | |
-28 | ? Al depth, depth interval alarm | off-on |
-27 | ? Al depth interval | See bug in settings section |
-26 | ? Al depth interval, MSB | If they get it right |
-25 | ? Max dive Time Alarm | off-on |
-24 | ? Max Divetime Alarm - seconds | |
-23 | Max Divetime Alarm - minutes | |
-22 | ? Max depth alarm | off-on |
-21 | ? Max depth alarm depth | LE_WORD |
-19 | ? Surface time alarm | off-on |
-18 | Surface time alarm - seconds | |
-17 | Surface time alarms - minutes | |
-16 | Longest dive - seconds | |
-15 | Longest dive - seconds | |
-14 | Unknown | 0xEC |
-13 | Unknown | 0x03 |
-12 | Water mode | (salt-fresh) |
-11 | Lowest Temperature | |
-10 - -9 | Max depth | LE_WORD |
-8 | Dive start date - year | |
-7 | Dive start date - month | |
-6 | Dive start date - day | |
-5 | Dive start time - hour | |
-4 | Dive start time - minute | |
-3 - -2 | Amount of dives freediving sections | LE_WORD, This can be '0' for dive with no profile. |
start + lenght -1 | Type of dive log entry | 00 Air | 01 EAN | 02 free | 03 b-t |
Heres an example of freedive section: bytes..
60 00 1b 00 07 00 00 00 22 00 05 00 0b 00 1c 00
04 00 3b 00 1f 00 07 00 06 07 24 00 0b 00 27 08
12 00 0b 00 15 01 1d 00 11 00 2f 00 22 00 19 00
31 00 21 00 16 00 2b 01 1c 00 18 00 29 00 1d 00
17 00 23 00 00 32 00 00 00 01 00 c8 00 00 1e 00
19 00 ec 03 00 13 24 00 06 01 1d 0d 29 0b 00 02
And the Profile section is in 0x03400 - ? . There can be only 1 profile at time. Nemo manual will tell you more about this.
It also states that: "Note: all the Free Dive mode alarm settings are recorded, how ever they can only be displyed using the PC Iris interface (optional)".
I could not find those in anywhere in Iris software. Perhaps the "how ever they can only be displyed using the PC Iris interface" is the key in here :).
Freedive Profile data is in format [ depth ]* [ 00 00 ], where depth is DWORD depth in 10 centimeres repeated in 4 second intervals and dive ends with [00 00]. This is repeated as many times as there are dives in feedive section.
11 00 1b 00 00 00 12 00 22 00 00 00 15 00 00 00
0e 00 1f 00 00 00 14 00 23 00 24 00 00 00 0f 00
11 00 12 00 00 00 13 00 19 00 1d 00 1d 00 16 00
00 00 0d 00 0f 00 14 00 1b 00 21 00 22 00 21 00
00 00 0f 00 12 00 1a 00 1e 00 21 00 1f 00 00 00
10 00 1b 00 1c 00 19 00 11 00 0d 00 00 00 0e 00
10 00 14 00 1c 00 1c 00 1d 00 00 00