message:
ESP32 on Arduino IDE: Identify the board type in code (preprocessor macro)

I have read the answers on [this post][1], but they do not seem to be providing a solution for ESP32 boards.

Is there a way to get the .name that is used from the boards.txt without modifying the platform.txt?

for example for uno there is uno.name=Arduino Uno
for esp32 esp32wrover.name=ESP32 Wrover Module

For ESP32 I can only find .name having the specific board name

This is a sample of the first 2 boards defined in boards.txt for esp332

    menu.UploadSpeed=Upload Speed
 menu.CPUFreq=CPU Frequency
 menu.FlashFreq=Flash Frequency
 menu.FlashMode=Flash Mode
 menu.FlashSize=Flash Size
 menu.PartitionScheme=Partition Scheme
 menu.DebugLevel=Core Debug Level
 menu.PSRAM=PSRAM
 menu.Revision=Board Revision

 ##############################################################
 ### DO NOT PUT BOARDS ABOVE THE OFFICIAL ESPRESSIF BOARDS! ###
 ##############################################################

 esp32.name=ESP32 Dev Module

 esp32.upload.tool=esptool_py
 esp32.upload.maximum_size=1310720
 esp32.upload.maximum_data_size=327680
 esp32.upload.wait_for_upload_port=true

 esp32.serial.disableDTR=true
 esp32.serial.disableRTS=true

 esp32.build.mcu=esp32
 esp32.build.core=esp32
 esp32.build.variant=esp32
 esp32.build.board=ESP32_DEV

 esp32.build.f_cpu=240000000L
 esp32.build.flash_size=4MB
 esp32.build.flash_freq=40m
 esp32.build.flash_mode=dio
 esp32.build.boot=dio
 esp32.build.partitions=default
 esp32.build.defines=

 esp32.menu.PSRAM.disabled=Disabled
 esp32.menu.PSRAM.disabled.build.defines=
 esp32.menu.PSRAM.enabled=Enabled
 esp32.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue

 esp32.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
 esp32.menu.PartitionScheme.default.build.partitions=default
 esp32.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
 esp32.menu.PartitionScheme.defaultffat.build.partitions=default_ffat
 esp32.menu.PartitionScheme.default_8MB=8M Flash (3MB APP/1.5MB FAT)
 esp32.menu.PartitionScheme.default_8MB.build.partitions=default_8MB
 esp32.menu.PartitionScheme.default_8MB.upload.maximum_size=3342336
 esp32.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS)
 esp32.menu.PartitionScheme.minimal.build.partitions=minimal
 esp32.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS)
 esp32.menu.PartitionScheme.no_ota.build.partitions=no_ota
 esp32.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
 esp32.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS)
 esp32.menu.PartitionScheme.noota_3g.build.partitions=noota_3g
 esp32.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576
 esp32.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS)
 esp32.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat
 esp32.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152
 esp32.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS)
 esp32.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat
 esp32.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576
 esp32.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS)
 esp32.menu.PartitionScheme.huge_app.build.partitions=huge_app
 esp32.menu.PartitionScheme.huge_app.upload.maximum_size=3145728
 esp32.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
 esp32.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
 esp32.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
 esp32.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FAT)
 esp32.menu.PartitionScheme.fatflash.build.partitions=ffat
 esp32.menu.PartitionScheme.fatflash.upload.maximum_size=2097152
 esp32.menu.PartitionScheme.app3M_fat9M_16MB=16M Flash (3MB APP/9MB FATFS)
 esp32.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB
 esp32.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728

 esp32.menu.CPUFreq.240=240MHz (WiFi/BT)
 esp32.menu.CPUFreq.240.build.f_cpu=240000000L
 esp32.menu.CPUFreq.160=160MHz (WiFi/BT)
 esp32.menu.CPUFreq.160.build.f_cpu=160000000L
 esp32.menu.CPUFreq.80=80MHz (WiFi/BT)
 esp32.menu.CPUFreq.80.build.f_cpu=80000000L
 esp32.menu.CPUFreq.40=40MHz (40MHz XTAL)
 esp32.menu.CPUFreq.40.build.f_cpu=40000000L
 esp32.menu.CPUFreq.26=26MHz (26MHz XTAL)
 esp32.menu.CPUFreq.26.build.f_cpu=26000000L
 esp32.menu.CPUFreq.20=20MHz (40MHz XTAL)
 esp32.menu.CPUFreq.20.build.f_cpu=20000000L
 esp32.menu.CPUFreq.13=13MHz (26MHz XTAL)
 esp32.menu.CPUFreq.13.build.f_cpu=13000000L
 esp32.menu.CPUFreq.10=10MHz (40MHz XTAL)
 esp32.menu.CPUFreq.10.build.f_cpu=10000000L

 esp32.menu.FlashMode.qio=QIO
 esp32.menu.FlashMode.qio.build.flash_mode=dio
 esp32.menu.FlashMode.qio.build.boot=qio
 esp32.menu.FlashMode.dio=DIO
 esp32.menu.FlashMode.dio.build.flash_mode=dio
 esp32.menu.FlashMode.dio.build.boot=dio
 esp32.menu.FlashMode.qout=QOUT
 esp32.menu.FlashMode.qout.build.flash_mode=dout
 esp32.menu.FlashMode.qout.build.boot=qout
 esp32.menu.FlashMode.dout=DOUT
 esp32.menu.FlashMode.dout.build.flash_mode=dout
 esp32.menu.FlashMode.dout.build.boot=dout

 esp32.menu.FlashFreq.80=80MHz
 esp32.menu.FlashFreq.80.build.flash_freq=80m
 esp32.menu.FlashFreq.40=40MHz
 esp32.menu.FlashFreq.40.build.flash_freq=40m

 esp32.menu.FlashSize.4M=4MB (32Mb)
 esp32.menu.FlashSize.4M.build.flash_size=4MB
 esp32.menu.FlashSize.8M=8MB (64Mb)
 esp32.menu.FlashSize.8M.build.flash_size=8MB
 esp32.menu.FlashSize.8M.build.partitions=default_8MB
 esp32.menu.FlashSize.2M=2MB (16Mb)
 esp32.menu.FlashSize.2M.build.flash_size=2MB
 esp32.menu.FlashSize.2M.build.partitions=minimal
 esp32.menu.FlashSize.16M=16MB (128Mb)
 esp32.menu.FlashSize.16M.build.flash_size=16MB

 esp32.menu.UploadSpeed.921600=921600
 esp32.menu.UploadSpeed.921600.upload.speed=921600
 esp32.menu.UploadSpeed.115200=115200
 esp32.menu.UploadSpeed.115200.upload.speed=115200
 esp32.menu.UploadSpeed.256000.windows=256000
 esp32.menu.UploadSpeed.256000.upload.speed=256000
 esp32.menu.UploadSpeed.230400.windows.upload.speed=256000
 esp32.menu.UploadSpeed.230400=230400
 esp32.menu.UploadSpeed.230400.upload.speed=230400
 esp32.menu.UploadSpeed.460800.linux=460800
 esp32.menu.UploadSpeed.460800.macosx=460800
 esp32.menu.UploadSpeed.460800.upload.speed=460800
 esp32.menu.UploadSpeed.512000.windows=512000
 esp32.menu.UploadSpeed.512000.upload.speed=512000

 esp32.menu.DebugLevel.none=None
 esp32.menu.DebugLevel.none.build.code_debug=0
 esp32.menu.DebugLevel.error=Error
 esp32.menu.DebugLevel.error.build.code_debug=1
 esp32.menu.DebugLevel.warn=Warn
 esp32.menu.DebugLevel.warn.build.code_debug=2
 esp32.menu.DebugLevel.info=Info
 esp32.menu.DebugLevel.info.build.code_debug=3
 esp32.menu.DebugLevel.debug=Debug
 esp32.menu.DebugLevel.debug.build.code_debug=4
 esp32.menu.DebugLevel.verbose=Verbose
 esp32.menu.DebugLevel.verbose.build.code_debug=5

 ##############################################################

 esp32wrover.name=ESP32 Wrover Module

 esp32wrover.upload.tool=esptool_py
 esp32wrover.upload.maximum_size=1310720
 esp32wrover.upload.maximum_data_size=327680
 esp32wrover.upload.wait_for_upload_port=true

 esp32wrover.serial.disableDTR=true
 esp32wrover.serial.disableRTS=true

 esp32wrover.build.mcu=esp32
 esp32wrover.build.core=esp32
 esp32wrover.build.variant=esp32
 esp32wrover.build.board=ESP32_DEV

 esp32wrover.build.f_cpu=240000000L
 esp32wrover.build.flash_size=4MB
 esp32wrover.build.flash_freq=40m
 esp32wrover.build.flash_mode=dio
 esp32wrover.build.boot=dio
 esp32wrover.build.partitions=default
 esp32wrover.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue

 esp32wrover.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
 esp32wrover.menu.PartitionScheme.default.build.partitions=default
 esp32wrover.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
 esp32wrover.menu.PartitionScheme.defaultffat.build.partitions=default_ffat
 esp32wrover.menu.PartitionScheme.default_8MB=8M Flash (3MB APP/1.5MB FAT)
 esp32wrover.menu.PartitionScheme.default_8MB.build.partitions=default_8MB
 esp32wrover.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS)
 esp32wrover.menu.PartitionScheme.minimal.build.partitions=minimal
 esp32wrover.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS)
 esp32wrover.menu.PartitionScheme.no_ota.build.partitions=no_ota
 esp32wrover.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
 esp32wrover.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS)
 esp32wrover.menu.PartitionScheme.noota_3g.build.partitions=noota_3g
 esp32wrover.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576
 esp32wrover.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS)
 esp32wrover.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat
 esp32wrover.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152
 esp32wrover.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS)
 esp32wrover.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat
 esp32wrover.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576
 esp32wrover.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS)
 esp32wrover.menu.PartitionScheme.huge_app.build.partitions=huge_app
 esp32wrover.menu.PartitionScheme.huge_app.upload.maximum_size=3145728
 esp32wrover.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
 esp32wrover.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
 esp32wrover.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
 esp32wrover.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FAT)
 esp32wrover.menu.PartitionScheme.fatflash.build.partitions=ffat

 esp32wrover.menu.FlashMode.qio=QIO
 esp32wrover.menu.FlashMode.qio.build.flash_mode=dio
 esp32wrover.menu.FlashMode.qio.build.boot=qio
 esp32wrover.menu.FlashMode.dio=DIO
 esp32wrover.menu.FlashMode.dio.build.flash_mode=dio
 esp32wrover.menu.FlashMode.dio.build.boot=dio
 esp32wrover.menu.FlashMode.qout=QOUT
 esp32wrover.menu.FlashMode.qout.build.flash_mode=dout
 esp32wrover.menu.FlashMode.qout.build.boot=qout
 esp32wrover.menu.FlashMode.dout=DOUT
 esp32wrover.menu.FlashMode.dout.build.flash_mode=dout
 esp32wrover.menu.FlashMode.dout.build.boot=dout

 esp32wrover.menu.FlashFreq.80=80MHz
 esp32wrover.menu.FlashFreq.80.build.flash_freq=80m
 esp32wrover.menu.FlashFreq.40=40MHz
 esp32wrover.menu.FlashFreq.40.build.flash_freq=40m

 esp32wrover.menu.UploadSpeed.921600=921600
 esp32wrover.menu.UploadSpeed.921600.upload.speed=921600
 esp32wrover.menu.UploadSpeed.115200=115200
 esp32wrover.menu.UploadSpeed.115200.upload.speed=115200
 esp32wrover.menu.UploadSpeed.256000.windows=256000
 esp32wrover.menu.UploadSpeed.256000.upload.speed=256000
 esp32wrover.menu.UploadSpeed.230400.windows.upload.speed=256000
 esp32wrover.menu.UploadSpeed.230400=230400
 esp32wrover.menu.UploadSpeed.230400.upload.speed=230400
 esp32wrover.menu.UploadSpeed.460800.linux=460800
 esp32wrover.menu.UploadSpeed.460800.macosx=460800
 esp32wrover.menu.UploadSpeed.460800.upload.speed=460800
 esp32wrover.menu.UploadSpeed.512000.windows=512000
 esp32wrover.menu.UploadSpeed.512000.upload.speed=512000

 esp32wrover.menu.DebugLevel.none=None
 esp32wrover.menu.DebugLevel.none.build.code_debug=0
 esp32wrover.menu.DebugLevel.error=Error
 esp32wrover.menu.DebugLevel.error.build.code_debug=1
 esp32wrover.menu.DebugLevel.warn=Warn
 esp32wrover.menu.DebugLevel.warn.build.code_debug=2
 esp32wrover.menu.DebugLevel.info=Info
 esp32wrover.menu.DebugLevel.info.build.code_debug=3
 esp32wrover.menu.DebugLevel.debug=Debug
 esp32wrover.menu.DebugLevel.debug.build.code_debug=4
 esp32wrover.menu.DebugLevel.verbose=Verbose
 esp32wrover.menu.DebugLevel.verbose.build.code_debug=5

  [1]: https://arduino.stackexchange.com/questions/21137/arduino-how-to-get-the-board-type-in-code

