0

I am working on a project involving bluetooth and wifi communications. Both of them are wired up to the Arduino and communicate to it using two software serial port. The scenario is the one in the picture attached.

What I am doing is:

  • retrieve the sensor value
  • send it from the BT slave module to the master one (wired up to Arduino)
  • take it and send it, using AT commands, through the WIFI channel (the WIFI module is a ESP8266-01) to a web server.

The problem is that if I start listening to the BT serial port (BTSerial.listen()) I am not able to properly send the sensor values through the WIFI connection. But if I comment out the lines related to the BT sotware serial, and try to send fixed value to the web server, the sending terminates succesfully.

In my opinion there are some problems with the BTSerial.listen() and WIFISerial.listen() calls, since they are not able to switch from one the the other correctly.

I saw the TwoSerialPort example provided into the Arduino IDE and I tried to apply it into my code but it still not works to me.

Does anyone have a idea which would be the problem? Does anyone already faced with this problem or a similar one?

Hoping to be as much clear as possible, thanks in advance to anyone would help me.

Filippo

[EDIT] Added two code snippets

// This method prepares the AT commands will be send to the ESP8266-01 module in order to upload the values on the web server 
void send2server(String ip, int port, String file, int t, int h, int p) {

  String queryString = "temp=";
  queryString.concat(t);
  queryString.concat("&hum=");
  queryString.concat(h);
  queryString.concat("&press=");
  queryString.concat(p);
  Serial.println(queryString);

  // Prepare and exec the AT+CIPSTART command provideing the TCP connection init
  String CIPSTART_cmd = "AT+CIPSTART=\"TCP\",\"" + ip + "\"," + port + "";
  exec_cmd(CIPSTART_cmd, 1000);

  // Prepare the POST request
  String httpPOST_cmd = "POST /";
  httpPOST_cmd.concat(file);
  httpPOST_cmd.concat(" HTTP/1.1\r\n");
  httpPOST_cmd.concat("Host: ");
  httpPOST_cmd.concat(ip);
  httpPOST_cmd.concat("\r\n");
  //httpPOST_cmd.concat("Accept: */*\r\n");
  httpPOST_cmd.concat("Content-Length: ");
  httpPOST_cmd.concat(queryString.length());
  httpPOST_cmd.concat("\r\n\r\n");
  //httpPOST_cmd.concat("Content-Type: text/html\r\n\r\n");
  httpPOST_cmd.concat(queryString);

  // Calculate the POST request length
  unsigned int len = httpPOST_cmd.length();

  // Prepare and exec the AT+CIPSEND statement with the POST request length just calculated
  String CIPSEND_cmd = "AT+CIPSEND=";
  CIPSEND_cmd.concat(len);
  exec_cmd(CIPSEND_cmd, 1000);

  // Exec the HTTP POST request
  exec_cmd(httpPOST_cmd, 1000);

  // Close the connection
  exec_cmd("AT+CIPCLOSE", 1000);
}

// This method execute each AT command in the previuous method
void exec_cmd(String cmd, int delayTime) {
   byte i = 0;

   while(1) {
      Serial.println("invio comando");
      WIFISerial.println(cmd);
      while(WIFISerial.available()) {
         if(WIFISerial.find("OK")) {
            i = 8;
         }
      }
      delay(delayTime);

      if(i > 5)
         break;

      i++;
   }

   if(i == 8) {
      Serial.println("OK");
      //return true;
   } else {
      Serial.println("ERRORE");
      //return false;
   }
}

The problem is the code goes properly till the AT+CIPSEND command, then the POST request is sent but no good feedback arrives, ending with the "ERRORE" error message. enter image description here

[EDIT 2] Attached serial monitor output This is the serial monitor output when I execute the skecth. It seems to work properly but it does not upload any value. enter image description here

