text:
How do I make the letters on my Arduino LED matrix scroll faster?
////*************************************************************************
////----------------1.开发环境:Arduino IDE or Visual Studio 2010----------------
////----------------2.使用开发板型号：Arduino UNO          ----------------
////----------------3.单片机使用晶振：16M                   ----------------
////----------------4.店铺名称：大学生电子商铺/小强电子设计  ----------------
////----------------5.淘宝网址：Ilovemcu.taobao.com       ----------------
////----------------        52dpj.taobao.com                ----------------
////----------------6.作者：神秘藏宝室              ----------------
////***********************************************************************

#include <Arduino.h>

//IO配置
#define LEDARRAY_D 5
#define LEDARRAY_C 6
#define LEDARRAY_B 7
#define LEDARRAY_A 8
#define LEDARRAY_G 9
#define LEDARRAY_DI 10
#define LEDARRAY_CLK 11
#define LEDARRAY_LAT 12

#define led 13

#define Display_Num_Word 2              //液晶能显示的汉字个数

unsigned char Display_Buffer[8];
unsigned char Display_Swap_Buffer[Display_Num_Word][32]={0};                    //显示缓冲区
bool Shift_Bit = 0;
bool Flag_Shift = 0;
unsigned char Timer0_Count = 0;
unsigned char temp = 0x80;
unsigned char Shift_Count = 0;
unsigned char Display_Word_Count = 0;

