> For the complete documentation index, see [llms.txt](https://docs.ceruleansonar.com/c/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ceruleansonar.com/c/s-500-sounder/technical-details/programming-api.md).

# Programming API

API Compatibility: S500 communication uses a binary packet format compatible with the Blue Robotics [Ping-Protocol](https://github.com/bluerobotics/ping-protocol). It supports most of the Blue Robotics [Ping1](https://bluerobotics.com/store/sensors-sonars-cameras/sonar/ping-sonar-r2-rp/) packet types.

Documentation: The generic packet format is documented below, as are the specific payloads. These packet types are recommended for new applications targeting the S500 sounder.

Apology: The terms "altitude," "distance," and "depth" are used somewhat interchangeably here. They all mean the sensed distance from the device to some object, which in many applications is "the bottom."&#x20;

## **Packet Format**&#x20;

<table data-header-hidden><thead><tr><th width="150"></th><th width="150"></th><th width="150"></th><th></th></tr></thead><tbody><tr><td><strong>Byte</strong></td><td><p> </p><p><strong>Data Type</strong></p><p> </p></td><td><p> </p><p><strong>Name</strong></p><p> </p></td><td><p> </p><p><strong>Description</strong></p><p> </p></td></tr><tr><td>0 to 1</td><td><p> </p><p>char[2]</p><p> </p></td><td><p> </p><p>start_of_packet</p><p> </p></td><td><p> </p><p>2 byte ASCII string "BR" marks start of packet</p><p> </p></td></tr><tr><td>2 to 3</td><td><p> </p><p>u16</p><p> </p></td><td><p> </p><p>payload_length</p><p> </p></td><td><p> </p><p>number of bytes in payload</p><p> </p></td></tr><tr><td>4 to 5</td><td><p> </p><p>u16</p><p> </p></td><td><p> </p><p>packet_id</p><p> </p></td><td><p> </p><p>corresponds to ID field in packet payload definitions below</p><p> </p></td></tr><tr><td>6</td><td><p> </p><p>u8</p><p> </p></td><td><p> </p><p>reserved</p><p> </p></td><td><p> </p><p>set to 0</p><p> </p></td></tr><tr><td>7</td><td><p> </p><p>u8</p><p> </p></td><td><p> </p><p>reserved</p><p> </p></td><td><p> </p><p>set to 0</p><p> </p></td></tr><tr><td>8 to n</td><td><p> </p><p>u8[]</p><p> </p></td><td><p> </p><p>payload</p><p> </p></td><td><p> </p><p>payload message. Format varies with packet id per payload definitions below</p><p> </p></td></tr><tr><td>(n+1) to (n+2)</td><td><p> </p><p>u16</p><p> </p></td><td><p> </p><p>checksum</p><p> </p></td><td><p> </p><p>sum of all the bytes in the packet. Truncated to 16 bits</p><p> </p></td></tr></tbody></table>

## **Packet Payload Definitions**

### **General**&#x20;

<table><thead><tr><th width="184">Name</th><th width="150">ID</th><th width="150">Data Type</th><th width="150">Name</th><th>Description</th></tr></thead><tbody><tr><td>nop</td><td>0</td><td></td><td>none</td><td>clients may ignore. Sometimes useful to keep things awake</td></tr><tr><td>ack</td><td>1</td><td>u16</td><td>id</td><td>id being acked</td></tr><tr><td>nack</td><td>2</td><td>u16</td><td>id</td><td>id being nacked</td></tr><tr><td></td><td></td><td>char[]</td><td>msg</td><td>optional ascii text message describing error*</td></tr><tr><td>ascii_text</td><td>3</td><td>char[]</td><td>msg</td><td>any ascii text string*</td></tr><tr><td>general_request</td><td>6</td><td>u16</td><td>id</td><td>request client to respond with packet id type</td></tr></tbody></table>

\*STR\_LEN: Length of the string determined based on payload\_length in packet header.

### **Request Info Response Packets**

*These are the responses that the device will send to the host in response to a general\_request packet (id = 6, see above). Alternatively, host may send any one of these packet ids with no payload and device will respond with same id and the payload indicated here.*

<table><thead><tr><th width="202">Name</th><th width="94">ID</th><th width="113">Data Type</th><th width="162">Name</th><th>Description</th></tr></thead><tbody><tr><td>fw_version</td><td>1200</td><td>u8</td><td>device_type</td><td></td></tr><tr><td></td><td></td><td>u8</td><td>device_model</td><td></td></tr><tr><td></td><td></td><td>u16</td><td>version_major</td><td></td></tr><tr><td></td><td></td><td>u16</td><td>version_minor</td><td></td></tr><tr><td>speed_of_sound</td><td>1203</td><td>u32</td><td>sos_mm_per_sec</td><td>current speed of sound setting in mm/sec default is 1500 m/sec</td></tr><tr><td>range</td><td>1204</td><td>u32</td><td>start_mm</td><td>normally 0</td></tr><tr><td></td><td></td><td>u32</td><td>length_mm</td><td>start_mm + length_mm is max range</td></tr><tr><td>ping_rate_msec</td><td>1206</td><td>u16</td><td>msec_per_ping</td><td>minimum time between successive pings. Can be longer depending on range</td></tr><tr><td>gain_index</td><td>1207</td><td>u32</td><td>gain_index</td><td>current gain index setting</td></tr><tr><td>altitude</td><td>1211</td><td>u32</td><td>altitude_mm</td><td>result of most recent calculated distance from device to bottom (or other target)</td></tr><tr><td></td><td></td><td>u8</td><td>quality</td><td>measure of confidence of altitude measure 0 (no idea) to 100 (quite sure)</td></tr><tr><td>processor_degC</td><td>1213</td><td>u32</td><td>centi_degC</td><td>device CPU temperature degrees C * 100</td></tr></tbody></table>

### **Commands**&#x20;

<table><thead><tr><th width="219">Name</th><th width="72">ID</th><th width="111">Data Type</th><th width="168">Name</th><th>Description</th></tr></thead><tbody><tr><td>set_speed_of_sound</td><td>1002</td><td>u32</td><td>sos_mm_per_sec</td><td>default value is 15000000 mm/sec (1500 meters/sec)</td></tr><tr><td>set_ping_params</td><td>1015</td><td>u32</td><td>start_mm</td><td>start of ping range, normally 0</td></tr><tr><td></td><td></td><td>u32</td><td>length_mm</td><td>length of the returned profile. so end of range = start_mm + length_mm. Set to 0 for auto range.</td></tr><tr><td></td><td></td><td>i16</td><td>gain_index</td><td>set to -1 for auto gain, otherwise 0-13 sets gain for manual gain</td></tr><tr><td></td><td></td><td>i16</td><td>msec_per_ping</td><td>set to -1 to start a single ping. Otherwise sets minimum ping interval</td></tr><tr><td></td><td></td><td>u16</td><td>pulse_len_usec</td><td>0 for auto mode. currently ignored and auto duration always used</td></tr><tr><td></td><td></td><td>u16</td><td>report_id</td><td>the ID of the packet type that you would like in response. Options are: distance2 (1223), profile6 (1308), or zero. Zero disables pinging.</td></tr><tr><td></td><td></td><td>u16</td><td>reserved</td><td>Set to 0.</td></tr><tr><td></td><td></td><td>u8</td><td>chirp</td><td>set to 1 for chirp, 0 for monotone ping</td></tr><tr><td></td><td></td><td>u8</td><td>decimation</td><td>set to 0 for auto range resolution in chirp mode.</td></tr></tbody></table>

### **Ping Response Packets**&#x20;

*These packet types can be returned after each ping by specifying their packet id in the report\_id field of the set\_ping\_params packet described above.*

*distance2 reports a simple distance measurement.*&#x20;

*profile6\_t report a measure of signal strength at all depths within the ping range. This could be used to present a "waterfall" type display similar to a commercial marine depth sounder or fish finder. The Cerulean SonarView app uses profile6\_t to do just that.*

*The native number of results reported for the profile6\_t is 1024 for monotone pings. For chirp pings, the range resolution is affected by the "decimation" field in the set\_ping\_params command. If decimation is set to 0, the device will vary decimation depending on range. The smallest decimation will be used that does not exceed 6000 reported data elements.*

*Keep in mind the bandwidth of the communication channel in use when considering which profile report to use. For example, profile6\_t can generate a lot of data, and is probably best used with the USB or Ethernet interface.*&#x20;

<table><thead><tr><th width="150">Name</th><th width="80">ID</th><th width="150">Data Type</th><th width="196">Name</th><th>Description</th></tr></thead><tbody><tr><td>distance2</td><td>1223</td><td>u32</td><td>this ping distance mm</td><td>most recent ping</td></tr><tr><td></td><td></td><td>u32</td><td>averaged distance mm</td><td>average over last 20 pings</td></tr><tr><td></td><td></td><td>u16</td><td>reserved</td><td></td></tr><tr><td></td><td></td><td>u8</td><td>this ping confidence</td><td>0 to 100</td></tr><tr><td></td><td></td><td>u8</td><td>confidence of averaged distance</td><td>0 to 100</td></tr><tr><td></td><td></td><td>u32</td><td>timestamp </td><td>msec</td></tr><tr><td></td><td></td><td></td><td></td><td></td></tr><tr><td>profile6_t</td><td>1308</td><td>u32</td><td>ping_number</td><td>sequentially assigned from 0 at power up</td></tr><tr><td></td><td></td><td>u32</td><td>start_mm</td><td></td></tr><tr><td></td><td></td><td>u32</td><td>length_mm</td><td></td></tr><tr><td></td><td></td><td>u32</td><td>start_ping_hz</td><td></td></tr><tr><td></td><td></td><td>u32</td><td>end_ping_hz</td><td></td></tr><tr><td></td><td></td><td>u32</td><td>adc_sample_hz</td><td></td></tr><tr><td></td><td></td><td>u32</td><td>timestamp_msec</td><td></td></tr><tr><td></td><td></td><td>u32</td><td>spare2</td><td></td></tr><tr><td></td><td></td><td>float</td><td>pulse_duration_sec</td><td></td></tr><tr><td></td><td></td><td>float</td><td>analog_gain</td><td></td></tr><tr><td></td><td></td><td>float</td><td>max_pwr_db</td><td></td></tr><tr><td></td><td></td><td>float</td><td>min_pwr_db</td><td></td></tr><tr><td></td><td></td><td>float</td><td>this_ping_depth_m</td><td>depth in meters as calculated from the most recent ping</td></tr><tr><td></td><td></td><td>float</td><td>smooth_depth_m</td><td>smoothed calculated depth</td></tr><tr><td></td><td></td><td>float</td><td>fspare2</td><td>0</td></tr><tr><td></td><td></td><td>u8</td><td>this ping depth measurement  confidence</td><td>depth measurement confidence (0-100) based on most recent ping</td></tr><tr><td></td><td></td><td>u8</td><td>gain_index</td><td></td></tr><tr><td></td><td></td><td>u8</td><td>decimation</td><td></td></tr><tr><td></td><td></td><td>u8</td><td>smoothed depth measurement confidence (0-100)</td><td>0</td></tr><tr><td></td><td></td><td>u16</td><td>num_results</td><td></td></tr><tr><td></td><td></td><td>u16</td><td>pwr_results[]</td><td>power results scaled from min_pwr to max_pwr. num_results entries</td></tr></tbody></table>
