0

Second time I'm asking the same question with no solution, let me elaborate in other way for clarity.

I wrote an Arduino program which uses two serial ports, one is hardware serial port and other is SoftwareSerial port.

No problem with hardware serial port, the problem is with software serial port.

The software serial port's Tx pin works but Rx pin does not work, i.e. portone.available() is always zero, nothing in the input buffer of the software serial port.

I'm using Arduino IDE 1.6.12 with an Uno board. Previously I used version 1.6.9 but neither works. Here is the piece of code:

#include <SoftwareSerial.h>

String code = "", customer = "";
bool complete = false;
byte c = 0, j = 0;
char customercode[27];
SoftwareSerial portone(10, 11);
void setup() {
  Serial.begin(9600);
  portone.begin(115200);
  pinMode(10, INPUT);
  pinMode(11, OUTPUT);
  if (Serial) {
    Serial.print("Connecting");
  }    
}

void loop() {
  String copy = "";
  char inchar = '0';

  if (Serial.available() > 0) {
    while (Serial.available()) {
      char bytes = (char)Serial.read();
      if (bytes == '1' || bytes == '2' || bytes == '3' || bytes == '4' || bytes == '5' || bytes == '6' || bytes == '7' || bytes == '8' || bytes == '9' || bytes == '0' || bytes == '.' || bytes == '-' && bytes != '#') {
        customercode[c] = bytes;
        c++;
      } else if (bytes == '#') {
        complete = true;
      }
      if (c > 12 && bytes != '#') {
        code += bytes;
      }
    }

    if (c == 13) {
      customer += '+';
      for (byte i = 0; i < 12; i++) {
        customer += customercode[i];    
      }
    }
  }
  portone.listen();
  if (portone.available() > 0) {
    portone.println("AT+CMGF=1");
    portone.println("AT+CNMI=2,2,0,0,0");
    portone.flush();

    while (portone.available()) {
      inchar = (char)portone.read();
      copy += inchar;
    }
    delay(1);
    Serial.print(copy);

  } else if (complete == true && customercode != "" && code != "") {
    sending();    
  }
  Serial.print(portone.available());
  delay(1000);
}
  • SoftwareSerial is pretty low performance, and 115200 bps is probably asking too much. Can you lower the baud rate? Can you search the Internet for alternative implementations of a software serial port? – Edgar Bonet Oct 28 '16 at 8:00
  • before I was using the 9600 baudrate but nothing happened that is why I decided to change, also I searched a lot in internet but I end up no solution. that is why I decided to come back again. – kassim Oct 28 '16 at 8:27
1

Don't call portone.listen(). That method is only necessary when you have created multiple SoftwareSerial ports. It specifies which port you are listening to, because only one of them can receive at a time (you can transmit on any of them at any time). It also empties the receive buffer so that data from one SoftwareSerial port is not mistakenly returned by another. In your code, this empties the input buffer before checking portone.available(). Surprise, it's always empty! ;)

Also, don't set the pin mode of the pins used for the SoftwareSerial object. The pin modes were set during the constructor of portone, which happens before setup. You're messing with pins that have been "promised" to that library for its own use and control.

As Edgar suggested, you should consider a more-efficient software serial library. AltSoftSerial is best, but is only available on certain pins. My NeoSWSerial library is next best, and works on any two pins, but only at 9600, 19200 and 38400. Both of those libraries can transmit and receive at the same time, unlike SoftwareSerial. Here is an answer with all the gory details.

And you really should ditch the String class usage. You obviously know how to use char arrays (aka "C strings"). We can't see the sending() function, but you can probably just print a few pieces instead of building a complete String and printing it:

    portone.print( '+' ); // leading plus sign
    portone.write( (uint8_t *) customerCode, 13 ); // array of bytes, length

It would be better to terminate the character arrays with a zero byte (NUL-termination) in loop so they can be used as a standard C string instead of a byte array:

    customerCode[14] = '\0'; // NUL-terminate the C string

Then you can use the standard C string print in sending:

    portone.print( '+' ); // leading plus sign
    portone.print( customerCode );

Printing the pieces is always more efficient than building a big buffer with all the pieces. This avoids copying the pieces and needing twice as much RAM.     :P

  • portone.print(code) is printing to the GSM module, then how can I control message so that it prints by iterations of peace wise message while the full message should reach the receiver, and to control the iterations on receiving the message from the GSM module peace wise between the input buffer of an arduino and GSM, as it is sent full. – kassim Oct 28 '16 at 14:20
  • @kassim, if I understand your question, I think you are asking about calling print several times instead of just once. The GSM does not see how many print calls were made, just that a certain number of characters were sent. Because it takes about 1ms per char, the Arduino is able to start sending the second piece (i.e., customerCode ) almost immediately (~ 0.001ms) after the '+' character. The GSM will not notice that tiny pause. It will see an almost continuous stream of chars. It is probably accumulating chars from the Arduino in the same way as loop accumulates customerCode. – slash-dev Oct 31 '16 at 2:30
  • I think the problem was library because I had added AltSoftwareSerial library now is fine. – kassim Oct 31 '16 at 22:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.