Seatalk - serial, related to parity

PeteV

New Member
Hi,

I'm relatively new to Picaxe and embedded stuff in general. I've completed one successful project (basic button, LED, buzzer, transistor type of thing) and now have a second in mind. This will need to communicate (both send and receive) on a Seatalk bus on a boat. Slightly to my surprise, nobody seems to have done this with a Picaxe before (or if they did, they didn't tell Google).

The Seatalk protocol is described here: http://www.thomasknauf.de/rap/seatalk1.htm . There are circuits out there for interfacing with a PIC, so I can deal with the 12v signalling level etc, but I believe the "command bit" presents a problem. This sits in the place where a parity bit would normally be, but needs to be read and written under software control in order to work with the protocol. A bit of searching this forum suggests that the Picaxe can't do this directly, but there might be ways - which I don't really understand!

I have an 08M2 handy, but could order a different part if it makes a difference.

Any pointers on this would be very much appreciated.

Thanks,

Pete
 

PeteV

New Member
Hmm, actually I think I'm starting to get this...

So first off I sfrpoke into RCSTA and TXSTA, in both cases setting bit 6 which says "do 9-bit mode". I can crib that from http://www.picaxeforum.co.uk/showthread.php?14516-SPI-Question&p=124882&viewfull=1#post124882 - wouldn't have occurred to me to read and write back the whole byte there, I'd have been trying to figure out how to set just the one bit, so that's saved a lot of head scratching :)

Then I do hsersetup to set the baud rate - presumably for the MHz stuff there I just put the speed I'm running the chip at. Also not quite sure how the setting of the mode bits works - many examples only seem to use two or three, which end is getting left out?

Then I "just" do hserin and hserout as normal, separately treating RX9D and TX9D as the "command bit".

I think this might be doable :)

Pete
 

geoff07

Senior Member
You might be able to use the standard 8-bit serial primitives, but you can just as easily (well almost) 'bit-bang' (i.e. do the detail work yourself) any kind of output you like. You need to represent the bits you want to send in storage in a suitable form, update them as required, and then have a routine to clock the individual bits out or in using low level commands. Exactly which commands will depend on the timing, but 4800 baud isn't so fast that it would be difficult.

One reason this has not been reported with Picaxe before maybe this: If you are planning to control an autohelm or some other safety-related device you will need to think long and hard before building it yourself, and talk to your insurance company! Monitoring is different of course. This forum is very good at helping those new to the art, but not very keen to help people get into unknown safety situations. Losing control of the helm at a crucial moment could be tricky! There has never been software written of any degree of complexity that could be proven to be bug free.
 

PeteV

New Member
One reason this has not been reported with Picaxe before maybe this: If you are planning to control an autohelm or some other safety-related device you will need to think long and hard before building it yourself, and talk to your insurance company!
Nope, not planning to take over the autopilot :)

The problem I have is that with the depth alarm set to 1.5m below the keel, it's not uncommon to have the alarm going off continually while berthing. Pressing any button will silence it, but only for 15 seconds or so. This is quite distracting while trying to come alongside. So my little gizmo will keep an eye out for message 00 with the "shallow alarm active" flag set, and if it sees it, it will emit a message 68 to cancel the alarm.

External to the Picaxe circuit will be a switch on the power line, so the whole thing is only working during those short periods when the depth alarm is counterproductive. There will also be a bright LED in parallel so that it isn't left in silent mode by mistake. A more sophisticated version would have the LED controlled by the Picaxe, and a built-in timer so that the device only operates for say fifteen minutes at a time - long enough to get tied up, but if it accidentally gets switched on at lunchtime, it won't still be muting the alarm that evening. But for a first pass at least, I'm going to keep it simple.

The main loop in the program is quite straightforward I think - get called by interrupt whenever a byte comes in, examine RX9D, bail if it's not set. If it is set, continue to receive bytes until I find one that doesn't match an incoming message-00-with-alarm-active, in which case bail back to the base state. If I get as far as the alarm flag without bailing, emit my pre-canned "shut up" command and then go back to the start.

I guess I need to wait till the bus is clear, so how about my main loop (when I'm not being interrupted) has a short pause in it. If I ever get past the pause without having been interrupted, there's no traffic coming in, so I'll check a flag to see whether I previously decided to transmit my shut-up message, and if so, I will.

There's a possibility I might still collide with something, but that's ok, seatalk is designed to work that way. Next time round, the alarm will still be active so I'll go through the whole procedure again and hopefully kill it this time.

It may or may not work, but I don't see much danger of accidentally generating a valid "autopilot engage" command :). And the disengage button is right in front of the wheel anyway. There's probably a greater danger of someone engaging it by sitting on the wireless remote than by the alarm-mute box going rogue :)