#define Num_Of_Word 33
const unsigned char Word[Num_Of_Word][32] =
{
0xFF,0xFF,0xFF,0x07,0xBB,0xBB,0xBB,0x87,0xBB,0xBD,0xBD,0xBD,0xBB,0x07,0xFF,0xFF,/*"B",0*/
0xFF,0xFF,0xFF,0xC7,0xBB,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0xBB,0xC7,0xFF,0xFF,/*"O"*/
0xFF,0xFF,0xFF,0x83,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0x83,0xFF,0xFF,/*"I",0*/
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
0xFF,0xFF,0xFF,0xC1,0xBD,0xBD,0xBF,0xDF,0xE7,0xFB,0xFD,0xBD,0xBD,0x83,0xFF,0xFF,/*"S"*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x03,0xBD,0xBD,0xBD,0x83,0xB7,0xB7,0xBB,0xBB,0xBD,0x1C,0xFF,0xFF,/*"R",0*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x83,0xBD,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBD,0x83,0xFF,0xFF,
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x03,0xBD,0xBD,0xBD,0x83,0xB7,0xB7,0xBB,0xBB,0xBD,0x1C,0xFF,0xFF,/*"R",0*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xC1,0xBD,0xBD,0xBF,0xDF,0xE7,0xFB,0xFD,0xBD,0xBD,0x83,0xFF,0xFF,/*"S"*/
0xFF,0xFF,0xFF,0x83,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0x83,0xFF,0xFF,/*"I",0*/
0xFF,0xFF,0xFF,0xC3,0xBB,0xBB,0x7F,0x7F,0x7F,0x71,0x7B,0xBB,0xBB,0xC7,0xFF,0xFF,/*"G",0*/
0xFF,0xFF,0xFF,0xBF,0x83,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xC7,0xBB,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0xBB,0xC7,0xFF,0xFF,/*"O"*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x01,0x6D,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xC7,0xFF,0xFF,/*"T",0*/
0xFF,0xFF,0xFF,0x18,0xBD,0xBD,0xBD,0xBD,0x81,0xBD,0xBD,0xBD,0xBD,0x18,0xFF,0xFF,/*"H",0*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x07,0xBB,0xBB,0xBB,0x87,0xBB,0xBD,0xBD,0xBD,0xBB,0x07,0xFF,0xFF,/*"B",0*/
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x83,0xBD,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBD,0x83,0xFF,0xFF,
0xFF,0xFF,0xFF,0xBE,0xBD,0xBB,0xB7,0xB7,0xBB,0xBB,0xBD,0xBD,0xBE,0xBE,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x07,0xBB,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBB,0x07,0xFF,0xFF,/*"D",0*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x01,0x6D,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xC7,0xFF,0xFF,/*"T",0*/
0xFF,0xFF,0xFF,0x18,0xBD,0xBD,0xBD,0xBD,0x81,0xBD,0xBD,0xBD,0xBD,0x18,0xFF,0xFF,/*"H",0*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xDF,0xD7,0xB7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xBE,0xBD,0xBB,0xB7,0xB7,0xBB,0xBB,0xBD,0xBD,0xBE,0xBE,0xFF,0xFF,
0xFF,0xFF,0xFF,0x83,0xBD,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBD,0x83,0xFF,0xFF,
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xFF,0xFF,
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
};
void setup()
{
    pinMode(LEDARRAY_D, OUTPUT);
    pinMode(LEDARRAY_C, OUTPUT);
    pinMode(LEDARRAY_B, OUTPUT);
    pinMode(LEDARRAY_A, OUTPUT);
    pinMode(LEDARRAY_G, OUTPUT);
    pinMode(LEDARRAY_DI, OUTPUT);
    pinMode(LEDARRAY_CLK, OUTPUT);
    pinMode(LEDARRAY_LAT, OUTPUT);

    Clear_Display();
}

void loop()
{
    unsigned int i;
    for(i = 0;i<30;i++)
    {
        Display(Display_Swap_Buffer);
    }
    Display_Word_Count = Shift_Count/16;                //计算当前显示第几个字
    Calc_Shift();

    Shift_Count++;

    if(Shift_Count == (Num_Of_Word+Display_Num_Word)*16 )               //移动次数
    {
        Shift_Count = 0;
    }
}

//************************************************************
//清空缓冲区
//************************************************************
void Clear_Display()
{
    unsigned char i,j;
    for(j = 0 ; j < Display_Num_Word; j++)
    {
        for(i = 0 ; i < 32 ;i++)
        {
            Display_Swap_Buffer[j][i] = 0xff;               //0=显示  1=不显示
        }
    }
}

//************************************************************
//计算移动数据，存在在缓冲器
//************************************************************
void Calc_Shift()
{
    unsigned char i;

    for(i = 0;i < 16;i++)
    {
        if((Display_Swap_Buffer[0][16+i]&0x80) == 0)                                    //每行第一个字节移位
        {
            Display_Swap_Buffer[0][i] = (Display_Swap_Buffer[0][i] << 1)&0xfe;          //最低位清零
        }
        else
        {
            Display_Swap_Buffer[0][i] = (Display_Swap_Buffer[0][i] << 1)|0x01;          //最低位置一
        }

        if((Display_Swap_Buffer[1][i]&0x80) == 0)                                   //每行第二个字节移位
        {
            Display_Swap_Buffer[0][16+i] = (Display_Swap_Buffer[0][16+i] << 1)&0xfe;            //最低位清零
        }
        else
        {
            Display_Swap_Buffer[0][16+i] = (Display_Swap_Buffer[0][16+i] << 1)|0x01;            //最低位置一
        }

        if((Display_Swap_Buffer[1][16+i]&0x80) == 0)                                    //每行第三个字节移位
        {
            Display_Swap_Buffer[1][i] = (Display_Swap_Buffer[1][i] << 1)&0xfe;          //最低位清零
        }
        else
        {
            Display_Swap_Buffer[1][i] = (Display_Swap_Buffer[1][i] << 1)|0x01;          //最低位置一
        }

        if(Shift_Count%16 < 8 && Display_Word_Count < Num_Of_Word)
        {
            Shift_Bit = Word[Display_Word_Count][i]&temp;
        }
        else if(Shift_Count%16 < 16 && Display_Word_Count < Num_Of_Word)
        {
            Shift_Bit = Word[Display_Word_Count][16+i]&temp;
        }
        else
        {
            Shift_Bit = 1;                      //把字移出缓冲区
        }

        if( Shift_Bit == 0)                                                     //后8位移位
        {
            Display_Swap_Buffer[1][16+i] = (Display_Swap_Buffer[1][16+i] << 1)&0xfe;        //最低位清零
        }
        else
        {
            Shift_Bit = 1;
            Display_Swap_Buffer[1][16+i] = (Display_Swap_Buffer[1][16+i] << 1)|0x01;        //最低位置一
        }

    }
    temp = (temp>>1)&0x7f;
    if(temp == 0x00)
    {
        temp = 0x80;
    }
}
//************************************************************
//num为字数  dat[][32]为字模的名称
//*************************************************************
void Display(const unsigned char dat[][32])
{
    unsigned char i;

    for( i = 0 ; i < 16 ; i++ )
    {
        digitalWrite(LEDARRAY_G, HIGH);     //更新数据时候关闭显示。等更新完数据，打开138显示行。防止重影。

        Display_Buffer[0] = dat[0][i];
        Display_Buffer[1] = dat[0][i+16];
        Display_Buffer[2] = dat[1][i];
        Display_Buffer[3] = dat[1][i+16];

    Display_Buffer[4] = dat[2][i];
    Display_Buffer[5] = dat[2][i+16];
    Display_Buffer[6] = dat[3][i];
    Display_Buffer[7] = dat[3][i+16];

    Send(Display_Buffer[7]);
    Send(Display_Buffer[6]);
    Send(Display_Buffer[5]);
    Send(Display_Buffer[4]);

        Send(Display_Buffer[3]);
        Send(Display_Buffer[2]);
        Send(Display_Buffer[1]);
        Send(Display_Buffer[0]);

        digitalWrite(LEDARRAY_LAT, HIGH);                   //锁存数据
        delayMicroseconds(0.1);

        digitalWrite(LEDARRAY_LAT, LOW);
        delayMicroseconds(0.1);

        Scan_Line(i);                       //选择第i行

        digitalWrite(LEDARRAY_G, LOW);

        delayMicroseconds(100);;        //延时一段时间，让LED亮起来。
    }
}

//****************************************************
//扫描某一行
//****************************************************
void Scan_Line( unsigned char m)
{
    switch(m)
    {
        case 0:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 1:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);
            break;
        case 2:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 3:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);
            break;
        case 4:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 5:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);
            break;
        case 6:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 7:
            digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);
            break;
        case 8:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 9:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);
            break;
        case 10:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 11:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);
            break;
        case 12:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 13:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);
            break;
        case 14:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);
            break;
        case 15:
            digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);
            break;
        default : break;
    }
}

//****************************************************
//发送数据
//****************************************************
void Send( unsigned char dat)
{
    unsigned char i;
    digitalWrite(LEDARRAY_CLK, LOW);
    delayMicroseconds(0);;
    digitalWrite(LEDARRAY_LAT, LOW);
    delayMicroseconds(0);;

    for( i = 0 ; i < 8 ; i++ )
    {
        if( dat&0x01 )
        {
            digitalWrite(LEDARRAY_DI, HIGH);
        }
        else
        {
            digitalWrite(LEDARRAY_DI, LOW);
        }

        digitalWrite(LEDARRAY_CLK, HIGH);               //上升沿发送数据
            delayMicroseconds(0);;
        digitalWrite(LEDARRAY_CLK, LOW);
            delayMicroseconds(0);;
        dat >>= 1;

    }
}

reduce any delays as much as practicable - if you've reduced them as far as you can, then you have achieved the maximum speed your code allows - if this isn't fast enough, then use a faster MCU, or perhaps your code can be written better, but this is unknown as the code is almost unreadable as it stands

Start by measuring the update time (microseconds). After that you may consider optimizations, for instance, faster digitalWrite, direct port access, SPI, etc.

You have 30x loop calling Display() that inside a 16X loop calls eight Send() that inside an 8x loop makes three digital writes each taking at least 2us to complete. At a minimum, only digitalWrite takes 180ms in one pass.
Use SPI if possible or search Google for "arduino speed up digitalWrite" , here is a good article on this.
Also unrolling the 8x loop inside Send() like this can spare some ms:
   if( dat&0x01 ) digitalWrite(LEDARRAY_DI, HIGH);
   else digitalWrite(LEDARRAY_DI, LOW);
   digitalWrite(LEDARRAY_CLK, HIGH);               //上升沿发送数据
   delayMicroseconds(0);;
   digitalWrite(LEDARRAY_CLK, LOW);
   delayMicroseconds(0);
   if( dat&0x02 ) digitalWrite(LEDARRAY_DI, HIGH);
   else digitalWrite(LEDARRAY_DI, LOW);
   digitalWrite(LEDARRAY_CLK, HIGH);               //上升沿发送数据
   delayMicroseconds(0);;
   digitalWrite(LEDARRAY_CLK, LOW);
   delayMicroseconds(0);
   ........
   if( dat&0x80 ) digitalWrite(LEDARRAY_DI, HIGH);
   else digitalWrite(LEDARRAY_DI, LOW);
   digitalWrite(LEDARRAY_CLK, HIGH);               //上升沿发送数据
   delayMicroseconds(0);;
   digitalWrite(LEDARRAY_CLK, LOW);
   delayMicroseconds(0);

These lines
    digitalWrite(LEDARRAY_LAT, HIGH);                   //锁存数据
    delayMicroseconds(0.1);

    digitalWrite(LEDARRAY_LAT, LOW);
    delayMicroseconds(0.1);

    Scan_Line(i);                       //选择第i行

    digitalWrite(LEDARRAY_G, LOW);

    delayMicroseconds(100);;        //延时一段时间，让LED亮起来。

Reduce the time in the last one.
I don't think delayMicroseconds(0.1); does anything, nor does delayMicroseconds(0); found elsewhere.
I see individual pins being controlled
#define LEDARRAY_D 5
#define LEDARRAY_C 6
#define LEDARRAY_B 7
#define LEDARRAY_A 8
#define LEDARRAY_G 9
#define LEDARRAY_DI 10
#define LEDARRAY_CLK 11
#define LEDARRAY_LAT 12

You don't say what the hardware is, but I bet you replace writing individual pins with blasting data out serially to a shift register with 8 MHz SPI clock as a way speed things up. Or if you had a '1284P or '2560 board, then you could do port writes also.


text:
How to connect 3 MPU9250 to Node Mcu together?
I don't know how to connect 3 MPU9250 together on Node Mcu. There is not much information available. I am using bolder flight library for imu sensor - https://github.com/bolderflight/MPU9250
Can anyone post the image of connection on sensor and example of code? Thanks a lot.

it connects the same way as any other I2C device, so lookup an image of say, an oled or ads1115 adc or something like that.

but I want to do it 3 together?

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Program Arduino via UART from ESP8266 SPIFFS
I have built a custom board that has an ATmega328p connected to an ESP8266 module via UART. I am currently programming the ATmega328p using a USBtiny programmer via an SPI header. The ESP8266 module is programmed via an FTDI cable connected the the UART.
Firmware for both are created in Arduino IDE.
I have set up a webserver on the ESP that allows for files to be uploaded to the SPIFFS via FTP. I would like to be able to upload a hex file for the ATmega and then have the ESP program the ATmega via the UART connection. A GPIO on the ESP controls a transistor that can pull the reset pin on the ATmega to ground.
I know I need a bootloader on the ATmega (e.g. optiboot), but I don't know what I need to make the ESP do to trigger the bootloader and flash the ATmega. I'm thinking I need something like:
void initialiseAtmegaFlash () {
  // Trigger the bootloader to accept incoming hex over UART
}

void flashHexToAtmega (File atmegaHex) {
  for (uint32_t i = 0; i < atmegaHex.size(); ++i) {
    // Handle timing of sending byte by byte over serial... or chunk by chunk?
  }
}

You need to start by understanding the STK500 protocol. Read and digest: http://ww1.microchip.com/downloads/en/AppNotes/doc2591.pdf

you can use the dfu library from here https://github.com/jandrassy/arduino-firmware-wifilink#atmega328p-sketch-ota-upload-support

That dfu library looks like I need to initiate the upload from Arduino IDE on the same network. The STK500 protocol documentation looks like the sort of thing I need. I was hoping there might be a neat library already, but looks like the info I need to get the functionality.

https://github.com/ciminaghi/libdfu

did u managed to do it? If yes, kindly share the details with me also and the connections.

To answer my own question in case someone else ends up here, the library Juraj suggested (https://github.com/ciminaghi/libdfu) looks like it does the job. I also found another project doing something similar (https://github.com/rene-win/esp_avr_programmer). Also the STK500 docs linked to by Majenko (http://ww1.microchip.com/downloads/en/AppNotes/doc2591.pdf) are really useful for understanding the nuts and bolts!

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
I got a problem in sending voice file
I wrote a code that can send a file.
If I send a text file it will work perfectly, but when I try to send voice it will send the whole file form the Sender side, but in the receiver side he won't understand some data or he won't read it i don't know what happened
i tried to send 50k byte and the  receiver only receive 20K
. I tried to send .wav .mp3 .m4p.
the Sender code
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SPI.h>
#include <SD.h>

const int push1 = 2;

File myFile;
char a[168];
int c= 0;
int counter = 0 ;
unsigned long data;
unsigned long result;
unsigned long remaining ;

// network parameters
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0E, 0x05, 0x02 };  // ethernet interface MAC address
IPAddress localIp(10,131,41,72);    // local ip address
IPAddress destIp(10,131,41,74);      // destination ip address
unsigned int port = 9631;               // destination port

// EthernetUDP to send and receive messages.
EthernetUDP Udp;

// timing

// setup the arduino and shields
void setup() {

    pinMode(push1, INPUT);

  //Initialize serial and wait for port to open:
  Serial.begin(9600); // 19200
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

  // start ethernet and udp
  Ethernet.begin(mac, localIp);   // static ip version
  //if(Ethernet.begin(mac) == 0) {     // dhcp version
  // report failure to obtain network parameters
  // Serial.println("DHCP error");

  // no point in carrying on, loop indefinitely:
  // while(true)
  // ;
  //}

  // open UDP port
  Udp.begin(port);

  // show the local ip address (useful for dhcp)
  Serial.print("Local IP: ");
  Serial.println(Ethernet.localIP());

}

// do tasks
void loop() {

if(digitalRead(push1) == LOW){

    myFile = SD.open("SV12.wav");
     data = myFile.size();

//     result = myFile.position();

  if (myFile) {
    Serial.println("inside the file there's");
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      a[c] = myFile.read();
       Serial.print(a[c]);
       c++;
      if ( c==168){
        Serial.println("");
      Serial.println("i will send now");
      Udp.beginPacket(destIp, port);
      Udp.write(a,168);
      Udp.endPacket();
      delay(250);
      Serial.println("Sending UDP message");
       counter++;
       Serial.print("Sending packet#");
       Serial.println(counter);
//         for (int x = 0 ; x<c ; x++){
//
//         a[x] = '\0';}
         c=0;

  Serial.println("clearing");}

//  Serial.println(result);
    }

          if ( c<168 ){ // if (remaining)
      Serial.println("i will send now");
      Udp.beginPacket(destIp, port);
      Udp.write(a,168);
      Udp.endPacket();
      Serial.println("Sending UDP message Last segment");
//      counter++;
//         for (int x = 0 ; x<c ; x++){
//
//         a[x] = '\0';}
         c=0;}

    // close the file:
    myFile.close();
     Serial.println("im here");
    Serial.println(counter);
    Serial.println("END");
  } else {
   // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
 }

}
}

the Reciver code
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SD.h>

int LED = 8;
int x=0;

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x06
};
IPAddress ip(10,131,41,74);
IPAddress remIp(10,131,41,72);

unsigned int localPort = 9631;      // local port to listen on // 123456

File myFile;
char y[100];
int c= 0;

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

char packetBuffer[168]; //buffer to hold incoming packet,
//UDP_TX_PACKET_MAX_SIZE
void setup()
{
  // start the Ethernet and UDP:
  Ethernet.begin(mac, ip);
  Udp.begin(localPort);
  pinMode(LED, OUTPUT);
  Serial.begin(9600);//change and try
  Serial.print("Local IP: ");
  Serial.println(Ethernet.localIP());

    if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

}

void loop()
{

  int packetSize = Udp.parsePacket();

  if (packetSize)
  {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i = 0; i < 4; i++)
    {
      Serial.print(remote[i], DEC);
      if (i < 3)
      {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer, 168);
    Serial.println("Contents:");

    RandS();
    Serial.println(x); //to check the message

  }

}

void RandS(){

   myFile = SD.open("Last123.mp3", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.println("i'm Writing what i got from UDP");
    myFile.print(packetBuffer);
    x++;
    // close the file:
    myFile.close();

    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

}

Can someone help please?

Could you show the serial output?

Check: Does Udp.write(a) terminate on zero? Shouldn't it be something like Udp.write(a, c)?

how do you know that the problem is caused by the type of file? ..... have you verified that the problem is not related to file size?

I kind of solved the old problem and other problem showed up, i modify the question above hope you can see it and help, thx.

Hint: Add a sequence number and you might be able to detect dropped UDP packages. You might want to use TCP instead.

i printed that arrived packet there's no packet are dropped, I'm Trying to do audio streaming UDP is the best choice, the problem here is when I try to store the arrival packet on the SD card something wrong happened and it store only few bytes


text:
How to connect MPU9250 with NodeMCU using SPI or I2C Slave?
I want to connect 3 MPU9250 sensors, but since there is just one I2C bus, so there are another 2 sensors I want to connect through SPI.
Library used - https://github.com/bolderflight/MPU9250/blob/master/examples/Basic_SPI/Basic_SPI.ino
There is an SPI example code written, but I don't know about the connections. There are no MISO and other pins on the sensor which i use but its SPI compatible. How do I connect 2 MPU9250 to NodeMCU with SPI?
If SPI connection is not possible then please post about I2C slave connection.

The MPU-9250 I2C address will be 0x68 if the AD0 pin is grounded or 0x69 if the AD0 pin is pulled high. So there's 2. The third one would be more complex, though you could use 2 i2c and 1 spi. You can also just use a 2nd pair of pins to run an additional i2c bus to the 3rd sensor, instantiae another Wire instance (passing the pins numbers to it) and feeding that wire instance to the MPU9250FIFO  constructor.

if you are working on a sensor your should have read its datasheet first rather going for some arduino library instead.

If you want to use SPI-
The homepage of the library you mentioned, clearly explains the circuit connections.-
The MPU-9250 pins should be connected as:

VDD: this should be a 2.4V to 3.6V power source.
GND: ground.
VDDI: digital I/O supply voltage. This should be between 1.71V and
VDD.
FSYNC: not used, should be grounded.
INT: (optional) used for the interrupt output setup in
enableDataReadyInterrupt and enableWakeOnMotion. Connect to
interruptable pin on microcontroller.
SDA / SDI: connect to MOSI.
SCL / SCLK: connect to SCK.
AD0 / SDO: connect to MISO.
nCS: connect to chip select pin. Pin 10 was used in the code snippets
in this document  and the included examples, but any digital I/O pin
can be used.
AUXDA: not used.
AUXCL: not used.

Each sensor's nCS (chip select pin) needs to be connected to a slave select pin (any digital pin) on the NodeMCU. This allows the NodeMCU toselect which sensor it wants to talk to.
Another easy way of connecting multiple sensors with the same I2C address is by using an I2C multiplexer like the Adafruit TCA9548A

This would allow you to connect up to 8 sensors having the same I2C address. Here's a youtube video explaining how to do so.
However, if you just want connect two MPU9250s, you dont need to do any of this, as the board offers two unique addresses via the AD0 pin-

0x68 if AD0 is grounded
0x69 if AD0 is pulled high

To connect multiple SPI components, you only need 4 pins on each 'slave' (thus sensors): SLCK, MOSI, MISO and SS (Slave Select).
The Slave select pin depends to which the master (NodeMCU in your case) is 'talking too'. So on your NodeMCU you will have 3 SS pins (one for each slave sensor). The NodeMCU should talk exactly to one slave device at the same time by setting that SS pin LOW (while the other SS pins are high).
See for the full article: Multiple-SPI-devices-to-an-arduino-microcontroller.

I uploaded the sensor image, which pin is SCLK, MOSI, MISO & SS in this case?

Those are I2C slaves, SPI is a completely different protocol.

Can you post the answer about connect 3 mpu9250 sensor with i2c slave? Thanks so far

I don't have much experience with I2C, I think the SDA and SCL are default I2C connection/pins, so use those.

The MPU-9250 pins should be connected as:
--Vcc: this should be a 2.4V to 3.6V power source.
--GND: ground.
--FSYNC: not used, should be grounded.
--SDA / SDI: connect to MOSI.
--SCL / SCLK: connect to SCK.
--AD0 / SDO: connect to MISO.
--nCS: connect to chip select pin (Any digital pin but in your example is PIN 10).
Also, you can check the connection from:
https://learn.sparkfun.com/tutorials/mpu-9250-hookup-guide?_ga=1.139382715.926858641.1470020364


text:
Arduino should check the same way like a USB keyboard or a USB mouse, if turned on notebook is connected
I have a USB HUB and have connected to it a USB keyboard and a USB mouse. As long I have not connected a Notebook to it those devices don't turn on. 5V is always turned on! So I could charge my phone. How do they know there is no notebook connected? My Arduino is always on. I want to emulate this with an Arduino. Without the need of extra software on a notebook, the Arduino should be able to tell if a notebook is connected to the USB Hub or not. Please help.

On the Nano, the FT232RL chip does the USB communication. This chip has a PWREN option. When you configure the chip for this, the selected pin will be HIGH if there is no USB host. You could carefully solder a wire from the selected pin (CBUS0-4) to one of the Arduino pins, so the ATMega328 can read it out.

just monitor the current of the hub, it will increase a lot if everything turns on.

I want to understand how a cheap USB mouse is doing it, and do the same thing with an arduino.

those devices don't turn on .... how do you know? .... you have no way to test that

Sure! The usb mouse does not light up (the red laser beneath) and on the keyboard you can not get any lights to light up (for example the numpad light)

With Arduino Nano, you don't have control over the USB, because it is handled by the USB-to-TTL-Serial chip on the board. The MCU is to this adapter connected only with RX and TX of the Serial interface.
With Arduino Micro you could retrieve the state of the USB connection, because he MCU ATmega32u4 has a build in USB support an handles the USB connection from application (sketch).

So the digispark would work, too?

ATtiny doesn't have native USB but Digispark has circuit for V-USB (software USB)

@Alexander_Projects, did the answer help?


text:
Arduino program to scan two different rfid cards in same program ? Im using nodemcu- esp8266 , rc522 reader and Firebase
/*My project is a Library management system using rfid cards. Im trying to generate a code wherein User first scan a book and then the record will be pushed in Issued_Books table in Firebase . Then the user scans his id to ensure that the book will be issued on his/her id.
But in my program is scanning only books id. It fails to scan users Id after that. Im a beginner so can anyone guide me? */
//My loop code is as following:
void loop() {

  if ( !mfrc522.PICC_IsNewCardPresent() ) {
    delay(50);
    return;
  }

  if ( !mfrc522.PICC_ReadCardSerial() ) {
    delay(50);
    return;
  }
String book;

  for ( byte i = 0; i< mfrc522.uid.size; i++ ) {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    book.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    book.concat(String(mfrc522.uid.uidByte[i], HEX));}
    book.toUpperCase();

    Firebase.pushString("Issued_Books/Book_rfid",book);

      Serial.println();

  if ( !mfrc522.PICC_IsNewCardPresent() ) {
    delay(50);
    return;
  }

  if ( !mfrc522.PICC_ReadCardSerial() ) {
    delay(50);
    return;
  }
  String user;

  //Serial.print("Scan your id: ");
    for ( byte i = 0; i< mfrc522.uid.size; i++ ) {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    user.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    user.concat(String(mfrc522.uid.uidByte[i], HEX));}
    user.toUpperCase();
    //Serial.print(F("Card UID: "));
    Firebase.setString("Issued_Books/Book_rfid/user_rfid",user);

    delay(3000);
}

also look into sprintf to get hex formatting
(I dont have these libraries so I cannot test, this is all written in stackexchange editor, so I might have a typo somewhere)
unsigned long startScanTime;
bool GotBookId = false, GotUserId = false;
void loop() {
GotBookId = false;
GotUserId = false;

  if ( !mfrc522.PICC_IsNewCardPresent() ) {
    delay(50);
    return;
  }

  if ( !mfrc522.PICC_ReadCardSerial() ) {
    delay(50);
    return;
  }
String book;

  for ( byte i = 0; i< mfrc522.uid.size; i++ ) {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    book.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    book.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
    book.toUpperCase();
    if(book != "")
       GotBookId = true;

    Serial.println("Got Book");

startScanTime = millis(); //timeout look to get user card
  while( !mfrc522.PICC_IsNewCardPresent() && (millis() - startScanTime < SCAN_TIMEOUT) ) {
   //do nothing but wait
  }

  if(!mfrc522.PICC_IsNewCardPresent())
  { //did not get the user id, return from loop
      return;
  }
  if ( !mfrc522.PICC_ReadCardSerial() ) {
    return; //should never hit this if library works correctly
  }
  String user;

  Serial.print("Scan your id: ");
    for ( byte i = 0; i< mfrc522.uid.size; i++ ) {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    user.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    user.concat(String(mfrc522.uid.uidByte[i], HEX));}
    user.toUpperCase();
    //Serial.print(F("Card UID: "));
    GotUserId = true;

   if(GotBookId && GotUserId){
       Firebase.pushString("Issued_Books/Book_rfid",book);
       Firebase.setString("Issued_Books/Book_rfid/user_rfid",user);
   }
}

Thanks for the reply , but actually even this code is encountering the same problem. After first scan the code eventually pushing same rfid as a 'book' and 'user' in the firebase where I want the user to scan a book whose rfid will be stored in firebase then user will scan his id and an user id will be set for that particular book.

Every book will be issued by a particular user ..so user id should be stored each time differently for that particular book . I mean 1 book rfid will have 1 user rfid. but due to setString(); each time it only updates previous id . Any solution for above problems?

I have not worked with Firebase so I am not familiar with their API, but a 10 second google query lead me to here which cites the update method you should be using instead of the set string
https://firebase.google.com/docs/database/admin/save-data

thanks but Im confused how to do it in firebase arduino. I mean through C Programming

have you tried something like Firebase.setString(String("Issued_Books/Book_rfid/") + String(book) + String("/user_rfid"),user);


text:
Optimizing Teensy 3.6 for data sampling?
So, I have a very basic project where I cycle through 8 IR individual transmitters. After setting the individual transmitter high, I cycle through all 8 IR receivers and print their values, RX_CYCLES many times. I need a huge amount, quality data from these loops to train a neural net, so
I want to optimize my code to where I can analogRead each receiver the fastest, but keep the maximum resolution possible.
I'm having trouble understanding Teensy's documentation and provided libraries and finding any relevant resources that are clear enough for me to weave through the jargon.

My questions are:

What would be or how do I go about calculating the optimization or balance of the fastest baudrate I can match with the Teensy 3.6, with the highest quality resolution possible?
How to optimize analogRead? I've read that the fastest way is to use continuous analogRead instead of single analogRead? I'm having trouble finding clear examples of what this actually does and how to use it effectively. I definitely could be wrong about it this.
Am I outputting data the best way possible? I was wondering if there would be any reason in my case to use print() or println() or if I should be using flush() after every cycle

These are a lot of questions, and I don't expect anyone to optimize my code for me, so if you can help point me in the direction of clear material I can use to direct me in this problem.
I'd also really appreciate any other suggestions or insight anyone would like to offer that I may be missing.

This is my very basic code:
const uint8_t RX_CYCLES = 1;
const uint8_t RX_START = 14, RX_END = 21;
const uint8_t TX_START = 0, TX_END = 7;

void setup() {
    Serial.begin(115200);
    while (!Serial);
    for (uint8_t reciever = RX_START; reciever <= RX_END; reciever++) pinMode(reciever, INPUT);
    for (uint8_t transmitter = TX_START; transmitter <= TX_END; transmitter++) pinMode(transmitter, OUTPUT);
}

void loop() {
    for (uint8_t transmitter = TX_START; transmitter <= TX_END; transmitter++) {
        digitalWriteFast(transmitter, HIGH);
        for (uint8_t i = 0; i < RX_CYCLES; i++) {
            for (uint8_t reciever = RX_START; reciever <= RX_END; reciever++) Serial.println(analogRead(reciever));
        }
        digitalWriteFast(transmitter, LOW);
    }
}

I was thinking of using DMA. It also seems that analogRead is pretty slow on the teensy because it calibrates itself every times it's called. This thread seems to contain a lot of useful info: https://forum.pjrc.com/threads/30171-Reconfigure-ADC-via-a-DMA-transfer-to-allow-multiple-Channel-Acquisition

@Gerben if the optimization would be turning off calibration before every call, wouldn't this produce uncalibrated readings which inherently agains't anyones interest?

please correct me if i'm wrong, but it seems to me that you have not explained what you are measuring and what parameter you are referring to when you say "maximum resolution" ..... just because you are using analogRead, it cannot be assumed that you are only measuring analog levels of some physical property

@jsotola I meant to imply that the IR receivers where measuring the output of the current IR transmitter in the loop. I realize now that's not so obvious. From what I understand resolution refers to the specificity of data, so having the highest resolution possible is the difference between 1024 and 1023.67. I'm going to break this question up, I think this may be too much and broad to ask.


text:
Need little bit of help on testing I2C sketch
I have this code I got from YouTube for communicating between two Arduinos. By typing 'R' manually into the serial monitor of the 'master' Arduino, the 'slave' will print "Success". I'm trying all this for the basis of a project I'm starting.
After success with the code, I am now trying to make it automatic. I want the 'master' Arduino to print "R" itself and for the 'slave' to read this and print "Success". println doesn't work here, maybe it'll work if the slave code is changed? Both original codes are below, any ideas on how to do what I need?
Master:
#include <Wire.h>
char incomingByte;
int x = 0;

void setup() {
  Serial.begin(9600);
  Wire.begin();
}

void loop()
{
  Wire.beginTransmission(9);
  if (Serial.available()) {
    while (Serial.available() > 0) {
      incomingByte = Serial.read();
      Wire.write(incomingByte);
      Serial.println(incomingByte);
      Wire.endTransmission();
  }
  }

}

Slave:
#include <Wire.h>

int x = 0;

void setup() {
  Wire.begin(9);
  Wire.onReceive(recieveEvent);
  Serial.begin(9600);
}

void recieveEvent(int bytes) {
  x = Wire.read();

}

void loop() {

  if (x == 'R'){
    Serial.println("Success");
    delay(100);
  }
}

Your Master supposedly should send 'R'. Where is the place in the code this happen?

Look at what the master is doing. It's reading from serial and writing what it reads to Wire. How do you think you would make it send an R rather than what it reads from serial?

make x volatile. volatile int x = 0;

@MarkSmith That's what I'm unsure of. I am new at this so I don't know what to change in either codes.

@smajli I have to manually type 'R' into the serial monitor.

Josh, what is your project? What problem are you trying to solve by using two arduino boards?

@Josh. You're getting these types of comments because StackExchange requires you show an effort at understanding the question you're asking. If you can't answer how to change the Master where the variable that is received is sent to the I2C device, you'd just be copying and pasting someone else's code that you don't understand, as appears to be the case with the code you managed to get working already.

The I2C communication is not easy and there are many things that can go wrong. Two Arduino boards instead of one board are often used for the wrong reason in the first place.
Using a serial port is easier. The Arduino Leonardo has an extra hardware serial port, you could use the serial port to communicate between two Arduino boards. The Arduino Mega 2560 has three extra serial ports.
Sometimes two Arduino boards are used because multiple things have to be done at the same time.
When you use the Blink Without Delay example with millis, then the Arduino can do many things at the same time.
Sometimes two Arduino boards are used because there is some distance between the Arduino boards.
The I2C bus is a "bus", but that does not mean that you can use a long cable. You can go up to 20 inch (50 cm).
When two Arduino Uno boards are connected with the I2C bus, then three wires are needed:

GND to GND
SDA to SDA  (plus pullup resistor)
SCL to SCL  (plus pullup resistor)

For a small test with short jumper wires, it is possible to do that without pullup resistors. For the final project pullup resistors should be used for SDA and SCL, for example 4k7 or 10k.
The example below uses a flag in the Slave Arduino. That extra variable makes it easier.
In the Slave receiveEvent function, there is a extra check to check if exactly one byte is received. That extra check is not required, but it can be useful.
I show this example as something to start with, because there are too many bad examples for I2C between Master and Slave.
Master
#include <Wire.h>

byte dataTransmit;

void setup() {
  Wire.begin();
}

void loop() {
  Wire.beginTransmission(9);   // sending to slave with i2c address 9
  Wire.write(dataTransmit);    // the data to send
  Wire.endTransmission();

  dataTransmit++;              // all numbers from 0 to 255

  delay(250);                  // 250ms delay, to send 4 times per second
}

Slave
#include <Wire.h>

volatile byte dataReceive;
volatile bool newData;    // a flag to indicate that new data has arrived

void setup() {
  Wire.begin(9);          // create i2c slave at i2c address 9
  Wire.onReceive(receiveEvent);
  Serial.begin(9600);
}

void loop() {
  if(newData) {           // is there new data?
    Serial.print("Received: ");
    Serial.println(int(dataReceive)); // convert to integer to print the number
    newData = false;      // reset flag
  }
}

void receiveEvent(int howMany) {
  if(howMany == 1) {      // extra check, to check if one byte is received
    dataReceive = Wire.read();
    newData = true;       // set flag, there is new data
  }
}

Here is my proposal to solve your issue:

Use the second Serial communication line of the master by connecting Rx and Tx Pins of Serial2 (this done only on master, practically a shortcut between Rx and Tx on Master)
Setup Serial2 if necessary: HardwareSerial Serial2(2); (that how it
is necessary/done for my M5Stack)
Define baud rate for Serial2: Serial2.begin(9600);
Start your Automation by Serial2.write("R\n"); at an appropriate place in your code
Change conditions of if(..) and while(..) in your master's code from Serial.available() to Serial2.available()
Change incomingByte = Serial.read(); to incomingByte =
Serial2.read();

With that solution you can still see your start signal printed out on your Serial monitor via the first Serial communication line. The communication to the slave is still working over IC2, Serial2 is only the proposal for the automation solution on master. Looks complicated, but this is how I understood the question, of course you also could directly use incomingByte="R\n"; to start your Automation and skip all that stuff with Serial2 :-)


text:
Will this buck converter power my arduino?
I'm thinking of using something like this: https://www.amazon.ca/Dolity-Converter-Isolated-Switching-Transformer/dp/B07CSZ1174?SubscriptionId=AKIAILSHYYTFIVPWUY6Q&tag=duc12-20&linkCode=xm2&camp=2025&creative=165953&creativeASIN=B07CSZ1174
or this: https://www.amazon.ca/Voltage-Regulator-Converter-Transformer-Protection/dp/B07LC1C4ZZ?SubscriptionId=AKIAILSHYYTFIVPWUY6Q&tag=duc12-20&linkCode=xm2&camp=2025&creative=165953&creativeASIN=B07LC1C4ZZ
to power my arduino.
The reason for this is I have a contained box with a few pieces of equipment (all on ac power) controlled by an Uno. There is a single AC power cord (North American) running from the box to power the whole unit. Obviously this just leaves the Uno.
Sure the standard 5V barrel adapter prongs could be shrink wrapped to the raw AC wires but that's not very clean. I was imagining a module like those converters that could be wired into the VIN pin and gnd after converting the AC input from the main power line going to the box.
The uno is powering an ethernet shield, 4 port relay, sht20 sensor, mh-z16 sensor, and 16x2 lcd display.
Thoughts? Honestly this isn't really my call. My boss doesn't want any plugs or standard outlets inside the box. It's like he only wants it to be formal circuit boards and soldering. No shrink wrap or electrical tape. Yes I realize standard adapters that plug into a wall are already at a price that won't be possible to beat.

I highly aggree with @Majenko. Any old USB phone charger would make a safer and also cheaper power source for your Arduino.

Sure the standard 5V barrel adapter prongs could be shrink wrapped to the raw AC wires but that's not very clean.

Also very deadly.  DO NOT DO THIS!!!!  The Arduino will explode (literally. I am NOT joking here!!!) and potentially electrocute you.

Those modules you show are not "buck" regulators. They are SMPS modules - an entirely different thing.
Yes, one of those would be suitable for powering an Arduino from a mains supply, but given your supposition above I rather suspect your skills and knowledge would make wiring it up a dangerous prospect.
Better would be to use a proper off-the-shelf power plug and have someone qualified install a suitable socket inside the enclosure.


text:
What am I missing? ST7735 TFT white screen
I followed this guy's guide with regards to wiring, etc., and all I seem to be getting is a white screen, as shown in these pictures. Is there an issue with the guy's guide, I'm missing or there is an issue with my wiring (pictures also included in above link) Any help would be appreciated.

the issue may well be that you haven't connected VCC and GND on the display to anything

The guide i was following suggested that "Connecting to VCC and ground like you’re accustomed to doing just won’t work here." ... that is not the case?

read comments in that guide

Oh look at that, "Thank you,
This worked for me only if I connected the VCC and Ground as well" and it indeed made it work. Sorry for the trouble.

TFT utterly temperamental anyway, i guess that's what you get for paying not much for it.


text:
Hold button / press button/ push button
I want to control a servo motor in a way that

if you push the button, you can control it by potentiometer a
if you push double time, you can control servo with infrared
if you hold button step motor start to to rotate from one position to another

I have a problem that when I press button it goes to an infinite loop and I can not stop it .
I try different button library but I still have a same problem.
Here is my code :
// includes the Servo library
#include <Servo.h>
#include <IRremote.h>
#include <OneButton.h>

int state = 0;
int RECV_PIN = 12;
const char type ='W';// W for white, B for black. Must keep single quotes like 'B' or 'W'
const boolean PCB = 0;// if receiver is PCB set to 1, if not set to 0. See video for details
boolean displayCode = true;// to display remote code. if not, set to false

const int SERVO_PIN = 8;  // analog pin used to connect the potentiometer
int angle =90;    // initial angle  for servo
int angleStep =10;
const int ANGLE_CENTRE =90;// the centre/reset angle of your servo
//**** Servo settings settings ends

// remote settings
const String RIGHT="CH+";// move servo to the right with this key on remote
const String LEFT ="CH-";// move servo to the left with this key on remote
const String CENTRE ="CH";// move servo to centre with this key on remote
// remote settings end

IRrecv irrecv(RECV_PIN);
// Defines Tirg and Echo pins of the Ultrasonic Sensor
const int trigPin = 10;
const int echoPin = 11;
const int potPin = 0;
const int pushButton = 8;
OneButton button(A1, true);
int value;

// Variables for the duration and the distance
long duration;
int distance_cm;
Servo myServo; // Creates a servo object for controlling the servo motor

// this is array holding codes for White Remote when used with non-PCB version of receiver
unsigned int whiteRemote[] ={
            0xFFA25D, // CH-
            0xFF629D,   // CH
            0xFFE21D,  // CH+

            0xFF22DD, // |<<
            0xFF02FD, // >>|
            0xFFC23D, // >||

            0xFFE01F, // -
            0xFFA857, // +
            0xFF906F, // EQ

            0xFF6897, // 0
            0xFF9867, // 100+
            0xFFB04F, // 200+

            0xFF30CF, // 1
            0xFF18E7, // 2
            0xFF7A85, // 3

            0xFF10EF, // 4
            0xFF38C7, // 5
            0xFF5AA5,  // 6

            0xFF42BD, // 7
            0xFF4AB5, // 8
            0xFF52AD  // 9
            };
// key lables of white remote
 String whiteRemoteKey[] ={
            "CH-",
            "CH",
            "CH+",

            "|<<",
            ">>|",
            ">||",

            "-",
            "+",
            "EQ",

            "0",
            "100+",
            "200+",

            "1",
            "2",
            "3",

            "4",
            "5",
            "6",

            "7",
            "8",
            "9"
            };

// this is array holding codes for Black Remote when used with non-PCB version of receiver
 unsigned int blackRemote[] ={
            0xFF629D, // ^
            0x38D3975C,   // <
            0x9334F738,  // OK
            0x320412D8, // >
            0xFFA857, // v

            0xFF6897, // 1
            0xFF9867, // 2
            0xF0C41643, // 3

            0xFF30CF, // 4
            0xFF18E7, // 5
            0xFF7A85,  // 6

            0xFF10EF, // 7
            0xFF38C7, // 8
            0xFF5AA5,  // 9

            0xFF42BD, // *
            0xFF4AB5, // 0
            0xFF52AD  // #
            };
// Black remote key names
 String blackRemoteKey[] ={
            "^",
            "<",
            "OK",
            ">",
            "v",

            "1",
            "2",
            "3",

            "4",
            "5",
            "6",

            "7",
            "8",
            "9",

            "*",
            "0",
            "#"
            };

decode_results results;

void setup() {
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an input
  Serial. begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  myServo.attach(SERVO_PIN); // Defines on which pin is the servo motor attached

  button.attachDoubleClick(doubleClick);            // link the function to be called on a doubleClick event.
  button.attachClick(singleClick);                  // link the function to be called on a singleClick event.
  button.attachLongPressStop(longClick);            // link the function to be called on a longpress event.

}
void loop() {
  button.tick();                                    // check the status of the button
  delay(10);                                        // a short wait between checking the button
}

// Function for calculating the distance measured by the Ultrasonic sensor
int calculateDistance(){
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HiGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH); // Reads the echoPin, returns the sound wave travel time in microseconds
  //Comment by me!
  //distance= duration*0.034/2;
  //
  distance_cm = (duration/2) / 29.1;
  return distance_cm;
}
void doubleClick() {                                // what happens when button is double-clicked
  while(1) {
    if (irrecv.decode(&results)) {
      if(displayCode)Serial.println(results.value, HEX);
      validateCode(results.value);// used the "robojaxValidateCode" bellow
      irrecv.resume(); // Receive the next value
    }
    delay(50);// 50 melisecond delay
    break;
  }
}