body:
As I guess you mean the preprocessor defines to distinguish between different boards and include/exclude based on this different code parts.
In ArduinoIDE except from

     #ifdef ESP32
     const uint8_t pinA = 12;
     #endif

no luck as of core 1.04, because there are no preproc macros defined (like in other architectures).
If you are using PlatformIO you can get the board type from the define ARDUINO_BOARD.

On ArduinoIDE you only can write your own macros (but this only solves the problem for your dev environment)
So as of core 1.04 you can only do it manually by un/commenting defines:

    /** Choose the correct model to use and compile the right pin settings*/
    #define AI_THINKER_KIT
    //#define WROVER_DEV_KIT
    //#define ESP_EYE_32
    //#define M5STACK_PSRAM
    //#define M5STACK_NO_PSRAM

As an example the build.board property for SAM Boards is:

    adafruit_itsybitsy_m0.build.board=ITSYBITSY_M0

Then in the Adafruit SAMD Boards platform.txt file you can see where the macro is defined:

    ## Compile c files
    recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {build.cache_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"

    ## Compile c++ files
    recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {build.cache_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"

    ## Compile S files
    recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {build.cache_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"

If you want to dig intoit deeper: [Arduino 3rd party hardware documantatuion](https://arduino.github.io/arduino-cli/platform-specification/)


sender: user

message:
Ethernet Shield Not Working With TFT Screen

I'm trying to stack up Arduino UNO, [Ethernet Shield][1] and [Waveshare 2.8" TFT Shield][2]. Since I'm new to this I'm mostly doing basic stuff.

I successfully manage to get ethernet shield and TFT shield to work individually. Then since TFT shield will not be able to use the ICSP interface I connected the jumpers as it says on [wiki][2].

> **Hardware configuration**
>
>  - When using the Arduino board with ICSP interface, the jumpers SB1,    SB2 and SB3 on the LCD module should be kept open.
>  - When using the Arduino board without ICSP interface, the jumpers SB1,    SB2 and SB3 on the module should be connected with a 0R
> resistor,    respectively.

After this I put everything together and try to get them working with the below code but for some reason I don't know, Ethernet shield stopped working. I get the error `Ethernet shield was not found.  Sorry, can't run without hardware. :(`. Even though the error, my TFT screen lights up and runs demo. Probably I'm missing something simple. I'll appreciate any help or guidance.

```
#include <stdint.h>
#include <LCD.h>
#include <SPI.h>
#include <Ethernet.h>

IPAddress server(192, 168, 0, 107);
IPAddress ip(192, 168, 0, 177);
IPAddress myDns(192, 168, 0, 1);
IPAddress gateway(192, 168, 0, 1);
EthernetClient client;
byte mac[] = {0x90, 0xA2, 0xDA, 0x00, 0x23, 0x36};

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

  /*--------- TFT Init -------------*/
  SPI.setDataMode(SPI_MODE3);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  SPI.begin();
  Tft.lcd_init();
  /*--------- TFT Init End -------------*/

  /*--------- Ethernet Setup -------------*/
  Serial.println("Initialize Ethernet with DHCP:");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    if (Ethernet.hardwareStatus() == EthernetNoHardware) {
      Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    } else if (Ethernet.linkStatus() == LinkOFF) {
      Serial.println("Ethernet cable is not connected.");
    }
    // no point in carrying on, so do nothing forevermore:
    // while (true) {
    //   delay(1);
    // }
  }
  // print your local IP address:
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());
  /*--------- Ethernet Setup End -------------*/

  /*--------- Ethernet Connection Demo Setup -------------*/
  if (client.connect(server, 3000)) {
    Serial.print("connected to ");
    Serial.println(client.remoteIP());
    // Make a HTTP request:
    client.println("GET / HTTP/1.1");
    client.println("Host: localhost");
    client.println("Connection: close");
    client.println();
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  beginMicros = micros();
  /*--------- Ethernet Connection Demo Setup End -------------*/
}

void loop()
{
  /*--------- TFT Demo -------------*/
  Tft.lcd_clear_screen(WHITE);
  for (int x = 1; x <= 240; x++) {
    for (int y = 1; y <= 320; y++) {
      Tft.lcd_draw_rect(x, y, 1, 1, RED);
      delay(1);
    }
  }
  /*--------- TFT Demo End -------------*/

  /*--------- Ethernet Check-Up ---------*/
  switch (Ethernet.maintain()) {
    case 1:
      //renewed fail
      Serial.println("Error: renewed fail");
      break;

    case 2:
      //renewed success
      Serial.println("Renewed success");
      //print your local IP address:
      Serial.print("My IP address: ");
      Serial.println(Ethernet.localIP());
      break;

    case 3:
      //rebind fail
      Serial.println("Error: rebind fail");
      break;

    case 4:
      //rebind success
      Serial.println("Rebind success");
      //print your local IP address:
      Serial.print("My IP address: ");
      Serial.println(Ethernet.localIP());
      break;

    default:
      //nothing happened
      break;
  }
  /*--------- Ethernet Check-Up End ---------*/

  /*--------- Ethernet Demo ---------*/
  int len = client.available();
  if (len > 0) {
    byte buffer[80];
    if (len > 80) len = 80;
    client.read(buffer, len);
    if (printWebData) {
      Serial.write(buffer, len); // show in the serial monitor (slows some boards)
    }
    byteCount = byteCount + len;
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    endMicros = micros();
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    Serial.print("Received ");
    Serial.print(byteCount);
    Serial.print(" bytes in ");
    float seconds = (float)(endMicros - beginMicros) / 1000000.0;
    Serial.print(seconds, 4);
    float rate = (float)byteCount / seconds / 1000.0;
    Serial.print(", rate = ");
    Serial.print(rate);
    Serial.print(" kbytes/second");
    Serial.println();

    // do nothing forevermore:
    // while (true) {
    //   delay(1);
    // }
  }
  /*--------- Ethernet Demo End ---------*/
}
```

  [1]: https://www.arduino.cc/en/Main/ArduinoEthernetShieldV1
  [2]: https://www.waveshare.com/wiki/2.8inch_TFT_Touch_Shield

sender: assistant

body:
The error message is from the ethernet library. As I do not have the sufficient hardware to test this indicates a pin conflict. So the ethernet shield v1 uses/needs one or more pins the LCD shield is using.
How to find out dig into the circuit documenation and look at the used pins.
Be aware that a lot of tuts/infos on the net are about **ethernet shield v2** which is hardware differnt from **v1**.

  - Circuit schematics for [Waveshare](http://www.waveshare.com/w/upload/d/d4/2.8inch_TFT_Touch_Shield_Schematic.pdf) and [Ethernet shield v1](https://www.arduino.cc/en/uploads/Main/arduino-ethernet-shield-06-schematic.pdf)

  - Check also for shorts between USB (Arduino) / Ethernet plug and the above shields, I isolate them normaly with a piece of isolation tape (to be safe than sorry).

**EDIT**

Ethernet shield: Arduino communicates with both the W5100 and SD card using the SPI bus (through the ICSP header).
This is on digital pins 10, 11, 12, and 13 on the Uno.
Pin 10 is used to select the W5100 and pin 4 for the SD card.
These pins cannot be used for general I/O

The wave share uses CS=D10, RS=D7, RST=D9 and the SD CS can be defined on eg SD_CS 5 with [this library](https://github.com/prenticedavid/HX8347D_kbv/) as the waveshare lib is not usable other than basic playing around.

This lib is Adafruit_GFX compatible so a wide variety of programs and other libs work.

So your chance is

  - to remap the SD CS by software if the other pins pose no conflict (you have to test it) or
  - get an other Ethernet connector (not a shield because its more flexible) or
  -  remap manually with dupont wires the LCD shield (because it's the top most) and change the according pins in the libs header file.

Do not cut traces or solder around its not worth the effort and you might break things


body:
From examining the schematics of the Ethernet shield as well as the TFT shield, it looks like the Chip Select (CS) pin of the Ethernet shield uses the same pin (Arduino pin D4) as the Interrupt pin of the Touch Panel on your TFT shield (TP_IRQ) in the schematic.

I don’t think you can solve this without modifying any hardware. Either the TFT shield or the Ethernet shield should be modified to use a different pin, and these modifications should be reflected in the underlying library.

My guess is the Ethernet shield would be easiest to modify as its PCB can be reached from two sides. You could also cut the D4 pin from the TFT shield and connect its PCB trace to an unused digital pin via a short wire.


message:
Arduino Turn Signals

Could I use an Arduino to power run the following lights? [Here][1] I have a project in mind, and although I am new to electronics, I am a computer programmer (C, C++, C#, Java) by profession so the coding side doesn't worry me, what I am confused about is what power supply I need etc.

  [1]: https://www.amazon.co.uk/dp/B07Z5RGXJ8/ref=sspa_dk_detail_0?psc=1&pd_rd_i=B07Z5RGXJ8&pd_rd_w=vW0xN&pf_rd_p=1055d8b2-c10c-4d7d-b50d-96300553e15d&pd_rd_wg=dcoXb&pf_rd_r=SF8MZNZ4KBBW3GT7VYRD&pd_rd_r=746fc479-d3ba-4bd5-90ad-e842d645c150&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUE0RVdQSDNEWDRSTEQmZW5jcnlwdGVkSWQ9QTAxNDY0NzkyRUhINTNLMzVGNTlRJmVuY3J5cHRlZEFkSWQ9QTA3MDM2OTkzQlNZRUs3NDFYUkFLJndpZGdldE5hbWU9c3BfZGV0YWlsJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ==

body:
If you mean you want to power it directly from a GPIO pin from an Arduino: no, for two reasons:

- It doesn't show the current needed, but it's likely more than 20 or 40 mA which is maximum for a GPIO pin. So you need to use a transistor, which can be used to turn on something with higher current, with the current of a GPIO pin. Search for 'Transistor as a switch' for more info.
- Also, it's 12 V and the Arduino delivers 5 V.

What you need is a separate 12V adapter, with a current capability MORE than what that light needs. I cannot find the current (mA) in the link, so you might need to measure it (e.g. with a digital multimeter). If you don't have a digital multimeter, buy one, you need one anyway if you will do electronics. You can even buy a 3 euro one from China if you want (for now).


body:
If you look at the specs of those lights, they draw 1 watt at 12 volts. That is both too much current and too much voltage for an Arduino. (You're only supposed to draw about 20 mA from a single pin, and somewhere between 500 mA and 1 amp from the 5V regulator. (It is heat limited, and typically not very well heat-sinked. Er, heat-sunk?)

An Arduino only puts out 3.3v and 5V.

If you're looking to drive these from a car/motorcycle, you should be able to power them directly from the 12V battery of the vehicle. Failing that, get a 12V power supply that can put out as much current as you need for ALL of the lights you need, plus 10%-20% extra, for "slop".

What you should do is to buy a MOSFET power transistor designed for switching logic level signals for each turn signal you need to control. These would work well:
 https://www.adafruit.com/product/355

You'd then use logic lines from the Arduino to control the gates of the transistors, and each transistor would switch the power for one of your turn signal lights.


message:
How does code typed in Arduino IDE runs on a nodemcu?

I actually have a series of questions regarding Nodemcu and esp8266.

1. How does code typed in Arduino IDE run on Nodemcu?

1. What firmware is present on the nodemcu?

1. How do I upload the above firmware on esp8266-01 module?

1. I want my esp8266-01 module to work with a Lilypad Arduino. So this is the way I want it to work: Lilypad Ardiuno has acquires some data using a sensor. It wants to post this data to a server on internet. So to do the job it uses a ESP8266-01. Will the configuration work?

body:
> how does code typed in Arduino IDE runs on Nodemcu

The IDE runs the compiler which turns the C into assembly and then machine code.  That is then uploaded to the ESP8266.

> what firmware is present on the nodemcu.

The code that you just wrote and uploaded.

> i want my esp8266-01 module to work with a Lilypad Arduino .So this is the way I want it to work Lilypad Ardiuno has acquires some data using a sensor it wants the post this data to a server on internet.So to do the job it uses a ESP8266-01.So will the configuration work?

Sure, if you program it to do that.  Two choices:

1. Use the AT firmware on the ESP-01 (installed by default)
2. Write custom firmware (as above) for the ESP-01 to do what you want.


message:
Several ESP8266 in wifi network should share information

I am currently working on a project for my home where several ESP8266 (each with a relay) control lights. I have developed an android for this where I find the ESP8266s via mdns but the problem is that sometimes one or two won't be found ever (depends on the position where I am trying it). So my idea was to make them talk to each other so everyone knows like an list of ip addresses from the others. This would give me the possibility to find every ESP as soon as i have found one.

body: I guess you are asking if it is feasible: if this is the case, I would say yes, without too many troubles. Each ESP can launch MDNS discovery, so they can discover each other.


body:
Waht you may be looking for is a mesh network, you can use the standerd lib ESP8266WiFiMesh. Mesh reduces the loading of smart devices on the router by
 forming a mesh between the smart devices.There are unluckely no examples ready to use but you can look at the provided example and modify it to your needs,

You find the lib in your core dir

    C:\Users\Your_Username\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266WiFiMesh

but be aware there are a [lot of open issues and PRs](https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WiFiMesh) (which means lot of trouble in a stable production)

**EDIT**

There is also the [Arduino library painlessMesh](https://gitlab.com/painlessMesh/painlessMesh). Its well documented and has lot of examples and can be combined with MQTT.
For MQTT there is one condition where you might consider this option, if you have deep sleeping nodes on battery (than mesh might be contra productive)


message:
How to code an arduino to execute a particular code using a slide switch

I’m pretty new to arduino. I need help concerning a project I’m making. I’m using a SPDT slide switch to switch between what code(method) should be executed.i.e when I shift the switch to the left, XXX method should be executed and when I move the switch to the right, YYYY method should be executed. The center pin of the switch is connected to arduino +5v while the     left and right leg of the switch are connected like how a tactile switch is interfaces with the arduino. Please can anyone help me with the code, or at least how to program the arduino? Thank you[![Here is the circuit connection][1]][1]

  [1]: https://i.stack.imgur.com/Saag7.jpg

body:
Your switch wiring for D12 is wrong. You connect your inputs directly to ground and that can never change, regardless of the position of the switch.

You effectively have:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/HUnKG.png)

<!-- End schematic -->

However you are over complicating things.  A SPDT switch is nothing more than two buttons, only one of which can be pressed at one time.  If one is pressed the other *must* be released.

You can completely ignore half the switch and treat the other half as a button: if the "button" is pressed then the switch is in one position. If the "button" is released then it's in the other position.

Unless it's a "center off" switch, in which case it has 3 positions, not 2, and the middle one has nothing connected.

If it is a simple 2-position SPDT switch then just disconnect the D12 wire and remove the right-and resistor in your drawing. Then read D13 to determine the position: HIGH is one position and LOW is the other.

If it's a 3-position "center off" switch then move the D12 wire 4 holes to the left so that it connects to the switch-resistor junction, not ground. Then you will need to read both D12 and D13 - which ever one is HIGH is the one that is activated, and the switch is in that position.

Then it's a simple "if / else" (2 position) or "if / elseif / else" (3 position center-off) structure to decide which code to run.


message:
problem using one function to blink different leds

I wrote a function to blink an led using millis and want to blink multiple leds with the same function but with different delay intervals. When I call this function thrice to blink 3 different leds, all the leds blink with the shortest delay. As far my understanding is, functions can be reused if you want to perform same task but why doesn't it work in this case? It works incase I rename the function before calling it again.

Is it wrong to call single function more than once to perform same task but on different pins? How would you call a function without renaming it?

    const int redLed = 10;
    const int yellowLed = 11;
    const int greenLed = 12;

    void setup() {
      pinMode(redLed, OUTPUT);
      pinMode(yellowLed, OUTPUT);
      pinMode(greenLed, OUTPUT);
    }

    void loop() {
    blinkLed(redLed, 1000);
    blinkLed(yellowLed, 4000);
    blinkLed(greenLed, 8000);
    }

    void blinkLed(int led, unsigned long timePeriod) {
      static unsigned long oldTime = 0;
      unsigned long newTime = millis();
      static boolean ledState = LOW;

      if (newTime - oldTime >= timePeriod) {
        oldTime = newTime;
        ledState = !ledState;
      }
      digitalWrite(led, ledState);
    }

Edit: I have modified the function to not have shared variables but it just blinks redLed. why doesn't it work now? Here is the code:

    const int redLed = 10;
    const int yellowLed = 11;
    const int greenLed = 12;

    void setup() {
      pinMode(redLed, OUTPUT);
      pinMode(yellowLed, OUTPUT);
      pinMode(greenLed, OUTPUT);
    }

    void loop() {

      blinkLed(redLed, 1000);
      blinkLed(yellowLed, 4000);
      blinkLed(greenLed, 8000);
    }

    void blinkLed(int led, unsigned long timePeriod) {

      switch (led) {
        case 10:
          static unsigned long oldTime1 = 0;
          unsigned long newTime1 = millis();
          static boolean redState = LOW;

          if (newTime1 - oldTime1 >= timePeriod) {
            oldTime1 = newTime1;
            redState = !redState;
          }
          digitalWrite(led, redState);
              break;

        case 11:
          static unsigned long oldTime2 = 0;
          unsigned long newTime2 = millis();
          static boolean yellowState = LOW;

          if (newTime2 - oldTime2 >= timePeriod) {
            oldTime2 = newTime2;
            yellowState = !yellowState;
          }
          digitalWrite(led, yellowState);
              break;

        case 12:
          static unsigned long oldTime3 = 0;
          unsigned long newTime3 = millis();
          static boolean greenState = LOW;

          if (newTime3 - oldTime3 >= timePeriod) {
            oldTime3 = newTime3;
            greenState = !greenState;
          }
          digitalWrite(led, greenState);
          break;
      }
    }

body:
You want to let the LEDs blink concurrently.
Your static variables oldTime, and ledState are shared between the three LEDs.
So there is ony ONE ledState in your program but you need that state for each one.
Same applies for oldTime.

Resolve the this issue and your LEDs will blink as expected.

btw. you don't need the ledState as you can read its current state.


body:
Yes, functions can be re-used if you want to perform the same task in different places or at different times. But your problem is that you only have one set of "time" variables.

You would be better off learning to create this as a *class* which can not only contain the "blink" function but also the variables that define the state for a specific instance of the blinking.

For example [here](https://github.com/MajenkoLibraries/Blinker) is a small library I wrote ages ago as a demonstration.


body:
Just putting other peoples' suggestions together:

    void blinkLed(int led, unsigned long timePeriod) {
      static unsigned long oldTime[42];
      unsigned long newTime = millis();
      boolean ledState = digitalRead(led);

      if (newTime - oldTime[led] >= timePeriod) {
        oldTime[led] = newTime;
        ledState = !ledState;
      }
      digitalWrite(led, ledState);
    }


message:
restart counter of elapsed millis willingly with read

When I trigger high it will count for as long as I ask it while I am high then shut off. I am able to start counting again whenever I want by triggering low and going back to high and it starts from the beginning as long as the time in low is not within the time I asked it to be high. The problem is I go low mid count then quickly back to high the count picks up where millis left off without starting from the beginning. Is there a way to make this better.

```
unsigned long induceTime = 0;
unsigned long elapseTime;
long setTime = 10000;
int openClose;
int openClosePin = 2;
int writeToPin = 3;
void setup() {
Serial.begin(9600);
}

void loop() {
  int openClose = digitalRead(openClosePin);
  elapseTime = millis();
  if (openClose == HIGH && elapseTime < induceTime + setTime){
    digitalWrite(writeToPin, HIGH);
    Serial.println(' ');
    Serial.println(elapseTime);
    Serial.println(' ');
    Serial.println(induceTime);
    Serial.println(' ');
}
  if (openClose == LOW && elapseTime > induceTime + setTime){
    induceTime = elapseTime;
    Serial.println(elapseTime);
    Serial.println(induceTime);
}

delay(500);
}
```

body:
First make your code rollover safe and second add an other condition:<br>
So as I understood LOW/HIGH changes should start a timer from zero irrelevant if a running timer is over or not - so timer is still running HIGH/LOW -> and LOW/HIGH should restart

    // repalce / paste before setup
    unsigned long startTime = 0;
    bool timerIsOn = false;
    //unsigned long elapseTime;

     // replace your loopwith this
    void loop() {
      int openClose = digitalRead(openClosePin);
    //  elapseTime = millis();
      if (openClose == HIGH && timerIsOn = false){
           timerIsOn = true;
           startTime = millis();
           digitalWrite(writeToPin, HIGH);
           Serial.print(' ');
           Serial.print(millis());
           Serial.print(' ');
           Serial.print(startTime);
            Serial.println(' ');
       }
       // This condition is for time is up
      if (timerIsOn = true && millis() - startTime > setTime){
         digitalWrite(writeToPin, LOW);
         timerIsOn = false;
         Serial.print(setTime);
         Serial.print(' ');
         Serial.println(millis()-startTime);
      }
       // This condition is for going low before time is up
      if (openClose == LOW && timerIsOn = true){
        digitalWrite(writeToPin, LOW);
        timerIsOn = false;
        Serial.print('timerIsOn = ');
        Serial.println(timerIsOn);
        Serial.print(' ');
        Serial.println(millis()-startTime);
      }
     // If you go LOW after time is up it does nothing waits for the next HIGH
    }


body:
For starters, millis should be used relatively to avoid rollover.  Simple fix is to subtract the induceTime over to the same side of the comparison.
Example:
    elapseTime - induceTime > setTime

This also brings up the issue that your 'counter' is always elapseTime aka millis instead of (elapseTime - induceTime) so it never truly stops counting.

You are also never calling
    digitalWrite(writeToPin, LOW);
So it goes high and stays high.  I suspect you meant to set it to low in an else statement somewhere.

Now for the issue regarding quickly changing signals:

Beyond that you could use an interrupt and timer so that your sample rate (determined by the delay(500)) doesn't come into play.  This will give the best possible timing at the cost of restricting which pins you can use for openClosePin and you should also check that you sufficiently debounce the signal (in hardware).

Alternatively you can reduce the 500 to an acceptable #. But you would then want to have another counter to prevent spamming your serial output.

Below example only implements ISR and reduction of 500.  Does not implement timer (which would be required for precise use of setTime to shut the writeToPin off to LOW).

    volatile unsigned long induceTime = 0;
    volatile unsigned long elapsedTime;
    unsigned long setTime = 10000;
    //volatile int openClose; //may want to toggle this in isr...
    int openClosePin = 2;
    int writeToPin = 3;

    void pinChangedISR(){
      if(digitalRead(openClosePin)){ //rising
        digitalWrite(writeToPin, HIGH);
        induceTime = millis();
      }
      else{//falling
        digitalWrite(writeToPin, LOW);
        elapsedTime = millis() - induceTime;
      }
    }

    void setup() {
      pinMode(writeToPin, OUTPUT);
      pinMode(openClosePin, INPUT); //may want INPUT_PULLUP depending on hardware
      attachInterrupt(digitalPinToInterrupt(openClosePin), pinChangedISR, CHANGE);
      Serial.begin(9600);
    }

    void loop() {
      static int frameCount = 0;
      unsigned long delayTime = 100;
      openClose = digitalRead(openClosePin);
      if (openClose == HIGH){
        elapsedTime = millis() - induceTime;
        if(elapsedTime >= setTime) digitalWrite(writeToPin, LOW);
        else if(setTime - elapsedTime < 100) delayTime = setTime - elapsedTime;
      }
      if(framecount >= 5){ //time to print...
        framecount = 0;
        if(digitalRead(writeToPin) == HIGH){
          Serial.println(' ');
          Serial.println(elapsedTime);
          Serial.println(' ');
          Serial.println(induceTime);
          Serial.println(' ');
        }
        else{ //this part's a bit different
          Serial.println(elapsedTime); //reporting duration of last pulse when pulse inactive
          Serial.println(millis()); //reporting current time for inducetime comparison
        }
      } else ++framecount;
      delay(delayTime);
    }


body:
Thanks for the help, this code is closer to what I was looking for. This is for a water level pump, when the trigger is high it turns on, when the water rises the trigger goes low and stays on during the timer as a failsafe and then turns off with when the elapsed time is greater than the set time and also not in my code it turns off with a additional trigger. Here is my working code.
```

unsigned long induceTime = 0;
unsigned long elapseTime;
long setTime = 10000;
int openClose;
int openClosePin = 2;
int writeToPin = 3;
void setup() {
Serial.begin(9600);
}

void loop() {
  int openClose = digitalRead(openClosePin);
  elapseTime = millis();
  if (openClose == HIGH){                //reset count
    induceTime = millis();
    digitalWrite(writeToPin, HIGH);
    Serial.println(induceTime);
}
  if (openClose == LOW){
    elapseTime = millis() - induceTime;  //induceTime is set when leave high
    if (elapseTime < setTime){
      digitalWrite(writeToPin, HIGH);
      Serial.println(elapseTime);
      Serial.println("within setTime high");
}
    if (elapseTime > setTime){
      digitalWrite(writeToPin, LOW);
      Serial.println(elapseTime);
      Serial.println("within setTime for low");
}
    Serial.println(' ');
    Serial.println(elapseTime);
    Serial.println(' ');
    Serial.println(induceTime);
    Serial.println(' ');
}
delay(1000);                              //so that I can see serial monitor
}
```


message:
i2c scanner stuck on scanning for my 0.96in OLED screen with my Arduino Nano

[![i2c scanner serial monitor][1]][1]

  [1]: https://i.stack.imgur.com/6A6Fq.png

>My pins are connected as follows; vcc-3v3, gnd-gnd, sda-A4, scl-A5.

body:
Is it a 3.3 V only OLED? I suppose its vcc(OLED)-3v3(Nano).

Most OLEDs use 3.3V -5V where sometimes the 3.3V from the Arduino is not sufficient.
If its a 3.3V only OLED could you give the make of the OLED (does it have jumpers to change I2C address). Normaly the I2C scanner should return at least with nothing found.


message:
How to get the free/used space on a SD card and transmit it

I'm using this block of code to read and sum up the bytes of all the text files I have on an SD card:

    long get_sd_memory_taken() {
      File dir = SD.open("/");
      long sd_memory_taken;
      int c = 0;
      while (true) {
        File entry = dir.openNextFile();
        if (!entry) {
          return sd_memory_taken;
          break;
        }
        if(strcmp(entry.name(), "SYSTEM~1") == 0) {
          continue;
        }
        if(c > 15) {
          tft.println(entry.name());
          tft.println(entry.size());
        }
        sd_memory_taken += entry.size();
        entry.close();
        c++;
      }
    }
The SD card is 8GB so the number won't be larger than 8,589,934,592. The function get_sd_memory_taken() returns the number so it can be send to a phone using Bluetooth. I just checked that long can hold max 2,147,483,647, so if the SD card is filled more than that, I suppose errors are gonna appear. How can I prevent this? I was thinking of maybe using a double and put the comma maybe 5 digits to the left and send that or maybe divide the number into 10 smaller longs and send them to the phone separately. I think the former method is better but I'm not sure if it'll work. What's the best way to go about this problem where I'm trying to use as less memory as possible?

body:
As SD.h includes

      #include "utility/SdFat.h"
      #include "utility/SdFatUtil.h"

or if you use the SDfat library than this function is more efficient than going all over the place:

    #include <SdFat.h>

    SdFat SD;

    void ShowFreeSpace() {
      // Calculate free space (volume free clusters * blocks per clusters / 2)
      long lFreeKB = SD.vol()->freeClusterCount();
      lFreeKB *= SD.vol()->blocksPerCluster()/2;

      // Display free space
      Serial.print("Free space: ");
      Serial.print(lFreeKB);
      Serial.println(" KB");
    }


message:
nodemcu doesnt response in at command mode

[![enter image description here][1]][1]I want to sent AT command into node mcu esp8266 module with arduino IDE  through serial monitor.
I connect the node mcu to arduino uno board in following sequence:
RX to pin 2 of arduino
TX to pin 3 of arduino
Vin of node mcu to 3.3V of arduino
GND to GND
EN of node mcu to 3.3V of arduino
I send at commands in serial monitor but dont get any response.
I also checked different baud rates.
what is the problem? what thing I'm doing wrong?

```
    #include <SoftwareSerial.h>
SoftwareSerial esp8266(2,3); //2 -->rx  ,3 -->tx

void setup() {
  Serial.begin(115200);
  esp8266.begin(115200);
}

void loop() {
  if (esp8266.available()>0)
  {
      char c = esp8266.read();
      Serial.write(c);
  }
  if (Serial.available()>0)
  {
    delay(1000);
    String cmd = "";
    while (Serial.available())
    {
      cmd += (char)Serial.read();
    }
    esp8266.println(cmd);
  }
}

```

  [1]: https://i.stack.imgur.com/v3WS6.jpg

body:
Some points to note:

* VIN should connect to 5V (it goes through the on-board 5V -> 3.3V regulator). If you connect VIN to 3.3V you will be starving the device of power.
* The NodeMCU doesn't come with AT firmware installed. You will have to install it first before it will respond.
* If you have a NodeMCU why are you bothering with an Arduino? The NodeMCU can do everything (and more) that the Arduino can do (except it lacks IO).


message:
Why when I pull an EEPROM index the value returned is garbage?

I have an array of colors for my tft screen:

    const uint16_t colorTheme [] PROGMEM = {BLACK, WHITE, NAVY, CYAN, RED, GREEN, VERDEAQ, PINK, ORANGE, PURPLE, GRAY, YELLOW};

When I try to use `colorTheme [EEPROM.read (2500)]` I am returned with a value of any garbage, or a value of 0, and I checked it in read_eeprom and the value of `EEPROM.read (2500)` is equal to 4, and 4 in mine vector is cyan color, not black or 0 number, why does this go so wrong?

body:
Your array is in PROGMEM, but you are accessing it as if it were in RAM.

You must use `pgm_read_word()` to access the data in your array.

```
pgm_read_word(&(colorTheme[EEPROM.read(x)]))
```

BTW - what Arduino board has more than 2kB of EEPROM?


message:
Read Simultaneously RFID TAG with multiple RFID Reader [MFRC522]

i have a project that use two RFID Reader, the project for counting tag from conveyor belt, in this case the reader will placed in the middle of the conveyor belt and the reader faces each other.

So i have question, can two RFID Reader reading one or many tag simultaneously? I tried before but when i tried to scan, the two readers did not respond, but if i scan one tag and one reader it will work correctly.

For example:
i have readers 0 and readers 1, and two variables count0 and count1, remember the readers faces each others, so i put one tag in the middle of reader0 and reader1, if the reader 0 scan the tag, count0 will increase to 1 and if reader 1 scan the tag in the SAME TIME it wouldn’t be counting because the reader 0 has scan that tag.

but in my case, the readers(0 and 1) didnt response if i put the tag in the middle of readers.

i use this tutorial for my project https://youtu.be/HmGmFknAIqc

and for this project the data count0 and count1 i send it to nodemcu using SoftwareSerial(5,6).

Im new for using Arduino and i still learn about it(i dont understand too much)

Heres my arduino code
```
/**
 * --------------------------------------------------------------------------------------------------------------------
 * Example sketch/program showing how to read data from more than one PICC to serial.
 * --------------------------------------------------------------------------------------------------------------------
 * This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
 *
 * Example sketch/program showing how to read data from more than one PICC (that is: a RFID Tag or Card) using a
 * MFRC522 based RFID Reader on the Arduino SPI interface.
 *
 * Warning: This may not work! Multiple devices at one SPI are difficult and cause many trouble!! Engineering skill
 *          and knowledge are required!
 *
 * @license Released into the public domain.
 *
 * Typical pin layout used:
 * -----------------------------------------------------------------------------------------
 *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD   Uno/101       Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin           Pin       Pin        Pin              Pin
 * -----------------------------------------------------------------------------------------
 * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
 * SPI SS 1    SDA(SS)      ** custom, take a unused pin, only HIGH/LOW required **
 * SPI SS 2    SDA(SS)      ** custom, take a unused pin, only HIGH/LOW required **
 * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
 * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
 * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
 *
 */
#include <Wire.h>
#include <SPI.h>
#include <MFRC522.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h> //library penampil LCD

#define RST_PIN         9          // Configurable, see typical pin layout above
#define SS_1_PIN        10         // Configurable, take a unused pin, only HIGH/LOW required, must be diffrent to SS 2
#define SS_2_PIN        8          // Configurable, take a unused pin, only HIGH/LOW required, must be diffrent to SS 1

#define NR_OF_READERS   2

LiquidCrystal_I2C lcd(0x27,20,4); //0x3f dapat dicari dengan i2c scanner
SoftwareSerial s(5,6);
//SoftwareSerial s1(2,3);

byte ssPins[] = {SS_1_PIN, SS_2_PIN};

MFRC522 mfrc522[NR_OF_READERS];   // Create MFRC522 instance.
int i = 1;
byte code[10];
String uidString;
int count0 = 0;
int count1 = 0;

/**
 * Initialize.
 */
void setup() {
  s.begin(9600);
 // s1.begin(9600);
  Serial.begin(9600); // Initialize serial communications with the PC
  while (!Serial);
  SPI.begin();        // Init SPI bus

  for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
    mfrc522[reader].PCD_Init(ssPins[reader], RST_PIN); // Init each MFRC522 card
    Serial.print(F("Reader "));
    Serial.print(reader);
    Serial.print(F(": "));
    mfrc522[reader].PCD_DumpVersionToSerial();
  }

//  lcd.init();
//  lcd.init();
//  lcd.backlight(); //menghidupkan lampu latar LCD
//  lcd.setCursor (3,0);
//  lcd.print("Final Project");
//  delay (1000);
//  lcd.clear();
}

/**
 * Main loop.
 */
void loop() {
//  lcd.setCursor (0,0);
//  lcd.print("SCAN RFID");

  for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
    // Look for new cards
    if(reader == 0){
      reader0(reader);
    }else if(reader == 1){
      reader1(reader);
    }
  }
}

/** SCAN RFID TAG READER0 */
void reader0(int reader){
    if (mfrc522[reader].PICC_IsNewCardPresent() && mfrc522[reader].PICC_ReadCardSerial()) {
      Serial.println();
      Serial.print(F("Reader "));
      Serial.print(reader);
      // Show some details of the PICC (that is: the tag/card)
      Serial.println();
      Serial.print(F("Card UID = "));
      dump_byte_array(mfrc522[reader].uid.uidByte, mfrc522[reader].uid.size);
      Serial.println();
//      Serial.print(F("PICC type: "));
//      MFRC522::PICC_Type piccType = mfrc522[reader].PICC_GetType(mfrc522[reader].uid.sak);
//      Serial.println(mfrc522[reader].PICC_GetTypeName(piccType));
      count0++;
      lcd.setCursor (0,0);

      Serial.print("Counter ");
      Serial.print(reader);
      Serial.print(" = ");
      Serial.print(count0);
      Serial.println();
      s.write(count0);
       }

      mfrc522[reader].PICC_HaltA();
      mfrc522[reader].PCD_StopCrypto1();
}

/** SCAN RFID TAG READER1 */
void reader1(int reader){
    if (mfrc522[reader].PICC_IsNewCardPresent() && mfrc522[reader].PICC_ReadCardSerial()) {
      Serial.println();
      Serial.print(F("Reader "));
      Serial.print(reader);
      Serial.println();
      // Show some details of the PICC (that is: the tag/card)
      Serial.print(F("Card UID = "));
      dump_byte_array(mfrc522[reader].uid.uidByte, mfrc522[reader].uid.size);
      Serial.println();
//      Serial.print(F("PICC type: "));
//      MFRC522::PICC_Type piccType = mfrc522[reader].PICC_GetType(mfrc522[reader].uid.sak);
//      Serial.println(mfrc522[reader].PICC_GetTypeName(piccType));
      count1++;
      lcd.setCursor (0,0);

      Serial.print("Counter ");
      Serial.print(reader);
      Serial.print(" = ");
      Serial.print(count1);
      Serial.println();
      s.write(count1);
    }

      mfrc522[reader].PICC_HaltA();
      // Stop encryption on PCD
      mfrc522[reader].PCD_StopCrypto1();
}

/**
 * Helper routine to dump a byte array as hex values to Serial.
 */
void dump_byte_array(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}
```
anyway sorry for my bad english :D

body:
That's because you can only listen at one `SoftwareSerial` interface at a time. On the other interface you will receive nothing.

The `SoftwareSerial` library uses interrupts to watch at the pins. These interrupts cannot easily be shared between different interfaces, thus the `SoftwareSerial` library doesn't support it.

You can do 2 things:

- You could ditch the code for reporting to the serial monitor (so no debugging code and no interaction with the serial monitor on the PC) and only use the LCD for displaying information. Then you can use the free hardware serial port to communicate with one of the RFID readers. The other can be services through a single `SoftwareSerial` interface.

- You could ditch the Uno and buy an Arduino Mega, which has 4 hardware serial ports. Then you can connect both RFID readers to hardware serial interfaces, using the first serial interface for communication with the PC and still having one interface left. This would be my preferred way.


body:
Take a look at this [this link][1] it might be of a help to you. It uses four RFID readers at the same time

  [1]: https://www.youtube.com/watch?v=ahc8Yai_sWI


body:
I'm just starting a project using RFID tags to track cars and engines on a model railroad.
Although I haven't gotten very far yet, my first thought was to use a multiplexer to select which reader I receive data from at any given time. It won't be simultaneous but I should be able to read a dozen or more per second which is probably enough.


message:
HC-SR04 ultrasonic sensor: How to check voltage on the ECHO pin

I'm using and ESP8266 with HC-SR04 ultrasonic sensor. The sensor requires 5v input and will also output to the GPIO pins at 5V.

ESP8266 has a strong recommendation to use 3.3V into the GPIO pins. I've found some setups online with people using voltage dividers to bring the ECHO pin voltage down.

Example on a PI: https://tutorials-raspberrypi.com/raspberry-pi-ultrasonic-sensor-hc-sr04/

I'm using a basic multimeter that i've found to be pretty accurate. When I put the BLACK cord on the ECHO and RED on the GROUND (of sensor pins), I get variable voltage readings. I'm trying to ensure a 3.3V coming from the ECHO into my ESP.
Questions:

1. Am I putting the black and red cords on the appropriate areas?
2. If yes to question 1, then why am i get such a variable of readings?
3. How can I test to ensure only 3.3V coming out of ECHO?

body:
You have your leads backwards. But that doesn't matter, since there's nothing to measure. You'll only see a voltage (and even then only a brief pulse) when an echo is actually received.

You would need an oscilloscope to be able to read that voltage.


body:
As Majenko already wrote, the black cord goes always to ground, so you have the leads backwards (though this just means, that your multimeter will report a negative voltage, if it is able to do so).

But besides that you cannot easily measure the echo pulse with a multimeter. A multimeter is build to measure either a DC voltage or a constant AC voltage. It is not build to measure the peak signal of a pulsed line. Some good multimeters may be able to do that, but it most of them (an definitely the basic ones) cannot do this. They are measuring the voltage over a relatively long period of time (longer than an echo pulse) with multiple measurements (to average out the noise). Also you cannot control, when exactly each measurement is taking place. So depending on the exact timing, the multimeter might have multiple pulses in the measurement (reading 5V there) or even missing pulses completely. That's the meaning of the Nyquist frequency, which states, that the measurement frequency must be higher than double of the signal frequency, or you will not be able to measure the signal correctly.

The echo pulse - if you receive one - will be rather short. With the maximum distance of most ultrasonic sensor boards of 3m, you will get a maximum pulse length of

    3m / (300 m/s) = 0,01s = 10ms

You won't be able to correctly read that pulse with a multimeter. You would need an oscilloscope for that.

**What to do now?** If you want to make sure, that the used voltage divider divides 5V input to 3.3V output, you can connect the input to the 5V pin (but disconnect the echo pin first). Then measure the voltage at the output (which is now HIGH all the time, not just for the time of a pulse). If it's 3.3V, you can be sure, that the divider works correctly. As the ultrasonic sensor is provided with 5V, it won't output more than that. So you can be sure, that the ESP will only see 3.3V.


message:
HTTP POST from Arduino/ESP8266/ESP32 How to send parameters (x-www-form-urlencoded)

------
EDIT: Thank you for the answer, also we had figured out how to do it **Micropython** too - I believe that it is relevant for the Arduino/ESP8266/ESP32 community to share this too.
[https://github.com/46elks/46elks-getting-started/blob/master/code-examples/MicroPython/https_post_with_micropython.py][1]
-------
How should I include parameters from, to and message to http.post?

Is this the correct way to do it?
http.POST("'from:+XXXXX','to:+XXXXX','message:Hej'");

    #include <M5StickC.h>
    #include <Arduino.h>
    #include <WiFi.h>
    #include <WiFiMulti.h>

    #include <HTTPClient.h>

    #define USE_SERIAL Serial

    WiFiMulti wifiMulti;

    void setup() {

        USE_SERIAL.begin(115200);

        USE_SERIAL.println();
        USE_SERIAL.println();
        USE_SERIAL.println();

        for(uint8_t t = 4; t > 0; t--) {
            USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
            USE_SERIAL.flush();
            delay(1000);
        }

        wifiMulti.addAP("YYYY", "ZZZZZ");

    }

    void loop() {
        // wait for WiFi connection
        if((wifiMulti.run() == WL_CONNECTED)) {

            HTTPClient http;

            USE_SERIAL.print("[HTTP] begin...\n");
            // configure traged server and url

              http.begin("https://api.46elks.com/a1/sms");
              http.addHeader("Content-Type", "application/x-www-form-urlencoded");
              http.setAuthorization("XXXXX", "YYYYYY");
              int httpCode = http.POST("'from:+XXXXX','to:+XXXXX','message:Hej'");

            USE_SERIAL.print("[HTTP] GET...\n");
            // start connection and send HTTP header
             httpCode = http.GET();

            // httpCode will be negative on error
            if(httpCode > 0) {
                // HTTP header has been send and Server response header has been handled
                USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);

                // file found at server
                if(httpCode == HTTP_CODE_OK) {
                    String payload = http.getString();
                    USE_SERIAL.println(payload);
                }
            } else {
                USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
            }

            http.end();
        }

        delay(10000);
    }

  [1]: https://github.com/46elks/46elks-getting-started/blob/master/code-examples/MicroPython/https_post_with_micropython.py

body:
What format of message does the server expect? <br>As you send "x-www-form-urlencoded" it should probably look like:

     "from=+XXXXX&to=+XXXXX&message=Hej"

where the different parts are

     "param1=paramValue1&param2=paramValue2&param3=paramValue3"

     param .... Name of the expected parameter
     = .... divides the param pair
     paramValue .... Content/value of the parameter
     & .... links the param pairs

so in your case

     int httpCode = http.POST("from=+XXXXX&to=+XXXXX&message=Hej");


message:
Why does the LEDs affect Analog Input?

So I'm working for a project to control RGB Led Strip using microphone or sound sensor with `Arduino Nano`. I'm using `5050 RGB Led Strip` around 120 LEDs, and I control them using simple transistor circuit to each channel R, G, and B, then I connect the base of the transistors to the resistors and PWM Outputs of the Arduino. And then I'm using `KY-038 Sound Sensor` (I'm using the Analog Output pin) and connect it to Arduino `A0`.

The problem is when I didn't connect the LEDs, the microphone worked correctly. I processed the analog input, put filter and threshold. When I connected the LEDs, the reading of the `A0` is disturbed by the transition of the LED (for example from 0% PWM to 50% PWM or ON). As the result, my analog read detected it as a voltage swing and recognize it as a sound, and trigger the LEDs, then oscillating without any external sound. If I disconnected the LEDs, it worked correctly, for example I change it to Arduino Built-In LED, it turned on according to the external sound.

Why does this happen? I don't think they share the same timer, and I also use proper Power Supply and Capacitor to provide the enough power.

My project is similar to [this][1] project.

  [1]: https://damian.pecke.tt/2015/03/02/beat-detection-on-the-arduino.html

body: Which model of LED are you using? 5050 is just the form factor. However, I think the problem is related to power consumption. The well-known WS2812B (a.k.a. Neopixel from Adafruit), may consume about 50mA. Considering 120LEDs, you can reach an important level of current (circuit supporting more than 1A should be properly designed). The sudden change of current can easily change introduce noise on the entire circuit. The solution should use an external power supply dedicated for LED, sharing GND with your Arduino.


body:
I think it is because of power consumption.

If the LEDs consume lots of power, the LED on Arduino(typically mini red LED) will be off or faded.
So before you connect the  LEDs, check the  mini red LED which is on Arduino and after connection the LEDs, check ones again.
If the red LED is faded or off, the problem must be power consumption.

Connect 12v or 5v to vin to powering the Arduino, and also to LEDs
The important thing is you should not connect LEDs to Arduino 5v.


message:
Activating a defined macro in a class from main.cpp

Sorry if this question been asked. I'm trying to activate certain function in a class using a macro defined in the class from main.cpp. I'm using jrowberg MPU6050 library if that matters.

main.cpp

    #include "gyro.h"
    gyro gyro(Serial);
    #define OUTPUT_READABLE_EULER

    void setup(){
    ...
    }
    void loop(){
    ...
    }

gyro.cpp

      #include "gyro.h"
      #ifdef OUTPUT_READABLE_EULER
          // display Euler angles in degrees
          mpu.dmpGetQuaternion(&q, fifoBuffer);
          mpu.dmpGetEuler(euler, &q);
          serial_.print("euler\t");
          serial_.print(euler[0] * 180/M_PI);
          serial_.print("\t");
          serial_.print(euler[1] * 180/M_PI);
          serial_.print("\t");
          serial_.println(euler[2] * 180/M_PI);
      #endif

If I define `OUTPUT_READABLE_EULER` in `gyro.h`, it works. But I want to do it from main.cpp.

body:
You cannot not, but also you should not try to define a macro in a cpp file and use it in another cpp file.

Instead, you have to define it in a h (header) file, which is included in both cpp files.

Why would you define it in `main.cpp` or `main.h` anyway if you don't use it in those files?

You have mainly three options:

- Define it in `gyro.h` so you include it in `gyro.cpp` where you use it. You can later use it in other files as well.
- Define it in `gyro.cpp` so you can use it only in that file. This prevents the macro being used in other files (which can be safer).
- Define it in a separate file, e.g. `euler.h` and include this header file everywhere you need it.

See also Juraj's comments below.


message:
Arduino Mega keep states after reprogramming

Based on:

https://forum.arduino.cc/index.php?topic=440978.0

And some previous experience with Arduinos. What I would like to accomplish here is that I have a 8 channel relay board with the relays in different states. The Arduino is connected to a RaspberryPI via USB.

The first problem is well known the automatic reset of the Arduino which can be taken care of with a resistor or desoldering a pin on the Mega board so you can reconnect your Arduino as many time as you wish (while running on an external +5V power source) to the Raspberry and it will never reset.

However I also remember that doing this to the boards will also make them impossible to program because they cannot reset at the end when the sketch is uploaded.

I have think of a workaround:

1, Create a programming command on the arduino which is when it's received from the RPI it will connect that cut off pin with a relay which will make resetting possible again

2, Save all relay states to the EEPROM

3, After reset the Arduino always checks this programming flag in it's EEPROM and if it's present it either does not touch the relays or set them to the same position ON/OFF depending on the value it read back from the EEPROM

The last guy claims that: When the Arduino is in reset, all pins act like they aren't connected to anything. If you have an output which must be in a specific state during that period, you must add an external resistor to pull it up or down as required.

Is there any other solution for this problem? Like using a newer Arduino board which can keep pin states over reprogramming?

[![ardu][1]][1]

  [1]: https://i.stack.imgur.com/xNe2R.jpg

body:
I had to solve a problem similar to this for an ESP32 based system. The solution I came up with was to use external D-type latches (flipflops) to store the state independently of the Arduino.

The Arduino has to actively load a new relay state into a latch in order for the relay to change state, and that state is retained regardless of what the Arduino does.

The outputs of the latches can also be connected to other input pins so the Arduino can find the current state of the relays at boot time.

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/ijQEb.png)

<!-- End schematic -->

The Arduino keeps track of what the outputs should be (reading the current state at boot) and then changes a state when needed. It then loads *all* the states onto the output pins and pulses the LOAD pin (CLK on the chip) high to load those states into the latches.

I used the 74HC374 chip for this since it contains 8 latches tied to a single CLK pin.


body:
You have basically 2 distinct problems here. The problem to somewhat automatically enable/disable the reset from USB and the problem to keep the relays at their set states over reprogramming.

- **Enable/disable reset:** The easiest way is to use a jumper, that you disconnect everytime you want to program the board. If you want to do it remotely, you already described a valid way, though I think, that you don't need a relay for that. A transistor or MOSFET should be sufficient for it.

- **Keep the relay states:**

    > Like using a newer Arduino board which can keep pin states over reprogramming?

    I don't think, that something like that exists. It does not make sense for general purpose microcontrollers to do that; they all start from a clean state. So you need to save the state of the relays outside of the Arduino. What type of device you want to use for that is up to you. Majenko mentioned flipflops, which gives you the most basic functionality for this. You could also use devices, which are interfaces serially, like shift registers or even port expanders. Using flipflops will be the easiest way, since the programming does not change much. There are many examples how to use each of these devices with an Arduino on the web.


body:
I use for this purpose (model railroading switching turnouts/signals with relays and coils) a simple and pin saving solution.
An I2C bus shield/module with 16 I/O ports (and its daisy chainable - up to 64 modules theoretically, 16 practically due to address encoding pins)
The 16-channel PCA9685/PCF8574 I/O extender module cost around 4-5 euro and requires beside GND/VCC only two data pins (SDA & SCL) to control the module. The I2C header has extra 10K pullup resistors and onboard of the module is a 25 MHz typical internal oscillator.

So after reseting, I first read the EEPROM/SPIFFS/SD-values and based on that stored set I work on. The Module(s) has(ve) a seperate power source which is not affected by the reset of the Arduino controlling them. The operating range of 2.3V to 5.5V allows the module to be powered from a range of power supplies and also used with 3.3V devices.
The green terminal block in the picture is for use with servos - the extra power supply attaches to the I2C header (but common ground with Arduino).

 Of course you have to use a lib (or like me write the functions you need) but once your into it its easy to use and also usable for other scenarios (LEDs, PWM generator, servos).

[![enter image description here][1]][1]

> The PCA9685 is a 'free running' PWM controller. Tell it what to do,
> and it will keep doing that until you tell it to do something else. If
> you wanted to set the relays to a specific state and keep them
> there, you could disconnect the Arduino until you wanted the relays to
> do something else.

  [1]: https://i.stack.imgur.com/LMgoM.jpg


message:
EspMQTTClient inside a class

I'm trying to use `EspMQTTClient` inside a class, called `myIOT32`.

An error, which I don't find the reason for is generated.

    /home/guy/Documents/git/Arduino/libraries/myIOTesp32/myIOTesp32.cpp: In lambda function:
    /home/guy/Documents/git/Arduino/libraries/myIOTesp32/myIOTesp32.cpp:25:5: error: 'this' was not captured for this lambda function
         client.publish("mytopic/test", "This is a message sent 5 seconds later");
         ^
    /home/guy/Documents/git/Arduino/libraries/myIOTesp32/myIOTesp32.cpp:25:5: error: invalid use of non-static data member 'myIOT32::client'
    In file included from /home/guy/Documents/git/Arduino/libraries/myIOTesp32/myIOTesp32.cpp:1:0:
    /home/guy/Documents/git/Arduino/libraries/myIOTesp32/myIOTesp32.h:20:19: note: declared here
         EspMQTTClient client;
                       ^
    Multiple libraries were found for "WiFi.h"
     Used: /home/guy/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/WiFi
     Not used: /home/guy/arduino-1.8.12/libraries/WiFi
    exit status 1
    Error compiling for board LOLIN D32.

`.h` file:

    #ifndef myIOT32_h
    #define myIOT32_h

    // OTA libraries
    #include <WiFi.h>
    #include <ESPmDNS.h>
    #include <WiFiUdp.h>
    #include <ArduinoOTA.h>

    #include "secrets.h"
    #include "EspMQTTClient.h"
    #include "Arduino.h"

    class myIOT32
    {
    private:
        void onConnectionEstablished();  // <--- this is a must have function ( was taken as is from lib's built-in example

    public:
        EspMQTTClient client;
        myIOT32(char *ssid, char *wifi_p, char *mqtt_broker, char *mqttU, char *mqttP, char *devTopic, int port = 1883);
    };

    #endif

`.cpp` file:

    #include "myIOTesp32.h"

    myIOT32::myIOT32(char *ssid, char *wifi_p, char *mqtt_broker, char *mqttU, char *mqttP, char *devTopic, int port)
        : client(ssid, wifi_p, mqtt_broker, mqttU, mqttP, devTopic, port)
    {
    }

    void myIOT32::onConnectionEstablished()
    {
      // Subscribe to "mytopic/test" and display received message to Serial
      client.subscribe("mytopic/test", [](const String & payload) {
        Serial.println(payload);
      });

      // Subscribe to "mytopic/wildcardtest/#" and display received message to Serial
      client.subscribe("mytopic/wildcardtest/#", [](const String & topic, const String & payload) {
        Serial.println(topic + ": " + payload);
      });

      // Publish a message to "mytopic/test"
      client.publish("mytopic/test", "This is a message"); // You can activate the retain flag by setting the third parameter to true

      // Execute delayed instructions
      client.executeDelayed(5 * 1000, []() {
        client.publish("mytopic/test", "This is a message sent 5 seconds later");
      });
    }

Appreciate any help in constructing such a class

body:
For the fix, just add the reference capture and it should compile fine:

       // Execute delayed instructions
      client.executeDelayed(5 * 1000, [&]() {   // [&] instead []
        client.publish("mytopic/test", "This is a message sent 5 seconds later");
      });

I could not test, but you will have to apply to other functions as well.<br>

    [] Capture nothing
    [&] Capture any referenced variable by reference
    [=] Capture any referenced variable by making a copy


message:
F() messes with program

I'm working on command-handler library and I have a big problem with `F()` function.
Example sketch for library uses quite a lot of RAM, because it has to print a lot of text over UART. As before, I've used `F()` to lower RAM usage. It worked on first!

Lib works with help of `strtok` function. Command fomar is:

> cmd1,..,paramN;..;cmdN,..,paramN

Commands are separated with `;` while command parameters(params) are separated with `,`
Library works without any problems, it returns memory address(`char*`) of any command and every param.

When I try to compare parameter/command with `strcmp` it works only if all commands are in uppercase.
Let's take `LED` command for example:
It works only with `Led`, `LED` or any case where is letter d in uppercase. `led` won't work, and it will say that command `le` doesn't exist. Yes, `le`, it won't print `led`. But, after `DURATION` command, it somehow start working.

Memory for serial buffer is dynamicly allocaed in object constructor, in global scope.
Why? All those problems are because `F()`. Can someone explain why? Here's the code and screenshot of serial monitor.

    void execCmd(const char *set)
    {
 char *cmdParam = CMDHandler.find(set, CMD_PARAM);

 if (!strcmp(cmdParam, "LED"))
 {
  // ONE WAY TO CHECK IF COMMAND HAS PARAM(S) - BEFORE GETTING PARAM(S) == BETTER WAY
  if (!CMDHandler.count(CMDHandler.getNext(CMD_PARAM), CMD_PARAM))
  {
   Serial.print(F("->> Command LED: Current LED status is "));
   Serial.println(digitalRead(LED_PIN));
   return;
  }

  cmdParam = CMDHandler.find(nullptr, CMD_PARAM);
  LEDStatus = 0;
  uint8_t status = atoi(cmdParam);

  digitalWrite(LED_PIN, status);
  Serial.print(F("->> Command led: LED Status is "));
  Serial.println(status, DEC);
 }
 else if (!strcmp(cmdParam, "LOOP"))
 {
  cmdParam = CMDHandler.find(nullptr, CMD_PARAM);

  // SECOND WAY TO CHECK IF COMMAND HAS PARAM(S) - AFTER GETTING EVERY PARAM
  if (cmdParam == nullptr)
  {
   Serial.println(F("->> Command LOOP: Expected one parameter!"));
   return;
  }

  uint8_t status = atoi(cmdParam);
  if (status)
  {
   LEDStatus = 2;
   digitalWrite(LED_PIN, HIGH);
   Serial.println(F("->> Command LOOP: LED Blink Loop is on!"));
   delay(blinkDuration);
  }
  else
  {
   LEDStatus = 0;
   digitalWrite(LED_PIN, LOW);
   Serial.println(F("->> Command LOOP: LED Blink Loop is off!"));
  }
 }
 else if (!strcmp(cmdParam, "DURATION"))
 {
  if (!CMDHandler.count(CMDHandler.getNext(CMD_PARAM), CMD_PARAM))
  {
   Serial.print(F("->> Command DURATION: Current blink duration is "));
   Serial.print(blinkDuration, DEC);
   Serial.println("ms");
   return;
  }

  cmdParam = CMDHandler.find(nullptr, CMD_PARAM);
  blinkDuration = atoi(cmdParam);

  Serial.print(F("->> Command DURATION: New blink duration is "));
  Serial.print(blinkDuration, DEC);
  Serial.println("ms!");
 }
 else if (!strcmp(cmdParam, "HELP"))
 {
  Serial.println(F("------ HELP ------\n-> LED [0/1] - Turns off/on LED on pin 13\n-> LOOP [0/1] - Stops/starts blink loop with LED on pin 13\n-> DURATION [X] - Changes duration of LED loop blink. Recommended values is 50-500ms\n"));
 }
 else
 {
  Serial.print(F("->> Command "));
  Serial.print(cmdParam);
  Serial.println(F(" does not exist!"));
 }
}

    char *CMDHand::find(const char *input, uint8_t const type)
    {
     char *found = nullptr;
     char separator = delimiter[type];

     if (input != nullptr) // FIRST CALL
     {
      constrain[type] = input + strlen(input) - 1;
      next[type] = input;
     }
     else if (next[type] > constrain[type]) return (nullptr);

     found = strtok(next[type], &separator); // FOR SOME REASON IT DOES NOT WORK IF I PUT &delimiter[type] INSTEAD OF &separator
     last[type] = next[type];
     next[type] += strlen(found) + 1;

     return (found);
    }

[![Screenshot of serail monitor][1]][1]

  [1]: https://i.stack.imgur.com/vAiel.png

body:
To compare with `F()` macro encased strings you have to use special forms of the string functions that are suffixed with `_P`.  You also need to cast the string literals to the right type (`PGM_P`).

To do a case-insensitive comparison you should use `strcasecmp` instead of `strcmp`.

To put those together you end up with:

    if (strcasecmp_P(cmdParam, (PGM_P)F("help")) == 0) {
        ...
    }

----

There is a problem here:

    found = strtok(next[type], &separator)

`strtok` takes a C string as a list of separators (must be NULL terminated). You're passing it the address of a single character. There may or may not (probably not) be a NULL in the next byte in memory, but everything else up to the first NULL found in memory will be taken as delimiter characters.