Sending Data Between Arduino Nano and D1 Mini

I am sending data from Arduino Nano to D1 Mini,

Transmitter is Arduino Nano

Transmitter Code:

#include <DES.h>
#include <SoftwareSerial.h>
SoftwareSerial link(2, 3); // Rx, Tx
DES des;
byte in[8];
String  input;
char text[20];
char charVal[6];
char buf[30];
void setup() {
  link.begin(9600);
  Serial.begin(9600);
  Serial.println("Hello! Pleace Enter Your Data to Encrypt");
}
void tdesTest() {
  byte out[8];
  byte key[] = {
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
    0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
  };
  Serial.println();
  Serial.println("====== Triple-DES test ======");
  //encrypt
  Serial.print("Encrypt...");
  unsigned long time = micros();
  des.tripleEncrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  delay(10000);
  printArray(out, link);
  link.write(out, 9);
  delay(2000);
  //decrypt
  for (int i = 0; i < 8; i++)
  {
    in[i] = out[i];
  }
  Serial.print("Decrypt...");
  time = micros();
  des.tripleDecrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  printArray(out);
  delay(2000);
}
//passing output and Print
void printArray(byte output[], Print& serial)
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");
    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
    delay(100);
  }
  
  Serial.println();
}
//printing output without link pass
void printArray(byte output[])
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");
    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
    delay(100);
  }
  Serial.println();
}
void userdata() {
  Serial.println("Sending User Data");
  byte user[] = {0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30};
  printArray(user, link);
  link.write(user, 9);
  delay(100);
  tdesTest();
  
}
void loop() {
  while (Serial.available() > 0) {
    String  input = Serial.readString(); // read the incoming data as string
    memset(in, 0, 9); // Erase the contents of in[]
    input.toCharArray((char *)in, 9); // Copy up to 8 bytes from the string
    
    userdata();
  }
}

And receiving same from D1 Mini (ESP8266)

Receiver Code:

//Receiver code
#include <SoftwareSerial.h>
SoftwareSerial link(4, 0); // Rx, Tx

byte greenLED = 13;
byte cString[8];
byte chPos;
byte ch;
byte out[8];
String hexstring = "";


void setup()
{
  link.begin(9600); //setup software serial
  Serial.begin(9600);    //setup serial monitor
  pinMode(greenLED, OUTPUT);
}

void loop()
{

  while (link.available() > 0)
  {
    ESP.wdtDisable(); // This helps th avoid not reciving data after second try 


    //read incoming char by char:
    ch = link.read();
    cString[chPos] = ch;
    chPos++;


    digitalWrite(greenLED, HIGH); //flash led to show data is arriving
    delay(20);
    digitalWrite(greenLED, LOW);

  }
  if (ch != 0)
  {
    printArray(cString);
    ESP.wdtEnable(1);
    Serial.flush();
    cString[chPos] = 0; //terminate cString
    chPos = 0;
  }


}

//printing output
void printArray(byte output[])
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");
    }
    Serial.print(output[i], HEX);
    hexstring += String(output[i], HEX);
    Serial.print(" ");
    delay(100);

  }
  Serial.println();
  Serial.println("Your String Sir:");
  Serial.print(hexstring);
  Serial.println();
  ch = 0; // Avoid printing 0s when no data is recived
  hexstring = ""; //Clear the memeory of hexstring
}

In Receiver I am receiving data as below:

8Evax

I want to get data in Single Stream to receiver as Example: 31 30 30 30 30 30 30 30 7E B5 2D 4D 93 CB 08 BA or in receiver join two streams in to a single stream,

On Side Note: 1st Part is Plain Data and 2nd Part will be Encrypted Data

Could anyone please help..

changed to a more appropriate forum.

the data comes in as a stream, but since you read fast and strp when the buffer is empty (while (link.available() > 0)), you don't get the full stream. ➜ Don't second guess timing, don't assume that because the buffer is empty, you received everything that was sent.

I would suggest to study Serial Input Basics to get a better understanding

Arduino Software Solutions has various sketches for reading from Serial with their pros and cons.
Arduino to Arduino via Serial covers sending from via Serial to ESP8266,

