text:
How Much mA dropped in ESP8266-01 Work in LiPo Battery if the WIFI function is continuously on
I working on the system where ESP8266-01 should continuously on because I want to get the Wi-Fi function on. In that case ,I can't use the Sleep mode which is given in the Esp8266-01 . So, My Question is that "How much will current(mA) dropped if the esp8266-01 continuously on in 4.2 LiPo battery??

Do you mean - "How much current is being consumed by the ESP8266 while using WiFi? " If that is your question then I would say that it depends on your specific board and if any external loads are present, given this I have found out that it has a current consumption of 400-420mA while using WiFi

Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking.

If you notice, an answer to this question gives you 200-220 mA is the current consumption, which is not wrong but you can see how it varies, so its best to measure it on your own with your particular case

I took some measurements here. Please be aware that you can be in Auto Light Sleep mode and still enjoy the occasional Wifi transmission, it will wake up when necessary.

If you really don't sleep at all you can count with about 70 mA, with some short spikes when transmitting.
Sleep mode disabled:

(100 mA per division)
But you don't need to disable sleep mode completely to use Wifi, you can be in Auto Light Sleep, which I think is the default for Arduino, Non-OS and RTOS.
Auto Light Sleep:

(100 mA per division)
The Wifi will automatically wake up to transmit and it will also wake up according to the Access Points DTIM interval to receive (usually every 300 ms). You're looking at about 2 mA baseline consumption plus the Wifi send and receive spikes.
Unfortunately after bootup there is a 10 second interval with full 70 mA consumption before the Auto Light Sleep mode kicks in. That's a significant drain if you have frequent system resets, but it might have been a bug that has been fixed in the meantime. (I took those measurements in 2017 with the Arduino SDK.)
There are other modes, but these were the ones that matter in your case.

this is consistent with my simple measurements and experiments

The short answer is - we don't know.
Longer answer:
It depends on such factors as:

The board circuit (the BBBL (known as The Big Bright Blue LED) on some boards could drain about 10-20ma only by itself)
The voltage regulator efficiency
The battery controller circuit / quality / keying efficiency.

The reasonable value is about 170-220 mA (taken from the PDF, section 5.2) for continuous data transfer.

The true solution is:
Take the ammeter, connect it in series with the battery and measure.

This is misleading in terms of battery guidance. The values in the chart are peaks, lasting only a ms. With a nodeMCU that doesn't sleep, I see ~70ma idle with traffic pushing it to ~87ma, as seen from a voltmeter (averaging out the spikes). Extending distance to the edge of reliability barely increases measured current of traffic: ~95ma. 100ma is a good (pessimistic) estimation figure with comfortable margins.

Yeah, 70 ma seems about right, if you don't sleep. I took some measurements here.


text:
Display GPS module data to my TFT display

I am using Arduino Mega 2560 and I have written code for my GPS module (Neo-6m-0-001/GY-NEO6MV2) and it is working fine independently.
I also have written code for Compass module (QMC5883L) which is also working fine independently and I am displaying the direction on my TFT (made a graphical compass dial on TFT) in real-time which is also working fine and needle varies according to my compass direction.
Now I am trying to combine both codes and display the long. and lat. values in graphical TFT fields but it is giving me error.

GPS code
//Connect with pin 18 and 19
#include <TinyGPS.h>
float lat,lon;
TinyGPS gps; // create gps object

void setup()
{
    Serial.begin(57600); // connect serial
    Serial.println("The GPS Received Signal:");
    Serial1.begin(9600); // connect gps sensor

}

void loop(){
    while(Serial1.available()){ // check for gps data
    if(gps.encode(Serial1.read()))// encode gps data
    {
    gps.f_get_position(&lat,&lon); // get latitude and longitude

    Serial.print("Position: ");

    //Latitude
    Serial.print("Latitude: ");
    Serial.print(lat,6);
    Serial.print(",");

    //Longitude
    Serial.print("Longitude: ");
    Serial.println(lon,6);

   }
  }
}

TFT and Compass Code
#include <stdlib.h>
#include <SPI.h>
#include <Wire.h>      // this is needed even tho we aren't using it
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <Adafruit_STMPE610.h>
#include <SoftwareSerial.h>

void Draw_Compass_Rose();
void display_item(int x, int y, String token, int txt_colour, int txt_size);
void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour);

// For the Adafruit TFT shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// The STMPE610 uses hardware SPI on the shield, and #8
#define STMPE_CS 8
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);

// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

/*** UI details */
#define BUTTON_X 40
#define BUTTON_Y 140
#define BUTTON_W 60
#define BUTTON_H 30
#define BUTTON_SPACING_X 20
#define BUTTON_SPACING_Y 10
#define BUTTON_TEXTSIZE 2

/* Back Button details */
#define BACK_BUTTON_X 40
#define BACK_BUTTON_Y 40

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

// text box where numbers go,position the text box/rectangle
#define TEXT_X 10
#define TEXT_Y 10
#define TEXT_X1 10
#define TEXT_Y1 50
#define TEXT_X2 10
#define TEXT_Y2 90
#define TEXT_W 220
#define TEXT_H 30
#define TEXT_TSIZE 3
#define TEXT_TCOLOR ILI9341_MAGENTA
// the data (phone #) we store in the textfield
#define TEXT_LEN 12
char latitude[TEXT_LEN+1] = "";
char longitude[TEXT_LEN+1] = "";
uint8_t latitude_i=0;
uint8_t longitude_i=0;
char STATUS_X;
char STATUS_Y;
float lat = 0.0;
float lon = 0.0;
float AZMTH = 0.0;
float add;

const int centreX  = 160;
const int centreY  = 120;
const int diameter = 100;
int last_dx, last_dy, dx, dy;

// 0 -> Keypad    1 -> Compass
unsigned int page_state = 0;

// 0 -> latitude     1 -> longitude
unsigned int cursor_state = 0;

/* create 15 buttons, in classic candybar phone style */
char buttonlabels[15][5] = {"ENT", "CLR", "NEXT", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", ">"};
uint16_t buttoncolors[15] = {ILI9341_DARKGREEN, ILI9341_DARKGREY, ILI9341_RED,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_ORANGE};
Adafruit_GFX_Button buttons[15];

char backButtonLable[1][5] = {"Back"};
uint16_t backButtonColors[1] = {ILI9341_DARKGREEN};
Adafruit_GFX_Button backButton[1];

// Print something in the mini status bar with either flashstring
void status(const __FlashStringHelper *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);//font size on top of white box
  tft.print(msg);
}
// or charstring
void status(char *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);//font size on top of white box
  tft.print(msg);
}

void setup() {
  Serial.begin(9600);
  Serial.println("Arduin-Test-LCD");

  // clear the screen
  tft.begin();
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_MAGENTA);
  tft.print("      WELCOME TO AZIMUTH SYSTEM");
  // eep touchscreen not found?
  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  Serial.println("Touchscreen started");

  // create buttons
  for (uint8_t row=0; row<5; row++) {
    for (uint8_t col=0; col<3; col++) {
      buttons[col + row*3].initButton(&tft, BUTTON_X+col*(BUTTON_W+BUTTON_SPACING_X),
                 BUTTON_Y+row*(BUTTON_H+BUTTON_SPACING_Y),    // x, y, w, h, outline, fill, text
                  BUTTON_W, BUTTON_H, ILI9341_WHITE, buttoncolors[col+row*3], ILI9341_WHITE,
                  buttonlabels[col + row*3], BUTTON_TEXTSIZE);
      buttons[col + row*3].drawButton();
    }
  }

  // create 'text field'
  tft.drawRect(TEXT_X, TEXT_Y, TEXT_W, TEXT_H, ILI9341_WHITE);
  tft.drawRect(TEXT_X1, TEXT_Y1, TEXT_W, TEXT_H, ILI9341_WHITE);
  tft.drawRect(TEXT_X2, TEXT_Y2, TEXT_W, TEXT_H, ILI9341_WHITE);

  tft.setCursor(TEXT_X+2, TEXT_Y+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" LAT:");

  tft.setCursor(TEXT_X1 + 2, TEXT_Y1+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" LONG:");

  tft.setCursor(TEXT_X2 + 2, TEXT_Y2+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" AZMTH:");
}

void loop() {
  TS_Point p;

  if (ts.bufferSize()) {
    p = ts.getPoint();
  } else {
    // this is our way of tracking touch 'release'!
    p.x = p.y = p.z = -1;
  }

  // Scale from ~0->4000 to tft.width using the calibration #'s
  if (p.z != -1) {
    p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
    p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
    Serial.print("("); Serial.print(p.x); Serial.print(", ");
    Serial.print(p.y); Serial.print(", ");
    Serial.print(p.z); Serial.println(") ");
  }

  switch(page_state){
    case 0: // Means Keypad
  // go thru all the buttons, checking if they were pressed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].contains(p.x, p.y)) {
      //Serial.print("Pressing: "); Serial.println(b);
      buttons[b].press(true);  // tell the button it is pressed
    } else {
      buttons[b].press(false);  // tell the button it is NOT pressed
    }
  }

  // now we can ask the buttons if their state has changed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].justReleased()) {
      // Serial.print("Released: "); Serial.println(b);
      buttons[b].drawButton();  // draw normal
    }

    if (buttons[b].justPressed()) {
        buttons[b].drawButton(true);  // draw invert!

        // ENT Button was clicked
        if (b == 0){
          lon = atof(longitude);
          lat = atof(latitude);
          status(F("  Searching and laser start rotating"));
          Serial.println("Searching ");
          Serial.print("Latitude : ");
          Serial.println(String(lat));
          Serial.print("longitude : ");
          Serial.println(String(lon));
          Serial.print("lat + lon = ");
          AZMTH=lat+lon;
          Serial.println(AZMTH);

            // just add this part in this location
          //----- AND REPLACE THE VALUE -----
          tft.setCursor(TEXT_X2 + 90, TEXT_Y2+10);
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              tft.print(AZMTH);
              Serial.print(AZMTH);

        }

        // CLR Button was clicked
        else if (b == 1) {
          switch(cursor_state){
            case 0:
              if (latitude > 0) {
                latitude_i--;
                latitude[latitude_i] = ' ';
              }
              break;

            case 1:
              if (longitude > 0) {
                longitude_i--;
                longitude[longitude_i] = ' ';
              }
              break;
          }
        }

        // NEXT Button was clicked
        else if (b == 2){
          page_state = 1;
          tft.fillScreen(BLACK);
          latitude[0]=0x00;
          latitude_i=0;
          longitude[0]=0x00;
          longitude_i=0;
          cursor_state = 0;

          tft.setRotation(1);
          Draw_Compass_Rose();
            double angle= 270; //use heading from compass
            dx = (diameter * cos((angle-90)*3.14/180)) + centreX;    // calculate X position
            dy = (diameter * sin((angle-90)*3.14/180)) + centreY;    // calculate Y position
            arrow(last_dx,last_dy, centreX, centreY, 20, 20,BLACK);  // Erase last arrow
            arrow(dx,dy, centreX, centreY, 20, 20,CYAN);             // Draw arrow in new position
            last_dx = dx;
            last_dy = dy;
          delay(25);
          tft.setRotation(0);

          }

        // '>' Button was clicked
        else if (b == 14){
          /* Toggle between latitude and longitude */
          if (cursor_state == 0){
            cursor_state = 1;
          } else if (cursor_state == 1){
            cursor_state = 0;
          }
        }

        // if a numberpad button, append the relevant # to the textfield
        else if (b >= 3) {
          switch(cursor_state){
            case 0:
              if (latitude_i < TEXT_LEN) {
                latitude[latitude_i] = buttonlabels[b][0];
                latitude_i++;
                latitude[latitude_i] = 0; // zero terminate
                //fona.playDTMF(buttonlabels[b][0]);
              }
              break;
            case 1:
              if (longitude_i < TEXT_LEN) {
                longitude[longitude_i] = buttonlabels[b][0];
                longitude_i++;
                longitude[longitude_i] = 0; // zero terminate
                //fona.playDTMF(buttonlabels[b][0]);
              }
              break;
          }

        }

      switch(cursor_state){
            case 0:
              // update the current latitude
              tft.setCursor(TEXT_X + 90, TEXT_Y+10);//set position of text when user key in the lat angle
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              tft.print(latitude);
              Serial.print(latitude);
              break;

              // update the current longitude
            case 1:
              tft.setCursor(TEXT_X1 + 90, TEXT_Y1+10);//set position of text when user key in the long angle
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              tft.print(longitude);
              Serial.print(longitude);
              break;
          }

    }
