Go Down

Topic: Asynchronous SeaTalk (Read 40332 times) previous topic - next topic


In any case, good luck with your project. Thanks, Nick for your efforts.  

My pleasure. Hopefully it will come in handy one day.

Meanwhile in your case I would be throwing hardware debugging at it, like a logic analyzer. You will see clearly what is being sent. Possibly supplemented with a scope to make sure the voltages are correct.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics


Ah but Nick,
I live on a boat.  We've had to raise the bootline three times since we moved aboard 8 years ago.  it isn't all electronics.  I know i can get scopes which use pcs for displays, but that might be a bit much for the local Chancellor of the Exchequer.

I'm beginning to have more confidence that I'll be able to make something work.  Until I saw the dos program printing out datagrams and realized that i couldn't have both the bridge and the converter on the seatalk bus and still have enough signal to read, i was just flailing.

it is useful to know that one's hardware is percolating before all sorts of time is spent troubleshooting software that will never work before a signal shows up.

it's all fun.  once this project works and I've made final hardware, it's on to using an accelerometer to provide altitude leveling for the tv satellite antenna.  It has great azimuth control, but to keep the costs down no altitude.  idea is you set it for the latitude you're at which here in NA in the lower lattitudes works great - farther north the twitchier.

best regards,   john ferguson


Feb 22, 2012, 12:25 am Last Edit: Feb 22, 2012, 02:12 pm by jferg Reason: 1
I think I've got it.  I very carefully built the hardware seatalk-rs232 converter - used a better PNP transistor - it's listen only.  Then I built a better rs232 to ttl converter with a max232 AND built a 12 volt to 5 volt supply - 5 volts from arduino isn't enough to drive the max232. I'm bringing the ttl data into my Mega on Serial1 and it's displaying.

I'm getting good SeaTalk data coming into the Arduino, and it looks like an UNO would be fine assuming it can hold the code.  All I need now is to parse the two datagrams I'm interested in.  

my recommendation to anyone thinking of doing this is FIRST get the hardware sorted out.  Build the SeaTalk to RS 232 converter shown on Thomas Knauf's site, and using Seamon1.exe in DOS, (you'll need a machine with a real serial port for this) keep working on your wiring until you get recognizable datagrams.  An unbelievable amount of time can be wasted in tail-chasing if you aren't getting a signal. :D - I know, I've already wasted it.


in reviewing older comments, you asked why not just connect the seatalk devices to separate ports, if i understood you correctly.  their output wouldn't change and the collision and retransmission events when they are on a single bus do not prevent an adequate flow of data.  Seatalk runs at 4800 bps.  Getting a usable sentence every few seconds is plenty good enough for this application - movement of a boat at anchor.  likely also good enough for 6 knot boat underway. 

i apologize for being a little slow, but it appears that setting  arduino Serial1 (seatalk listener port)  to 9 bit and then reading the 9th bit has nothing to do with parity.  If the 9th bit is up,  then the byte is a "command" byte and the first byte of a datagram.  If there is only a space there, then the byte is not a command byte and is either nothing, or a databyte.

this is very hard for me.


True, it looks like they are using the 9th bit in that way. However that bit is in the "place" where parity bits used to be (and still are). It appears that you either can use the 9th bit for data, or parity, but not both (which would require a 10th bit, if you had 9 data bits AND parity).
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics


it's amazing how limiting nomenclature can be.  As soon as i realized this the 9th bit didn't have any other name if I was reading 9 bits, it got a whole lot simpler.  Just look in the 9th bit's place - now i have to figure out how to do that.  i have a bunch of suggestions including the ones in the manual.  I need to run the seatalk bus back to where i can sit down while i'm running trial and error.  the joy of the arduino is how quickly you can interate code. 

it's funny that sampling a datastream is a bit like sticking your toe in the water, you don't need to know how cold a specific pint of water is only any pint that is there when you touch it.  this must be completely different for the people who have to deal with every byte and cannot miss any.

best regards,  john


Just look in the 9th bit's place - now i have to figure out how to do that.

Yes. In the modified serial code I posted the 9th bit's place is the 0x100 bit (in hex). Or in binary: 0b100000000 (1 followed by 8 zeroes, the 9th bit).
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics


Feb 26, 2012, 04:39 pm Last Edit: Feb 26, 2012, 07:21 pm by jferg Reason: 1

Output from Arduino mega2560 with Raymarine ST40 Depth and Anemometer connected via Signal Convertor (See Thomas Knauth) and max232 (with 5 volt power supply) to reduce 12 volt signals to ttl, connected to RX1 on mega and read by code which follows.  See Knauth's website for datagram translation.

UPDATE: (following wrong, it is there) note that I appear to be losing one byte on the windspeed datagram.  should be another one at end. ???

Code: [Select]
// simple port reader for seatalk
// runs on mega2560
// 9th bit leads first byte such that "00" becomes "100" 2/26/12 j ferguson

