text:
How to create minimal web server example with a dropdown menu?
I want to create a three-item menu: Verizon, T-Mobile, AT&T. Since the example uses LEDs, I'll do the same--except with a dropdown menu to select among the three.
I'm trying to combine these two examples:

https://randomnerdtutorials.com/esp8266-web-server
https://www.w3schools.com/html/tryit.asp?filename=tryhtml_elem_select

Except with phone carriers instead of cars:

I'm struggling on the polyglot part of the programming, combining the HTML and Arduino program in the middle:
        // Web Page Heading
        client.println("<form action='/action_page.php'>");
        client.println("  <select id='providor' name='providor'>");
        client.println("    <option value='verizon'>Verizon</option>");
        client.println("    <option value='tmobile'>T-Mobile</option>");
        client.println("    <option value='atnt'>AT&T</option>");
        client.println("  </select>");
        client.println("  <input type='submit'>");
        client.println("</form>");

        if (providor==verizon)
          client.println("
Provider Selected: Verizon
");
        else if (providor==tmobile)
          client.println("
Provider Selected: T-Mobile
");
        else if (providor==atnt)
          client.println("
Provider Selected: AT&T
");

Here is the rest of the program:
/*

Based from
https://randomnerdtutorials.com/esp8266-web-server

HTML tool
https://www.w3schools.com/html/tryit.asp?filename=tryhtml_elem_select
*/

#include <ESP8266WiFi.h>

// Replace with your network credentials
const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Auxiliar variables to store the current output state
//String output5State = "off";
//String output4State = "off";

// Assign output variables to GPIO pins
const int output5 = 14;    // D5 verizon
const int output6 = 12;    // D6 tmobile
const int output7 = 13;    // D7 atnt

// Current time
unsigned long currentTime = millis();
// Previous time
unsigned long previousTime = 0;
// Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;

void setup() {
  Serial.begin(115200);
  // Initialize the output variables as outputs
  pinMode(output5, OUTPUT);
  pinMode(output6, OUTPUT);
  pinMode(output7, OUTPUT);
  // Set outputs to LOW
  digitalWrite(output5, LOW);
  digitalWrite(output6, LOW);
  digitalWrite(output7, LOW);

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

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

  if (client) {                             // If a new client connects,
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    currentTime = millis();
    previousTime = currentTime;
    while (client.connected() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected
      currentTime = millis();
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();

            // turns the GPIOs on and off
            if (header.indexOf("GET /5/on") >= 0)
            {
              Serial.println("D5 on");
              output5State = "on";
              digitalWrite(output5, HIGH);
            }
            else if (header.indexOf("GET /5/off") >= 0)
            {
              Serial.println("D5 off");
              output5State = "off";
              digitalWrite(output5, LOW);
            }
            else if (header.indexOf("GET /6/on") >= 0)
            {
              Serial.println("D6 on");
              output4State = "on";
              digitalWrite(output6, HIGH);
            }
            else if (header.indexOf("GET /6/off") >= 0)
            {
              Serial.println("D6 off");
              output4State = "off";
              digitalWrite(output6, LOW);
            }
            else if (header.indexOf("GET /7/on") >= 0)
            {
              Serial.println("D7 on");
              output4State = "on";
              digitalWrite(output7, HIGH);
            }
            else if (header.indexOf("GET /7/off") >= 0)
            {
              Serial.println("D7 off");
              output4State = "off";
              digitalWrite(output7, LOW);
            }
            // Display the HTML web page
            client.println("<!DOCTYPE html>");
            client.println("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the on/off buttons
            // Feel free to change the background-color and font-size attributes to fit your preferences
            client.println("");

            // HERE
            // ↓
            // ↓
            // ↓
            // ↓

            // Web Page Heading
            client.println("<form action='/action_page.php'>");
            client.println("  <select id='provider' name='providor'>");
            client.println("    <option value='verizon'>Verizon</option>");
            client.println("    <option value='tmobile'>T-Mobile</option>");
            client.println("    <option value='atnt'>AT&T</option>");
            client.println("  </select>");
            client.println("  <input type='submit'>");
            client.println("</form>");

            if (providor==verizon)
              client.println("
Provider Selected: Verizon
");
            else if (providor==tmobile)
              client.println("
Provider Selected: T-Mobile
");
            else if (providor==atnt)
              client.println("
Provider Selected: AT&T
");

            // ↑
            // ↑
            // ↑
            // ↑

            client.println("");

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

Any suggestions or solutions on how to change or the correct code?

what do you expect the drop down menu to do?

Change a "provider" variable to whichever is selected. And in this case, turn on the LED corresponding to it (one of three LEDs should be on).

put the HTML code for the drop down menu right after the second button

I use

Look at the code in your post. It is syntax-highlighted, i.e. color-coded according to the grammar of the C++ language. Don't you see something weird with the colors around “HERE”? That's the syntax-highlighter showing you your syntax error.

And, further up in the first code block. Your quotes are not matching, all over the place.

First thing: be careful with matching your quotes. Every string literal
should be written as "bla, bla, bla", with no unescaped double-quotes
in between. Do use the syntax highlighting: it is here precisely for
helping you spot this kind of trivial programming mistakes. Also, for
writing very long constant strings, use the C++ “raw string literal”
feature: it just makes this easier.
Second thing, you should understand how a form submission works at the
HTTP level. You should be able to find the info on the Web but, to make
it short, when the user clicks on your form, the browser will send a
request looking like
GET /action_page.php?providor=verizon HTTP/1.1
Some-Header-Name: some header value
Other-Header-Name: other header value
...

You should parse this to find the actual provider between the '='
character and the following space. Also, get rid of action_page.php,
it is useless here.
Then a few random remarks:

Do not write “providor”: the correct spelling is “provider” (although
you may prefer “carrier” in this context).

Within an HTML document, the ampersand should be written &.

The HTML page needs a <title> element to be valid.

Remove the whole section of the code titled “turns the GPIOs on and
off”: it does not make sense in your context.

Now, to illustrate these points, here is how I would code parsing the
request:
// Find the provider in the URL.
String provider;
const String provider_before = "GET /?provider=";
int request_begin = header.indexOf(provider_before);
if (request_begin < 0) {
    provider = "unknown";
} else {
    int provider_begin = request_begin + provider_before.length();
    int provider_end = header.indexOf(' ', provider_begin);
    provider = header.substring(provider_begin, provider_end);
}

And here is how I would send the page to the client:
// At the beginning of the sketch (in global context).
const char page_before_provider[] = R"rawstr(<!DOCTYPE html>

<title>Phone carrier selection</title>
[...]

Provider Selected: )rawstr";
const char page_after_provider[] = "
\n\n\n";

// At the place where the page has to be sent.
client.print(page_before_provider);
if (provider == "verizon")
    client.print("Verizon");
else if (provider == "tmobile")
    client.print("T-Mobile");
else if (provider == "atnt")
    client.print("AT&T");
else
    client.print(provider);
client.print(page_after_provider);

For the global const char stuff, I am confused. Is that a function I should create? Tried putting some of that in, but pretty confused: https://github.com/adamaero/WebServer/blob/main/polyglot/ESP8266dropDownMenu/ESP8266dropDownMenu.ino

@adamaero: No, not in a function. “Global context” means outside any function. It's a constant declaration, just like ssid, to put at the beginning of the program. PS: do not worry about this until after you fix the first, most important issue: get your quotes matched.

Quotes were matched.

Since all the current answers are not clear to me, I'll try to come up with my own with `const char page_before_provider[] = R"rawstr(
)rawstr";`

@adamaero: 1. Do you believe quotes are matches in client.println("
carrier Selected: T-Mobile"
 ");? 2. If something is not clear in this answer, please tell what exactly you do not understand, so I can elaborate on that specific point.

Ok, now the quotes are matched... in the pseudo code that doesn't do anything to begin with.

Apart from the syntax errors (you aren't matching double quotes in multiple places) web pages don't work like that.
To do something like your form you:

Send the form, more-or-less like you have.

   if (providor==verizon)
       client.println("
Providor Selected: Verizon
");

You can't test the providor (provider?) right there. Do you mean if (providor=="verizon")?

The form has to be sent to the client, the user has to fill it in, and send it back. Thus you can't test for what they filled in a line or so under sending the form.

So, testing for what they entered is a subsequent step. It's a little hard to explain without taking dozens of paragraphs. I suggest reading up on how web forms work.

Here's an analogy:
Say you want to write to a company and apply for a job. You fill in a form and send it off. You do not, a moment later, check to see if you got the job. The form has to go to the company. Someone has to process it. Then they make a reply. The reply might say "in reference to your job application of 11 September 2023 you were/were not successful."
It's like that with HTML. The form, which the user fills in, is the initial step. Then the user fills it in. That might be an hour later. Then they press Send and the reply comes back to you. That's when you process the reply.


text:
Arduino Uno RFID-RC522 won't scan any card or tag
So I bought a RFID-RC522 module with a blue tag and a white card, and I searched for tutorials and found this library that I used it.
and here is my code :
#include <MFRC522.h>
#include <SPI.h>

#define SAD 10
#define RST 9

MFRC522 nfc(SAD, RST);

void setup() {
  SPI.begin();
  // Read a fast as possible. There is a limit for how long we are
  // allowed to read from the tags.
  Serial.begin(115200);

  Serial.println("Looking for MFRC522.");
  nfc.begin();

  // Get the firmware version of the RFID chip
  byte version = nfc.getFirmwareVersion();
  if (! version) {
    Serial.print("Didn't find MFRC522 board.");
    while(1); //halt
  }

  Serial.print("Found chip MFRC522 ");
  Serial.print("Firmware ver. 0x");
  Serial.print(version, HEX);
  Serial.println(".");
}

byte keyA[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, };
byte keyB[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, };

void loop() {
  byte status;
  byte data[MAX_LEN];
  byte serial[5];
  int i, j, pos;

  // Send a general request out into the aether. If there is a tag in
  // the area it will respond and the status will be MI_OK.
  status = nfc.requestTag(MF1_REQIDL, data);

  if (status == MI_OK) {
    Serial.println("Tag detected.");
    Serial.print("Type: ");
    Serial.print(data[0], HEX);
    Serial.print(", ");
    Serial.println(data[1], HEX);

    // calculate the anti-collision value for the currently detected
    // tag and write the serial into the data array.
    status = nfc.antiCollision(data);
    memcpy(serial, data, 5);

    Serial.println("The serial nb of the tag is:");
    for (i = 0; i < 3; i++) {
      Serial.print(serial[i], HEX);
      Serial.print(", ");
    }
    Serial.println(serial[3], HEX);

    // Select the tag that we want to talk to. If we don't do this the
    // chip does not know which tag it should talk if there should be
    // any other tags in the area..
    nfc.selectTag(serial);

    // Assuming that there are only 64 blocks of memory in this chip.
    for (i = 0; i < 64; i++) {
      // Try to authenticate each block first with the A key.
      status = nfc.authenticate(MF1_AUTHENT1A, i, keyA, serial);
      if (status == MI_OK) {
        Serial.print("Authenticated block nb. 0x");
        Serial.print(i, HEX);
        Serial.println(" with key A.");
        // Reading block i from the tag into data.
        status = nfc.readFromTag(i, data);
        if (status == MI_OK) {
          // If there was no error when reading; print all the hex
          // values in the data.
          for (j = 0; j < 15; j++) {
            Serial.print(data[j], HEX);
            Serial.print(", ");
          }
          Serial.println(data[15], HEX);
        } else {
          Serial.println("Read failed.");
        }
      } else {
        // If we could not authenticate with the A key, we will try
        // the B key.
        status = nfc.authenticate(MF1_AUTHENT1B, i, keyB, serial);
        if (status == MI_OK) {
          Serial.print("Authenticated block nb. 0x");
          Serial.print(i, HEX);
          Serial.println(" with key B.");
          status = nfc.readFromTag(i, data);
          if (status == MI_OK) {
            for (j = 0; j < 15; j++) {
              Serial.print(data[j], HEX);
              Serial.print(", ");
            }
            Serial.println(data[15], HEX);
          } else {
            Serial.println("Read failed.");
          }
        } else {
          Serial.print("Access denied at block nb. 0x");
          Serial.println(i, HEX);
        }
      }
    }

    // Stop the tag and get ready for reading a new tag.
    nfc.haltTag();
  }
  delay(2000);
}

and I connected the module like this :
===================================
|   RFID-RC522   |  Arduino Uno   |
___________________________________
|      SDA       |       10       |
|      SCK       |       13       |
|      MOSI      |       11       |
|      MISOI     |       12       |
|      RQ        |     Skipped    |
|      GND       |       GND      |
|      RST       |        9       |
|      3.3V      |       3.3V     |
===================================

and when I virify and uplaod the code, the RFID-RC522 module turned the light D1 to On (red light)
and in the serial it show :
Looking for MFRC522.
Didn't find MFRC522 board.

and when i try to scan the card or the tag nothing happened in the serial, I searched in google and i found that Arduino uno 3.3V pin is too weak, so i changed the 3.3V to 5V, and click in reset button of arduino uno board and check the serial and it showed :
Looking for MFRC522.
Found chip MFRC522 Firmware ver. 0xFF.

But still not scaning the tag or the card (also tried another tag and another card that i bought them from the same seller and still not working)
any help please, and thanks

use an external power supply that can deliver the necessary current ... please review the RFID-RC522 module datasheet for minimum power requirement

What is external power? a battery ? or resistor... and thanks for reply

a resistor is not a power supply ... do not use the Arduino to supply power... use anything that is able provide the required voltage to the RFID reader at the necessary current level ... 5 Vdc power supply is probably the most suitable

source: Stack Exchange

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

sort: votes


text:
Arduino Servo with temperature sensor (TMP36)
The essence of the program is to measure the temperature, and if the temperature is higher than 26 degrees, the servo rotates by 45 degrees, and if it's lower, it rotates by 179 degrees. However, a short circuit is occurring. At the moment of the first servo rotation, the temperature jumps to 40 degrees (the temperature is calculated from voltage), and after that, the servo continuously rotates back and forth because the temperature is fluctuating between 40 and 20 degrees. What could be the cause of this issue?
My code:
#include <Servo.h>
Servo myServo;
const int sensorPin = A0;
const float baselineTemp = 20.0;
int angle;
void setup() {
  myServo.attach(9);
  Serial.begin(9600);
}

void loop() {
  int sensorVal = analogRead(sensorPin);
  Serial.println("Sensor Value: ");
  Serial.print(sensorVal);
  float voltage = (sensorVal/1024.0) * 5.0;
  Serial.println("Volts:");
  Serial.print(voltage);
  Serial.println("Celcius:");
  float temperature = (voltage - .5) * 100;
  Serial.print(temperature);
  if (temperature < baselineTemp) {
    myServo.write(179);
  } else {
    myServo.write(45);
  }
  delay(800);
}

Output in terminal:
sensorVal: 149
 Volts:0.73
 Celcius:22.75
 sensorVal: 192
 Volts:0.94
 Celcius:43.75
 sensorVal: 154
 Volts:0.75
 Celcius:25.20
 sensorVal: 188
 Volts:0.92
 Celcius:41.80
 sensorVal: 150
 Volts:0.73
 Celcius:23.24
 sensorVal: 184
 Volts:0.90
 Celcius:39.84
 sensorVal: 151

Are all GNDs connected?

What could be the cause of this issue? ... the servo

@SimSon I have just one GND and it's connected to "-"

upvote for removing the picture and posting text

@jsotola Can you tell me why it happens?

maybe the power supply voltage changes when the servo runs

You need to power the servo through a separate power supply. High power devices such as motors etc. should not be powered via the Arduino's regulator.  That is surely affecting the analogRead() and therefore also the temperature reading as already noted by @jsotola.
Secondly, you need to add some hysteresis here to prevent continuous thrashing when the temperature is around the baseline:
if (temperature < baselineTemp) { myServo.write(179); }
else { myServo.write(45); }

Maybe try something like :
if (temperature < baselineTemp - 1.0 ) { myServo.write(179); }
elseif (temperature > baselineTemp + 1.0 ) { myServo.write(45); }

You could also try adding a capacitor across the power rails of the temperature sensor say 10uF very close to the sensor itself.

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


text:
Is there a way to increase the number of output pins in Arduino Uno?
I am an amateur. I know about Arduino, but I am still learning.
And I was making this Bluetooth rover with a camera, ultrasonic sensor, mecanum wheels, air-soft shooter, and sand sample collector. I am using two L298 motor drivers, because L23D requires soldering and is a bit less compatible with me. So, when creating this amazing robot I realised that I ran out of pinmode spaces for the air-cannon and some other features.
So, is there a way to increase the number of output pins in an Arduino Uno or can I connect the Rx and Tx pins of the Bluetooth module and the trig and echo pin and use them both as one for two more spaces?

There is I2C I/O expanders that can solve this issue.

As an extension to Dario.Casciato’s response, there are not only I²C I/O expanders, but also the simple 74HC595 IC, which can be cascaded and used via Arduino's shiftOut function. It needs three signal pins for 8 / 16 / 24 ...  outputs.
The link is not a purchase recommendation, but rather a technical hint.

thank you! I was able to use this and increase the number of features originally planned

It sounds like you are using some GPIOs ;) If you need more digital pins, you can use the analog pins as digital pins (if you didn't already).

If you already occupied these pins, then I would think about getting an I/O expander. It's a chip/IC that can be mostly controlled via I²C, offering you a way to scale your project's GPIO capabilities.

thank you for your comment, I wanted it to be a small robot for a competition but with your help I was able to add even more features than the air cannon!

@AnikSingh That's nice to hear! glad i could help!

What you probably want is called an ‘I/O Expander’. They come in many different varieties based both on exact means you use to communicate with them, how many I/O pins they give you, and what you can do with those pins.
The usual recommendation for use with an Arduino is an I²C based I/O expander, such a Microchip MCP23017 (available readily online from many sources and available in a DIP format so that you can use it with solderless breadboards), because this provides a reasonably fast interface that is very well supported on the Arduino and uses relatively few pins (only 2 pins are required, not counting Vcc and ground).
I’ve also personally used a Analog Devices DS2408 for this purpose before. It uses a 1-Wire interface, cutting the required pins down to only 1 not counting Vcc and ground, and also not actually requiring the use of a specific I/O pin like a proper I²C device would, but it’s also slower and not as nice to work with (you need a separate library to work with 1-Wire on most Arduino chips), and also only comes in SOIC packages (so requires some precise, but not necessarily difficult, soldering).
In theory you could also use an SPI I/O expander, but they are often a bit more of a pain to work with, and eat at last three pins (possibly four) other than Vcc and ground.

In theory, there are two other options in specific circumstances.
The first is a multiplexer chip, which is essentially a fancy solid-state switch with multiple outputs. These are only really practical if you just need to trigger external devices individually, though that may be viable for your use case (it could easily drive a simple level trigger for the airsoft gun and a simple edge trigger for the sand sample collector).
The second is to use a shift register. These are only viable if you have some way to latch outputs (for example, putting a gated D-latch on each output) or only need the outputs to be valid at specific points in time, because updating the outputs cycles each pin through the output values of each other pin. They’re great if you are doing something like implementing a parallel bus, but not as good if you need fast outputs that retain state.

Re “[shift registers] are only viable if you have some way to latch outputs”: the 74HC595, which is kind of a standard in Arduino land and has been mentioned in a previous answer, is double-buffered. A rising edge on RCLK latches the shift register proper into the storage register, which is the one you see on the outputs of the chip.

thank you so much I was able to complete the air cannon and even add more features!


text:
convert string representing a binary number to binary
I have a serial input "1111111" and I would like to convert this to a binary B1111111 that I can send to a led matrix.
I tried to search, but, all the results were misleading, led to full text to binary conversion. Please advise.
edit:
This is my sample code where I am missing a step in the conversion part
LedControl mat = LedControl(DIN_PIN, CLK_PIN, CS_PIN, MAX_SEG); // MAX7219
void OneLine() {

//input
char text[] = "11111110";
//convert to binary number somehow

//show one line
      mat.setRow(0, 0, convertednr);
}

"I tried to search, but, all the results were misleading", How about start from understanding of ASCII? An ASCII '1' that show on your Serial Monitor is binary 0x31, a binary value of 1 is ASCII '1' - '0' (0x31 - 0x30).

Have you searched for something like "C++ binary to int"? There is the strtoi() function, which also takes a parameter with the number base used (which is 2 for binary). Please try it

why do you need to convert to binary? ... what will you do with the binary number?

I receive this as serial input and would like to send it to a 8x8 led display row (max7219)

why do you need a binary number for that?

Welcome to SE/Arduino! Please take the [tour] to learn how this site works, and read "[ask]". Then come back and [edit] your question to add at least one example of what you tried.

@jsotola added sample code.

@chrisl: strtoi() is not standard. He should be using strtol().

@EdgarBonet Thanks, this did the job and I don't need to further convert this do binary, the ledcontrol can work with this.

Is your edit meant as a solution? If so, remove it from the question and write a proper answer. You can mark it (later) as accepted, if it fits you best. This is the way this Q&A site works, it is not a forum. -- If it is not a solution, [edit] and explain why.

@thebusybee the solution was in EdgarBonet's comment: convert to integer, then I can pass this to the led matrix without further conversion.

@vilmarci As mentioned by the busybee, you shouldn't change your original post to make it right. This confused the future readers of this post and they can't see where is the problem. You should either post your working code as an Answer, or simply leave it "as is".

As pointed out by @EdgarBonet, I can convert the string to binary number with strtoul() and pass this to my led control.
Adding this as an answer for future readers:
 LedControl mat = LedControl(DIN_PIN, CLK_PIN, CS_PIN, MAX_SEG); // MAX7219
void OneLine() {

//input
char text[] = "11111110";
//convert to number
uint32_t convertednr = strtoul(text, NULL, 2);
//print out
mySerial.println(convertednr);

//show one line
      mat.setRow(0, 0, convertednr);

you can use mySerial.println(convertednr, BIN);

Re “I can convert the string to decimal number”: Note that strtoul() converts the string to a binary (not decimal) number, and that is what you LED control is using (convertednr is a binary number). You may be confused by the fact that mySerial.println(convertednr) converts this binary number to a decimal string representation, for the purpose of displaying it on the serial port.

thanks @EdgarBonet, corrected the text


text:
Raspberry pi pico I2S work on byte by byte transfer but not on buffer read writes
I'm using a raspberry pi pico W and testing audio loopback (microphone to speaker in a loop) using INMP441 microphone and MAX98357 amp board.
Followed functions from this page https://arduino-pico.readthedocs.io/en/latest/i2s.html
I arrived at this code:
#include <I2S.h>

I2S* I2SOutputDevice = nullptr;
I2S* I2SInputDevice = nullptr;
#define I2S_SAMPLE_RATE 44100
#define I2S_BITS 24
#define BUFFER_LENGTH 256
#define I2S_BUFFER_SIZE 1024

uint8_t* data;

// the setup function runs once when you press reset or power the board
void setup() {

    I2SOutputDevice = new I2S(OUTPUT);
    I2SOutputDevice->setBCLK(16);
    I2SOutputDevice->setDATA(18);
    I2SOutputDevice->setBitsPerSample(I2S_BITS);
    I2SOutputDevice->setFrequency(I2S_SAMPLE_RATE);
    I2SOutputDevice->setSysClk(I2S_SAMPLE_RATE);
    I2SOutputDevice->setBuffers(2, BUFFER_LENGTH);

    pinMode(19,OUTPUT);
    digitalWrite(19,HIGH);

    I2SInputDevice = new I2S(INPUT);
    I2SInputDevice->setBCLK(20);
    I2SInputDevice->setDATA(22);
    I2SInputDevice->setBitsPerSample(I2S_BITS);
    I2SInputDevice->setFrequency(I2S_SAMPLE_RATE);
    I2SInputDevice->setSysClk(I2S_SAMPLE_RATE);
    I2SInputDevice->setBuffers(2, BUFFER_LENGTH);

    pinMode(LED_BUILTIN,OUTPUT);

    data = new uint8_t[I2S_BUFFER_SIZE];
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);

    I2SOutputDevice->begin();
    I2SInputDevice->begin();
}

// the loop function runs over and over again until power down or reset
void loop() {

    // does not work
    size_t actuallyRead = I2SInputDevice->readBytes(data, I2S_BUFFER_SIZE);
    I2SOutputDevice->write(data, actuallyRead);

    // works

    //int32_t L, R;
    //I2SInputDevice->read24(&L, &R);
    //I2SOutputDevice->write24(L, R);

}

As indicated in the code reading one sample at a time and writing works fine I can hear on speaker what I speak into the microphone.
however if I go the buffer read and write route all I get is noise form the speaker that does not react or correspond to any microphone input .
If I add a serial print to see how many bytes were read then it is a positive number the same as size of the buffer, so it is reading data but playback is missing in this case
what am I doing wrong?
Bonus question: INMP441 seem to have very low sensitivity , you have to speak very close to it which is nearly impractical , is this normal?

Please extend your test code to print the number of read bytes in each loop. Are you aware that both I²C transfers and serial transmissions need time, and therefore the playback can have another sampling rate?

I did print the read bytes and its always the full size of the buffer


text:
blink a Grove - RGB LED Stick
I am trying to blink a Grove - RGB LED Stick (10 - WS2813 Mini 3535) with this code:
#include "FastLED.h"

int ledState = LOW;       // ledState used to set the LED
long previousMillis = 0;  // will store last time LED was updated
long interval = 1000;     // interval at which to blink (milliseconds)

#define NUM_LEDS 10
CRGB myLeds[NUM_LEDS];

void setup() {
  FastLED.addLeds<NEOPIXEL, 4>(myLeds, NUM_LEDS);
}

void loop() {
  unsigned long currentMillis = millis();
  FastLED.setBrightness(25);

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      for (int i = 0; i < NUM_LEDS; i++) {
        myLeds[i] = CRGB::White;
        FastLED.show();
      }
    } else {
      for (int i = 0; i < NUM_LEDS; i++) {
        myLeds[i] = CRGB::Black;
        FastLED.show();
      }
    }
  }
}

Any idea why it does not blink?
Thanks

Your code sets the LEDs color depending on the value of ledState, but its value is never updated after initialization, so your LEDs remain white.

Thanks. Added the ledState = HIGH; and ledState = LOW;

@dkin did it now work with adding this?

Yes. Any other idea/comment is always welcome

Well, if the correction of a coding error, which was pointed out by @StarCat , solved the original problem then StarCat should convert the comment into an answer. Failing that, after waiting a reasonable period, the OP should write the answer.

In your code, you define the global variable ledState and initialize it to the value "LOW".
In the loop() function, the ledState variable is used to determine the (next) state of the LED once every 1000 milliseconds, like this:
...
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
  for (int i = 0; i < NUM_LEDS; i++) {
    myLeds[i] = CRGB::White;
    FastLED.show();
  }
} else {
  for (int i = 0; i < NUM_LEDS; i++) {
    myLeds[i] = CRGB::Black;
    FastLED.show();
  }
}
...

However, since your code does not change value of ledState to reflect the new state of the LED array, the next time the above if (...) comparison is run, the outcome is the same and the color of the LEDs not be changed.
The simplest change to make your LEDs blink as you intended, would be to change the above piece of code to the following:
...
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
  for (int i = 0; i < NUM_LEDS; i++) {
    myLeds[i] = CRGB::White;
    FastLED.show();
    ledState = HIGH;
  }
} else {
  for (int i = 0; i < NUM_LEDS; i++) {
    myLeds[i] = CRGB::Black;
    FastLED.show();
  }
  ledState = LOW;
}
...

An alternative (arguably more elegant) solution would be to declare ledState as a boolean (true/false) variable so that you can further simplify your code:
#include "FastLED.h"

bool ledState = false;    // ledState used to set the LED
long previousMillis = 0;  // will store last time LED was updated
long interval = 1000;     // interval at which to blink (milliseconds)

#define NUM_LEDS 10
CRGB myLeds[NUM_LEDS];

void setup() {
  FastLED.addLeds<NEOPIXEL, 4>(myLeds, NUM_LEDS);
}

void loop() {
  unsigned long currentMillis = millis();
  FastLED.setBrightness(25);

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (!ledState) {
      for (int i = 0; i < NUM_LEDS; i++) {
        myLeds[i] = CRGB::White;
        FastLED.show();
      }
    } else {
      for (int i = 0; i < NUM_LEDS; i++) {
        myLeds[i] = CRGB::Black;
        FastLED.show();
      }
    }
    ledState = !ledState;    // make ledState reflect the new LED state

  }
}


text:
Is the EEPROM the best alternative for store non-volatile values with Arduino?
SD-cards are capable of store values even if it is turned off.
I don't know what is the time that a EEPROM can keep a value in it's memory, but of course are better than the volatile memory.
There are some others ways of store non-volatile values for arduino?
Which of these need hardware built-in and which doesn't?
Are the EEPROM the best alternative (in terms of facility, durability, and cost) for store non-volatile values when we talk about Arduinos (or even microcontrollers in general)?

the best alternative for store non-volatile values. Updated question

Do you know what is a SQL?

I mean what is the best way to store non-volatile values in the Arduino, dear

it is a language for manipulating databases ... it is kind of irrelevant to the question

So, don't is the EEPROM and the SQL used for the same thing? Store non-volatile values?

instead of getting caught up in details like a grammar nazi, try to catch the idea behind the question

you are not understanding. . one person's best may be another person's don't care ... for example, one person may only be interested in data retention... another person may be interested in write speed ... etc.etc. .... so, what is your definition of best?

So you can respond like that: If you are interested in data retention, do like this... If you are interested in write speed, thus. In this way, we can have a broad understanding of the question. I am not able to define my question more than this, because if I could, I would be likely to respond it by myself.

then the EEPROM is not suitable because it has a limited number of write cycles available before it fails

I wouldn't say alternative, it's fundamentally different. EEPROM is basically stand alone (on chip, or on board) and small. For full blown SQL you'll probably need network connection and server with SQL. Alternative for EEPROM can be FRAM (almost unlimited writes), flash (size but less writes), sd card or similar (even bigger, also limited writes).

@jsotola thanks. Now i appreciate your response.

don't is the EEPROM and the SQL used for the same thing? ... you are confusing a hardware component with software ... a comparison between EEPROM and SD card would make more sense

@KIIV I am grateful. Let me do a question. Do sd card need hardware aditional parts or no? The FRAM kind of store and the flash you said, need aditional hardware too?

@jsotola ok, i will improve the question

Usually needs few wires and maybe slot or so. But no need for full blown server and network (another computer)

Question improved.

Your question got down-voted because asking what is the "best" thing is pretty subjective. You may as well ask what is the best car to buy. If you are more specific next time you may get a better response and less argument. A more general question like "what are the advantages and disadvantages of using EEPROM?" could probably be answered with a Google search.

EEPROM on the Atmega328P (such as on the Arduino Uno) holds 1KB (1024 bytes) and has a documented write/erase cycle of 100,000 writes.
So, if your application only needs to store 1024 bytes in a non-volatile way, and you do not plan to write more than 100,000 times then that is suitable.
The sort of things I would use EEPROM for are remembering settings (eg. fan speed, oven temperature, a password for accessing WiFi, that sort of thing).
I also personally use it for "remembering" RFID card codes for access to my house. In my experience, using it for that purpose, it has never "forgotten" a code. According to the datasheet it will retain data for 100 years at 25°C.
It is convenient because you don't need any extra hardware.

Other alternatives are SPI or I2C based external EEPROM, such as NVRAM (non-volatile RAM) which would have larger capacity, but you would need to connect it. That would likely be about 5 wires and somewhere to put the chip. An example of that is Adafruit I2C FRAM Breakout.

You could use a micro-SD card, which I have used on another project to record temperature readings every 15 minutes. This has a lot more capacity than EEPROM, and then you can just take the SD card out and read it in an ordinary PC. This needs extra hardware (eg. a holder for the SD card and possibly voltage-level shifters). However you can buy that for around $20, and it is easy enough to hook up.

I don't know how SQL got into the discussion under the question, but that is a language (Structured Query Language) and not a piece of hardware.

Another alternative, if you don't particularly want portability, is to send your data along a connection to your PC, and record the data there. Conceivably WiFi could be used for that.

Speed
Speed-wise, I would say EEPROM is the fastest because it is natively inside the chip. Other alternatives required sending messages along wires (I2C, SPI, or maybe USB) to somewhere else and that takes time.
Writing is slower than reading, because writing involves using electricity to make a chemical change in the chip (turning a 1-bit into a 0-bit) but it is still quite fast.

Try FRAM either SPI or I2C, read and writes in the billions. 32K x 8. Here is a link: https://learn.adafruit.com/adafruit-i2c-fram-breakout/wiring-and-test

@Gil Nice. Easy to use and ridiculously cheap. I might order myself one ... or a few. :)
My only problem with it would be that you would need to fiddle around to get the data off it (if that was a requirement). Using an SD card makes that part simpler.

It works like external EEPROM but no delays for read or write. You can do one location at a time if wanted. In general, ferroelectric-based memory technologies (FeRAM, FeFET, and FTJ) exhibit fast write/read speed, long retention, high endurance, and low write energy consumption.


text:
Can Arduino UNO/MEGA master assert SPI SS LOW on multiple slaves at once if Full Duplex is unnecessary?
I have a computer talking serially to an UNO SPI Master and, beyond it, multiple MEGA Slaves.  The slaves never talk back to the master.
I understand it is normal and correct to assert SS LOW to select one slave at a time, such that the master clocks bits via MOSI to the selected slave on the same clock edges the slave sends bits to the master via MISO.
Multiple slaves clocking on MISO would garble the communication back to the master.  But what if I don't care?  Instead, on a system with a pulled-up MISO pin that does not even have MISO wires attached, what if the master selects all the slaves at once, then clocks a byte out on MOSI with a bit set calling for one specific slave (of 8 possible) to respond to subsequent bytes?  That is way faster than the master sorting out with code which slave should get the message originating in the computer.  ALL the slaves can check the bit they expect and ignore the subsequent bytes of the SPI message if the bit is CLEAR-- they are not doing anything else at the moment anyway, say.
What is wrong with this idea?  Are there electronic issues in the UNO or MEGAs I am not thinking of?  Is this done?  Why not?

What is wrong with this idea?

Nothing, this is perfectly possible. The main advantage is the avoidance of multiple SS lines, reducing pin count and/or decoding hardware.
The SPI main device does not know the number of SPI sub devices, and it will happily sample the level at the MISO pin, whatever you give it.
Each SPI sub device does not know that the other SPI sub devices receive the very same bytes. As you write, if the first byte (or any other protocol detail) tells it to ignore the rest of the transmission, it will.

Are there electronic issues in the UNO or MEGAs I am not thinking of?

You need to read the data sheet to learn about the load of each input of the SPI sub devices, and the guaranteed provided drive capability of each output of the SPI main device, that means SS, SCLK, MOSI. Then make sure the driver can drive all receivers.
Commonly you can connect a two-digit number without any concern.You write that you have eight, so just go ahead.
You can leave the MISO outputs of the SPI sub devices simply unconnected. At the SPI main device make sure you have a pull-up or pull-down resistor on its MISO input.

Is this done?

I have no personal experience or example, but I'm sure it is done.

Why not?

When you actually need responses from the SPI sub devices, you need to do it differently. However, even then you can combine all the MISO outputs of the SPI sub devices with some clever digital logic.

Note: I prefer "main" and "sub", which still match the abbreviations, instead of the old terms of the former century.

The electronic circuit of an SPI work this way,  when a slave device is not been selected (i.e. its CS pin is not asserted), its MISO line will be in tri-state output, i.e. it is in a high impedance floating state, electrically disconnect, this allows multiple devices sharing the same MISO bus. For this reason, you can't tie all the slave devices with a single CS pin as all the MISO outputs from the devices will be activated.
If you don't care about the MISO data clocking in from the slave devices, you simple don't connect the MISO pin to the bus.

try-state -> Tri-state (as in 3 states). Otherwise, I agree with you.

Ops. Thanks for pointing that out.


text:
How to get recover numeric data sent by an Arduino in binary
I am a C# dev and these C++ data conversions are killing me.
I have an Arduino sending binary data through LoRaWAN to AzureIOT. I am trying to decode my Temp/Humid/Bat payload that I am pulling out of AzureIOT Hub.
Here is a sample method I am using in C# to parse the byte array. Once I have parsed it, how do I convert those numbers back to their actual values?
Here is the input data on the sensor side:

T=74.48
RH=45.20
BatteryVoltage:3332

Thanks.
Here is how the data was input:
float temperature = readDHTTemperature(); //this method prints T to Serial
float humidity = readDHTHumidity(); //this method prints H to Serial
uint16_t batteryVoltage = readBattery(true);
delay(100);

unsigned char *puc;

puc = (unsigned char *)(&temperature);
appDataSize = 10;
appData[0] = puc[0];
appData[1] = puc[1];
appData[2] = puc[2];
appData[3] = puc[3];

puc = (unsigned char *)(&humidity);
appData[4] = puc[0];
appData[5] = puc[1];
appData[6] = puc[2];
appData[7] = puc[3];

appData[8] = (uint8_t)(batteryVoltage>>8);
appData[9] = (uint8_t)batteryVoltage;

Here is the output:
private static void BytesToString()
{
    var hexStringFromPayLoad = "MzOYQgAAHEINBA==";
    var bytes = Base64Decode(hexStringFromPayLoad);

    Console.WriteLine($"Temp: {bytes[0]}, {bytes[1]}, {bytes[2]}, {bytes[3]}");
    Console.WriteLine($"Humid: {bytes[4]}, {bytes[5]}, {bytes[6]}, {bytes[7]}");
    Console.WriteLine($"Bat: {bytes[8]}, {bytes[9]}");

    /*
    Temp: 51, 51, 152, 66
    Humid: 0, 0, 28, 66
    Bat: 13, 4
    */
}

what is the received payload data, in hex?

https://stackoverflow.com/questions/26310249/converting-4-raw-bytes-into-32-bit-floating-point

@jsotola, sorry, I updated my post iwth the input and the CSV output.  Thank you for your help.

I edited the question to remove the word “decimal”, which you were misusing here.

Arduinos use very standard formats for their internal binary
representations of data:

integers are in two's complement
floats follow the IEEE 754 standard
both are little-endian.

This is the same as your typical x86_64. The implication is that, once
the bytes are in your PC, you do not need to perform any conversion at
all. All you need to do is either alias or copy the bytes to the memory
locations of the variables that are meant to get the values.
Example in plain C:
uint8_t temperature_bytes[] = { 51, 51, 152, 66 };
float temperature;
memcpy(&temperature, temperature_bytes, sizeof temperature);
// now `temperature` holds the value 76.1.

How you would do this in C# is a question that is out of topic in this
site.

Good point.  Thanks for the guidance.  I will move over to overflow.


text:
Turn on by long press of a button?
In my project on Arduino, I want to implement turning on the whole circuit by long press of a button.
But at the same time, I want the Arduino to be turned off in standby or sleep mode, but I don't know how to wake it up then.
Can you please advise me how this can be realized?

Your project has one button. You want a (*long) press of the button to wake the Arduino. After some time you want the Arduino to sleep (maybe to save battery power). You want the Arduino to wake again when there is a (*long) press of the button and all that in a continuous cycle. Is that correct or do you also want the Arduino to wake on other triggers as well ?  (*Technically, the Arduino would wake on a short button press but immediately resume sleeping if the button press was too short)

@6v6gt Yes, it's just as you described.
Ideally, I'd like it like this:

3 seconds press (on)
Short press during operation (sleep mode)
Long press during operation (3 sec.) shutdown

Which Arduino are you using ? Not all Arduinos, especially not development boards, bring significant power savings in sleep mode. You'd have to tolerate the Arduino entering "wake" mode as soon as the power supply is connected.  There will only be wake and sleep states using software alone. A full shutdown is also possible but would involve additional hardware to unlatch the Arduino from the power supply. Do you require a full shutdown?

Yes, a complete shutdown is required. I am using an Arduino Mega2560

3 seconds press (on) - Short press during operation (sleep mode) - Long press during operation (3 sec.) shutdown ... please add that to the question ... it does not belong in a comment

you could use an ultra low power microcontroller to detect the keypress and control power to the arduino ... something like https://www.st.com/resource/en/datasheet/stm8l001j3.pdf

You can use a circuit like this to get close to what you want to achieve.

Found on: https://forum.arduino.cc/t/switch-microcontroller-on-and-off-with-a-button-and-mofset/1047044
It is a latching circuit with the special property that you can use the same button to power up the Arduino and later when the Arduino is running, test the button in code.
It works like this. If the Arduino is powered off, pressing the button powers up the Arduino. Your program will immediately (or after a specific chosen interval) switch on D6. This sustains the latch.
Now in your code, you can detect the button press and do what you like with it. Maybe power the device off by setting D6 to LOW if the button has been pressed for X ms.
If you want the device simply to enter sleep mode on a button press, then you can do that also. However, it gets a bit more complicated because the button then has to be used to wake the device. That means setting a pin change interrupt on pin A0 and then testing A0 on wake up to determine the length of the button press. If it is too short, then you can force the Arduino to resume sleep.


text:
Lora SX1278 stops receiving after a short time
I am working with two Lora ra-02 sx1278 modules and two Arduino Uno.
Programming on Arduino IDE 2.1.1
sender

receiver

The problem is the receiver receives a few packets successfully, but then the board no longer receives the signal. I know the sender is sending data constantly because the RX LED on Arduino blinks.
Every time I reset the receiver board, it starts receiving again and then stops after a few packets.
I have this problem when running the basic send and receive example of the Lora library itself.
Here's the library I'm using from Arduino IDE libraries:
link of the Lora library
(I just changed the frequency to 433 for my area, and reduced the delay of sending packets from 5 seconds to 1 second)
I couldn't find anything helpful on the internet.
Any suggestions?
Update: My project is a hand-gesture-controlled car. I uploaded the project's program on boards. With this code, if the command to the robot car is "stop", it receives some packets every 1 second and then after an acceptable time, doesn't receive anymore. But if I move my hand so it sends move commands to the car, it receives the move command and motors work but it doesn't receive the next packet.
When I detached the motor drivers from Arduino, it received at least 15-20 packets. Apparently, it receives packets but after motor drivers and motors work, it suddenly doesn't receive anything. I'm confused.
Sender:
#include <SPI.h>
#include <LoRa.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

int counter = 0;
String msg = "";
int xdata = 0;
int ydata = 0;
int flag=0;
Adafruit_MPU6050 mpu;

void setup() {
  Serial.begin(9600);
  while (!Serial)
  Serial.println("LoRa Sender");
  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");
  LoRa.setTxPower(10);
}
void loop() {
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);
  xdata = a.acceleration.x;
  ydata = a.acceleration.y;
  Serial.println(counter);

  if((xdata>2)&&(flag==0))
  {
    flag=1;
    msg = "l";
    Serial.println("l");
    }
  if(xdata<-2 && flag==0)
  {
    flag=1;
    msg = "r";
    Serial.println("r");
    }
  if(ydata>2 && flag==0)
  {
    flag=1;
    msg = "b";
    Serial.println("b");
    }
  if(ydata<-2 && flag==0)
  {
    flag=1;
    msg = "f";
    Serial.println("f");
    }
  if((xdata<2)&&(xdata>-2)&&(ydata<2)&&(ydata>-2)&&(flag==1))
  {
    flag=0;
    msg = "s";
    Serial.println("s");
    }

  LoRa.beginPacket();
  LoRa.print(counter);
  LoRa.print(msg);
  LoRa.endPacket();
  counter++;
  delay(1000);
}

Receiver:
#include <SPI.h>
#include <LoRa.h>

int motor1pin1 = 3;   //front left
int motor1pin2 = 4;
int motor2pin1 = 5;   //front right
int motor2pin2 = 6;
int motor3pin1 = A0;  //back right
int motor3pin2 = A1;
int motor4pin1 = A2;  //back left
int motor4pin2 = A3;
String  msg="";

void setup() {
  pinMode(motor1pin1, OUTPUT);
  pinMode(motor1pin2, OUTPUT);
  pinMode(motor2pin1, OUTPUT);
  pinMode(motor2pin2, OUTPUT);
  pinMode(motor3pin1, OUTPUT);
  pinMode(motor3pin2, OUTPUT);
  pinMode(motor4pin1, OUTPUT);
  pinMode(motor4pin2, OUTPUT);

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

  Serial.println("LoRa Receiver");

  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  // try to parse packet
  int packetSize = LoRa.parsePacket();
  yield();
  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");
    // read packet
    while (LoRa.available()) {
      msg=(char)LoRa.read();
      Serial.print(msg);
    }
    //Serial.println(msg);
    if(msg=="f")
    {
      digitalWrite(motor1pin1, HIGH);
      digitalWrite(motor1pin2, LOW);
      digitalWrite(motor2pin1, HIGH);
      digitalWrite(motor2pin2, LOW);
      digitalWrite(motor3pin1, HIGH);
      digitalWrite(motor3pin2, LOW);
      digitalWrite(motor4pin1, HIGH);
      digitalWrite(motor4pin2, LOW);
      Serial.println(" :  Forward");
    }
    else if(msg=="b")
    {
      digitalWrite(motor1pin1, LOW);
      digitalWrite(motor1pin2, HIGH);
      digitalWrite(motor2pin1, LOW);
      digitalWrite(motor2pin2, HIGH);
      digitalWrite(motor3pin1, LOW);
      digitalWrite(motor3pin2, HIGH);
      digitalWrite(motor4pin1, LOW);
      digitalWrite(motor4pin2, HIGH);
      Serial.println(" :  Back");
    }
    else if(msg=="l")
    {
      digitalWrite(motor1pin1, LOW);
      digitalWrite(motor1pin2, HIGH);
      digitalWrite(motor2pin1, HIGH);
      digitalWrite(motor2pin2, LOW);
      digitalWrite(motor3pin1, HIGH);
      digitalWrite(motor3pin2, LOW);
      digitalWrite(motor4pin1, LOW);
      digitalWrite(motor4pin2, HIGH);
      Serial.println(" :  Left");
    }
    else if(msg=="r")
    {
      digitalWrite(motor1pin1, HIGH);
      digitalWrite(motor1pin2, LOW);
      digitalWrite(motor2pin1, LOW);
      digitalWrite(motor2pin2, HIGH);
      digitalWrite(motor3pin1, LOW);
      digitalWrite(motor3pin2, HIGH);
      digitalWrite(motor4pin1, HIGH);
      digitalWrite(motor4pin2, LOW);
      Serial.println(" :  Right");
    }
    else if(msg=="s")
    {
      digitalWrite(motor1pin1, LOW);
      digitalWrite(motor1pin2, LOW);
      digitalWrite(motor2pin1, LOW);
      digitalWrite(motor2pin2, LOW);
      digitalWrite(motor3pin1, LOW);
      digitalWrite(motor3pin2, LOW);
      digitalWrite(motor4pin1, LOW);
      digitalWrite(motor4pin2, LOW);
      Serial.println(" :  Stop");
    }
    LoRa.receive();
  }
}

There are 10 sketches in the library, you need to be more specific which is/are the one you are using. We don't want to guess which one. 2) Does it crash/stop working if you change the interval to 5s instead of 1s? 3) BTW, Lora is designed for Long range communication(as compare to WiFi) for a limited shared frequency resource, before you decide to blasting the airwave every second (even you are using it as peer-to-peer), please be away of duty cycle requirement.

@hcheung thanks for your reply. 1)I'm testing LoRaSender and LoRaReceiver. 2) Yes. With more delay, it receives more packets but it stops again. 3)I don't have much information about it. Can you tell me the limitations? I'm using 433 MHz. I read the link you provided but don't know what the duty cycle is in my case.

The first thing that comes to mind is that the delay between sends is too short. Not only are you flooding the airwaves with your packets (fair use, 1% airtime and all that), but after a few packets your receiver might not be able to keep up and start missing packets.
Also, there's the definite possibility that another device in the neighourhood is sending packets too, and interferes with your transmission. You are after all on the standard 433 MHz frequency, with default settings.
Try:

Change frequency to something less crowded.
Change SF / BW to something less standard.
Set delay between pings to around 30 seconds.
Depending on the LoRa library you are using, consider using CAD, Channel Activity Detection.

I just saw you are using the arduino-LoRa library. It has CAD, not in the master branch, but in a separate branch.


text:
Image capture at QSXGA resolution by OV5640 in ESP32s3
// Include necessary libraries
#include "WiFi.h"
#include "esp_camera.h"
#include "Arduino.h"
#include "soc/soc.h"           // Disable brownout problems
#include "soc/rtc_cntl_reg.h"  // Disable brownout problems
#include "driver/rtc_io.h"
#include <SPIFFS.h>
#include <FS.h>
#include <Firebase_ESP_Client.h>
#include <addons/TokenHelper.h>
//#include <ArduinoJson.h>      // JSON library

// Replace with your network credentials
const char* ssid = "SSID";
const char* password = "PASSSS";

// Replace with your Firebase project details
#define API_KEY "API"
#define USER_EMAIL "EIMAI@gmail.com"
#define USER_PASSWORD "PASS"
#define STORAGE_BUCKET_ID "esp32cam-AAA.appspot.com"
#define FILE_PHOTO "/photo.jpg"

#define CAMERA_MODEL_ESP_EYE  // Has PSRAM
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 15
#define SIOD_GPIO_NUM 4
#define SIOC_GPIO_NUM 5
#define Y9_GPIO_NUM 16
#define Y8_GPIO_NUM 17
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 12
#define Y5_GPIO_NUM 10
#define Y4_GPIO_NUM 8
#define Y3_GPIO_NUM 9
#define Y2_GPIO_NUM 11
#define VSYNC_GPIO_NUM 6
#define HREF_GPIO_NUM 7
#define PCLK_GPIO_NUM 13

// Flags and variables
boolean takeNewPhoto = true;
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig configF;
bool taskCompleted = false;

void initCamera() {
  // OV2640 camera module
  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sccb_sda = SIOD_GPIO_NUM;
  config.pin_sccb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.frame_size = FRAMESIZE_QSXGA;
  config.pixel_format = PIXFORMAT_JPEG;  // for streaming
  //config.pixel_format = PIXFORMAT_RGB565; // for face detection/recognition
  config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
  config.fb_location = CAMERA_FB_IN_PSRAM;
  config.jpeg_quality = 12;
  config.fb_count = 1;

  // if PSRAM IC present, init with UXGA resolution and higher JPEG quality
  //                      for larger pre-allocated frame buffer.
  if (config.pixel_format == PIXFORMAT_JPEG) {
    if (psramFound()) {
      config.jpeg_quality = 10;
      config.fb_count = 2;
      config.grab_mode = CAMERA_GRAB_LATEST;
    } else {
      // Limit the frame size when PSRAM is not available
      config.frame_size = FRAMESIZE_SVGA;
      config.fb_location = CAMERA_FB_IN_DRAM;
    }
  } else {
    // Best option for face detection/recognition
    config.frame_size = FRAMESIZE_240X240;
#if CONFIG_IDF_TARGET_ESP32S3
    config.fb_count = 2;
#endif
  }

#if defined(CAMERA_MODEL_ESP_EYE)
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
#endif

  // camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  sensor_t* s = esp_camera_sensor_get();
  // initial sensors are flipped vertically and colors are a bit saturated
  if (s->id.PID == OV3660_PID) {
    s->set_vflip(s, 1);        // flip it back
    s->set_brightness(s, 1);   // up the brightness just a bit
    s->set_saturation(s, -2);  // lower the saturation
  }
  // drop down frame size for higher initial frame rate
  if (config.pixel_format == PIXFORMAT_JPEG) {
    // s->set_framesize(s, FRAMESIZE_QVGA);
    s->set_framesize(s, FRAMESIZE_XGA);
    Serial.println("Frame UXGA..");

  }

#if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)
  s->set_vflip(s, 1);
  s->set_hmirror(s, 1);
#endif

#if defined(CAMERA_MODEL_ESP32S3_EYE)
  s->set_vflip(s, 1);
#endif

// Setup LED FLash if LED pin is defined in camera_pins.h
#if defined(LED_GPIO_NUM)
  setupLedFlash(LED_GPIO_NUM);
#endif
}

// Initialize WiFi connection
void initWiFi() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi...");
}

// Check if photo file is valid
bool checkPhoto(fs::FS& fs) {
  File f_pic = fs.open(FILE_PHOTO);
  unsigned int pic_sz = f_pic.size();
  return (pic_sz > 100);
}

// Initialize SPIFFS file system
void initSPIFFS() {
  if (!SPIFFS.begin(true)) {
    Serial.println("An Error has occurred while mounting SPIFFS");
    ESP.restart();
  } else {
    delay(500);
    Serial.println("SPIFFS mounted successfully");
  }
}

// Initialize camera
void capturePhotoSaveSpiffs() {
  camera_fb_t* fb = NULL;
  bool ok = false;

  Serial.println("Taking a photo...");
  fb = esp_camera_fb_get();
  if (!fb) {
    Serial.println("Camera capture failed");
    return;
  }

  Serial.printf("Picture file name: %s\n", FILE_PHOTO);
  File file = SPIFFS.open(FILE_PHOTO, FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file in writing mode");
  } else {
    file.write(fb->buf, fb->len);
    Serial.print("The picture has been saved in ");
    Serial.print(FILE_PHOTO);
    Serial.print(" - Size: ");
    Serial.print(file.size());
    Serial.println(" bytes");
  }
  file.close();
  esp_camera_fb_return(fb);
  //ok = checkPhoto(SPIFFS);
  File imageFile = SPIFFS.open(FILE_PHOTO, FILE_READ);
  if (imageFile) {
    //if (Firebase.ready() && !taskCompleted) {
    // taskCompleted = true;
    Serial.println("Uploading picture...");

    if (Firebase.Storage.upload(&fbdo, STORAGE_BUCKET_ID, FILE_PHOTO, mem_storage_type_flash, FILE_PHOTO, "image/jpeg")) {
      Serial.printf("Download URL: %s\n", fbdo.downloadURL().c_str());
    } else {
      Serial.println(fbdo.errorReason());
    }
  }
  // } else {
  //   Serial.println("Failed to open image file in reading mode");
  // }
  imageFile.close();
  SPIFFS.remove(FILE_PHOTO);  // Remove image after upload
}

// Setup function
void setup() {
  Serial.begin(115200);
  initWiFi();
  initSPIFFS();
  initCamera();
  configF.api_key = API_KEY;
  auth.user.email = USER_EMAIL;
  auth.user.password = USER_PASSWORD;
  Firebase.begin(&configF, &auth);
  Firebase.reconnectWiFi(true);
}

// Main loop
void loop() {
  if (takeNewPhoto) {
    capturePhotoSaveSpiffs();
    takeNewPhoto = false;
  }
  delay(1);
}

How to set image resolution at QSXGA level by OV5640 camera in ESP32S3 module. Everything is working for low resolution but if going to highest resolution it is not working


text:
Read values from a txt file on an SD card
I'm trying to read a text file (has numeric values) from SD card. The values in the file like this
87 512
255

I need to read 87 in ch1 and 512  in ch2 and 255 in ch3.
Why did I get on 'SKIP_NONE' 'SKIP_WHITESPACE' was not declared in this scope?
int ch1 = in_file.parseInt(SKIP_WHITESPACE);
Serial.printf("First = %d \n",ch1);

int ch2 = in_file.parseInt(SKIP_NONE, '\n');
Serial.printf("Second = %d \n",ch2);

int ch3 = in_file.parseInt();
Serial.printf("Third = %d \n",ch3);

What Arduino are you compiling for? What core version are you using?

Can I know why the -1 ??!!!

Why the -1? Because some people... (fill in the blanks).  I just corrected the transgression by upvoting your question.  Why?  Because it's a good question, and a downvote without a helpful comment serves no purpose except to discourage you, and that doesn't help anyone and only hurts the community.

Ignore the downvotes. People are allowed to downvote, and they are not required to give a reason. Just ignore them. I'm a moderator and I get downvoted. :P

These symbols were introduced in the Arduino AVR core 1.6.7, in
December 2015. You can find them in Stream.h. They are probably
defined in other cores too.
For some reason, the Teensy cores do not define them. You may consider filing an issue in their GitHub project.


text:
The port is not recognized when working with esp32 in arduino ide 2.2.1 (windows 11 home edition)
I'm trying to program the ESP32 board with Arduino IDE.

But The port it's not recogniized when working with esp32 in arduino ide 2.2.1.
After some research I found that the port is not recognized by my operating system (WINDOWS 11 home edition).
Image of Device Manager showing the message that the port is not recognized.

I installed the Silicon Labs drivers for the CP210x USB to UART Bridge.
After restarting the PC, the port is still not recognized.
I did a search with the command line and the driver CP210x USB to UART Bridge is not installed.
CMD Line image:

I'm out of ideas how to solve this problem, some one knows how to solve this issue?

please do not post a picture of text ... copy and paste the text instead ... format it as "code" so that it looks the same as on screen

I don't have a Stack Account yet, but i saw this and i know the answer...

it appears by your photo that you do indeed have a CP2102 Chip which requires the driver from here
CP2102 DRIVER

This driver should be able to be installed without connecting your ESP32 Dev Board.

This is a driver issue, so .. do this
In Device Manager  (i'm going to make some assumptions because i don't know what motherboard you have or machine )  But....

Uninstall the USB Drivers completely
Re Install the USB Drivers
Re Install the chipset drivers for your mainboard
Ensure your BIOS is up to date, if not, Update it via the correct software.

After all that , Restart Your computer

Try it again, if problem persists

Open cmd.exe    Run  sfc/scannow    and press enter
This will run the windows System File Checker

Try again, If problem persists

You likely have a knock off board, They are notorious for not wanting to play
nice with the drivers.

it's also possible that your computer is faulty,  Try it on another computer, obviously
but at the end of the day , it's more likely that you have a knock off board or
you have a driver issue and things need to get updated and resolved.

I installed the drivers using legacy mode of the device manager. But the operating system trys to open the ESP32 as a simple usb. I'll try to uninstall the drivers, then I'll give the feedback.


text:
Why is char being "extended" to an int?
I know I'm missing something so simple here, but I can't figure it out.
If I do char letter = 'A'; then letter = letter << 8, letter = 0, as one should expect, since we are shifting the bits "off the shelf" to the left.
But, if we do this:
char letter = 'A';

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

  int twoBytes = letter << 8;
  Serial.println(twoBytes, BIN);

}

