Connecting Arduino with esp32 to send data to MQTT

Hello all,
I want to ask that if I connect Arduino 5V pin to a voltage divider and then from the divider can I connect it to the 3V3 pin of esp32?
If anyone has the schematic of the circuit it will be helpful for me.
I am trying to establish a transmission line from Arduino to ESP32 to send eeg and emg data to MQTT.

No - Use an external power supply for the ESP32 as it can pull quite a large current when operating.

I checked it via multimeter and the voltage is around 3.4V.
Can you suggest that how can I establish a communication between arduino and esp32?
Even if it is a basic program just to check the output.
Thanks

Some forms of transmitting data from an Arduino Uno to an ESP32 are serial, SPI, I2C. Which kind of transmission are you trying to establish?

Also, I cannot see how an Uno can do a thing, like read eeg or emg data and an ESP32 cannot. Would it be a bit more simple to have the ESP32 do the sensor reading and the MQTT thing?

Anyways, once you’ve decided on which form of communication between the 2 devices then, I am sure, support for the chosen communication path can be gained.

You can use resistor a resistor divider to bring the 5V signal down to 3.3V, My preference is to use an active component logic level shift thingy.

Do NOT power the ESP32 from the Arduino Uno.

@bilal93_q, your topic has been moved to a more suitable section of the forum.

I want to establish a serial communication. It goes like this that Arduino provides data to ESP32 and then ESP32 transfers this data to MQTT broker.
I am writing a thesis on an exoskeleton project which has two sensors namely EEG and EMG which provide numeric values after preprocessing.

I want this data to transfer to MQTT broker via ESP32 which is also connected to an Arduino.

Any more advice in that would be helpful. Thank you.

I am confused. What is the Arduino doing? Since the ESP32 can do almost anything the Arduino does, why are you even using an Arduino?

Basically, the sensors are implemented on Arduino that’s why I am trying to make the Arduino read the data and then transfer this data to MQTT via ESP32.

Yea, me too but since the OP insists.

OP, you will, most likely need to use software serial on the Uno, so go get and learn how to set up software serial on the UNO.

Whiles you are studying up on software serial, purchase 2 channels of level shifting or make your own level shifters.

Do an internet search on using the ESP32 serial ports, the ESP32 has 4 but an proficient ESP32 user can only use 3 and you should only use 2, being new to the ESP32.

That should get you started.

If you want I can post ESP32 code on using the serial port BUT it will be using freeRTOS.

Which Arduino?

Arduino Uno R3

Except for analog ports the ESP32, which only has one analog port, can do everything the Uno can do plus it has a faster processor, more RAM, and WiFi built in. If you need more Analog ports, use the MCP3008 Analog Port Expander.

Using an ESP to connect an Uno to WiFi will result in frustration at best. It makes little sense to use an ESP just for WiFi connection when it is perfectly capable of replacing the Uno.

You don’t say which sensors, but some of the new Arduino Nano boards have sensors and WiFi, but I’ve never used any of them. My go-to board is the Wemos D1 Mini. (Mostly because they are only $5 each).

I will try hooking up the ESP32 to send data to MQTT.
Also can you tell me that is there a possibility to have bidirectional communication between ESP32 and MQTT?

I have seen some examples where they use Arduino Uno connected to ESP32 to send data to MQTT and also have bidirectional communication between them.

Also, if you could share any links to a code which I can use to have a communication between ESP32 and MQTT?
Thanks

