Go Down

Topic: Mods to HardwareSerial to handle 9-bit data (Read 28696 times) previous topic - next topic

marijn

Hi,

I finally came to make my Seatalk project. I started out here and downloaded Nick great code. Thanks Nick.
Then it was time to make the hardware to read the Seatalk data. And things did not compute. I got the wrong commands and it did not work.
Until I looked on a logic analyser (Analog discovery 2, great toy if you can get the edu discount ) the code was inverted. All the schematics I found did invert the signal.
I used: this but this one inverts! So I added an ttl inverter to the rx and tx in fact I did use a 74LS86B a 4 dual EXOR gates. By pulling one input of the EXOR high it inverts the other input on the output. If pulled low it does not invert. Very handy while experimenting with stuff like this. In the schematic R6 should be lower like 1.5K else the gate will not go low.

In the protocoll there is no end character. But after 10mS an other sender can take the line. On the logic analyser the most time between two bytes of the same message was 4.45ms. So I wait for 6mS to process the input buffer.
After 10mS no data the code can send commands to the bus.
It is only the first setup of the code:

Code: [Select]
/*
 * The seatalk receive circuit mut be NON-INVERTING there are many wrong circuits out there. I could only find the wrong versions!
 * I used: http://berreizeta.blogspot.de/2016/10/blog-post.html but this one inverts! So I added an ttl inverter to the rx and tx.
 * in fact I did use a 74LS86B a 4 dual EXOR gates. By pulling one input of the EXOR high it inverts the other input on the output. If
 * pulled low it does not invert. Very handy while experimenting with stuff like this. In the schematic R6 should be lower like 1.5K
 * else the gate will not go low.
 * The code is my first setup but you get my drift
 */
#define SEATALKBUBLEN 20
char seaTalkBufRX[SEATALKBUBLEN]; //longest string found = 16 bytes
char seaTalkBufTX[SEATALKBUBLEN]; //longest string found = 16 bytes

void setup() {

  Serial.begin(115200);
  Serial1.begin(4800,SERIAL_8N1, true); //this is the only init possible if you leave out SERIAL_8N1 you get 8 bit!
  //The seatalk receive circuit mut be NON-INVERTING there are many wrong circuits out there. I could only find the wrong versions!

}

void loop() {
  // put your main code here, to run repeatedly:
  int i;
  int n=0;
  unsigned long t1;
  t1=millis();
  while(1)
  {  
  while(Serial1.available())
  {
    t1=millis();
    i=Serial1.read();
    i=i&0x1ff; //if there is leftover data in the high byte delete this.
    if(i & 0x100)
      Serial.println(' ');
    Serial.print(i,HEX);
    Serial.print(' ');
    seaTalkBufRX[n]=i;
    n++;
  }
  if(millis()-t1>6) //there is no closing char. but the most time between bytes is 4.45ms (on my logic analyser) 6ms should be safe
    DoBufRX();
  if(millis()-t1>=10)
    SendSeatalk();
  }
}

void SendSeatalk(void)
{
  //here goes the send commands. 10ms no data on the bus is bus is free for data
}

ClearBuf(char * buf, int len)
{
  for(int i=0;i<len;i++)
    buf[i]=0;
}

void DoBufRX(void)
{
  //do your rx stuff here
  
}


I hope this helps making your seatalk project.

wbiter

were you able to read data being sent from an actual seatalk device.  Like Martin in the previous post, I also set this one and everything seemed to be working fine, but getting nonsense from the ST 60.  Will try the non-investing approach next time on the boat.

amano001

#32
Dec 18, 2018, 05:10 am Last Edit: Dec 18, 2018, 05:38 am by amano001
Hey Nick just wanted to say thanks for writing this library! 

It seems like I have the read working and I can see the incoming 9th bit from my device but when I try to write the char 0x85 my oscilloscope is showing a 0? 

I did look through your code some and saw something about low baud rates, I am down at 1200 if that makes a difference?

Using Arduino Mega 2560 Arduino 1.8.5 (I will try using the version you posted as well in the meantime just to rule that out)
 Serial1.write9bit(0x85);

Thanks again!

Update: tried using 1.6.9 to compile but still same issue not getting the 9th bit set when using the write9bit function.

Update2: Am I supposed to write Serial1.write9bit(0x185); in order to have the 9th bit set?  I see on my oscilloscope 0x185 on the output now but I may be a little lost.

dgholstein

I've installed the ZIP and added the CPP file but get, "prototype for 'void HardwareSerial::begin(long unsigned int, byte, bool)' does not match any in class 'HardwareSerial'"

It bombs out on:
 
Code: [Select]
 void HardwareSerial::begin(unsigned long baud, byte config, bool use9Bits) {...}
Your prototypes are:
Code: [Select]
   void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
   void begin(unsigned long, uint8_t, bool use9Bits = false);

Can anyone explain what's going on? I have limited experience overloading a function but it looks like the second of the begin() functions matches the hardware declaration.

Go Up