Filippo
  • 73
  • 1
  • 10
  • 4
    SoftwareSerial is poor at best. With two it's poor squared. – Majenko Jul 06 '17 at 21:39
  • You can't use two instances of the normal software serial. Probably you best bet is to drop the Arduino and instead run your sketch on the ESP8266, with that talking to the BT. Or use nRF24L01's to link the sensors instead of BT. – Chris Stratton Jul 06 '17 at 21:51
  • Arduinos now come in so many configurations and use so many different processors you now need to specify exactly what you are using. If a processor has only 1 hardware serial port you will have to implement the 2nd serial port in software. There are different libraries to use for this. Needless to say, a software implemented serial port is not as good (fast) as a hardware serial port. As you can see, there is more to programming serial ports on Arduinos then simply instantiating another instance of the standard serial port library. Goodby software. Welcome to firmware. – st2000 Jul 06 '17 at 23:50

1 Answers1

0

This answer provides full details on choosing "good" combinations of hardware and software serial ports. To summarize:

  • Use the HardwareSerial port (i.e., Serial) for one of the devices. You can still use it for debug prints, as long as the device has some kind of command "format". For example, if commands start with "AT", just make sure that none of your debug prints start with "AT". It is the absolute best choice. You would have to disconnect RX pin 0 from the device in order to upload new sketches over USB.

  • Use AltSoftSerial for the other device. It is the most efficient software serial port, and it can be used at the same time as Serial. It only works on two specific pins.

  • NeoSWSerial is the next best choice, at limited baud rates. It can be used with the above choices, but transmitting on NeoSWSerial prevents them from receiving.

  • SoftwareSerial is the worst choice. Receiving or transmitting on SoftwareSerial prevents all of the above from receiving anything. It disables interrupts for long periods of time.


UPDATE - Here is the most reliable configuration:

enter image description here

Your code will have something like this:

#include <AltSoftSerial.h>
AltSoftSerial BT; // 8 is RX, 9 is TX

#define WIFI Serial  // 0 is RX, 1 is TX (disconnect 0 to upload new sketch)

void setup()
{
  WIFI.begin( 115200 );
  BT.begin( 9600 );
}