void loop() {}

The result is 100000100000000, but why? << has precedence over =, so it should be bitshifting letter left by 8 first, then assigning that value (which should be 0) to twoBytes.

Isn't there an implication that it will work (for some definition of "work")? If you were expecting zero why not just write: int twoBytes = 0; - the fact that you didn't implies that you expect letter to be treated as 16 bits.

I just want to point out that although you posted it here, this is entirely a C++ question. The Arduino compiler is the GNU C++ compiler. Nothing "Arduino" about the way it treats code you write, with the exception of some pre-processing that the IDE does. See here for more details about that.

@NickGammon .....because I need letter to be in high byte of twoBytes, and I'm putting another char into the low byte of twoBytes. Even though the code I wrote worked, being the inquisitive person I am I realized it didn't make sense, hence the question.

This is a funny, non-intuitive rule of the C++ language called “integral
promotion”. Simply stated, it says that no computation is ever performed
on a type smaller than int: anything smaller gets implicitly promoted
to int as soon as it appears in an arithmetic or logic expression.
See Implicit conversions in cppreference.com (warnings: it's
hairy).

Thank you, I'll take it on faith! Would it be good practice to say int twoBytes = letter; twoBytes << 8; instead for clarity, or does it even matter?

I would say that, for an experienced C or C++ programmer, it may not really matter. For someone unfamiliar with these rules, anything that can make the code clearer is a good thing. You may also write int twoBytes = int(letter) << 8;, or you may stick with letter << 8 and add a comment.

