Can we do RTS CTS flow control in Arduino Uno?

Hello,

I need to interface my Uno with Sierra HL8 modem through UART for controlling it using AT commands.
I have connected them (Rx and Tx pins to 0 and 1 pins in Uno) using a TTL - RS232 converter. Then I'm sending "AT" from Uno, but not getting any response from the modem. Same modem works perfectly if I connect it to PC through UART - USB cable.

My observation is that the modem is having RTS/ CTS flow control and is waiting for these signals.
Is it possible to enable the same in Uno side? If so what's the procedure and to which pins in Uno should I be connecting those?

Please guide me with your valuable inputs.

Thank you,
~Jinoj

Can you post your code here. We can see what mistake being made

Hi,

Here is my sample code to send AT to the modem and expecting a response.
When I run this from one Uno to another Uno, I can receive "AT" in the other Uno.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}

pinMode(10, INPUT);
Serial.println("Welcome");

// set the data rate for the SoftwareSerial port
mySerial.begin(9600);
mySerial.write("AT");
}

void loop() // run over and over
{
while (mySerial.available())
Serial.write(mySerial.read());

mySerial.write("AT");
delay(500);
}

Thanks
~Jinoj

Hi,

Can anyone please give some inputs to understand the limitation in Uno and if I can somehow overcome the issue?

Thanks
~Jinoj

Hi,

Is it possible to implement the Hardware flow control in Uno?
If not in Uno, is it possible in any other Arduino board?

Please suggest.

Thank you for your support,
~Jinoj

but not getting any response from the modem.

Sounds like a wiring issue to me. In the olden days we used to hard-wire CTS/RTS for some modems to make them work. Nothing to do with the Arduino.

Ok, thank you.
Can you suggest the correct method of wiring? I mean I don't know where to connect the CTS/ RTS pins in Uno board.
Please suggest.

Thanks
~Jinoj

Depending on the type of plug your modem has, as I recall, you connect RTS to CTS (just with a wire) at the plug. The exact pins depend on whether you have a 15 or 25 pin connector. You don't connect either of those to the Uno.

Also you need to get Rx/Tx the right way around. Perhaps measure with a multimeter?

http://www.lammertbies.nl/comm/info/RS-232_null_modem.html

If you have a proper RS232 converter, such as one based on a chip from the MAX232 family, then you will have several spare outputs on the chip. They will be labelled R2in, T2out and so on. The reason for the extra outputs is you can use them to operate the RTS and CTS lines. Just hook them up to spare Arduino inputs and outputs and you can do full hardware flow control from the Arduino.

However, most modems will work if you just tie them high to the +12v provided by the MAX232 chip's power supply capacitors. I can't remember exactly which is which, so you will have a bit of reading to do to work out the correct connections without blowing up any of your components.

[quote author=Nick Gammon link=msg=2102545 date=1424428357]
Depending on the type of plug your modem has, as I recall, you connect RTS to CTS (just with a wire) at the plug.
[/quote]I remember doing something like that too but I think that what it does is to fool the modem into sending/receiving data at its own pace rather than implementing flow control. Rather like the modem giving itself permission to communicate.

Ah, the joys of serial communications. Many Moons ago now I spent many "happy" hours with a serial breakout box getting serial comms working with cables of uncertain origin and wiring. Phrases like "null modem" still make me shiver.

Whenever I had to connect a serial device to a computer, I knew that there was half-an-hour of wasted time head. Null-modem cable? Connect CTS to RTS? What about DTR? But this is all wiring, nothing to do with "does the Arduino support it?".

You could, I suppose, actually implement processor support of CTS/RTS but I don't think I have seen this done recently (that is, to actually do flow control with it).

jinojs:
I have connected them (Rx and Tx pins to 0 and 1 pins in Uno) using a TTL - RS232 converter. Then I'm sending "AT" from Uno,.

BUT

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
....
....
  mySerial.write("AT");
...

It appears you've wired up your hardware serial port to communicate with your modem, then use software serial on completely different pins to attempt your communications.

Hi,

Sorry. Earlier code that I posted was incorrect.
Please see the code below.

#include <AltSoftSerial.h>

// AltSoftSerial always uses these pins:
//
// Board Transmit Receive PWM Unusable
// ----- -------- ------- ------------
// Teensy 3.0 & 3.1 21 20 22b
// Teensy 2.0 9 10 (none)
// Teensy++ 2.0 25 4 26, 27
// Arduino Uno 9 8 10
// Arduino Leonardo 5 13 (none)
// Arduino Mega 46 48 44, 45
// Wiring-S 5 6 4
// Sanguino 13 14 12

AltSoftSerial altSerial;

int onModulePin= 2;

void setup(){
uint8_t answer=0;

Serial.begin(9600);

altSerial.begin(9600);
delay(3000);

power_on();
}

void loop(){

}

void power_on(){

uint8_t answer=0;

// checks if the module is started
answer = sendATcommand("AT", "OK", 2000);
if (answer == 0)
{
Serial.println("GSM modem NOT working!");
// power on pulse
digitalWrite(onModulePin,HIGH);
delay(3000);
digitalWrite(onModulePin,LOW);

// waits for an answer from the module
while(answer == 0){
// Send AT every two seconds and wait for the answer
answer = sendATcommand("AT", "OK", 2000);
Serial.println("GSM modem NOT working!");
}
}
else
Serial.println("GSM modem IS working!");

}

