text:
How to use C++20 in Arduino IDE?
I'm writing a program for esp32 using the Arduino IDE that needs to count the number of '1' bits in a byte.
I found a post elsewhere that says there's a nice function in the standard library to do it: std::popcount(value)
... the catch is, it only exists in C++20.
Where is the C++ standard level defined in an Arduino IDE project, and what do I have to do to change whatever level it selected by default when I created the project to C++20?
Update
@jsotola's comment solved my immediate problem. That said, I was still curious about changing the C++ version used by Arduino IDE.
I'm still unsure about the present version, but it appears that at least as of approximately 2018, the version of C++ used by Arduino IDE is (was?) hardwired & not something you can easily change. The bundled C++ compiler itself can probably deal with newer versions, but the IDE itself instructs it to compile the code according to an older version of C++ (C++2011 or C++2014, I believe).
There's apparently still disagreement about just how much of the C++ standard library is available to code built using Arduino with ARM, and it's more of a spectrum than black & white.
In the case of 8-bit AVR, most of the C++ Standard Library is missing (though it's sometimes possible to forcibly put back the chunks that were ripped out... I distinctly remember finding a method a couple of years ago to restore sprint's ability to format floats if you're building for something like a Mega 2560 and don't have to particularly care about minimizing size).
The (as yet unconfirmed) impression I got last night is that as of 2024, there are standard library limits imposed by Arduino IDE, but not necessarily imposed by Arduino framework. Meaning, there are language features that won't work in Arduino IDE, but will (or at least, can be forcibly made to) work if you're using something like PlatformIO and VS Code.
Likewise, changing the target C++ level (11, 14, 17, 20, 23) is semi-straightforward if you're using PlatformIO + VS Code (or some other IDE that isn't "Arduino IDE"), but effectively impossible with Arduino IDE.
I got the impression that in most cases, almost any C++ standard library can be made to compile without errors and run from the canonical source code... but libraries that have never been optimized for something like esp32 might run really, really poorly compared to their performance on a PC, or even a Raspberry Pi.
Using the population-count/Hamming-distance example, a CPU like the one in an esp32 might actually have a proper instruction to do it (I don't actually know whether it does), but the code in the "canonical" C++ standard library, having never been tweaked to optimize it for esp32, might fail to use that optimized instruction & instead compile to code that does the task in just about the worst way possible.
In the specific context of ESP32, there are apparently a lot of of as-yet-unoptimized standard library classes that make poor choices about SRAM vs PSRAM (or make no choices at all, and just ignore PSRAM) when forcibly-compiled for esp32, and do bad things with dynamic memory allocation in general.
Some of those things have improved over time as other standard-library classes the standard-library classes depend upon have been improved and optimized for esp32, but until someone who knows what they're doing makes a point of really reviewing the way code in a library compiles for esp32 and optimizes for it, it's kind of a crapshoot as to whether it will compile "well", or compile to something that would horrify you if you looked at (and understood) the generated assembly language.
Take the above with a few kilograms of skeptical doubt. It's the result of a few hours of reading about a topic I don't have a particularly deep understanding of.

https://stackoverflow.com/questions/109023/count-the-number-of-set-bits-in-a-32-bit-integer#109025


text:
String or unsigned char to uint8_t
I'm attempting to save a string to EEPROM of an ESP8266 radio and then read it back before I encrypt the data (evenutally I would like to save the encrypted data but I'm simplifing things at the moment). Here is the source code:
#include <Arduino.h>
extern "C"
{
    #include "cryptoauthlib.h"
}
#include "aes_cbc.h"
#include <EEPROM.h>
// Key Slot number
uint8_t KEY_SLOT = (uint8_t)9;

ATCAIfaceCfg cfg;
ATCA_STATUS status;

void writeStringToEEPROM(int addrOffset, const String &strToWrite)
{
  byte len = strToWrite.length();
  EEPROM.write(addrOffset, len);
  for (int i = 0; i < len; i++)
  {
    EEPROM.write(addrOffset + 1 + i, strToWrite[i]);
  }
}

String readStringFromEEPROM(int addrOffset)
{
  int newStrLen = EEPROM.read(addrOffset);
  char data[newStrLen + 1];
  for (int i = 0; i < newStrLen; i++)
  {
    data[i] = EEPROM.read(addrOffset + 1 + i);
  }
  data[newStrLen] = '\0';
  return String(data);
}

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

    // Init the constuctor for the library
    cfg.iface_type = ATCA_I2C_IFACE;  // Type of communication -> I2C mode
    cfg.devtype = ATECC608A;          // Type of chip
    cfg.atcai2c.slave_address = 0X30; // I2C address of the Adafruit Breakout Board
    cfg.atcai2c.bus = 1;
    cfg.atcai2c.baud = 100000;
    cfg.wake_delay = 1500; // Delay of wake up (1500 ms)
    cfg.rx_retries = 20;
    atca_trace_config(stdout);
}

void loop()
{
    ATCA_STATUS status = atcab_init(&cfg);
    if (status != ATCA_SUCCESS)
    {
        Serial.println(F("atcab_init() failed : Code -> 0x"));
        Serial.println(status, HEX);
    }
    writeStringToEEPROM(0, "test");
    String retrievedString = readStringFromEEPROM(0);
    uint8_t plaintext = atoi(retrievedString.substring(1,3).c_str());
    uint8_t iv[IV_LENGTH_CBC];
    uint8_t cypherdata[sizeof(plaintext)];

    Serial.println("Beginning of the encryption !");
    status = aes_cbc_encrypt(&cfg, plaintext, sizeof(plaintext), iv, cypherdata, KEY_SLOT);
    if (status == ATCA_SUCCESS)
    {
        Serial.println("encrypted");
    }
    else
    {
        // See file atca_status.h for the code Error
        Serial.print(F("Impossible do the encryption | Code Error 0x"));
        Serial.println(status, HEX);
        return;
    }
}

and here is the error message:

EDIT**:
Found out that the "Save to EEPROM" portion of my code wasn't working so I corrected that. Here is the new code:
#include <Arduino.h>
extern "C"
{
    #include "cryptoauthlib.h"
}
#include "aes_cbc.h"
#include <EEPROM.h>
// Key Slot number
uint8_t KEY_SLOT = (uint8_t)9;

ATCAIfaceCfg cfg;
ATCA_STATUS status;

void setup()
{
    Serial.begin(74880);
    // Init the constuctor for the library
    cfg.iface_type = ATCA_I2C_IFACE;  // Type of communication -> I2C mode
    cfg.devtype = ATECC608A;          // Type of chip
    cfg.atcai2c.slave_address = 0X30; // I2C address of the Adafruit Breakout Board
    cfg.atcai2c.bus = 1;
    cfg.atcai2c.baud = 100000;
    cfg.wake_delay = 1500; // Delay of wake up (1500 ms)
    cfg.rx_retries = 20;
    atca_trace_config(stdout);
}

void loop()
{
    ATCA_STATUS status = atcab_init(&cfg);
    if (status != ATCA_SUCCESS)
    {
        Serial.println(F("atcab_init() failed : Code -> 0x"));
        Serial.println(status, HEX);
    }
    uint addr = 0;
    struct
    {
      uint val = 0;
      char str[16] = "";
    } data;

    EEPROM.begin(512);// commit 512 bytes of ESP8266 flash (for "EEPROM" emulation)
    strcpy(data.str,"test");
    EEPROM.put(addr,data);
    EEPROM.commit();
    EEPROM.get(addr,data);
    Serial.println(String(data.str));

    uint8_t plaintext = atoi(data.str);
    //uint8_t plaintext[16] = "test";
    uint8_t iv[IV_LENGTH_CBC];
    uint8_t cypherdata[sizeof(plaintext)];
    uint8_t decryptdata[sizeof(plaintext)];

    Serial.println("Beginning of the encryption !");
    status = aes_cbc_encrypt(&cfg, &plaintext, sizeof(plaintext), iv, cypherdata, KEY_SLOT);
    if (status == ATCA_SUCCESS)
    {
        Serial.println("encrypted");
        status = aes_cbc_decrypt(&cfg, cypherdata, sizeof(cypherdata), iv, decryptdata, KEY_SLOT);
        if (status == ATCA_SUCCESS)
        {
            Serial.print("Decrypted text is : ");
            for (size_t i = 0; i < sizeof(decryptdata); i++)
            {
                Serial.print((char)decryptdata[i]);
            }
            Serial.println("");
        }
    }
    else
    {
        // See file atca_status.h for the code Error
        Serial.print(F("Impossible do the encryption | Code Error 0x"));
        Serial.println(status, HEX);
        return;
    }
    delay(1000);
}

Now I'm seeing this in the terminal (no errors on compile!):
encrypted
ERROR Decrypt : ATCA_BAD_PARAMI2C send 1 bytes to addr 0x30: 01

When I change (the aes_cbc_encrypt function expects a length of 16)
sizeof(plaintext)

to
16

I see:
Decrypted text is : ␀␀␀␀␀␀␀␀l��?���?

When I proved that the encrypt/decrypt portion of my code was working, this is what "plaintext" was:
 uint8_t plaintext[16] = "test";

No text as image please. You can copy the error message as text into your question and format it the same way as the code

The function expects a pointer to the data. Try passing it by reference as &plaintext. Though I'm not sure if you really want that. The variable name plaintext suggests, that it should be text. Though it is just a number (8 bit unsigned integer)

Again, you seem to think, that plaintext contains a text message. It does not. sizeof(plaintext) is always 1, since plaintext has only 1 byte. You are encrypting a single "character", though not really a character, but the binary representation of the number. It really doesn't make any sense to me, that you would encrypt a single byte. Why are you doing the atoi() when assigning plaintext? The commented line suggests, that this should be an array containing a c string.

