MAX232 RS-232 communication to hyperterminal

Hi,

I started experimenting today with interfacing the Arduino to a computers COM-port using the MAX232 chip.

My code comes exactly out of this tutorial:

ArduinoSoftwareRS232
(I'm not able to include the hyperlink as this is my first message on the forum -the tutorial can be found on this website)

Hardware is completely set as in the tutorial, only the chip is different and I'm using pin 7 and 10 as Tx/Rx

I open hyperterminal up and set it to 9600 baud, 8 databits, no parity, 1 stop bit, as described in the tutorial. When I start typing in character, it does return me a character, but not the right one.

By comparing the binary values in the ASCII table I was able to tell that the decimal difference between typed and returned character was exactly 128. So I figured that somehow there was a problem with the 8th bit. When I set the hyperterminal settings to: "9600, 7databits, no parity, 1 stop bit" this problem seems to be solved. When I type in "a", the character "a" returns.

Also, the debugging start message "hi", appears as "45" and a non-displayable character. So basically, the problems that I have:

-Why does the "hi" doesn't display?
-Why do I have to set hyperterminal to 7-databits, while it should be 8-bits according to the tutorial?
-Why do the characters typed just return exactly as I type them? They are supposed to be capitalized (that's the purpose of the program).

Any help is greatly appreciated!
Thanks,
Jens

It looks like there are bits shifted,
h = 0110 1000
4 = 0011 0100 / / all bits shifter 1 pos

i = 0110 1001
5 = 0110 0101 // all bits shifted except the last

Then again, it could be a timing problem. Please try another terminal program like putty or teraterm to see if you have similar problems,

Please post a second message the code used. (use the # button for the [ code] tags)

only the chip is different

Did you check the datasheet of this alternative chip?

They are supposed to be capitalized

Capitalizing characters in ASCII is done by subtracting 32 or 0x20 if that is done on the wrong bit it could explain that every character is 128 to big ...

//Created August 23 2006
//Heather Dewey-Hagborg
//http://www.arduino.cc

#include <ctype.h>

#define bit9600Delay 84  
#define halfBit9600Delay 42
#define bit4800Delay 188 
#define halfBit4800Delay 94 

byte rx = 8;
byte tx = 10;
byte SWval;

void setup() {
  pinMode(rx,INPUT);
  pinMode(tx,OUTPUT);
  digitalWrite(tx,HIGH);
  digitalWrite(13,HIGH); //turn on debugging LED
  SWprint('h');  //debugging hello
  SWprint('i');
  SWprint(10); //carriage return
}

void SWprint(int data)
{
  byte mask;
  //startbit
  digitalWrite(tx,LOW);
  delayMicroseconds(bit9600Delay);
  for (mask = 0x01; mask>0; mask <<= 1) {
    if (data & mask){ // choose bit
     digitalWrite(tx,HIGH); // send 1
    }
    else{
     digitalWrite(tx,LOW); // send 0
    }
    delayMicroseconds(bit9600Delay);
  }
  //stop bit
  digitalWrite(tx, HIGH);
  delayMicroseconds(bit9600Delay);
}

int SWread()
{
  byte val = 0;
  while (digitalRead(rx));
  //wait for start bit
  if (digitalRead(rx) == LOW) {
    delayMicroseconds(halfBit9600Delay);
    for (int offset = 0; offset < 8; offset++) {
     delayMicroseconds(bit9600Delay);
     val |= digitalRead(rx) << offset;
    }
    //wait for stop bit + extra
    delayMicroseconds(bit9600Delay); 
    delayMicroseconds(bit9600Delay);
    return val;
  }
}

void loop()
{
    SWval = SWread(); 

    SWprint(toupper(SWval));

}

I did check the MAX232 datasheet. For me, the only difference is the value of the capacitor (I had to use 1µF in stead of 0,1). It would suprise me if the problem lies in the hardware (but obviously I'm not sure.. :))

I still have to check with another terminal program. Will keep you updated.

Thanks for the fast reply!

(I had to use 1µF in stead of 0,1)

Hmm. Not even that as I see now :slight_smile: The ones in the tutorial are 1µF as well..

I just check with Tera Term. Same problem.

Hi Jens, I think I recognize the problem. Your code clocks out the bits using some magic numbers. And if you read enough fairytales you know that "magic spells" should be 100% correct to work properly or otherwise very nasty things happen :slight_smile:
There is a big chance that your magic numbers are not 100% right for 9600 baud and clocking out the data fails (drifts).

Have a look at the NewSoftSerial library (google for it) to use for Serial communication, it works very well.

Rob

Try also to replace this modified version, it might work better as the receiving end will sample in the middle of the pulses iso at the edges. (make a drawing to understand the difference better)

void SWprint(int data)
{
  byte mask;
  //startbit
  digitalWrite(tx,LOW);
  delayMicroseconds([glow]halfBit9600Delay[/glow]);  //line changed
  for (mask = 0x01; mask>0; mask <<= 1) {
    if (data & mask){ // choose bit
     digitalWrite(tx,HIGH); // send 1
    }
    else{
     digitalWrite(tx,LOW); // send 0
    }
    delayMicroseconds(bit9600Delay);
  }
  //stop bit
  digitalWrite(tx, HIGH);
  delayMicroseconds(bit9600Delay);
}

Update: ^^ does not work see below.

The half delay suggestion didn't work. It still returns characters but again -not the right ones :slight_smile:

Then you have to look for it in the magic numbers.

I notice now that your 4800 delay is 188, 9600 should be approx half 94 ? it is defined as 84 however.

1.000.000 / 9600 = 104 so by looking at the numbers I think the are too small

replace

#define bit9600Delay 84 // and the half version

in small steps to 104 max to find better magical numbers .

Any help is greatly appreciated!

Step 1: get rid of the software serial you found.

Step 2: download NewSoftSerial.

Step 3: enjoy tested, working, maintained software.

-j

Step 2: download NewSoftSerial.

Actually, this seems to be doing the trick :slight_smile: I just have started testing, with this code it will nicely count from 0 to 16 in hyperterminal, 8 databits.

#include <NewSoftSerial.h>                  

NewSoftSerial mySerial(8, 10);            


void setup()
{
mySerial.begin(9600);                  
}


void loop() {

for (int i=0; i <= 16; i++)
  {
    mySerial.print(i);      
    delay(1000);
  }
}

Now I just need to figure out all the possibilities of this library.

Thanks a lot,
Jens