void singleClick(){                                 // what happens when the button is clicked
  while(1) {
    value = analogRead(potPin);
    value = map(value, 0, 1023, 15, 165);
    myServo.write(value);
    delay(30);
    distance_cm = calculateDistance();

    Serial.print(value); // Sends the current degree into the Serial Port
    Serial.print(","); // Sends addition character right next to the previous value needed later in the Processing iDE for indexing
    Serial.print(distance_cm); // Sends the distance value into the Serial Port
    Serial.print("."); // Sends addition character right next to the previous value needed later in the Processing iDE for indexin
  }
}

void longClick(){                                   // what happens when buton is long-pressed
  for(int i=15;i<=165;i++){
    myServo.write(i);
    delay(30);
    distance_cm = calculateDistance();// Calls a function for calculating the distance measured by the Ultrasonic sensor for each degree

    Serial.print(i); // Sends the current degree into the Serial Port
    Serial.print(","); // Sends addition character right next to the previous value needed later in the Processing iDE for indexing
    Serial.print(distance_cm); // Sends the distance value into the Serial Port
    Serial.print("."); // Sends addition character right next to the previous value needed later in the Processing iDE for indexin
  }
  // Repeats the previous lines from 165 to 15 degrees
  for(int i=165;i>15;i--){
    myServo.write(i);
    delay(30);
    distance_cm = calculateDistance();

    Serial.print(i);
    Serial.print(",");
    Serial.print(distance_cm);
    Serial.print(".");
  }
}
/*
 * function: validateCode
 * validates the remote code and prints correct key name
 * cd is code poassed from the loop
 * Written by A. S. for Robojax
 */