In this sort of case, where you only want the right-most 8 bits I would personally "and" it, like this: int twoBytes = (letter << 8) & 0xFF;  Since you want the low-order byte, make it explicit.

I'm not sure how what you're saying is connected to what they're saying, but int twoBytes = (letter << 8) & 0xFF; is either complicated way of putting zero in twoBytes or potentially undefined behavior, depending on the value and system.

The OP was surprised that the result wasn't zero, so I was pointing out that if you are doing a shift (left or right) and you aren't sure how many bits are being retained in the result, then anding it would make it clear. I don't see how the results could possibly be undefined.


text:
Multiple definition error in STM32CubeIDE
How do global variable declarations work?
For example:
In file1.c I am defining:
#define volt_add 0x20

uint8_t vol[8]= {0x53, 0x35, 0x05, 0x22, volt_add,0x00,0x00,0x00};

uint16_t EM_vol;

I need to use all above variables in file2.c.
I tried to define them in the global.h file and included that file in both file1.c and file2.c, but I am getting a multiple definition error, first defined here error.
How can I do it?

If you want global variable accessible from everywhere you include global.h, you'll need declaration of that variable in header (declatation only):
// globals.h:
extern uint8_t vol[8];

Anywhere else you'll #include "global.h"
But there must be one cpp or c file with:
#include "global.h"
uint8_t vol[8]= {0x53, 0x35, 0x05, 0x22, volt_add,0x00,0x00,0x00};