unsigned char sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout)
{

unsigned char x=0, answer=0;
char response[100];
unsigned long previous;

memset(response, '\0', 100); // Initialize the string

delay(100);

while( altSerial.available() > 0)
{
x = altSerial.read(); // Clean the input buffer
Serial.print(x);
}

altSerial.println(ATcommand); // Send the AT command

x = 0;
previous = millis();

// this loop waits for the answer
do{

if(altSerial.available() != 0){
response[x] = altSerial.read();
x++;
// check if the desired answer is in the response of the module
if (strstr(response, expected_answer1) != NULL)
{
answer = 1;
}
}
// Waits for the asnwer with time out
}
while((answer == 0) && ((millis() - previous) < timeout));

return answer;
}

The connection I'm doing is:
Dev kit UART_MAIN -> Gender changer -> RS232 -> TTL -> UNO. Here, in 'TTL to UNO' connection we are connecting Tx from TTL to Rx (pin 8 ) in Uno and Rx from TTL to Tx (pin 9) in Uno. Also we are connecting the GND pin.

With the above program I'm always getting the output "GSM modem NOT working!".

Please let me know if I'm making any mistake in connection or code.

Thank you,
~Jinoj

Hi,

From Sierra, I heard the baud rate should be less than 9600. So I used different low rates like even 1200 bps. Also connected DTR to ground.
There is no improvement. Still I'm unable to get "OK" from modem when sending "AT" from Uno.

Can anyone give some suggestion?

Thanks
~Jinoj

Please edit your post, select the code, and put it between [code] ... [/code] tags.

You can do that by hitting the "Code" button above the posting area (It looks like a scroll with < > inside it).

Please post your exact wiring and a link to the datasheet for your modem.

unsigned char sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout)

I can think of several reasons that this would fail, even if communications were working perfectly at the lower level:

  • What does the modem expect for end-of-line after the AT command? Old Hayes modems would abort the command if they received additional characters after the \r, and I think Serial.print() sends \r\n
  • Echoing. Does the modem echo the AT? Does it echo the newline?
  • Does it precede the response with its own newline?

Start with something simpler, to establish that you ARE talking to the modem correctly. Just a bridge between Serial and AltSerial, or something. (actually... See if you can talk to the modem from your PC, through 3 wires worth of Serial connection. You can use a real USB/RS232 adapter! Experiment with the Arduino Serial Monitor or a better application, to see exactly what characters/commands elicit what responses.)

(Standard procedure for DB25 "fussy" system: Jumper together pins 4,5, and 6.
Standard truism: "It's always the cables.")

I think my issue might shed light on this one, as it seems I have similar problems and have been trying to implement something along the lines of @westfw's response:

I am trying to read the serial communication from a pulse oximeter monitor (manual) on my Arduino Serial monitor.

SUCCESSFUL COMMUNICATION:
Using a cheap Amazon DB-9 to USB cable connected to a laptop and using RealTerm Serial Capture software.
Settings: 9600 b/s, Data Bits: 8 bits, Parity Bit: none, Stop Bits: 1, Flow Control: RTS/CTS handshake

I am able to see a successful stream of bytes (each frame is 6 bytes long, starting with 180 and ending with 255, with my desired data to be parsed in between).

I want the stream of bytes seen in the terminal to be read by the Arduino (instead of software on my laptop)!

UNSUCCESSFUL WITH ARDUINO:

Failure 1: RS-232 Arduino UNO shield (LinkSprite)
Failure 2: RS-232 to TTL module (Amazon)
Failure 3: DB-9 to USB cable on Arduino (Amazon)

In each case, we were able to see a stream of 255 values showing up in the Serial monitor (whether plugged in or not!) Even using a logic analyzer on the tx and rx pins showed nothing.

However, we did see a 6.5V difference on the RTS to CTS pins of the DB-9 port. We tried connecting them together with a wire, but still didn't see a difference in the data stream.

None of these options we tried so far had any flow control options available to the Arduino (TTL logic), so now I'm looking at this module which does.

However, I'm still not sure whether to be pursuing an electrical solution (wiring up RTS & CTS somehow or DTR?) or an Arduino Software solution to control the handshake.

In each case, we were able to see a stream of 255 values showing up in the Serial monitor (whether plugged in or not!) Even using a logic analyzer on the tx and rx pins showed nothing.

Then the problem is in the code you didn't post.

#include <SoftwareSerial.h>

#define rxPin 7
#define txPin 6

int b = 12;


SoftwareSerial mySerial(rxPin, txPin); // RX, TX


void setup()
{
  Serial.begin(9600);
  Serial.println("Goodnight moon!");
 
  mySerial.begin(9600);
  mySerial.println("Hello, world?");
}

void loop()
{
  if (mySerial.available()) 
 {   
    b = mySerial.read();
    Serial.print(b);
    Serial.println();
 }

  delay(100);

}

This the latest code we used to simply read serial communication from the TX and RX pins from a RS-232 to TTL shield. Nothing fancy... No CTS/RTS handshaking protocols...

We did test this to be able to read Serial communication from another Arduino and it worked.