A possible issue may be that you may have 0's in your encrypted Data, depending on what it does. Neither of the two links above will work with data that as zero bytes.
If that is the case you can use a modified version of Serial Input Basics that handles all bytes including '\0'

The receiver will have know when the byte data has all been received. Start synchoronization may also be an issue. A deadtime timeout may do the trick for both start and end.

As a really nasty use of Strings you could use

Serial.setTimeout(500); // data ends after 500mS of no chars received
if (Serial.available()) {
  String input = Serial.readString();
}

This relies on a 'bug' of String that is happy to have embedded '\0' in the String. So it will read in all the bytes even the 0 bytes. The length() method will return the correct value and you can use c_str() to get the char[ ] with the data and just ignore the extra '\0' on the end.

Could you help me to adopt this in to my reciver code, Also please note that I am using SoftwareSerial library ?

I don't think it's a good practice to rely on a bug to get something working :wink:

Also I'm not 100% sure of your claim. Here is my thought:

When you receive a new char using Serial.readString(), it's tentatively added to the String using concat() (this is a side effect of using += in the code for readString(), which is defined as calling concat())

this is what concat do:

unsigned char String::concat(char c) {
	char buf[2];
	buf[0] = c;
	buf[1] = 0;
	return concat(buf, 1);
}

so you create a temporary char array as a cString, stuff whatever char you got in the first position (so in our case a null char), add a trailing null char (as cString terminator) and call another version of the concat() method with the newly created cString and length of 1 (as there is one new char to add).

This is the code being executed:

unsigned char String::concat(const char *cstr, unsigned int length) {
	unsigned int newlen = len + length;
	if (!cstr) return 0;
	if (length == 0) return 1;
	if (!reserve(newlen)) return 0;
	strcpy(buffer + len, cstr);
	len = newlen;
	return 1;
}

So a new buffer is possibly created to allow for the extra byte and then the data is added using strcpy(buffer + len, cstr);.

That's where the challenge is: as strcpy() will stop copying the source data to the destination as soon as it sees a '\0' null char, and because in our case cstr first byte in null, nothing ends up being copied at the end of the String buffer.

➜ The possible extra byte that was allocated through reserve(newlen) is left unmodified.

As I don't think realloc() zeroes the rest of the block, you might end up with garbage in that byte, whatever was there in the heap and possibly not the '\0' you were trying to add.

thoughts?

Could you advise me a best way of doing this ?

Also reading string Serial.readString()is not the problem, What I am trying to achieve is to send date from Nano to D1 Mini in single stream which is plain data + Encrypted data. I am now sending them in two streams.

as I said, I would suggest to study Serial Input Basics to get a better understanding of what's happening on the Serial port.

if a timeout is what drives the end marker, then use millis to monitor if enough time has elapsed
since you received the last byte.

Let's keep serial sent for a aside bit, Do you have any thoughts to combine two streams in a single stream in Transmitter ?

Not sure exactly what you mean. Just listen to the two streams and when you get something from one of those, send it out.

here is a quick example for listening the Serial port until a timeout and storing the incoming data in a buffer

const size_t bufferSize = 100;
uint8_t payload[bufferSize];

bool getInputUntilTimeout(size_t& byteCount, uint32_t timeout = 1000) // default value for timeout = 1s
{
  static size_t bufferPosition = 0;
  static uint32_t lastActivity;

  if ((bufferPosition > 0) && (millis() - lastActivity >= timeout)) {
    byteCount = bufferPosition;
    bufferPosition = 0; // get ready for next time
    return true;
  }
  int r = Serial.read();
  if (r != -1) {
    lastActivity = millis();
    if (bufferPosition < bufferSize) payload[bufferPosition++] = (uint8_t) r;
    else {Serial.println(F("buffer overflow"));} // decide what to do to handle buffer overflow
  }
  return false;
}

void printHexByte(uint8_t aByte) {
  if (aByte < 0x10) Serial.write('0');
  Serial.print(aByte, HEX);
}

