text:
How to connect neo 6m 6pin module with nodemcu v3
I got this neo 6m gps module from a broken drone. and i would like to connect it to nodemcu v3 board.
most of the gps module that i have seen are with 4 pins (vcc,gnd,tx,rx) , but this module has 6 pins (gnd,vcc,txd,rxd,scl,sda) .
i am not sure how to wire it up and what library to use.

Have you read the datasheet for the NEO M6?

@MatsK  i am a just beginner, don't understand much about diagram.

Ok, then just hook up 3 wires like this: GND - GND, Tx - Rx, Rx - Tx. And then start to read this: https://lastminuteengineers.com/neo6m-gps-arduino-tutorial/  NB The NodeMCU is a 3,3 volt device and the url is using a std Arduino, a 5 volt device, please adapt accordingly.

The 4 pins VCC/GND/TX/RX are the same as any other GPS module.
The other two pins, SCL and SDA, are nothing to do with the GPS. They connect to the HMC5883L compass chip.
Use the normal TinyGPS library for the GPS, and a HMC5883L library (such as this one) for the compass.

Rx and tx pin are for UART communication and SCL and SDA are for I2C communication. Most common gps module use UART communication method .... You can go with UART too this will help you to choose better  library option. Most library file are coded for UART method.  I recommend you to use vcc , gnd ,rx and tx pin. Escape scl and sda pins.

The I2C is not connected to the GPS. It's only connected to the HMC5883L.

I have just cleared about communication protocol ...not suggested to use i2c communication


text:
Do Arduino Nano Every devices short out?
I have an Arduino Nano Every device that seems to have shorted out.
I use a lighted USB hub with buttons that turn connections on and off.  Each button has its own LED that indicates power state for its associated port.
Anyway, when I plug my Arduino Nano Every into that USB hub, the lighted buttons turn off for half of the hub, like the Arduino is shorting out the hub.
I use a different Arduino and have no problems, so it's definitely the Arduino.
Any idea what could have caused this?  I was using the Arduino with a TMUX1511 switch chip and using pins  D9-D12 to turn on and off the 4 internal switches in the chip.  It's using very low voltage (5v) and amperage is (25 mA).  I used the 5v and gnd pins on the Arduino to power the TMUX1511 chip, but with such low amperage, I can't see how that could have caused the Arduino to fry.
Any ideas?

Probably you at some time created a short somewhere. Though that is impossible to say for us. We don't see the board and we don't know your exact circuit, that you used. Have you tested the Arduino with a different power source? If yes, was it working there?

I have 5 identical devices that use these Arduino Nano Everys.  Only one has had this problem and it is after it was connected for several weeks.  One day, it just stopped working and when I checked it out, it appeared that the Arduino Nano Every was malfunctioning.  I replaced the Every, and now the defective device works fine.

Still the same answer. You are right that the TMUX chip shouldnt have fried the Arduino. So I can only guess, that something else happened, for example a short, maybe only for a short time. But how should someone find out, what exactly happened? Imagine I would ask you "My car doesn't turn on anymore. I just drove the normal way home. As I drove the way with another car, it worked, so its definitely the car, which has problems. What could have happened?" There are many possible answers to that question. Without information on what exactly happened when the error occurred, nobody can say.

Is there anything connected to the MUX, which you didn't mention?

Just using the Arduino to switch the MUX back and forth between sources.  The MUX is connecting and disconnecting network wires.  Just turning on and off network connectivity, so no major voltage or amperage that would cause the Every to fry...  Maybe I just got a defective one.  I've never had problems with them before.  I guess we'll see on the other 5 devices that I'm using, but they've been fine for the past month with no issues.

this might because of powering issue...try using different source having a good number of current capability. likely up

source: Stack Exchange

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

sort: votes


