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
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 ]


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
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
0x0014Time format 12-2400 | 01
0x0015Alarm off-on 00 | 01
0x0016Alarm hour
0x0017Alarm minute
0x00182nd Time off-on(00-01)
0x0019Hourbeep off-on(00-01)
0x001AUnits type C-F(00-01)
0x001BAudible alarms(00-01) ** See also free dive
0x001CType of water S-F(00-01)
0x001DAltitude Program(00-03)
0x001EPersonal Factor(00-02)
0x001FDive Mode(00 Air | 01 EAN | 02 free | 03 b-t )
0x0020Fast ascend alarm(00-01)
0x0021O2 persentage ?
0x0022PPo setting(140 = 1,4) ** Iris gets this wrong
0x0023Freedive - Max dive time alarm(00-01)
0x0024Freedive - Max dive time alarm seconds
0x0025Freedive - Max dive time alarm minutes
0x0026Freedive - Max depth alarm(00-01)
0x0027-0x0028Freedive - Max depth alarm depthLE_WORD
0x0029Freedive - Surface time alarm(00-01)
0x002AFreedive - Surface time alarm seconds
0x002BFreedive - Surface time alarm minutes
0x002CFreedive - Al depth, depth interval alarm(00-01)
0x002DFreedive - Al depth interval ( tens of meter ) ** Bug in nemo **!!
0x002E-0x003fUnknown00 c6 00 dd 00 e3 00 00 00 00 00 00 00 00 00 00 00
0x0040Unknown, has changed once during my debug, Battery was changed before this dive (2nd battery in machine. Go Figure ??)01 - 02
0x0021-0x004fUnknown00 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
0x0050-0x0051Total number of dives done with this computer ( MSB is not verified)LE_WORD
0x0052-0x0055Total Divetime in seconds (0x0055 not verfied) LE 32 Bit Integer
0x0056Scuba - Lowest logged temperature
0x0057-0x0058Scuba - Deepest logged depthLE_WORD
0x005FUnknown, but seems to correlate with total dives - x between syncs.
0x0060Freedive - Longest dive seconds
0x0061Freedive - Longest dive minutes
0x0066Freedive - Lowest logged temperature
0x0067-0x0068Freedive Deepest logged depth ( LE_WORD ), MSB not verified
0x0069-0x006aFreedive - total number of freedives (LSB matches, MSB not verified) Or is this, how many there is in current profile?
0x006b-0x006cStart location of next dive **
0x0070-0x33FFDivelogbook section
0x3400-0x3FFFFreedive 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
0x0000 - 0x0001The 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
0x0000 - 0x0001The length this dive log section in bytes, including these 2 bytes LE_WORD
0x0002 - 0x0003profile log entryProfile-Entry
..profile log entryProfile-Entry
.. (amount of profile entries * 2)profile log entry
-53Max Ascend RateMeters per minute ..
-52Altitude Program0 - 4
-51Personal Factor0 - 3
-50Uncontrolled ascent alarm00/01
-49Audible Alarms ( Sound alarm )00/01
-48Fast Ascend Alarm ( Stop )00/01
-47Uncontrolled Ascent00/01
-46Omited Deco stop00/01
-45Deco Depth Error00/01
-44Decompression Stop Dive00/01
-43O2 persentage
-42PPo setting(140 -> 1,4)
-41Start CNS persentage
-40End CNS persentage
-39Depth M Prec ? 0
-38 ? Average depth in meters ?
-37Dive Days - what ever means00
-36DeepStop 1 and 24-bit DS 2 LSB , 4-bit DS 1 LSB
-35DeepStop 1 and 24-bit DS 1 MSB , 4-bit DS 2 MSB
-34? Tissue 1
-33Tissue 1
-32? Tissue 2
-31Tissue 2
-30? Tissue 3
-29Tissue 3
-28? Tissue 4
-27Tissue 4
-26? Tissue 5
-25Tissue 5
-24? Tissue 6
-23Tissue 6
-22? Tissue 7
-21Tissue 7
-20? Tissue 8
-19Tissue 8
-18? Tissue 9
-17Tissue 9
-16? Tissue 10
-15Tissue 10
-12Water mode(salt-fresh)
-11Lowest Temperature
-10 - -9Max depthLE_WORD
-8Dive start date - year
-7Dive start date - month
-6Dive start date - day
-5Dive start time - hour
-4Dive start time - minute
-3 - -2Amount of profile entries in this diveLE_WORD, This can be '0' for dive with no profile.
start + lenght -1 Type of dive log entry00 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
0x0000 - 0x0001The length this dive log section in bytes, including these 2 bytes LE_WORD
0x0002 - 0x0003Max depth of first diveLE_WORD * 10cm
0x0004 Dive Time seconds
0x0005 Dive Time Minutes
0x0006Surface time before this dive, seconds
0x0007Surface time before this dive, minutes
repeat * Amount of dives freediving sections
-28 ? Al depth, depth interval alarmoff-on
-27 ? Al depth intervalSee 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
-12Water mode(salt-fresh)
-11Lowest Temperature
-10 - -9Max depthLE_WORD
-8Dive start date - year
-7Dive start date - month
-6Dive start date - day
-5Dive start time - hour
-4Dive start time - minute
-3 - -2Amount of dives freediving sectionsLE_WORD, This can be '0' for dive with no profile.
start + lenght -1 Type of dive log entry00 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            
Last edit 13/5/2007 - total divetime calculation.
- Drop me a mail to if you find this at all interesting - teemu.tingander -