//
      delay(50); // UI debouncing

     }
   }
}

void display_item(int x, int y, String token, int txt_colour, int txt_size) {
    tft.setCursor(x, y);
    tft.setTextColor(txt_colour);
    tft.setTextSize(txt_size);
    tft.print(token);
    tft.setTextSize(2); // Back to default text size
}

void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour) {
  float distance;
  int dx, dy, x2o,y2o,x3,y3,x4,y4,k;
    distance = sqrt(pow((x1 - x2),2) + pow((y1 - y2), 2));
    dx = x2 + (x1 - x2) * alength / distance;
    dy = y2 + (y1 - y2) * alength / distance;
    k = awidth / alength;
    x2o = x2 - dx;
    y2o = dy - y2;
    x3 = y2o * k + dx;
    y3 = x2o * k + dy;
    x4 = dx - y2o * k;
    y4 = dy - x2o * k;
    tft.drawLine(x1, y1, x2, y2, colour);
    tft.drawLine(x1, y1, dx, dy, colour);
    tft.drawLine(x3, y3, x4, y4, colour);
    tft.drawLine(x3, y3, x2, y2, colour);
    tft.drawLine(x2, y2, x4, y4, colour);
}
void Draw_Compass_Rose(){
  int dxo, dyo, dxi, dyi;
    tft.drawCircle(centreX,centreY,diameter,YELLOW);  // Draw compass circle
  for (float i = 0; i <360; i = i + 22.5) {
    dxo = diameter * cos((i-90)*3.14/180);
    dyo = diameter * sin((i-90)*3.14/180);
    dxi = dxo * 0.9;
    dyi = dyo * 0.9;
    tft.drawLine(dxi+centreX,dyi+centreY,dxo+centreX,dyo+centreY,YELLOW);
  }
    display_item((centreX-5),(centreY-85),"N",RED,2);
    display_item((centreX-5),(centreY+70),"S",RED,2);
    display_item((centreX+80),(centreY-5),"E",RED,2);
    display_item((centreX-85),(centreY-5),"W",RED,2);
}

Combine Code
#include <stdlib.h>
#include <SPI.h>
#include <Wire.h>      // this is needed even tho we aren't using it
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <Adafruit_STMPE610.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>

TinyGPS gps; // create gps

void Draw_Compass_Rose();
void display_item(int x, int y, String token, int txt_colour, int txt_size);
void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour);

// For the Adafruit TFT shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// The STMPE610 uses hardware SPI on the shield, and #8
#define STMPE_CS 8
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);

// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

/*** UI details */
#define BUTTON_X 40
#define BUTTON_Y 140
#define BUTTON_W 60
#define BUTTON_H 30
#define BUTTON_SPACING_X 20
#define BUTTON_SPACING_Y 10
#define BUTTON_TEXTSIZE 2

/* Back Button details */
#define BACK_BUTTON_X 40
#define BACK_BUTTON_Y 40

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

// text box where numbers go,position the text box/rectangle
#define TEXT_X 10
#define TEXT_Y 10
#define TEXT_X1 10
#define TEXT_Y1 50
#define TEXT_X2 10
#define TEXT_Y2 90
#define TEXT_W 220
#define TEXT_H 30
#define TEXT_TSIZE 3
#define TEXT_TCOLOR ILI9341_MAGENTA
// the data (phone #) we store in the textfield
#define TEXT_LEN 12
char latitude[TEXT_LEN+1] = "";
char longitude[TEXT_LEN+1] = "";
uint8_t latitude_i=0;
uint8_t longitude_i=0;
char STATUS_X;
char STATUS_Y;
float lat = 0.0;
float lng = 0.0;
float AZMTH = 0.0;
float add;

const int centreX  = 160;
const int centreY  = 120;
const int diameter = 100;
int last_dx, last_dy, dx, dy;

// 0 -> Keypad    1 -> Compass
unsigned int page_state = 0;

// 0 -> latitude     1 -> longitude
unsigned int cursor_state = 0;

/* create 15 buttons, in classic candybar phone style */
char buttonlabels[15][5] = {"ENT", "CLR", "NEXT", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", ">"};
uint16_t buttoncolors[15] = {ILI9341_DARKGREEN, ILI9341_DARKGREY, ILI9341_RED,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_ORANGE};
Adafruit_GFX_Button buttons[15];

char backButtonLable[1][5] = {"Back"};
uint16_t backButtonColors[1] = {ILI9341_DARKGREEN};
Adafruit_GFX_Button backButton[1];

// Print something in the mini status bar with either flashstring
void status(const __FlashStringHelper *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);//font size on top of white box
  tft.print(msg);
}
// or charstring
void status(char *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);//font size on top of white box
  tft.print(msg);
}

void setup() {
Serial.begin(57600); // connect serial
Serial.println("The GPS Received Signal:");
Serial1.begin(9600); // connect gps sensor

  // clear the screen
  tft.begin();
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_MAGENTA);
  tft.print("      WELCOME TO AZIMUTH SYSTEM");
  // eep touchscreen not found?
  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  Serial.println("Touchscreen started");

  // create buttons
  for (uint8_t row=0; row<5; row++) {
    for (uint8_t col=0; col<3; col++) {
      buttons[col + row*3].initButton(&tft, BUTTON_X+col*(BUTTON_W+BUTTON_SPACING_X),
                 BUTTON_Y+row*(BUTTON_H+BUTTON_SPACING_Y),    // x, y, w, h, outline, fill, text
                  BUTTON_W, BUTTON_H, ILI9341_WHITE, buttoncolors[col+row*3], ILI9341_WHITE,
                  buttonlabels[col + row*3], BUTTON_TEXTSIZE);
      buttons[col + row*3].drawButton();
    }
  }

  // create 'text field'
  tft.drawRect(TEXT_X, TEXT_Y, TEXT_W, TEXT_H, ILI9341_WHITE);
  tft.drawRect(TEXT_X1, TEXT_Y1, TEXT_W, TEXT_H, ILI9341_WHITE);
  tft.drawRect(TEXT_X2, TEXT_Y2, TEXT_W, TEXT_H, ILI9341_WHITE);

  tft.setCursor(TEXT_X+2, TEXT_Y+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" LAT:");

  tft.setCursor(TEXT_X1 + 2, TEXT_Y1+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" LONG:");

  tft.setCursor(TEXT_X2 + 2, TEXT_Y2+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" AZMTH:");
}

void loop() {
  TS_Point p;
  while(Serial1.available()){ // check for gps data
  if(gps.encode(Serial1.read()))// encode gps data
   Serial.print("Position: ");
  }
  if (ts.bufferSize()) {
    p = ts.getPoint();
  } else {
    // this is our way of tracking touch 'release'!
    p.x = p.y = p.z = -1;
  }

  // Scale from ~0->4000 to tft.width using the calibration #'s
  if (p.z != -1) {
    p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
    p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
    Serial.print("("); Serial.print(p.x); Serial.print(", ");
    Serial.print(p.y); Serial.print(", ");
    Serial.print(p.z); Serial.println(") ");
  }

  switch(page_state){
    case 0: // Means Keypad
  // go thru all the buttons, checking if they were pressed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].contains(p.x, p.y)) {
      //Serial.print("Pressing: "); Serial.println(b);
      buttons[b].press(true);  // tell the button it is pressed
    } else {
      buttons[b].press(false);  // tell the button it is NOT pressed
    }
  }

  // now we can ask the buttons if their state has changed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].justReleased()) {
      // Serial.print("Released: "); Serial.println(b);
      buttons[b].drawButton();  // draw normal
    }

    if (buttons[b].justPressed()) {
        buttons[b].drawButton(true);  // draw invert!

        // ENT Button was clicked
        if (b == 0){
          lng = atof(longitude);
          lat = atof(latitude);
          status(F("  Searching and laser start rotating"));
          Serial.println("Searching ");
          Serial.print("Latitude : ");
          Serial.println(String(lat));
          Serial.print("longitude : ");
          Serial.println(String(lng));
          Serial.print("lat + lng = ");
          AZMTH=lat+lng;
          Serial.println(AZMTH);

            // just add this part in this location
          //----- AND REPLACE THE VALUE -----
          tft.setCursor(TEXT_X2 + 90, TEXT_Y2+10);
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              tft.print(AZMTH);
              Serial.print(AZMTH);

        }

        // CLR Button was clicked
        else if (b == 1) {
          switch(cursor_state){
            case 0:
              if (latitude > 0) {
                latitude_i--;
                latitude[latitude_i] = ' ';
              }
              break;

            case 1:
              if (longitude > 0) {
                longitude_i--;
                longitude[longitude_i] = ' ';
              }
              break;
          }
        }

        // NEXT Button was clicked
        else if (b == 2){
          page_state = 1;
          tft.fillScreen(BLACK);
          latitude[0]=0x00;
          latitude_i=0;
          longitude[0]=0x00;
          longitude_i=0;
          cursor_state = 0;

          tft.setRotation(1);
          Draw_Compass_Rose();
            double angle= 270; //use heading from compass
            dx = (diameter * cos((angle-90)*3.14/180)) + centreX;    // calculate X position
            dy = (diameter * sin((angle-90)*3.14/180)) + centreY;    // calculate Y position
            arrow(last_dx,last_dy, centreX, centreY, 20, 20,BLACK);  // Erase last arrow
            arrow(dx,dy, centreX, centreY, 20, 20,CYAN);             // Draw arrow in new position
            last_dx = dx;
            last_dy = dy;
          delay(25);
          tft.setRotation(0);

          }

        // '>' Button was clicked
        else if (b == 14){
          /* Toggle between latitude and longitude */
          if (cursor_state == 0){
            cursor_state = 1;
          } else if (cursor_state == 1){
            cursor_state = 0;
          }
        }

        // if a numberpad button, append the relevant # to the textfield
        else if (b >= 3) {
          switch(cursor_state){
            case 0:
              if (latitude_i < TEXT_LEN) {
                latitude[latitude_i] = buttonlabels[b][0];
                latitude_i++;
                latitude[latitude_i] = 0; // zero terminate
                //fona.playDTMF(buttonlabels[b][0]);
              }
              break;
            case 1:
              if (longitude_i < TEXT_LEN) {
                longitude[longitude_i] = buttonlabels[b][0];
                longitude_i++;
                longitude[longitude_i] = 0; // zero terminate
                //fona.playDTMF(buttonlabels[b][0]);
              }
              break;
          }

        }

      switch(cursor_state){
            case 0:
              // update the current latitude
              tft.setCursor(TEXT_X + 90, TEXT_Y+10);//set position of text when user key in the lat angle
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              Serial.print(latitude);
              if (gps.f_get_position(&lat,&lng))
              {
              tft.print(String(gps.f_get_position(&lat));
              double lat=gps.f_get_position(&lat,&lng));
              Serial.print(lat, 6);
              }
              break;

              // update the current longitude
            case 1:
              tft.setCursor(TEXT_X1 + 90, TEXT_Y1+10);//set position of text when user key in the long angle
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              Serial.print(longitude);
              if (gps.f_get_position(&lat,&lng))
              {
              tft.print(String(gps.f_get_position(&lng));
              double lng=gps.f_get_position(&lat,&lng));
              Serial.print(lng, 6);
              }
              break;
          }

    }
//
      delay(50); // UI debouncing

     }
   }
}

void display_item(int x, int y, String token, int txt_colour, int txt_size) {
    tft.setCursor(x, y);
    tft.setTextColor(txt_colour);
    tft.setTextSize(txt_size);
    tft.print(token);
    tft.setTextSize(2); // Back to default text size
}

void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour) {
  float distance;
  int dx, dy, x2o,y2o,x3,y3,x4,y4,k;
    distance = sqrt(pow((x1 - x2),2) + pow((y1 - y2), 2));
    dx = x2 + (x1 - x2) * alength / distance;
    dy = y2 + (y1 - y2) * alength / distance;
    k = awidth / alength;
    x2o = x2 - dx;
    y2o = dy - y2;
    x3 = y2o * k + dx;
    y3 = x2o * k + dy;
    x4 = dx - y2o * k;
    y4 = dy - x2o * k;
    tft.drawLine(x1, y1, x2, y2, colour);
    tft.drawLine(x1, y1, dx, dy, colour);
    tft.drawLine(x3, y3, x4, y4, colour);
    tft.drawLine(x3, y3, x2, y2, colour);
    tft.drawLine(x2, y2, x4, y4, colour);
}
void Draw_Compass_Rose(){
  int dxo, dyo, dxi, dyi;
    tft.drawCircle(centreX,centreY,diameter,YELLOW);  // Draw compass circle
  for (float i = 0; i <360; i = i + 22.5) {
    dxo = diameter * cos((i-90)*3.14/180);
    dyo = diameter * sin((i-90)*3.14/180);
    dxi = dxo * 0.9;
    dyi = dyo * 0.9;
    tft.drawLine(dxi+centreX,dyi+centreY,dxo+centreX,dyo+centreY,YELLOW);
  }
    display_item((centreX-5),(centreY-85),"N",RED,2);
    display_item((centreX-5),(centreY+70),"S",RED,2);
    display_item((centreX+80),(centreY-5),"E",RED,2);
    display_item((centreX-85),(centreY-5),"W",RED,2);
}

Attached is the image of error line, GUI on TFT with lat. and long. field, TFT, and log errors.
Errror line

Please do not include images of errors but include the full text. So, read what the error message says: "could not convert from 'void' to 'bool' ".... This gives a massive clue. You cannot use the output of gps.f_get_position(...), which is a void, inside an if statement, which expects something it can evaluate to a bool (i.e. a "true" or "false") to base its decision on.

source: Stack Exchange

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

sort: votes


text:
Problem with gps.encode() using TinyGPS library
First, see the schematics (attached).
The GPS is working properly when I write code only for reading data from it as below:
//Connect with pin 18 and 19
#include <TinyGPS.h>
//long   lat,lon; // create variable for latitude and longitude object
float lat,lon; //notice herewhy lon is not ina   get same same
TinyGPS gps; // create gps

void setup()
{
  Serial.begin(57600); // connect serial    for TFT
Serial.println("The GPS Received Signal:");
Serial1.begin(9600); // connect gps sensor    for GPS
  }

void loop(){

    while(Serial1.available()){ // check for gps data

      delay(1000);

        Serial.println( Serial1.read());

    if(gps.encode(Serial1.read()))// encode gps data
    {
    gps.f_get_position(&lat,&lon); // get latitude and longitude

    Serial.print("Position: ");

    //Latitude
    Serial.print("Latitude: ");
    Serial.print(lat,6);
    Serial.print(",");

    //Longitude
    Serial.print("Longitude: ");
    Serial.println(lon,6);

   }
  }
}

In the above code, when I print serial data coming from GPS, it is like 44,65,46,48,57,44,13,10,84.... and then gps.encode() function encodes it properly and returns true and ultimately I get correct values of longitude and latitude.
Now, the problem is when I use that same code along with my TFT code, it does not read serial data correctly and prints like 0,44,0,57,0,10,0,44,0,50,0,44... and the gps.encode() function always returns false. and I am unable to get any values of longitude and latitude.
Here is the complete code of TFT + GPS:
#include <stdlib.h>
#include <SPI.h>
#include <Wire.h>      // this is needed even tho we aren't using it
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <Adafruit_STMPE610.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>

TinyGPS gps; // create gps

void Draw_Compass_Rose();
void display_item(int x, int y, String token, int txt_colour, int txt_size);
void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour);

// For the Adafruit TFT shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// The STMPE610 uses hardware SPI on the shield, and #8
#define STMPE_CS 8
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);

// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

/*** UI details */
#define BUTTON_X 40
#define BUTTON_Y 140
#define BUTTON_W 60
#define BUTTON_H 30
#define BUTTON_SPACING_X 20
#define BUTTON_SPACING_Y 10
#define BUTTON_TEXTSIZE 2

/* Back Button details */
#define BACK_BUTTON_X 40
#define BACK_BUTTON_Y 40

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

// text box where numbers go,position the text box/rectangle
#define TEXT_X 10
#define TEXT_Y 10
#define TEXT_X1 10
#define TEXT_Y1 50
#define TEXT_X2 10
#define TEXT_Y2 90
#define TEXT_W 220
#define TEXT_H 30
#define TEXT_TSIZE 3
#define TEXT_TCOLOR ILI9341_MAGENTA
// the data (phone #) we store in the textfield
#define TEXT_LEN 12
char latitude[TEXT_LEN+1] = "";
char longitude[TEXT_LEN+1] = "";
uint8_t latitude_i=0;
uint8_t longitude_i=0;
char STATUS_X;
char STATUS_Y;
float lat = 0.0;
float lon = 0.0;
float AZMTH = 0.0;
float add;

const int centreX  = 160;
const int centreY  = 120;
const int diameter = 100;
int last_dx, last_dy, dx, dy;

// 0 -> Keypad    1 -> Compass
unsigned int page_state = 0;

// 0 -> latitude     1 -> longitude
unsigned int cursor_state = 0;

/* create 15 buttons, in classic candybar phone style */
char buttonlabels[15][5] = {"ENT", "CLR", "NEXT", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", ">"};
uint16_t buttoncolors[15] = {ILI9341_DARKGREEN, ILI9341_DARKGREY, ILI9341_RED,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_ORANGE};
Adafruit_GFX_Button buttons[15];

char backButtonLable[1][5] = {"Back"};
uint16_t backButtonColors[1] = {ILI9341_DARKGREEN};
Adafruit_GFX_Button backButton[1];

// Print something in the mini status bar with either flashstring
void status(const __FlashStringHelper *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);//font size on top of white box
  tft.print(msg);
}
// or charstring
void status(char *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);//font size on top of white box
  tft.print(msg);
}

void setup() {
Serial.begin(57600); // connect serial
Serial.println("The GPS Received Signal:");
Serial1.begin(9600); // connect gps sensor

  // clear the screen
  tft.begin();
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_MAGENTA);
  tft.print("      WELCOME TO AZIMUTH SYSTEM");
  // eep touchscreen not found?
  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  Serial.println("Touchscreen started");

  // create buttons
  for (uint8_t row=0; row<5; row++) {
    for (uint8_t col=0; col<3; col++) {
      buttons[col + row*3].initButton(&tft, BUTTON_X+col*(BUTTON_W+BUTTON_SPACING_X),
                 BUTTON_Y+row*(BUTTON_H+BUTTON_SPACING_Y),    // x, y, w, h, outline, fill, text
                  BUTTON_W, BUTTON_H, ILI9341_WHITE, buttoncolors[col+row*3], ILI9341_WHITE,
                  buttonlabels[col + row*3], BUTTON_TEXTSIZE);
      buttons[col + row*3].drawButton();
    }
  }

  // create 'text field'
  tft.drawRect(TEXT_X, TEXT_Y, TEXT_W, TEXT_H, ILI9341_WHITE);
  tft.drawRect(TEXT_X1, TEXT_Y1, TEXT_W, TEXT_H, ILI9341_WHITE);
  tft.drawRect(TEXT_X2, TEXT_Y2, TEXT_W, TEXT_H, ILI9341_WHITE);

  tft.setCursor(TEXT_X+2, TEXT_Y+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" LAT:");

  tft.setCursor(TEXT_X1 + 2, TEXT_Y1+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" LONG:");

  tft.setCursor(TEXT_X2 + 2, TEXT_Y2+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" AZMTH:");
}

void loop() {

  TS_Point p;

  /*
  while(Serial1.available()){ // check for gps data    //this has issue it is not written correctly
  if(gps.encode(Serial1.read()))// encode gps data
   Serial.print("Position: ");
  }
  */

  //lets try starts

  while(Serial1.available()){

    delay(1000);

      Serial.println( Serial1.read());

    bool res = gps.encode(Serial1.read());

    Serial.println(res);

    if(res)// encode gps data       //here is the problem lies    <<<<<<<<<===================================== it always return 0 thats why not working
    {
      gps.f_get_position(&lat,&lon); // get latitude and longitude

       Serial.print("Position: ");

    //Latitude
    Serial.print("Latitude: ");
    Serial.print(lat,6);
    Serial.print(",");

    //Longitude
    Serial.print("Longitude: ");
    Serial.println(lon,6);

      }

    }

  //lets try ends

  if (ts.bufferSize()) {
    p = ts.getPoint();
  } else {
    // this is our way of tracking touch 'release'!
    p.x = p.y = p.z = -1;
  }

  // Scale from ~0->4000 to tft.width using the calibration #'s
  if (p.z != -1) {
    p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
    p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
    Serial.print("("); Serial.print(p.x); Serial.print(", ");
    Serial.print(p.y); Serial.print(", ");
    Serial.print(p.z); Serial.println(") ");
  }

  switch(page_state){
    case 0: // Means Keypad
  // go thru all the buttons, checking if they were pressed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].contains(p.x, p.y)) {
      //Serial.print("Pressing: "); Serial.println(b);
      buttons[b].press(true);  // tell the button it is pressed
    } else {
      buttons[b].press(false);  // tell the button it is NOT pressed
    }
  }

  // now we can ask the buttons if their state has changed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].justReleased()) {
      // Serial.print("Released: "); Serial.println(b);
      buttons[b].drawButton();  // draw normal
    }

    if (buttons[b].justPressed()) {
        buttons[b].drawButton(true);  // draw invert!

        // ENT Button was clicked
        if (b == 0){
          lon = atof(longitude);
          lat = atof(latitude);
          status(F("  Searching and laser start rotating"));
          Serial.println("Searching ");
          Serial.print("Latitude : ");
          Serial.println(String(lat));
          Serial.print("longitude : ");
          Serial.println(String(lon));
          Serial.print("lat + lon = ");
          AZMTH=lat+lon;
          Serial.println(AZMTH);

            // just add this part in this location
          //----- AND REPLACE THE VALUE -----
          tft.setCursor(TEXT_X2 + 90, TEXT_Y2+10);
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              tft.print(AZMTH);
              Serial.print(AZMTH);

        }

        // CLR Button was clicked
        else if (b == 1) {
          switch(cursor_state){
            case 0:
              if (latitude > 0) {
                latitude_i--;
                latitude[latitude_i] = ' ';
              }
              break;

            case 1:
              if (longitude > 0) {
                longitude_i--;
                longitude[longitude_i] = ' ';
              }
              break;
          }
        }

        // NEXT Button was clicked
        else if (b == 2){
          page_state = 1;
          tft.fillScreen(BLACK);
          latitude[0]=0x00;
          latitude_i=0;
          longitude[0]=0x00;
          longitude_i=0;
          cursor_state = 0;

          tft.setRotation(1);
          Draw_Compass_Rose();
            double angle= 270; //use heading from compass
            dx = (diameter * cos((angle-90)*3.14/180)) + centreX;    // calculate X position
            dy = (diameter * sin((angle-90)*3.14/180)) + centreY;    // calculate Y position
            arrow(last_dx,last_dy, centreX, centreY, 20, 20,BLACK);  // Erase last arrow
            arrow(dx,dy, centreX, centreY, 20, 20,CYAN);             // Draw arrow in new position
            last_dx = dx;
            last_dy = dy;
          delay(25);
          tft.setRotation(0);

          }

        // '>' Button was clicked
        else if (b == 14){
          /* Toggle between latitude and longitude */
          if (cursor_state == 0){
            cursor_state = 1;
          } else if (cursor_state == 1){
            cursor_state = 0;
          }
        }

        // if a numberpad button, append the relevant # to the textfield
        else if (b >= 3) {
          switch(cursor_state){
            case 0:
              if (latitude_i < TEXT_LEN) {
                latitude[latitude_i] = buttonlabels[b][0];
                latitude_i++;
                latitude[latitude_i] = 0; // zero terminate
                //fona.playDTMF(buttonlabels[b][0]);
              }
              break;
            case 1:
              if (longitude_i < TEXT_LEN) {
                longitude[longitude_i] = buttonlabels[b][0];
                longitude_i++;
                longitude[longitude_i] = 0; // zero terminate
                //fona.playDTMF(buttonlabels[b][0]);
              }
              break;
          }

        }

       Serial.println("Value of cursor_state: ");    //where is written touch screen started? you there????
       Serial.print(cursor_state);

      switch(cursor_state){   //This condition is always false

            Serial.print("If successfully comes here then this line should print");  //This means

            case 0:
              // update the current latitude
              tft.setCursor(TEXT_X + 90, TEXT_Y+10);//set position of text when user key in the lat angle
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              Serial.print(latitude);
             // if (gps.f_get_position(&lat,&lon))    //<- this condition is wrong
              {
             // tft.print(String(gps.f_get_position(&lat));
              gps.f_get_position(&lat,&lon);
              Serial.println("Latitude on Serial: ");

              Serial.print(lat, 6);
              }
              break;

              // update the current longitude
            case 1:
              tft.setCursor(TEXT_X1 + 90, TEXT_Y1+10);//set position of text when user key in the long angle
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              Serial.print(longitude);
             // if (gps.f_get_position(&lat,&lon))
              {
             // tft.print(String(gps.f_get_position(&lon));
              gps.f_get_position(&lat,&lon);
              Serial.println("Longitude on Serial: ");
              Serial.print(lon, 6);
              }
              break;
          }

    }
//
      delay(50); // UI debouncing

     }
   }
}

void display_item(int x, int y, String token, int txt_colour, int txt_size) {
    tft.setCursor(x, y);
    tft.setTextColor(txt_colour);
    tft.setTextSize(txt_size);
    tft.print(token);
    tft.setTextSize(2); // Back to default text size
}

void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour) {
  float distance;
  int dx, dy, x2o,y2o,x3,y3,x4,y4,k;
    distance = sqrt(pow((x1 - x2),2) + pow((y1 - y2), 2));
    dx = x2 + (x1 - x2) * alength / distance;
    dy = y2 + (y1 - y2) * alength / distance;
    k = awidth / alength;
    x2o = x2 - dx;
    y2o = dy - y2;
    x3 = y2o * k + dx;
    y3 = x2o * k + dy;
    x4 = dx - y2o * k;
    y4 = dy - x2o * k;
    tft.drawLine(x1, y1, x2, y2, colour);
    tft.drawLine(x1, y1, dx, dy, colour);
    tft.drawLine(x3, y3, x4, y4, colour);
    tft.drawLine(x3, y3, x2, y2, colour);
    tft.drawLine(x2, y2, x4, y4, colour);
}
void Draw_Compass_Rose(){
  int dxo, dyo, dxi, dyi;
    tft.drawCircle(centreX,centreY,diameter,YELLOW);  // Draw compass circle
  for (float i = 0; i <360; i = i + 22.5) {
    dxo = diameter * cos((i-90)*3.14/180);
    dyo = diameter * sin((i-90)*3.14/180);
    dxi = dxo * 0.9;
    dyi = dyo * 0.9;
    tft.drawLine(dxi+centreX,dyi+centreY,dxo+centreX,dyo+centreY,YELLOW);
  }
    display_item((centreX-5),(centreY-85),"N",RED,2);
    display_item((centreX-5),(centreY+70),"S",RED,2);
    display_item((centreX+80),(centreY-5),"E",RED,2);
    display_item((centreX-85),(centreY-5),"W",RED,2);
}

Please help me. I shall be very thankful to the person who helps me.

i fail to understand how anyone would identify the problem to be the gps.encode()  function, when the problem is clearly the data from the GPS module being corrupted by the presence of the TFT module and/or the TFT program ... determine if the problem is caused by the presence of the TFT module alone, or if it caused by software ... try to narrow down what part of the program causes the fail

@jsotola Okay. but I mentioned earlier that if I run GPS standalone then it works properly but when it is used with TFT it does not give proper serial data.I don't know where is the problem. I am stuck on it for weeks now

Added: the TFT is connected when I run the GPS code (and excluding TFT code) and GPS works properly

now add simple hello world TFT code

Do you realise that you're discarding every other byte from the GPS? Serial.println(Serial1.read()); reads a byte, displays it, then you never get that byte back again.

@Majenko yes I know that, it was for testing purpose only.

@Majenko any suggestions what could be the problem?

And that "testing" breaks everything. Ditch that. Or put the read value into a variable so you can use it twice. At the moment you're seeing, instead of "Hello world" just "el od"

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


text:
not able to figure out what is wrong with my nodemcu code
#include <ESP8266WiFi.h>
#include <FirebaseArduino.h>

//Firebase settings
#define FIREBASE_HOST "..........firebaseio.com/"     //cant share
#define FIREBASE_AUTH "..............."               //cant share

//Wi-Fi settings
#define WIFI_SSID "kello"
#define WIFI_PASSWORD "8888"

//Define trigger and echo digital pins
const int trigPin = 4;
const int echoPin = 3;

// The amount of time the ultrassonic wave will be travelling for
long duration = 0;
// Define the distance variable
double distance = 0;

void setup()
{
     Serial.begin(9600);
    // Connect to Wi-Fi
    Serial.print("Wi-Fi...");
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    Serial.print("Connecting...");
    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.print(".");
        delay(500);
    }
    Serial.println();
    Serial.print("Connected to: ");
    Serial.println(WiFi.localIP());

    Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);

    // Ultrasonic sensor, set echo as Input and trigger as Output
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);

}

void loop()
{

    getDistance();
    // Prints the distance value to the serial monitor
    Serial.print("Distance: ");
    Serial.println(distance);

    delay(500);
}

void getDistance()
{
    // Clear trigPin
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);

    // trigPin HIGH por 10ms
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    //Reads echoPin, returns the travel time of the sound wave in ms
    duration = pulseIn(echoPin, HIGH);

    // Calculating the distance, in centimeters, using the formula described in the first section.
    distance = duration * 0.034 / 2;

    // Sends the distance value to Firebase
    Firebase.setFloat("distance", distance);

}

I am a computer graduate so i do not have much knowledge about nodemcu. I saw some documentations about nodemcu. I want to show the data obtained by the ultrasonic distance sensor in the realtime database of firebase. But i am not able to figure out why i am not able to get output of serial.println(distance) in the com5 window even though the code compiles successfully .
This is what i get when running the program
Executable segment sizes:

IROM   : 330560          - code in flash         (default or ICACHE_FLASH_ATTR)

IRAM   : 27760   / 32768 - code in IRAM          (ICACHE_RAM_ATTR, ISRs...)

DATA   : 1408  )         - initialized variables (global, static) in RAM/HEAP

RODATA : 2044  ) / 81920 - constants             (global, static) in RAM/HEAP

BSS    : 25160 )         - zeroed variables      (global, static) in RAM/HEAP

Sketch uses 361772 bytes (34%) of program storage space. Maximum is 1044464 bytes.
Global variables use 28612 bytes (34%) of dynamic memory, leaving 53308 bytes for local variables. Maximum is 81920 bytes.
esptool.py v2.8
Serial port COM5
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: ec:fa:bc:c1:44:d2
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 365920 bytes to 264395...

Writing at 0x00000000... (5 %)
Writing at 0x00004000... (11 %)
Writing at 0x00008000... (17 %)
Writing at 0x0000c000... (23 %)
Writing at 0x00010000... (29 %)
Writing at 0x00014000... (35 %)
Writing at 0x00018000... (41 %)
Writing at 0x0001c000... (47 %)
Writing at 0x00020000... (52 %)
Writing at 0x00024000... (58 %)
Writing at 0x00028000... (64 %)
Writing at 0x0002c000... (70 %)
Writing at 0x00030000... (76 %)
Writing at 0x00034000... (82 %)
Writing at 0x00038000... (88 %)
Writing at 0x0003c000... (94 %)
Writing at 0x00040000... (100 %)
Wrote 365920 bytes (264395 compressed) at 0x00000000 in 23.4 seconds (effective 125.3 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

Is the ultrasonic sensor not getting enough power supply as nodemcu is connected to my laptop?
Please help me out and let me know if more information is required.

https://electronics.stackexchange.com/questions/402066/esp8266-free-gpios-for-relay-switching/404845#404845

Your echoPin Is defined as 3. GPIO3 of the NodeMCU is also the “RX” pin needed for serial communication to the host. This might explain why you don’t see any output. You should change it to a different pin (for example pin 5 / D1 is a safe choice).
Each pin on the NodeMCU has a “GPIO” number (which is just the pin number as defined by the ESP8266 architecture) and a corresponding “Dx” designation (which is usually marked on the NodeMCU board).
Which GPIO pin corresponds to which which “D” pin is shown in pinout diagrams, like the one here. Scroll to the NodeMCU 12-E pinout.
Some of the safest pins to use are:

Pin 5 (D1)
Pin 4 (D2)
Pin 12 (D6)
Pin 13 (D7)
Pin 14 (D5)

Some of the other pins could also be used, but have some restrictions, as you can see on the page I linked to.
Note that pins 12-14 are used for SPI and pins 4 and 5 are (normally) used for (software) I2C. If you want to control hardware that uses these protocols, these are the default pins it uses.


text:
Using RX TX pin
Can i use pin RX TX on Arduino Uno as reguler pin ? .
For input and output pin , because two digital pin on my board doesn’t work . Thank’s

can you be a bit more specific? do you mean pins 0 and 1?
What can't digital pin 2 do?

Yes, you can use those pins like regular digital pins on the Uno. They are numbered 0 and 1. That is... provided you do not try to use Serial.

and the component wired to this pins can interfere with sketch upload. and if one of this two stops working then no serial upload will be possible.

Oke , thank’s u so much

TX can be used as a general input or output
The TX pin is normally an output from the Arduino microcontroller to a serial converter (RS-232 voltage converter or a USB-to-serial converter) that sends data to the host computer.  In this usage, the only thing driving the pin is the serial hardware inside the Arduino microcontroller.
However, it is possible to re-configure the pin as a general-purpose digital output.  You will first need to disable the TX serial function as described in this answer.  Example code:
disable_tx();
pinMode(1, OUTPUT);
//...
digitalWrite(1, whatever);

It is also possible to re-configure the pin as a general-purpose digital input.  Again, first disable TX.  Example code:
disable_tx();
pinMode(1, INPUT);
//...
foo = digitalRead(1);

You can also use INPUT_PULLUP to enable the internal weak pullup resistors, and even switch back and forth between pinModes.  Conveniently, the TX/1 pin is on the standard Arduino header, where you can connect the rest of your circuit to read the output or drive the input.
Beware that TX is still connected to the serial converter.  Electrically, this is not a problem because the serial converter only reads the TX value and never drives it; there is no contention.  However, the signals you generate as general I/O will probably not be valid serial signals, and thus you will be unable to communicate with a host system the same time you are using TX for general I/O.  In other words, don't bother trying to use Serial the same time as general I/O.
You will still be able to upload programs to the Arduino, though this will send spurious signals to your external circuitry during that process, possibly causing contention.  Unplug your external circuitry before uploading programs.
RX should not be used as general input or output
The RX pin is normally driven by the serial converter, and the microcontroller reads it as an input.  This allows the host system to download programs and also to read Serial in running programs.
You can't simply reconfigure the pin as an output, because then both the serial converter and the microcontroller will be trying to drive the pin, and you will have contention.
You also can't simply reconfigure the pin as an input.  Whatever circuit that you are trying to read will be trying to drive that pin at the same time that the serial converter is trying to drive the pin, and you will have contention.
In theory, you have several options:

You could cut the trace between the serial converter and the pin on the microcontroller.  This assumes that the trace is accessible, you know what you are doing, and you get it right.  The downside is that you will never be able to upload another program to that Arduino board.

You could cut the trace as #1, and put a resistor across it (say 470 ohm).  This requires even more skill than #1.  When the serial converter is in contention to drive the pin, the serial converter will lose and the other thing will win.

In theory, the serial converter could use a tri-state output that can be disabled, or a weak open-collector output that can be over-driven.  However, of all of the Arduino board schematics I have seen, none of them actually do this.  Plus, you'd have to manually switch it on and off each time you want to upload a new program.

Design your own board that doesn't use serial.

None of these alternatives are actually practical, so your best plan is to never use RX for general-purpose input or output.

Contention on the RX pin is generally not an issue: the Arduino Uno has a 1 kΩ resistor between the serial converter’s TX and the ATmega328P’s RX. It’s resistor RN4B in this Arduino Uno schematic.

downvote is mine ("The answer is not useful")


text:
Wire Library Timer Usage
I would like to know if the Wire Library is using a Hardware Timer from the Arduino Mega 2560. And If so which Timer it is.
As I am using the Timer 1. After implementing the Wire Library I have some strange things happening that are probably due to the Timer.
Thanks a lot.

No, it's not.
It has its own timer called the "Bit Rate Generator Unit" which is controlled using the TWBR register.  It takes its time source direct from the main CPU clock and divides it down.


text:
How do I use a SMD crystal with 4 pins?
I am running my arduino project with the atmega328 chip like this:

I have purchased by mistake this crystal:

The reason why I purchased by mistake that crystal was because it has this description:

16MHz ±10ppm 22pF 60Ω SMD-3225 SMD Crystal Resonators RoHS

I thought that it contained the 22pF ceramic capacitors inside. But latter I learned that I still the 22pf ceramic capacitors. (Please correct me if I am wrong)
Anyways how can I use that crystal? I only know how to connect the 2 pin crystal. Since this crystal has 4 pins now I am confused.
To me it makes sense to connect it like this:

Connect pins 9 and 10 from atmega --TO--> pins 1 and 3 from the crystal.
Connect pins 2 and 4 from crystal --TO--> Ground
Connect the 22pf ceramic capacitors to pins 1 and 3 from crystal and ground like in the first diagram.

this is a nice question. Once for a project I stumbled upon this problem too.
The way you described the connection should work perfectly fine.

To me it makes sense to connect it like this:
  Connect pins 9 and 10 from atmega --TO--> pins 1 and 3 from the crystal.
  Connect pins 2 and 4 from crystal --TO--> Ground
  Connect the 22pf ceramic capacitors to pins 1 and 3 from crystal and ground like in the first diagram.

Keep it going and greetings from Switzerland.


text:
Turn on Indicator LED if Moisture Sensor Value >= MaxDryness for longer than 20 min
Hi so I am making a self watering flower pot with a moisture sensor and a peristaltic pump, the code is as follows:

I want to add an indicator LED which turns on if the sensor value has been equal to or greater than MaxDryness for longer than twenty minutes.
How would I alter the code to do that?

why did you post a picture of the code? ... do you really think that someone will spend time typing it in so that it could be added to, and posted as an answer?

Ditch the delay() calls and learn the non-blocking coding style from the BlinkWithoutDelay example. It uses the millis() function, that returns the milliseconds since startup. You can use this as a clock to time the 20min. The coding style has been explained many times on the web.

@jyc43 please replace your source code picture with a code block, this will allow us to insert the lines of code you are looking for.

Please code the text as text

Following is an example how it could be coded.
Remember that the soil is dry by setting DrySoil = true.
Register the time at which a dry period starts in DrySoilBegin.
Check at each 'dry' reading whether DrySoil was true for more than 20 minutes.
Set DrySoil = false at every 'not dry' reading.
The ul after the constant 1200000 makes it an unsigned long value. This because millis() returns a unsigned long result. I am not 100% sure this is necessary (maybe the compiler takes care of this automatically).
As I don't have a plant watering system I couldn't verify the proper working..
#define WATERPIN 10
#define READSOILPIN A0
#define LEDPIN 13

// higher number is more dry
#define MAXDRYNESS 700

#define WATERDELAY 10000
#define WATERPOSTDELAY 5000

bool DrySoil = false; // State of soil
unsigned long DrySoilBegin; // Time when DrySoil became true

void setup() {
  Serial.begin(9600);
  pinMode(READSOILPIN, INPUT);
  pinMode(WATERPIN, OUTPUT);
  pinMode(LEDPIN, OUTPUT);
}

void loop() {
  int SensorValue = analogRead(READSOILPIN); //take a sample
  Serial.print(SensorValue);
  Serial.print(" ־ ");

  if(SensorValue >= MAXDRYNESS) {
    // Soil is too dry
    // Check if soil was already in a dry state
    if(DrySoil){
      // If already in a dry state check the duration
      if((millis()-DrySoilBegin) > 1200000ul){
        // If duration is longer than 20 minutes switch LED on
        //   or keep LED switched on
        digitalWrite(LEDPIN, HIGH);
      }
    }
    else{
      // First 'dry' result after 'wet' result(s)
      DrySoil = true; // Set DrySoil in true state
      DrySoilBegin = millis(); // Set beginning of DrySoil period
    }
    // start watering for 10 seconds then
    //    wait for 5 seconds before monitoring again
    Serial.println("Soil dry start watering");
    digitalWrite(WATERPIN, HIGH);
    delay(WATERDELAY); // wait until WATERDELAY milliseconds have passed
    digitalWrite(WATERPIN, LOW);
    delay(WATERPOSTDELAY); // wait until WATERPOSTDELAY milliseconds have passed
  }
  else{
    // Soil is not too dry
    DrySoil = false; // Set or keep DrySoil in state false
    digitalWrite(LEDPIN, LOW); // Switch LED off, or keep it switched off
    delay(50); // Wait 50 ms before next sampling
  }
}

You should move your first else down so that it matches if(DrySoil). 2. You should replace while((millis()-TimerStart)<... by delay(). Using millis() in this blocking fashion has zero advantage over delay() and it makes the code harder to read.

Thank you, you are right. Have edited accordingly. 2. My guess was, this left more internal processes running. But I understand this is not true. Also corrected accordingly.

Here's a little example how to do it. Adapt this way(if you want) by yourself.
// GLOBAL VARIABLES
unsigned long lowSensorTick = 0;
bool dry = false;

void loop()
{
    if (analogRead(/* PIN */) > /* THRESHOLD VALUE */)
    {
        // DRY
        if (dry == false)
        {
            lowSensorTick = millis();
            dry = true;
        }
        else
        {
            if (millis() - lowSensorTick > 720000) // 720000ms = 12min * 60000ms (1s = 1000ms)
            {
                digitalWrite(LED_PIN, HIGH); // LED GOES HIGH/ON
            }
        }
    }
    else
    {
        // WET
        dry = false;
        digitalWrite(LED_PIN, LOW); // LED GOES LOW/OFF
    }
}

Note that zero is a perfectly valid timestamp. You should use a separate boolean variable, like in PimV's answer, rather having lowSensorTick perform double duty of storing the timestamp and a "timestamp valid" state.

Why? millis() will never return zero as value. I use this way in my projects and it works without any problem.

millis() returns zero at the beginning of the program run, and then once again every 49.7 days.

At the begining you have pinMode function. Zero stays for 1/1000s. For overflow that's another problem.

pinMode() executes in way less than a millisecond. 2. lowSensorTick = 0 is a kludge to shoehorn a valid/invalid status info into a variable that is meant to hold something else, and this can make the program misbehave, albeit very rarely. Other than laziness, there is no reason to not use a separate Boolean. If you want to take the (very tiny) risk on you own programs, that's OK. But when answering questions, you should avoid teaching bad practices, especially considering that there is already a perfectly valid answer.

@EdgarBonet fixed.


text:
Library Compiler Error - ArduinoJson
I have installed via the Arduino Library Manager a library called ArduinoJson.  It seems to install fine and I have included the library in my sketch using:
#include "ArduinoJson.h"

But when I compile the sketch I get the following error:
"C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega2560 -DF_CPU=16000000L -DARDUINO=10807 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR "-IC:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino" "-IC:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\variants\\mega" "-IG:\\My Drive\\Personal\\jdeation\\Arduino\\libraries\\HX711-0.1" "-IG:\\My Drive\\Personal\\jdeation\\Arduino\\libraries\\ArduinoJson\\src" "C:\\Users\\jason\\AppData\\Local\\Temp\\arduino_build_7871\\sketch\\counting_machine.ino.cpp" -o nul

In file included from G:\My Drive\Personal\jdeation\Arduino\libraries\ArduinoJson\src/ArduinoJson/JsonBufferBase.hpp:7:0,

                 from G:\My Drive\Personal\jdeation\Arduino\libraries\ArduinoJson\src/ArduinoJson/DynamicJsonBuffer.hpp:7,

                 from G:\My Drive\Personal\jdeation\Arduino\libraries\ArduinoJson\src/ArduinoJson.hpp:9,

                 from G:\My Drive\Personal\jdeation\Arduino\libraries\ArduinoJson\src/ArduinoJson.h:9,

                 from G:\My Drive\Personal\jdeation\Arduino\counting_machine\counting_machine.ino:32:

G:\My Drive\Personal\jdeation\Arduino\libraries\ArduinoJson\src/ArduinoJson/Deserialization/JsonParser.hpp:7:29: fatal error: ../JsonBuffer.hpp: No such file or directory

compilation terminated.

I'm very new to Arduino programming,  can someone point me in the right direction.
Thanks.

delete it and try to install again

Go through the library manager and make sure your version is 5.14.3 and not higher. The higher ones are Beta versions and there has been changes that are not compatible with the previous non-Beta versions.
This is an annoyance because you would think that the latest would be the best. But that is not always the case.


text:
Possible to drive Waveshare E-ink without driver hat?
I bought and E-Ink display from waveshare and it came with such a “driver hat”: https://www.waveshare.com/wiki/E-Paper_Driver_HAT#Display_Config_Switch
I am wondering what exactly is the role of this component? Why can’t I directly connect the cables from the display to the GIPO pins and drive the display without the driver hat - given the right software?
(I am also happy to get a pointer to a better forum to ask in if this here isn’t the right place.)

Have you completed the steps in the "Working With Arduino" section: https://www.waveshare.com/wiki/E-Paper_Driver_HAT#Working_with_Arduino

No, you need the hat, or something equivalent. Turn it over. You see all those components? They exist to generate the right voltages for the ePaper display. Without those it won't work.
Sure, you can recreate it from the schematic, but why bother when you have it already?

I think i was hoping that it could be emulated in software. Of course I assumed that it was not possible, but i was wondering WHY not.


text:
How to control 2 micro magnetic actuators with esp12e
i want to control two micro magnetic actuators (just two coil where I want to flow current in +to- and-to+ each motor for wifi airplane) with esp12e
Do I need an h-bridge like l293d ?
Also I will be using mit app inventor any advice for it will nice:)))

Yes you need an H-bridge. "Any advice" is rather broad. This site works best for more narrow questions

Alternatively you can get by with half an H bridge but will need a power supply which can deliver positive, ground and negative voltages.  Your choice.

Thanks for your response but I noticed that l293d works on min.4.5v but I can provide 3.3v or 4v only:((


text:
MKR 1010 WIFI Built-in RGB LED not working with BLE
in addition to the standard LED_BUILTIN, MKR 1010 WIFI comes with a built-in RGB LED.
This RGB LED fails when used along the on-board BLE, no matter what program sequence I test.
To reproduce the issue, turn on the LED and then start BLE which will turn the LED off.
#include <WiFiNINA.h>
#include <utility\wifi_drv.h>
#include <ArduinoBLE.h>

void setup() {

  const int ledPin = 27;  //R=26 G=25 B=27

  WiFiDrv::pinMode(ledPin, OUTPUT);

  WiFiDrv::digitalWrite(ledPin, HIGH);

  Serial.begin(115200);
  while (!Serial);

  if (!BLE.begin()) { // ble.begin trun the led off
    Serial.println("BLE Failed");
    while (1);
  }

  Serial.println("BLE started"); // last line shown on console

  WiFiDrv::digitalWrite(ledPin, HIGH);

  // program never gets here

}

void loop() {}

The RGB LED is connected to NINA’s GPIO pins. Two of them (green and blue) are part of the UART, and another one is used for system control signals (red).
I assumed that BLE.begin uses the UART to communicate with the processor and therefore avoided the red pin and added delays between commands hoping to separate the actions, but it didn’t work.
My goal is to use the RGB LED to indicate BLE states without adding three sets of MOSFETs and resistors. Ideas?

The ArduinoBLE library resets the NINA firmware to BLE mode (code here). In this mode the NINA firmware just sets ESP32 SDK (IDF framework) to handle the BLE commands.
The RGB LED is handled by the part of the Arduino NINA firmware which handles the commands from the WiFiNINA library. These commands are communicated over SPI and are not handled if the firmware is in BLE mode.

Appreciate the clarifications, thanks Juraj


text:
Using String instead of C string, yet another attempt to touch a loaded issue
I've been reading a lot over the years why we should not use the notorious String class and how heap fragmentation is bad practice and not professional and we should never use it in our programs or we'll never enter the C hall of fame and get to be called programmers.
Fine, I get it, C string is pro, String is people toying with Arduino, but having read all that I still don't understand:

Where is the risk? If I use String and my heap gets fragmented, and there's still enough memory for the program to run for months without crashing, why should I not use String if it makes my work so much easier? Just because it's a bad habit is a very lame answer.

Is it possible to quantify the fragmentation and get a feel of what's safe and when it becomes risky? Are there any tools to measure / alert / help us know how close we are to fall off that cliff?

And really, what is potential harm, in practical terms not theoretically, what are the limits, does anyone know when a program will crash?

Happy coding!

I totally agree. I use String all the time and in all the ways I know I shouldn't and my gadgets never have any problems.  So, in practice, I don't see the harm in using String and I'll keep using them.

if your device crashes after several months, isn't that a problem?

Interesting to see this discussion, because if you speak to infosec people they will tell you that C string handling is one of the profession's great disasters.

Whether or not String is actively harmful depends on context. The problem is that ignorant (in the technical sense) usage of String can easily lead to difficult-to-diagnose problems: those least likely to understand how to diagnose the issues are the most likely to have the issues.

@pjc50 Indeed, but the issues faced by devs with a few K of memory are different than those faced by the majority of programmers.

You can create just as much mess on the heap allocating your own string memory with malloc() and free() as you can by using a string class. Especially considering that the code of the string class itself was probably written by someone who knows more about software development than you do.

If it works, great, use it! If it turns out to be a problem, switch away from it. Organize your code in a way that this is easily doable. Don't prematurely optimize. That being said, on limited platforms (embedded), using C strings from the start might be a good idea.

It's not that String itself is evil, it's more that it's very easy to abuse it and cause heap fragmentation. Used judiciously it's fine and a useful tool. Used in "bad" ways and you open the door to random crashes.
By "bad" ways I mean excessive (and not needed) data duplication and heap reallocation. The biggest pitfalls are:

Using .concat() or "adding" strings together with +
Passing String objects to functions by value instead of by reference

Basically anything where a new string is created and the old one thrown away leaves holes in the heap.
Those holes (fragmentation) themselves aren't a problem - the problem is the very tiny amount of RAM the typical low-end Arduino (i.e., ATMega328P based) has. When you have wasted space in your heap in the form of holes it's more and more likely that you will end up having the top of your heap meet the bottom of your stack, and that is when problems arise.
For transient operations String is fine. By "transient" I mean operations where all the data is discarded at the end. All temporary and source strings are destroyed and all the memory is returned to the pool, thus leaving no holes in the heap.
Also on microcontrollers with far more memory than a little Arduino UNO (such as ESP32, etc) heap fragmentation ceases to really be a problem. By the time the heap grows big enough to be noticeable any holes have got big enough that they start to get filled again.

Comments are not for extended discussion; this conversation has been moved to chat.

(Outsider here, checking this out from the hot network questions) Returning String objects from functions by value instead of by reference Does the Arduino environment use C++, or C? In C++, copy-elision on return is now guaranteed, so I don't think this should be an issue.

The short answer is that fragmentation crashes are infrequent because they require very specific conditions to arise—and that's the problem.
Imagine you have a crash that occurs once every few days and can't figure out why. It never happens while testing and doesn't seem to be caused by anything specific.
Then it turns out that your code is printing numbers to a string, usually 4 digits but sometimes 2 or 3. And it turns out that very specific sequences of the lengths of strings being allocated and deallocated trigger a crash. But there's no good way to analyse or predict the problem because it hinges on absolutely everything that's happened since boot. If there was a 3- instead of 4-digit number 8 hours ago, that completely changes what would need to happen now to trigger a crash.
While answering this question I tried to come up with some code that would leave memory very fragmented. It was very difficult. Memory fragmentation is very sensitive to what happens, in what order. Basically it's a highly chaotic system.
This is reminiscent of problems related to multithreading, where running a simple program multiple times can easily give different results. Problems like this are really, really frustrating to identify and diagnose. A lot of people have felt the pain and that is why there is such stigma about String.
To answer your questions:

why should I not use String if it makes my work so much easier?

As long as you understand the pitfalls and how to avoid them, sometimes Strings are the best tool for the job.
The main goal of avoiding String is to prevent severe heap fragmentation. There are other ways to do that, though:

Don't store lots of heap-allocated objects on a long-term basis. If you only have 3 global String variables then it's probably fine to allocate 100 small strings if you delete them before doing anything else
If you have to store many heap-allocated objects long-term, try not to allocate them during a period of a lot of heap allocations, deallocations, and resizings (such as during a loop when a string is being built). You want to avoid these long-term objects being given "random" positions through memory.

If you want to use String in an application where reliable long-term operation is important, you really have to be thorough in understanding your memory usage patterns and why they are unlikely to trigger a problem.
I should add that each String adds several bytes of memory overhead, both for the string descriptor and for the invisible bookkeeping that the malloc() implementation does. They are also slower to access than char []s.

Is it possible to quantify the fragmentation and get a feel of what's safe and when it becomes risky?

This is difficult because of how sensitive things are to tiny differences in allocation history. There are a few simple analyses you can do, though.
If you have n heap-allocated objects, you have n+1 fragments (although some fragments may be zero size.) The average fragment size will be ≤ the amount of free space divided by n+1. For example if you have 19 allocated objects and 2000 bytes of remaining space, your average fragment size will be 100 bytes. Mathematically this implies that at least one fragment is ≥ this size, and therefore you are guaranteed to be able to allocate anything smaller than 100 bytes. Keep in mind though that every allocated object consumes a few bytes of invisible bookkeeping data used by the runtime's implementation of malloc(), and there may be other hidden things floating around in the system, like some objects allocated by libraries. Also remember that on Arduino, SRAM is shared by stack and heap.
Now let's say you have 8KB of heap space and you allocate a lot of stuff, then deallocate a lot of stuff, leaving exactly 3 small objects allocated. This will divide your heap into 4 regions. The average size will be just under 2KB and so no matter how unlucky you are, one or more of the regions will be at least that size. So you should be able to allocate one large object of around 2KB, or, allocate hundreds of small objects, or allocate one object and keep resizing it anywhere up to 2KB. If you then free everything except for 3 small objects, you will be back in the same situation: you are guaranteed a region of at least 2KB.
There are two noteworthy conclusions:

If the maximum number of items that will ever be allocated at a time is n, and their maximum size is s, and your heap size is at least (2n+1) × (s+4), you will never have a fragmentation problem. (3 is an architecture-dependent fudge factor to cover malloc bookkeeping and padding issues.)
If there are "checkpoints" in your code where only a few objects are allocated, this makes it easier to reason about what can happen between these checkpoints.

Are there any tools to measure / alert / help us know how close we are to fall off that cliff?

Not for Arduino that I know of. The problem is, a program susceptible to severe fragmentation may only display signs for short periods once every few days or something.
The easiest technique you can use is to consume say 30% of your memory with malloc() at the start of your program to put more heap pressure on it, and see if it still works. This isn't guaranteed to bring the problems out of the woodwork, but it greatly boosts the chances that you will see something.
You can also write a function to try to allocate the largest objects possible over and over, slowly reducing the size, and see to what extent you are prevented from allocating large objects but can allocate small ones. I was going to post one but I decided it would be of limited benefit.
If you really want to see what is going on with your heap you can look at the source of your malloc() implementation and inspect its data structures from within your program. In this case it seems to be as simple as putting this at the start of your code
struct __freelist {
  size_t sz;
  struct __freelist *nx;
};
extern struct __freelist *__flp;

and then you can traverse the contents of the freelist using __flp.

I'd like to answer your question without discussing the more technical side. This has been admirably covered by my learned colleagues in their own answers. I am going to address the cost-benefit side of using String.
Certainly, in the short term, it is almost certainly faster and easier to use String than to allocate buffers of characters, keeping track of how full they are, appending to the end of them, and so on.
For example, to read serial input, this is easy:
String inputBuffer;

void loop()
  {
  while (Serial.available () > 0)
    inputBuffer += Serial.read ();

  if (inputBuffer == "something")
    doSomething ();
  }  // end of loop

This, by the way, is the very sort of code that is likely to cause heap fragmentation and a crash. :)
So, you may well save an hour or two of coding by using the String class. So far, so good. You are ahead.
Then you start testing. Things go well for a while, but then after your code runs for an hour it mysteriously crashes, or probably, hangs. Your device stops doing what it is supposed to do, and you start looking for bugs. There is nothing obviously wrong, so you spend quite a bit of time trying to solve the issue. Heap fragmentation doesn't jump out and slap you in the face like, say, forgetting to add one variable to another.
So you look over the code, maybe post a question on Stack Exchange, maybe ask friends, maybe ask your teacher (where appropriate). Soon enough, time is mounting. You spend an hour debugging, two hours, four hours, and soon you have spent eight hours on it. Now you have wasted all the benefit you got from using the "easy" String class. Not only that, you are way behind, compared to allocating a fixed-size buffer and managing putting data into it yourself.
Sooner or later you identify that heap fragmentation is the culprit, and have to rewrite it. In other words, you eventually have to stop using the String class. So the whole episode has been a waste of time.
Certainly this won't always happen, and for the occasional use of fixed-length String objects, there won't be an issue. But if you look at the conditions mentioned in the other answers, you can see that it is easier, in fact, to "just don't use String" than to use them in very careful ways, and hope that your project doesn't break today, tomorrow, next week, or after three months "in the field".

why should I not use String if it makes my work so much easier?

Certainly you should, if it makes your work easier, and if it doesn't crash.

does anyone know when a program will crash?

No, probably not. If you are "lucky" it will crash soon after you start it, and you will at least know you have a problem. If you are unlucky your fish feeder will stop feeding your fish two weeks into your holiday and they will die.

As you mentioned, amazing answers given here and your adds to that so thanks everyone for taking the time.

I'm not an Arduino programmer, but I am a C programmer.  And the problem of string types in C -- or, rather, the absence of a first-class string type in C -- is an old but important one.
The fundamental problem is this.  In C, you can say things like
int a, b, c, d, f();
a = b + c;
d = f();

And you can say things like
float q, r, s, t();
q = r / s + t();

But you can not say
string x, y, z();
x = y + z();

C has no first-class string type.  In pure C, if you want to manipulate strings, you have to use some combination of char [] arrays and char * pointers.  You have to remember to allocate enough memory to hold the strings you're working with today.  In many cases you can't assign strings; you may have to call strcpy or the like.  In most cases you can't directly compare strings; you usually have to call strcmp or the like.  This can all be a real nuisance, and if you get the details wrong, you get strange bugs and crashes.
So, especially if you're a beginning or casual programmer, It Would Be Nice if C had a true, first-class string type.  (And of course C++ does have such a type.)
But there's a very good reason that plain C doesn't have such a type.  Manipulating strings is just plain harder than manipulating ints or floats.  The reason it's harder is precisely because they're variable-length, and potentially rather large.  Under C's low-level philosophy, the best person to make good tradeoffs when it comes to deciding how to handle a particular program's strings is that program's author, not the compiler or library writer.
You can write a decently good, decently efficient, high-level, first-class string type.  But, it's never going to be as efficient, for every problem, as handcrafted char [] and char ** code would be.  Also, if there are a bunch of rules for how to use a first-class string type efficiently, avoiding fragmentation and the like, those rules are probably going to end up being almost as complicated as the rules for using char [] and char * correctly -- but the whole point of introducing the first-class string type was so that programmers wouldn't have to worry about those low-level details all the time!  It's really rather a pretty pickle.
So when someone says, "you shouldn't use that high-level string type, it's wasteful and inefficient", the question to ask is, is it unacceptably wasteful or inefficient?
Once upon a time, people said we shouldn't use compiled languages, since they're wasteful and inefficient.  Those people thought we should all write everything in assembly language.  (And there are still a few people who say this.)  Most of the time, though, we've discovered that compiled code is adequately efficient, and its other advantages more than make up for any slight lingering inefficiencies.
And the question for C strings versus Strings is almost perfectly equivalent.  If your program is making significant use of strings, expending a large fraction of its time or a large fraction of the available memory towards them, the inefficiencies of Strings might well be unacceptable.  If there are relatively few strings, however, the convenience to the programmer of using a high-level String type (along with the absence of bugs) might be well worth it, and the costs might be inconsequential.
But there's no one right answer to the question of "Do or don't use Strings", because it's a subjective question, and different people under different circumstances will legitimately come to different conclusions.

C wouldn't need to add much to allow programmers to implement things that are much closer to be usable as first-class types.  If it included static const compound literals, and offered a strong recommendation that such literals should be omitted if their addresses are taken and directly used as the second operand of a ?: operator whose first operand is always zero, or the third operand of one whose first operand is never zero, better string types could be easier to use than C strings.

Mega point is: don't use String (or anything else that uses the heap) inside interrupts - even with objects created outside the interrupt. the underlying memory allocation functions cannot deal with it and you've got a good chance something will go boom.
As for the rest, so much of this is dependant on implementation
Nick's answer with the input buffer yes will crash, he never clears it! (j/k)
But even if he did after matching with something, i.e.
      if (inputBuffer == "something") {
            inputBuffer="";
            doSomething ();
      }

after we've hit this there will be no more (possible) fragmenting to do with this code, as the implementation for String on the copy (or a concatenation) there does not reallocate the memory buffer unless it is too small. So as we go round this whole loop after the first time, no heap allocations will happen.
We could also remove any reallocations during the initial building of the 'something' string in the inputBuffer by allocating enough space right at the beginning of the code with
    inputBuffer.reserve(9);

where 9 is the length of the string 'something' (reserve will add an extra byte on the buffer for the string terminator)
You can also use this to reserve space for doing multiple concatenations . Anything above 1 concat / += will save time because of not multiply reallocating space, plus stop the fragmentation.
    int newSize=a.length()+b.length()+c.length();
    a.reserve(newSize); // only memory realloc happens here
    a.concat(b);
    a.concat(c);

Similarly you could create a much bigger buffer to briefly handle something you're not sure the size of (say, reserve 512 bytes) but beware! because of the point above (.reserve() does not reallocate the buffer unless the requested size is larger) you are stuck with that buffer until the string object is destroyed by going out of scope or being explicitly deleted. Global objects are stuck with it. So if you need a global object that could get bigger or smaller, make it a pointer to a String then use new/delete as required.
Also we need to consider object lifetime. Even if you use a bunch of String objects in a function, if they are all destroyed at the end, and you haven't created any other heap objects within that function, when you have left and all the Strings are auto destroyed there should be no impact on the heap, it should return to its previous state as the memory is reclaimed
If you are creating String objects on the heap (via new) though it does compound any fragmentation problems you may have in your code anyway as you end up with 2 heap items, the String wrapper object and the data itself. If you're just using a local or global variable the wrapper won't be in the heap, either in global memory or on the stack.

As you already got good answers to most of your questions, I will try
to cover here only this one:

Is it possible to quantify the fragmentation and get a feel of what's  safe and when it becomes risky?

A quick Web search for “Arduino free memory” finds a few code snippets
that can be used to measure, at run time, the amount of free memory:

Available Memory, in the Arduino Playground, only works on AVR. It
measures  the total amount of available RAM, including the holes in
the heap.

Measuring Memory Usage, an Adafruit tutorial, shows some portable
(AVR and ARM) code that measures the available RAM between the heap
and the stack. This does not include the holes in the heap.

If you compare the AVR versions of these two code snippets, you can see
the difference is in the freeListSize() function of the Playground
version. This function returns the total memory residing in heap holes,
which could be a measure of the heap fragmentation.
The function is AVR-specific, but then AVR is where heap fragmentation
is most worrisome.


text:
Connecting Winsen ZE11-C2H4 Sensor to Arduino
How should I connect the ZE11 Ethylene Sensor to an Arduino Uno? I want to know how to attach the pins of the sensor to the Arduino and which resistor I should use. I'm very unprofessional at working with circuits so I most likely will need step-by-step help. To make things easier, I am attaching the datasheet associated with the sensor. The pin identification and technical parameters are on pages 3-4. Also if someone taught me how to do advanced coding for this project then that would be great. Please note that Winsen is a company based in China, so some things can be inaccurate because of translation. Any help is appreciated.

Why do you ask "what resistor to use?" To use for what? What makes you think you want a resistor for anything? Do you know what a resistor does? What it is used for?

Pin 5 & pin 6 are UART Bus. To use UART, connect pin 5 with TX pin on Arduino and pin 6 to RX pin on Arduino. Details about communication settings are at 4th page.
I can't find library for that sensor so guess you're on your own.
UART also Know as Serial communication.


text:
FastLED: Can't address led individually
I'm unable to access the first led in my strip with this code:
void loop()
{
  leds[0] = CRGB::White; FastLED.show(); delay(100);
  leds[0] = CRGB::Black; FastLED.show(); delay(100);
}

Instead, it blinks 3 leds, though I expect it to blink only the first one.

Here's how my setup code looks like:
#define DATA_PIN    1
#define CLK_PIN   5
#define LED_TYPE    WS2812B
#define COLOR_ORDER RGB
#define NUM_LEDS    60
CRGB leds[NUM_LEDS];

#define BRIGHTNESS          10

void setup() {
  delay(1000); // Power-up delay

  // tell FastLED about the LED strip configuration
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);

  // set master brightness control
  FastLED.setBrightness(BRIGHTNESS);
}

The led was bought from here: https://www.aliexpress.com/item/0-5-5M-30-60-LEDs-M-2811-Pixels-Programmable-Individual-Addressable-LED-Strip-light-WS2811/32849630888.html?spm=a2g0s.9042311.0.0.8e664c4dU4dru2

Dude, you own a WS2811 led strip, NOT a WS2812B. You need to know how to program this kind of led strip, but the line you want to change is this one: #define LED_TYPE    WS2812B

If you look at the video in your link carefully, you'll see that as per answer below, as much as the description says the LED are individually controlled, they are in fact controlled in groups of 3

@k.Cyborg tried that as well, didn't help

The description in the link of where you bought the strip says:

Description:

LED Type: 5050SMD with External IC WS2811 （1 IC control 3leds）

So, this is probably as intended.
Note the application circuits in the datasheet for the controller IC (WS2811) [Page 5] where, for 5V, you can address a single LED, but for a 12V configuration, you must group the LEDs in sets of 3.

Thanks for your answer. I got another WS2811 (https://www.aliexpress.com/item/12mm-black-Wire-WS2811-pixel-module-led-string-Chrismas-tree-50pcs-a-string-with-3pin-JST/32444382333.html?spm=a2g0s.9042311.0.0.27424c4d7GMaSp), it's 12V but individually addressable though


text:
SD Card Read/Write Arduino Mega Fail
I have an Arduino Mega 2560 where I have used a MicroSD Card Module to Read/Write Data on the Micro SD Card.
I have tried using the Example in the Arduino IDE but the data is not being written or read by Arduino to the SD Card Module. The connections with the module is exactly how it is described in the Sketch.
I have attached pictures of the Connection and the module I use for the same.
The Example sketch for the SD Card Read/Write is also attached.
If there is a problem that you can notice, please let me know what the problem is and if it can be solved.
Thank you in advance.
/*
SD card read/write

This example shows how to read and write data to and from an SD card file
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)

created   Nov 2010
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe

This example code is in the public domain.

*/

#include <SPI.h>
#include <SD.h>

 File myFile;

 void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
     while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
      }

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

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

  Serial.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
   myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
    if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
     } else {
     // if the file didn't open, print an error:
     Serial.println("error opening test.txt");
   }

    // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile) {
   Serial.println("test.txt:");

    // read from the file until there's nothing else in it:
     while (myFile.available()) {
     Serial.write(myFile.read());
     }
    // close the file:
    myFile.close();
     } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
     }
    }

    void loop() {
   // nothing happens after setup
     }