text:
Estimating CPU load of a task scheduler
First off, I should note that I'm not sure what tags best apply here, and I can't seem to find any that relate to schedulers, etc. Please inform me if they are not the right ones.
I have a simple, portable task scheduler (it only relies on millis(), and runs on different Arduino-supported systems) that is called via a function in loop() and that picks and then runs a function pointer (the "task") from a list of tasks with status, sleep, and priority information.
I would like to have a way to determine and to tell the user how much CPU time is being spent on running tasks vs. being idle.
The problem is that there can be other functions being called from loop(), not just my scheduler. It would thus be a bad idea to track total time vs. time spent in a task. If I did, the CPU use would always read low, since the actual task time cannot use all of the CPU time since the other tasks in loop() would be quietly using some of it.
However, if I specifically track time in the scheduler vs. time spent in task, I run into a new issue. I would use more memory (a few more bytes, but I'm using a lot already...) and more CPU*, since I'd have to keep track of the total so far and also the current runtime for that iteration of the scheduler. That's on top of the similar construct determining the runtime of the task. Mainly, though, the issue is that the loop() function and scheduler run fast enough that the millis() timer can tick slower than the changeover between my scheduler and the loop() function. This causes the timing to also be off, since it would be counted if it ticks in the scheduler even if it was mainly loop()'s fault.
Is there a general methodology for computing the CPU time? It would be difficult to time-slice the scheduler, and that would run slower anyway. I could count the proportion of scheduler calls that run/don't run tasks, but that won't work because tasks take longer than the no-op that happens if a task doesn't run, and it makes no accounting for task length.
*On an AVR system, the 8-bit CPU uses a surprising aggregate time on all those 32-bit operations, between the sleep time calculations (on sleeping tasks only, to be fair) and the elapsed time calculations that fed into my prior CPU use attempt. It wasn't the only cause, but I saw quite a bit of timing slip on one attempt of coding the scheduler because of a similar issue.

Addressing the issue about mills() being too low resolution, you can also use micros() for a microsecond count, though on some Arduino it has 4µs or 8µs resolution and not true microsecond.

I'm considering that, but the same issue can still apply, just not as much. I'm hoping that there's some sort of well-known or popular approach for getting the CPU load that minimizes this, or at least so that mine won't be any worse. It also doesn't answer what's the better approach here for what's less wrong--do I ignore reading too low from including loop() inadvertently, or do I take the overhead and complexity of tracking only the scheduler's runtime, with reading too low for different reasons?

The only metric you have is time. The only thing you can do is compare that time over iterations / task calls. The typical approach is to note the time at the start of a task "tick", and note it at the end. Then add the difference to the total for that task.
When you want to then look at usage percentages you can compare those totals to the total time the system has been running.
The total runtime is already done for you, in the form of millis(), so you don't need to worry about that.
Recording each task's total runtime in microseconds is simple enough, but of course will entail an overhead. That is unavoidable no matter what strategy you take. It's kind of quantum: the act of measuring changes the results.
If you treat your "idle" task the same as any other task (which is the normal way of doing things - the idle task is just a task that does nothing) then the sum of all the time counts for all the tasks = (within a certain granularity) the total amount of time your task scheduler has been running. The difference between that and the system runtime (millis()) is the proportion of the time your scheduler has been running compared to other things happening in loop().
Whether you compare to millis() or micros() for the system runtime is up to you. By storing micros() per task you're getting a reasonable resolution for each tasks's runtime (but with a limit to how long before it wraps - but you can handle that in software by carrying over to another lower resolution counter if you want), but you can then discard some of that resolution when doing your calculations if you don't need it at the time.
Estimating runtime in a co-operative multitasking system like this is never good, and often not bothered with because of that. It's always a guestimate with the results being skewed by the measuring, since the measuring is synchronous with the execution of the tasks.
In a proper context-switching multitasking system you would normally operate on the number of "ticks" of the system rather on time. That is, simply count 1 each time a task is switched in by the context switcher. Since each task has a fixed runtime controlled by the granularity of the scheduler it's then trivial to know that task X has been running for X/TOTAL_TICKS % of the time. Any calculations will be themselves done in a task - maybe the idle task, or a system accounting task.

I think I can get that working. The problem, of course, is that I don't have an idle task; on the event of no task, it simply fails and checks again. It's all in the scheduler itself, not the task. I can't really count zero time, and that skews any measurements I try. But if I can figure out how to make the idle task wait until a task is (almost?) ready, perhaps I can get that working. Or add up the time spent in the scheduler itself, but that's still too small to measure...

The cheapest (in every sense) way I know to display "idleness" is to set an output pin when you enter the scheduler and clear it again when you dispatch a task (other than your idle task, if there is one). Or reverse this, if you want to display load instead. These can be accomplished with a single instruction each. Low impact on your memory, execution time, assembly time, and wallet.
How precisely do you want to report this?

An LED on the output will fade and brighten according to the load. If you need damping (perhaps the load is brief and "peak-y") add an R-C filter to the LED circuit.

Connect a DVM, or even better, a mechanical VOM if you can find one, to the output and read load from the meter. A mechanical meter would do some damping for you. A DVM will probably need the filter from the previous suggestion.

Loop the filtered output back into an analog input and read the load to a precision of ~ 0.1%! That's way more significance than is justified so round it as you see fit.

I can't feasibly use that here, but your idea is quite ingenious. I like it!

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


text:
ISR Issue: Arduino Pro Micro
I'm trying to do a small test where I am using the ISR on the Arduino Pro Micro it up from sleep mode. I'm using a Force Sense Resistor (FSR, a resistor that changes it's resistance depending on how hard you press it) with a voltage divider circuit with the output of the voltage divider connected to an analog pin and the digital interrupt pin. I'm not able to get the interrupt to trigger no matter what condition I have. I don't believe the Vout on the voltage divider is too low since the ADC registers values between 0 to 1000 (0V to about 4.8V) when the FSR is pressed. Is there anything wrong with my code that is preventing my test from working properly?
uint8_t LED = 9;
uint8_t wakeup = 2;
uint8_t enable = 0;

void Wakeup(void);

void setup() {
  // put your setup code here, to run once:
  pinMode(LED, OUTPUT);
  pinMode(wakeup, INPUT);
  attachInterrupt(digitalPinToInterrupt(1), Wakeup, RISING);
  Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  //Serial.println(analogRead(A2));
  if (enable == HIGH)
    digitalWrite(LED, HIGH);
  else if (enable == LOW)
    digitalWrite(LED, LOW);
  if (analogRead(A2) < 700)
    enable = 0;
}

void Wakeup(void) {
  enable = 1;
  Serial.println("Interrupt");
}

perhaps you should not be using the serial port pin for the interrupt

I thought 0 and 1 were serial pins. I'm using digital pin 2

@jsotola it's pro micro with 32U4. it doesn't use pin 2 for serial

please review your code

Don't do serial prints inside an ISR.

Your variable enable should be declared volatile as it changes inside an ISR. The compiler is entitled to cache the variable value if you don't do that.

You are inconsistent in your use of enable. You test for LOW or HIGH but set it to 0 or 1. Now they happen to be the same, but someone might wonder. If you are going to test for LOW or HIGH, then assign LOW or HIGH to it.

See my reference question How do interrupts work on the Arduino Uno and similar boards?.

I thought 0 and 1 were serial pins. I'm using digital pin 2

Not in the code you are not:
attachInterrupt(digitalPinToInterrupt(1), Wakeup, RISING);

Do you mean:
attachInterrupt(digitalPinToInterrupt(wakeup), Wakeup, RISING);

It's kind of confusing to have two names which differ only in case.


text:
Cannot pair HM10 BLE 4.0 module from Android phone
I am currently learning Arduino Bluetooth connectivity with a HM-10S module.
I did some sample tutorial code and it works only with LightBlue app.
However, when I use the default Bluetooth pairing function from the android phone(samsung S10 plus), it seems failed to pair or connect.
So here is the cases I tried:
Android App(LightBlue and also Arduino Bluetooth Controller) :
Success connection without entering password.
Windows 10 PC:
Success pairing only by entering password: "123456", but no com port added
Android phone(S10 plus) Default pairing method from setting
Entered "123456" as password to pair, then no response.
So, what puzzles me is:

I can connect with some apps and do my work, without pairing using Android's setting utility; Is that implies establishing a connection for further action does not necessary to firstly getting things paired?

There are no com port installed after I paired the bt module, so it probably mean the module does not provide my desired feature. If that's the case, which BT module is recommended?

Great thanks if somebody could give me some ideas.

I tried a while ago to connect my HC-06 bluetooth module zo my andriod smartphone. The imortant bit, which I couldnt find anywhere described is, that the pairing doesn't really build up the connection. It sets the settings for the connection and then closes it. I always needed an app (either a bluetooth serial terminal app  or my own self written app) initiating and holding the actual connection. And that makes kind of sense. Where should Andriod send the data, when you don't use it anywhere? Why would it hild the connection then?

On Windows I guess it just creates a serial COM port, which is independent there, even if you don't read it.

I'm not sure, if this also applies to the HM-10S, but it might very well. What are you actually trying, that you want to connect without an app running the connection?

While I did compare the HM10 to HC-06, they are still different technologies and they don't need to behave the same. The HM10 is Bluetooth 4 BLE. It seems it can have different characteristics, also depending on the firmware. When the serial com port characteristic is not active, no com port will show up. Unfortunately I don't have enough experience with the HM10 to guide you there. I have just googled for "HM10 serial bridge" and found this blog entry. Maybe it helps. Otherwise you should try similar searches.


text:
ESP8266, Twilio doesn't send SMS
I've been trying to create SMS alarm using Twilio, Firebase and Arduino IDE. Using sensors I am measuring the temperature. If the temperature is higher than a specified value (ESP reads that value from Firebase Realtime Database), a SMS should be sent using twilio. I am also storing the measures in Firebase Realtime Database. The code worked well, until I tried to add the part where it also pushed measurements (temperatures) to Firebase Realtime Database. It even prints in serial that it is connecting to Twilio api, however, I never receive the message.
Here's my code:
#/*
 * Twilio SMS and MMS on ESP8266 Example.
 */
 #include "FirebaseArduino.h"
#include "OneWire.h"
#include "DallasTemperature.h"
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ESP8266WebServer.h>
#include <sstream>
#include <iostream>
#include "twilio.hpp"

// Use software serial for debugging?
#define USE_SOFTWARE_SERIAL 0

// Print debug messages over serial?
#define USE_SERIAL 1

// Your network SSID and password
const char* ssid="SSID";
const char* password = "PASSWORD";

// Find the api.twilio.com SHA1 fingerprint, this one was valid as
// of July 2020. This will change, please see
// https://www.twilio.com/docs/sms/tutorials/how-to-send-sms-messages-esp8266-cpp
// to see how to update the fingerprint.
const char fingerprint[] = "BC B0 1A 32 80 5D E6 E4 A2 29 66 2B 08 C8 E0 4C 45 29 3F D0";

// Twilio account specific details, from https://twilio.com/console
// Please see the article:
// https://www.twilio.com/docs/guides/receive-and-reply-sms-and-mms-messages-esp8266-c-and-ngrok

// If this device is deployed in the field you should only deploy a revocable
// key. This code is only suitable for prototyping or if you retain physical
// control of the installation.
const char* account_sid = "SID";
const char* auth_token = "TOKEN";

// Details for the SMS we'll send with Twilio.  Should be a number you own
// (check the console, link above).
String to_number    = "+55555";
String from_number = "+66666";
String message_body    = "Hello from Twilio and the ESP8266!";

// The 'authorized number' to text the ESP8266 for our example
String master_number    = "+55555";

// Optional - a url to an image.  See 'MediaUrl' here:
// https://www.twilio.com/docs/api/rest/sending-messages
String media_url = "";

// Global twilio objects
Twilio *twilio;
ESP8266WebServer twilio_server(8000);

//  Optional software serial debugging
#if USE_SOFTWARE_SERIAL == 1
#include <SoftwareSerial.h>
// You'll need to set pin numbers to match your setup if you
// do use Software Serial
extern SoftwareSerial swSer(14, 4, false, 256);
#else
#define swSer Serial
#endif

String b;
int c;
#define FIREBASE_HOST "firebaseio.com"
#define FIREBASE_AUTH ""

#define ONE_WIRE_BUS 4
/********************************************************************/
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
/********************************************************************/
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

float temp1 = 0;

/*
 * Setup function for ESP8266 Twilio Example.
 *
 * Here we connect to a friendly wireless network, set the time, instantiate
 * our twilio object, optionally set up software serial, then send a SMS
 * or MMS message.
 */
void setup() {
        WiFi.begin(ssid, password);
        twilio = new Twilio(account_sid, auth_token, fingerprint);

        #if USE_SERIAL == 1
        swSer.begin(115200);
        while (WiFi.status() != WL_CONNECTED) {
                delay(1000);
                swSer.print(".");
        }
        swSer.println("");
        swSer.println("Connected to WiFi, IP address: ");
        swSer.println(WiFi.localIP());
        #else
        while (WiFi.status() != WL_CONNECTED) delay(1000);
        #endif

        // Response will be filled with connection info and Twilio API responses
        // from this initial SMS send.

        twilio_server.begin();

        // Use LED_BUILTIN to find the LED pin and set the GPIO to output
        pinMode(LED_BUILTIN, OUTPUT);

         sensors.begin();
         Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);

}

/*
 *  In our main loop, we listen for connections from Twilio in handleClient().
 */
void loop() {
  b = Firebase.getString("002/alarm");
  c = b.toInt();
  Serial.print(c);

   sensors.requestTemperatures();
   temp1 = sensors.getTempCByIndex(0);
   StaticJsonBuffer<256> jsonBuffer;
JsonObject& timeStampObject = jsonBuffer.createObject();
timeStampObject[".sv"] = "timestamp";

JsonObject& root = jsonBuffer.createObject();
JsonArray& timestamp = root.createNestedArray("timestamp");
timestamp.add(timeStampObject);
JsonArray& temperature = root.createNestedArray("temperature");
temperature.add(temp1);

Firebase.push("Sensors/001", root);
   if (temp1 > c) {
        String response;
        bool success = twilio->send_message(
                to_number,
                from_number,
                message_body,
                response,
                media_url
        );
   }

          delay(20000);
}

Thanks in advance!

reduce your code to the minimum code that still exhibits the problem ... remove the firebase and the temperature sonsor code ... send only a fixed text SMS

Hi, thanks for your reply! This is the minimum code. If I remove the part in the loop where it pushes the values to Firebase and it only sends a fixed SMS, when the value (temperature) is too high then the SMS gets send. However, I would also need it to push the values to Firebase. Is it possible that NodeMCU Amica V2 is not powerful enough to do that all in one loop?


text:
Problem with serial input from android serial usb app
I'm using two (nrf24L01 + Arduino Uno) nodes to communicate with each other. Serial input from node1 will be sent to node2. A special character 'p' when sent to node2, it will reply that it's available. It is working fine when using arduino ide serial monitor on pc. When I use serial usb app on android to get serial input only the text is sent to another node and the special character sent does nothing and prints like any other message.

Please show your code.

if it works correctly with a PC, then the problem is not with the Arduino .... make sure that the android app is set up correctly

I checked the Android app settings and turned off newline controls. Now everything is working fine.

I solved this problem by turning off CR+LF and selecting None for newline in send section. CR+LF was adding something extra to my input. By removing that program works fine with Android.
About CR,LF :
"Newline is a control character or sequence of control characters in a character encoding specification that is used to signify the end of a line of text and the start of a new one. Some text editors set this special character when pressing the ↵ Enter key." - (Wikipedia)


text:
Counter program
I'm an absolute beginner, and lately I had some problem with this program I was trying to do.
Basically I wanted with the Arduino to count 3 pulses from an oscillator and store the time  of these 3 pulses, but as I said I am a beginner so I have no Idea on how to do it, I would appreciate your help.

Doing what you'd like to do well is an advanced topic that could take a long time to learn. What code have you written so far in your attempts? Please post your efforts (code) thus far. There are many many approaches, many of which are viable, depending on the width and frequency of the pulses you'd like to measure. What is their pulse width, duty cycle, and frequency?

What is "The time of these 3 pulses"? You may want to better define it and start with a simpler version. Like count the time between two 'high' signals. Also, how accurate will you need it to be? Milliseconds or microseconds?

Time counting is easiest done with millis() or micros() (tons of tutorials on the web about them). Though that does not work for high frequency. Please define your exact requirements. What frequency are we talking about? How are the pulses shaped? Do you need to do other things besides that?

get a pencil and paper .... write down what you would do if you had to do the task yourself ... pretend that the pulses are several minutes long and tens of minutes apart .... write down in small, clear steps what you would do ... that becomes pseudo code that can be translated to real code

I had some problem with this program I was trying to do - have you written a program then? Please post it so people can help you with it. (Edit your question to do that).  You might also find helpful this post: How to ask a good question for Arduino Stack Exchange.

While this is likely to need tweaks for your needs, it should get you looking at the right things - millis, interrupts, etc.
Official references at:
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
https://www.arduino.cc/reference/en/language/functions/time/millis/

#define pulsesToStore 3
#define interruptPin 2
volatile unsigned char index;
unsigned long storedTimes[pulsesToStore];

void restartStorage() {
 index = 0;
 attachInterrupt(digitalPinToInterrupt(interruptPin), storeTime, RISING);
}

void storeTime() {
 storedTimes[index] = millis();
 index = index + 1;
 if(index >= pulsesToStore) { //stop storage
  detachInterrupt(digitalPinToInterrupt(interruptPin));
 }
}

void setup() {
 pinMode(interruptPin, INPUT_PULLUP);
 restartStorage();
}

void loop() {
  // does nothing for now.  this is where you would do something with the stored pulses, print to serial, etc.
}

Thanks, I will try it out

Simple code
int pin = 7;
unsigned long duration;

void setup() {
  Serial.begin(9600);
  pinMode(pin, INPUT);
}

void loop() {
long duration = pulseIn(pin, HIGH);
 Serial.println(duration);
//delay(100);
}

Assuming that you are mentioning a squrewave this code mesures the time that squrewave pulse stays in HIGH and prints out in computer serial monitor.
You should send the signal to digital pin 7 (or put any pin you won't modify code int pin = 7;) 5 V HIGH and 0 V LOW.
The time unit measuring in here is in microseconds.
If you won't to measure low then pulseIn(pin, LOW);
I took the example from Arduino official site you can refer more here
https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/
Remember this is the basic example there are other good methods than this...
Analog wave is bit too complex.

That could help, but is there any other way than using a blocking function?


text:
L298N Motor Driver with Nodemcu/ESP32
I have seen a lot tutorials on L298N motor driver with nodemcu and ESP 32, which are 3.3v logic boards where the motordriver is a 5v logic board, now in Arduino while doing speed control 255 means 5v or even a high means 5v but in nodemcu/ESP32 this means 3.3v, so my question is how it will work ?

It's not a question of voltage. You make a basic mis-assumption:

in Arduino while doing speed control 255 means 5v

No, it doesn't.  255 means "Provide a logic HIGH signal all the time".
128 means "Provide a logic HIGH signal 50% of the time".
The 255 (or whatever number) is the "duty cycle" of a PWM signal. That is a digital signal that can be LOW or HIGH which is switching on or off rapidly. The duty cycle defines the ratio of ON time to OFF time.
You're not providing a voltage - you're providing an ON/OFF signal.
As long as the HIGH voltage of that signal is above the threshold of the receiving device (the L298N in this case) then it will see it as an ON/OFF signal.
According to the datasheet for the L298 the HIGH logic threshold (VIH) is 2.3V. That means anything above 2.3V is seen as ON and anyting below that is seen as OFF (actually there is hysteresis, so it has to drop below 1.5V to switch to OFF).
So your 3.3V from the NodeMCU is above that ON threshold, so the ON/OFF PWM signal is received properly as such.
Incidentally, it's because of this PWM signal that motors make a whining sound when they start up slowly. Because of this most proper motor drivers run the PWM at above 25kHz instead of the 500-ish Hz of the Arduino, so that whine is above the threshold of human hearing.

Explained with awesomeness!  :


text:
Is AT command the only way to connect from Arduino to esp2866?
If I am programming an arduino and I wanted to communicate with the internet thru the esp2866 then is AT command the only thing that I can do?
I see a lot of this in the web
void loop() {
 valSensor = getSensorData();
 String getData = "GET /update?api_key="+ API +"&"+ field +"="+String(valSensor);
sendCommand("AT+CIPMUX=1",5,"OK");
 sendCommand("AT+CIPSTART=0,\"TCP\",\""+ HOST +"\","+ PORT,15,"OK");
 sendCommand("AT+CIPSEND=0," +String(getData.length()+4),4,">");
 esp8266.println(getData);delay(1500);countTrueCommand++;
 sendCommand("AT+CIPCLOSE=0",5,"OK");
}

If I set my Board -> Arduino Uno, I was thinking I can use the following library https://arduino-esp8266.readthedocs.io/en/2.7.4_a/esp8266wifi/readme.html
#include <ESP8266WiFi.h>

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

void setup() {
  Serial.begin(115200);
  // We start by connecting to a WiFi network

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

  WiFi.begin(ssid, password);

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

But I am getting
exit status 1
ESP8266WiFi.h: No such file or directory

Looks like the following library is only available when you set the Board-> Generic ESP8266 Module and is only used when you want to program the ESP8266 in the Arduino IDE?  Is this correct?
So in my question, does it mean that to communicate from the Arduino into the internet, I will be sending the AT command and communicate thru the SoftwareSerial.h?

you could use a library which has a nice standard Arduino networking interface over the AT commands. The WiFiEsp library for old AT firmware or my WiFiEspAT for AT 1.7+ https://github.com/jandrassy/WiFiEspAT

is AT command the only thing that I can do?

No. The AT commands are provided by the AT command firmware. You can replace that firmware with whatever you want.
It is common to write your own software for the ESP8266 to do your communication for you and communicate with other devices (including an Arduino) in whatever way is suitable.
Many times you don't even need the Arduino any more as the ESP8266 can do everything (it struggles with analog signals as there is only one rather inferior ADC pin).

Looks like the following library is only available when you set the Board-> Generic ESP8266 Module and is only used when you want to program the ESP8266 in the Arduino IDE? Is this correct?

That is correct. That is for when you are writing your own ESP8266 firmware to replace the AT firmware.

So in my question, does it mean that to communicate from the Arduino into the internet, I will be sending the AT command and communicate thru the SoftwareSerial.h?

Only if you retain the AT firmware on the ESP8266. To be honest that firmware is terrible and all the tutorials are bad. You should at the first available opportunity learn to program the ESP8266 directly and maybe retire the Arduino unless you need to use it as a glorified IO expander.

Thank you very much.  Yes this is where I am very much confused.  I see a lot of google search results like this https://www.instructables.com/id/Using-ESP-01-and-Arduino-UNO/.  and it looks like it is passing only AT commands into the ESP2866.  I am studying this for now so I cannot remove the Arduino in the equation.  But to satisfy my curiosity, if I don't replace the AT firmware then I could only use AT commands right?

Also another question please, I followed the following link https://learn.adafruit.com/adafruit-huzzah-esp8266-breakout/using-arduino-ide and I was able to make it work but my ESP8266  is not from Adafruit.  I noticed that after doing so, the AT commands stop working.  Does it mean that my firmware now is that of the https://arduino-esp8266.readthedocs.io/en/2.7.4_a/esp8266wifi/readme.html?  I am a bit confused on this parts.  I set my ESP board in bootload mode and then uploaded the blink.  After that my AT commands stop working when I used the serial monitor.

The AT firmware only responds to AT commands. That 's what it is and what it does. If you want to use anything other than AT commands then you will have to replace the AT firmware with firmware that responds to the commands you want to send.

Yes, you replaced the AT firmware with your own (adafruit's) custom firmware. You have successfully directly programmed the ESP8266.

Ohh okay so that is why it is not responding to my AT commands anymore.  Just one last thing please.  If I retain my current setup with an Arduino and the custom firmware from the https://arduino-esp8266.readthedocs.io/en/2.7.4_a/esp8266wifi/readme.html in my ESP 8266.  Then how can I connect thru the internet from my Arduino code since AT command is not available anymore.  I could not find any google links to do this.  I always see AT commands.  I spent 2 days reading on this subject for my project.  Thank you very much for your time.

You write your own software for the ESP8266 that accepts commands through serial (which you define) and does things according to those commands.

Oooohh okay... so the logic goes like this.  I program a series of functions in my ESP-8266 like connectToWifi() and in my loop() function I watched for messages from Serial.  What ever messages I received from serial corresponds to the function that I will be calling.  I then burn those program in my ESP.  I go back to Arduino, set the Board to Arduino Uno and in my loop, I will be sending a mesage serially like connectToWifi() and my ESP will received this and call the corresponding function and return it back to the Arduino Uno serially also.  Is this the pattern?

I spent two days already on this and I really don't like the examples in using the AT command.  However there is no documentation that I have seen or I might not be typing the correct search keys that would discuss the logic of defining your custom commands.

Yep, that's the idea.  I have an ESP8266 sketch specifically for MQTT that does that kind of thing: https://github.com/MajenkoProjects/MQTTGateway

The point of defining your own custom commands is they are your commands. You define them how you want to define them and handle them how you want to handle them. They're just bytes arriving over serial.

This is really sweet mate.  I learned so much from you by just several minutes compare to the countless hours I have tried the past two days by trying all those AT commands that I don't like actually.  Thank you very much mate

https://imgflip.com/i/4cihtl ;)

Just out of curiosity, why have I not found any google hits from what you have laid out.  This could really help lots of beginning programmer.  From my perspective as a beginner, I was under the impression that the ESP8266 is just like any normal components with a library that you can call and add to your arduino with a defined API and not those quirky AT commands.  Anyhow than you very much again.

There is the basic assumption that you know the ESP8266 is just a microcontroller that is running firmware that exposes AT commands. Unless you already know that then googling for information is not easy.


text:
ESP32 SPI communication with MCP3903 not working
I am trying to read out the Microchip MCP3903 six channel ADC using an ESP32 via SPI communication. The MCP3903 is powered with 5V and 3,3V and is connected with an external 3,57 MHz crystal. The ESP32 I use is the Olimex ESP32-EVB and the code is uploaded with the Arduino IDE. It works perfectly for other projects, so the ESP seems to be OK.
For the MCP3903 a library exists (https://github.com/mjklopfer/MCP3903) with an example that I am trying to run but nothing is happening. I have tried to use VSPI (GPIO 23, 19,18 and 5) and HSPI (GPIO 13, 12, 14, 15) but I am not getting a CLK signal when I check with the scope. I also tried to alter the code using pointers as suggested here: SPI Digital Potentiometer not working on ESP32, but also that is not changing anything.
You can find the code of the MCP3909 example that I am trying out below. I suppose that when the MCP is not connected, I would still see the CLK running? Is there something special that needs to happen with the GPIOs, like pull-up resistors or something the like? How can I check that the problem is software related or hardware related?
/*
mcp3903example.ino
Arduino example for the MCP3903 - Example tested
Extended from the Arduino Library for MCP3903 A/D Converter
 * MCP3903 Library
 * Kerry D. Wong
 * http://www.kerrywong.com, http://www.kerrywong.com/2014/05/10/mcp3903-library/, https://github.com/kerrydwong/MCP3903) * 5/2014
Minor Arduino Feature extensions by Zhi Luo, Kaixin Chen, Yaxin "Erica" Deng, Yutian Ren, and Michael Klopfer, Ph.D.
University of California, Irvine
2018
*/

#include <SPI.h>
#include "MCP3903.h"

//Set the gains and offsets for your ADC channels:
#define ch0_gain 2.383490972 //these are values for calibration. By setting these values, reads will be the same as the inputs.
#define ch0_offset -0.007884781 //the maximum read for each channel will be around 0.7866. The deviation for these values is around 2%

#define ch1_gain 2.383490972
#define ch1_offset -0.007884781

#define ch2_gain 2.383490972
#define ch2_offset -0.007884781

#define ch3_gain 2.383490972
#define ch3_offset -0.007884781

#define ch4_gain 2.383490972
#define ch4_offset -0.007884781

#define ch5_gain 2.383490972
#define ch5_offset -0.007884781

MCP3903 mymcp3903;  //Initialize mymcp3903 object for the MCP3903

void setup()
{
    //esp.begin(); Needed with ESP8266 for ESP class functions
  Serial.begin(9600); //set serial comm at 9600 bps
  SPI.begin(); //Start SPI
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));  //Start SPI transaction with defined parameters
        mymcp3903.init(10); // (10 for UNO; 15 for esp8266)Setings for your Arduino's/ESP8266's SPI pin used for interfacing(pinCS) - make sure this is the pin you have your CS on!
        mymcp3903.reset(MCP3903::OSR_256);
        mymcp3903.setGain(1,MCP3903::GAIN_8);
  //Need to initialize all channels to use
  SPI.endTransaction(); //End SPI transaction

}

void loop()
{
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));  //Start SPI transaction with defined parameters

  //Print out the ADC value of channel 0
  Serial.print("Channel 0 ADC Value: "); //Start your line here
    double ch0 = mymcp3903.readADC(0);
    double ch0Cal = (ch0* ch0_gain)+ch0_offset;
    Serial.println(ch0Cal);//Add value then end your line
  delay(10);  //Delay before next Ch read (totally optional)

  //Print out the ADC value of channel 1
    Serial.print("Channel 1 ADC Value: "); //Start your line here
    double ch1 = mymcp3903.readADC(1);
    double ch1Cal = (ch1* ch1_gain)+ch1_offset;
    Serial.println(ch1Cal);//Add value then end your line
  delay(10);  //Delay before next Ch read (totally optional)

  //Print out the ADC value of channel 2
    Serial.print("Channel 2 ADC Value: "); //Start your line here
    double ch2 = mymcp3903.readADC(2);
    double ch2Cal = (ch2* ch2_gain)+ch2_offset;
    Serial.println(ch2Cal);//Add value then end your line
  delay(10);  //Delay before next Ch read (totally optional)

  //Print out the ADC value of channel 3
  Serial.print("Channel 3 ADC Value: "); //Start your line here
    double ch3 = mymcp3903.readADC(3);
    double ch3Cal = (ch3* ch3_gain)+ch3_offset;
    Serial.println(ch3Cal);//Add value then end your line
  delay(10);  //Delay before next Ch read (totally optional)

  //Print out the ADC value of channel 4
  Serial.print("Channel 4 ADC Value: "); //Start your line here
    double ch4 = mymcp3903.readADC(4);
    double ch4Cal = (ch4* ch4_gain)+ch4_offset;
    Serial.println(ch4Cal);//Add value then end your line
  delay(10);  //Delay before next Ch read (totally optional)

  //Print out the ADC value of channel 5
  Serial.print("Channel 5 ADC Value: "); //Start your line here
    double ch5 = mymcp3903.readADC(5);
    double ch5Cal = (ch5* ch5_gain)+ch5_offset;
    Serial.println(ch5Cal);//Add value then end your line
  delay(10);  //Delay before next Ch read (totally optional)

    delay(100);  //Delay, then re-run loop to read sensors again
  //SPI.endTransaction(); //End SPI transaction - we are keeping this open for this example
}

I suggest you just reduce your program to using SPI to send a byte repeatedly. Remove the MCP3903 library from the equation.


text:
Controling 5V relay with Wemos D1 R1
I would like to control a 5V relay with Wemos D1 R1 module through webserver. I'm using the following modules:

Tongling 5vdc Relay
Wemos D1 R1

I'm using the following schematic:

and here is the code I'm using:
#include <ESP8266WiFi.h>

const char* ssid = "Myssidname";
const char* password = "Myssidpass";

int ledPin = D3;
WiFiServer server(80);

void setup() {
 Serial.begin(9600);
 delay(10);

 pinMode(ledPin, OUTPUT);
 digitalWrite(ledPin, LOW);

 // Connect to WiFi network
 Serial.println();
 Serial.println();
 Serial.print("Connecting to ");
 Serial.println(ssid);

 WiFi.begin(ssid, password);

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

 // Start the server
 server.begin();
 Serial.println("Server started");

 // Print the IP address
 Serial.print("Use this URL : ");
 Serial.print("http://");
 Serial.print(WiFi.localIP());
 Serial.println("/");

}

void loop() {
 // Check if a client has connected
 WiFiClient client = server.available();
 if (!client) {
   return;
 }

 // Wait until the client sends some data
 Serial.println("new client");
 while(!client.available()){
   delay(1);
 }

 // Read the first line of the request
 String request = client.readStringUntil('\r');
 Serial.println(request);
 client.flush();

 // Match the request

 int value = LOW;
 if (request.indexOf("/LED=ON") != -1) {
   digitalWrite(ledPin, HIGH);
   value = HIGH;
 }
 if (request.indexOf("/LED=OFF") != -1){
   digitalWrite(ledPin, LOW);
   value = LOW;
 }

 // Return the response
 client.println("HTTP/1.1 200 OK");
 client.println("Content-Type: text/html");
 client.println(""); //  do not forget this one
 client.println("<!DOCTYPE HTML>");
 client.println("");

 client.print("Led pin is now: ");

 if(value == HIGH) {
   client.print("On");
 } else {
   client.print("Off");
 }
 client.println("

");
 client.println("Click here Turn relay ON
");
 client.println("Click here Turn relay OFF
");
 client.println("");

 delay(1);
 Serial.println("Client disconnected");
 Serial.println("");

}

After uploading the code successfully and watching the monitor, the light gets turned on and I get the following message:
16:02:20.400 -> WiFi connected
16:02:20.425 -> Server started
16:02:20.479 -> Use this URL : http://192.168.100.7/
16:02:41.680 -> new client
16:02:41.680 -> GET / HTTP/1.1
16:02:41.680 -> Client disconnected

However, when I turn on or off the relay using the browser, nothing happens:
19:38:56.010 -> new client
19:38:56.010 -> GET /LED=ON HTTP/1.1
19:38:56.010 -> Client disconnected
19:38:57.016 -> new client
19:38:57.016 -> GET /LED=OFF HTTP/1.1
19:38:57.063 -> Client disconnected

However nothing happens to the light and relay doesn't click.
a few more notes:

I tried in upload the code with relay at high to disconnect the circuit but light is still on
Wemos Network name appears in my network list
It doesn't not respond to AT Commands

did you in Tools select exactly the  "D1 R1"?

@Juraj  yes the board selected is Wemos D1 R1

Your code should switch off the lamp when starting up (set the relay pin to LOW), but this is not what you experience. Are you sure you connected the lamp correctly (to COM and NO and not COM and NC)? What happens when you connect an LED (through a 200 to 330 ohm resistor) to Pin 3 instead of the relay?

The negative side of the LED should be connected to ground.

@StarCat I replaced the relay with LED with resistor and it just works perfect :)

So, now you know that the pin switches at the correct time, you have confirmation that your code works correctly and the problem is likely with your hardware. I think the fact that you're trying to switch a 5V relay with a 3.3V device might be the problem (see Duncan C's answer).

@StarCat I tried to power the 5V Relay from Arduino UNO R3 by attaching VCC and GND to it and keeping the in wired to Wemos D1 R1 D3 pin, but it didn't work either. Any suggestion to resolve the issue with additional Modules.

The relay likely needs about 5V on the "IN" pin to be able to switch the relay, which it will not get from your Wemos D1 as that is a 3.3V device. If you want to control a relay from your Wemos D1, you need a one that works with 3.3V.

@StarCat Solved by implementing 2N2222 transistor and 5K resistor. Thx for the help

The issue lies with Wemos Module where it only outputs 3.3V which insufficient to 5V Relay so this can be solved by implementing 2N2222 Transistor as per schematic below.

Is the Wemos D1 R1 a 5V board, or 3.3V? If it's a 3.3V board, that's your problem. Get a 3.3V relay.
(From a little digging it looks like the Wemos is a 3.3V device. If so, that is your problem. Those "digital relays" are available in 5V and 3.3V models. Replace your 5V relay with a 3.3V relay.)
What are the current requirements of the relay, and what is the max current you can draw out of the Wemos? How are you powering the Wemos?
I would say break this into pieces and solve them separately. Put a multimeter (OR an LED with a current limiting resistor) on pin D3 and make sure the pin is turning on and off. If it is, it is a problem with your relay. If it's not, it's a problem with your sketch or your Arduino.
If the pin is turning on and off, try attaching the IN pin on your relay directly to +5V. Does your lightbulb light then?

The led is working perfect but for the last recommendation by attaching the in pin to +5V, nothing happens except the bulb turning off as soon as I pulled the wire out of D3

You disconnect the wire from D2 and hook it directly to the +5 (or rather the +3.3v) pin, and the lightbulb does not light? What if you touch that wire to ground? (I'm wondering if you're wired your lightbulb into the normally open (NC) terminal on your relay rather than normally closed (NC).

@DuncanC I wired it to NC and the same thing no response, however light is off now. BTW, I don't hear any clicks from the relay.

A 5V relay requires 5 volts to operate. Your Wemos appears to be a 3.3V device. It only puts out 3.3V on it's logic lines. Get a voltmeter and measure the voltage on pin D3 when it is set to HIGH. I bet dollars to doughnuts it's putting out 3.3V. Buy a 3.3V of your digital relay and use that instead (Assuming your Wemos has enough current out of it's regulator to power the relay.


text:
ESP32 open "captive portal" on connected
I am using the default example SimpleWiFiServer that comes as an example from the ESP32:
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>

#define LED_BUILTIN 2   // Set the GPIO pin where you connected your test LED or comment this line out if your dev board has a built-in LED

// Set these to your desired credentials.
const char *ssid = "MyNetwork";
//const char *password = "YourPassword";

WiFiServer server(80);

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);

  Serial.begin(115200);
  Serial.println();
  Serial.println("Configuring access point...");

  // You can remove the password parameter if you want the AP to be open.

  //tcpip_adapter_dns_info_t dns_info;
  //dns_info.ip.u_addr.ip4.addr = IPAddress(192,168,4,1);
  //tcpip_adapter_set_dns_info(TCPIP_ADAPTER_IF_AP, TCPIP_ADAPTER_DNS_MAIN, &dns_info);

  WiFi.softAP(ssid);
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.begin();

  Serial.println("Server started");
}

void loop() {
  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,
    Serial.println("New Client.");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("Click here to turn ON the LED.
");
            client.print("Click here to turn OFF the LED.
");

            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {    // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /H")) {
          digitalWrite(LED_BUILTIN, HIGH);               // GET /H turns the LED on
        }
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(LED_BUILTIN, LOW);                // GET /L turns the LED off
        }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("Client Disconnected.");
  }
}

That initializes the ESP32 as an Access Point. On my phone I am able to see the network MyNetwork. If I connect to it and then open a my browser and go to 192.168.4.1 I am able to see the default page.
How can I change that code so that when I connect to that network it automatically open my browser going to http://192.168.4.1 ?
When researching on the internet I found this library that does that WiFiManager . That library helps you connect to an existing WiFi network. I do not want to do that. I only want that when I connect to MyNetwork my default page opens up just like when you connect to guest networks on hotels etc.
Other people on the internet have modified WiFiAPP.cpp and added these three lines of code:
tcpip_adapter_dns_info_t dns_info;
dns_info.ip.u_addr.ip4.addr = IPAddress(192,168,4,1);
tcpip_adapter_set_dns_info(TCPIP_ADAPTER_IF_AP, TCPIP_ADAPTER_DNS_MAIN, &dns_info);

That only makes my esp32 crash and does not work.
Has someone figure out a simple way to open a popup window (captive portal) pointing to http://192.168.4.1 once you connect to the ESP32 access point?
Lastly I found this example but that is using esp8266.

How you get things like automatic browser opening on an wifi connection event to happen depends on your operating system. It's not something I have ever heard of. The normal thing to do is set up a "captive portal" that redirects all requests to itself, so you open a browser and wherever you try and go to it responds with the portal page. There's an example in the bundled DNSServer library that does that.

Sorry I meant to say "captive portal" English is not my first language. @Majenko

@Majenko i have an Android v8 phone ... at AP connection it automatically browses to the captive portal page ... my previous phone required manual browsing to any unencrypted (http:) webpage

@jsotola That's usually something the phone does by itself. Apples try opening the page http://captive.apple.com/hotspot-detect.html and if it returns anything other than "Success" it opens the browser for you to log in.

@Majenko♦ i understand that the phone does it on its own ... i misunderstood your first comment ... thanks for the useful apple.com link

Thanks to @Majenko I was able to find what I was looking for on the internet from this link. When I googled "captive portal" instead of the phrases that I was using I found a lot more examples.
This code opens a "captive portal" once I connect to the esp32 access point.
#include <WiFi.h>
#include <DNSServer.h>

const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 1, 1);
DNSServer dnsServer;
WiFiServer server(80);

String responseHTML = ""
  "<!DOCTYPE html><title>CaptivePortal</title>"
  "
Hello World!

This is a captive portal example. All requests will "
  "be redirected here.
";

void setup() {
  WiFi.disconnect();   //added to start with the wifi off, avoid crashing
  WiFi.mode(WIFI_OFF); //added to start with the wifi off, avoid crashing
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP("DNSServer CaptivePortal example");

  // if DNSServer is started with "*" for domain name, it will reply with
  // provided IP to all DNS request
  dnsServer.start(DNS_PORT, "*", apIP);

  server.begin();
}

void loop() {
  dnsServer.processNextRequest();
  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {
    String currentLine = "";
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c == '\n') {
          if (currentLine.length() == 0) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();
            client.print(responseHTML);
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
      }
    }
    client.stop();
  }
}