Pete
 

srnet

Senior Member
How are the messages; information and commands, error checked on the bus ?

i.e. whats to prevent a corrupt message or command being acted on ?
 

Buzby

Senior Member
From the link in post #1 :
Since each device also listens to its own transmission it will recognize when its message is garbled by a second talker. In this case it abandons the remaining characters of the datagram. It waits for the bus to become free again and then retransmits the whole message.
and :
Some characters are repeated with all bits inverted for noise or transmission error detection. Example: 0xA2 is followed by 0x5D. The sum of both bytes must always be 0xFF.
So there is a little bit of protection, but it depends on how many characters are 'inverted'.
 

srnet

Senior Member
Collision detection is for bus sharing, its not going to pick up errors in reception.

And whilst there are 'some' characters repeated in the protocol, my reading of the protocol would be that 'very few' characters are repeated (and thus error checked).

Did I miss something ?
 

Buzby

Senior Member
There is a link to a SeaTalk message generator on the website. Looking at the provided example command files ( .ray ) shows the data to be sent for a few commands.

If this simulator was run, and the ouput redirected to a file, or captured by a second PC, it may become clearer where the 'inverted' bytes are used.

It does seem from the description so far that there is scant error detection at the reciever, but the SeaTalk protocol seems well established, so maybe we are both missing something ! :)
 

hippy

Technical Support
Staff member
It might be possible but I expect it would be challenging and hard to say if it would work without trying it.

Generating messages and detecting collisions when sending should be possible as up to 2ms is allowed between sending bytes. Receiving arbitrary messages is harder though it may be possible to handle without 9th bits and determine packets anyway. It may be possible to filter so only the desired message comes through which the earlier thread suggests might be achievable.

Probably the best way to try it is to build an off-boat Seatalk system with two or more PICAXE. I would say it needs to be PICAXE-X2 based because of the asynchronous receive.

An alternative may be to interface not to the received packets but the physical alarm. Then only packets have to be transmitted to silence it.
 

PeteV

New Member
How are the messages; information and commands, error checked on the bus ?
They aren't :)

Bear in mind that Seatalk was originally devised back in the 80s to allow a few items of data (depth, wind speed and direction, boat speed, etc) to be displayed remotely, and a bit of simple integration (like taking the apparent wind and boat speed and doing some vector maths to display true wind). This data is broadcast several times a second - if one of the speed messages, say, got corrupted to say the boat was travelling at 100 knots, then at worst a repeater display might flicker for a moment before a new valid value arrives. The general philosophy is a bit like UDP-based IP protocols - it's stateless, it doesn't matter if this packet gets screwed up, there'll be another along shortly.

This principle got corrupted a bit when they started adding more sophisticated equipment, so a handful of the messages do now affect state and a corrupted one could potentially cause some noticeable change. This is where the repeated-byte scheme for basic error checking seems to be used. Actually I find it very interesting that command 65 looks to be the only stateful command which doesn't use such error checking - a couple of years ago on the sailing forum I use, a guy with a very noisy seatalk bus (unshielded, long lengths of wire bundled with radio transmitter and engine wiring and god-knows-what) said that his depth display very occasionally switched itself to fathoms.

In summary, a Seatalk bus sounds like a pretty anarchic place, but in practice it works pretty well.

Pete
 

PeteV

New Member
It might be possible but I expect it would be challenging and hard to say if it would work without trying it.
Oh dear. That doesn't sound promising...

Generating messages and detecting collisions when sending should be possible as up to 2ms is allowed between sending bytes.
I was proposing not to bother with collision detection. If I collide with anyone else they'll stop, I'll carry on barging a couple more bytes onto the bus. If the resulting message is corrupted and ignored, no worries, next time I see a message 00 I'll try again. Maybe the alarm beeps briefly till a successful un-collided message gets through. That's acceptable. If I cause temporary mayhem on the bus for half a second every twenty, that's ok, the instruments might flicker but they'll pick up again after. I'm not really using them at this point anyway.

Receiving arbitrary messages is harder though it may be possible to handle without 9th bits and determine packets anyway.
That sounds worrying - why is it hard to receive messages? While receiving I'm barely doing anything else, and 4800bps doesn't sound all that fast (after all, it needed to be handled by 80s microcontrollers, albeit programmed by more skilful folk than me :) ).

