S500 ID Code Errors and Questions

I’ve hooked up the S500 using QT on a Raspberry Pi through a USB serial connection and it seems to be working. I’m able to connect, I can send codes, and I get responses. Thanks to Larry for the qtpacket class (in a different post) which streamlined things a lot.

However, I’m having problems with a few API ID codes from Appendix F of the S500 online user manual. Here is a very quick summary of issues before I provide a more detailed explanation:

  1. There appear to be several typos in the S500 user manual related to the processor temperature command (113), including a possible error in the command ID code
  2. The set_ping_params command (1015) does not provide a response to the host
  3. When the report_id parameter is set to distance2 (1223) by the set_ping_params command (1015), the transducer starts to ping, but the module does not appear to send any distance2 packets to the host. Not any bytes (not even erroneous ones) were observed.

First, for those interested, let me confirm that the following codes have been tested and are working on my unit: fw_version (1200), speed_of_sound (1203), range (1204), ping_rate_msec (1206), gain_index (1207), altitude (1211), and set_speed_of_sound (1002). These all send the proper response and adjust the relevant parameters correctly (in the case of ID 1002).

What does not do what I expected:
First, processor_mdegC (113) does not work. When I send the code I get an ascii response that says it is an unrecognized code. No big deal to me, though it is nice to stay ahead of the processor temperature. I looked at the other IDs and this one seemed like it might be a typo in the online user manual, so I tried (1213) instead. I got a response that is possibly valid, though the S500 only returned a u16 instead of a u32, so I don’t trust that it is in millidegrees C, though it could be in centi-degrees C. In fact, this is what is stated in the ping1d protocol, so I suspect that there are a few typos in the S500 manual with respect to processor temperature (id number, variable type, and the units of the output).

Second, set_ping_parameters (1015) appears to partly work. It appears to correctly set the start_mm, length_mm, gain_index, msec_per_ping, report_id, and chirp. I had no way to check decimation. However, it does not send a response packet after making these changes. I’m not sure if the module is supposed to send a response to the host, but that would seem natural based on all of the other commands. No response packet or response bytes are observed. There is not even an ACK or a NACK packet. That’s fine with me, as long as it does the trick, but maybe should be documented. I don’t know how the command is able to set the parameters without it being fully received by the module along with a proper checksum, so I have to assume that the command is operating properly for setting parameters other than that there is no response from the module.

I have a more serious concern about the (1015) command, though. When a distance2 (1223) report id is sent in the (1015) command, the transducer begins pulsing as it should, but no ping response packets are received by the host. I expected to receive distance2 (1223) packets for every ping, but I did not observe a single byte of data at the host, even though the transducer was clearly pinging. In my case, it is possible that none of the echos returned valid depths and that the unit only sends packets if it detects a valid depth, but that is not documented in the manual, and my assumption is that it sends packets even to report a measurement with no confidence. I did try the device in a jar of water - the jar was not very deep, but I would expect a result of some kind, even if the signal was garbage.

The profile6_t (1308) report id does appear to work when sent in the (1015) command and the module is regularly transmitting profile data for every ping. I have not parsed all of the data to see what it says, yet, but the bytes received look to be about the right number and I have verified some of the parameters in the profile packet. I’ll have to check this in more depth later, but the profile6_t packets are promising.

If anyone has any insights regarding the issues I encountered, I would be appreciative.


Wow, yeah, re: processor temperature you are correct. Not sure how that happened, but the command is 1213 and the response is u16 degC * 100. Updating doc now, then I will look at the rest of your issues.

Can you try the S500 using SonarView app? SonarView will also be able to update the S500 f/w if needed. Download instructions here: Installation - Cerulean Sonar Docs.

I want to make sure your device is up to date and that we’re on the same version. The fact that there is no ack or nack on set_ping_params could be the f/w version issue.

Regardless though there should be some response if it is pinging. Let’s see what happens once the version is confirmed and you’re getting acks from the set_ping_params.

