Real communication between arduino and NodeMCU

Hi everyone

As you all know Nodemcu or Wemos d1 both have not enough pins to make a comprehensive project which is include several sensors and switches and also using ds3231 and a display at the same time.

So I apparently have no choice to connect everything to an arduino mega and then connect the mega to a nodemcu with i2c. In fact, the most important thing that i want about this communication is three issues:
1- transfer long json
2- send and receive at one code
3- no crash :grinning:

I found a few codes on internet for both arduino and nodemcu but there are so many fault or lack of response or even more wierd, ruined transfered json.
One of code that i have used (but was not suitable and contains some mistakes):

My question is: is there any cleaned, practical and robust way to make such conversation between arduino and nodemcu (wemos mini d1)

( Actually i dont want to use esp8266 itself due to related dirty codes)

Hi,
Have you thought of changing to ESP32?

Tom… :grinning: :+1: :coffee: :australia:

Tom ESP32 is similar to NodeMCU somehow . It has limited pin numbers too… You know I’m talking about more than 10 or even 15 pins (include digital, analog, PWM ,…)

I2C is a poor choice for many reasons. UART serial would be much better and easier to implement.

wrong.
use port expanders, either I2C or SPI and you will have enough pins on your NodeMCU. Analog, Digital, whatever you want. No need for an additional atmega!

if you provide more information about WHAT you want, I assume here are guys which can suggest proper ICs. Digital, ADC, keypad drivers, matrix, PWM, lot of LEDs…
SMD, DIL, modules/breakouts
… what ever you might need.

For Serial connections between Uno/Mega and 3V3 boards see my
Arduino to Arduino/PC which has circuits and code for sending a line at a time (includes adding a check sum for error checking)
If you are sending less the 60chars to UNO or 125chars to Mega at a time, the code will cope with very long delays on either side.

1 Like

It is unbelievable what crap people have uploaded.
As for error sensitivity, it does depend a little on what you think you need to send back and forth.
If you are sending whole webpages or major parts thereof, you are doing something wrong.
The board with the biggest memory and fastest CPU should be in charge, and some information can be fetched and sent. Serial Input basics is very reliable, but a method that sends a header of a few bytes + length of transmission and optional CRC check can also be very efficient. Still if it is just for lack of pins, port expanders or even multiplexer or bitshifters are usually enough of a solution.

I want to order several output digital pins to switch on and off , read a few sensors values which are obviously input analog and optionally control a few pwm pins. Additionally, i have a plan to connect a clock (ds3231) to my board , an oled display and a keyboard and maybe more. (Im trying to scheme a flexible, modular and expandable base for the future)

But as far as i know (maybe Im wrong), if i use the above items there are not enough pins to do it, for example a multiplexer for input analog values will consume 4 digital pins aside from the only analog pin on wemos, and also ds3231 will take two pins and display … Etc.

Unfortunately i know very little things about combining some elements together by i2c or UART or …
Is it possible to handle all of these items by expanders on wemos?

1 Like

By UART i can send simple data from arduino to wemos but at the same time no value transfered from weons to arduino. I have no idea about how to sync and how to stop at a suitable time to receive data from opposite side an also so many other things. I’m very beginner at this stage but my search through different forums and related sites has been pointless up to know … :confused:

Do you know a comprehensive tutorial about this issue?

Why not? People do this all the time. Start on this forum with Serial Input Basics.

It is pretty simple to design your own command/communications protocol. For example, serial commands could look something like this:

<s4,1> set digital output pin 4 to 1
<p9,150> set PWM on pin 9 to 150
<g2,0> get analog input on A2

The MCP23017 will give you 16 digital ports
The PCF8574 will give you 8 digital ports
The PCA9685 will give you 16 PWM ports
The ADS1115 will give you 4 analog pins

all on just two pins - which you might already use for your i2c display. That’s what I2C is used for: a bus where you connect multiple ICs.

Tnx a lot jremington, the link seems great :+1:

Hi again,

As I told you above, I need to send and receive a big JSON between Arduino and Weoms at one code, but at first, I started to send a moderate size string of about 75 characters ( 75 doesn’t matter, I just want to send a not short string.
According to Serial Input Basics - updated (which you guys had recommended) I tried to send the string from UNO to Wemos D1 (as shown in the picture) but apparently, there are just only 64 characters could pass through serial communication.

whats is the problem?

Arduino Side:

#include <SoftwareSerial.h>
#include <ArduinoJson.h>
SoftwareSerial s(5,6);

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

  s.write("<");
  s.write("1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890");
  s.write(">");


  delay(2000);
}

Wemos Side:

#include <SoftwareSerial.h>
#include <ArduinoJson.h>
SoftwareSerial s(D6,D5);

const byte numChars = 1000; 
char receivedChars[numChars];
String stringBuffer;
boolean newData = false;

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

void loop() {
    Serial.println(SerialReceiver());
    delay(2000);
}

char* SerialReceiver()
{
    memset(receivedChars, 0x00, sizeof(receivedChars));     // i ssuppose this code clear the 
    receivedChars each loop
    newData = false;
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (s.available() > 0 && newData == false) {
        rc = s.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                //stringBuffer +=String(rc);
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
    return receivedChars;
}


Wiring

Received char A in Wemos Serial Side
What Wemos get is only 64 characters of what Arduino sent

Hi again
What is your idea about my latest question above?
tnx for your attention jremington

Your problem is here

void loop() {
    Serial.println(SerialReceiver());
    delay(2000);   // here
}

That means that you only start reading once the buffer is already overflowing.
your SerialReceiver function is in essence ‘non-blocking’ (or could be)
Your return the pointer to the input buffer, but there is no need for that, the buffer receivedChars[]
is global, so we know where it is.
The problem is that you decide right there and then that you want to print it.

    memset(receivedChars, 0x00, sizeof(receivedChars));     // i ssuppose this code clear the 
    receivedChars each loop

So that we should remove,

All you need to do is the following.

void loop() {
  SerialReceiver();
  if (newData) {
    Serial.println(receivedChars);
  }
}

Now how big is your buffer ?

Actually let me expand on that a little. This code is a copy of one of Robin2’s Serial Input Basics examples, that someone altered. This someone didn’t know what he was doing, Where did you get this code ? Because like this it doesn’t work.

s.begin(115200);

Keep in mind that on an UNO that BAUD rate is not reliable for reception (it is for transmission)
Apparently it is on the Wemos, (faster CPU) But you are planning to use hwSerial in the end anyway i guess.

If you change to an ESP32 the RTC is onboard
As soon as you connect to a WLAN-router time-information is obtained over WiFi
best regards Stefan

Tnx a lot deva,
As you told me, I changed the code to the original (Robin2’s Serial Input Basics) and everything went as should be. But for the next step I’d like to transfer a JSON. I used the ArduinoJSON-6, I made a JSON object in loop () :

StaticJsonDocument<1000> doc;

then I started creating its children and related nested objects, then convert the JSON to something that able to put in software serial by:

  s.write("<");
  serializeJson(doc, s);  // s: declared as sowtware serial by: SoftwareSerial s(5,6);
  s.write(">");

But on Wemos’s side, I couldn’t receive the complete message, actually, if i consider a very small and simple size JSON from arduino everything will go well but as soon as I change the JSON to a moderate JSON (for example a JSON with 4 objects and each object has more than 2 or 3 nested children) the message in Wemos’s side will be received incomplete and corrupted.

Do you know what the problem is?

Tnx Stephan
ESP32?
You mean something like NodeMCU?
if so, I tested it and get the same problems …