void validateCode(int cd)
{

  // Robojax IR Remote decoder
  int found=0;

 if(type =='W' && !PCB)
 {
    // Robojax IR White Remote decoder
    // if tyepe is set to 'W' (white remote) and PCB=0 then check Black remote code
      for(int i=0; i< sizeof(whiteRemote)/sizeof(int); i++)
      {
        if(whiteRemote[i] ==cd)
        {

          Serial.print("Key pressed:");
          Serial.println(whiteRemoteKey[i]);
          servoAction(whiteRemoteKey[i]);// take action
          found=1;
        }// if matched
      }// for
 }else{

      // if tyepe is set to 'B' (black remote) and PCB =0 then check Black remote code
       for(int i=0; i< sizeof(blackRemote)/sizeof(int); i++)
      {
        // Robojax IR black Remote decoder
        if(blackRemote[i] ==cd)
        {

          Serial.print("Key pressed:");
          Serial.println(blackRemoteKey[i]);
          servoAction(blackRemoteKey[i]);// take action

          found=1;
        }// if matched
      }// for
 }// else
  if(!found){
    if(cd !=0xFFFFFFFF)
      {
    Serial.println("Key unkown");
      }
  }// found
}// validateCode end

/*
 *
 * servoAction()
 * receives string "value" as input and based on the settings,
 * sends translates it to servo value and controls servo
 * either
 * rotates servo to right
 * rotates servo to left
 * moves the servo to middle
 *
 */