Probably the best way to try it is to build an off-boat Seatalk system with two or more PICAXE. I would say it needs to be PICAXE-X2 based because of the asynchronous receive.
I'm more inclined to dig out an old laptop and install the Picaxe tools on it, then go down and play with the real system on the boat. Some means of seeing what's going on on the bus would be handy though - I think there are instructions out there for piping it into a PC serial port for display on a terminal.

An alternative may be to interface not to the received packets but the physical alarm. Then only packets have to be transmitted to silence it.
I don't really want to open up the sealed case of the depth instrument, plus its physical location is awkward from a wiring point of view. I really want to build a single box that can just connect to the Seatalk bus anywhere (in this case inside the binnacle at the wheel).

Thanks for your help,

Pete
 

Buzby

Senior Member
I'm more inclined to dig out an old laptop and install the Picaxe tools on it, then go down and play with the real system on the boat. Some means of seeing what's going on on the bus would be handy though - I think there are instructions out there for piping it into a PC serial port for display on a terminal.
Sounds like a plan !.

Once you see what is really on the bus you will have a better idea as to what the PICAXE needs to do, then building a receiver should be not too difficult.

I think you could ignore the 'parity' if doing RX only, just process the bytes and ignore nonsense. TX will need the 'parity', but let's cross that bridge when we get to it.

This looks like a cool project.

Cheers,

Buzby
 

PeteV

New Member
I think you could ignore the 'parity' if doing RX only
I don't think I want to ignore it. It serves the useful role of letting me know when to start paying attention. As long as it's not set, I can just ignore what's going past. When it's set I need to look at the current byte and see if it's the message I'm interested in. If not, I can go back to sleep.

Without the command bit I'm going to have a much more complicated state machine to keep track of where in the message stream I am. In fact, without the command bit it may not even be possible to tell where one message ends and the next starts.

Pete
 

hippy

Technical Support
Staff member
why is it hard to receive messages? While receiving I'm barely doing anything else, and 4800bps doesn't sound all that fast
You could be right as you will only get one byte every 2ms even with back-to-back data bytes. I was thinking, if you were doing things leisurely, relying upon background receive, you might have to accept the loss of the 9th command bit and have to figure out where that would have been to determine valid packets.

It's definitely worth connecting a PC up to the boat. It always helps to actually see what is happening in reality rather than in theory.

I am now thinking it could be easier than I first thought. I would still go for collision handling as per spec seeing as that's rather easy to do. Speed now seems more important than a large receive buffer so a 20X2 at 64MHz may be the ticket.
 

nekomatic

Member
By total coincidence I just read this which sounds as if it might be describing the same protocol (click 'read the full case study' for full details). The good news is they solved the problem... the bad news is they solved the problem using several grand's worth of hardware and software.
 
Last edited:

PeteV

New Member
I would still go for collision handling as per spec seeing as that's rather easy to do.
If it's easy then I suppose I should do it :). But it's not at all obvious to me how to go about it - any tips? In post 4 I set out a rough idea of how I plan to do things.

As I said in my first post, I'm completely new to embedded programming - in my day job, directly setting headers on an HTTP request counts as low-level :)

Pete
 

PeteV

New Member
By total coincidence I just read this which sounds as if it might be describing the same protocol (click 'read the full case study' for full details). The good news is they solved the problem... the bad news is they solved the problem using several grand's worth of hardware and software.
I doubt the Condor ferries are using Seatalk to monitor their engines :). And PIC hardware can definitely do it, there's a guy on my sailing forum who makes various Seatalk and NMEA gadgets similar to what I'm planning. But as a trimaran (no keel) sailor in Scotland (deep water), he had no interest in making this one.

Pete
 

hippy

Technical Support
Staff member
If it's easy then I suppose I should do it :). But it's not at all obvious to me how to go about it - any tips?
The advantage of a single wire bus is that anything sent is automatically received so whatever is sent out via serial is automatically received back. It's just a case then of sending out your 'cancel alarm' packet a byte at a time, and after each byte sent check the same was received. If so continue, else pause and restart sending the packet from the beginning.
 

PeteV

New Member
The advantage of a single wire bus is that anything sent is automatically received so whatever is sent out via serial is automatically received back. It's just a case then of sending out your 'cancel alarm' packet a byte at a time, and after each byte sent check the same was received. If so continue, else pause and restart sending the packet from the beginning.
Gotcha. So in my "byte received" interrupt I have another thing to check for, if I'm in "sending shut-up" state. I guess I'll have the current byte in a variable for sending purposes, so I can just compare against that in the interrupt. Yay for no scoping whatsoever in Picaxe :)

Pete
 
Top