chrisl,
In the other working code, I had
uint8_t plaintext[16] = "test";
Without the EEPROM bit, this worked. When I try replace "test" with data.str, it gives a compile error. If I need to call something other than plaintext, fine. I'm a hardware guy that is trying my best to get better at firmware, so sorry if I'm ignorant about simple things.

The function atoi() tries to interpret a string as a textual
representation of a number written in decimal. For example, atoi("42")
returns the integer 42. Here:
uint8_t plaintext = atoi(data.str);

You are asking it to interpret "test", which does not look like a
number. In such a case, atoi() returns zero. I do not know what was
your intent, but it was probably not this.
Further down, you have
uint8_t cypherdata[sizeof(plaintext)];
uint8_t decryptdata[sizeof(plaintext)];

Given that plaintext is a single byte, its length is one. Thus this is
declaring two arrays of length one. Again, you probably meant something
else.

From you comment, I understand that you want plaintext to represent
the string "test" as an array of uint8_t.
Since both char and uint8_t represent bytes, no conversion is
needed. You can simply use the address of the original char array and
“pretend” it is the address of an array of uint8_t:
uint8 *plaintext = (uint8_t *) data.str;

I just what the string "test" stored in EEPROM and then converted in to uint so it can be placed in the aes_cbc_encrypt function. I changed the atoi command to toInt and still get the same thing. I'll edit the post to explain that in the original aes_ebc_encrypt example, I was using uint8 plaintext[16] = "test"; and that was working

that makes sense. That worked and I just put it 16 for the sizeof(plaintext). That should work for now. Thanks!

source: Stack Exchange

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

sort: votes


text:
SdFat.h pin selection ESP8266
This super simple code, that saves data to a csv file, works perfectly fine on my Arduino Uno (I am using the default SPI pins).
However, for my project I need to use an ESP8266. Does the library automatically use the default SPI pins for any other boards?
In my code I have tried changing the CS pin from 10 to 15 for the ESP8266. All I get is "Initialization failed"! I figure, I need to somehow change the other SPI pins like MOSI, MISO and SCK. Is there a way to do this? I'm an absolute noob so sorry in advance if I oversaw some kind of easy fix.
#include <SdFat.h>

SdFat sd;
SdFile file;

void setup() {
  Serial.begin(9600);
  if (!sd.begin(10, SD_SCK_MHZ(50))) {
    Serial.println("Initialization failed!");
    return;
  }

  if (!file.open("data.csv", O_RDWR | O_CREAT | O_AT_END)) {
    Serial.println("Error opening file!");
    return;
  }

  file.println("Sensor1,Sensor2,Sensor3");
}

void loop() {
  float sensorReading1 = 1;
  float sensorReading2 = 1;
  float sensorReading3 = 1;

  file.print(sensorReading1);
  file.print(",");
  file.print(sensorReading2);
  file.print(",");
  file.println(sensorReading3);

  file.sync();

  delay(1000);
}

So I just tried again and somehow I happened to replace the SD_SCK_MHZ(50), that worked on my arduino Uno, with SPI_HALF_SPEED. Now the same code as above works perfectly fine on my esp8266.

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


text:
What module can I use for receiving 433.42 MHz transmissions with ASK/OOK modulation?
I am looking for a module that would be able to receive communication in the 433.42 (ch01) range with ASK/OOK modulation. Can someone recommend anything that would work and not be an expensive general purpose SDR module?
Long story: I have tried using the cheap RF 433MHz modules(picture below). I was able to modify the transmitter by de-soldering 433.92 crystal & soldering-in 433.42 one (picture two).
Now I have no way of testing this, as I am not receiving any communication while using the standard receiver that is tuned to 433.92 MHz. There doesn't seem to be any obvious way to tune the receiver to 433.42 MHz.
Reference ebay example for the crystal oscillator.

I was able to solder the crystal ... solder where? ... are you sure that it is a crystal?

please add a reference to the pictures into your post ... edit the post, do not write a comment

This is quite a good description of those modules and how to use them https://lastminuteengineers.com/433mhz-rf-wireless-arduino-tutorial/. If the receiver is no longer tuned to your modified transmitter, then you could try adjusting its [the receiver's] trimmer (brass coloured screw in the green cube).

It turns out that:

the receiver DOES work with the different frequency when the range is sufficiently small (a couple centimetres at most)
the library that I was using was expecting different kinds of transmissions so it wasn't showing anything useful
only low level interrupt service routine is actually giving me access to the actual data from the module
the issue that is complicating things with those modules is that in the absence of actual transmission noise is getting amplified and the module is outputting gibberish, so serious thinking needs to go into recognising when actual transmission starts & ends


text:
Find MAC address of client connected to ESP32 Bluetooth SPP via esp32-Arduino Bluetooth serial library
Let's suppose I'm using Espressif's Arduino-esp32 Bluetooth Serial library with code similar to the following:
#include "BluetoothSerial.h"

// snip

BluetoothSerial bts;
bool firstTime = true;

void setup() {
  bts.begin("bts");
}

void loop() {
  if (firstTime && bts.hasClient()) {
    // somehow get the MAC address of the client that paired & opened a connection
    firstTime = false;
  }
}

First, I ran the above code and paired a MacBook Pro to the ESP32.
I then opened a terminal window & ran system_profiler SPBluetoothDataType.
Among other things, it gave me:

the 6-byte MAC address of the laptop's Bluetooth controller

the 6-byte MAC address of the connected ESP32

I originally thought the following (executed on the ESP32, in loop()) would fetch the MAC address of the client connected to the ESP32:
uint8_t[6] mac;
bts.getBtAddress(mac);

But when I printed it as hex, it matched the MAC address the MacBook said belonged to the ESP32.
Likewise, I was originally under the impression that ESP.getEfuseMac() would return the base MAC address from which the ESP32's Ethernet, WiFi, and Bluetooth MAC addresses are all derived, but it returned a value that looks nothing at all like either one of the MAC addresses printed by system_profiler.
What do I need to do to get the MAC address of the connected Bluetooth SPP client that's the reason the call to bts.hasClient() is returning true?


text:
Having issues with RS232 UART wiring to a physical PC connection
TL;DR: Attempting to connect UART2 on ESP32-WROOM to a physical PC RS232 results in odd behavior and ESP32 crashes or errors. Suspect electrical design problems. Wondering if I need special consideration for voltages or diodes to avoid feedback to GPIO connectors on ESP side.

Hello! I'm relatively new to the community. I'm attempting to build a tool that will interact with a video conference bridge on its serial port to do room automation (mute/unmute/answer/raise_blinds/dim_lights/etc). Since the bridge interface is serial, I want to have two usable RS232 ports. One to interact with the bridge and the other to act as a console for troubleshooting and configuration.
I've purchased several ESP32-WROOM kits and have a good portion of the rest of the tool built, but I'm now struggling with getting UART2 to talk to my physical serial port on my PC so I can troubleshoot the actual bridge interactions. I've built a test sketch that just sends "Hello!" every second or so to UART2 and echoes anything it receives on UART2 back to UART0. UART0 is set for 115200 and UART2 is set to 9600. I have changed this to match and it made no difference.
Configuration:

UART0 is 115200,8N1 on standard USB console.
UART2 is 9600,8N1 on default GPIO 17/18 (TX2/RX2).
Pin17/18 and ground are wired to an 8 port single row header which is then plugged into a Teansic RJ45 breakout board.
Using Arduino IDE serial monitor to observe. Shows as COM3 on my PC.
UART2 is connected to a StarTech USB to RJ45 adapter made specifically for Cisco consoles (ICUSBROLLOVR) it shows as COM7 and I'm just using Putty to observe.

Sketch:
#include <HardwareSerial.h>

#define RXD2 16
#define TXD2 17
#define Serial0 Serial
#define Serial2 SerialPort

HardwareSerial Serial2(2);

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

void loop() {
  while (Serial2.available()) {
    Serial0.printf("[%012d]      In: ", esp_timer_get_time());
    //Serial0.print(char(Serial2.read()));
    Serial0.print(Serial2.readStringUntil('\n'));
    Serial0.print("\n");
  }
  while (Serial0.available()) {
    Serial2.printf("\n[%012d]  Insert: ", esp_timer_get_time());
    //Serial0.print(char(Serial2.read()));
    Serial2.print(Serial0.readStringUntil('\n'));
    Serial2.print("\n");
  }
  Serial0.printf("[%012d]     Out: ", esp_timer_get_time());
  Serial0.print("Hello!\n");
  Serial2.print("Hello!\n");
  delay(1100);

}

Behaviors:
When I connect my PC up, it receive characters but they are (consistent) garbage of about the right number of characters. It looks like:

▒::
   ▒[▒::
        ▒[▒::
             ▒[▒::
                  ▒[▒::
                       ▒

I sometimes receive phantom characters in from the PC even though I'm not sending anything.
If I loop UART2 back on itself (connect TX to RX at my serial header) I get a perfect response back out UART0 as though the input was coming from the PC.
If I send data from the PC to UART2, it results in crashes/errors similar to the following. The error implies it is rebooting, but it is not:
rst:0x7 (TG0WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13964
load:0x40080400,len:3600
entry 0x400805f0
[000000011533]     Out: Hello!
[000001111758]      In:
[000002111056]     Out: Hello!

I've observed the electrical output with an oscilloscope and it casually looked like a good RS232 signal. I went so far as to convert my character string to little endian binary and add the start and stop bits and it looks exactly like it should to me except that I am expecting that 0 and 1 should be in the range of -3 to -10 and +3 to +10 and instead the pattern appears to be about +400mV for 1 and markbits and just above zero for a 0 (relative to ground).

I have found very little to reference for RS232 to an actual PC. Almost everything appears to be logic level connections ESP32 to ESP32 or peripheral board to ESP32.
I suspect that this is a case of needing circuitry to convert the logic level voltages to external RS232 +10/-10v ranges and perhaps diodes or something to prevent phantom feedback since TX/RX have a shared ground, but I'm flying blind. I'm hoping someone here has experience with this and can point me to an answer or better reference materials.

I think I found the answer to my own question by Googling around for widgets.
There are a bunch of kits out there that do just this but Sparkfun was kind enough to provide me with a diagram on exactly how to build it.
SparkFun tutorial
I'll leave this out here for others and I'm still looking for feedback, but I think I have my answer.
It wasn't obvious to me (but should have been) that the board is only going to deal with low voltage positive (TTL) signals and the onboard UART doesn't magically make it inverted, higher voltage signals.


text:
Attempt to change an ESP8266's flashs layout over-the-air
Backstory
Several Tasmota devices based on an ESP8285 have to be flashed with alien firmware. The devices' programming ports are not accessible (except for one dummy device which was cracked open for testing).
The Tasmota firmware currently installed is based on the Arduino core, uses ESP8266httpUpdate.h and allows to OTA-update from a http server.
Problem
The problem is that the Tasmota firmware for the ESP8266 (=8285) family always uses a 1MB partition scheme while my specific device is based on the ESP8285H16 which incorporates 2MB of flash.
The second half of flash memory is therefore unused.
What I want to do
Using only over-the-air updates I want to update the Tasmota devices' flash layout so that the full 2MB of flash can be used and eventually upload a firmware that is bigger than what's currently possible.
Ideally the final flash layout uses a completely new partition scheme.
How can it be achieved?
I know this can be challenging and will probably require multiple intermediate firmware versions.
This is okay because the upgrade process will not happen "in the field" (but still no physical access to the chips) and occasional fails are acceptable - the process will be tested beforehand.
There's already a related answer from @Majenko here, but it covers the ESP32.
While I know where to start with an ESP32, I'm a bit puzzled with the ESP8266/8285:
I tried to read the whole flash images of the device to get a picture of what I'm dealing with and found the flash layout to be completely different from what I'm used to (ESP32).
Mainly, there wasn't a partition table at flash address 0x8000 while the Espressif documention specifies this exact address.
I found almost no documentation about the ESP8266 partition scheme as defined by the Arduino core:

Where in flash is the partition table?
If there is none, how does OTA work on ESP8266?
Where in flash is the bootloader?
Where does the filesystem begin (if there is one)?

Requirements

The flash layout needs to be changed using only OTA updates
Any information stored in the current flash or filesystem may be deleted
Multi-step updates are no problem
There's physical access to one device so the routine can be tested

Edit: Illustration
This is the normal OTA routine according to the docs:

and this is what I have in mind:

But for this I need to know the borders of each section, ideally during runtime.

As it turns out the update routine of ESPhttpUpdate.h works just fine when the flash layout changes after an OTA update.
At least in my case where the second half of flash memory is unused.
If there was a file system in the initial installation, it will be lost.
Though, it should be possible to even preserve the filesystem if it is copied to the right location before a firmware with different partition scheme is uploaded, but I have no need to follow that path now...
to summarize...

A Tasmota firmware was installed on a 2MB ESP8285H16. Since Tasmota firmware for ESP8266/8285 devices uses only 1MB of flash - maybe something like ~500kB sketch, ~400kB OTA, ~100kB FS).
The second half of flash was unused and the maximum size of a firmware that could be directly uploaded over-the-air was therefore ~400kB .

An intermediate firmware was provided on a http server for the device to update.
This firmware:

was built for a 2MB flash layout (1MB sketch, ~700kB OTA, ~256kB FS)
contains nothing but Wifi login and the OTA routine
Upon success, this update will leave the flash in the new layout

With the additional 300kB of OTA memory, the device could now be updated to the final firmware. This firmware was built with the same partitioning like the intermediate firmware.

This is the platformio.ini which was used in my case:
[env:esp8285]
platform = espressif8266
framework = arduino
board = esp8285

board_build.filesystem = littlefs
board_build.ldscript = eagle.flash.2m256.ld
board_build.mcu=esp8285
board_upload.flash_size=2MB
board_build.flash_mode=dout

monitor_speed = 115200
upload_port = COM5

If there is only little space left for OTA in the original flash layout, the firmware binary can be gzip'ed to save some memory.


text:
Why does my Arduino show weird characters with my code?
When I had the code run just the LCD it worked perfectly fine, but when I added an HC-SR04 without changing the text it showed weird characters. All I had the code do with the HC-SR04 was print it in the serial monitor.
// include the library code:
#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 5, e = 4, d4 = 3, d5 = 2, d6 = 1, d7 = 0;
const int trigPin = A0;
const int echoPin = A1;
LiquidCrystal lcd(rs, e, d4, d5, d6, d7);

void setup() {
  // set up the LCD's number of columns and rows:
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.print("zach is cool");
  pinMode(trigPin,OUTPUT);
  pinMode(echoPin,INPUT);
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  long duration, inches, cm;
  lcd.setCursor(0, 1);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);

  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();

  delay(100);
}

long microsecondsToInches(long microseconds) {
  // According to Parallax's datasheet for the PING))), there are 73.746
  // microseconds per inch (i.e. sound travels at 1130 feet per second).
  // This gives the distance travelled by the ping, outbound and return,
  // so we divide by 2 to get the distance of the obstacle.
  // See: https://www.parallax.com/package/ping-ultrasonic-distance-sensor-downloads/
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds) {
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the object we
  // take half of the distance traveled.
  return microseconds / 29 / 2;
}

It looks like you have the LCD connected to pins 0 and 1.  Those are the Serial Rx and Tx pins.  When you also use Serial in your sketch it creates a conflict.  Move those two lines from the LCD to different pins and update the sketch.

it was the Tx and Rx pins Thank You!

Thanks.  Please mark as solution if it fixed the problem.

With the following code, I ran an HCSR04 and a 16x2 LCD with Arduino UNO. It ran successfully.
#define trigPin 8
#define echoPin 9
#define pinIR 7
// Define variables:
float duration=0.00;
float distance=0.00;
int visitor,sum,threshold,temp;

// declaring variables to hold the new and old IR states
boolean oldIRState = LOW;
boolean newIRState = LOW;

#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
  // Define inputs and outputs:
  pinMode(pinIR, INPUT);
  pinMode(trigPin, OUTPUT);

  pinMode(echoPin, INPUT);
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Visitor=");
  lcd.print(visitor);

  //Begin Serial communication at a baudrate of 9600:
  Serial.begin(9600);
}

void loop() {
  // Clear the trigPin by setting it LOW:
  newIRState = digitalRead(pinIR);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  // Trigger the sensor by setting the trigPin high for 10 microseconds:
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Read the echoPin, pulseIn() returns the duration (length of the pulse) in microseconds:
  duration = pulseIn(echoPin, HIGH);
  // Calculate the distance:
  distance = duration /58.82 ;

  // Print the distance on the Serial Monitor (Ctrl+Shift+M):
  Serial.print("Distance = ");
  Serial.print(distance);
  Serial.println(" cm");

  delay(1000);
  if(distance<=10 && abs(temp)>=70)
  {
    visitor++;
    lcd.clear();
    lcd.print("Visitor=");
    lcd.print(visitor);

  for(int i=0;i<500;i++)
 {

 sum +=distance;
 delay(5);

 }
 threshold = sum/500;
  }

temp=threshold-distance;

 if ( newIRState != oldIRState )
  {

    if ( newIRState == LOW && visitor>0 )
    {

        visitor--;
         lcd.clear();
    lcd.print("Visitor=");
    lcd.print(visitor);

      }

    }
    oldIRState = newIRState;

}

You can follow this code and circuit arrangement. I also suggest you check the HCSR04 and LCD separately with The Arduino. You can also check this Arduino UNO pinout configuration guideline This will be helpful for any Arduino UNO project you work on.

Thank you, I will try this. I tried simplifing the code to just the LCD and it didnt work either so that is probably the issue.

can you explain to me the IRstate and Is and extra stuff you added? I'm new to this and I don't understand the new code.

Actually, there was two sensors in my setup. One was the HCSR04, another was the IR obstacle sensor. I was making a visitor counter. The HCSR04 was counting people entering the room. IR sensor was counting people exiting the room. When you are working with the HCSR04, you do not need the variables associated with the IR sensor. You can get a simplified example here: https://www.theengineeringprojects.com/2017/08/ultrasonic-sensor-arduino-interfacing.html  This one only features an Arduino UNO and an HCSR04.


text:
Controlling dynamixel servo from Arduino-Mega
I was trying to control a dynamixel servo from Arduino Mega. The protocol for the communication is half duplex, and I successfully sent data to the servo motor and got it actuated/turned the LED on and off. However, unfortunately, the status packet coming back from the servo is somehow corrupted. I am only getting everything 0xFF.
The code used is
#include <Arduino.h>

#define Direction_PIN PG5

#define TX_DIRECTION (PORTG |= 1<< Direction_PIN)
#define RX_DIRECTION (PORTG &= ~(1<<Direction_PIN))

#define FOSC 16000000
#define BAUD 57600
#define BAUD_UBRR (FOSC / 16/ BAUD - 1)

void USART_initialization();

void USART_Transmit(unsigned char data);

unsigned short update_crc(unsigned short crc_accum, unsigned char *data_blk_ptr, unsigned short data_blk_size);

void sendData_to_Dxl(unsigned char *packet, uint8_t n);

void USART_initialization() {
    /* Set baud rate */
    UBRR2H = (unsigned char) (BAUD_UBRR >> 8);
    UBRR2L = (unsigned char) BAUD_UBRR;
    /* Enable receiver and transmitter */
    UCSR2B = (1 << RXEN2) | (1 << TXEN2) | (1 << RXCIE2) | (1 << TXCIE2);
    /* Set frame format : 8data, 1stop bit; no parity */
    UCSR2C = (3 << UCSZ20);
}

/*
 * DXL Specific Codes
 */
unsigned short update_crc(unsigned short crc_accum,
                          unsigned char *data_blk_ptr,
                          unsigned short data_blk_size) {
    unsigned short i, j;
    unsigned short crc_table[256] = {
            0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
            0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
            0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
            0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041,
            0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2,
            0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1,
            0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1,
            0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082,
            0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192,
            0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1,
            0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1,
            0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2,
            0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151,
            0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162,
            0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132,
            0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101,
            0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312,
            0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321,
            0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371,
            0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342,
            0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1,
            0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2,
            0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2,
            0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381,
            0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291,
            0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2,
            0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2,
            0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1,
            0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252,
            0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261,
            0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231,
            0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202
    };

    for (j = 0; j < data_blk_size; j++) {
        i = ((unsigned short) (crc_accum >> 8) ^ data_blk_ptr[j]) & 0xFF;
        crc_accum = (crc_accum << 8) ^ crc_table[i];
    }
    return crc_accum;
}

void setup() {

    DDRG = (1 << Direction_PIN); // setting the pin4:PG5 as output for controlling the direction
    RX_DIRECTION;

    USART_initialization();

    uint8_t CRC_L = 0x00;
    uint8_t CRC_H = 0x00;

    /* LED ON */
    unsigned char TxPacketLed_ON[] = {
            0xFF, 0xFF, 0xFD, 0x00,
            0x01,
            0x06, 0x00,
            0x03,
            0x41, 0x00,
            0x01,
            CRC_L, CRC_H
    };
    /* LED OFF */
    unsigned char TxPacketLed_OFF[] = {
            0xFF, 0xFF, 0xFD, 0x00,
            0x01,
            0x06, 0x00,
            0x03,
            0x41, 0x00,
            0x00,
            CRC_L, CRC_H
    };

    uint8_t n;

    while (true) {

        n = sizeof(TxPacketLed_ON);
        sendData_to_Dxl(TxPacketLed_ON, n);

        delay(1000);
        n = sizeof(TxPacketLed_OFF);
        sendData_to_Dxl(TxPacketLed_OFF, n);

        delay(1000);
    }
}

void sendData_to_Dxl(unsigned char *packet, uint8_t n) {
    uint8_t CRC_L, CRC_H;
    unsigned short CRC;
    CRC = update_crc(0, packet, n - 2);   // 12 = 5 + Packet Length(7)

    CRC_L = (CRC & 0x00FF);               //Little-endian
    CRC_H = (CRC >> 8) & 0x00FF;

    packet[n - 2] = CRC_L;
    packet[n - 1] = CRC_H;

    TX_DIRECTION;
    for (uint8_t i = 0; i < n; i++) {
        USART_Transmit(packet[i]);
    }
}

void loop() {

}

void USART_Transmit(uint8_t data) {
    /*Wait for empty transmit buffer*/
    while (!(UCSR2A & (1 << UDRE2)));
    /*Transfer the data*/
    UDR2 = data;
}

ISR(USART2_TX_vect) {
    RX_DIRECTION;
}

The schematic of the circuit made to drive the servo is shown below. Where PIN4 is the direction pin and TX and RX are the UART transmit and Receive corresponding to the Serial 2

There is no part in the code for receiving the status data from the servo motor after the instruction set is sent. A logic analyzer was used, and the instruction data is shown as send, but the status data is all 0xff.
what is the mistake I am doing here.?
The various link I have used
MOTOR USED
dynamixel protocol 2.0
74LS126 datasheet
74HC06 datasheet
I have tried the library from this answer here, but the status was faulty.


text:
Why is conversion time 10 times slower in my ESP32-WROOM-32U?
The following code is used to show conversion time and maximum sampling frequency. The code is from this GitHub page for a spectrum analyzer based on the ESP32. The author in his YouTube video shows that his reading is around 10 μs for the conversion time and around 100000 Hz as maximum sampling frequency.
Here is my case:
Conversion time: 93.54 uS
Max sampling frequency: 10690.92 Hz

It is 10 times slower! What is the problem?
#define AUDIO_IN_PIN 35

int analogValue;
unsigned long newTime;

void setup() {
  Serial.begin(115200);
  Serial.println("START");
}

void loop() {
  newTime = micros();

  // Do 1 million reads and record time taken
  for (int i = 0; i < 1000000; i++) {
    analogValue = analogRead(AUDIO_IN_PIN);

  }

  float conversionTime = (micros() - newTime) / 1000000.0;
  Serial.println("END");
  Serial.print("Conversion time: ");
  Serial.print(conversionTime);
  Serial.println(" uS");

  Serial.print("Max sampling frequency: ");
  Serial.print((1.0 / conversionTime) * 1000000);
  Serial.println(" Hz");
}

Edit: Sorry my bad, I added yield() to see what happens, but nothing has changed.
Edit: I have tried the @thebusybee recommandation and the result is the same!
void loop() {

  newTime = micros();
  //delay(10);
  //delay(100);
  delay(1000);
  // Do 1 million reads and record time taken
  for (int i = 0; i < 1000000; i++) {
    analogValue = analogRead(AUDIO_IN_PIN);

  }

  float conversionTime = (micros() - newTime) / 1000000.0;
   Serial.println("END");
  Serial.print("Conversion time: ");
  Serial.print(conversionTime);
  Serial.println(" uS");

  Serial.print("Max sampling frequency: ");
  Serial.print((1.0 / conversionTime) * 1000000);
  Serial.println(" Hz");
}

No luck yet! But I have found a better solution for my case esp32_is2_adc_reading

Probably that yield() as it might introduce task switching and so

In the github project, that you linked, the author doesn't yield

Yeah, I added yield() to see what happens, but nothing has changed!

Try removing the println("START"); from setup(). Serial interrupts while transmitting data during the sampling stage might slow it down.

I added the start and end print to calculate the time, it wasn't there in the beginning, yet nothing changes.

Delay before the loop reading the analog values, to make sure that no serial transmission takes place. You have some 60 to 70 characters per test, these need about 6ms at 115200 baud. Start with delay(10); to see what happens. -- Please [edit] your question to add your then current code and results.

@the busybee no luck mate!

Next try: Toggle a port pin in the acquiring loop and use the oscilloscope to see what's really happening.

Read this: Slower ADC Sampling rate using firmware versions 2.0.6, 1.0.6, or 1.0.5 compared to version 1.0.4. Earlier versions of the ESP32 Arduino Core might have had a much shorter ADC conversion time.

Also see here on Electronics StackExchange: Why doesn't the sampling rate of the ESP32 go any higher than 10 kHz?. No solutions however.

If you have found a solution, please write an actual answer that is self-contained and mark it. This is the way this site is intended to work. You can and probably should provide the link to the external resource. However, the answer shall have enough details to understand it without visiting that resource.


text:
Same LED but different brightness on same PIN
I connected a led to pin 7 (with a small resistance to avoid burning it) and tried the code below, with and without pinMode as output
void setup() {
  pinMode(7, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  digitalWrite(7, HIGH);
  delay(5000);
  digitalWrite(7, LOW);
  delay(200);

  Serial.println("hello world");
}

Why does commenting the line pinMode(7, OUTPUT); make the led dimmer ?

try pinMode(7, INPUT); and pinMode(7, INPUT_PULLUP);

not sure what i'm supposed to understand @jsotola
it seems pull up is default but what is it?

All the pins are configured as INPUT by default on startup. So if you leave out the pinMode(7, OUTPUT);, pin 7 will still be configured as input. An Input doesn't provide any current (or only a very very low leak current), so the LED will be off in this time.
When you write HIGH to a pin, while it is configured as INPUT, you are activating the internal pullup resistor. This is a resistor (typically about 10kOhm) from the pin to Vcc (HIGH level) inside the microcontroller itself. Now a small current - set by the total resistance (your resistor + internal pullup) - can flow through the diode, making it light up very dim.
Configuring a pin as INPUT with the internal pullup resistor activated can be done in one command: pinMode(7, INPUT_PULLUP);, which makes the intent more clear, but does exactly the same under the hood as setting to INPUT and writing HIGH to the pin.


text:
strip.clear() is not clearing/turning off the NeoPixel strip after resetting the ESP8266
In the code below which is running on a WEMOS D1 (ESP8266), a NeoPixel strip turns on 1 LED in red which moves left to right and then right to left whilst the board attempts to connect to Wi-Fi in the while (WiFi.status() != WL_CONNECTED) loop.
If I hold down the button 'SW' connected to the pin D7 and click the reset button, the code turns on the 7 segment display, however the LED on the NeoPixel strip which was last lit remains on (as though it is 'frozen'). Once I exit the while(configRPM > 0){ loop, all goes back to normal and the NeoPixel strip unfreezes.
I thought strip.clear() would clear the NeoPixel strip near the start of setup() but that does not appear to work. I thought adding a delay might fix it and it hasn't. Why is the NeoPixel strip not turning off when the board is reset and how do I fix it?
Here is the code:
#include <ESP8266WiFi.h> // Include the ESP8266WiFi library.
#include <ELMduino.h> // Include the ELMduino library.
#include <Adafruit_NeoPixel.h> // Include the Adafruit NeoPixel library.
#include <Encoder.h>
#include <TM1637Display.h>
#include <EEPROM.h>

// Define the addresses where you want to store your variables in EEPROM
#define ADDR_MINIMUMRPM 0
#define ADDR_MAXIMUMRPM (ADDR_MINIMUMRPM + sizeof(int))

#define CLK D1
#define DT D2
#define SW D7

#define CLK_TM1637 D5
#define DIO_TM1637 D6

TM1637Display display(CLK_TM1637, DIO_TM1637);
Encoder encoder(CLK, DT);

int configTriggered = 0;
int buttonReleased = 0;
int configRPM = 0;
int minimumRPM = 2500;
int maximumRPM = 6000;
int currentPosition = minimumRPM - 100;
int oldPosition = -1000;
int newPosition = 0;

// WiFi credentials and server details
const char* ssid = "WIFI_OBDII"; // Set the SSID of the ELM327.
WiFiClient client; // WiFiClient is a class that defines how to create objects that represent WiFi clients. client is an object of this class, allowing the ESP8266 to function as a WiFi client.
ELM327 myELM327; // Creates an object named myELM327 of the ELM327 class. This object represents an instance of the ELM327 OBD-II interface, allowing the program to interact with it using methods provided by the ELM327 class.

const int neopixel_Count = 16; // Indicates that there are 16 NeoPixels in the strip, with IDs ranging from 0 to 15.
Adafruit_NeoPixel strip(neopixel_Count, D8, NEO_GRB + NEO_KHZ800); // Initializes a NeoPixel strip object with 16 NeoPixels connected to pin D2, using the color order Green-Red-Blue and a data transmission frequency of 800 KHz.

const int potentiometer_Pin = A0; // Sets the constant variable potentiometer_Pin to A0, being the ID of the analog pin

int rpm = 0; // RPM variable which is taken from the car and used in the code.

void setup() { // Setup function to initialize NeoPixels and establish WiFi and ELM327 connections.
  pinMode(SW, INPUT_PULLUP);
  Serial.begin(9600);
  display.clear();

  strip.begin(); // Initialize NeoPixels.
  delay(100);
  strip.clear(); // Initialize all pixels to 'off'.

  EEPROM.begin(sizeof(minimumRPM) + sizeof(maximumRPM));
  EEPROM.get(ADDR_MINIMUMRPM, minimumRPM);
  EEPROM.get(ADDR_MAXIMUMRPM, maximumRPM);

  if (digitalRead(SW) == LOW){
    configRPM = 1;
    display.setBrightness(0x0f); // Set brightness to maximum
    delay(50);
  }

  while(configRPM > 0){
    if (digitalRead(SW) == HIGH) {
      buttonReleased = 1;
      delay(50);
    }

    if (digitalRead(SW) == LOW && buttonReleased == 1 && configRPM == 1) {
      buttonReleased = 0;
      configRPM = 2;
      minimumRPM = currentPosition;
      Serial.println("Value saved for minimum RPM is " + String(minimumRPM));
      currentPosition = maximumRPM;
      display.showNumberDec(currentPosition);
      delay(50); // Debounce delay
    }

    if (digitalRead(SW) == LOW && buttonReleased == 1 && configRPM == 2) {
      buttonReleased = 0;
      configRPM = 0;
      maximumRPM = currentPosition;
      Serial.println("Value saved for maximum RPM is " + String(maximumRPM));
      display.clear();

      EEPROM.put(ADDR_MINIMUMRPM, minimumRPM);
      EEPROM.put(ADDR_MAXIMUMRPM, maximumRPM);
      EEPROM.commit();
      EEPROM.end();

      delay(50); // Debounce delay
    }

    newPosition = encoder.read();

    if (newPosition != oldPosition) {
      if (newPosition > oldPosition) {
        currentPosition += 100; // Increase by 100 for each clockwise turn
      } else {
        currentPosition -= 100; // Decrease by 100 for each counterclockwise turn
      }

      // Limiting the current position within 0 to 9990
      if (currentPosition < 0) {
        currentPosition = 0;
      } else if (currentPosition > 9900) {
        currentPosition = 9900;
      }

      display.showNumberDec(currentPosition);
      oldPosition = newPosition;
    }
  }

  Serial.println("Connecting to " + String(ssid)); // Print the SSID in the serial monitor.

  WiFi.mode(WIFI_STA); // Set the Wi-Fi mode as 'station' where the ESP8266 act as a client of a network.
  WiFi.begin(ssid); // Initates the process for connecting to the Wi-Fi network of the ELM327.

  while (WiFi.status() != WL_CONNECTED) { // While the Wi-Fi status of the ESP8266 is not connectied to the ELM327 Wi-Fi network, execute the following code.
    movePixels("right", neopixel_Count, 100); // Move from the left most LED to the right most LED with a delay of 100 milliseconds.
    movePixels("left", neopixel_Count, 100); // Move from right most LED to left most LED with a delay of 100 milliseconds.
    Serial.print("."); // Print "." in the serial monitor.
  }

  Serial.println("\nConnected to Wifi. The IP address of the ESP8266 is: " + WiFi.localIP().toString()); // Print the IP address of the ESP8266.

  if (!client.connect(IPAddress(192, 168, 0, 10), 35000)) { // This line tries to connect the client object to a server at the IP address 192.168.0.10 and port 35000. If the connection fails, it executes the code inside the if block.
    Serial.println("Connection to ELM327 failed. Resetting and restarting the ESP8266."); // If the connection fails, print this line.
    ESP.reset(); //  completely resets the ESP8266 microcontroller, disconnecting it from any Wi-Fi network and restarting its setup process defined in the setup() function.
  }
  myELM327.begin(client); // Initialize ELM327.
}

void loop() { // Loop function to continuously read RPM and update NeoPixels.
  rpm = myELM327.rpm(); // Read the RPM from the ELM327.

  if (myELM327.nb_rx_state == ELM_SUCCESS) { // Check for ELM327 communication status. If successful, do the following.
    Serial.print("RPM: " + rpm); // Print the RPM to the serial monitor.
    updateNeopixels(rpm); // Update the NeoPixels based on RPM.
  } else if (myELM327.nb_rx_state != ELM_GETTING_MSG) { // Check if the ESP8266 is not currently receiving a message from the ELM327.
    myELM327.printError(); // Print ELM327 error if communication is not successful.
  }
}

void updateNeopixels(int rpm) { // Function to update NeoPixels based on RPM
  strip.clear(); // Clear all NeoPixels.

  if (rpm >= 2500 && rpm < 5900) { // If the RPM is between the two values, do the following. The max RPM for this loop is higher to make all LEDs red for between 5800 and 5900.
    // Specifying the number of LEDs on the left and right to create a converging effect.
    int leftIndex = map(rpm, 2500, 5800, 0, neopixel_Count / 2 - 1); // Map the RPM from 2500 to 5800 to the range of 0 to 7.
    int rightIndex = neopixel_Count - 1 - leftIndex; // Take the leftIndex from 15.

    // For example, if the RPM is 5800, leftIndex = 7 and rightIndex = 8.

    // Map RPM to colors
    int red = map(constrain(rpm, 2500, 5800), 2500, 5800, 0, 255); // Map RPM to the amount of 'red' of the LEDs. The higher the RPM, the more red.
    int green = map(constrain(rpm, 2500, 5800), 2500, 5800, 255, 0); // Map RPM to the amount of 'green' of the LEDs. The higher the RPM, the less green.

    // For example, if the RPM is 5800, red = 255 and green = 0. This will apply to all LEDs to be lit.

    // Left side of the strip
    for (int i = 0; i <= leftIndex; i++) { // The loop increments i by 1 whilst i <= leftIndex, moving towards the right end of the strip. i++ is done after the body of the loop completes.
      strip.setPixelColor(i, strip.Color(red, green, 0)); // Set the color of the NeoPixel matching the ID of i.
    }

    // Right side of the strip (mirroring the left side)
    for (int i = neopixel_Count - 1; i >= rightIndex; i--) { // The loop decreases by 1 whilst i >= rightIndex, moving towards the left end of the strip. i-- is done after the body of the loop completes.
      strip.setPixelColor(i, strip.Color(red, green, 0)); // Set the color of the NeoPixel matching the ID of i.
    }

  } else if (rpm >= 5900) { // If the RPM is at least 5900, do the following.
    for (int i = 0; i < neopixel_Count; i++) { // The loop increments i by 1 whilst i < neopixel_Count (16) as you can't send a single command to change the colour of all LEDs.
      strip.setPixelColor(i, strip.Color(255, 0, 255)); // Set the color of each NeoPixel to purple.
    }
  }
  strip.setBrightness(map(analogRead(potentiometer_Pin), 0, 1023, 0, 255)); // Map the potentiometer value to brightness range (0-255) and set the strip brightness accordingly. 1023 is the max value obtainabled from the analog-to-digital (ADC) converter.
  strip.show(); // Update the NeoPixel strip.
}

void movePixels(String direction, int numPixels, int delayTime) { // Function to move NeoPixels from left to right and then right to left.
  for(int i = 0; i < numPixels; i++) { // The loop increments i by 1 whilst i < numPixels (16).
    int index;
    if (direction == "right") { // If direction is equal to 'right'...
      index = i; // Set index to i.
    } else if (direction == "left") { // If direction is equal to 'left'...
      index = numPixels - 1 - i; // Set index to numPixels (16) - 1 - i.
    } else { // Handle an invalid direction input (neither right or left).
      return; // Exit the function with no response.
    }
    strip.setPixelColor(index, strip.Color(255, 0, 0)); // Set the LED which shares the ID of index as red.
    strip.setBrightness(map(analogRead(potentiometer_Pin), 0, 1023, 0, 255)); // Map the potentiometer value to brightness range (0-255) and set the strip brightness accordingly. 1023 is the max value obtainabled from the analog-to-digital (ADC) converter.
    strip.show(); // Update the NeoPixel strip.
    delay(delayTime); // Adjust the delay based on potentiometer value.
    strip.setPixelColor(index, 0); // Turn off the LED at the current position.
  }
}

I thin you need to call strip.show() also when using clear

We can have a look at the clear() function inside the Adafruit_Neopixel library. In Adafruit_Neopixel.cpp you can find at line 3396 (searching for clear(void) will get you there):
void Adafruit_NeoPixel::clear(void) { memset(pixels, 0, numBytes); }

This is a very short function. memset() sets all bytes in a defined range to the provided value. So all bytes in pixels will be set to zero. Though this is only the libraries internal memory. There is no IO action here, no code sending data to the Neopixels.
That means: clear() only acts on the libraries internal representation of the strip, just like setPixel() and its siblings. To actually send the data to the Neopixels you still need to call strip.show(), which then takes the libraries internal representation of the strip and sends the data out through the digital pin to the Neopixels.
I want to encourage people to look into the source code of libraries, they use. When you learn how to read them, you can get quick answers even without understanding the actual full implementation of the library.

Thank you very much for your response @chrisl, much appreciated!


text:
Grove relay stuttering
I have bought this Grove relay: Grove - Relais | Kiwi Electronics.
I use it to drive a low-power water pump with a 9v battery. So the pump circuit is isolated from the Arduino circuit.
When the Arduino sends 'high' to the relay, this relay begins to stutter. Contract-release at high frequency. This only happens if the pump is attached. I have bought multiple relays and they all behave in the same way.
When I use a non-grove relay, such as Twee-kanaals 5V relais module | Kiwi Electronics I do not have this issue.
I made a small film of both relays: https://photos.app.goo.gl/szHHE5EGqjHzJy3f7 (shared google photo's album).
Why does this happen? What can I do to correct this issue with the Grove-relais?
I want to use these Grove-relays because they need to be used by students that are used to work with Grove components.
Please help!
The code:
void setup() {
  Serial.begin(9600);
  pinMode(7, OUTPUT);
  Serial.println("start");
  delay(1000);
}

void loop() {
  digitalWrite(7, HIGH);
  delay(2000);
  digitalWrite(7, LOW);
  delay(3000);
}

This is the schema:

Please try the grove relay again with the exact same connections and code as the other relay. If it then still happens, then the relay board is probably broken

I use the exact same code and arduino setup. I tested it with multiple different Grove relays. They all have the same issue.

could be bad code

The circuit works properly when I switch to the non-grove relay. And it's just setting a digital output port high. Can't be much bad about that, i think. :-(

maybe the arduino is resetting

Have you tried triggering the relay by directly attaching the relays input pin with ground and 5V? You need to narrow down the source of the problem. Currently we don't have much to work with. Please also include your code in the question, so that we can check that too.

yes indeed, it is resetting, but I do not understand why. It only happens when I put the load on the high-power side of the relay. Without the pump attached, the relay just functions fine. I tested two relays, both show the same behaviour. So adding a load on the high-power side affects the low-power side?! That should be completely isolated, right?

The Grove relay in your photo (the black one) clearly says DC3V: you are presumably energising the coil, as well as controlling it, with DC5V.
Perhaps you should try their 5V version:

The datasheets says the 3.3v version can be operated both at 3.3v and at 5v. It has a 5-3.3v shifter a board: https://wiki.seeedstudio.com/Grove-Relay/


text:
Combining esp_wakeup_timer with external interrupt ext0
I'm working with ESP32-Dev-Kit1 and MMA8452Q accelerometer. I want the ESP to read the accelerometer for 10s, then go to sleep for 10s. If within the sleep period, the accelerometer magnitude reading exceeds the threshold, it will also wake up the ESP.
#include <Wire.h>
#include "SparkFun_MMA8452Q.h"

MMA8452Q accel;

void setup()
{
  Serial.begin(9600);
  Serial.println("MMA8452Q Test Code!");

  accel.init(SCALE_2G, ODR_6);

  // Configure the wake-up source
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0); // GPIO 33, HIGH logic level
}

void loop()
{
  // Read accelerometer and print values for 10 seconds
  unsigned long startTime = millis();
  unsigned long duration = 10000; // 10 seconds
  while (millis() - startTime < duration) {
    if (accel.available()) {
      accel.read();
      printCalculatedAccels();
    }
  }

  // Sleep for 10 seconds or wake up immediately if magnitude > 1.0
  Serial.println("Going to sleep or waking up if magnitude exceeds 1.0...");
  Serial.flush(); // Ensure all serial data is sent
  float magnitude = sqrt(pow(accel.cx, 2) + pow(accel.cy, 2) + pow(accel.cz, 2));
  if (magnitude > 1.0) {
    Serial.println("Magnitude exceeded 1.0, waking up...");
    esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 1);
    esp_deep_sleep_start();

  } else {
    esp_sleep_enable_timer_wakeup(10 * 1000000); // 10 seconds
    esp_deep_sleep_start();
  }
}

void printCalculatedAccels()
{
  Serial.print(accel.cx, 3);
  Serial.print("\t");
  Serial.print(accel.cy, 3);
  Serial.print("\t");
  Serial.print(accel.cz, 3);
  Serial.println("\t");
}

start by reducing your code to only the sleep code ... remove all of the accelerometer code ... when the 10 second sleep works, then add the accel code

I made some small changes to my code. Now, it works fine by sleeps for 10 seconds and triggers when the threshold is exceeded. But there's a problem about the threshold trigger part: the ext0 wakeup function activates only before it enters sleep mode. Once the ESP is sleeping, it only wakes up using the timer, not by ext0 interrupt.
is there something I miss in configuration?


text:
Removing the L from F_CPU in assembly
I am developing a mixed c++ /asm project.
In the asm I am using F_CPU to do some busy waiting as follows. However, by default, the F_CPU is defined with a trailing L (for long). The asm is not able to cope with the L. I can fix this by manually defining a new define in the asm,  but that's a pretty dirty solution. What's the correct way to fix this?
.macro _delay_1u
.rept (F_CPU/1000000)
nop
.endr
.endm

Welcome to SE/Arduino! As a regular user of this network, you know how these sites work. Unfortunately, your issue does not seem to be about Arduino, I suggest to read "[ask]". Please clarify the relation, and while you're at it, add the compiler and assembler versions you are using. (Disclaimer: I did not vote down.)

Thanks for your comment. If I am not mistaken,  F_CPU is a define provided by the Arduino environment.

Actually, it is a standard macro for avrgcc/avrlibc and not specific to Arduino. If that is your issue's only connection to Arduino, you might want to ask on [so] instead. It looks as an general GNU assembler question, which AFAIK does not accept suffices on integer literals.

That is indeed the culprit. Since pretty much any single arduino project defines F_CPU, I hoped it was a commonly encountered problem. I did not find any answers googling, though. Probably having time critical sections written in asm is less common than one would imagine.

You have an XY problem: You want to busy-wait some cycles depending on the system's clock frequency. You think you can realize that with (inline) assembly and a repetition macro. But as you found, the assembler does not accept C literals with suffixes, as it has no usage for the type information.
However, this is a possible solution to do busy-wait in C++: built-in functions of the compiler. In this case you want to use __builtin_avr_delay_cycles().
This simple sketch shows the effectively generated machine code. It contains some calls of digitalWrite() to separate the different delays.
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  // delay 1us
  __builtin_avr_delay_cycles(F_CPU / 1000000UL);
  digitalWrite(LED_BUILTIN, LOW);
  // delay 1 cycle
  __builtin_avr_delay_cycles(1UL);
  digitalWrite(LED_BUILTIN, HIGH);
  // delay 10 cycles
  __builtin_avr_delay_cycles(10UL);
  digitalWrite(LED_BUILTIN, LOW);
  // delay 100 cycles
  __builtin_avr_delay_cycles(100UL);
}

Commonly you will not have access to the intermediately generated files, because the IDE uploads the resulting machine code directly to the target. However, as long as the IDE is running, you can access the files from some temporary location. In my case, this is the path "/tmp/arduino_build_119348", and I copied the linked sketch to save it. It is an ELF file named "test.ino.elf".
The tool "avr-objdump" (exists in your Arduino IDE installation) disassembles the binary code of loop() for further investigation:
avr-objdump -d test.ino.elf

If you want, you can redirect the output into a file.
The relevant part is this quite at the end:
 2c4:   81 e0           ldi r24, 0x01   ; 1
 2c6:   0e 94 70 00     call    0xe0    ; 0xe0 <digitalWrite.constprop.0>
 2ca:   85 e0           ldi r24, 0x05   ; 5
 2cc:   8a 95           dec r24
 2ce:   f1 f7           brne    .-4         ; 0x2cc <main+0xc8>
 2d0:   00 00           nop
 2d2:   80 e0           ldi r24, 0x00   ; 0
 2d4:   0e 94 70 00     call    0xe0    ; 0xe0 <digitalWrite.constprop.0>
 2d8:   00 00           nop
 2da:   81 e0           ldi r24, 0x01   ; 1
 2dc:   0e 94 70 00     call    0xe0    ; 0xe0 <digitalWrite.constprop.0>
 2e0:   83 e0           ldi r24, 0x03   ; 3
 2e2:   8a 95           dec r24
 2e4:   f1 f7           brne    .-4         ; 0x2e2 <main+0xde>
 2e6:   00 00           nop
 2e8:   80 e0           ldi r24, 0x00   ; 0
 2ea:   0e 94 70 00     call    0xe0    ; 0xe0 <digitalWrite.constprop.0>
 2ee:   81 e2           ldi r24, 0x21   ; 33
 2f0:   8a 95           dec r24
 2f2:   f1 f7           brne    .-4         ; 0x2f0 <main+0xec>
 2f4:   00 00           nop

The different delays are clearly visible. The following parts have the number of cycles in parentheses.
Since the system's clock of my chosen target is 16 MHz, the delay of 1us needs to wait 16 cycles:
 2ca:   85 e0           ldi r24, 0x05   ; (1)
 2cc:   8a 95           dec r24         ; (1)
 2ce:   f1 f7           brne    .-4     ; (1 if not taken, 2 if taken)
 2d0:   00 00           nop             ; (1)

We have nCycles = 1 + 4 * (1 + 2) + 1 + 1 + 1 = 16.
To delay 1 cycle, the compilers inserts exactly one nop:
 2d8:   00 00           nop

To delay more cycles, a loop is used, as before. This is the delay of 10 cycles:
 2e0:   83 e0           ldi r24, 0x03   ; (1)
 2e2:   8a 95           dec r24         ; (1)
 2e4:   f1 f7           brne    .-4     ; (1 if not taken, 2 if taken)
 2e6:   00 00           nop             ; (1)

We have nCycles = 1 + 2 * (1 + 2) + 1 + 1 + 1 = 10.
And the delay of 100 cycles is:
 2ee:   81 e2           ldi r24, 0x21   ; (1)
 2f0:   8a 95           dec r24         ; (1)
 2f2:   f1 f7           brne    .-4     ; (1 if not taken, 2 if taken)
 2f4:   00 00           nop             ; (1)

We have nCycles = 1 + 32 * (1 + 2) + 1 + 1 + 1 = 100.

Just as a complement to the busybee's answer: the avr-libc provides the
macros _delay_ms() and _delay_us() for busy-wait delays.
Internally, they use __builtin_avr_delay_cycles() and F_CPU to
provide the required number of delay cycles. For example, on an Uno,
_delay_us(0.25);  // delay for 0.25 µs

compiles to
rjmp .  ; 2 cycles
rjmp .  ; 2 cycles

which takes exactly 0.25 µs (4 cycles at 16 MHz) and takes
less code space than four nops.

A really preferable solution! In one place I do not find again, I remember a minimum delay like 3 µs. I might have been hallucinating but I'm not an AI. :-D


text:
RFID-RC522 unable to detect some tags but correctly reads others
I'm trying to read an NFC/RFID tag using Arduino and an RFID-RC522 module.
Currently I'm able to successfully read the data from a key fob and from a card that were included with the RC522, but the tag I want to read is not detected at all.
Is the module I'm using unsuitable to read this kind of tags?
Tag:

Code:
    #include <SPI.h>
    #include <MFRC522.h>

    #define SS_PIN 10
    #define RST_PIN 9

    MFRC522 rfid(SS_PIN, RST_PIN);

    void setup() {
      Serial.begin(9600);
      SPI.begin(); // init SPI bus
      rfid.PCD_Init(); // init MFRC522

      Serial.println("Tag reader on");
    }

    void loop() {
      if (rfid.PICC_IsNewCardPresent()) { // new tag is available
        if (rfid.PICC_ReadCardSerial()) { // NUID has been readed
          MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
          Serial.print("RFID/NFC Tag Type: ");
          Serial.println(rfid.PICC_GetTypeName(piccType));

          // print NUID in Serial Monitor in the hex format
          Serial.print("UID:");
          for (int i = 0; i < rfid.uid.size; i++) {
            Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " ");
            Serial.print(rfid.uid.uidByte[i], HEX);
          }
          Serial.println();

          rfid.PICC_HaltA(); // halt PICC
          rfid.PCD_StopCrypto1(); // stop encryption on PCD
        }
      }
    }

Output read on Serial Monitor when I scan the key fob and the card:
Tag reader on
RFID/NFC Tag Type: MIFARE 1KB
UID: BC 38 B4 12
RFID/NFC Tag Type: MIFARE 1KB
UID: 86 FB 35 B6

Wiring:

My RC522 module:

seems that way .

the tag I want to read is not detected at all - what tag, exactly?

Did you see on https://en.wikipedia.org/wiki/Radio-frequency_identification that there are multiple frequencies in use? The RC522 knows only 13,56 MHz...

@NickGammon the flat round one in the picture.

I was hoping for a part number, not a picture of some coils. As the busybee said, different RFID cards operate at different frequencies.

@NickGammon I see, thank you. Unfortunately I don't know the specification of the tag. It's on the package of consumable goods, whose production is now discontinued. These tags used to be read by a cooking device. Would you suggest me to try another RFID module according to the shape of the tag? Which one?

I did a Google Lens search of that image, and some results appear to suggest it is a 13.56 MHz tag, however I didn't see exactly a match on your image. Possibly another RFID module would work, or possibly that tag has failed. Those tags have a small microprocessor on them, conceivably it has gone bad.

@NickGammon thank you so much for your valuable help. If so, I should be able to read it (if the tag itself is not faulty). I suspect I may be affected by this issue.

Quite possibly. I buy stuff from eBay, and it often works, but I also wonder if I am dealing with seconds. You know, stuff the manufacturer discarded because it didn't work properly.


text:
Problem adding IR receiver to smart car
I’m making a smart car using an arduino uno, sensor shield v5, motor control with a L298N and a servo motor + HC-SR04 ultrasound sensor. I want to add a IR receiver on the board so I can also control the car with a remote.
The problem is when I add in the code for the IR Receiver and make the 3 additional connections, the right motor doesn’t respond anymore, it only moves at the beginning, though slower than the left one during the initial setup, then only the left motor functions properly.
Here is the whole code with comments next to the IR-Receiver specific code:
#include <Servo.h>
#include <IRremote.h> //IR Receiver
Servo servo ;
const int trigPin = 13;
const int echoPin = 12;
const int servoPin = 11;
const int enAPin = 6;
const int in1Pin = 7;
const int in2Pin = 5;
const int in3Pin = 4;
const int in4Pin = 2;
const int enBPin = 3;
const int receiverPin = 9; //IR Receiver

IRrecv irrecv(receiverPin);  //IR Receiver
decode_results signals; //IR Receiver

enum Motor { LEFT, RIGHT };
void go(enum Motor m, int speed)
{
  digitalWrite (m == LEFT ? in1Pin : in3Pin , speed > 0 ? HIGH : LOW );
  digitalWrite (m == LEFT ? in2Pin : in4Pin , speed <= 0 ? HIGH : LOW );
  analogWrite(m == LEFT ? enAPin : enBPin, speed < 0 ? -speed : speed );
}

void testMotors ()
{
  static int speed[8] = { 128, 255, 128, 0 , -128, -255, -128, 0};
  go(RIGHT, 0);
  for (unsigned char i = 0 ; i < 8 ; i++)
    go(LEFT, -speed[i]), delay(200);

  for (unsigned char i = 0 ; i < 8 ; i++)
    go(RIGHT, speed[i]), delay(200);
}

unsigned int readDistance()
{
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  unsigned long period = pulseIn(echoPin, HIGH);
  return period * 343 / 2000;
}

#define NUM_ANGLES 7
unsigned char sensorAngle[NUM_ANGLES] = {60, 70, 80, 90, 100, 110, 120};
unsigned int distance [NUM_ANGLES];

void readNextDistance()
{
  static unsigned char angleIndex = 0;
  static signed char step = 1;
  distance[angleIndex] = readDistance();
  angleIndex += step ;
  if (angleIndex == NUM_ANGLES - 1) step = -1;
  else if (angleIndex == 0) step = 1;
  servo.write(sensorAngle[angleIndex]);
}

void setup () {
  Serial.begin(9600);  //IR Receiver
  irrecv.enableIRIn();  //IR Receiver

  pinMode(trigPin , OUTPUT);
  pinMode(echoPin, INPUT);
  digitalWrite(trigPin, LOW);
  pinMode(enAPin, OUTPUT);
  pinMode(in1Pin, OUTPUT);
  pinMode(in2Pin, OUTPUT);
  pinMode(in3Pin, OUTPUT);
  pinMode(in4Pin, OUTPUT);
  pinMode(enBPin, OUTPUT);
  servo.attach(servoPin);
  servo.write(90);
  go(LEFT, 0);
  go(RIGHT, 0);
  testMotors();
  servo.write(sensorAngle[0]);
  delay(200);
  for (unsigned char i = 0 ; i < NUM_ANGLES ; i ++)
    readNextDistance(), delay (200);
}

void loop () {

 //IR Receiver:
  if (irrecv.decode(&signals)) {
        Serial.println(signals.value);
        irrecv.resume();
        if (signals.value == 0xFFA25D) {
          Serial.println("yeees");
        }
  }

  readNextDistance ();

  unsigned char tooClose = 0;
  for (unsigned char i = 0 ; i < NUM_ANGLES ; i++)
    if (distance[i] < 200)
      tooClose = 1;

  if (tooClose) {
    go(LEFT, 180);
    go(RIGHT, -80);
  } else {
    go(LEFT, -180);
    go(RIGHT, 180);
  }
  delay (50);
}

Are you saying that the code that works correctly is only different because it is missing the lines commented with //IR Receiver? Maybe you should also post the working code (that doesn't have the IR receiver code included), so that we may compare the two versions ourselves?

@Greenonline Yes, exactly. If you remove the few lines commented with //IR Receiver, then you have the working code.

It seems to be the motors conflicting with the IRremote library, due to both usage of same timers. Need to find another library or find a way to make it use another timer

Please post that as an answer

Finally found the problem: it is due to the IRremote library using the same timers than the Servo.
Solutions are to change the specified timer that the IRremote library uses in the library files (didn't work for me though) or to not use a library for either the IR receiver or the Servo or to change the physical connection of the component plugged in a pin also used by a timer.
Link to an Arduino Forum post suggesting an alternative for controlling the Servo without a library


text:
Arduino Nano Er.43
I am using an Arduino Nano clone on Windows 10. Worked perfectly fine for a year until I uploaded a code with some Serial functions. After trouble shooting for hours with drivers, and checking all over the internet, I come to the conclusion that the last code uploaded was faulty and corrupted the Serial interface. Every time I plug it in now, Windows gives a popup saying "USB Device Not Recognized."
I have checked for shorts all over the board, but none found, and the indicating lights are working fine. From what I have read, I believe that the board is still recoverable.
How to get it working?
The link to the board purchased: Mini USB Nano V3.0 ATmega328P CH340G 5V 16M Micro-Controller Board for Arduino Nano Micro USB

For whole last year there was many issues with fake CH340G and solution was installing drivers from 2022 at latest (it got broken around jan/feb 23) and disabling auto update for drivers in windows update. It had slightly different symptoms, but it could get another update


text:
Running code inside void loop() vs inside a separate function with an infinite loop in it
I'm writing a program for running a stepper motor at a high RPM using accelStepper on a NodeMCU esp8266. Super New to the accelStepper but reading, experimenting and learning as I go
When the code to cycle the stepper one way and then the other is inside the void loop() it works as expected, but there's a bunch of other inputs I need to check in there for setting up the system and when they are all inside the void loop() they slow down the cycle noticeably as it does various digital and analog reads.
While the stepper is cycling I only really need to watch one e-stop input instead of everything so I figured to create a separate function with an infinite loop in it, call the stepper code there and just check the one input and return out of the function when done
Testing this and it partially works but the stepper only makes it part way to its end point and then abruptly stops (instead of decelerating) and then reverse and same thing.
Probably not even the right way of trying to solve my issue but it's what I came up with tonight.
Any help would be much appreciated.
Here's the entire test code I'm using. When I un-comment the block of code inside the void loop() and comment out the call to the go_to function it works perfectly fine. When that basically exact same block of code is run inside the go_to instead, it gives the weird results
    #include <AccelStepper.h>

    const int DIR = D6;
    const int STEP = D7;

    AccelStepper stepper(1,STEP,DIR);

    int EndPoint = 50000

    void setup()
    {
      stepper.setMaxSpeed(8000);
      stepper.setAcceleration(10000);
      stepper.setMinPulseWidth(10);
      stepper.setCurrentPosition(0);
      delay(2000);  // need to prevent partial run when loading
    }

    void loop()
    {
      /*  if this code runs it works perfectly
      stepper.run();
      if (stepper.currentPosition()==EndPoint)
        {
        NewEndPoint=0;
        stepper.moveTo(NewEndPoint);
        }
      else if (stepper.currentPosition()==0)
        {
        NewEndPoint=EndPoint;
        stepper.moveTo(NewEndPoint);
        }
        */

      go_to();

    }

    void go_to()
    {
      for(;;) // have tried while(true) also, same results
      {
      stepper.run();
      if (stepper.currentPosition()==EndPoint)
        {
        NewEndPoint=0;
        stepper.moveTo(NewEndPoint);
        }
      else if (stepper.currentPosition()==0)
        {
        NewEndPoint=EndPoint;
        stepper.moveTo(NewEndPoint);
        }
      }
    }

The reason I'm trying to get this to work is for the full program, there's several digital and analog reads than need to be done for speed, distance, number of cycles etc. that all must be in the void loop(), or called from there, and if they are in the same loop where the stepper.run() is it slows the RPM down a lot so I'm trying to get the stepper.run() into it's own loop where it's not looking at any inputs it doesn't need to but I ran into this problem and don't see why it's reacting the way it is.

both of the codes do the same thing ... the second code never exits back to loop()

They were supposed to do the same thing. It's the exact same code but when it's inside the separate function the stepper only goes part way towards the endpoint and then stops hard, delays a bit and then starts the reverse direction, goes part way and stops hard, then repeats. I never bothered adding the way out of the function since it's not working the way I expected.

there may be some housekeeping done at each iteration of loop() ... the loop inside go_to() prevents it from executing

If the stepper motor code has to be serviced quickly then you have to focus on the other code that you have removed from the loop() for this demonstration and which slowed it down. You must eliminate any blocking code such as delay() or complex float or other time intensive calculations. An alternative is maybe to move to the ESP32 platform where you can use RTOS to run fast and slow code more or less in parallel.

look at the random example sketch in the accelStepper library ... use distanceToGo instead of currentPosition for simpler code

Your problem lies in a part of your code that you have removed. Please, post a complete, testable (and tested!) example.

I've added the complete code that I'm testing, it's only the setup that is missing. This is the actual code I'm testing that works inside the void loop but only moves the steppers part way if run inside the separate function.

Can you try this on an AVR-based micro, an Uno or a Mega? My expectation is that you will see the motor run as expected, whether executing within loop() or within go_to().On an ESP8266, a lot more happens between calls to loop() than does on AVRs. It seems likely that some one or more of these background tasks on the ESP between calls to loop() is necessary for your motor code to execute properly. But when you run the motor in go_to() on an ESP, loop() never returns and those background tasks don't get done.

I can wire it and try on a mega tonight and see if that works. What you're saying about the background tasks between loop calls being missing makes a certain amount of sense. Will post back results

Or, an even simpler test, possibly even a fix: still using the ESP: just add a call to yield() inside the for(;;){} loop at the top or bottom of it. yield() is designed specifically to allow long-running processes such as yours to give the background an opportunity to do its necessary chores, at a point of the programmer's choosing.

So the original problem of the steppers acting differently inside a different function than the loop() certainly seems to be because of the "additional code that needs to run between iterations of the loop function", "On an ESP8266, a lot more happens between calls to loop() than does on AVRs" that was pointed out. Adding a yield() to the separate function fixed the stepper issue... I'll say that this problem is solved. Unfortunately it also brought up a different problem with my process so back to the drawing board.
Thanks so much for the insight and suggestions, I'm going to go and try some

loop already runs indefinitely, hence its name. You don't need to add another loop in your go_to function. Remove that and it should be functionally identical.

The ESP8266 has additional code that needs to run between iterations of the loop function.  If you are going to trap it elsewhere in some while loop, then you need to also be sure to call delay(0); or yield; in there so that it can handle its other business.  If the code around loop doesn't get run in time, then the board resets from the watchdog IIRC.  I believe that is the symptom you are seeing.
And like the others say, there is no good reason for a blocking loop in your code.  Let the loop function be the loop.

I'd like to have it in the main loop but I haven't figured out how to prevent the digital and analog reads that have to happen in there from slowing this run() down. Bad enough I'm still going to have to have a single digitalRead of the e-stop switch happen with this run(). Maybe using a interrupt (attachInterrupt()? ) would be a better option than the digitalRead().

Put those reads in an if statement so they only run when the other part isn't.  You're not running anything concurrently, so however you have it structured now you could just move the function back into loop.

No, an interrupt will just make it more complicated.  You need a boolean variable that tells which part should be happening and then a couple of if statements in loop to decide if loop is reading inputs or running steppers.  Really it should be able to do both.  There's really no reason that the stepper code needs to be blocking.  But for some reason everyone is reluctant to try to learn non-blocking techniques.

Adding the yield() to the end of the go_to() function resolved the weird behaviour of the stepper motors and now they act the same as they did when running the code within the loop(). BUT it's not treating the function as something that needs to be completed before returning to the main loop.... I've got some more reading to do on that command I guess. But it answers the question of why the test code wasn't working.

You shouldn't code it to need to be complete before returning to the main loop.  That is a poor blocking design.  Code it like a state machine so the loop can still run while the steppers are moving.

The simplest way to fix all of this is going to be to keep your stepper code within the loop function, but keep a variable that "remembers" when the stepper is running. Use that variable to know when not to do the time-consuming tasks. Let loop() return after each iteration whether the stepper is running or not. No yield() call will be needed. Just make sure to know when the stepper is running and don't do the long jobs if when is.
Perhaps something like this (untried!) code-structure:
void loop()
{
   static bool isStepping = false;
     :
   if( !isStepping ){
      /* call time-consuming tasks here; */

      if( time to start the stepper now ){
         /* set up any stepping conditions you need to here; */
         isStepping = true;
   }

   if( isStepping ){
      /* run one iteration of the stepper code; */
      if( stepping is complete ){
         isStepping = false;
      }
   }
}  // let your loop() return after each stepper iteration

I'll have to try some of these other approaches since the separate loop doesn't seem to work the way I was hoping, the yield did work to fix the stepper stopping but it created a different problem in the sub-function so I'm going to re-read all of these answers and suggestions and try a different approach.