void servoAction(String value){
  // Servo button demo with IR remote by Robojax.com
  while(value == RIGHT){

    if (angle > 0 && angle <= 180) {
      angle = angle - angleStep;
       if(angle < 0){
        angle = 0;
       }else{
      myServo.write(angle); // move the servo to desired angle
      Serial.print("Moved to: ");
      Serial.print(angle);   // print the angle
      Serial.println(" degree");
       }
    }// if
    value =".";
    delay(100);
  }// while for RIGHT
  while(value == LEFT){

    // Servo button demo with IR remote by Robojax.com
    if (angle >= 0 && angle <= 180) {
      angle = angle + angleStep;
      if(angle >180){
        angle =180;
       }else{
      myServo.write(angle); // move the servo to desired angle
      Serial.print("Moved to: ");
      Serial.print(angle);   // print the angle
      Serial.println(" degree");
       }
    }
    value =".";
    delay(100);
  }// while for LEFT

  if(value == CENTRE)
  {
    angle = ANGLE_CENTRE;
    myServo.write(angle); // move the servo to centre at 90 degree angle
  }
    // Robojax IR Servo control
}//relayAction end

sorry about my English.
I hope someone help me.

You have infinite loops in the click event call functions, after a button event you never return to the main loop.
Use the event functions just to set a status variable then, in the main loop use switch case case to select the code used by the servo control like this:
 ....
 unsigned int status = 0;
 ....
 void doubleClick(){
    status = 0;
 }
 void singleClick(){
    status = 1;
 }
 void longClick(){
    status = 2;
 }
 void setup() {
 ....
 }
 void loop {
   button.tick();                                    // check the status of the button
   //delay(10); // this is not needed.
   switch (status){
     case 0:{
       //action for double click
     }
     case 1:{
       //action for single click
     }
     case 2:{
       //action for long click
     }
 }

Inside each case insert the corresponding code code you have in the while(1) loops of the button event functions.
Another option is to insert inside the forever loops a return when the button is pressed like this:
if (button pressed)  return;

Please use Enum instead of "magic number"

Thanks for your answer.But I need that action happen infinitely until the status of the button change from for example single push to double push .when I use if statement It does not work properly.

@AmirHosseinJobeiri The while(1) loop is replaced by the main loop so it is happening forever until you press the button and change the status variable. Or just use return on button pressed inside while(1) loop but it is quite difficult to extend your code further.


text:
Cascaded Control loop Arduino
I am trying to implement cascaded control system, with velocity inner loop and position outer loop.
Separately and without cascaded control, I have implemented position control and velocity control easily, thanks to the "pid library."
I have no idea how to convert position output from position pid to reference velocity.
Any help would be appreciated, since I am blank on this topic.
Thanks and best regards

This is not an Arduino specific topic, but here is just a pragmatic answer:
Use the output of the PID controller directly as your reference velocity, subtract your actual velocity and use it as input for the PID velocity. Units do not care in this case.
You have to make sure that the paramters of your PID position are well adjusted, this will set the problem with the units.
Here is an example to understand (only P gain considered):
If you want to drive from A to B with your car and the distance from A to B is 10 km, then your desired position is 10km and i would choose to drive about 100km/h. So in this example you start with a control deviation of 10km - 0km = 10km. If you choose a P gain of 10 the output of the PID will be 100, which is an ideal refernce Velocity, if velocity is given in km/h.
But if you are measuring your distance not in km but in m, the control deviation will be (10.000m - 0m = 10.000m), with a P gain of 10 you will end up with a refernce velocity of 100.000km/h, which is not an appropriate reference velocity in this case.
Now someone may object that in my example if you want do drive from A to C and C is 1.000km away, you will end up with an reference velocity of 10.000km/h, which is also not appropriate, but that is where the limitations in a PID controller are usefull, just set them for this example to 130km/h and you will end up stil with an appropriate reference velocity, and also your integrator part will not wind up endlessly.
You can look at I and D gain in a similar manner.

Yeah I got it thanks

@SyedTirmizi you are welcome, I hope your system works. :-)


text:
What do the numbers behind lcd (0x27) mean?
I can't seem to figure out what the numbers after 0x27 mean. I understand that 0x27 stands for the I2C address and POSITIVE stands for the backlight, but what do the other number mean?

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE)

Which LiquidCrystal_I2C library are you using? Usually you would call the constructor like this: LiquidCrystal_I2C lcd(0x27, LCD columns, LCD rows);.

My guess is they refer to the pins on the IO expander to use for the different pin functions. Without knowing what library you are using, or what LCD display and interface board you have, it's impossible to say.

A “4x20” LCD is one with 4 rows and 20 columns. You can guess a “0x27” has 0 rows and 27 columns. ;-)

It's a bit late, but I'm using Newliquidcrystal_1.3.5. I don't think it stands for columns x rows. I tried 16, 2 and the LCD didn't work.

Assuming You're using the same LCD library I'm using, there is a longer form of the constructor that takes pin assignments for the different pins on the I2C module, as Majenko says.
I'm at work, so I don't have access to my code, but your constructor looks a whole lot like the one I use for my module, which has non-standard pin assignment. (I got my LCD modules from oddWires, and they came without documentation. I had to do quite a bit of detective work to figure out how to make them work.)
EDIT
I use the Newliquidcrystal_1.3.5 library in my project, to interface the above-mentioned oddWires I2C LCD display. That library has various constructors, one of which takes all the parameters you list. Those extra numbers indicate the pins that connect to the I2C module.
My oddWires LCDs need exactly the settings you list in the constructor. Your milage may vary.
The long form is defined in the library header with
LiquidCrystal_I2C(
    uint8_t lcd_Addr,
    uint8_t En,
    uint8_t Rw,
    uint8_t Rs,

    uint8_t d4,
    uint8_t d5,
    uint8_t d6,
    uint8_t d7,
    uint8_t backlighPin,
    t_backlighPol pol
);

From the naming of the parameters you can deduce most of them:

En is an enable line
Rw is a read/write line?
Rs is ?
d4-47 are the data pins
backlightPin is the pin that turns backlight on and off
pol indicates the backlight polarity (POSITIVE probably means pull the line high to enable the backlight.


text:
Arduino + USB Host Shield + ESP8266
I am using an Arduino Uno and a USB Host shield for Barcode Scanner. The whole scenario is that when I scan the barcode through USB Barcode Scanner, it scans and gives a code. Now the question is how to connect the ESP8266 with the USB Host Shield to transfer data to the web server. I have set the pins to 2, 3 for receiving data from server. Send Data and Receive data with ESP8266.
The Arduino Code:
#include <SoftwareSerial.h>
#include <hid.h>
#include <hiduniversal.h>
#include <LiquidCrystal.h>
#include <avr/pgmspace.h>
#include <Usb.h>
#include <usbhub.h>
#include <avr/pgmspace.h>
#include <hidboot.h>
String result = "";
#define DISPLAY_WIDTH 16

// initialize the LCD library with the numbers of the interface pins
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
SoftwareSerial esp(3, 2);

USB     Usb;
USBHub     Hub(&Usb);
HIDUniversal Hid(&Usb);
HIDBoot<HID_PROTOCOL_KEYBOARD>    Keyboard(&Usb);

class KbdRptParser : public KeyboardReportParser
{
 void PrintKey(uint8_t mod, uint8_t key);
protected:
  virtual void OnKeyDown  (uint8_t mod, uint8_t key);
  virtual void OnKeyPressed(uint8_t key);
};

void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)
{

    uint8_t c = OemToAscii(mod, key);

    if (c)
        delay(100);
       OnKeyPressed(c);

}

/* what to do when symbol arrives */
void KbdRptParser::OnKeyPressed(uint8_t key)
{
static uint32_t next_time = 0;      //watchdog
static uint8_t current_cursor = 0;  //tracks current cursor position

    if( millis() > next_time ) {
      lcd.clear();
      result = "";
      current_cursor = 0;
      delay( 5 );  //LCD-specific
      lcd.setCursor( 0,0 );
    }//if( millis() > next_time ...

    next_time = millis() + 200;  //reset watchdog

    if( current_cursor++ == ( DISPLAY_WIDTH + 1 )) {  //switch to second line if cursor outside the screen
      lcd.setCursor( 0,1 );
    }

 result += (char)key;//Serial.print("Result "+result+"\n");
 delay( 50 );
    //Serial.print((char)key );
    //lcd.print((char)key );
};

KbdRptParser Prs;

void setup()
{
    Serial.begin(9600);
    Serial.println("Start");
    esp.begin(115200);
    if (Usb.Init() == -1) {
        Serial.println("OSC did not start.");
    }

    delay( 200 );

    Hid.SetReportParser(0, (HIDReportParser*)&Prs);
    // set up the LCD's number of columns and rows:
    lcd.begin(DISPLAY_WIDTH, 2);
    lcd.clear();
    lcd.noAutoscroll();
    lcd.print("Ready");
    delay( 200 );

}

void loop()
{
  String content = "";
  char character;
  Usb.Task();
  if(result != ""){
    delay(10);
    Serial.println(result);
    }
   /*while(Serial.available()){
    character = Serial.read();
    content.concat(character);
    Serial.print("Serial Result : "+content);

    }*/
    if (esp.available())
   {

    char c = esp.read();
    if(isDigit(c)){
      lcd.clear();
      lcd.print(c);
        Serial.print(c);

       }
    }

}

