Pages: [1] 2   Go Down
Author Topic: Mods to HardwareSerial to handle 9-bit data  (Read 4449 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Following on from a discussion in this thread:

http://arduino.cc/forum/index.php?topic=54120

The posters there wanted to use the "9th" bit in async comms to communicate with some gadget that uses that extra bit as a "command" bit.

This turned out to be a bit non-trivial, so I have made an amended HardwareSerial library, which can be downloaded from here:

http://gammon.com.au/Arduino/HardwareSerial9bit.zip

The diffs for any developers interested are:

http://gammon.com.au/Arduino/hardwareSerial_diffs.txt

Because of the way that hardware serial is integrated into the IDE it is, unfortunately, necessary to find your existing files:

Code:
HardwareSerial.cpp
HardwareSerial.h

... and replace them with the ones in the download.

Note that this is for version 1.0 1.0.1 of the IDE. No guarantees are given that this will work with other versions. Be warned.

Changes:

  • The internal buffers have been changed from 8-bit characters to 16-bit characters (to hold the 9th bit). Thus the buffers double in size.
  • There is a new argument to the Serial.begin() function, which is a boolean, whether or not you want 9-bit mode. It defaults to false.
  • There is a new function Serial.write9bit (). This takes an unsigned int argument, letting you supply a character with the 9th bit set. I didn't want to change the existing write function because it is used in the Print class.
  • The read function, which already returns an int, now will return the 9th bit where required.

Test sketch, run on a Mega2560:

Code:
void setup ()
{
  Serial.begin (115200);  // debugging prints
  Serial1.begin (115200, true);  // 9 bit mode
  Serial2.begin (115200, true);  // 9 bit mode
  Serial.println ("--- starting ---");
}  // end of setup

int i;

void loop ()
{

  Serial1.write9bit (i++);  // send another byte
  
  // display incoming on Serial2
  if (Serial2.available ())
    Serial.println ((int) Serial2.read (), HEX);
    
  // check if we have sent all possible characters
  if (i >= 0x200)
    {
    delay (100);
    while (Serial2.available ())
      Serial.println ((int) Serial2.read (), HEX);
    delay (5000);
    i = 0;
    }  // end of sent 512 bytes
}  // end of loop

The sketch uses Serial (pins D0 and D1) for debugging. To test jumper D18 (Tx1) and D19 (Rx2).

The sketch will send all possible 512 bytes out from Serial1, and read them into Serial2, displaying them on Serial for manual evaluation.
« Last Edit: October 29, 2012, 07:55:56 pm by Nick Gammon » Logged

Greenville, IL
Offline Offline
Edison Member
*
Karma: 11
Posts: 1309
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


 Wow Nick! You have been on a role lately with all of the things you have been doing! I find myself referring to your posts and your blog quite a lot lately.

 I am curious would it be difficult to change to 7-bit data? In some automotive applications I am lead to believe they use 7-bit but, don't quote me on that.
Logged


Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When I was doing that change I noticed there didn't seem to be any provision for different bit lengths, let alone 9 which was the trickiest.

Changing to other bit lengths should be trivial.

However for 7-bits you can "fudge" that by setting the high-order bit of the data you are sending. Since the high-order bit is sent last, and a stop bit is a 1, if you make sure that the high-order bit is a 1, then 8 bits of data with the high-order bit set, would look like 7 bits followed by a stop bit (well, 2 stop bits).

For receiving, just mask out the high-order bit (eg. "and" it with 0x7F).
Logged

Greenville, IL
Offline Offline
Edison Member
*
Karma: 11
Posts: 1309
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


 Ok, masking bits would be a lot simpler than changing library definitions. Thanks Nick!
Logged


Offline Offline
Jr. Member
**
Karma: 0
Posts: 64
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nick,
could you check the download url?  I get looped back to this page.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 64
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oops, the loopback was so fast, I didn't realize that the file had downloaded. thank you so much Nick.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12430
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

As allways great inspiring job Nick,
thanks
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Guildford, UK
Offline Offline
Full Member
***
Karma: 0
Posts: 217
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am curious would it be difficult to change to 7-bit data? In some automotive applications I am lead to believe they use 7-bit but, don't quote me on that.
If you want 5 - 8 bits of serial data, have you considered this library?

It replaces the existing HardwareSerial and it's quite a bit faster and has configurable buffer sizes (transmit and receive).

http://arduino.cc/forum/index.php/topic,85207.0.html

Iain
Logged

Greenville, IL
Offline Offline
Edison Member
*
Karma: 11
Posts: 1309
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


 I have downloaded that library. I forgot some of the things it is capable of. Thanks!
Logged


Guildford, UK
Offline Offline
Full Member
***
Karma: 0
Posts: 217
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Make sure you have the latest version. I'm not sure the variable bit stuff was in the early versions.

Iain
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 77
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

this is exactly what i am looking for, but i am not successful in getting it to work.
using arduino 1.01

I am using an Ardino UNO and have a max232 connected to pins 0 and 1

at the device i can see the bytes i am sending from the UNO but none of them have the ninth bit set

i have download and installed the revised hardwareserial files

and am using the following in the setup
 Serial.begin(19200,true);

and

in the loop
Serial.write9bit(0x03); //wakeup device at address
delay (10);
Serial.write(0x17);      // command
delay (10000);

Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It looks like those amendments didn't work perfectly with 1.0.1 of the IDE.

The files above (same names) have been amended now and should work with 1.0.1. This test checked out on the logic analyzer:

Code:
void setup ()
{
  Serial.begin (115200, true);  // 9 bit mode
  Serial.println ("--- starting ---");
}  // end of setup

int i;

void loop ()
{

  for (i = 0; i <= 0x1FF; i++)
    Serial.write9bit (i);  // send another byte
 
}  // end of loop
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 77
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks i will test it in my code tommorrow
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 36
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Nick et al.,
I know this topic is fairly old, but figured it was best to ask the question here vs. starting a new thread?

I recently got involved in a project where 9-bit serial data was required, and not really knowing what to do I was pretty excited to see Nick's work here (thanks, Nick!).

So my quick question is whether or not the mods to the library are specific to AVR-based micros, or more specifically will the mod work with ARM-based micros? I just don't know enough about how libraries work (yet) to be able to answer this question myself.

Thanks in advance for any pointers, and thanks again Nick for your work here!

Cheers,
David
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You are welcome.

The mod was specific to the way that the hardware on this particular processor worked. It probably can be carried over to similar ones in the same line (eg. the Mega2560).

As for ARM ones, they would have different hardware interaction. Quite possibly they might support some sort of 9-bit serial, however I just don't know.
Logged

Pages: [1] 2   Go Up
Jump to: