Send Character into Serial Monitor via button press

Hello Everyone .. I have a problem when I want to send a message on the serial monitor by pressing a button.

the thing i want to do is press a button, then some sensor data that has been captured by arduino can be sent to the database.

when I press the button, the program returns to setup() and it
shows "Connecting........" on the serial monitor

#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
WiFiClient client;
String data;
String arrData[4];
boolean parsing=false;

SoftwareSerial DataSerial(12, 13);

unsigned long previousMillis = 0;
const long interval = 3000;

const char *ssid = "My WiFi";
const char *password = "My Password WiFi";

const char *host = "My Host";
HTTPClient http;

void setup() {
  Serial.begin(9600);
  DataSerial.begin(9600);

  pinMode(D1, INPUT_PULLUP);

  data="";

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  Serial.print("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

int value = 0;

void loop() {
  if(Serial.available() > 0)
  {
    char inChar = (char)Serial.read();
    data += inChar;
    if (inChar == '\n') 
    {
      parsing = true;
    }
  }
  if(parsing)
  {
    parsingData();
    parsing=false;
    data="";

    delay(1000);
    ++value;

    Serial.print("Connecting to ");
    Serial.println(host);

    WiFiClient client;
    if(!client.connect(host, 80))
    {
      Serial.println("Connection Failed!");
      return;
    }

    String url = "/coba_sensor/write-data.php?data1=";
    url += arrData[0].toInt();
    url += "&data2=";
    url += arrData[1].toFloat();
    url += "&data3=";
    url += arrData[2].toFloat();
    url += "&data4=";
    url += arrData[3].toFloat();

    Serial.print("Requesting URL: ");
    Serial.println(url);

    client.print(String("GET ") + url + " HTTP/1.1\r\n" + 
                  "Host: " + host + "\r\n" + 
                  "Connection: close\r\n\r\n");
    unsigned long timeout = millis();
    while (client.available() == 0)
    {
      if (millis() - timeout > 1000)
      {
        Serial.println(">>> Client Timeout !");
        client.stop();
        return;
      }
    }

    while (client.available()){
      String line = client.readStringUntil('\r');
      Serial.print(line);
    }
    Serial.println();
    Serial.println("Closing Connection");
  }
}

void parsingData()
{
  unsigned long currentMillis = millis();  //membaca waktu milis saat ini
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;  //update previousMillis

    String data = "";  //baca data serial
    while (DataSerial.available() > 0) {
      data += char(DataSerial.read());
    }
    data.trim();

    int j=0;
    arrData[j]="";
    for(int i=1;i<data.length();i++)
    {
      if((data[i] == '#'))
      {
        j++;
        arrData[j]="";
      }
      else
      {
        arrData[j] = arrData[j] + data[i];
      }
    }
    DataSerial.println("Ya");
  }
}

Thank you!

Welcome to the forum

Your topic was MOVED to its current forum category which is more appropriate than the original as it has nothing to do with Installation and Troubleshooting of the IDE

my bad.. forgot to set that up..
anyway thank you..

I don't see anywhere in your code where you read a button input. Also, how is your button wired? What Arduino are you using?

If you are pressing a button and the Arduino resets there is something really wrong.

Why do you read from DataSerial into the global String data until '\n' is read and then don't do anything with it? You set data to "" before doing anything with it.

  if (Serial.available() > 0)
  {
    char inChar = (char)Serial.read();
    data += inChar;
    if (inChar == '\n')
    {
      parsing = true;
    }
  }

In this code if there are more than 3 '#' characters in data you will write past the end of the arrData array which could cause all kinds of weirdness due to memory corruption. You may want to put a safety check in for the j index.

    int j = 0;
    arrData[j] = "";
    for (int i = 1; i < data.length(); i++)
    {
      if ((data[i] == '#'))
      {
        j++;
        arrData[j] = "";
      }
      else
      {
        arrData[j] = arrData[j] + data[i];
      }
    }

here I connect the Arduino Uno with the nodemcu esp8266, the main microcontroller here is the Arduino Uno. Initially, the process of transferring data from Arduino to nodemcu was done by sending a "Yes" message to the nodemcu serial monitor, and it worked. but at this point I want to change the action by using the button.

and I haven't put the code to access the button yet, cause at this point when I pressed the button, it will perform a reset action.

Most likely, the button is short-circuiting the Arduino power supply. Redo all the connections. Make SURE you understand the button pinouts.

A much safer approach is to use pinMode(button_pin, INPUT_PULLUP) and connect the button between the pin and ground. No resistor needed.

If that is really a 1K pull-down resistor try 20K...or do what @jremington suggested, which is how most people do it.

I still haven't found a solution to solve this problem. Maybe you can help me, for more detailed diagram and code I have posted a new forum here. Thanks in advance.

I still haven't found a solution to solve this problem. Please help me here. Thanks in advance.

Hello Everyone.. I have some problem in building a prototype..
Actually, I've asked this problem on my forum before, but I still can't find a solution.

At first, my prototype parse the data that had been obtained into the database by type some characters on the serial monitor. But now, I want to change that action by pressing the button.

Here is the diagram before the button is held.

And here is the diagram after the button was added.

And here is my Arduino's code

#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

//DHT DEFINE//
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

//SOIL MOISTURE DEFINE//
#define sensor A0 //pin sensor soil moisture
#define wet 210 //wet limit
#define dry 510 //dry limit

//ph Tanah
#define pH_sensor A1

LiquidCrystal_I2C lcd(0x27, 16, 2);

float humidity, temperature;
int pHValue = 0;
float pHOutput = 0.0;

void setup() {
  Serial.begin(9600);
  dht.begin(); //aktivasi sensor dht
}

void loop() {
  String minta = "";      //request from NodeMCU

  while(Serial.available()>0){       //read the request
    minta += char(Serial.read());
  }

  minta.trim(); //membuang spasi
  if (minta == "Ya") {    
    kirimdata();
  }

  minta = ""; //set variabel minta to null
  delay(1000);
}

void kirimdata() {
  
  //read DHT
  temperature = dht.readTemperature();
  humidity = dht.readHumidity();

  //read Soil Moisture
  float value = analogRead(sensor);
  int pre = map(value, wet, dry, 100, 0)+14;

  //read pH
  pHValue = analogRead(pH_sensor);
  pHOutput = (-0.0139*pHValue)+7.7851; //show in lcd

  //variabel data kirim
  String datakirim = "@" + String(pre) + "#" + String(temperature) + "#" + String(humidity) + "#" + String(pHOutput);
  Serial.println(datakirim);
}

And here is my NodeMCU's code

#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
WiFiClient client;
String data;
String arrData[4];
boolean parsing=false;

SoftwareSerial DataSerial(12, 13);

unsigned long previousMillis = 0;
const long interval = 3000;

const char *ssid = "my ssid";
const char *password = "my password";

const char *host = "my host";
HTTPClient http;

void setup() {
  Serial.begin(9600);
  DataSerial.begin(9600);
  data="";

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  Serial.print("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

int value = 0;

void loop() {
  if(Serial.available() > 0)
  {
    char inChar = (char)Serial.read();
    data += inChar;
    if (inChar == '\n') 
    {
      parsing = true;
    }
  }
  if(parsing)
  {
    parsingData();
    parsing=false;
    data="";

    delay(1000);
    ++value;

    Serial.print("Connecting to ");
    Serial.println(host);

    WiFiClient client;
    if(!client.connect(host, 80))
    {
      Serial.println("Connection Failed!");
      return;
    }

    String url = "/coba_sensor/write-data.php?data1=";
    url += arrData[0].toInt();
    url += "&data2=";
    url += arrData[1].toFloat();
    url += "&data3=";
    url += arrData[2].toFloat();
    url += "&data4=";
    url += arrData[3].toFloat();

    Serial.print("Requesting URL: ");
    Serial.println(url);

    client.print(String("GET ") + url + " HTTP/1.1\r\n" + 
                  "Host: " + host + "\r\n" + 
                  "Connection: close\r\n\r\n");
    unsigned long timeout = millis();
    while (client.available() == 0)
    {
      if (millis() - timeout > 1000)
      {
        Serial.println(">>> Client Timeout !");
        client.stop();
        return;
      }
    }

    while (client.available()){
      String line = client.readStringUntil('\r');
      Serial.print(line);
    }
    Serial.println();
    Serial.println("Closing Connection");
  }
}


void parsingData()
{
  unsigned long currentMillis = millis();  //membaca waktu milis saat ini
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;  //update previousMillis

    String data = "";  //baca data serial
    while (DataSerial.available() > 0) {
      data += char(DataSerial.read());
    }
    data.trim();

    int j=0;
    arrData[j]="";
    for(int i=1;i<data.length();i++)
    {
      if((data[i] == '#'))
      {
        j++;
        arrData[j]="";
      }
      else
      {
        arrData[j] = arrData[j] + data[i];
      }
    }
      DataSerial.println("Ya");
  }
}

In the NodeMCU's code, I still haven't added the command for the button because I'm still confused. Please help me. T_T

Thank You!

Your two topics on the same or similar subject have been merged.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum

It will help you get the best out of the forum in the future.

Thank you.

don't see code to detect a button Press

const byte ButtonPin = A1;
byte buttonState;

// -----------------------------------------------------------------------------
void loop ()
{
    byte but = digitalRead (ButtonPin);
    if (buttonState != but)  {      // change
        buttonState = but;
        delay (10);                 // debounce

        if (LOW == but)
            Serial.println (" button pressed");
    }
}

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (9600);

    pinMode      (ButtonPin, INPUT_PULLUP);
    buttonState = digitalRead (ButtonPin);
}

I still haven't given the code to access the button because I'm still confused where I should put the code, whether I should put it in the NodeMCU or in my Arduino.

If it's like this then I put the code to access the button on my Arduino, isn't it? Then what about the data request action that was initially performed by NodeMCU?

why do you have both an Arduino and MCU? how do they communicate? can't the MCU connect to the same devices

on the processor the button is connected to

in your MCU code why do you put client code inside the condition when parsing is true? don't you want it to execute when you haven't received any serial data?

shouldn't the relevant code under the parsing condition only be executed when you've received serial data?

shouldn't you only "connect" once, in setup()?

why are there 2 while loops checking for client available

why is there a timer that delays execution in parsingData()? is this unrelated to Serial input?

if there are multiple sources of input shouldn't loop() be structured and either doing a read() or readBytesUntil()?

void loop ()
{
    if (Serial.available() > 0) {
        char inChar = (char)Serial.read();
        // ...
    }

    if (DataSerial.available() > 0) {
        data += char (DataSerial.read());
        // ...
    }

    if (client.available()){
        String line = client.readStringUntil ('\r');
        // ...
    }
}

I use Arduino cause I need some analog pins in this case. But this Arduino that I used can't directly connect to the internet, that's why I connect My Arduino with NodeMCU using serial communication.

And about the other question, I think you are right, maybe I check again my MCU's code.

you may be better off with a single esp32

I see. Anyway, Thank you.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.