void printBuffer(size_t byteCount) {
  Serial.println(F("\n----\nI received:"));
  for (size_t i = 0; i < byteCount; i++) {
    Serial.print(i);
    Serial.print(F("\t0x")); printHexByte(payload[i]);
    if (isalnum(payload[i])) {
      Serial.print(F("\t("));
      Serial.write(payload[i]);
      Serial.write(')');
    }
    else if (payload[i] == '\r') Serial.print(F("\t(CR)"));
    else if (payload[i] == '\n') Serial.print(F("\t(LF)"));
    else if (payload[i] == '\t') Serial.print(F("\t(Tab)"));
    Serial.println();
  }
}

void setup() {
  Serial.begin(115200);
}

void loop()
{
  size_t byteCount;
  if (getInputUntilTimeout(byteCount))  printBuffer(byteCount);
}

Managed Get it Working:

Change the Transmitter Code to Cascade Two Char Streams Before Sending:

Transmitter Code:

#include <DES.h>
#include <SoftwareSerial.h>
SoftwareSerial link(2, 3); // Rx, Tx
DES des;
byte in[8];
String  input;


void setup() {
  link.begin(9600);
  Serial.begin(9600);
  Serial.println("Hello! Pleace Enter Your Data to Encrypt");

}

//passing output and Print
void printArray(byte output[], Print& serial)
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");

    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
    delay(100);


  }

  Serial.println();

}
//printing output without link pass
void printArray(byte output[])
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");

    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
    delay(100);

  }
  Serial.println();
}

void userdata_and_Encrypt() {
  Serial.println("Sending User Data");
  byte username[] = {0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30};
  printArray(username, link);
  byte username_data = (username, 9);
  delay(100);

  byte out[8];
  byte key[] = {
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
    0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
  };

  Serial.println();
  Serial.println("====== Triple-DES test ======");
  //encrypt
  Serial.print("Encrypt...");
  unsigned long time = micros();
  des.tripleEncrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  delay(100);
  printArray(out, link);
  byte password_data = (out, 9);
  delay(100);
  byte data_stream = username_data + password_data; 
  printArray(data_stream, link);
  link.write(out, 17);

  //decrypt
  for (int i = 0; i < 8; i++)
  {
    in[i] = out[i];
  }
  Serial.print("Decrypt...");
  time = micros();
  des.tripleDecrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  printArray(out);
  delay(100);

}

void loop() {

  while (Serial.available() > 0) {

    String  input = Serial.readString(); // read the incoming data as string
    memset(in, 0, 9); // Erase the contents of in[]
    input.toCharArray((char *)in, 9); // Copy up to 8 bytes from the string

    userdata_and_Encrypt();

  }
}

Receiver Code to Accept 16 Bytes

Receiver Code:

//Receiver code
#include <SoftwareSerial.h>
SoftwareSerial link(4, 0); // Rx, Tx

byte greenLED = 13;
byte cString[8];
byte chPos;
byte ch;
byte out[8];
String hexstring = "";
static String data = "";


void setup()
{
  link.begin(9600); //setup software serial
  Serial.begin(9600);    //setup serial monitor
  pinMode(greenLED, OUTPUT);
}

void loop()
{

  while (link.available() > 0)
  {
    ESP.wdtDisable(); // This helps th avoid not reciving data after second try


    //read incoming char by char:
    ch = link.read();
    cString[chPos] = ch;
    chPos++;


    digitalWrite(greenLED, HIGH); //flash led to show data is arriving
    delay(20);
    digitalWrite(greenLED, LOW);

  }
  if (ch != 0)
  {
    printArray(cString);
    ESP.wdtEnable(1);
    Serial.flush();
    cString[chPos] = 0; //terminate cString
    chPos = 0;
  }


}

//printing output
void printArray(byte output[])
{
  for (int i = 0; i < 16; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");
    }
    Serial.print(output[i], HEX);
    hexstring += String(output[i], HEX);
    Serial.print(" ");
    delay(100);



  }
  Serial.println();


  Serial.println("Your String Sir:");
  Serial.println(hexstring);




  Serial.println();
  ch = 0; // Avoid printing 0s when no data is recived
  hexstring = ""; //Clear the memeory of hexstring
}

Working Output:
Working Output

Thanks @drmpf for your Extra Support, and @J-M-L for insights.
Also I am open for improvements and suggestions

you are overflowing your array.... you declared it with 8 bytes

