Pages: [1]   Go Down
Author Topic: serial on different pins than 0 or 1  (Read 3684 times)
0 Members and 1 Guest are viewing this topic.
Canada
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
I Love Arduino!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, is it easy to implement serial communication on pins other than 0 or 1.
I do not need to have 2 simultaneous serial connections, I would like to use pins 11 and 12 instead (as they are linked with the ICSP connector and provide an easy way to connect external devices.

Tom
Logged

Thomas Ouellet Fredericks

Forum Administrator
Cambridge, MA
Offline Offline
Faraday Member
*****
Karma: 12
Posts: 3538
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It's not so easy: there are plenty of libraries that provide a software serial port on any pins, but all the ones I've seen require the use of hardware timers, which on Arduino are already used (for millis() and PWM generation).  Could you try something hacky like configuring pins 11 and 12 as input and connecting them to pins 0 and 1?  

We've managed to put together a function to send serial data out, but not yet one that receives it.  Here's the serial out code, which should work at 9600 and 19200 baud, at least:

Code:
#define BAUDRATE 9600

int tx = 7;

// function that puts a byte of data to software serial port
void serout(int txPin, byte data)
{
  int bitDelay = 1000000 / BAUDRATE - 25;
  byte i = 0;
  byte mask;

  digitalWrite(txPin, LOW);
  delayMicroseconds(bitDelay);

  for (mask = 0x01; mask; mask <<= 1) {
    if (data & mask){ // choose bit
      digitalWrite(txPin,HIGH); // send 1
    }
    else{
      digitalWrite(txPin,LOW); // send 1
    }
    delayMicroseconds(bitDelay);
  }

  digitalWrite(txPin, HIGH);
  delayMicroseconds(bitDelay);
}

void setup() {
  pinMode(tx,OUTPUT);
}

void loop() {
  serout(tx,'h');
  serout(tx,'e');
  serout(tx,'l');
  serout(tx,'l');
  serout(tx,'o');
  delay(1000);
}
Logged

Rennes
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everybody,

I have the same question as Tof, but in my case, I need to have 2 simultaneous serial connections. The previous code can help me to send data on a second serial line, but there is still the problem to receive data on the second serial connection.
Mellis, you talked about libraries that provide a software serial, as far as there is an unused hardware timer. Is it possible to add a second timer to Arduino (for example on an digital pin) and then use it for the software serial?

Antonio
Logged

Forum Administrator
Cambridge, MA
Offline Offline
Faraday Member
*****
Karma: 12
Posts: 3538
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It's probably easier to try to get a purely software serial (i.e. no hardware timers) working.  Here's some code that tries to do, but doesn't quite work.  

The fudge variable is used to slightly adjust the delay between bits for each byte read - an attempt to get the timing exactly right.  

Code:
#define BAUDRATE 9600

// the width of a single bit of serial data in microseconds
// in each second (1000000 microseconds) there are a number of bits equal
// to the baud rate (e.g. 9600), so each bit lasts for 1000000 / baudrate
// microseconds
int width = 1000000 / BAUDRATE;
int fudge = 20;
int val = 0;
int count = 0;

int rx = 6;

void setup() {
  pinMode(rx,INPUT);
  digitalWrite(13,HIGH);
  beginSerial(BAUDRATE);
}

void loop() {
  int offset;
  boolean error = true;

  // one byte of serial data (LSB first)
  // ...--\    /--\/--\/--\/--\/--\/--\/--\/--\/--...
  //       \--/\--/\--/\--/\--/\--/\--/\--/\--/
  //      start  0   1   2   3   4   5   6   7 stop

  while (digitalRead(rx));

  // frame start indicated by a falling edge and low start bit
  // jump to middle of start bit
  //delayMicroseconds(width / 2 + fudge);

  // confirm that this is a real start bit, not line noise
  //if (digitalRead(rx) == LOW) {

    for (offset = 0; offset < 8; offset++) {
      // jump to middle of next bit
      delayMicroseconds(width + fudge);
      val |= digitalRead(rx) << offset;
    }

    // check stop bit is high
    delayMicroseconds(width + fudge);
    if (digitalRead(rx) == HIGH) {
      error = false;
    }
    serialWrite(val);
    count++;
    if (count % 2 == 0) {
      fudge--;
      serialWrite(width + fudge);
    }
  //}
}
Logged

China
Offline Offline
Jr. Member
**
Karma: 0
Posts: 60
I love Arduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi ! mellis , I also very want the  software serial  too, can I use the codes you gived together ? (I means full duplex)

and about the hardware timers , I know a timer IC called :"555" , and there is a software(English) help people to use it , you can download : http://fallen11.googlepages.com/555timer_install.rar
but I don't have experience to programme a software serial  use this IC , if you have some codes or examples about let Arduino work with it , please help us , thank you !
Logged

Rennes
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Finally, Fabrice and I got something quite interesting. The previous code for software Rx didn't work for us. So we changed some things (don't ask us why it works now, we don't really know ...).

______                                      _________                ______
|         |         __________          |               |              |          |
| PC1  |-------|  MAX233  |--------|  Arduino  |-----------|  PC2  |
|_____|         |_________|          |________|              |______|

Our PC1 serial Tx is connected on our new software Rx (pin 6) through a MAX233 (to switch from RS232 to TTL). Arduino is connected to PC2 with the classical hardware serial link.
When I type a text in a hyperterminal on PC1, it is received by Arduino and sent back on PC2 hyperterminal.

It works for a typed text, but not yet by sending a text file.  

Here is the modified software Rx code:

Code:
#define BAUDRATE 9600

// the width of a single bit of serial data in microseconds
// in each second (1000000 microseconds) there are a number of bits equal
// to the baud rate (e.g. 9600), so each bit lasts for 1000000 / baudrate
// microseconds
int width = 1000000 / BAUDRATE;
int fudge = -25;
unsigned int val = 0;
int count = 0;
int state = 0;

int rx = 6;

void setup() {
  pinMode(rx,INPUT);
  digitalWrite(13,HIGH);
  beginSerial(BAUDRATE);
}

void loop() {
  int offset;
  boolean error = true;

  // one byte of serial data (LSB first)
  // ...--\    /--\/--\/--\/--\/--\/--\/--\/--\/--...
  //       \--/\--/\--/\--/\--/\--/\--/\--/\--/
  //      start  0   1   2   3   4   5   6   7 stop

  while (digitalRead(rx));

  // frame start indicated by a falling edge and low start bit
  // jump to middle of start bit
  //delayMicroseconds(width / 2 + fudge);

  // confirm that this is a real start bit, not line noise
  if (digitalRead(rx) == LOW) {
    delayMicroseconds(width/2);
    
    for (offset = -1; offset < 8; offset++) {
      // jump to middle of next bit
        val |= (digitalRead(rx) << offset);
      delayMicroseconds(width + fudge);
    }

    // check stop bit is high
    delayMicroseconds(width + fudge);
    if (digitalRead(rx) == HIGH) {
      error = false;
    }

    Serial.print(val,BYTE);
    val = 0;

  }
}

It seems to be very sensitive to time delay. As soon as you add some code, the pin value can be sampled at a wrong instant.

Antonio
Logged

Forum Administrator
Cambridge, MA
Offline Offline
Faraday Member
*****
Karma: 12
Posts: 3538
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Very cool!  We've been trying to get this working for a long time.

By using a faster baud rate to send data back to the computer from the Arduino board, I was able to almost handle file transfers.  I also cleaned up the code a bit.  Here it is:

Code:
#define BAUDRATE 9600

// the width of a single bit of serial data in microseconds
// in each second (1000000 microseconds) there are a number of bits equal
// to the baud rate (e.g. 9600), so each bit lasts for 1000000 / baudrate
// microseconds
int width = 1000000 / BAUDRATE;
int fudge = -25;
int rx = 6;

void setup() {
  Serial.begin(115200);
  pinMode(rx,INPUT);
  digitalWrite(13,HIGH);
}

void loop() {
  int val = 0;
  
  // one byte of serial data (LSB first)
  // ...--\    /--\/--\/--\/--\/--\/--\/--\/--\/--...
  //       \--/\--/\--/\--/\--/\--/\--/\--/\--/
  //      start  0   1   2   3   4   5   6   7 stop

  while (digitalRead(rx));

  // confirm that this is a real start bit, not line noise
  if (digitalRead(rx) == LOW) {
    // frame start indicated by a falling edge and low start bit
    // jump to the middle of the low start bit
    delayMicroseconds(width / 2);
    
    // offset of the bit in the byte: from 0 (LSB) to 7 (MSB)
    for (int offset = 0; offset < 8; offset++) {
      // jump to middle of next bit
      delayMicroseconds(width + fudge);
      
      // read bit
      val |= digitalRead(rx) << offset;
    }
    
    delayMicroseconds(width + fudge);

    Serial.print(val, BYTE);
    
    val = 0;
  }
}
Logged

Canada
Offline Offline
Jr. Member
**
Karma: 0
Posts: 75
I Love Arduino!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

There are probably hardware solutions that could be more effective:
http://www.acroname.com/robotics/info/ideas/sermux/sermux.html

Or even more promising, check the circuit on page 10c.3 of:
http://www.ece.utexas.edu/~valvano/metrowerks/Lab10c.pdf

One master device, many slaves.

Tom
Logged

Thomas Ouellet Fredericks

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I want to be able to transmit data on an RS-485 interface using the Arduino. Will the MAX2232 chip work or should I use something else?
Logged

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

How do you even transmit data out of a pin? i cannot get anything to work. when i think i am transmitting, i can unplug the usb cord and get errors. I have a Duemilanove and tried serial.write  , digitalWrite and got nothing. Any help would be greatly appreciated.

Thank you
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

See the first post in this thread : http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1233298805

This has a link to NewSoftSerial, a library tha enables you to send (and receiver) on any data pin
Logged

Pages: [1]   Go Up
Jump to: