Go Down

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

TobyMay

Asynchronous SeaTalk

Hope I've posted in the right place.
Last Monday somebody told me about the Arduino.  By the w.end  had a Relay shield driving motors in response to switches.  Now I'm loosing what hair I have left.

Big project, build a modular control system for a 40' sailing yacht (so that a high level quadriplegic can sail it).
Current step, replicate the PIC based system that controls her existing 20' boat (hence switches and motors).  Built by a guy in Canada some years ago, don't have very much info.
Current problem, getting a Mega to talk to a Raymarine ST4000+ autopilot.

The ST4000+ talks to the world over SeaTalk (see http://www.thomasknauf.de/seatalk.htm).  SeaTalk is a Raymarine proprietary bus. 
11 bits are transmitted for each character:
  1  Start bit (0V)
  8  Data Bits
  1  Command bit
  1  Stop bit (+12V)

Where I am at the moment is reading SeaTalk on Serial 3 and then sending it to Serial Monitor over the USB.  It looks like rubbish. What I want to know is how to set the serial port to 11 bits?  Is there a command or procedure?   How much control can be had over how the serial ports work?

In the Thomas Knauf article there code in C with the line:

_outb(0x3B, PORT+3); /*LCR Stick Parity to 0, Enable Parity, 1 Stop bit, 8 bits/char */

Does Arduino C++ have an equivalent command?

Thanks

Toby

sy kristina

As far as I remember, the Raymarine plug can comminucate on SeaTalk or NMEA. At least on the st1000 tiller pilots.

TobyMay

Kristina

Err...yes, the ST4000+ has NMEA0183. 

Getting the SeaTalk working on this is a stepping stone to getting access to another set up (S1 tiller pilot, C80, ST60 instruments) on another boat.  I want to be able to access the SeaTalk bus, read messages and send messages.  I eventually want to be able to plug any manufacturers equipment into a boat control computer.  Got to start somewhere.

So, how do I set up the serial port?

Toby

Nick Gammon

So far what you have described is absolutely standard RS232 (async serial) communications with 9 data bits (you don't count the start and stop bit).

And from the Atmega spec on page 180 it says:

Code: [Select]
A serial frame is defined to be one character of data bits with synchronization bits (start and stop bits),
and optionally a parity bit for error checking.

The USART accepts all 30 combinations of the following as valid frame formats:

• 1 start bit
• 5, 6, 7, 8, or 9 data bits
• no, even or odd parity bit
• 1 or 2 stop bits


So, you want to configure it for 9 data bits, no parity, and 1 stop bit (and of course the right baud rate).

I don't have a SeaTalk to test it with, so how about showing your test code and we'll take it from there?
Please post technical questions on the forum, not by personal message. Thanks!

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

TobyMay

Nick

Code is below.

Data sheet I have (2549M-AVR-09/10), "8-Bit AVR Microcontroller with...." is talking about PWM on page 180, so I guess its not the one you are talking about.  Page 215/216 looks like what your talking about but I don't have a clue how to write this into a sketch.


Code: [Select]
/*
  HLOR / Toby May
  Experimental stuff with Arduino Mega and home made hardware interface to SeaTalk.
  Rx only. 
  I.Face is a pair of resistors as a voltage dropper.
  Receives on serial port 3, sends to the main serial (Serial 0) and then to Monitor on a laptop.
  This example for Arduino Mega
  WORK IN PROGRESS - may not work!!!!!
*/

char not_receiver_buf,receiver_buf;

void setup()                                        // initialise both serial ports
  {
    Serial.begin(9600);   
    Serial3.begin(4800);
  }

void loop()
  {                                                 // Continuous data processing loop 
  if((Serial3.available()) > 0)                     // LSR New SeaTalk Data received ?
     {
        receiver_buf=Serial3.read();                // RBR Read SeaTalk Data Byte
        not_receiver_buf=~receiver_buf;             // Invert received character...
        Serial.println(not_receiver_buf, HEX);      // ...and prints it out. 
     }
  }

Nick Gammon

Ah I see you have a Mega. I was initially confused because they are all Atmega chips, so this is the Mega Atmega, right?

Well, I'm not filled with confidence, but this works converting my Uno to output 9 bits (on normal Serial, not Serial3):

Code: [Select]
Serial.begin(9600);   
UCSR0B = 0;  // turn off
UCSR0B = 0b10011100;  // turn on again in 9-bit mode


And this might possibly work for Serial3:

Code: [Select]
Serial3.begin(4800);
UCSR3B = 0;
UCSR3B = 0b10011100;


I'm a little troubled about where that 9th bit is going to come from (after all, normally a byte is 8 bits).

You could try that in reading mode anyway to see if you get reasonable data from the gadget.

Also this page seems relevant:

http://sailboatinstruments.blogspot.com/2011/02/seatalk-interface.html
Please post technical questions on the forum, not by personal message. Thanks!

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

Nick Gammon


In the Thomas Knauf article there code in C with the line:

_outb(0x3B, PORT+3); /*LCR Stick Parity to 0, Enable Parity, 1 Stop bit, 8 bits/char */


By the way, this is doing it a different way. I am guessing he is using space parity, which means "the parity bit is always zero". There is also mark parity which is "the parity bit is always one". However browsing the Atmega documentation it doesn't seem to support mark and space parity (only odd, even and none).

If your device supports space and mark parity, then that is a way (perhaps a rather obscure one) of putting a 0 or 1 into the 9th bit.
Please post technical questions on the forum, not by personal message. Thanks!

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

retrolefty

#7
Mar 04, 2011, 07:26 am Last Edit: Mar 04, 2011, 07:27 am by retrolefty Reason: 1
I looked in the AVR 328 datasheet under the USART section. And indeed the hardware USART can be made to handle 9 data bit sending and receiving data transactions. This is not related to enabling the parity bit, as it appears if you want to utilize the 9 bit mode you can't also have parity enabled, one or the other or neither option are your choices.  At least that's my read on the subject. It is however a little complex and requires extra steps to set up the 9th bit before sending the character out, or reading the 9th bit before reading the 8 bit character on received characters. This is certainly not something you can configure with the standard arduino serial commands. You would have to drop down to direct USART register controls and write your own serial library to accomplish 9 bit transactions. Like I said, a little complex and obscure but it is covered in the 328 datasheet in the USART section.

Lefty

Nick Gammon

Yes indeed. Looking at the datasheet is always interesting. It is interesting that they allow for 9 bits OR parity. It's almost as if the 9th bit is "parity on the fly".

Anyway, this seemed to work for me, to change the 9th bit for every other byte:

Code: [Select]
void loop()
  {                                         
  Serial.print ("a");
  UCSR0B = 0b10011101;  // turn 9th bit on
  Serial.print ("a");
  UCSR0B = 0b10011100;  // turn 9th bit off
  }


The low-order bit of the UCSRnC register (where n is the serial port) is the 9th bit. So by setting or clearing that before you send a byte, you control the contents of the 9th bit.

Please post technical questions on the forum, not by personal message. Thanks!

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

teeman

My solutions was to adapt the softserial library to get a 9th data bit. It was quite easy in the recv function. afther the loop, add an extra delay and receive the parity bit.

You have to juggle a bit with data types to get the 9th bit in the recv buffer. I cahnged the type from byte to int and shift the 9th bit completely to the left.

jferg

teeman,
could you share your softwareserial mod?  I have Thomas Knauf's code for a pc, but bridging the gap in my understanding of how to mod the usart on the arduino uno is still beyond me.

best, john

DavidFoe

Teeman,

Add me to the list of people interested in seeing your mods.  I'm trying to talk to a raymarine display (no nmea) and it sounds like you have it figured out.  Please share!

David

jferg

David,
Frank Wallenwein makes an excellent nmea-seatalk bridge.  It is an ATMEGA32 small computer which accepts seatalk and nmea sentences and converts each type to the other and sends them out to their respective ports.  I have one and it works brilliantly allowing me to show depth, windspeed and windangle on my notebook computer running PolarView (an inexpensive and excellent charting program which runs on Linux, MacOS, and Windows).

you get all of Frank's code on a cd when you buy the bridge (something about buying a bridge seems a bit off, but there it is).  Code is C and wrritten for the Atmega32 .

my effort is to get part of it ported to arduino uno, although I think I'm going to get a mega2560 - won't have to cut so much.  i wanted a repeater in my berth which shows heading, windspeed, wind-direction, depth, and distance and bearing to last time I pressed rest button - for drag detection.

I can do all this by feeding nmea-seatalk bridge data to arduino and input from arduino mounted tilt compensated compass, but I thought it would be better just to feed seatalk to arduino (wind and depth) and have one fewer devices running.

you may be able to get Frank's code if you ask him - don;t know, but i thought the Bridge was well worth the price.

he's at:

http://www.gadgetpool.de/nuke/modules.php?name=Forums&file=viewforum&f=12

DavidFoe

Thanks JFerg,

Buying a seatalk<->nmea bridge was what I had hoped to avoid though thanks very much for the pointer to a low cost supplier as I may go that way if I have to.  A Seatalk hack would be an awesome contribution to the sailing-arduino fan base!  I understand that the signal would need to be turned into a 0-5 V TTl or rs232 or whatever and I can do that but modifying the softwareserial library to read the 9 bit seatalk protocall is currently beyond me. If someone were to make a library available, they would attain hero status amongst those of us on a budget and who are sailing older boats with 20 year old instruments!

I am building an arduino based autopilot for my boat and I was hoping to use (as additional input) wind direction (it's a sail boat) and boat speed  (to try to make a surfing mode functionality and to adjust rudder response for one of the PID loops) from my existing ST50 instruments.  I also have a spare raymarine ST50 display that I would like to use to display heading info from my fluxgate compass.  The arduino works well for the compass NMEA and for controlling the linear actuator and with relatively little effort I have something that looks like it will drive the boat quite well (its too cold to test on the water now).   Sailing to the wind and a sparkfun gyro are the next steps.

David




Nick Gammon

As I mentioned further up, you can do the 9th bit with hardware serial. Can't you rejig your design so you use hardware serial for the 9-bit comms?
Please post technical questions on the forum, not by personal message. Thanks!

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

Go Up