If you make this definition in header or more than one .c file, you'll get multiple definition error.
Another way would be make it static and make whole definition in the header, however each compilation unit will be using it's own instance and it won't be visible from other compilation units (compilation unit == every c file compiled into own .o file). This is issue on MCUs and if you even want to write into it, it'll be total mess (although nobody uses const correctness in C)


text:
Wolfram Mathematica reads but closes stream feeds from Arduino Serial port after a few data sets
This is a Wolfram Mathematica / Arduino serial feed problem , but I am posting here just in  for any suggestions on enhancing the Arduino code or the Mathematica notebook.  The original post is here Mathematica Exchange post and in here
The Arduino sketch monitor a sensor and returns a set of three intergers.
     #include <Wire.h>
#include "Adafruit_AS726x.h"

//create the object
Adafruit_AS726x ams;

//buffer para leer valores en bruto
uint16_t sensorValues[AS726x_NUM_CHANNELS];

//buffer para  guardar los valores calibrados( no esta siendo utilizado en este codigo)
//float calibratedValues[AS726x_NUM_CHANNELS];

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

  // inicializa el pin digital LED_BUILTIN como un output.
  pinMode(LED_BUILTIN, OUTPUT);

  //inicia y permite la comunicacion con el sensor
  if(!ams.begin()){
    Serial.println("could not connect to sensor! Please check your wiring.");
    while(1);
  }
}