void setup()
 Serial.begin(115200) ;
 Serial1.begin(4800,true) ;
 Serial.println("this is the start of simple seatalk passthough") ;
 delay(2000) ;
void loop()
 if (Serial1.available ())
{ int inbyte = (Serial1.read());
  if (inbyte >= 0x100)
  Serial.println (";") ;
  Serial.print (inbyte, HEX) ;


This uses Nick's modified HardwareSerial. h to see the 9th bit.  David, if you are still following along here, and would like very specific description of hardware, let me know.  Now on to the parsing.


Code: [Select]

if (inbyte >= 0x100)
  Serial.println (";") ;
Serial.print (inbyte, HEX) ;

I'm not sure if it will make much difference but I would "and" out that command bit, like this:

Code: [Select]

if (inbyte & 0x100)
  Serial.println (";") ;   // got command bit
Serial.print (inbyte & 0xFF, HEX) ;

Also changed your test to be a bit more "logical".
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics


Feb 26, 2012, 07:17 pm Last Edit: Feb 26, 2012, 07:19 pm by jferg Reason: 1
thanks much Nick.  It turns out I wasn't losing the last byte of the windspeed datagram - one beginning with "111"  I was fooled by the printer dropping leading zeros in hex print.  It won't matter though because now that I've got reliable reading, I just need run these strings into a buffer, extract the bytes which have the data, do the math, and then cook up the display routines for the LCD.  

i had been reading these data from an NMEA stream, but for some reason thought it was worth the several weeks of fussing with this to just get the data directly from the SeaTalk instruments.  I see I need to become comfortable with bitwise manipulation.  I can vaguely remember using this sort of thing writing Z80 assembler for modem routines on the old Osborne.  I didn't know what i was doing then either, but eventually i got it to work.

best regards and thank you again.

john ferguson



Yes, I am absolutely still following and I stand in amazement at what you've accomplished in such a short time.  I'd very much like to hear about your hardware converter.  I haven't had time to do much of anything but I did try to buy the transistors suggested on Thomas' converter schematic and was unable to find them at the usual places (Digikey and jameco).  Any suggestions for equivalent transistors?


Feb 26, 2012, 11:49 pm Last Edit: Feb 27, 2012, 05:32 am by jferg Reason: 1
Knauf's transistors are popular in europe. Here's what i used. i got everything from mouser - no minimum order.  also they have good price for mega2560.

BC557ATA PNP Transistor
LM7805ACT Voltage regulator to drop 12volts to 5
mouser # 651-1725711 2.54 pitch terminal blocks (need a jeweler's screw driver for these
mouser # 810-fk18y5v1c105z 1.0 uF caps
MAX232N rs232/ttl driver
16 pin socket for above
mouser 854-sb400 board to build this on.
also mouser 517-850-01-10 header sockets.  these are to hold the gps and compass modules.
also resistors needed - 3 10k, 1 2,2k ohma - radio shack - they are also starting to carry ardunino stuff and more prototyping boards
although i liked the mouser board better.
also need a 12 volt dc jack.
still haven't bought box. I already had one.

then for my project, add the I2C 4x20 lcd, the 6 buttons, the box, a couple of LEDs so i know it's energized, and maybe an alarm, for high wind, shallow depth, or excessive distance from anchor point. 

it may be that this is all folly.  i'm the guy that slept through the night that the building next door burned to the ground.

and remember, i'm only interested in 3 SeaTalk datagrams and it's listen only.
best,  john


Feb 27, 2012, 10:13 pm Last Edit: Mar 02, 2012, 03:33 am by jferg Reason: 1
Here is what I did. It reads Depth, Windspeed and Windangle (degrees to right from bow) and prints them as it reads them.  Now that this works, I'm going to make this routine into a separate loop to run when called and output to global variables rather than the ones built in now.  A lot of the rest of the code for reading the GPS module and the compass module is already up and running as well as the button readers and LCD output.

it all has to be combined.  On my setup, the datagrams are read in sequence starting with Depth whose Command byte is 0x00.  Nick's SerialHardware library reads the 9th bit which then shows up as a 1 appended to the head of each command byte, hence 0x00 is 0x100 with the 9th bit.

i was able to use the calculations shown in Thomas Knauth's reference to derive each of the datatypes.

I'll make a sketch of what i built for the hardware converter when I get a chance.

UPDATE 2/29/12: changed code example to note requirement for Nick Glammon's HardwareSerial core and clean up.  Criticisms welcomed.  Added sample of datastream.

UPDATE 3/1/12 changed "pointer" to "index" and moved varable type declaration to Global in effort to improve C-worthiness

This is what the SeaTalk input looks like on my system.  I added the spaces for legibility.  Byte 3 should always be 20, and is, once the stream settles down. I may add some filters to ignore lines where byte 3 is not 20.  

100 2 20 6D 0 110 1 0 21 111 1 C 2;
100 2 30 70 0 110 1 0 1A 111 1 B 1;
100 2 30 73 0 110 1 0 20 111 1 B 4;
100 2 20 71 0 110 1 0 3 111 1 B 4;
100 2 20 6E 0 110 1 0 3B 111 1 B 3;
100 2 28 6C 0 110 1 0 2A 111 1 B 0;
100 2 20 6D 0 110 1 0 1B 111 1 B 0;
100 2 20 6E 0 110 1 0 3B 111 1 B 2;
100 2 20 6F 0 110 1 0 31 111 1 B 6;
100 2 20 6F 0 110 1 0 29 111 1 A 1;

Code: [Select]

/* - SeaTalk reader: Depth, Windspeed, Windangle
  - no error detection, no collision detection
  - requires new SerialHardware core library with
  - 9th bit processing by Nick Gammon available
  - http://arduino.cc/forum/index.php/topic,91377
  - which requires Arduino 1.0 IDE 2/29/12 jaf

char SeaTalkData[256] , index ;
float printdepth, printwind ;
int printangle, inbyte ;
long interval = 2000 ;
unsigned long currentMillis ;
void setup()
 Serial.begin(9600) ;
 Serial1.begin(4800,true) ; //Nick G's SerialHardware core req'd.
 Serial.println("SeaTalkReader2 Startup") ;
 delay(2000) ;

void readSeaTalk()

 if (Serial1.available ())
    inbyte = (Serial1.read());
    if (inbyte == 0x100)
    index = 0 ;
/* Code above reads SeaTalk Stream and starts inbyte buffer when
   9th bit and first byte of depth sentence (command byte)come in.  
   On my system with two talkers, ST40 depth and wind, the datagrams
   follow each other in sequence so it's easy to pick out the
   bytes needed to derive wanted data - always in same place */
  SeaTalkData[index++] = inbyte ;

  printwind = ((SeaTalkData[11] & 0x7f) + SeaTalkData[12]/10) ;
  printangle = (makeWord(SeaTalkData[7] , SeaTalkData[8]))/2 ;  
  printdepth = (makeWord(SeaTalkData[4] , SeaTalkData[3])) / 10.0 ;


void serialprint ()
 Serial.print("windspeed: ") ; Serial.print (printwind, 1) ;
 Serial.print("  Wind Angle: "); Serial.println (printangle) ;
 Serial.print("Depth: ") ; Serial.println (printdepth, 1) ;
void loop()
 currentMillis = millis() ;
 while (millis() - currentMillis <= interval) //not tested yet, but this is a timer to make sure uart is up and delivering data.
 readSeaTalk () ;
 serialprint () ;


Absolutely beautiful.   Thank John and Nick, this is going to help a lot of folks (starting with me as soon as my work life stops getting in the way!).   

I'll be interested in seeing how you put it all neatly in a box.  Right now, I am using an out door PVC waterproof junction box and a plexiglass cover but I haven't (among many other things) figured out the waterproof feed through.

Anyway,  there is no doubt that this is an inspiring project and success.



Feb 29, 2012, 11:11 pm Last Edit: Mar 02, 2012, 03:29 am by jferg Reason: 1
Hi David,
I'm thinking of buying one of the prototype shields for the mega and locating the seatalk hardware, GPS, and compass on it. It looks like all of this might fit in an Arduino Uno/Mega box which costs about $13.  the box looks very nice in the pictures.  I'm also going to experiment with reducing the SeaTalk signal to ttl levels with a couple of resistors and try to dodge need for max232.  I might be able to get rid of the 12 volt/ 5 volt power supply on the daughter card this way.  I found a 4x6x2 plastic box for the v-berth display.  plan is to run 4 wires to the display, +12, ground, TX (serial to 4x20 lcd) and the analog line from the buttons.  There will be a 12 volt to 5 volt power supply in the remote so that I will be starting with sure thing 5 volts for the button resistor array, and to power the lcd.

plan is one button will control backlighting level on the lCD, one will reset max windspeed record, one to step through different displays (assuming there turns out to be a need for more than one), one button to record present position, and one to give bearing and distance from present position to recorded position, (drag discoverer).  I could also use combinations of buttons to get more voltage drops.  need to think very carefully about this so that I have something that will be helpful when I wake up out of a deep sleep and want to know what's happening.

I should add that m/v arcadian is a trawler and the gps and compass work quite well sitting on a prototype board on the bridge.  I may later find that they should be on the radar arch and will build a waterproof case for them if it proves necessary.  the Arduino mega case is unlikely to be waterproof.

let me know how you do with your project.  I might add that i retired in 2003.  I've spent an unGodly amount of time on this thing, but then I didn't know much when I started -- and I've had help from some very kind people.


Go Up