When providing HTTP server you generally have two options:

Using WebServer class and set handlers for roots. The parsing and handling of HTTP header is done by the library.
Use WifiServer and receive the HTTP message with header included and handler everything by your own.

If you are doing number 1 and pretend using by connecting with an Android device I suggest adding a handler for the error case showing the captive portal:
server.onNotFound(handleRoot);

I noticed that for Android 10, to properly detect the captive portal and make the phone to show "Touch to log in the network" message is necesary. If not you must navigate to any HTTP address and let the DNS do the job for you (not HTTPS).


text:
What is the logic behind Arduino inlining `HardwareSerial::_rx_complete_irq()` for receiving serial data (but NOT `_tx_udr_empty_irq()`)?
Q: What is the logic behind Arduino inlining HardwareSerial::_rx_complete_irq() for receiving serial data (but NOT _tx_udr_empty_irq()), and when is it advisable?
From the bottom of the HardwareSerial class in HardwareSerial.h:
// Interrupt handlers - Not intended to be called externally
inline void _rx_complete_irq(void);  // <======= inline!
void _tx_udr_empty_irq(void);        // <======= NOT inline! Why?

Furthermore, what is the design logic behind putting one of the serial ISR function definitions in a header file vs in a source file? Also, when is this good design and what are the tradeoffs, and when is it illegal or not permitted by the language, compiler or anything else?
Here is the exact scenario that made me think of this question:

See here for the HardwareSerial implementation files: https://github.com/arduino/ArduinoCore-avr/tree/master/cores/arduino
Here is the main header file. https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/HardwareSerial.h
The inline ISR _rx_complete_irq():

Line 138 of "HardwareSerial.h" declares the inline ISR for when serial data is received:
 inline void _rx_complete_irq(void);

This ISR is called whenever "there are unread data present in the receive buffer." (ATmega328 Datasheet 20.7.3 p190)

Line 40 and 48-50 of "HardwareSerial0.cpp" is where the ISR is set up:
   ISR(USART_RX_vect)  // line 40
   {                   // line 48
     Serial._rx_complete_irq();  // line 49
   }                   // line 50

Line 101-121 of "HardwareSerial_private.h" implements the inline _rx_complete_irq() function:
  void HardwareSerial::_rx_complete_irq(void)
  {
    if (bit_is_clear(*_ucsra, UPE0)) {
      // No Parity error, read byte and store it in the buffer if there is
      // room
      unsigned char c = *_udr;
      rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE;

      // if we should be storing the received character into the location
      // just before the tail (meaning that the head would advance to the
      // current location of the tail), we're about to overflow the buffer
      // and so we don't write the character or advance the head.
      if (i != _rx_buffer_tail) {
        _rx_buffer[_rx_buffer_head] = c;
        _rx_buffer_head = i;
      }
    } else {
      // Parity error, read byte but discard it
      *_udr;
    };
  }

The NON-inline ISR _tx_udr_empty_irq():

Line 139 of "HardwareSerial.h" declares the ISR for transmitting serial data: void _tx_udr_empty_irq(void);

This ISR is triggered by the "USART Data Register Empty" flag and is called whenever the transmit buffer has passed its value to the shift register and now is "ready to receive new data" (ATmega328 Datasheet 20.11.2 p200)

Its implementation is on lines 89-113 of "HardwareSerial.cpp"
   void HardwareSerial::_tx_udr_empty_irq(void)
   {
     // If interrupts are enabled, there must be more data in the output
     // buffer. Send the next byte
     unsigned char c = _tx_buffer[_tx_buffer_tail];
     _tx_buffer_tail = (_tx_buffer_tail + 1) % SERIAL_TX_BUFFER_SIZE;

     *_udr = c;

     // clear the TXC bit -- "can be cleared by writing a one to its bit
     // location". This makes sure flush() won't return until the bytes
     // actually got written. Other r/w bits are preserved, and zeroes
     // written to the rest.

   #ifdef MPCM0
     *_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << MPCM0))) | (1 << TXC0);
   #else
     *_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << TXC0)));
   #endif

     if (_tx_buffer_head == _tx_buffer_tail) {
       // Buffer empty, so disable interrupts
       cbi(*_ucsrb, UDRIE0);
     }
   }

Why the difference? Why inline one ISR and not the other?
Again, from the bottom of the HardwareSerial class in HardwareSerial.h:
// Interrupt handlers - Not intended to be called externally
inline void _rx_complete_irq(void);  // <======= inline!
void _tx_udr_empty_irq(void);        // <======= NOT inline! Why?

Why the somewhat complicated set of 3+ files?
Mainly:

HardwareSerial.h
HardwareSerial_private.h
HardwareSerial.cpp

I first documented this to myself and wondered about it on 31 Jan. 2018, while studying the Arduino source code. I'd like to hear some more insight on the topic from other developers.

What is the logic behind Arduino inlining HardwareSerial::_rx_complete_irq() for receiving serial data (but NOT _tx_udr_empty_irq()), and when is it advisable?

There's a couple of reasons which end up with this arrangement:

The RX interrupt has to be fast as we're reacting to an external stimulus. The TX interrupt doesn't have to be fast as it's only used to move data from the buffer to the UART.

We need to be able to respond rapidly to incoming data so we can store it away in the RX ring buffer in time to handle the next byte that arrives. Not really a problem at low baud rates, but when it comes to higher ones every cycle that can be shaved off that interrupt time is beneficial.  The TX interrupt, though, really doesn't matter. All it does is load the next byte into the outgoing UART buffer, and it doesn't matter if that takes a little longer, so there's no need to shave off the extra instruction cycles consumed by making a function call.

The TX interrupt is called from multiple places but the RX isn't.

The RX interrupt code is only ever called when the interrupt fires. That means it's only ever going to be called through one execution path.  However the TX interrupt code is not only called by the interrupt itself, but by other areas of the code. For example, if interrupts are disabled then the write function will manually poll the UART for the buffer state and manually call the interrupt function to send the data (see line 262 of HardwareSerial.cpp).
If the TX interrupt code were inlined then there would be lots of places throughout the code where that block would be duplicated causing code bloat. That's code bloat with no reason (See point 1) so it's something to be avoided.

Furthermore, what is the design logic behind putting one of the serial ISR function definitions in a header file vs in a source file?

Inlining can only be done within a single translation unit. If you want a function to be inlined in multiple translation units (HardwareSerial0.cpp, HardwareSerial1.cpp, etc) then you would have to have it within those translation units. And that means that you need it in the header1. Since the TX interrupt is not wanted to be inlined it can be put in a CPP file instead.

Why the somewhat complicated set of 3+ files?

Simple: management. It's easier to manage the (rather complex UART) code if it's broken down into different areas.  You have a common base object in HardwareSerial.cpp which is then used by the code for each individual UART in the HardwareSerial[0-3].cpp files.  You have a single header file that defines the class and all its methods and data (HardwareSerial.h). And then you have the "private" header with any inline functions in it that is included where it's needed.
True you could merge the HardwareSerial.h and the HardwareSerial_private.h into one, but this way the inline functions are excluded from translation units where they aren't needed. This way you don't get those chunks of code included in your sketch. True the linker will discard them as they're not used, but it's just tidier this way - the functions are only included in those translation units where those function are actually used.

Notes:

This code was written before the compiler had support for Link Time Optimization which allows inlining between translation units. The compiler may have moved on, but there is no point in changing code that works perfectly fine.

and that part was written before LTO was used

Indeed. I did think about mentioning LTO but thought it was probably outside the scope, since it didn't influence the coding style as it didn't exist in the compiler at that time.

the HardwareSerial[0-3].cpp files were an optimization without LTO.


text:
Using HC-08 bluetooth module with arduino
I have an arduino mega 2560 and a recently purchased HC-08 module and the connection is as the following:
Arduino | HC-08
VCC - VCC
GND - GND
14TX3 - TXD
15TX3 - RXD
When I power up the arduino it shows that flashing light and I am able to see it on my android phone but would only reject the connection every time I tried to pair. Also I am not able to send or receive any data from it at all, here is my code:
#include <SoftwareSerial.h>

SoftwareSerial hc08(15,14) // RX pin, TX pin;

void setup(){
  //Initialize Serial Monitor
  Serial.begin(9600);
  Serial.println("ENTER AT Commands:");
  //Initialize Bluetooth Serial Port
  hc08.begin(9600);
}

void loop(){
  //Write data from HC08 to Serial Monitor
  if (hc08.available()){
    Serial.println("Reading from bluetooth");
    Serial.write(hc08.read());
  }

  //Write from Serial Monitor to HC08
  if (Serial.available()){
    Serial.println("Writing to bluetooth");
    hc08.write(Serial.read());
  }
}

I'd really appreciate help on how to get it working.

Don't use SoftwareSerial when you're using the hardware serial pins. For TX3/RX3 use Serial3. In fact, on the 2560 don't use SoftwareSerial at all - there's only certain select pins it will work on.

Could you send a link to any documentation of this so I can see how to use Serial3

I've now seen I can just use Serial1, 2 or 3 just like I would use Serial. Thanks

But there still is the problem with the pairing being rejected.

But now you should be able to see and control the HC-08 through the Arduino to configure the pairing - however that's done on that board (I've never used one).

void setup(){
  //Initialize Serial Monitor
  Serial.begin(9600);
  Serial.println("ENTER AT Commands:");
  //Initialize Bluetooth Serial Port
  Serial3.begin(9600);
}

void loop(){
  //Write data from HC08 to Serial Monitor
  if (Serial3.available()){
    Serial.println("Reading from bluetooth");
    Serial.write(Serial3.read());
  }

  //Write from Serial Monitor to HC08
  if (Serial.available()){
    Serial.println("Writing to bluetooth");
    Serial3.write(Serial.read());
  }
}

ALSO: the HC-08 uses BLE, unlike the HC-05 and HC-06 and so won't exactly connect through the phone's system bluetooth settings.

I think this is the problem on the hardware setting. It should be:
Arduino | HC-08
VCC - VCC
GND - GND
14RX3 - TXD
15TX3 - RXD
Variable declare:
SoftwareSerial hc08(14,15) // RX pin, TX pin;


text:
How to fix serial communication?
I am trying to use serial communication to open and close a Blue Robotics Newton gripper. The gripper works with normal commands, but when I try to use serial communication to control it, it is extremely slow and my commands do not correspond to the action I would like. For example, I'll write a "o" in the serial monitor and the gripper will not open.
Does anyone know what is wrong?
#include "Servo.h"

#define GRIPPER_PWM_PIN   10    // Gripper PWM output pin
#define OPEN_TIME         5.0   // Gripper open time (seconds)
#define CLOSE_TIME        5.0   // Gripper close time (seconds)

#define OPEN_PWM_US       1100  // Gripper open PWM output (us)
#define CLOSE_PWM_US      1900  // Gripper close PWM output (us)
int incomingByte =0; // for incoming serial data
Servo gripper;

void setup() {
 // Attach gripper to proper pin
 gripper.attach(GRIPPER_PWM_PIN);
 Serial.begin(9600); // opens serial port, sets data rate to 9600 bps

}

void loop() {
 if (Serial.available() > 0){
   incomingByte = Serial.read();
   if (incomingByte == 'o')
   {
     // Open the gripper
     gripper.writeMicroseconds(1100);
     // Let the gripper open up (microseconds)
     delay(OPEN_TIME*1000);
   }

   if (incomingByte == 'c')
   {
     // Close the gripper
     gripper.writeMicroseconds(1900);
     // Let the gripper close for a while (microseconds)
     delay(CLOSE_TIME*1000);
   }
 }
}

maybe remove the 5 seconds delays or don't send commands at that time.

Why do you even have this 5 second delay? I don't see any sense in it.

Ok this worked - how do I accept it as an answer!? Many thanks

You have a big 5s delay in your code, right after both serial commands. You don't need a delay there; it does not do anything. But it makes your code unresponsive. So you can simply remove it.
I guess you wanted to do some timed thing there and accidentally left it there.  But in general you should not use any big delay() in any code. As you have seen, it makes your code unresponsive, as the Arduino doesn't do anything during this time. Instead look at the BlinkWithoutDelay example, that comes with the Arduino IDE (Its a really important principle to learn). It uses the millis() function (or alternatively the micros() function) to check, if it is time to do something. If yes, it will execute this, if not, it will exit fast and give the rest of the code an opportunity to execute. Much like you would bake a pizza: You start the baking and then regularly  check the clock, if it is time to take the pizza out. In between you can do other things, like reacting go messages on your phone. Its the same principle, just in code.

Great advice! Thank you very much


text:
Uno to ESP32 - HardwareSerial repeats value on ESP32's side even though Uno is disconnected
I have an Arduino UNO connected to ESP32 through voltage divider with TX0 from Uno to RX2 to ESP32. My goal is to send data from my Uno to my ESP32 through HardwareSerial. Here's my code for the Uno:
void setup() {
Serial.begin(9600);
}

void loop() {
int t = 100;
String myString = String(t);
Serial.println(t);
delay(5000);
}

Here I assign an int to 100 and then cast it to String so I can send it on my ESP32's side. My code for ESP32 is:
#define RXD2 16
#define TXD2 -1

HardwareSerial Serial2(1); // Use UART channel 1

void setup() {
Serial.begin(9600);
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
}

void loop() {
if(Serial2.available() >= 1){
Serial.print("Data received:");
Serial.print(Serial2.readString());
}
}

The serial monitor on ESP's side is printing only "100" on every 5 seconds but if I disconnect the Uno from my Port, the ESP's monitor keeps printing "100" even tho it shouldn't.
However, IF I type Serial.println("100"); then I get "Data received: 100" on ESP's side and if I unplug the Uno, the ESP's monitor doesn't print anything or with other words it works properly. Is there a way I can fix this?

The whole String thing is irrelevant. You're not using it. You're printing the integer. Delete the string rubbish.

you print to Serial. Serial prints to Serial Monitor. on what port is your Serial Monitor listening?

I'm well aware of that but my goal here is to "pass" a variable to the Serial communication. With the String thing, the ESP's side doesn't act properly and that's what I'm trying to fix.

Uno's port is COM3 and ESP's port is COM4 @Juraj

the output you see depends on which COM port is in Serial Monitor, not on code changes. the port changes as you change it for upload

Thank you, I think I fixed my problem now @Juraj


text:
Arduino Micro Breadboard USB Not Connecting
I have been working on getting an Atmega32u4 connected to USB. I lifted the connections from the Arduino Micro schematic for the preliminary schematic shown here. When I connect the chip to USB, the system (Ubuntu 18.04) does not appear to recognize it.
I was able to burn the Caterina-Micro bootloader via my Pololu USB AVR Programmer as well as through ArduinoISP to confirm that everything was uploaded correctly. The following is the output of avrdude using the pololu programmer:

$ avrdude -p m32u4 -P /dev/ttyACM0 -c avrispv2 -U flash:w:Caterina-Micro.hex
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100%
0.00s
avrdude: Device signature = 0x1e9587 (probably m32u4) avrdude: NOTE:
"flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option. avrdude: erasing chip avrdude: reading input file "Caterina-Micro.hex" avrdude:
input file Caterina-Micro.hex auto detected as Intel Hex avrdude:
writing flash (32730 bytes):
Writing | ################################################## | 100%
8.21s
avrdude: 32730 bytes of flash written avrdude: verifying flash memory
against Caterina-Micro.hex: avrdude: load data flash data from input
file Caterina-Micro.hex: avrdude: input file Caterina-Micro.hex auto
detected as Intel Hex avrdude: input file Caterina-Micro.hex contains
32730 bytes avrdude: reading on-chip flash data:
Reading | ################################################## | 100%
6.76s
avrdude: verifying ... avrdude: 32730 bytes of flash verified
avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)
avrdude done.  Thank you.

Using a Saleae Logic Analyzer, I sniffed the following USB communications. It seems to me that the atmega is transmitting properly but not receiving any responses but I am not certain.
I confirmed that the USB cable in use was working by plugging it into an Arduino Micro that I have. System was able to identify Arduino Micro, Arduino Uno and pololu AVRisp.
I am hoping that there is an easily assignable cause to the issues that I am experiencing. If any addition information is required, please ask.

Your title mentions breadboard... how exactly are you building this circuit?