Connection with Arduino
SD Card Module

The SPI wiring described in the SD card example sketch is for Uno. On Mega the SPI pins are 50 MISO, 51 MOSI and 52 CLK.

SD.begin(53); for 53 as CS for SD card

Thank you so much. I will check with your information and update you.

I am so sorry for the delay. I had tried it and it worked. I could not come back go StackExchange because of getting stuck with other projects. Thank you so much for your help.


text:
Problem getting data from Arduino pro mini
I am currently working on a drone project using multiwii.
I m using mpu6050 as gyro and accelerometer sensor with i2c protocol. I was able to read data coming from mpu6050 while using Arduino Uno through multiwii but can't get it work with Arduino pro mini. I was able to get data with pro mini while using i2c scanner and mpu6050 test codes available on web but can't see any data from sensor on multiwii platform though it shows that Arduino is connected. I tried using pull up resistors and try with another pro mini but with no luck. One note is that because I will be using this with a 1s lipo battery ,I bootloaded both pro mini with 8mhz internal oscillator at 3.3v and even tried using external oscillator 8mhz but with no luck (I actually modified both of them cause 3.3v Mini's are not available in my country). I am using Arduino Uno without ic to program the pro mini board and its having no problem while programing or while reading data on serial monitor but only with multiwii. I tried multiwii with my Uno and nano and both worked just fine so right now I m wondering if on board programmer effects this but I have seen some people using pro mini with multiwii
My connections are not lose at all cause I soldered them directly to the Uno board.


text:
Nrf24l01 smd pcb placement tips
I am working on pcb design with nrf24l01 smd. I have read somewhere that nrf24l01 module has problem while communication when it is placed with its antenna within the pcb. I want my module to be within the pcb as much as possible to save some space. I will be making the pcb at home and will be placing atmega 328p smd on the opposite layer. Should I fill the opposite layer with ground pad?

You need to keep the ground plane away from the antenna. The rest of the module doesn't care (and having a ground plane under it can help with unwanted EMI).
Here's a design I did recently for a customer with the same module in it. It's placed near the edge of the PCB with the ground plane cut out around the antenna:

That layout is actually set up for either the small SMD, the SMD with PA+LNB or the thorugh-hole version. The important thing is that there is a nice big exclusion zone in the ground plane where the antenna is.

Thanks for your answer

Hi @Majenko! Would it be okay to have the NRF24L01 module and ATMega module on the same PCB with also the antenna on the PCB?