arduino to RS232

Hi, im trying to communicate with arduino through my rs232 port and a terminal window, not the arduino IDE. I am using a MAX3233 chip and can communicate with the arduino.

my problem is storing each character and waiting for a CR or LF to “process” the command. as it is now my code (i grabbed from here) only looks at each character sent and blinks an LED. id like to change it so that a command say, “blink” then enter makes it blink.

can someone help me? ive tried a bunch of things and just cant get it to work. thanks in advance

#define bit9600Delay 100  
#define halfBit9600Delay 50
#define bit4800Delay 188 
#define halfBit4800Delay 94 

byte rx = A0;
byte tx = A1;
byte SWval;

void setup() {
  pinMode(rx,INPUT);
  pinMode(tx,OUTPUT);
  digitalWrite(tx,HIGH);
  delay(2);
  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(); 

    digitalWrite(13,LOW);
    delay(500);
    digitalWrite(13,HIGH);
    //SWprint(SWval);
     
}

Create an array of bytes of say 10 elements.
Store each byte received into the array.
When you receive the carriage return byte = 13, append NULL to the array of bytes.
Use strcmp( ) to compare what you received to what you expect.

Do a search for the "serial input basics" thread to get some ideas. Don't have link at hand at this moment

yeah, using this i can get it to work through the arduino IDE serial terminal. I need to be able to use tera term or some sort of terminal program.

David7099:
yeah, using this i can get it to work through the arduino IDE serial terminal. I need to be able to use tera term or some sort of terminal program.

What is “this”?

Further, all terminal programs are more or less the same; if your Arduino code works with serial monitor, it should also work with others. Maybe a configuration setting in the PC terminal program.

sterretje: What is "this"?

Further, all terminal programs are more or less the same; if your Arduino code works with serial monitor, it should also work with others. Maybe a configuration setting in the PC terminal program.

sorry, i meant "this" being the "serial input basics"

the code needed for me to communicate with the arduino with the IDE serial terminal and a typical terminal is quite different. sorry, im just confused.

What the heck are you doing with A0 and A1 for your serial communication ? ? ? ?

ieee488: What the heck are you doing with A0 and A1 for your serial communication ? ? ? ?

im new to this. it works, why cant i?

David7099: im new to this. it works, why cant i?

I have no clue what you are trying to do.

Out of here.

.

ieee488: I have no clue what you are trying to do.

Out of here.

.

Does it feel good to talk down to people looking for help? Does it make you feel better about yourself?

I was clear about what I was trying to do.

ieee488:
What the heck are you doing with A0 and A1 for your serial communication ? ? ? ?

@David7099 is bitbanging a serial port on A0 and A1; I guess you would not have complained if it would have been SoftwareSerial on those pins.

David7099:
my problem is storing each character and waiting for a CR or LF to “process” the command. as it is now my code (i grabbed from here) only looks at each character sent and blinks an LED. id like to change it so that a command say, “blink” then enter makes it blink.

I don’t have something like a MAX232 at hand at the moment, so I have modified your SWprint and SWread to use the serial port and behave similar. You should be able to use your originals if they currently work.

int SWread()
{
  while (Serial.available() == 0);
  return Serial.read();
}

void SWprint(int data)
{
  Serial.write(data);
}

The below is Robin’s recvWithEndMarker function, modified to use your SWread. I’ve taken the while loop to check for available characters out as it will not work with your SWread.

void recvWithEndMarker()
{
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  // read character from bitbanged serial port
  rc = SWread();

  if (rc != endMarker)
  {
    receivedChars[ndx] = rc;
    ndx++;
    if (ndx >= numChars) {
      ndx = numChars - 1;
    }
  }
  else
  {
    receivedChars[ndx] = '\0'; // terminate the string
    ndx = 0;
    newData = true;
  }
}

I’ve made a slightly simpler version of Robin’s showNewData that uses your SWprint; it simply loops through the characters in the buffer like Serial.print does.

Next in loop(), you can check the newData flag; it will be true if a LF was received, else false. This part differs a little from Robin’s example.

void loop()
{
  recvWithEndMarker();
  if (newData == true)
  {
    newData = false;
    showNewData();
  }
}

Tested with realterm and serial monitor.

Just a note on the last line in your setup(). You’re working with characters, so why do you print the decimal value 10? It would make sense to show that you’re sending a linefeed

  SWprint('\n');

In which case you also don’t have to add the incorrect comment (it’s a LF, not a CR :wink: )

Hope that this gets you on track; full code below

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
bool newData = false;

#define bit9600Delay 100
#define halfBit9600Delay 50
#define bit4800Delay 188
#define halfBit4800Delay 94

byte rx = A0;
byte tx = A1;
byte SWval;


void SWprint(int data)
{
  Serial.write(data);
  return;

  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()
{
  while (Serial.available() == 0);
  return Serial.read();

  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 setup() {

  Serial.begin(57600);

  pinMode(rx, INPUT);
  pinMode(tx, OUTPUT);
  digitalWrite(tx, HIGH);
  delay(2);
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH); //turn on debugging LED

  SWprint('h');  //debugging hello
  SWprint('i');
  SWprint('\n');
}

void loop()
{
  recvWithEndMarker();
  if (newData == true)
  {
    newData = false;
    showNewData();
  }
}

void recvWithEndMarker()
{
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  // read character from bitbanged serial port
  rc = SWread();

  if (rc != endMarker)
  {
    receivedChars[ndx] = rc;
    ndx++;
    if (ndx >= numChars) {
      ndx = numChars - 1;
    }
  }
  else
  {
    receivedChars[ndx] = '\0'; // terminate the string
    ndx = 0;
    newData = true;
  }
}

void showNewData()
{
  // print the characters one-by-one
  for (uint8_t cnt = 0; cnt < strlen(receivedChars); cnt++)
  {
    SWprint(receivedChars[cnt]);
  }
}

Note 1)
There are libraries for what you’re trying to do :wink:
Note 2)
I have removed the debug led as it will interfere with the SWread when using serial monitor; in realtearm, it will work if you type with a speed less than the flash time (1 character per second).