void loop() {

  //lee la temperatura del sensor
  uint8_t temp = ams.readTemperature();

  //ams.drvOn(); // descomentar esto si quieres usar el led del sensor para hacer medidas
  ams.startMeasurement(); //begin a measurement

  //permite que el sensor lea la data cuando este disponible
  bool rdy = false;
  while(!rdy){
    //delay(1000);
    rdy = ams.dataReady();
  }
  //ams.drvOff(); //descomentar esto si quieres usar el led del sensor para hacer medidas

  //lee los valores!
  ams.readRawValues(sensorValues);
  //ams.readCalibratedValues(calibratedValues);

   //Serial.print("{");
  //Serial.print("Temp: ");
  //Serial.print(temp);
  //Serial.print(",");
  //Serial.print(" Violet: ");
  //Serial.print(sensorValues[AS726x_VIOLET]);
   //Serial.print(",");
  //Serial.print(" Blue: ");
  Serial.print(sensorValues[AS726x_BLUE]);
   Serial.print(",");
  //Serial.print(" Green: ");
  //Serial.print(sensorValues[AS726x_GREEN]);
   //Serial.print(",");
  //Serial.print(" Yellow: ");
   Serial.print(sensorValues[AS726x_YELLOW]);
    Serial.print(",");
  //Serial.print(" Orange: ");
  //Serial.print(sensorValues[AS726x_ORANGE]);
   //Serial.print(",");
  //Serial.print(" Red: ");
  Serial.print(sensorValues[AS726x_RED]);
  //Serial.print("}");

  Serial.println();
  //Serial.println();
  delay(400);

The Mathematica notebooks is
dev = DeviceOpen["Serial", "COM3"]

parseData[{val1__, 44, val2__, 44, val3__}] :=
 ToExpression@FromCharacterCode@# & /@ {{val1}, {val2}, {val3}}
parseData[___] := Sequence[]
rawReadings = {}
task = SessionSubmit[
  ScheduledTask[
   AppendTo[rawReadings,
    DeviceReadBuffer[dev, "ReadTerminator" -> 10]], {1, 100},
   "AutoRemove" -> True]]
test1 = parseData /@ rawReadings
ListLinePlot[Transpose[parseData /@ rawReadings],
  PlotLegends -> Automatic] // Dynamic
DeviceClose[dev]

But the Notebooks is not returning a dynamic feed of data from Arduino. It closes and not able to determine why.  It is suppose to stream a feed continously.

I think the outcommented code should be removed.

There is a whole class of these connection problems on Stack Overflow. Sample 1. Sample 2. Here too?

This thread has nothing to do with Processing , LabView or Matlab.  It applies to Wolfram Mathematica handle of Arduino serial port.  Can you explain how these contribute to my problem?

Jose! As I already mentioned in Mathematica SE, you need to remove the delay statements out of your code and additionally send the data to serial only if new data has arrived.

Thank you for the feedback. I posted a update in Mathematica Exchange with a revised code with you suggestions.   But so far no getting the dynamic stream to maintain continuously.


text:
ESP-IDF logging library slows down ISR processing
I'm hacking a project with ESP32-WROOM module. I'm running some timers with alarms along with some peripherals triggering ISRs. In the ISR routine I'm sending events to a queue, and receiving them in a task. Normally I'm seeing ~50 micros delay between ISR routine and the task.
I added the esp_log component for logging to UART. If I call some ESP_LOGx in the task after receiving the queue event, the aforementioned delay grows to 25 millis in some cases (depending on the amount of logging).
What's the reason? Does esp_log have longish noInterrupt sections internally? Is there any way to avoid them? Any other remedies?
Those delays are quire troublesome because on one hand I need logging to get things working. On other hand those delays turn all the timings upside down...
I actually switched to esp_log form hand-rolled logger. In my logger I had a 5k fifo queue for log data. The logging calls would format strings and push them into the queue. A low priority task would pop the data and print it to the UART. It was much better in terms of performance. I switched to esp_log for richer functionality, but ... Going back unless there is a fix.

Since your logger uses the UART, you need to take the transmission time into account.
Supposing that you use a 9600 baud line and send about 25 bytes.
A single byte has 10 bits on the wire, start bit, data bits, and at least one stop bit. There are more options to the protocol, but this is it basically.
Each bit takes 1/9600 seconds, this is the definition of 9600 baud. (Actually, this is oversimplified, but nevertheless a correct number here.) 10 bits of one byte take t_Byte = 10 / 9600 s = 1.042 ms.
To send 25 bytes, this sums up to about 25 ms.
Lesson learned: do not log directly to UART in a time critical task. You found the common solution by queuing the bytes to send. Just make sure that the queue will not fill up in the long term.

that makes sense, I realized I can redefine vprintf function esp_log_set_vprintf and implement buffering and flushing the buffer asynchronously


text:
(Why is) getLocalTime() on ESP32 taking several seconds to complete successfully
This is a cross-post from https://github.com/espressif/arduino-esp32/discussions/8653 as it didn't yield any results there.
I noticed that getLocalTime() is consistently taking 5-10+ seconds to complete. So far I haven't been able to find the root cause.
I am testing on a ESP32-WROVER-B module. On startup the device first connects to WiFi and then tries to sync time.
boolean initTime() {
  struct tm timeinfo;

  log_i("Synchronizing time.");
  // Connect to NTP server with 0 TZ offset, call setTimezone() later
  configTime(0, 0, "pool.ntp.org");
  // getLocalTime uses a default timeout of 5s -> the loop takes at most 3*5s to complete
  for (int i = 0; i < 3; i++) {
    if (getLocalTime(&timeinfo)) {
      log_i("UTC time: %s.", getCurrentTimestamp(SYSTEM_TIMESTAMP_FORMAT).c_str());
      return true;
    }
  }

  log_e("Failed to obtain time.");
  return false;
}

  ...
  10:12:28.118 > [  3634][I][connectivity.h:17] startWiFi(): ...done. IP: 192.168.0.57, WiFi RSSI: -55.
- 10:12:28.118 > [  3700][I][util.h:25] initTime(): Synchronizing time.
|
->10:12:34.025 > [ 11572][I][util.h:37] initTime(): UTC time: 2023-09-19 08:12:34.
  10:12:34.037 > [ 11572][I][util.h:60] setTimezone(): Setting timezone to 'CET-1CEST,M3.5.0,M10.5.0/3'.
  10:12:34.042 > [ 11574][I][main.cpp:175] syncTime(): Current local time: 2023-09-19 10:12:34
  ...

In the above example it took ~6s for a "valid" timestamp to become available.

Have you tried a different NTP server? 2) Why is it important to synchronize your local clock in as few seconds as possible?