The ESP8266 Code is:
#include <ESP8266WiFi.h>

const char* ssid     = "stormfiber"; //Wi-Fi SSID
const char* password = "11223344"; //Wi-Fi Password

//Server IP or domain name
const char* host = "192.168.100.228";
void setup()
{
  Serial.begin(115200);
  Serial1.begin(9600);
  WiFi.begin(ssid, password);
  Serial.println(ssid);
  while (WiFi.status() != WL_CONNECTED) { //Wait till connects
    delay(500);
    Serial.print(".");
  }

}

void loop()
{
  char character;
  String content = "";
  delay(5000);

  //Serial.print("connecting to ");
  //Serial.println(host);
  while(Serial1.available()){
    character = Serial1.read();
    content.concat(character);
    }
    if(content == ""){
      content = "123";
     }
  WiFiClient client; //Client to handle TCP Connection
  const int httpPort = 2124;
  if (!client.connect(host, httpPort)) { //Connect to server using port httpPort
    Serial.println("connection failed");
    return;
  }

  // We now create a URI for the request
  String url = "/test/index.php?code="+content; //File or Server page you want to communicate with. along with data

  // This will send the request to the server
  client.print(String("GET ") + url + "\r\n");

  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 25000) { //Try to fetch response for 25 seconds
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }

  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  Serial.println();
  //Serial.println("closing connection");
  client.stop(); //Close Connection
  /*static unsigned long timer = 0;
  unsigned long interval = 5000;
  static unsigned int index = 0;
  if (millis() - timer >= interval)
  {
    timer = millis();
    Serial.print("The index ");
    Serial.println(index);
    index++;
  }*/
}

Please help how to connect the ESP8266 with the host shield. Although it works fine with Arduino only.
Any help regarding this will be appreciated.
Thanks

the USB host shield doesn't use pins 2 and 3 but your LCD setup does

Thanks for the answer but how we can connect esp8266 communicating with USB Host Shield. Is there any possibility?

Can we read data from 2,3 pin by esp8266?

what problem do you have with the USB shield? it changes nothing for the SoftwareSerial on pins 2 an 3

yes it shows nothing

you write that it works without the shield. so what are you asking? it should work the same way with the shield. but you use pins 2 and 3 for LCD too. how?

The USB shield has no relevance to anything here. It is "the other sided" of the Arduino. USB <=> Arduino <=> ESP8266. Ignore the USB shield. Remove it from your perception completely.

Bro I have just removed the USB Host shield over Arduino and place ESP8266 directly to arduino. Now it shows the data that comes from ESP8266 , When i place again USB Host shield and ESP over Host shield it again shows nothing on 2,3.

Does disconnecting the USB host shield also disconnect the LCD that is conflicting with the serial connection?

i did not connect LCD yet. just writing a code for that. Sorry for the inconvenience

please ignore the LCD here just i am focusing on ESP8266

Remove all the code for the LCD then. It's confusing matters.


text:
Cannot read modbus data repetitively
I try to communicate with 2 RS485 sensors (pH and EC), but I have some troubles with my code. First, I tried to get data from just one:
The function in charge of request sending:
String GET_probe(String probe){

if(probe == "pH"){
Serial.println("Sending request pH...");
digitalWrite(modbusModuleRE, RS485Transmit);  // Init Transceiver
digitalWrite(modbusModuleDE, RS485Transmit);  // Init Transceiver
byte  RTUrequest[] = {0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x85, 0xDB};
RS485Serial.write(RTUrequest, sizeof(RTUrequest));
}

if(probe == "EC"){
Serial.println("Sending request EC...");

digitalWrite(modbusModuleRE, RS485Transmit);  // Init Transceiver
digitalWrite(modbusModuleDE, RS485Transmit);  // Init Transceiver
byte  RTUrequest[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B};
RS485Serial.write(RTUrequest, sizeof(RTUrequest));
}

RS485Serial.flush();
RS485Serial.listen();
}

The function in charge of reading sensor's answer:
void ReadRx() {
     digitalWrite(modbusModuleRE, RS485Receive);
     digitalWrite(modbusModuleDE, RS485Receive);
     if(RS485Serial.available()) {
     Serial.print("Answer: ");
      for(int i=0; i<7; i++){
          String myByte = String(RS485Serial.read(), HEX);// Read the byte

          if (myByte.length() == 1)
          {
            myByte = "0"+myByte;
          }
          modbusHexBuffer[i] = myByte;

          Serial.print(myByte);
          Serial.print(" ");
      }
      Serial.println();
    }
   }

And the loop, sending the request each 5s:
void loop(){

  static uint32_t ts = millis();

  if (millis() - ts >= 5000) {
      ts = millis();
      GET_probe("pH");
  }

ReadRx();
}

The loop runs fine once and fails the second time, as shown in terminal. Can you tell me why and help me to fix it?
Sending request pH...
Answer: 00 03 02 05 78 86 f6
Sending request pH...

comments: wire DE and RE to one pin; you don't need to call listen if you have only one SoftwareSerial instance; don't use String; if  at least 1 byte is available you read 7

Are you talking about this line?:
String myByte = String(RS485Serial.read(), HEX);

regarding String and reading blindly, yes. use RS485Serial.readBytes(RTUresponse, 7);. readBytes will wait for the next byte

I have found why !!!
1st: buf[8] instead buf[7] in declaration
2nd: reinit byte buf[8] before EC request part.
So the code who works fine is:
byte buf[8];
void loop(){

      Serial.print("pH: ");
      digitalWrite(modbusModuleRE, RS485Transmit);  // Init Transceiver
      digitalWrite(modbusModuleDE, RS485Transmit);  // Init Transceiver
      byte  pHrequest[] = {0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x85, 0xDB};
      RS485Serial.write(pHrequest, sizeof(pHrequest));
      RS485Serial.flush();
      digitalWrite(modbusModuleRE, RS485Receive);
      digitalWrite(modbusModuleDE, RS485Receive);
      RS485Serial.readBytes(buf, 8);
     Serial.print(buf[3], HEX);Serial.println(buf[4], HEX);

byte buf[8];

      Serial.print("EC: ");
      digitalWrite(modbusModuleRE, RS485Transmit);  // Init Transceiver
      digitalWrite(modbusModuleDE, RS485Transmit);  // Init Transceiver
      byte  ECrequest[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B};
      RS485Serial.write(ECrequest, sizeof(ECrequest));
      RS485Serial.flush();
      digitalWrite(modbusModuleRE, RS485Receive);
      digitalWrite(modbusModuleDE, RS485Receive);
      RS485Serial.readBytes(buf, 8);
      Serial.print(buf[3], HEX);Serial.print(buf[4], HEX);Serial.print(buf[5], HEX);Serial.println(buf[6], HEX);

Serial.println();

}

rewrite it please as standalone answer


text:
How should I combine the codes for two sensors in 1 Arduino sketch?
Name of study: AUTOMATIC ELECTRIC FAN
We used an ultrasonic sensor for the switching on/off of our Fan and an LM35 SENSOR to control the speed regulation.
During our experiment, we use a LED instead of a Fan before we proceed to fan. Here is our code:
Description: Codes for LM35 Sensor using LED and Arduino Uno as Microcontroller)
#define led 9
float temp;

void setup ()
{
   pinMode(led, OUTPUT);
   Serial.begin(9600);
}

 void loop ()
{
    temp = analogRead (A0);
    temp = temp*0.48828125;
     if (temp < 31 )
  {
    digitalWrite(led, HIGH);
  }
  else {

    digitalWrite(led, LOW);
  }
    Serial.print("TEMPERATURE: ");
    Serial.print(temp);
    Serial.print("*C");
     Serial.println();
     delay(1000);
 }