the receiver code still uses a single while (link.available() > 0) so you are not guaranteed to read an entire "sentence"... Only whatever manages to arrive in time in the incoming buffer.

What is recommended ?

what I recommended already in #2 and #8

➜ understand how to deal with the Serial buffer.

I also gave you a code listening for a byte stream until a timeout, you could study this (but now seems you send data in ASCII with a CR/LF at the end, so you could use that as an end marker)

Here is a proof of concept receiving binary data in a String (I did say it was nasty).

The code here blocks for simplicity, but could be recast as non-blocking by adding some state flags to keep track of the ping-pong between the boards.
Only one side sends at a time so SoftwareSerial is OK to use.
Rx buffer overflow is not a problem, just don't prompt the other side to send until you are ready to receive.

Uno Sender

#include<SoftwareSerial.h>
SoftwareSerial softSerial(10, 11); // RX,TX works in Mega also
void setup() {
  Serial.begin(115200); //for debug
  for (int i = 10; i > 0; i--) {
    delay(500);
    Serial.print(i); Serial.print(' ');
  }
  Serial.println("Uno started");
  softSerial.begin(9600);
  softSerial.setTimeout(100);
  softSerial.readString();   // clear any pending stuff
}

byte key[] = {  // change some values to 0x00 and 0xff for testing
  0x00, 0xff, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
  0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x00, // key B
  0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xff, 0x00, // key C (in this case A)
};

// NOTE: this loop() blocks to handle send/receives
void loop() {
  {
    Serial.println(F("Waiting for other side to be ready"));
    String rec;
    while ((rec.length() != 1) || (rec[0] != '\n')) {
      rec = softSerial.readString(); //try again
    }
    softSerial.readString(); // clear any other input coming
  }
  Serial.println(F("Other side ready sending key"));
  // ok other side ready send key
  for (size_t i = 0; i < sizeof(key); i++) {
    softSerial.write(key[i]);
    if (i % 8 == 0) {
      Serial.println();
    }
    Serial.print(" 0x");
    if (key[i] < 10) {
      Serial.print("0");
    }
    Serial.print(key[i], HEX);
  }
  Serial.println();
}

ESP8266 receiver

#include<SoftwareSerial.h>
SoftwareSerial softSerial(13, 12);

String  sensor_data_from_arduino;
void setup() {
  Serial.begin(115200); //for debug
  for (int i = 10; i > 0; i--) {
    delay(500);
    Serial.print(i); Serial.print(' ');
  }
  Serial.println("ESP8266 started");
  softSerial.begin(9600);
  softSerial.setTimeout(100);
  // clear any pending stuff
  softSerial.readString();

}


void loop() {
  // ready so send prompt to other side
  Serial.println(F("Prompt other side we are ready"));
  softSerial.print('\n');

  String rec = softSerial.readString();
  if (rec.length() > 0) {    // print it out
    Serial.println(F("received data"));
    for (size_t i = 0; i < rec.length(); i++) {
      if (i % 8 == 0) {
        Serial.println();
      }
      Serial.print(" 0x");
      if (rec[i] < 10) {
        Serial.print("0");
      }
      Serial.print(rec[i], HEX);
    }
    Serial.println();
  }
  rec = ""; // clear for next receive
  delay(3000); // some other processing here
}

Sample output

Prompt other side we are ready
received data

 0x00 0xFF 0x98 0x37 0x15 0x20 0xF7 0x5E
 0x92 0x2F 0xB5 0x10 0xC7 0x1F 0x43 0x00
 0x3B 0x38 0x98 0x37 0x15 0x20 0xFF 0x00

Seems to handle 0x00 just fine. @J-M-L I will leave you to explain why this is the case.
Edit -- I was actually using the 'correct' WString from Taming Arduino Strings
But even rolling back that fix, the sketch still works because the un-initialized memory that @J-M-L pointed out is the last location that would normally hold the terminating '\0' for the String, but in the code above that location is never accessed as the String added terminating '\0' is not part of the input.

As for using this 'bug' of Strings storing 0x00, It is more a 'feature' that cannot be removed since
str[i] = '\0';
is always possible and cannot be removed without removing assign to index functionality. When the ArduinoCore-API is released the bug @J-M-L noted will be fixed.