Sorry for being vague on the build. Please find an image of the breadboard (https://www.dropbox.com/s/ljlww8ytaqym3ve/IMG_20200825_123859.jpg?dl=0). A sparkfun 44TQFP breakout was used for the atmega32u4.

Ok. I thought it might be. A breadboard is not a conducive environment for usb. The timing has to be precise and the capacitance of the breadboard is probably skewing your crystal frequency.

Also you should check dmesg for errors when you plug the USB in.

Thank you for your suggestions and solutions. The following is the output of 'dmesg | grep -i usb' after plugging in the board:
[1735217.833561] usb 2-1-port2: attempt power cycle
[1735218.437472] usb 2-1.2: new full-speed USB device number 71 using ehci-pci
[1735218.853479] usb 2-1.2: device not accepting address 71, error -32
[1735218.933476] usb 2-1.2: new full-speed USB device number 72 using ehci-pci
[1735219.349481] usb 2-1.2: device not accepting address 72, error -32
[1735219.349551] usb 2-1-port2: unable to enumerate USB device

Taking capacitance between the crystal and the microcontroller as the most likely issue causing my USB problems, is there a way that the internal oscillator can be used for USB (low speed or high speed)?

No. The internal oscillator is not accurate enough. You need to have the crystal and its capacitors mounted direct on the PCB with the chip. This is why people use the small development boards when working with breadboards.


text:
Arduino nano 33 ble vs ble sense. Power consumption, etc
After working with an Arduino Uno at work, I am looking to buy myself a board for some projects/experiments at home. The nano size seems like a great option, especially the one without soldered headers, as it is very flexible and easy to fit in projects with limited space. More specifically, I am interested in nano 33 ble and nano 33 ble sense.
My question is, apart from price does anyone know of any other disadvantages the sense board might have on comparison to the 33 ble?
Does it consume more power if the sensors are not used in a projects (just from being integrated in the board’s circuit)?
Also, does the light intensity sensor work like an LDR (photoresistor)? E.g. will I be able to do things like turn on LEDs automatically when it is dark, based on the sensor’s readings?

The official page for the Nano 33 BLE Sense mentions various things including the datasheet for the light sensor. That appears to be much more sophisticated than an LDR.
According to the sensor documentation (above):

Upon  power-up,  POR,  the  device  initializes  and  immedi-ately enters the low power SLEEP state. In this operational state  the  internal  oscillator  and  other  circuitry  are  not  active,  resulting  in  ultra-low  power  consumption.

You would have to read the documentation for the other devices to check these things. Personally I haven't used one, and Arduino claim it "is a completely new board". So, you may not find a lot of people that can answer those questions.
Keeping power consumption low is quite a complex field. You need to look at clock speeds, sleep states, peripheral power consumption and so on.


text:
Arduino MKR GSM 1400: Can I tell from code if the power has tripped
Is there a way to tell if an Arduino MKR GSM 1400 has lost power and has to rely on the connected battery?
Ideally, I'd like to do this without adding additional circuitry. Alternatively, can I connect VIn to an analogue input pin?
On the schematic, there are two lines that seem promising. One named VBATT\2.4B that go into PB09 of U1 via a voltage divider and another named VBAT\1.4B. Also the BQ24195L is an I2C device which would probably be connected the the main micro controller.
What I need to do is to send an SMS as soon as the incoming power is lost to notify a user that the power supply has tripped. Does anyone have any code samples?

did you succeed with this? Looking at the suggested library, the (misnamed)  function 'isBattConnected()' returns the DPM_STAT bit from the SystemStatusRegister. I think that this indicates when there is a draw of current from the battery, but I'm not 100% sure about that when I read the spec sheet: (https://www.ti.com/lit/ds/symlink/bq24195l.pdf section 8.3.2.2 Dynamic Power Management) Can you share anything you figured out?

It did work, yes. I'm going to have to dig out the code for this, but yes, there is a call to see if I power was lost and it worked perfectly.

VBATT/2.4B is used for measuring the batter voltage using the internal ADC of the MCU. It can't really tell if the battery is being used or not - except by maybe monitoring it over time and see if the voltage goes up or down.
However the BQ24195 is where all your hope lies.  It has a status register that can tell you all sorts of things.
For example it can tell you if there is incoming power, and what that incoming power is coming from (a USB host, a USB power adaptor, or operating in OTG mode). It can also tell you what the battery is doing - if it's charging, or not for example.
A quick google search throws up this library specifically for the purpose.


text:
Reset a UART connection on a Due
I have a system that involves an Arduino Due connected to a Raspi 4 through UART in which the Due sends a heartbeat signal over UART for the pi to receive and send back as confirmation. One of the events that I need to handle is re-establishing the UART connection between the two devices if the program receiving UART on the pi (or the pi itself) fails for any reason and reboots. At the moment, I have the initial heartbeat working (as long as the pi program starts first) but when I stop the pi program to simulate a fatal error and restart it, the Due doesn't seem to receive heartbeat confirmation until it's reset as well.
Is there a clean way to reset just the one Serial connection from the Arduino script? I thought of using Serial.end() and Serial.begin() but that's really ugly and I'd prefer to avoid it. None of the other Serial library methods seem to provide the ability to reset the connection.
I'm using Serial2 at 115200 baud.
Edit: Including relevant heartbeat code:
#include <DueTimer.h>

bool heartbeat = true;

void rx_heartbeat() {
  int received_data;

  if (Serial2.available() > 0) {
    received_data = Serial2.read();
    heartbeat = true;
    Serial.println("beat");
  }
}

void setup() {
  Serial2.begin(115200);
  Timer1.attachInterrupt(heartbeat_ISR).setFrequency(1).start();
}

void loop() {
  rx_heartbeat();
}

void heartbeat_ISR() {
  if (heartbeat) {
    heartbeat = false;
  } else {
    // no heartbeat returned - stop normal operation
  }
  Serial.println("heart");
  Serial2.write(255);
}

You want to reset the connection, that is to turn it off and back on again.  Why do you think end and then begin isn't a good solution for that?  What's ugly about it?

why do you need to use 115200 baud for a heartbeat?

@Delta_G I could be approaching it very wrong, but the way I was thinking of implementing them would mean that both Serial.end() and Serial.begin() would be executed with every loop iteration. It just seems messy.

@jsotola it's definitely not necessary to have that high of a baud for a heartbeat. It's just my default rate I set for serial connections in general

Why would you do it every loop?  Does the communication need to be reset every loop?  Just reset it when needed, like when you stop getting your heartbeat.

Silly me forgot to actually upload the code that fixed my issue. The code shown in the question is correct and works as intended.


text:
Gamepad connection using Pro Micro(ATMEGA32u4 + HC-05
I have been working on making a HID compatible Gamepad using Pro Micro and HC-05 module. I have successfully configured the class of HC-05 module to appear as an Input device(A gamepad) on my PC without changing the firmware of the HC-05. However, after the bluetooth device gets paired there is no option showing to connect to it. My question is how do I start the blutooth connection?
Note: The class of device calculator tells you the hex for the class of device you want to make.

you said that the device pairs successfuly and it is seen as a gamepad ... that means it is connected ... what option are you trying to find?

@jsotola For audio devices I have to explicitly press a connect button, even after the device is paired(for windows). Also I tried looking for the device in device manager but I couldn't find it there. Maybe I am missing something. I also tried sending a hex message on loop using the arduino but still nothing. The message was, "0xFD 0x06 0x00 0x00 0x00 0x00 0x55 0xAA" as I saw on a blog.

This link helps you to connect the Gamepad to the pc - https://mitxela.com/projects/bluetooth_hid_gamepad

@MojtabaJahaniDarestani I've actually tried that blog before. Unfortunately the RN42 firmwares available online aren't compatible with any of my three different HC-05s. And after seeing that I could alter the class of BT device from the base HC-05 firmware I thought maybe I won't have to flash another firmware and someone might have figured it out.


text:
Keypad as game input device?
I have been trying to get a button matrix to work but im not experienced enough in programming.
I Have tried to read up but i don't know how to execute so some help would be greatly appreciated.
I want the keypad to function as a game controller of sorts. when i pres the 1 key on the keypad i want the read light to light up and only go out when i release the button. code was copied from "mstanley" on arduino forum.
Q: How do i use the Keypad.h library to get my keypad press to run one line of code when i press a button and another line when i release the button.
I Was testing with leds now, the code is identical, digitalWrite(1, HIGH); then digitalWrite(1, LOW); this can easily get exchanged for joystic.PressButton 1 and Joystick.ReleaseButton 1

#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {9,8,7,6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5,4,3,2}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

char holdKey;
unsigned long t_hold;

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

  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
}

void loop(){
  char key = keypad.getKey();

   if (key){
     holdKey = key;
     Serial.println(key);
   }

   if (keypad.getState() == HOLD) {
      if ((millis() - t_hold) > 100 ) {
          switch (holdKey) {
              case '1':
                  digitalWrite(11, HIGH);
                  delay(200);
                  digitalWrite(11, LOW);
                  break;
              case '2':
                  digitalWrite(12, HIGH);
                  delay(200);
                  digitalWrite(12, LOW);
                  break;
              case '3':
                  digitalWrite(13, HIGH);
                  delay(200);
                  digitalWrite(13, LOW);
          }
          t_hold = millis();
      }
   }
}

What do you mean by "game input device"? Do you want to use it as gamepad for your PC? Or is this just about the LEDs?

I Was testing with leds now, the code is identical,
digitalWrite(1, HIGH); then digitalWrite(1, LOW); this can easily get exchanged for joystic.PressButton 1 and Joystick.releasebutton 1

do you have a question? ... it is unclear what problem you are having

sorry it was unclear. Q: How do i use the Keypad.h library to get my keypad press to run one line of code when i press a button and another line when i release the button.

I did a post about keypad handlers. I'm reluctant to mention it because we aren't supposed to post "link only" answers.
It refers to a library available on GitHub which handles keypads. In particular you can have a callback function for both the keydown and the keyup, for multiple keys.

How do i use the Keypad.h library to get my keypad press to run one line of code when i press a button and another line when i release the button.

That seems to be what you want to do.
Example code:
/*
 *
 * Example of using Keypad_Matrix with a 4x4 keypad matrix.
 *
 */

#include <Keypad_Matrix.h>

const byte ROWS = 4;
const byte COLS = 4;

// how the keypad has its keys laid out
const char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'},
};

const byte rowPins[ROWS] = {6, 7, 8, 9}; //connect to the row pinouts of the keypad
const byte colPins[COLS] = {2, 3, 4, 5}; //connect to the column pinouts of the keypad

  // Create the Keypad