Last night I successfully pulled profiles from the transducer. I still didn’t get the abbreviated depth command to do anything, but the profile command is working fine. I tested the sensor out in a bath and it gave believable depths. The profile command contains the information I need, but it would still be nice to reduce the bandwidth for some types of measurements.

I already have SonarView installed on a laptop, but all of the equipment is at home since I have been working on it there in the evening. So, I’ll check the firmware version tonight and post it.

Much appreciated.

Good news. I connected to SonarView and updated the firmware from V 2.24.0 to V 2.29.0, and all of my troubles went away. Apparently, V2.24.0 was the culprit.

I reconnected to the Pi and I’m now getting an ACK back when I send a 1015, and the module starts sending 1223 packets on every ping when the distance2 command is sent. I deciphered the received packets and everything looks great. I also checked the other commands and everything seems to be working. I’ll do a more thorough testing once the display and recording software is complete and the hardware is mounted, but I’m confident that it’s working correctly based on data I’m seeing at the port.

It seems all the software and electronics are functioning now. On to cleaning up the software and building a frame to hold the transducer.

Thanks for the troubleshooting tips and pointing me to the f/w update.



Excellent! Keep us posted on progress.

If you’d be willing to share your code there have been some others expressing interest in using QT to interface to our sonars. Cheers.

Hi Larry,

I put together a program in QT Creator that allows the user to identify active ports, connect to the port with the S500, and communicate with the S500. It’s a little rough and does not include any storage to files, but the program collects packets and displays information on screen. It should be helpful to anyone who is having a tough time connecting via Raspberry Pi.

I’m using the Bullseye Raspberry Pi OS, which has QT 5.15.2 as an optional package.

It looks like the Pi is going to be a great option for this system since it is small and inexpensive and they are once again becoming more widely available. I would not recommend using anything less than a Pi 4. I have worked with a Pi 3 and it will probably do the trick, but I don’t know that it is fast enough for a pleasant experience with Bullseye.

What is the best way for me to share the code?



I think I figured out how to share the code with Dropbox. If this doesn’t work, let me know. Here’s the link:

No guarantees that the pro file will work from any location, but my expectation is that whoever uses this can load the project into QT, build it and execute it. I’ll be doing some heavier coding before I use this.
In other words, no guarantees that it will work perfectly or that it is without bugs.



I’ll add a little more information to smooth the road. I am using a Raspberry Pi 4 with 2 Gb of memory. As I said earlier, I’m using Bullseye and QT 5.15.2 with QT Creator to build the GUI. The S500 is connected directly to the USB port of the Pi. I only have three or four serial speeds. I know that USB is much faster than what is in my program, but I’m not real familiar with how USB speeds are set (I’ll have to read up a little), so I just when with the speeds I had set for a different traditional serial device. It is easy enough to adjust available settings within the code to allow for faster data rates. It is important, however that some of the preselected port settings are left unchanged. For example, I was having problems when the Flow Control flags were incorrectly set. The settings that I successfully used were:
Baud Rate: 115k
Data Bits: 8
Flow Ctl: None
Parity: None
Stop Bits: one

When using the program, the user must first search for ports (use ID Ports button), then open the port connected to the S500, and finally go to the Cerulean tab to get or set information. Different types of results will appear in different panels, including sent information and received information.

If the S500 is set to start pinging by setting the Output to “Depth” or “Profile” it should continuously transmit data until the user sets the Output to “No Pinging”. Note that in order to cause pinging to start or stop, the user has to press the “Set Profiler” button. In other words, no commands are sent by changing the settings, only by pressing the “Set Profiler” button. I should also note that setting the temperature has no effect (An equation to convert temp to speed of sound is needed, but available equations are pretty in-depth, and I haven’t had the time). Also, “local echo” on the port page does nothing and is a leftover from a past project. It can be safely deleted (I just forgot to do this).

Thanks for sharing! Hopefully others will find it useful.