Edit - Just check the latest code from ArduinoCore-API which is where the String fixes are being committed and str += '\0' is still supported (and the un-initialize memory fixed)

On the other hand you cannot use SafeString for this code, because it explicitly guards against adding '\0' and does not support str[i] = ... because it cannot be guarded against. Instead you use setCharAt(.) which ignores '\0' arguments and raises an error.

Édit: checked and indeed they now memcpy instead of strcpy so in the future that will add the null byte into the memory. So it’s no longer a bug but a feature with… strings attached :slight_smile:

Thank you very much for the effort.
Since I am not sending the key to ESP (D1 Mini) which I am sending the Encrypted Data User input

while (Serial.available() > 0) {

    String  input = Serial.readString(); // read the incoming data as string
    memset(in, 0, 9); // Erase the contents of in[]
    input.toCharArray((char *)in, 9); // Copy up to 8 bytes from the string

    userdata_and_Encrypt();

How to adopt your solution ?
I will be grateful if you can help

Try and integrate the solution and post what you have and why it is not working.
Sample input / output will help and show where it is not working as you expect.
Post full send and receive sketches.

@drmpf Thanks for helping me.

I have change my code to work with once I send the encrypted data along with user data to D1 Mini (ESP8266) from Nano

I am trying to get confirmation from D1 Mini once data is received.

This is my Nano (Transmitter) Code:


#include <DES.h>
#include <SoftwareSerial.h>
SoftwareSerial link(2, 3); // Rx, Tx
DES des;
byte in[8];
String  input;

byte greenLED = 5;
char cString[20];
byte chPos = 0;
byte ch = 0;
char dataStr[6];
String hexstring = "";


void setup() {
  Serial.begin(9600);
  for (int i = 10; i > 0; i--) {
    delay(500);
    Serial.print(i); Serial.print(' ');
  }
  link.begin(9600);
  Serial.println("Your Data Sir:");
  link.setTimeout(100);
  //link.readString();   // clear any pending stuff

}

void loop() {


  while (Serial.available() > 0) {

    String  input = Serial.readString(); // read the incoming data as string
    memset(in, 0, 9); // Erase the contents of in[]
    input.toCharArray((char *)in, 9); // Copy up to 8 bytes from the string

    userdata_and_Encrypt();
   

}

//passing output and Print
void printArray(byte output[], Print& serial)
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");

    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
    delay(100);


  }

  Serial.println();

}
//printing output without link pass
void printArray(byte output[])
{
  for (int i = 0; i < 8; i++)
  {
    if (output[i] < 0x10)
    {
      Serial.print("0");

    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
    delay(100);

  }
  Serial.println();
}

void userdata_and_Encrypt() {
  Serial.println("Sending User Data");
  byte username[] = {0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30};
  printArray(username, link);
  byte username_data = (username, 9);
  delay(100);

  byte out[8];
  byte key[] = {
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
    0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
  };

  Serial.println();
  Serial.println("====== Triple-DES test ======");
  //encrypt
  Serial.print("Encrypt...");
  unsigned long time = micros();
  des.tripleEncrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  delay(100);
  printArray(out, link);
  byte password_data = (out, 9);
  delay(100);
  byte data_stream = username_data + password_data;
  printArray(data_stream, link);
  link.write(out, 17);
  recieve();
  /*
    //decrypt
    for (int i = 0; i < 8; i++)
    {
      in[i] = out[i];
    }
    Serial.print("Decrypt...");
    time = micros();
    des.tripleDecrypt(out, in, key);
    time = micros() - time;
    Serial.print("done. (");
    Serial.print(time);
    Serial.println(" micros)");
    printArray(out);
    delay(100);
  */

}

void recieve() {
  Serial.println("Waiting to Recieve");
  Serial.println(F("Waiting for Confirmation"));
  int  starttime = millis();
  int endtime = starttime;
  String rec;
  while ((rec.length() != 1) || (rec[0] != '\n')) {
    rec = link.readString(); //try again
  }
  link.readString(); // clear any other input coming
  endtime = millis();

}

and this is my Receiver (D1 Mini) Code:

//Receiver code
#include <SoftwareSerial.h>
SoftwareSerial link(4, 0); // Rx, Tx

byte greenLED = 13;

void setup()
{
  Serial.begin(115200); //for debug
  for (int i = 10; i > 0; i--) {
    delay(500);
    Serial.print(i); Serial.print(' ');
  }
  Serial.println("ESP8266 started");
  link.begin(9600);
  link.setTimeout(100);
  // clear any pending stuff
  link.readString();
  pinMode(greenLED, OUTPUT);
}

void loop() {

  String rec = link.readString();
  if (rec.length() > 0) {    // print it out
    Serial.println(F("Received data"));
    confirmation();
    for (size_t i = 0; i < rec.length(); i++) {
      digitalWrite(greenLED, HIGH); //flash led to show data is arriving
      delay(20);
      digitalWrite(greenLED, LOW);
      if (i % 8 == 0) {
        Serial.println();
      }
      Serial.print(" 0x");
      if (rec[i] < 10) {
        Serial.print("0");
      }
      Serial.print(rec[i], HEX);

    }
    Serial.println();

  }
  rec = ""; // clear for next receive
}

void confirmation() {
  Serial.println(F("Prompt other side Confirmation"));
  link.print('\n');

}

Thanks to you I was bale to reduce no of code in receiver,
Now in this code I am trying to get confirmation from D1 Mini when data is received, This function in future will be used to send Error codes to Nano after receiving the data from Nano.

Now with that function Nano is unable to execute the rest of the code and it is not passing the setup(). I am suspecting some memory issue due to the code on receiving confirmation on Nano.

Output:
Stuck

But if I comment all the things related to receiving data from D1 Mini (Confirmation) Code Is executing and Sending Data.

The fields I have to comment in Nano:
link.readString();
recieve();

void recieve() {
  Serial.println("Waiting to Recieve");
  Serial.println(F("Waiting for Confirmation"));
  int  starttime = millis();
  int endtime = starttime;
  String rec;
  while ((rec.length() != 1) || (rec[0] != '\n')) {
    rec = link.readString(); //try again
  }
  link.readString(); // clear any other input coming
  endtime = millis();

}

Then only it sends data to D1 Mini.

How to sort this issue:
Basically I want to send some data from D1 Mini once it receive Data from Nano. As a confirmation. Like link.write("Success")

Sketch reboots due to incorrect array lengths (DES.cpp also has incorrect array lengths)
try these, Note I have used different pins from your sketch

#include <DES.h>
#include<SoftwareSerial.h>
SoftwareSerial link(10, 11); // RX,TX works in Mega also

//In function '__base_ctor .constprop',
//    inlined from '__static_initialization_and_destruction_0.constprop' at C:\Users\matthew\Documents\Arduino\SenderUnoBinaryEncrypted\SenderUnoBinaryEncrypted.ino:7:5,
//    inlined from 'global constructors keyed to 65535_0_SenderUnoBinaryEncrypted.ino.cpp.o' at C:\Users\matthew\Documents\Arduino\SenderUnoBinaryEncrypted\SenderUnoBinaryEncrypted.ino:135:1:
//C:\Users\matthew\Documents\Arduino\libraries\ArduinoDES-master\DES.cpp:177:9: warning: '__builtin_strcpy' writing 25 bytes into a region of size 24 overflows the destination [-Wstringop-overflow=]
//  sprintf((char *)key,"000000000000000000000000\0");
//         ^

// change line DES.h:349 to
//  byte key[25];/**< holds the key for the encryption */ // was 24 but code use sprintf to copy in 0000... so need 25


void userdata_and_Encrypt();

DES des;
byte in[8];
String  input;

byte greenLED = 5;
char cString[20];
byte chPos = 0;
byte ch = 0;
char dataStr[6];
String hexstring = "";


void setup() {
  Serial.begin(115200);
  for (int i = 10; i > 0; i--) {
    delay(500);
    Serial.print(i); Serial.print(' ');
  }
  link.begin(9600);
  Serial.println("Your Data Sir:");
  link.setTimeout(100);
  //link.readString();   // clear any pending stuff

}

void loop() {
  if (Serial.available() > 0) {
    String  input = Serial.readString(); // read the incoming data as string
    //    memset(in, 0, 9); // Erase the contents of in[] << buffer overflow
    //    input.toCharArray((char *)in, 9); // Copy up to 8 bytes from the string
    memset(in, 0, sizeof(in)); // Erase the contents of in[]
    size_t inputLen = input.length();
    memcpy(in, input.c_str(), (inputLen < sizeof(in)) ? inputLen : sizeof(in));
    printArray(in);
    userdata_and_Encrypt();
    Serial.println("Your Next Data Sir:");
  }
}

//passing output and Print
void printArray(byte output[], Print &serial) {
  for (int i = 0; i < 8; i++)   {
    serial.write(output[i]); // helps if you actually send to the link !!
    if (output[i] < 0x10)     {
      Serial.print("0");
    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
    //  delay(100);
  }
  Serial.println();
}
//printing output without link pass
void printArray(byte output[]) {
  for (int i = 0; i < 8; i++) {
    if (output[i] < 0x10) {
      Serial.print("0");
    }
    Serial.print(output[i], HEX);
    Serial.print(" ");
    //   delay(100);
  }
  Serial.println();
}

void userdata_and_Encrypt() {
  Serial.println("Sending User Data");
  byte username[] = {0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30};
  printArray(username);
  // byte username_data = (username, 9);
  // delay(100); // ??

  byte out[8];
  byte key[] = {
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
    0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
    0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
  };

  Serial.println();
  Serial.println("====== Triple-DES test ======");
  //encrypt
  Serial.print("Encrypt...");
  unsigned long time = micros();
  des.tripleEncrypt(out, in, key);
  time = micros() - time;
  Serial.print("done. (");
  Serial.print(time);
  Serial.println(" micros)");
  //  delay(100);
  printArray(out);
  //  byte password_data = (out, 9);
  //  delay(100);
  //  byte data_stream = username_data + password_data;
  Serial.println(F("send to link"));
  printArray(username, link);
  printArray(out, link);
  // link.write(out, 17);
  // no need for delay(100) here as recieve waits for response
  recieve();
  /*
    //decrypt
    for (int i = 0; i < 8; i++)
    {
      in[i] = out[i];
    }
    Serial.print("Decrypt...");
    time = micros();
    des.tripleDecrypt(out, in, key);
    time = micros() - time;
    Serial.print("done. (");
    Serial.print(time);
    Serial.println(" micros)");
    printArray(out);
    delay(100);
  */
}

void recieve() {
  Serial.println(F("Waiting for Confirmation"));
  String rec;
  while (rec.length() == 0) {
    rec = link.readString(); //try again
  }
  Serial.print(F("rec:")); Serial.println(rec);
  link.readString(); // clear any other input coming
}
#include<SoftwareSerial.h>
SoftwareSerial link(14, 15);
//Receiver code
byte greenLED = 13;

String  sensor_data_from_arduino;
void setup() {
  Serial.begin(115200); //for debug
  for (int i = 10; i > 0; i--) {
    delay(500);
    Serial.print(i); Serial.print(' ');
  }
  Serial.println("ESP8266 started");
  link.begin(9600);
  link.setTimeout(100);
  // clear any pending stuff
  link.readString();
  pinMode(greenLED, OUTPUT);
}

void loop() {
  if (link.available()) {
    String rec = link.readString();
    Serial.print(F("rec:")); Serial.println(rec);
    if (rec.length() > 0) {    // print it out
      Serial.println(F("Received data"));
      for (size_t i = 0; i < rec.length(); i++) {
        digitalWrite(greenLED, HIGH); //flash led to show data is arriving
        delay(20);
        digitalWrite(greenLED, LOW);
        if (i % 8 == 0) {
          Serial.println();
        }
        Serial.print(" 0x");
        if (rec[i] < 10) {
          Serial.print("0");
        }
        Serial.print(rec[i], HEX);

      }
      Serial.println();
      confirmation();
    }
    rec = ""; // clear for next receive
  }
}

void confirmation() {
  Serial.println(F("Prompt other side Confirmation"));
  link.print("Success");
}
1 Like