void loop()
{
  if (BT.available) {
    char c = BT.read();
    // do something with the character
       ... save them until '\n' arrives?
         ... then parse some values?

    if (values all received) {
      Serial.print( F("Sending values") ); // this is the WIFI port, but
          //  the ESP8266 ignores this debug print because it doesn't
          //  start with "AT".

      WIFI.println( F("AT+ ...") ); // all the AT commands
          ...
      WIFI.print( btValue1 );    // and the BT values
          ...
    }
  }
}
slash-dev
  • 2,009
  • 11
  • 12
  • Thanks for the replies @slash-dev. If I understand correctly, using NeoSWSerial I would be able to receive data on the BT serial and transmit it towards the WIFI module over the WIFI serial _simultaneously_. Am I right or not? – Filippo Jul 07 '17 at 08:36
  • And if so, is there a guide or a tutorial on NeoSWSerial? Thanks again!! – Filippo Jul 07 '17 at 08:59
  • @Filippo, so you're ignoring the two best choices? You would have to create a NeoSWSerial instance with a RX pin for the BT TX, and a TX pin for the WIFI RX. Right now, you can only transmit and receive simultaneously with the one NeoSWSerial that is "listening". You could make another instance for the WIFI TX/BT RX. Just like `SoftwareSerial`, `NeoSWSerial` can only listen to one pin at a time. Srsly, use `AltSoftSerial` (pins 8 & 9) with `Serial` (pins 0 & 1) to avoid all these issues. – slash-dev Jul 07 '17 at 14:22
  • @Filippo, there is no "tutorial" for `NeoSWSerial`, because it is a drop-in replacement for `Serial` or `SoftwareSerial`. Some extra info at the [NeoSWSerial](https://github.com/SlashDevin/NeoSWSerial) github page. All these libraries are available from the Arduino IDE Library Manager, under the menu **Sketch -> Include Library -> Manage Libraries...**. – slash-dev Jul 07 '17 at 14:26
  • Already found either github page or library into the Arduino IDE, thanks @slash-dev. I am trying to understand the test sketch in to the NeoSWSerial library in order to apply it into my project. But, since I am nquite new to Arduino, could you explain ti tom me a little bit, please? I have an Arduino UNO, so I got no Serial1, Serial2, ecc. ports. How can I apply your library to the scenario in the picture below? – Filippo Jul 07 '17 at 14:53
  • @Filippo, the test sketch is for verifying the library, not an *example* for you. Look at any example for `Serial`, `AltSoftSerial` or `SoftwareSerial` and it will work with `NeoSWSerial`. I will add an update in my answer to show the best connections/libraries. – slash-dev Jul 08 '17 at 01:23
  • Huge thanks @slash-dev!!! My picture was just to give you an idea about the communication scenario, but I have the exactly same wirings than the ones in your schema. Now I have a better idea about I have to do! Thanks again so much!! – Filippo Jul 08 '17 at 07:54
  • Just a curiosity regarding the example in the code you posted above: what if I would use a software serial (e.g. `AltSoftSerial` or `NeoSWSerial`) instead of hardware serial (`Serial`) for the WIFI connection? Should it be possible? – Filippo Jul 08 '17 at 08:57
  • @Filippo, you can only have one AltSoftSerial port, and it must be on two specific pins (8 & 9 for an UNO). And as I said, "[NeoSWSerial] can be used with the above choices [i.e. AltSoftSerial], but **transmitting on NeoSWSerial prevents them from receiving.**" If you never transmit to the BT and the BT can run at 9600, 19200 or 38400, you could use NeoSWSerial for the BT. Then you could use AltSoftSerial for the WIFI. It won't be as reliable as the above configuration, because AltSoftSerial can affect NeoSWSerial reception, especially if AltSoftSerial is running above 38400. – slash-dev Jul 08 '17 at 14:00
  • Thanks @slash-dev! I wired up all the stuff as in the circuit you posted and used `AltSoftSerial` for the BT and the hardware serial (pin 0 and pin 1) for the WiFi. Despite all this I am not able to send the sensor value to the web server. I edit my initial question and added two snippets. Any yours feedback would be strongly appreciated!! – Filippo Jul 08 '17 at 16:48
  • Sorry, I don't know how to help with the AT commands, but I would suggest that you eliminate the `String` variables. There's no reason to build up a big `String` and call `WIFI.println` once. Just print the pieces to WIFI, individually. This will save a huge amount of RAM, which could be the problem. The one exception is the Content-length. I believe there is a mode where you can send the content and terminate it with ^Z (char 26), instead of sending the length first. Maybe. – slash-dev Jul 08 '17 at 17:55
  • Thank you so much again @slash-dev. Your help was very very appreciated! Just one more question: using the hardware serial port as a serial one for WIFI (`#define WIFISerial Serial;`), would not be the possibility the that the command for the ESP8266-01 module would be interpreted as simple prints on the serial monitor instead of the instruction for the module, leading to not actually producing the WIFI command – Filippo Jul 09 '17 at 09:25
  • Yes, the ESP8266 commands would be visible in the Serial Monitor window, but they are only *interpreted* by the ESP8266. It is the debug prints that must be *ignored* (not interpreted) by the ESP8266. As long as they don't start with "AT", the ESP8266 should ignore them. Or comment out all the debug prints to see if it starts working. (I doubt it changes the behavior). So you will see both debug prints and AT commands in the Serial Monitor window, but it doesn't matter. – slash-dev Jul 09 '17 at 15:20
  • Still it does not works fine for me, since the WIFISerial.println("AT+...") statements are only printed out onto the serial monitor window and they **DO NOT** produce any effective results about uploading values to the web server. In my previuos connections (in which I used two SoftwareSerial ports, but commenting out the BT.begin(9600) statement), I used the exactly same code for the AT commands and it worked properly since the upload works fine (althought with fixed values). I edited the intial post to attach to you the serial monitor output for a better comprehension. Thanks again!! – Filippo Jul 09 '17 at 15:56
  • Well, that doesn't make any sense to me... it seems to be replying "OK", but it doesn't actually send to the server? A poor level-shifting circuit could affect the ESP8266. Using [tt]Serial[/tt] means that there is extra loading on the TX and RX pins (0 & 1) from the on-board FTDI chip (for the USB). You could try the alternative I suggested in the comment above: "you could use NeoSWSerial for the BT. Then you could use AltSoftSerial for the WIFI." This assumes you never send to the BT. – slash-dev Jul 10 '17 at 15:01