sterretje: @David7099 is bitbanging a serial port on A0 and A1; I guess you would not have complained if it would have been SoftwareSerial on those pins.

Yeah, let's use bit banging for this.

A great idea. So obvious. NOT.

Take something simple, and let us make it complicated! That's the idea.

.

David7099: Does it feel good to talk down to people looking for help? Does it make you feel better about yourself?

I was clear about what I was trying to do.

Talk down?

Yeah, pick up code that uses bit banging.

It makes no sense to me to do it this way.

Bit bang the letter 'b'. 00110010 Then bit bang the letter 'l' 00111010 Then bit bang the letter 'i' 00111001 Then bit bang the letter 'n' 00111110 Then bit bang the letter 'k' 00111010

It is so intuitive. NOT.

ieee488:
Talk down?

Yeah, pick up code that uses bit banging.

It makes no sense to me to do it this way.

Bit bang the letter ‘b’. 00110010
Then bit bang the letter ‘l’ 00111010
Then bit bang the letter ‘i’ 00111001
Then bit bang the letter ‘n’ 00111110
Then bit bang the letter ‘k’ 00111010

It is so intuitive. NOT.

As I said, I’m new to this. Help me understand what I’m doing wrong or don’t comment.

But hey, if you’ve got so much free time that you can post on forums trying to make newbies feel bad about trying to learn things so be it. Continue to be a jackass

sterretje:
@David7099 is bitbanging a serial port on A0 and A1; I guess you would not have complained if it would have been SoftwareSerial on those pins.
I don’t have something like a MAX232 at hand at the moment, so I have modified your SWprint and SWread to use the serial port and behave similar. You should be able to use your originals if they currently work.

int SWread()

{
 while (Serial.available() == 0);
 return Serial.read();
}

void SWprint(int data)
{
 Serial.write(data);
}




The below is Robin's *recvWithEndMarker* function, modified to use your *SWread*. I've taken the while loop to check for available characters out as it will not work with your *SWread*.


void recvWithEndMarker()
{
 static byte ndx = 0;
 char endMarker = ‘\n’;
 char rc;

// read character from bitbanged serial port
 rc = SWread();

if (rc != endMarker)
 {
   receivedChars[ndx] = rc;
   ndx++;
   if (ndx >= numChars) {
     ndx = numChars - 1;
   }
 }
 else
 {
   receivedChars[ndx] = ‘\0’; // terminate the string
   ndx = 0;
   newData = true;
 }
}



I've made a slightly simpler version of Robin's *showNewData* that uses your *SWprint*; it simply loops through the characters in the buffer like Serial.print does.

Next in loop(), you can check the newData flag; it will be true if a LF was received, else false. This part differs a little from Robin's example.


void loop()
{
 recvWithEndMarker();
 if (newData == true)
 {
   newData = false;
   showNewData();
 }
}



Tested with realterm and serial monitor.

Just a note on the last line in your setup(). You're working with characters, so why do you print the decimal value 10? It would make sense to show that you're sending a linefeed


SWprint(’\n’);



In which case you also don't have to add the incorrect comment (it's a LF, not a CR ;) )


Hope that this gets you on track; full code below


const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
bool newData = false;

#define bit9600Delay 100
#define halfBit9600Delay 50
#define bit4800Delay 188
#define halfBit4800Delay 94

byte rx = A0;
byte tx = A1;
byte SWval;

void SWprint(int data)
{
 Serial.write(data);
 return;

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()
{
 while (Serial.available() == 0);
 return Serial.read();

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 setup() {

Serial.begin(57600);

pinMode(rx, INPUT);
 pinMode(tx, OUTPUT);
 digitalWrite(tx, HIGH);
 delay(2);
 pinMode(13, OUTPUT);
 digitalWrite(13, HIGH); //turn on debugging LED

SWprint(‘h’);  //debugging hello
 SWprint(‘i’);
 SWprint(’\n’);
}

void loop()
{
 recvWithEndMarker();
 if (newData == true)
 {
   newData = false;
   showNewData();
 }
}

void recvWithEndMarker()
{
 static byte ndx = 0;
 char endMarker = ‘\n’;
 char rc;

// read character from bitbanged serial port
 rc = SWread();

if (rc != endMarker)
 {
   receivedChars[ndx] = rc;
   ndx++;
   if (ndx >= numChars) {
     ndx = numChars - 1;
   }
 }
 else
 {
   receivedChars[ndx] = ‘\0’; // terminate the string
   ndx = 0;
   newData = true;
 }
}

void showNewData()
{
 // print the characters one-by-one
 for (uint8_t cnt = 0; cnt < strlen(receivedChars); cnt++)
 {
   SWprint(receivedChars[cnt]);
 }
}



Note 1)
There are libraries for what you're trying to do ;)
Note 2)
I have removed the debug led as it will interfere with the SWread when using serial monitor; in realtearm, it will work if you type with a speed less than the flash time (1 character per second).

Thank you for your detailed response. I’ll try this out asap. I appreciate it

Help me understand what I'm doing wrong or don't comment.

We will but you need to understand that bit-banging serial is repulsive to some, and fun to others it is the sort of thing that will surely ruffle some feathers.