Description: Code for ULTRASONIC SENSOR using two LED’s AND Arduinbo Uno as Microcontroller
#define trigPin 13
#define echoPin 12
#define led 6
#define led 5
{
  digitalWrite(trigPin, LOW);
  delayMicroseconds (2);

  digitalWrite(trigPin, HIGH);
  delayMicroseconds (10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  distance = duration*0.034/2;
  if (distance < 100 )
  {
    digitalWrite(led, HIGH);
  }
  else {

    digitalWrite(led, LOW);
  }
  Serial.print("Distance:");
  Serial.println(distance);
  Serial.print("cm");
  delay(1000);
}

You need to edit your question, select the code, and tap the code format button. (It looks like open and close braces: {}. That will format the code so that it's readable. Right now it is decidedly not readable.

Thank You. You know how to combined the codes for the two sensors?

As I always say: Step 1: understand your existing code and how it works. Step 2: write a new program which incorporates what you learned in step 1.

@MichelKeijzers, I resisted the urge to edit the OPs code. I was trying to use their first post as a "teaching moment" for how questions should be formatted.

@DuncanC Sorry, I justed improved the layout without reading all comments.

You don't have two codes; the 2nd section has no setup() or loop().
If it did, then you could do this:

The stuff before setup() gets put together.
The stuff in setup() from one gets moved into the other. The empty setup() gets deleted.
The stuff in loop() from one gets moved into the other. The empty loop() gets deleted.

Take care of any duplicate names, pin assignments, etc.
Review the combined loop() code and adjust as needed to do what you want.

Thanks for the cleanup Michel, easier to read now.

You're welcome!


text:
ESP8266 won't receive messages after a while
There are 5 ESP8266s being used. Three act as a middleman (in AP_STA mode), one sends the message, and the last one receives the message after being passed over the middlemans (imagine it as a line, starting with nr. 1 in STA mode, sending the date to middleman 1. M1 sends it to M2, M2 sends it to M3, M3 sends it to the receiver, set in AP mode).
After like 10 min. of sending a message, one chip always stops. Stops as in, not receiving or sending the message. Every time a message is send, I use the command Client21.flush() (Client21 is just a name).
My idea is that I have to somehow also flush() after recieving a message, not just after sending one. Is there like a "receive buffer" that I can flush(), and how is it possible?
(no code provided)
Update 1: This is what the first middleman (chip no.3) printed in serial monitor when he "crashed":
Exception (29):
epc1=0x4000e1c3 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000018 depc=0x00000000

ctx: sys
sp: 3fffebc0 end: 3fffffb0 offset: 01a0

stack
3fffed60:  3fffc278 40101fe8 3fffc200 00000000
3fffed70:  3ffed93c 3fffb374 000000c0 401004e4
3fffed80:  40000f83 3fffb374 402384b0 401068b0
3fffed90:  402268ac 00000023 00000000 402268d1
3fffeda0:  000000c0 4021403b 00000018 3ffed6cc
3fffedb0:  00000000 00000000 00000020 40100f22
3fffedc0:  4021881e 4021873c 3ffef80c 40100f22
3fffedd0:  01004e43 4010000d 3ffee034 4021cb7d
3fffede0:  00000018 3ffed750 3ffed6cc 00000000
3fffedf0:  402188df 3ff20a00 3ffef80c 3ffe9be6
3fffee00:  3ffe9bcc 3fffee90 3fffee90 00000000
3fffee10:  4c4c4148 3331324f 40102200 3ffe9bcc
3fffee20:  3ffe9be6 0000002c 00000004 40100518
3fffee30:  3ffe9bd6 3ffefc74 402154a0 3ff20a00
3fffee40:  3ffef80c 3fffbfcc 00000015 40215373
3fffee50:  4000050c 3ffef45c 00000000 4021b377
3fffee60:  40106afd 00000030 00000011 ffffffff
3fffee70:  00000000 4bc6a7f0 7645a1ca 00000000
3fffee80:  00000000 00000000 4bc6a7f0 00000000
3fffee90:  4020cb8c 3ffe8f84 40106520 00190810
3fffeea0:  00000000 4bc6a7f0 3ffe8f84 40212cbc
3fffeeb0:  1cf15308 00000000 00000002 4020bad8
3fffeec0:  4021d149 ffffffa2 00000000 000001f4
3fffeed0:  40214baf 3ffe9bcc 3ffecd80 3ffef80c
3fffeee0:  00000000 3ffe9bd6 3ffe9bf0 3ffeeec4
3fffeef0:  4020cb8c 00000000 00000000 3ffe9bd6
3fffef00:  61c78017 000000c3 00000000 3ffefc74
3fffef10:  3ffe9bc0 00000000 00000002 4022463a
3fffef20:  3ffecd80 3ffe9bc0 3fffdcc0 3ffe9370
3fffef30:  3ffe9bdc 3ffefab4 00000040 3ffe9370
3fffef40:  00000040 3ffecd80 00000000 3ffe85e0
3fffef50:  40223f17 3fffdab0 00000000 40204ac7
3fffef60:  3ffe9370 40000f49 3fffdab0 40000f49
3fffef70:  40000e19 40001878 00000002 00000000
3fffef80:  3fffff10 aa55aa55 0000008f 40104424
3fffef90:  4010442a 00000002 00000000 056f21c7
3fffefa0:  4010000d 31c0f00e 8b4afbe9 f30f0180
3fffefb0:  00000000 3fffef4c 00000000 3fffff28
3fffefc0:  3fffffd0 00000000 00000000 feefeffe
3fffefd0:  feefeffe feefeffe feefeffe feefeffe
3fffefe0:  feefeffe feefeffe feefeffe feefeffe
3fffeff0:  feefeffe feefeffe feefeffe feefeffe
3ffff000:  feefeffe feefeffe feefeffe feefeffe
3ffff010:  feefeffe feefeffe feefeffe feefeffe
3ffff020:  feefeffe feefeffe feefeffe feefeffe
3ffff030:  feefeffe feefeffe feefeffe feefeffe
3ffff040:  feefeffe feefeffe feefeffe feefeffe
3ffff050:  feefeffe feefeffe feefeffe feefeffe
3ffff060:  feefeffe feefeffe feefeffe feefeffe
3ffff070:  feefeffe feefeffe feefeffe feefeffe
3ffff080:  feefeffe feefeffe feefeffe feefeffe
3ffff090:  feefeffe feefeffe feefeffe feefeffe
3ffff0a0:  feefeffe feefeffe feefeffe feefeffe
3ffff0b0:  feefeffe feefeffe feefeffe feefeffe
3ffff0c0:  feefeffe feefeffe feefeffe feefeffe
3ffff0d0:  feefeffe feefeffe feefeffe feefeffe
3ffff0e0:  feefeffe feefeffe feefeffe feefeffe
3ffff0f0:  feefeffe feefeffe feefeffe feefeffe
3ffff100:  feefeffe feefeffe feefeffe feefeffe
3ffff110:  feefeffe feefeffe feefeffe feefeffe
3ffff120:  feefeffe feefeffe feefeffe feefeffe
3ffff130:  feefeffe feefeffe feefeffe feefeffe
3ffff140:  feefeffe feefeffe feefeffe feefeffe
3ffff150:  feefeffe feefeffe feefeffe feefeffe
3ffff160:  feefeffe feefeffe feefeffe feefeffe
3ffff170:  feefeffe feefeffe feefeffe feefeffe
3ffff180:  feefeffe feefeffe feefeffe feefeffe
3ffff190:  feefeffe feefeffe feefeffe feefeffe
3ffff1a0:  feefeffe feefeffe feefeffe feefeffe
3ffff1b0:  feefeffe feefeffe feefeffe feefeffe
3ffff1c0:  feefeffe feefeffe feefeffe feefeffe
3ffff1d0:  feefeffe feefeffe feefeffe feefeffe
3ffff1e0:  feefeffe feefeffe feefeffe feefeffe
3ffff1f0:  feefeffe feefeffe feefeffe feefeffe
3ffff200:  feefeffe feefeffe feefeffe feefeffe
3ffff210:  feefeffe feefeffe feefeffe feefeffe
3ffff220:  feefeffe feefeffe feefeffe feefeffe
3ffff230:  feefeffe feefeffe feefeffe feefeffe
3ffff240:  feefeffe feefeffe feefeffe feefeffe
3ffff250:  feefeffe feefeffe feefeffe feefeffe
3ffff260:  feefeffe feefeffe feefeffe feefeffe
3ffff270:  feefeffe feefeffe feefeffe feefeffe
3ffff280:  feefeffe feefeffe feefeffe feefeffe
3ffff290:  feefeffe feefeffe feefeffe feefeffe
3ffff2a0:  feefeffe feefeffe feefeffe feefeffe
3ffff2b0:  feefeffe feefeffe feefeffe feefeffe
3ffff2c0:  feefeffe feefeffe feefeffe feefeffe
3ffff2d0:  feefeffe feefeffe feefeffe feefeffe
3ffff2e0:  feefeffe feefeffe feefeffe feefeffe
3ffff2f0:  feefeffe feefeffe feefeffe feefeffe
3ffff300:  feefeffe feefeffe feefeffe feefeffe
3ffff310:  feefeffe feefeffe feefeffe feefeffe
3ffff320:  feefeffe feefeffe feefeffe feefeffe
3ffff330:  feefeffe feefeffe feefeffe feefeffe
3ffff340:  feefeffe feefeffe feefeffe feefeffe
3ffff350:  feefeffe feefeffe feefeffe feefeffe
3ffff360:  feefeffe feefeffe feefeffe feefeffe
3ffff370:  feefeffe feefeffe feefeffe feefeffe
3ffff380:  feefeffe feefeffe feefeffe feefeffe
3ffff390:  feefeffe feefeffe feefeffe feefeffe
3ffff3a0:  feefeffe feefeffe feefeffe feefeffe
3ffff3b0:  feefeffe feefeffe feefeffe feefeffe
3ffff3c0:  feefeffe feefeffe feefeffe feefeffe
3ffff3d0:  feefeffe feefeffe feefeffe feefeffe
3ffff3e0:  feefeffe feefeffe feefeffe feefeffe
3ffff3f0:  feefeffe feefeffe feefeffe feefeffe
3ffff400:  feefeffe feefeffe feefeffe feefeffe
3ffff410:  feefeffe feefeffe feefeffe feefeffe
3ffff420:  feefeffe feefeffe feefeffe feefeffe
3ffff430:  feefeffe feefeffe feefeffe feefeffe
3ffff440:  feefeffe feefeffe feefeffe feefeffe
3ffff450:  feefeffe feefeffe feefeffe feefeffe
3ffff460:  feefeffe feefeffe feefeffe feefeffe
3ffff470:  feefeffe feefeffe feefeffe feefeffe
3ffff480:  feefeffe feefeffe feefeffe feefeffe
3ffff490:  feefeffe feefeffe feefeffe feefeffe
3ffff4a0:  feefeffe feefeffe feefeffe feefeffe
3ffff4b0:  feefeffe feefeffe feefeffe feefeffe
3ffff4c0:  feefeffe feefeffe feefeffe feefeffe
3ffff4d0:  feefeffe feefeffe feefeffe feefeffe
3ffff4e0:  feefeffe feefeffe feefeffe feefeffe
3ffff4f0:  feefeffe feefeffe feefeffe feefeffe
3ffff500:  feefeffe feefeffe feefeffe feefeffe
3ffff510:  feefeffe feefeffe feefeffe feefeffe
3ffff520:  feefeffe feefeffe feefeffe feefeffe
3ffff530:  feefeffe feefeffe feefeffe feefeffe
3ffff540:  feefeffe feefeffe feefeffe feefeffe
3ffff550:  feefeffe feefeffe feefeffe feefeffe
3ffff560:  feefeffe feefeffe feefeffe feefeffe
3ffff570:  feefeffe feefeffe feefeffe feefeffe
3ffff580:  feefeffe feefeffe feefeffe feefeffe
3ffff590:  feefeffe feefeffe feefeffe feefeffe
3ffff5a0:  feefeffe feefeffe feefeffe feefeffe
3ffff5b0:  feefeffe feefeffe feefeffe feefeffe
3ffff5c0:  feefeffe feefeffe feefeffe feefeffe
3ffff5d0:  feefeffe feefeffe feefeffe feefeffe
3ffff5e0:  feefeffe feefeffe feefeffe feefeffe
3ffff5f0:  feefeffe feefeffe feefeffe feefeffe
3ffff600:  feefeffe feefeffe feefeffe feefeffe
3ffff610:  feefeffe feefeffe feefeffe feefeffe
3ffff620:  feefeffe feefeffe feefeffe feefeffe
3ffff630:  feefeffe feefeffe feefeffe feefeffe
3ffff640:  feefeffe feefeffe feefeffe feefeffe
3ffff650:  feefeffe feefeffe feefeffe feefeffe
3ffff660:  feefeffe feefeffe feefeffe feefeffe
3ffff670:  feefeffe feefeffe feefeffe feefeffe
3ffff680:  feefeffe feefeffe feefeffe feefeffe
3ffff690:  feefeffe feefeffe feefeffe feefeffe
3ffff6a0:  feefeffe feefeffe feefeffe feefeffe
3ffff6b0:  feefeffe feefeffe feefeffe feefeffe
3ffff6c0:  feefeffe feefeffe feefeffe feefeffe
3ffff6d0:  feefeffe feefeffe feefeffe feefeffe
3ffff6e0:  feefeffe feefeffe feefeffe feefeffe
3ffff6f0:  feefeffe feefeffe feefeffe feefeffe
3ffff700:  feefeffe feefeffe feefeffe feefeffe
3ffff710:  feefeffe feefeffe feefeffe feefeffe
3ffff720:  feefeffe feefeffe feefeffe feefeffe
3ffff730:  feefeffe feefeffe feefeffe feefeffe
3ffff740:  feefeffe feefeffe feefeffe feefeffe
3ffff750:  feefeffe feefeffe feefeffe feefeffe
3ffff760:  feefeffe feefeffe feefeffe feefeffe
3ffff770:  feefeffe feefeffe feefeffe feefeffe
3ffff780:  feefeffe feefeffe feefeffe feefeffe
3ffff790:  feefeffe feefeffe feefeffe feefeffe
3ffff7a0:  feefeffe feefeffe feefeffe feefeffe
3ffff7b0:  feefeffe feefeffe feefeffe feefeffe
3ffff7c0:  feefeffe feefeffe feefeffe feefeffe
3ffff7d0:  feefeffe feefeffe feefeffe feefeffe
3ffff7e0:  feefeffe feefeffe feefeffe feefeffe
3ffff7f0:  feefeffe feefeffe feefeffe feefeffe
3ffff800:  feefeffe feefeffe feefeffe feefeffe
3ffff810:  feefeffe feefeffe feefeffe feefeffe
3ffff820:  feefeffe feefeffe feefeffe feefeffe
3ffff830:  feefeffe feefeffe feefeffe feefeffe
3ffff840:  feefeffe feefeffe feefeffe feefeffe
3ffff850:  feefeffe feefeffe feefeffe feefeffe
3ffff860:  feefeffe feefeffe feefeffe feefeffe
3ffff870:  feefeffe feefeffe feefeffe feefeffe
3ffff880:  feefeffe feefeffe feefeffe feefeffe
3ffff890:  feefeffe feefeffe feefeffe feefeffe
3ffff8a0:  feefeffe feefeffe feefeffe feefeffe
3ffff8b0:  feefeffe feefeffe feefeffe feefeffe
3ffff8c0:  feefeffe feefeffe feefeffe feefeffe
3ffff8d0:  feefeffe feefeffe feefeffe feefeffe
3ffff8e0:  feefeffe feefeffe feefeffe feefeffe
3ffff8f0:  feefeffe feefeffe feefeffe feefeffe
3ffff900:  feefeffe feefeffe feefeffe feefeffe
3ffff910:  feefeffe feefeffe feefeffe feefeffe
3ffff920:  feefeffe feefeffe feefeffe feefeffe
3ffff930:  feefeffe feefeffe feefeffe feefeffe
3ffff940:  feefeffe feefeffe feefeffe feefeffe
3ffff950:  feefeffe feefeffe feefeffe feefeffe
3ffff960:  feefeffe feefeffe feefeffe feefeffe
3ffff970:  feefeffe feefeffe feefeffe feefeffe
3ffff980:  feefeffe feefeffe feefeffe feefeffe
3ffff990:  feefeffe feefeffe feefeffe feefeffe
3ffff9a0:  feefeffe feefeffe feefeffe feefeffe
3ffff9b0:  feefeffe feefeffe feefeffe feefeffe
3ffff9c0:  feefeffe feefeffe feefeffe feefeffe
3ffff9d0:  feefeffe feefeffe feefeffe feefeffe
3ffff9e0:  feefeffe feefeffe feefeffe feefeffe
3ffff9f0:  feefeffe feefeffe feefeffe feefeffe
3ffffa00:  feefeffe feefeffe feefeffe feefeffe
3ffffa10:  feefeffe feefeffe feefeffe feefeffe
3ffffa20:  feefeffe feefeffe feefeffe feefeffe
3ffffa30:  feefeffe feefeffe feefeffe feefeffe
3ffffa40:  feefeffe feefeffe feefeffe feefeffe
3ffffa50:  feefeffe feefeffe feefeffe feefeffe
3ffffa60:  feefeffe feefeffe feefeffe feefeffe
3ffffa70:  feefeffe feefeffe feefeffe feefeffe
3ffffa80:  feefeffe feefeffe feefeffe feefeffe
3ffffa90:  feefeffe feefeffe feefeffe feefeffe
3ffffaa0:  feefeffe feefeffe feefeffe feefeffe
3ffffab0:  feefeffe feefeffe feefeffe feefeffe
3ffffac0:  feefeffe feefeffe feefeffe feefeffe
3ffffad0:  feefeffe feefeffe feefeffe feefeffe
3ffffae0:  feefeffe feefeffe feefeffe feefeffe
3ffffaf0:  feefeffe feefeffe feefeffe feefeffe
3ffffb00:  00000000 00000000 00000020 40100f22
3ffffb10:  3ffe92f0 40104304 3ffefd44 feefeffe
3ffffb20:  00000001 40103523 3ffed470 feefeffe
3ffffb30:  40103986 feefeffe feefeffe feefeffe
3ffffb40:  feefeffe feefeffe feefeffe feefeffe
3ffffb50:  4010346a 0000007f 7fffffff 00000000
3ffffb60:  0000007f feefeffe feefeffe feefeffe
3ffffb70:  401022eb 00080000 00000020 40100f22
3ffffb80:  00000000 00000000 00000000 4000050c
3ffffb90:  3fffc278 40101fe8 3fffc200 00000022
3ffffba0:  3ffffbb0 00000030 00000008 ffffffff
3ffffbb0:  00000000 00000000 0000001f 40104bfd
3ffffbc0:  4000050c 3ffedf28 00000002 00008e88
3ffffbd0:  40226856 00000030 00000008 ffffffff
3ffffbe0:  4021744b 00000000 00000001 3ffec950
3ffffbf0:  00000002 00000000 3fffab2a 00000001
3ffffc00:  00000003 00020021 00000001 3fff02f8
3ffffc10:  00000000 00000000 0000001f 40104bfd
3ffffc20:  4000050c 00ffffff 0000003f 3ffeca10
3ffffc30:  40000f83 00000030 00000008 ffffffff
3ffffc40:  4020b372 00000023 3fffdcc0 3fffb452
3ffffc50:  0000003a 000000f1 000000b9 00000003
3ffffc60:  00000001 fffffffd 00000001 3ffeee88
3ffffc70:  00000000 00000000 0000001f 40104bfd
3ffffc80:  4000050c 00000000 40225077 00000001
3ffffc90:  40000e86 00000030 0000001f fffffffe
3ffffca0:  40000e86 00000023 00000002 00000010
3ffffcb0:  00000010 00000000 3fffdbc0 3ffe93a8
3ffffcc0:  00000000 3fffc6fc 00000002 00000000
3ffffcd0:  3ffed440 00000001 00000000 00000030
3ffffce0:  00000000 3ffed470 20110486 00000000
3ffffcf0:  ffffffff 3fffc6fc 00000000 3ffefd44
3ffffd00:  3ffed440 00000001 00000000 00000030
3ffffd10:  3fffb41c 00000000 00000020 40100f22
3ffffd20:  3ffe92f0 4020b391 3ffeee88 3ffefc74
3ffffd30:  3fffb452 0000003a 3ffed470 40100f22
3ffffd40:  0000000c 00000000 00000020 3ffef2e1
3ffffd50:  000005e0 00000000 40103125 3ffed470
3ffffd60:  0000003c 00000000 3fffb452 00000100
3ffffd70:  0000001c 00000001 4010426a 3ffed470
3ffffd80:  3ffed440 4010431f 00000000 3ffed094
3ffffd90:  00000005 00000000 00000020 40100f22
3ffffda0:  3ffe92f5 4010431f 3ffecd80 40100f22
3ffffdb0:  40101c3d 3ffecd80 3ffefd44 40100f22
3ffffdc0:  00000023 61c7d6c4 3ffed750 40101e0e
3ffffdd0:  3ffe9b70 00000000 00000000 40100f22
3ffffde0:  00000023 61c7d6c4 4010224e 00000100
3ffffdf0:  7fffffff 3ffe9b70 3ffe9b70 00000001
3ffffe00:  00000001 00000040 3ffed750 40101e0e
3ffffe10:  3ffe9ba0 61c7d6c4 00000000 4000050c
3ffffe20:  3fffc278 40101fe8 3fffc200 00000022
3ffffe30:  3ffe9bac 3ffe9ba0 3ffe9ba0 00000001
3ffffe40:  40204bf3 00000030 00000010 ffffffff
3ffffe50:  40204bf3 00000001 00000001 00000000
3ffffe60:  00000000 00000000 00000000 fffffffe
3ffffe70:  ffffffff 3fffc6fc 00000001 00000064
3ffffe80:  3ffeebc8 3ffeeb98 3ffeec60 00000030
3ffffe90:  40204b9b 00000000 3ffeee68 00000000
3ffffea0:  00000000 00000000 00000000 fffffffe
3ffffeb0:  ffffffff 3fffc6fc 00000001 00000000
3ffffec0:  00000000 3fffdad0 3ffeed20 00000030
3ffffed0:  00000000 00000000 00000001 3ffeed18
3ffffee0:  00000000 3fffdad0 3ffeed20 00000030
3ffffef0:  ffffffff 3fffc6fc 00000001 3ffeed18
3fffff00:  00000000 3fffdad0 3ffeed20 00000030
3fffff10:  00000000 3fffdad0 3ffeed20 00000030
3fffff20:  3ffeeb98 3ffeebc8 3fffff60 401006dc
3fffff30:  3ffeeb98 3ffeec60 40204b0c 40204734
3fffff40:  4020158e 00000000 3ffeed18 40204f14
3fffff50:  3ffeeb98 3ffeebc8 3ffeed18 40202b38
3fffff60:  00000000 00000000 00000000 0106a8c0
3fffff70:  00000000 00000000 00000000 00000000
3fffff80:  00000000 3ffeec14 3ffeec60 40202a43
3fffff90:  40205198 6407a8c0 00000000 3ffeed20
3fffffa0:  00000000 00000000 00000001 40204b2d
stack

last failed alloc call: 3FFED93C(192)

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
vbb28d4a3
~ld

Update 2: It isn't only the first middleman (chip no.1) which crashes, now it happened to be the second one (chip no.4)

Are you sure it's not receiving, and not that the whole chip has crashed? What attempts at debugging it have you made?

can you use ESP-NOW instead of wifi? it's a lot faster/more stable for ad-hoc p2p

@dandavis I can't use ESP-NOW, because the project requires more abilities to control the system (I'd like to explain the project but it's way too big already). The chain reaction (sending) works fine for like 20 min. tho which is kinda weird

@Majenko I'll try to hook all up and wait until it "crashes" (takes around 20 min.). Sending info tomorrow

would rebooting every 15 mins cause too much downtime?

I have LEDs installed, to see "where the message is at" when it's being send. I have the LED connected to PIN 13 which is  "UART0 also has hardware flow control on pins 15 and 13 (RTS0 and CTS0 resp.). These two pins can also be used as alternative TX0 and RX0 pins." https://tttapa.github.io/ESP8266/Chap04%20-%20Microcontroller.html , going to change it to an unused one

@dandavis the project applies to many fields, and in certain circumstances it should go down every 6 hours. Plus I'm also not aware, if the ~20 min. are a safe time, maybe it could go down after 5 min.. I'm trying something out right now, giving feedback tomorrow

there are hardware watchdog timers, or maybe software is enough, if you find the hanging timeout consistent.

@Majenko So when no.1 sends a message, no.2 doesn't seem to handshake or respond to the sent message, which then results into no.1 having problems to go on int the code. After that no.2 actually crashed... going to hook it up to a serial monitor, maybe I can find out more.

Next thing I'll try is changing all the 'delay()'s inside the code and use millis() for timing instead

do you know about https://github.com/me-no-dev/EspExceptionDecoder ? it will give you the actual line number of your code where the problem occurs. When things go bad for more than 5 mins, it's time to bust it out...

@dandavis Took me a while to get it installed, but what I received was "Decode failed"

you might have to restart your IDE or possibly reflash the ESP with a higher debug level, but the data you pasted looks like the info it needs (the first few lines, not the raw ram dump)

I couldn't get that Exception Decoder to work, guess I'm to stupid for that. But what I've noticed now is, that when I only use 3 chips (so only one middleman instead of 3), it doesn't crash nor slow down

@dandavis I found the solution but still I'm thankful that you've tried to help me (posted as an answer). Have a nice day

I've swapped through 25 ESP8266-12 chips hoping I just had bad luck when receiving these things. I also tried changing the baud-rate, which resulted into some chips becoming a so called "brick" (don't set the baud-rate to 9600, or else you will have to flash them again). Changing the power supply wasn't helpful too. I tried to see if this was caused by a memory leak, so I included the method ESP.getFreeHeap() and printed the results. They didn't seem suspicious at all.
What I think did the trick was to put a delay(1) at the end of the loop and reduce the time interval of messages being sent from five seconds to one. For now this seems stable and reliable.
Update: I changed the delay(1) to the method yield(). As the ESP8266 runs a lot of utility functions in the background (keeping WiFi connected, managing the TCP/IP stack, and performing other duties) blocking these functions from running can cause the ESP8266 to crash and reset itself. To avoid these mysterious resets, avoid long, blocking loops in your sketch. Blocking loops can be for example sending messages with the TCP/IP.
Still delay(1) also worked for me because delays don't "freeze" the chip completely. There are multiple layers, some which are reachable for us and some which are not (keeping WiFi connected etc.), so delay() has a similar outcome as yield(). You can even find yield() in the delay() method in wiring.c.
void delay(unsigned long ms)
{
    uint32_t start = micros();

    while (ms > 0) {
        yield();                       //<-------
        while ( ms > 0 && (micros() - start) >= 1000) {
            ms--;
            start += 1000;
        }
    }
}

But to set a delay() one needs to know how long it has to be so the duties get finished in time. yield() on the other hand pauses reading the script until the background duties are finished (that doesn't take too long).
Editing your script so that the chip keeps executing the yield() method often enough per run fixed it for me.