#include <WiFi.h>
#include <PubSubClient.h>
#include "certs.h"
#include "sdkconfig.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "freertos/event_groups.h"
#include "time.h"
#include <ESP32Time.h>
//
ESP32Time rtc;
//
hw_timer_t * timer = NULL;
EventGroupHandle_t eg;
#define evtDoDisplay ( 1 << 1 )
#define evtDoTheMQTT_Watch   ( 1 << 2 )
#define evtParseMQTT ( 1 << 5 )
#define evtDoTheSunLampThing ( 1 << 10 )
//
int SunLampManual = 0; // manual on or off
int SunLampAuto = 1;// auto mode
int mqttOK = 0;
////
WiFiClient wifiClient;
PubSubClient MQTTclient( mqtt_server, mqtt_port, wifiClient );
////
String str_eTopic;
char strPayload [300] = { '\0' };
////
SemaphoreHandle_t sema_MQTT_Parser; //if parsing is in progress hold up callback a moment to let parsing finish before sending a new things to parse
SemaphoreHandle_t sema_MQTT_KeepAlive;
SemaphoreHandle_t sema_mqttOK;
////
volatile bool TimeSet = false;
volatile int iDoTheThing = 0;
////
void IRAM_ATTR onTimer()
{
  BaseType_t xHigherPriorityTaskWoken;
  iDoTheThing++;
  if ( iDoTheThing == 60000 )
  {
    xEventGroupSetBitsFromISR( eg, evtDoTheSunLampThing, &xHigherPriorityTaskWoken );
    iDoTheThing = 0;
  }
}
////
void IRAM_ATTR mqttCallback(char* topic, byte * payload, unsigned int length)
{
  xSemaphoreTake( sema_MQTT_Parser, portMAX_DELAY); //if parsing is in progress hold up a moment to let parsing finish before sending a new things to parse
  str_eTopic = topic + '\0';
  int i = 0;
  for ( i; i < length; i++) {
    strPayload[i] = ((char)payload[i]);
  }
  strPayload[i] = '\0';
  xSemaphoreGive ( sema_MQTT_Parser );
  xEventGroupSetBits( eg, evtParseMQTT ); // trigger tasks
} // void mqttCallback(char* topic, byte* payload, unsigned int length)
////
void setup()
{
  //
  gpio_config_t io_cfg = {};
  io_cfg.mode = GPIO_MODE_OUTPUT;
  //bit mask of the pins to set
  io_cfg.pin_bit_mask = ( (1ULL << GPIO_NUM_15) );
  //  //configure GPIO with the given settings
  gpio_config(&io_cfg);
  REG_WRITE(GPIO_OUT_W1TC_REG, BIT15); // sunlamp
  //
  /* Use 4th timer of 4.
    1 tick 1/(80MHZ/80) = 1us set divider 80 and count up.
    Attach onTimer function to timer
    Set alarm to call timer ISR, every 1000uS and repeat / reset ISR (true) after each alarm
    Start an timer alarm
  */
  timer = timerBegin( 3, 80, true );
  timerAttachInterrupt( timer, &onTimer, true );
  timerAlarmWrite(timer, 1000, true);
  timerAlarmEnable(timer);
  //
  str_eTopic.reserve(300);
  //
  eg = xEventGroupCreate();
  //
  sema_MQTT_Parser = xSemaphoreCreateBinary();
  sema_MQTT_KeepAlive = xSemaphoreCreateBinary();
  sema_mqttOK    =  xSemaphoreCreateBinary();
  xSemaphoreGive( sema_mqttOK );
  xSemaphoreGive( sema_MQTT_KeepAlive ); // found keep alive can mess with a publish, stop keep alive during publish
  ////
  xTaskCreatePinnedToCore( fparseMQTT, "fparseMQTT", 7000, NULL, 5, NULL, 1 ); // assign all to core 1, WiFi in use.
  xTaskCreatePinnedToCore( MQTTkeepalive, "MQTTkeepalive", 7000, NULL, 2, NULL, 1 ); //this task makes a WiFi and MQTT connection.
  xTaskCreatePinnedToCore( fDoTheSunLampThing, "fDoTheSunLampThing", 2000, NULL, 3, NULL, 1 );
  xTaskCreatePinnedToCore( fmqttWatchDog, "fmqttWatchDog", 2000, NULL, 3, NULL, 1 );
  ////
} //setup() END
////
///
void fmqttWatchDog( void * paramater )
{
  int UpdateImeTrigger = 86400; //seconds in a day
  int UpdateTimeInterval = 86300; // 1st time update in 100 counts
  int maxNonMQTTresponse = 60;
  for (;;)
  {
    vTaskDelay( 1000 );
    xSemaphoreTake( sema_mqttOK, portMAX_DELAY );
    if ( mqttOK >= maxNonMQTTresponse )
    {
      ESP.restart();
    }
    mqttOK++;
    UpdateTimeInterval++; // trigger new time get
    if ( UpdateTimeInterval >= UpdateImeTrigger )
    {
      TimeSet = false; // sets doneTime to false to get an updated time after a days count of seconds
      UpdateTimeInterval = 0;
    }
    //log_i( "mqttOK %d", mqttOK );
    xSemaphoreGive( sema_mqttOK );
  }
  vTaskDelete( NULL );
}
////
void fDoTheSunLampThing( void * parameter )
{
  int _hour = rtc.getHour(true);
  // SunLampManual = sunlamp on manual mode, automatic mode off for manual mode to work
  // SunLampAuto = sun lamp enable automatic mode
  for (;;)
  {
    xEventGroupWaitBits (eg, evtDoTheSunLampThing, pdTRUE, pdTRUE, portMAX_DELAY );
    // sun lamp auto mode of operation
    //log_i( "SunLampManualOnOff %d SunLampAuto %d",  SunLampManual, SunLampAuto  );
    if ( SunLampAuto )
    {
      // run in automated mode
      _hour = rtc.getHour(true); // get hour in 24 hours format
      //log_i( "get hour %d", _hour );
      if ( (_hour >= 7) && (_hour <= 17) )
      {
        REG_WRITE(GPIO_OUT_W1TS_REG, BIT15);
      }
      if ( (_hour < 7) || (_hour > 16) )
      {
        REG_WRITE(GPIO_OUT_W1TC_REG, BIT15);
      }
    } else {
      // manual mode off/on
      if ( (SunLampManual == 1)  )
      {
        REG_WRITE(GPIO_OUT_W1TS_REG, BIT15);
      } else {
        REG_WRITE(GPIO_OUT_W1TC_REG, BIT15);
      }
    }
    //log_i( " AlreadyOn = %d", AlreadyOn );
    xSemaphoreGive( sema_MQTT_KeepAlive );
    //log_i( "fDoTheSunLampThing high watermark %d",  uxTaskGetStackHighWaterMark( NULL ) );
  }
  vTaskDelete( NULL );
} // void fDoTheSunLampThing( void * parameter )
////
/*
    Important to not set vtaskDelay to less then 10. Errors begin to develop with the MQTT and network connection.
    makes the initial wifi/mqtt connection and works to keeps those connections open.
*/
void MQTTkeepalive( void *pvParameters )
{
  // setting must be set before a mqtt connection is made
  MQTTclient.setKeepAlive( 90 ); // setting keep alive to 90 seconds makes for a very reliable connection, must be set before the 1st connection is made.
  for (;;)
  {
    //check for a is-connected and if the WiFi 'thinks' its connected, found checking on both is more realible than just a single check
    if ( (wifiClient.connected()) && (WiFi.status() == WL_CONNECTED) )
    {
      xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY ); // whiles MQTTlient.loop() is running no other mqtt operations should be in process
      MQTTclient.loop();
      xSemaphoreGive( sema_MQTT_KeepAlive );
    }
    else {
      log_i( "MQTT keep alive found MQTT status %s WiFi status %s", String(wifiClient.connected()), String(WiFi.status()) );
      if ( !(WiFi.status() == WL_CONNECTED) )
      {
        connectToWiFi();
      }
      connectToMQTT();
    }
    vTaskDelay( 250 ); //task runs approx every 250 mS
  }
  vTaskDelete ( NULL );
}
////
void connectToMQTT()
{
  // create client ID from mac address
  byte mac[5];
  WiFi.macAddress(mac);
  log_i( "mac address %d.%d.%d.%d.%d", mac[0], mac[1], mac[2], mac[3], mac[4] );
  String clientID = String(mac[0]) + String(mac[4]) ;
  log_i( "connect to mqtt as client %s", clientID );
  while ( !MQTTclient.connected() )
  {
    MQTTclient.connect( clientID.c_str(), mqtt_username, mqtt_password );
    log_i( "connecting to MQTT" );
    vTaskDelay( 250 );
  }
  log_i("MQTT Connected");
  MQTTclient.setCallback( mqttCallback );
  MQTTclient.subscribe( topic_SunLampOn );
  MQTTclient.subscribe( topic_SunLampEnable );
  MQTTclient.subscribe( topicOK );
}
//
void connectToWiFi()
{
  while ( WiFi.status() != WL_CONNECTED )
  {
    WiFi.disconnect();
    WiFi.begin( SSID, PASSWORD );
    vTaskDelay( 4000 );
  }
  WiFi.onEvent( WiFiEvent );
}
////
void fparseMQTT( void *pvParameters )
{
  xSemaphoreGive ( sema_MQTT_Parser );
  for (;;)
  {
    xEventGroupWaitBits ( eg, evtParseMQTT, pdTRUE, pdTRUE, portMAX_DELAY ); //
    xSemaphoreTake( sema_MQTT_Parser, portMAX_DELAY );
    if ( String(str_eTopic) == topic_SunLampOn )
    {
      SunLampManual = String(strPayload).toInt();
    }
    if ( String(str_eTopic) == topic_SunLampEnable )
    {
      SunLampAuto = String(strPayload).toInt();
    }
    // parse the time from the OK message and update MCU time
    if ( String(str_eTopic) == topicOK )
    {
      if ( !TimeSet)
      {
        String temp = "";
        temp = strPayload[0];
        temp += strPayload[1];
        temp += strPayload[2];
        temp += strPayload[3];
        int year =  temp.toInt();
        temp = "";
        temp = strPayload[5];
        temp += strPayload[6];
        int month =  temp.toInt();
        temp = "";
        temp = strPayload[8];
        temp += strPayload[9];
        int day =  temp.toInt();
        temp = "";
        temp = strPayload[11];
        temp += strPayload[12];
        int hour =  temp.toInt();
        temp = "";
        temp = strPayload[14];
        temp += strPayload[15];
        int min =  temp.toInt();
        rtc.setTime( 0, min, hour, day, month, year );
        log_i( "%s   rtc  %s ", strPayload, rtc.getTime() );
        TimeSet = true;
      }
    }
    // clear pointer locations
    memset( strPayload, '\0', 300 );
    str_eTopic = ""; //clear string buffer
    xSemaphoreGive( sema_MQTT_Parser );
    xEventGroupSetBits( eg, evtDoTheSunLampThing );
    xSemaphoreTake( sema_mqttOK, portMAX_DELAY );
    mqttOK = 0;
    xSemaphoreGive( sema_mqttOK );
  }
} // void fparseMQTT( void *pvParameters )
////
// great trouble shooting tool when uncommented
////
void WiFiEvent(WiFiEvent_t event)
{
  // log_i( "[WiFi-event] event: %d\n", event );
  switch (event) {
    //    case SYSTEM_EVENT_WIFI_READY:
    //      log_i("WiFi interface ready");
    //      break;
    //    case SYSTEM_EVENT_SCAN_DONE:
    //      log_i("Completed scan for access points");
    //      break;
    //    case SYSTEM_EVENT_STA_START:
    //      log_i("WiFi client started");
    //      break;
    //    case SYSTEM_EVENT_STA_STOP:
    //      log_i("WiFi clients stopped");
    //      break;
    case SYSTEM_EVENT_STA_CONNECTED:
      log_i("Connected to access point");
      break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
      log_i("Disconnected from WiFi access point");
      break;
    //    case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
    //      log_i("Authentication mode of access point has changed");
    //      break;
    //    case SYSTEM_EVENT_STA_GOT_IP:
    //      log_i ("Obtained IP address: %s",  WiFi.localIP() );
    //      break;
    //    case SYSTEM_EVENT_STA_LOST_IP:
    //      log_i("Lost IP address and IP address is reset to 0");
    //      //      vTaskDelay( 5000 );
    //      //      ESP.restart();
    //      break;
    //    case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
    //      log_i("WiFi Protected Setup (WPS): succeeded in enrollee mode");
    //      break;
    //    case SYSTEM_EVENT_STA_WPS_ER_FAILED:
    //      log_i("WiFi Protected Setup (WPS): failed in enrollee mode");
    //      //      ESP.restart();
    //      break;
    //    case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT:
    //      log_i("WiFi Protected Setup (WPS): timeout in enrollee mode");
    //      break;
    //    case SYSTEM_EVENT_STA_WPS_ER_PIN:
    //      log_i("WiFi Protected Setup (WPS): pin code in enrollee mode");
    //      break;
    //    case SYSTEM_EVENT_AP_START:
    //      log_i("WiFi access point started");
    //      break;
    //    case SYSTEM_EVENT_AP_STOP:
    //      log_i("WiFi access point  stopped");
    //      //      WiFi.mode( WIFI_OFF);
    //      //      esp_sleep_enable_timer_wakeup( 1000000 * 2 ); // 1 second times how many seconds wanted
    //      //      esp_deep_sleep_start();
    //      break;
    //    case SYSTEM_EVENT_AP_STACONNECTED:
    //      log_i("Client connected");
    //      break;
    case SYSTEM_EVENT_AP_STADISCONNECTED:
      log_i("WiFi client disconnected");
      break;
    //    case SYSTEM_EVENT_AP_STAIPASSIGNED:
    //      log_i("Assigned IP address to client");
    //      break;
    //    case SYSTEM_EVENT_AP_PROBEREQRECVED:
    //      log_i("Received probe request");
    //      break;
    //    case SYSTEM_EVENT_GOT_IP6:
    //      log_i("IPv6 is preferred");
    //      break;
    //    case SYSTEM_EVENT_ETH_GOT_IP:
    //      log_i("Obtained IP address");
    //      break;
    default: break;
  }
}
////
void loop() { }

Here is a project of mine that uses a Wemos D1 Mini and it both sends and receives MQTT messages.