Try replacing pool.ntp.org with (one of) its IP addresses eg. 159.196.3.239

@st2000 I tried different servers but all by-name so far (i.e. implicitly using DNS). I want this to be done as quickly as possible as it's part of the setup() sequence. The sketch should only proceed with an accurately synced clock.

@NickGammon thanks, didn't try that yet.

it should connect to the server just once at boot, and then every so often, which is the 4th argument to the NTPClient constructor (the refresh time in ms). On the ESP32, every 15 mins is fine to keep well under 1s drift, which is the resolution of the interface anyway.

try sntp_set_sync_mode(SNTP_SYNC_MODE_IMMED);

Based on the wording in the question, it appears you are requesting an NTP re-synchronizing event often.  Perhaps as often as possible.  Consider that most Arduino projects request an NTP re-synchronizing event once to set the local RTC.  Then perhaps once a day to check if the RTC is accurate.
Keep in mind that many NTP servers defend them selves from attack by throttling the service from an IP address who utilize them excessively. This quote:

The NTP  server may throttle traffic, especially for clients making
frequent requests.

... is from this web site.

In case you are not aware, if time is important for your Arduino project, consider adding RTC hardware.  This can be set to the the local time just after the NTP re-synchronizing.  From that point forward, the local RTC can provide the time.  Later, it may be prudent to check the local RTC against the NTP reported time.  But this is usually not necessary for days at a time for the vast majority of Arduino projects.

