Android Question Sending clear text via tcp/IP

Tim Chapman

Active Member
Licensed User
Longtime User
Below is the C++ code on ESP32 that will be receiving the text. It is looking for a { curly brace character as the starting character. See line 41.
If I user the AsyncStreams and send bytes, the text is not transmitted in the clear as I understand it so the receiving code is not seeing the curly brace character.

What am I missing here?
Thank you in advance for helping!

Receiving Code:
/*
 * @Descripttion:
 * @version:
 * @Author: Elegoo
 * @Date: 2023-10-11
 * @LastEditors: Changhua
 * @LastEditTime: 2023-10-23
 */
//#include <EEPROM.h>
#include "CameraWebServer_AP.h"
#include <WiFi.h>
#include "esp_camera.h"
WiFiServer server(100);

#define RXD2 3
#define TXD2 40
CameraWebServer_AP CameraWebServerAP;

bool WA_en = false;

void SocketServer_Test(void)
{
  static bool ED_client = true;
  WiFiClient client = server.available(); //尝试建立客户对象 Try to create a client object
  if (client)                             //如果当前客户可用 If the current client is available
  {
    WA_en = true;
    ED_client = true;
    Serial.println("[Client connected]");
    String readBuff;
    String sendBuff;
    uint8_t Heartbeat_count = 0;
    bool Heartbeat_status = false;
    bool data_begin = true;
    while (client.connected()) //如果客户端处于连接状态 If the client is connected
    {
      if (client.available()) //如果有可读数据 If there is readable data
      {
        char c = client.read();             //读取一个字节 Read a byte
        Serial.print(c);                    //从串口打印 Printing from the serial port
        if (true == data_begin && c == '{') //接收到开始字符 Received start character
        {
          data_begin = false;
        }
        if (false == data_begin && c != ' ') //去掉空格 Remove spaces
        {
          readBuff += c;
        }
        if (false == data_begin && c == '}') //接收到结束字符 End character received
        {
          data_begin = true;
          if (true == readBuff.equals("{Heartbeat}"))
          {
            Heartbeat_status = true;
          }
          else
          {
            Serial2.print(readBuff);
          }
          //Serial2.print(readBuff);
          readBuff = "";
        }
      }
 

emexes

Expert
Licensed User
What are you getting via the Serial.print(c) ?

Are the squiggly bracket etc characters appearing out the other end of the serial cable?

Did you write that parsing code? I think we can simplify it. But you're on the right track: first, get the bits and bytes working. 🍻
 
Upvote 0

emexes

Expert
Licensed User
Perhaps try something like:

C++:
    while (client.connected()) //如果客户端处于连接状态 If the client is connected
    {
        if (client.available()) //如果有可读数据 If there is readable data
        {
            char c = client.read();             //读取一个字节 Read a byte
            Serial.println("c = " + c);                    //从串口打印 Printing from the serial port

            if (c == '{') {    // start of packet
                if(readBuff.Length) {    // clear buffer if not already empty (contains junk noise?)
                    Serial.println("line noise = " + readBuff);
                    readBuff = "";
                }
            }

            if (c != ' ') {    // ignore spaces
                readBuff += c;
            }
     
            if (c == '}') {    // end of packet
                if (readBuff.equals("{Heartbeat}")) {
                    Heartbeat_status = true;
                } else {
                    Serial2.println("bad packet = " + readBuff);
                }
                readBuff = "";
            }
        }    // end if
    }    // loop
 
Last edited:
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
I am new to ESP32 chips. The project this is from is the ELEGOO Conqueror Tank Kit (https://us.elegoo.com/products/elegoo-conqueror-robot-tank-kit). Available on Amazon.
I have swapped the Arduino Uno for an Arduino Mega 2560 and programmed it in B4R. I have duplicated the functionality of some of the original C++ code that is used in the original robot.
I am trying to now write code in B4A to communicate via TCP/IP with the robot as is now done via the Android App that is available for the kit. The code and other details are all here: https://download.elegoo.com/?t=ConquerorRobotTank.

My goal is to be able to make a different interface on an Android tablet to control the Tank and still view the video from its camera.

I am not comfortable yet in changing the code on the ESP32 so I am trying presently to duplicate the communication currently sent to the ESP32 from the Android App.

I checked the schematic and found that the Serial.println pins (TXD0 and RXD0) are connected to another chip on the PCB if I understand correclty. I am not able presently to see the output from the Serial.println statements. I am contacting the manufacturer to find out where that serial data goes so I can determine if I can intercept that data.

I thank you for your help on this.

Note: If you plan to try any of this, the A4 and A5 (SDA and SCL) pins on the Conqueror Car Shield have to have wires soldered onto them which are then connected to the SDA and SCL pins on the Arduino Mega 2560.

Attached is the code that I made to run on the Tank and the code used on my Android phone to test connection and sending data to the ESP32 over TCP/IP.
 

Attachments

  • Tank.zip
    11.4 KB · Views: 8
  • TestClientSocket.zip
    8 KB · Views: 11
Last edited:
Upvote 0

emexes

Expert
Licensed User
I am not comfortable yet in changing the code on the ESP32 so I am trying presently to duplicate the communication currently sent to the ESP32 from the Android App.

If we're not changing the above ESP32 code...

what does your Android (B4A?) code look like?

Is the same phone already able to communicate with the robot via an app that was supplied with the robot? (ie, is the hardware working, and are we attempting the possible?)
 
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
If we're not changing the above ESP32 code...

what does your Android (B4A?) code look like?

Is the same phone already able to communicate with the robot via an app that was supplied with the robot? (ie, is the hardware working, and are we attempting the possible?)
Hi Emexes. The Android code is now attached to my previous post. Yes. I can run the app on my android phone. I have to turn off mobile data to do so. My android code connects to the server socket successfully but does not seem to be sending data that begins with the left curly brace even though that is what I sent.
 
Upvote 0

emexes

Expert
Licensed User
Well, your absolute first problem is going to be that you're using .InitializePrefix

https://www.b4x.com/b4i/help/irandomaccessfile.html#asyncstreams_initializeprefix

InitializePrefix (In As Object, BigEndian As Boolean, Out As Object, EventName As String)
Initializes AsyncStreams in prefix mode. This mode can only be used if both sides of the connection adhere to the "prefix" protocol.
In / Out - The monitored streams.
BigEndian - The prefix endianess.


Use plain old boring .Initialize
 
Upvote 0

emexes

Expert
Licensed User
A second likely problem is that the received data comes back in fits and starts, and I think the label is only going to show you the last chunk received, rather than an entire complete message or packet.

B4X:
Sub AStreams_NewData (Buffer() As Byte)
    Dim msg As String
    msg = BytesToString(Buffer, 0, Buffer.Length, "ISO-8859-1")
    lbl_status.Text = msg
End Sub

Ironically, this is the issue that .Prefix mode was intended to address but, as noted in the documentation, both ends have to be using it for it to work at all.
 
Upvote 0

emexes

Expert
Licensed User
Does the B4A logging work in debug mode? As in, can you see Log() messages on your PC that is running the B4A IDE?

That'll make debugging a shipload easier if it does.
 
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
Does the B4A logging work in debug mode? As in, can you see Log() messages on your PC that is running the B4A IDE?

That'll make debugging a shipload easier if it does.
Hi Emexes. Yes. Debugging is working like normal. I see the [{"N":"102","D1":"1","D2":"250"}] JSON text from line 51. I note that the text is supposed to be {"N":102,"D1":1,"D2":250} without the brackets. It is supposed to start and end with the curly brace. I added line 50 to remove the brackets.

I am getting data from the server on my Android client. Heartbeat is being received correctly as text.

When I try to send data from the Android client to the server, I get the error that the Astreams is not initialized.
My current code is attached.

I also want to add that the ESP32 chip is communicating with the Arduino. It is passing an ok message when I connect to the server on the ESP32 as it should.
I see that data that is passed because I forward it out a bluetooth connection which is picked up at my PC and displayed on a terminal program.
But it is not passing any of the JSON code which tells me it is not seeing a curly brace first. So the question still remains about the encoding and transmitting of plain text.
 

Attachments

  • TestClientSocket.zip
    8.3 KB · Views: 11
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
Update. When I connect to the server and then send a message right away, it goes through. If I wait a few seconds, I get the Astreams not initialized error. Then I have to connect to the server again in order to send quickly but without the error. I am now focusing on the heartbeat part of the code. I am having OpenAI duplicate the heartbeat system in my B4A code like it is being done in the C++ code. Will report back shortly.
Progress!
 
Upvote 0

emexes

Expert
Licensed User
I am getting data from the server on my Android client.

What is the server? The ESP32 on the robot?

Heartbeat is being received correctly as text.

What is receiving the heartbeat? You uploaded ESP32 C++ code for receiving the heartbeat. Is that the code receiving the heartbeat? How do you know it is being received? I thought we weren't touching the ESP32 code. Or does each heartbeat packet already flash a LED on the robot or something like that?

Or are there heartbeats in both directions, from Android "remote control" to robot ESP32, and also from robot ESP32 to Android?

Now that you mention it, the ESP32 code does seem to echo back the heartbeat packet. I thought that was for debugging, but if we're not changing the ESP32 code, then you've just made me twig that the echoing back is going to look a lot like the robot emitting its own heartbeat.
 
Upvote 0

emexes

Expert
Licensed User
I did not modify any code on the ESP32. Only the Arduino.

Super. No wonder I was confused.

Three processors:

1/ Android Phone B4A program to replace existing robot manufacturer's remote control app
2/ Robot Arduino
3/ Camera ESP32

What are the communication links between those three?

I think is:

1/ wifi tcp between Android Phone B4A and Robot Arduino
2/ serial wire between Robot Arduino and Camera ESP32

plus diagnostic/debug channels

3/ regular B4A Log() by wifi from Android Phone B4A to PC B4A IDE
4/ bluetooth from Robot Arduino to ... terminal program on PC ??? same PC as is running B4A IDE, or a standalone spare PC? or a spare Android tablet? or ?

OMG OMG OMG are you also running B4R at the same time for the Robot Arduino ?

Which device needs the heartbeat? Which device is supposed to generate it?

I am assuming that a heartbeat packet is similar to a watchdog: intended to stop things from timing out, and useful to make sure that everybody's still alive and awake. Is this assumption correct?

Updat When I connect to the server and then send a message right away, it goes through. If I wait a few seconds, I get the Astreams not initialized error.

Yeah, that's a bit odd. If anything, you'd think a few seconds pause at the start would be a good thing.
 
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
It works correctly now. Attached is my test code. I will implement it into the Tank code later. It is 3am and I have to get up at 8am tomorrow.

To reply to your question. You got it all correct down to here:
plus diagnostic/debug channels

3/ regular B4A Log() is by usb c cable from Android Phone to PC running B4A IDE. Can't connect via WiFi because phone wifi is connected to ESP32 Access Point.
4/ bluetooth from Robot Arduino to terminal program on same PC as is running B4A IDE. Bluetooth echos anything that comes in from the ESP32 to the Arduino and sends it to the PC terminal program. The main reason I added the bluetooth is so I can get data from the robot to the PC while the robot is in motion. USB cable is not good for this.

The heartbeat is supposed to be generated by the Android Client and sent via wifi to the ESP32 server which it is now.
Yes. Your assumption is correct. Heartbeat is like a watchdog timer.

Thank you again for your help on this! Where do you live if you don't mind my asking? I am in Cheyenne, Wyoming, USA.
 

Attachments

  • TestClientSocket.zip
    8.5 KB · Views: 8
Upvote 0
Top