Keypad_Matrix kpd = Keypad_Matrix( makeKeymap (keys), rowPins, colPins, ROWS, COLS );

void keyDown (const char which)
  {
  Serial.print (F("Key down: "));
  Serial.println (which);
  }

void setup()
{
  Serial.begin (115200);
  Serial.println ("Starting.");
  kpd.begin ();
  kpd.setKeyDownHandler (keyDown);
}

void loop()
{
  kpd.scan ();
  // do other stuff here
}

You can also use setKeyUpHandler to do another function when a key is released. You can also call isKeyDown to see if a key is down (eg. when pressing key A is key B also down?).
Note that (as mentioned in the linked post) you need to use diodes to stop having false (ghost) key presses if more than two keys are pressed at once.

Hi! Thank you for the answer!

How do i use the Keypad.h library to get my keypad press to run one
line of code when i press a button and another line when i release the
button

Edit 1:
void loop() {
  char key = keypad.getKey();

  if (key != NO_KEY) {
    Serial.println(key);
  }

  if (keypad.isPressed('*'))
  {
  randomr = random(10, 2000);
  Serial.println(randomr);
  }

}

From the link: https://playground.arduino.cc/Code/Keypad/ you can find all the functions supported by the Keypad library.
One relevant function is
KeyState getState()

It returns the current state of any of the keys.
The four states supported are IDLE, PRESSED, RELEASED, and HOLD.
Hence you can use this function for the keys you are interested in.
Also, if helpful consider this function as well.
setHoldTime(unsigned int time)

Set the number of milliseconds the user will have to hold a button until the HOLD state is triggered.

You can find the keypad.h library in action here. I motivate you to also try the code with this online Arduino emulator
you already have a builtin function defined to get the status of the key pressed
void loop() {
  char key = keypad.getKey();

  if (key != NO_KEY) {
    Serial.println(key);
  }
}

I have a poorly taken screenshot for the same for your quick reference.
Original Arduino emulator link: (you can play with the logic)

https://wokwi.com/playground/keypad

Disclosure: I use wokwi.com, to create interesting tools and libraries for the Arduino community
https://github.com/wokwi
for a more free demonstration of the libraries:
https://github.com/wokwi/arduino-libraries

Hi! Thank you for your answer. im aware och the KeyState getState() command but i do not understand how to implement it in code. i have not found an example that shows it doing what i'm after. in kombination wit the keyStateChanged() komand i feel like it should definitely be possible.

@OpticalOpal I will get back to you with an example


text:
ESP32 start BLE after deep sleep
I'm new to using the esp32 as a microcontroller. I'm currently working on a so-to-say remote control. Since I want to use the esp32 with an external battery I need to put it in deep-sleep after I pressed some buttons to preserve battery.
All that works fine I've connected a small touchpad to put the esp32 into deep sleep mode using the esp_deep_sleep_start() function . The controller itself goes to sleep and can be woken up using the following 2 lines:
  touchAttachInterrupt(T0, wakeCallback, TOUCH_THRESHOLD);
  esp_sleep_enable_touchpad_wakeup();

In order to communicate with my Raspberry Pi 'Base Station' I decided to use BLE.
My server is configured the following way (where bleServer, bleCharacteristic and bleService are global variables):
  BLEDevice::init("esp-32-remote");
  bleServer = BLEDevice::createServer();
  bleServer->setCallbacks(new ServerCallbacks());

  bleService = bleServer->createService(SERVICE_UUID);
  bleCharacteristic = bleService->createCharacteristic(
                        CHARACTERISTIC_UUID,
                        BLECharacteristic::PROPERTY_READ |
                        BLECharacteristic::PROPERTY_WRITE
                      );

  bleCharacteristic->addDescriptor(new BLE2902());
  bleService->start();

  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();

Upon regular restart using the buttons everything works fine. I can connect to the device using python and the bluepy library.
If I now wake the controller I can't do anything anymore. The setup() function gets called and there are no errors, nor does the controller crash due to any code errors (seemingly).
Then the loop function gets called once, and thats it. I can't connect to the device anymore until I press the hardware reset button.
The questions that arise are:

might there be some error in the way I shutdown the bluetooth module?
Does the loop function work after being woken up from deep sleep?

Maybe one of you has an idea regarding my issue. If there are more information that I need to provide, don't hesitate to tell me, I'm new to the whole mcu topic and I don't know whats best to provide here.

Does the loop function work after being woken up from deep sleep? YES
loop function isn't magical.  its just a function that gets called over and over.  In other words, if it gets called once, it can be called again except if

it did something to deactivate itself
never reached the end

during that first call.  Check that you are not activating some sort of state inside the loop or going into a blocking call awaiting a signal that is never sent.
For good measure, make sure to reset all your variables to their expected states - expecting something to be 0 or set via the original definition may be insufficient.  This is something that occurs on a power reset so if reset is making it work again, thats a likely culprit.  Use a bare minimum of code in the loop for debug so you can figure it out.

Thanks for the answer I'll look into that.
Do you have any recommendation regarding the BLE issue?

I do not at this time.  I did read that a "the TV Begone remote control" intentionally went to a sleep without wake upon sending a power off signal, and tied into the reset button for waking again, so be careful what you copy and from where.  https://www.gammon.com.au/power

There's a good tutorial here on how to connect the BLE server client to the ESP32. And a Good fix here for reconnection issues.
Below is a piece of prototype code I wrote for BLE server client connectivity:
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      deviceDisconnected=false;
      interface->onBoardLED->led[0] = interface->onBoardLED->LED_GREEN;
      interface->onBoardLED->statusLED(100, 1);
      BLEDevice::startAdvertising();
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      interface->onBoardLED->led[0] = interface->onBoardLED->LED_BLUE;
      interface->onBoardLED->statusLED(100, 1);
      interface->onBoardLED->led[0] = interface->onBoardLED->LED_BLUE;
      interface->onBoardLED->statusLED(100, 1);
      interface->onBoardLED->led[0] = interface->onBoardLED->LED_BLUE;
      interface->onBoardLED->statusLED(100, 1);
      pServer->getAdvertising()->start();
    }
};

class pCharacteristicTX_Callbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();

      if (rxValue.length() > 0) {
        String msg="";
        mserial->printStrln("*********");
        mserial->printStr("Received Value: ");
        for (int i = 0; i < rxValue.length(); i++) {
           msg=msg+String(rxValue[i]);
           mserial->printStr(String(rxValue[i]));
        }

        mserial->printStrln("");
        mserial->printStrln("*********");

        //valueReceived=msg;
      }
    }

    void onRead(BLECharacteristic *pCharacteristic) {
      mserial->printStrln("*********");
      mserial->printStr("onRead...");
      pCharacteristic->setValue("OK");
    }

  };

class pCharacteristicRX_Callbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();

      mserial->ble=false;

      if (rxValue.length() > 0) {
        String msg="";
        mserial->printStr("Received Value: ");
        for (int i = 0; i < rxValue.length(); i++) {
           msg=msg+String(rxValue[i]);
           mserial->printStr(String(rxValue[i]));
        }

        msg.trim();
        $BLE_CMD=msg;
        mserial->ble=true;
        newCMDarrived=true;
      }
    }

    void onRead(BLECharacteristic *pCharacteristic) {
      mserial->printStrln("*********");
      mserial->printStr("onRead...");
      pCharacteristic->setValue("OK");
    }

  };

//------------------------------------------------------------------

// Create the BLE Device
  BLEDevice::init("Smart Concrete Curing");  // Give it a name

  // Create the BLE Server
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  // Create the BLE Service
  pService = pServer->createService(SERVICE_UUID);

  // Create a BLE Characteristic

  pCharacteristicTX = pService->createCharacteristic(
                      CHARACTERISTIC_UUID_TX,
                      BLECharacteristic::PROPERTY_NOTIFY
                    );

  pCharacteristicTX->addDescriptor(new BLE2902());

  pCharacteristicRX = pService->createCharacteristic(
                      CHARACTERISTIC_UUID_RX,
                      BLECharacteristic::PROPERTY_READ   |
                      BLECharacteristic::PROPERTY_WRITE  |
                      BLECharacteristic::PROPERTY_NOTIFY |
                      BLECharacteristic::PROPERTY_INDICATE
                    );

  pCharacteristicTX->setCallbacks(new pCharacteristicTX_Callbacks());
  pCharacteristicRX->setCallbacks(new pCharacteristicRX_Callbacks());

  interface->init_BLE(pCharacteristicTX);

  // Start the service
  pService->start();

on this particular code, I'm using light sleep , so to go to sleep :
      btStop();
      delay(1000);
      WiFi.disconnect(true);
      WiFi.mode(WIFI_OFF);

      changeMcuFreq(interface, interface->MIN_MCU_FREQUENCY);

and to wake up :
changeMcuFreq(interface, interface->WIFI_FREQUENCY);
btStart();


text:
A word after function arguments braces
I'm just reading through a header files for task code in ESP8266 SDK.
I found this line and wondering what does the word PRIVILEGED_FUNCTION after the function arguments braces means ?
void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION;

PRIVILEGED_FUNCTION is defined here, but why it's used after the function braces ?
/* Ensure API functions go in the privileged execution section. */
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))

That's impossible to tell without looking in the source code for that SDK.
However it will just be a pre-processor macro which probably expands out to one or more attributes, some of which may be specific to the XTensa LX106 compiler.

Update after your edit:
It places the function in the privileged_function section. That section is then placed into a specific area of memory by the linker.
To further examine what it does you will have to look in the linker script to see how it handles that section, and what that means from the chip's perspective, by cross-referencing that with the chip's technical datasheet.

OK, let me check where that word is defined.

I edited the post.

Yep, you're right #include <xtensa/config/core.h> #include <xtensa/tie/xt_interrupt.h> #include <xtensa/tie/xt_timer.h> it's xtensa.

Replay to your answer: Thanks for the explanation. But my question also is about the method of putting something after function braces in C programming rules. What does that method called ?

It’s called writing code.

It's called adding attributes to a function prototype. They can go anywhere in the prototype.

@Majenko .. dude, thank you so much. I just feel honored that you reply to me. Thanks again !

So, it can be also like this: void vTaskDelay PRIVILEGED_FUNCTION( const TickType_t xTicksToDelay ); ? That I can add this attribute, before after the name of the function or even after the braces of function parameters, right ?

@R1S8K yep, that's right.