That is a very plausible explanation, thanks! While working on a new sketch I go through the compile-upload-reboot loop (far to) often. Since my initTime() is triggered from setup(), requests from my IP address hit the NTP servers very frequently. I guess I should consider running my own NTP server (e.g. a cturra/ntp Docker container) and rewire my sketches to hit that one.

Thanks.  I am curious.  If you do not make an NTP request for, say 24 hours.  Do you see an improvement in NTP response time?

Appears indeed to have been the root cause. Being away from sketch development for a couple of days solved it.


text:
Arduino to Arduino communication
When I send data to an Arduino Uno via the serial monitor, the serial data goes down the same USB cable used to program the Arduino.  So there must be a device on the Arduino board like a FTDI or USB-capable AVR that drives the RXD pin of the Arduino.  So my question is: When I want two Arduino boards to communicate with each other over serial, many tutorials say just connect RX and TX on one Arduino to TX to RX on the other.  So how come the device on the board that normally drives the RXD pin doesn't "fight" the other Arduino that is also now driving the RXD line?

The Atmega16U2 that does the USB communications is connected to Rx and Tx via 1k resistors, so when communicating with another Arduino it "overpowers" the USB interface. See image:

By the way, note that the Tx and Rx LEDs are connected to the Atmega16U2, not the Atmega328P, so they do not light when doing Arduino-to-Arduino communications.

Measuring with an empty sketch on my Uno, the current between Tx and Gnd was 0.14 mA, not 5 mA. So that suggests that the Atmega16U2 sets the pins to high-impedance when not actually receiving data from the USB interface.
It's logical it would do that, because the 5 mA you mention (in a comment) could be a nuisance if you wanted to use that pin for something else.

Awesome, thanks!  You were both very quick.  So does this mean that it is safe to power the Arduinos via the USB even when they are wired for serial communications with another Arduino?  And that the ATmega16U2 and the other Arduino will fight, but only with ~5mA?

Yes, I think that's done all the time. However, and this is important, because the Arduino-to-Arduino connection will overpower the USB interface, you will have trouble programming it (the one you are trying to program) while they are connected.

It's also possible, although I'm not certain, that the USB chip would set the pins to high-impedance when not actually in use. In fact, I just measured on my Uno, the current between Tx and Gnd was 0.14 mA, not 5 mA. It's logical it would do that, because the 5 mA you mention could be a nuisance if you wanted to use that pin for something else.

@NeilStockbridge So those 1k resistors are probably there as a precaution against you trying to reprogram the chip while it is connected to something else.

If we take a look at this portion of the Arduino Uno schematic (whole schematic is located here):

... we see there are two 1K Ohm (1,000 Ohms) resistors (labeled RN4A and RN4B) between the USB to serial conversion chip on the left to the Atmel processor at center right.  These allow the Rx (Receive) and Tx (Transmit) pins to be back driven by an externally connected device.

Beat me by a few seconds! :)

... you are a hard person to beat in these circles!

That must be an old schematic, as the Uno now has a Atmega328P not an Atmega8. However the principle is the same.

Hmmm, it came right off of arduino.cc's web site.
Oooh, that's what they meant by "Reference Design".

Mine has "Rev 3" on it, so you must have found an earlier revision. It's still a reference design though.

Here's the Rev 3 link.

Another  way to do serial communication between Arduinos is to use the SoftwareSerial library using (digital) pins of your choosing for serial communication between the Arduinos. Incidentally, it avoids interference from your computer under simple serial communication,

The SoftwareSerial library allows serial communication on other digital pins of an Arduino board, using software to replicate the functionality (hence the name "SoftwareSerial"). It is possible to have multiple software serial ports with speeds up to 115200 bps. A parameter enables inverted signaling for devices which require that protocol.

https://docs.arduino.cc/learn/built-in-libraries/software-serial
It takes just a little preparation and understanding, but not much.
#include <SoftwareSerial.h>

#define rxPin 10
#define txPin 11

// Set up a new SoftwareSerial object
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);

void setup()  {
    // Define pin modes for TX and RX
    pinMode(rxPin, INPUT);
    pinMode(txPin, OUTPUT);

    // Set the baud rate for the SoftwareSerial object
    mySerial.begin(9600);
}

void loop() {
    if (mySerial.available() > 0) {
        mySerial.read();
    }
}

In this example (copied from the above/linked article), you would use the mySerial variable to do your Arduino to Arduino communication in the same way as you use the standard serial connection. You would also need to wire the RX and TX pins of one Arduino to the TX and RX pin of the other Arduino, respectively.
One of the benefits of learning how to use the SoftwareSerial library is that there are many communication devices that use serial connection, such as Bluetooth modules (HC-05, HC-06, and HM-10 for example), that you can now use with ease. In this case, you can replace the wires I had you add with a Bluetooth module and communication between the 2 Arduinos wirelessly. Or you can instead communicate with a mobile device with the Bluetooth module.
https://www.instructables.com/Tutorial-Using-HC06-Bluetooth-to-Serial-Wireless-U-1/
Or you could access the internet with a WiFi module over SoftwareSerial.
https://www.taintedbits.com/2017/07/21/arduino-uno-esp8266-software-serial/

the question doesn't ask how to avoid interference. it asks why there isn't one.


text:
Python script cannot connect to serial port
I want to control the LEDs with my hand, for this I used the repository https://github.com/paveldat/finger_counter/tree/main. I want to control the LEDs with my hand, for this I used the repository. To connect to the arduino mega serial port, I use the pyserial library, here is the code to which I pass variables.
arduinoData = serial.Serial("com9", 9600)
arduinoData.write(bytes(str(variable), "utf-8"))

to control the LEDs and process data from the serial port, I wrote the following code in the Arduino IDE:
void setup() {
  Serial.begin(9600);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
}

void loop() {
/*
  if (Serial.available() > 0){
    serialData = Serial.read();

    for (int i = 3; i<serialData; i++){
      digitalWrite(i, HIGH);
    }
    }
*/
  if (Serial.available() > 0){
    char serialData = Serial.read();
    if (serialData == '3'){
      digitalWrite(3, HIGH);
      }
    else if (serialData == '4'){
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      }
    else if (serialData == '5'){
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH);
      }
    else if (serialData == '6'){
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH);
      digitalWrite(6, HIGH);
      }
    else if (serialData == '7'){
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH);
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
      }
    else if (serialData == '0'){
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
      }

    //Serial.println(serialData);
    //digitalWrite(serialData, HIGH);
    //delay(1000);
  }
}

when I run this code without connecting the camera and just pass the values to the serial port, then everything works. However, when I try to run this code together with the camera, the following error occurs:
serial.serialutil.SerialException: could not open port 'com9': PermissionError(13, 'Access denied.', None, 5)

The camera is a laptop webcam, I have not tested the code with the USB camera, the assumption is that the USB camera will not occupy all serial ports.

What operating system do you use? Are you sure, that "com9" is the correct port, especially when the camera is connected? (as this might change) Can you connect the camera and then open the port in the Arduino IDE?

There is the remote possibility that you also opened the Serial Monitor of Arduino IDE when you connected the USB camera. This may seem unrelated, but the Serial Monitor blocks other programs from using that COM port while it is running.

when I tested the code, my IDE was basically closed @orithena

I use windows 10 when the camera is turned on in the device manager as well as before COM9 is busy with arduino mega @chrisl

If it works fine with one part but not the other, then it may be that both parts are attempting to use the same resources, or that your old run is still using a port and has not been killed.  End your python piece with an exit call or simply del arduinoData

The problem with accessing the port is solved, it was busy since I tried to open it every time in a loop that receives an image and displays it on the screen. I took out the code for a cycle, but the LEDs did not start.
here is the updated code:
import cv2
import time
import os
import serial
import HandTrackingModule as htm

wCam, hCam = 640, 480

cap = cv2.VideoCapture(0)
cap.set(3, wCam)
cap.set(4, hCam)

folderPath = "fingers" # name of the folder, where there are images of fingers
fingerList = os.listdir(folderPath) # list of image titles in 'fingers' folder
overlayList = []
for imgPath in fingerList:
    image = cv2.imread(f'{folderPath}/{imgPath}')
    overlayList.append(image)

pTime = 0

detector = htm.handDetector(detectionCon=0.75)
totalFingers = 0

def arduino_write(totalFingers):
    arduinoData = serial.Serial("com9", 9600)
    arduinoData.write(bytes(str(totalFingers+2)+"\n", "utf-8"))
    arduinoData.close()

while True:
    sucess, img = cap.read()
    img = cv2.flip(img, 1)

    img = detector.findHands(img)
    lmList, bbox = detector.findPosition(img, draw=False)

    if lmList:
        fingersUp = detector.fingersUp()
        totalFingers = fingersUp.count(1)

    h, w, c = overlayList[totalFingers].shape
    img[0:h, 0:w] = overlayList[totalFingers]

    cTime = time.time()
    fps = 1/ (cTime-pTime)
    pTime = cTime

    cv2.putText(img, f'FPS: {int(fps)}', (400, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 0), 3)
    cv2.rectangle(img, (20, 225), (170, 425), (0, 255, 0), cv2.FILLED)
    cv2.putText(img, str(totalFingers), (45, 375), cv2.FONT_HERSHEY_PLAIN, 10, (255, 0, 0), 25)

    arduino_write(totalFingers)

    cv2.imshow("Image", img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

authors: Дмитрий Насонов


text:
L LED on Arduino is constantly on and com is not detected
When I connect the Arduino to the computer, the L LED is constantly on and com is not detected. However, when I press the reset button, the L LED starts blinking for about 10 seconds and com appears. But then he leaves.

What happens if you upload the Blink example in the moment when the com port appears?

Hold the Reset button down with one hand and start uploading the sketch (like, an empty sketch or the Blink sketch) with the other. Once you see "uploading" release the Reset button.


text:
error: expected unqualified-id before 'if' if (send) { but all semicolons are available
I am getting a compilation error: expected unqualified-id before 'if' .  Btu I have check all the semicolons . Please help finding my error.
The rest of the message error reads
C:\Users\jecalderon\Documents\Arduino\Codigo_AS7262_Investigacion_V2\Codigo_AS7262_Investigacion_V2.ino:35:1: error: expected unqualified-id before 'if'
 if (currentMillis - previousMillis >= interval) {
 ^~
C:........\Codigo_AS7262_Investigacion_V2.ino:40:1: error: expected unqualified-id before 'if'
 if (send) {
 ^~

exit status 1

Compilation error: expected unqualified-id before 'if'

#include <Wire.h>
#include "Adafruit_AS726x.h"
//create the object
Adafruit_AS726x ams;
//buffer para leer valores en bruto
uint16_t sensorValues[AS726x_NUM_CHANNELS];
//buffer para  guardar los valores calibrados( no esta siendo utilizado en este codigo)
//float calibratedValues[AS726x_NUM_CHANNELS];
unsigned long previousMillis = 0;
const long interval = 250;
bool send = false;
void setup() {
  Serial.begin(115200);
  while (!Serial) {
    // inicializa el pin digital LED_BUILTIN como un output.
    pinMode(LED_BUILTIN, OUTPUT);

    //inicia y permite la comunicacion con el sensor
    if (!ams.begin()) {
      Serial.println("could not connect to sensor! Please check your wiring.");

    }
  }
}
void loop() {
  //lee la temperatura del sensor
  //uint8_t temp = ams.readTemperature();
  //ams.drvOn(); // descomentar esto si quieres usar el led del sensor para hacer medidas
  ams.startMeasurement();  //begin a measurement
  //permite que el sensor lea la data cuando este disponible
  unsigned long currentMillis = millis();
};
//ams.drvOff(); //descomentar esto si quieres usar el led del sensor para hacer medidas
if (currentMillis - previousMillis >= interval) {
  previousMillis = currentMillis;
  send = true;
}

if (send) {
  //lee los valores!
  ams.readRawValues(sensorValues);
  //ams.readCalibratedValues(calibratedValues);

  //Serial.print("{");
  //Serial.print("Temp: ");
  //Serial.print(temp);
  //Serial.print(",");
  //Serial.print(" Violet: ");
  Serial.print(sensorValues[AS726x_VIOLET]);
  Serial.print(",");
  //Serial.print(" Blue: ");
  Serial.print(sensorValues[AS726x_BLUE]);
  Serial.print(",");
  //Serial.print(" Green: ");
  Serial.print(sensorValues[AS726x_GREEN]);
  Serial.print(",");
  //Serial.print(" Yellow: ");
  Serial.print(sensorValues[AS726x_YELLOW]);
  Serial.print(",");
  //Serial.print(" Orange: ");
  Serial.print(sensorValues[AS726x_ORANGE]);
  Serial.print(",");
  //Serial.print(" Red: ");
  Serial.print(sensorValues[AS726x_RED]);
  //Serial.print("}");

  Serial.println();

  send = false;
}

If your original issue is solved, please mark the answer. Do not change this question into something else, instead post a new question. You can link back to this question to provide some background. However, each question shall be self-contained.

Thank you or breaking my troubleshooting process. Publishing Updates have always been very effective to reach solutions to very difficult subjects.  I suggest you not to edit or remove any edit that specifically calls to be an UPDATE.  Now, I had to issue credit to an answer that although close to  a solution, had not  accomplished to  satisfy the objective.  This is bad enough added to the fact that you had down voted my original post that where active   receiving  feedbacks from community contributions.

Disclaimer: I did not vote down or edited your question. However, I feel with the one who did. -- You might want to take the [tour] (again) and read some of the [help] pages. This site is not a forum, and it might not support your process of troubleshooting. This is a Q&A site, with specific questions and answers, if there are some. If your issue is not solved, do not mark an answer and clarify why it does not answer the specific issue. But if your process leads to another issue, please post that in a new question. Otherwise you render all work done to the former useless.

Your update is not lost. You can see it if you follow the "edited" link. You can use that to post a new question. Please learn about this site before blaming.

I consider to watch closely people down voting on threads but offering no significant contribution to the post.  I have been around for 10 years and find this down voting activity motivated for the wrong reasons. I pointing  to the number of negative credits when compared to positive votes.  Hope my feedback is taken  well by the moderators and administrators.

The reasoning on closures and down-votes are already well formulated. If a question is closed, there is a lot of help in the frame above the question. The "down" button has a helpful popup. What should someone voting to close or down contribute more? The questioner is supposed to follow the rules, and many voters I see additionally leave a comment telling why. Please don't be paranoid, you are not stalked. If you have just above 100 reputation points after 10 years, it's not the fault of others.

Check your braces.  Use Control-T to autoformat your code and the error will become apparent.
This is your entire loop function.  Everything after this is is outside of the function.
void loop() {
  //lee la temperatura del sensor
  //uint8_t temp = ams.readTemperature();
  //ams.drvOn(); // descomentar esto si quieres usar el led del sensor para hacer medidas
  ams.startMeasurement();  //begin a measurement
  //permite que el sensor lea la data cuando este disponible
  unsigned long currentMillis = millis();
};

Thankyou for the contribution.

Did it solve your problem?