text:
Gyro reading of MPU6050 drifts too much on fast changes only
I am trying to write a simple sketch for the MPU6050.
The problem is that the sensor is pretty much solid when stationary or changing the angle steadily at slow to mid angular velocities but if I try to change the angle too fast there's a huge drift in the readings by pretty much tens of degrees in either direction as shown in the below images from the serial plotter.
On slow to mid changes in the pitch angle the gyro is tracking the accelerometer pitch almost identically (it drifts a little over time but it's normal and acceptable for the complementary filter).
On fast changes however the pitch drifts instantly by tens of degrees from the accelerometer. The huge drift makes the complementary filter pretty much useless in correcting the output
It's my first try with the sensor so I don't have any experience with its parameters. But the problem seems to be in the lines of integrating the new angular velocities in roll and pitch.

I got lazy and used the default sensitivity scale factors; does this have anything to do with this behaviour?

The dt measured for the Arduino is 20 ms between readings; is this too slow for the fast changes or something?

The datasheet also mentioned a programmable output range. Does this need to be programmed for more bandwidth and accurate results?

EDIT:
I tried to read a bit about the sensitivity scale factor. It seemed that increasing the angular velocity beyond 250 degrees per second is not measured when selecting the default configuration.
After some testing I realized that 1000 deg/s is a good configuration for me; the drift certainly is much better but still not what I hoped for.
It still drifts by +- 10 degrees in two or three seconds of moving it around.
Slow to Mid changes output:

Fast changes output:

#include <Wire.h>
#define CAL_AVERAGE 2000

const int MPU = 0x68; //I2C address of MPU6050
const float alpha = 0.95;

double ax, ay, az;
double gx, gy, gz;

//float accAngleX, accAngleY, accAngleZ;
//float gyroAgnleX, gyroAngleY, gyroAngleZ;

double accErrorX, accErrorY, accErrorZ;
double gyroErrorx, gyroErrorY, gyroErrorZ;

double accRoll, accPitch;
double gyroRoll, gyroPitch, gyroYaw;

double roll, pitch, yaw;

double dt, currentTime, previousTime;

void setup(){
  previousTime = 0;

  Serial.begin(115200);
  Wire.begin();     //init the communication

  //reset the mpu
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);
  Wire.write(0x00);
  Wire.endTransmission(true);

  //calibrate here
  calculateError();
}

void loop(){
  readAcc();
  readGyro();

  //get roll and pitch of accelerometer
  accRoll = atan2(ay, az) * 180 / PI;
  accPitch = atan2(ax, az) * 180 / PI;

  currentTime = millis();
  //set gyro roll and pitch for accelerometer roll and pitch on first reading only
  if (previousTime != 0) {
    //get roll, pitch and yaw of gyro
    dt = currentTime - previousTime;
    dt /= 1000;
    gyroRoll += gx * dt;
    gyroPitch += -gy * dt;
    gyroYaw += gz * dt;
  } else {
    gyroRoll = accRoll;
    gyroPitch = accPitch;
    gyroYaw = 0;
  }

  previousTime =  currentTime;

  roll = alpha*gyroRoll + (1 - alpha)*accRoll;
  pitch = alpha*gyroPitch + (1 - alpha)*accPitch;
  yaw = gyroYaw;

  //finally print the values collected
  printData();
}

void readAcc(){
  //first read accelerometer data
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true);

  //accelerometer raw data
  ax = ( (Wire.read() << 8) | Wire.read() ) / 16384.0;
  ay = ( (Wire.read() << 8) | Wire.read() ) / 16384.0;
  az = ( (Wire.read() << 8) | Wire.read() ) / 16384.0;

  ax -= accErrorX;
  ay -= accErrorY;
  az -= accErrorZ;
}

void readGyro(){
  //second read gyro
  Wire.beginTransmission(MPU);
  Wire.write(0x43);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true);

  //gyro raw data
  gx = ( (Wire.read() << 8) | Wire.read() ) / 131.0;
  gy = ( (Wire.read() << 8) | Wire.read() ) / 131.0;
  gz = ( (Wire.read() << 8) | Wire.read() ) / 131.0;

  gx -= gyroErrorx;
  gy -= gyroErrorY;
  gz -= gyroErrorZ;
}

void calculateError(){
  float axErr = 0, ayErr = 0, azErr = 0;
  float gxErr = 0, gyErr = 0, gzErr = 0;

  for (int i = 0; i < CAL_AVERAGE; i++) {
    readAcc();
    az = az - 1;

    axErr += ax;
    ayErr += ay;
    azErr += az;

    readGyro();

    gxErr += gx;
    gyErr += gy;
    gzErr += gz;
  }

  accErrorX = axErr/CAL_AVERAGE;
  accErrorY = ayErr/CAL_AVERAGE;
  accErrorZ = azErr/CAL_AVERAGE;

  gyroErrorx = gxErr/CAL_AVERAGE;
  gyroErrorY = gyErr/CAL_AVERAGE;
  gyroErrorZ = gzErr/CAL_AVERAGE;
}

void printData() {
  Serial.print(ax);
  Serial.print(",     ");
  Serial.print(ay);
  Serial.print(",     ");
  Serial.print(az);

  Serial.print(",               ");

  Serial.print(gx);
  Serial.print(",     ");
  Serial.print(gy);
  Serial.print(",     ");
  Serial.print(gz);

  Serial.print(",               ");

  Serial.print(accPitch);
  Serial.print(",     ");
  Serial.print(accRoll);

  Serial.print(",               ");

  Serial.print(gyroPitch);
  Serial.print(",     ");
  Serial.print(gyroRoll);
  Serial.print(",     ");
  Serial.print(gyroYaw);

  Serial.print(",               ");

  Serial.print(pitch);
  Serial.print(",     ");
  Serial.print(roll);
  Serial.print(",     ");
  Serial.print(yaw);

  Serial.print(",     ");
  Serial.println(dt);
}

In his answer, st2000 recommends you use quaternions, rather than Euler
angles, for tracking the orientation of your vehicle. I will give the
exact same recommendation, but for a different reason: the formulas you
use, namely
gyroRoll += gx * dt;
gyroPitch += -gy * dt;
gyroYaw += gz * dt;

are just plain wrong. They are correct if rotations only ever happen
along a single axis. They are also “kinda good” (correct as a
first-order approximation) if the angles involved are very small. But in
the general case, they are wrong. A easy way to convince yourself of
this fact is to notice that the final (yaw, pitch, roll) being the sum
of many small contributions, they do not depend on the order in which
these contributions were added. In other words, these formulas imply
that the composition of rotations is commutative, which I hope you know
is not the case.
The only reasonable ways of composing many rotations (which is what this
attitude-tracking code tries to do) are rotation matrices and
quaternions, the latter being more efficient.
Now, a few remarks:

You should not track (gyroRoll, gyroPitch and gyroYaw)
independently from (roll, pitch, yaw), otherwise your
complementary filter becomes inefficient at canceling gyro drift.
You should instead merge those variable into a single triplet.

The line
( (Wire.read() << 8) | Wire.read() ) / 16384.0;

gets you the two bytes from the MPU in an unspecified order. They
may be in the right order with this particular version of this
particular compiler when run with this particular set of options,
but you should not count on this order being reliable. You should
instead read the two bytes in two separate statements.

If you do not care about the yaw, you may just track the gravity
vector instead of the full attitude. This should save you the calls
to atan2() and possibly simplify the math further. You may not
even need the quaternions after all.

Consider what might happen if the code or hardware dead reckoning capabilities were too slow to accurately sample short events. Such as a sudden stop. Robbed of the opportunity to integrate a fast deceleration event, the code and hardware might continue to report motion.
To speed up code execution, consider switching from trigonometry based calculations to quaternion calculations.  In general this replaces time consuming repetitive summation algorithms with simple math calculations more suitable for embedded processors.
To speed up the hardware, consider an Arduino platform with a faster processor.
Also consider more creative solutions suitable for your application:

If angular momentum is more important than linear motion sample the accelerometer only every other time through your main loop.
Or, if motion is totally random, and the device is on Earth, consider zero-calibrating the gyroscope when there is no movement perceived by the accelerometer.  Specifically, when there is a 9.8m/s*s vector sensed by the accelerometer and the pitch, roll and yaw of the accelerometer is not changing.


text:
Avrdude verification error when uploading to Arduino Mega 2560
I have been getting the error
avrdude: verification error, first mismatch at byte 0x036c
0xb8 != 0xf8
avrdude: verification error; content mismatch
avrdude done.  Thank you.

When trying to upload the example blink sketch to an Arduino mega 2560.
I did some googling and found that the common recommendation to solve this is to flash the bootloader.
Which does fix the issue for the first upload after flashing, but the issue reappears after one upload. But every time I flash the bootloader I do get one successful upload following that with no errors.
The mismatch is always at 0x036c every time.

Did you see this answer?

I did see that and flashed a new bootloader, the voltage of the board seems stable 4.9V
and I think the usb driver or cable are unlikely because I was able to try an identical Arduino that does not have the errors which means maybe its be a hardware issue with this specific board?

The verification is there to check two possible error situations: Transmission error while uploading or faulty flash memory. Apparently, the error can also happen for a bunch of other reasons (see the linked answer), but these two cases should still be considered. Since another Arduino works with the same cable, it's unlikely a communication error and hence, based on all we know, I am assuming your Arduino is bad.
You might be lucky that for some reason (the fault is in some piece of code that's not actually used) the program works despite the error, but it's likely that sooner or later you'll get very strange crashes or otherwise undefined behavior.

Yeah its probably just a bad arduino. I just found it weird that the verification seemed to work fine after flashing the bootloader but then went back to failing.

Maybe something is different the first time internally. Or the bootloader itself already doesn't work correctly.

source: Stack Exchange

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

sort: votes


text:
How can I force an I2C module (for 1602 and 2004) to work with a 1601 LCD at my Arduino Micro
I'm new to Arduino and want to build a Button Box. When I buyed the parts I didn't watched out for the specifications of the I2C module. When I tried to print sth on the LCD nothing happened (in retro perspective it's logical). I wouldn't like to have to buy a new LCD.
How can I make the LCD work with the I2c module?
LCD - http://cdn-reichelt.de/documents/datenblatt/A500/DEM16101SYH.pdf
I2C-module - http://mantech.co.za/datasheets/products/lcd2004-i2c.pdf
it's wired correctly (VCC to 5V, GND to GND, SDA to SDA and SCL to SCL)
The Code I used is the "Hello World" Example thats included in the LiquidCrystal_I2C library, but with a few changes:
//YWROBOT
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,1);  //instead of LiquidCrystal_I2C lcd(0x27,20,4);

void setup()
{
  lcd.init();                      // initialize the lcd
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(3,0);
  lcd.print("Hello, world!");
  lcd.setCursor(2,0); //isntead of lcd.setCursor(2,1);
  lcd.print("Ywrobot Arduino!");
   lcd.setCursor(0,0); //instead of lcd.setCursor(0,2);
  lcd.print("Arduino LCM IIC 2004");
   lcd.setCursor(2,0); //instead of lcd.setCursor(2,3);
  lcd.print("Power By Ec-yuan!");
}

void loop()
{
}

Hi @Chritzeltopf, welcome to Stack Overflow. If you edit your question to include the code you tried, what kind of LCD you’re connecting and how you wired it up, someone may be able to help you. Otherwise we know even less about what you’re doing than you do.

Sorry :(, I thought the given informations would be enough for the question. Added the infos :)

Yep, it's one line. That's the problem

what connections did you make? ... the I2C module provides the 8 data bits to the LCD module ... the E, R/S and RE signals to the LCD must be generated by the arduino

@VE7JRO it happens nothing

@jsotola what exactly do you want to know? I don't really get it?

How about this library just to test if you can get it to work with a simple sketch? https://github.com/AlexMartin17/Arduino-LCD-Library-16x1

Welcome! You mentioned how you you connected it but a schematic is always better. Where did you put your pull up resistors and did the I2C scan return the correct port?

@Gil do I need Pullup resistors on the SDA and SCL pins to use the I2C module? The I2C scan sketch that I used didn't worked (no address was printed in the Serial) so I guess the I2C module didn't communicated with the LCD?

I think we just found your problem. This happens a lot, I see it several times a week. Keep up the good work.

Welcome Chritzelopf! Yes pull up resistors are required by the I2C definition. Your link on the driver shows they are not included and no schematic to  indicate otherwise. The I2C bus is driven by open collector/drain semiconductor devices. This configuration will pull the line low but not source any current into it other then possibly some leakage. When the outputs of the I2C device are off the bus is pulled high or placed in the recessive state by the pull up resistors. When one or more of the devices turn on the bus is now in the dominate state or low. This configuration allows anything to turn on or off without damaging other devices on the bus. I like the pull up(s) to be in the 4.7K for 5V and about 3.3K in the 3V3v.
Some modules come with pull ups that are permanently connected, others are selectable with jumpers etc. This is NOT the A0 - A? jumpers which are address select lines. I always check the modules to determine if there are pull ups enabled and adjust my other resistances to get an appropriate value, sometimes even removing them.

So should I try it again with "pinMode(2, INPUT_PULLUP)"; pinMode(3, INPUT_PULLUP) ;

The library I use does not allow that as it programs them the way it wants. It does not report it just does. The safest, most likely to work is to use the recommended external resistors. Once you get it working then try your pull up idea. Remember they are somewhere in the 30 to 50K range.

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


text:
ESP8266 web server not responding when running a http request function
I am trying to build something that can control a stepper motor based on weather information from openweathermap. I've set up a ESP8266 webserver to manually control motor movement with buttons and I have set up the structure to talk to openweathermap API to get the information I want (printing them to serial monitor for now for testing).
However, when I combined the 2 things break. The current code allows me to get weather perfectly but I can no longer connect to my web server running in STA mode. Something in the getWeather() function is messing with the web server because if I remove getWeather() from my loop the web server works.
Any idea what I am doing wrong here?
#include <SPI.h>
#include <AccelStepper.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>  // http web access library
#include <ArduinoJson.h>        // JSON decoding library

// Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver:
#define dirPin 5
#define stepPin 4
#define motorInterfaceType 1
bool motorStop;
bool motorCW;
bool motorCCW;

AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

//Put your SSID & Password
const char* ssid = "[ssid]";  // Enter SSID here
const char* password = "[password]";  //Enter Password here

//OpenWeatherMap API key
String apiKey= "[apikey]";

//OpenWeatherMap location
String location= "lat=37.30&lon=-121.91";
String unit= "metric";

const unsigned long postingInterval = 1000*60*60; // delay between updates, in milliseconds

WiFiClient client;

ESP8266WebServer server(80);

// Set your Static IP address
IPAddress local_IP(192, 168, 86, 248);
// Set your Gateway IP address
IPAddress gateway(192, 168, 86, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(192, 168, 86, 1);

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

// Configures static IP address
if (!WiFi.config(local_IP, gateway, subnet,primaryDNS)) {
  Serial.println("STA Failed to configure");
}

  stepper.setMaxSpeed(1000);

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

  //connect to your local wi-fi network
  WiFi.begin(ssid, password);

  //check wi-fi is connected to wi-fi network
  while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.print(".");
  }
  //Print out connection info
  Serial.println("");
  Serial.println("WiFi connected..!");

  server.on("/", handle_OnConnect);
  server.on("/cw_on", handle_CW_on);
  server.on("/cw_off", handle_CW_off);
  server.on("/ccw_on", handle_CCW_on);
  server.on("/ccw_off", handle_CCW_off);
  server.on("/mstop", handle_stop);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop() {

  server.handleClient();
  if(motorStop)
  {stepper.setSpeed(0);}
  if(motorCW)
  {stepper.setSpeed(400);}
  if(motorCCW)
  {stepper.setSpeed(-400);}

  // Step the motor with a constant speed as set by setSpeed():
  stepper.runSpeed();

  getWeather();
}

void getWeather()
{
  // if there's a successful connection:
  if (client.connect("api.openweathermap.org", 80))
  {
    Serial.println("connected");
    // send the HTTP PUT request:
    client.println("GET /data/2.5/onecall?" + location + "&exclude=current,minutely,hourly" +  "&appid=" + apiKey);
    client.println("Host: api.openweathermap.org");
    client.println("Connection: close");
    client.println();

    const size_t capacity = 8*JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(8) + 16*JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + 8*JSON_OBJECT_SIZE(6) + 8*JSON_OBJECT_SIZE(14) + 1810;
    DynamicJsonDocument doc(capacity);

    deserializeJson(doc, client);

    float lat = doc["lat"]; // 37.3
    float lon = doc["lon"]; // -121.91
    const char* timezone = doc["timezone"]; // "America/Los_Angeles"
    int timezone_offset = doc["timezone_offset"]; // -25200

    JsonArray daily = doc["daily"];

    // tomorrow's forecast (daily_1)
    JsonObject daily_1 = daily[1];
    long daily_1_dt = daily_1["dt"]; // 1596225600
    long daily_1_sunrise = daily_1["sunrise"]; // 1596201109
    long daily_1_sunset = daily_1["sunset"]; // 1596251761

    JsonObject daily_1_temp = daily_1["temp"];
    float daily_1_temp_day = daily_1_temp["day"]; // 306.61
    float daily_1_temp_min = daily_1_temp["min"]; // 288.67
    float daily_1_temp_max = daily_1_temp["max"]; // 306.61
    float daily_1_temp_night = daily_1_temp["night"]; // 288.67
    float daily_1_temp_eve = daily_1_temp["eve"]; // 295.94
    float daily_1_temp_morn = daily_1_temp["morn"]; // 293.26

    JsonObject daily_1_feels_like = daily_1["feels_like"];
    int daily_1_feels_like_day = daily_1_feels_like["day"]; // 303.31
    float daily_1_feels_like_night = daily_1_feels_like["night"]; // 287.59
    float daily_1_feels_like_eve = daily_1_feels_like["eve"]; // 293.77
    float daily_1_feels_like_morn = daily_1_feels_like["morn"]; // 292.42

    int daily_1_pressure = daily_1["pressure"]; // 1015
    int daily_1_humidity = daily_1["humidity"]; // 17
    float daily_1_dew_point = daily_1["dew_point"]; // 278.68
    float daily_1_wind_speed = daily_1["wind_speed"]; // 3.12
    int daily_1_wind_deg = daily_1["wind_deg"]; // 318

    JsonObject daily_1_weather_0 = daily_1["weather"][0];
    int daily_1_weather_0_id = daily_1_weather_0["id"]; // 800
    const char* daily_1_weather_0_main = daily_1_weather_0["main"]; // "Clear"
    const char* daily_1_weather_0_description = daily_1_weather_0["description"]; // "clear sky"
    const char* daily_1_weather_0_icon = daily_1_weather_0["icon"]; // "01d"

    int daily_1_clouds = daily_1["clouds"]; // 0
    int daily_1_pop = daily_1["pop"]; // 0
    float daily_1_uvi = daily_1["uvi"]; // 9.53

    // print out weather information
    Serial.print("Tomorrow's Forecast");
    Serial.print("Temperature: ");
    Serial.println(daily_1_feels_like_day);
    Serial.print("Weather: ");
    Serial.println(daily_1_weather_0_main);
    delay (postingInterval);
  }
  else
  {
    // if you couldn't make a connection:
    Serial.println("connection failed");
    delay (postingInterval);
  }
}

void handle_OnConnect() {
  motorStop = HIGH;
  motorCW = LOW;
  motorCCW = LOW;
  Serial.println("Motor: Stopped");
  server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
}

void handle_CW_on() {
  motorStop = LOW;
  motorCW = HIGH;
  motorCCW = LOW;
  Serial.println("Motor: Running Clock-wise");
  server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
}

void handle_CW_off() {
  motorStop = HIGH;
  motorCW = LOW;
  motorCCW = LOW;
  Serial.println("Motor: Stopped");
  server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
}

void handle_CCW_on() {
  motorStop = LOW;
  motorCW = LOW;
  motorCCW = HIGH;
  Serial.println("Motor: Motor: Running Counter Clock-wise");
  server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
}

void handle_CCW_off() {
  motorStop = HIGH;
  motorCW = LOW;
  motorCCW = LOW;
  Serial.println("Motor: Stopped");
  server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
}

void handle_stop() {
  motorStop = HIGH;
  motorCW = LOW;
  motorCCW = LOW;
  Serial.println("Motor: Stopped");
  server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(uint8_t mstop,uint8_t cw, uint8_t ccw){
  String ptr = "<!DOCTYPE html> \n";
  ptr +="<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr +="<title>LED Control</title>\n";
  ptr +="\n";
  ptr +="\n";
  ptr +="\n";
  ptr +="
Weather Station
\n";
  ptr +="
Runs either direction continuously
\n";

   if(cw)
  {ptr +="
Motor running Clock-wise
Stop\n";}
  else
  {ptr +="
Motor not running Clock-wise
Run\n";}

  if(ccw)
  {ptr +="
Motor running Counter Clock-wise
Stop\n";}
  else
  {ptr +="
Motor not running Counter Clock-wise
Run\n";}

  ptr +="\n";
  ptr +="\n";
  return ptr;
}

At the end of getWeather() you call delay(postingInterval);
postingInterval is set to 60*60*1000 ... one hour. That means getWeather() won't return for one hour and nothing else in loop() will be processed during that time, including the web server.
You need to remove that delay() call and rewrite your loop to check if postingInterval milliseconds have passed and only call getWeather() if they have.

Thanks this works! However now there is a new problem. I am using millis() in my loop to call getWeather(). However the interval will affect how stepper runs. stepper.runSpeed() is suppose to get stepper to run continuously at the set direction; but now the stepper would pause at interval.

Great, happy that helped. The new problem sounds like a good thing to post as a new question; then you'll get the attention of a lot of people who might answer it and not see it here as a comment :)

Will do. Thank you!


text:
Switch power of PN532 on and off from ESP32?
I have a strange issue with PN532, by some reason it is not every time recognized, and it turns out that if I switch Off and On the power - it goes recognised , but I am trying no to switch the whole board, so I wonder if I use a transistor to make this switch - like BD139 will it cause some issue, or if there is a better solution ?
Here the circuit I am wondering about :

P.S. I have this board :

Before you get too far down this track you should try the PN532's powerdown/reset signal.

hey @timemage. Well.. How to do that ?

To know that the signal is even exposed on your board, we'd need to know which exact breakout you have, which might also inform other useful answers. You're asking about this circuit where you're try to control the PN532's GND which will have nothing to do with a prospective answer about RESET, again, assuming that's even possible. The NPN circuit itself is perhaps more ESE material. So, I'm not sure how you want to proceed. I'd give details on the breakout your using, code you're using, and how it's wired.

@timemage I jut added the board i have. I am using SPI. ( SCK / MISO / MOSI / SS ).

I've research on the net, and seems like this stall of the board is something common, which caused a lot of projects to fail.

There is a hardware Reset and Power-Down pin on pin38 of the chip, turn your board upside down and you will see a pin RSTPDN or something like that. Read about on-board LDO on page 85 and Hard Power-Down mode on page 91 of the datasheet to get to know more.

Mine has a slightly different silkscreen, otherwise the same. I'd have liked to try their code and wiring scheme to replicate the problem to see that it actually solves it, but that hasn't materialized. Going to be away form the normal setup for a couple of days anyway now. If the code and wiring does show up, someone may answer with something completely different with the new information or be able to actually test your problem.

@YordanYanakiev, are you able to share your code?

I beieve this is the schematic for the PN532 Module shown in the photo https://www.elechouse.com/elechouse/images/product/PN532_module_V3/PN532_shematic_drowing.pdf

Looking now at the datasheet you've posted i realised that both SPI and I2C is marked 5V, while I am powering it from 3.3V ( as it is shown in most examples ) Could this cause the issue?

The manual for the (similar) module from Elechouse suggests it’s voltage tolerant. https://www.elechouse.com/elechouse/images/product/PN532_module_V3/PN532_%20Manual_V3.pdf

therefore this should not be an issue..

Hi @YordanYanakiev are you able to share your code and wiring setup? It would be interesting to see if the module recognition problem can be replicated. There may be a more elegant solution, but if power cycling using the RSTPD_N pin is the way forward suggestions can be made that fit with your code.

hey @RowanP sure. asap as i return from holydays will do.


text:
L LED keeps staying on
I am trying to get the Arduino to reboot my PC when it is off.
Using the front panel header on the PC, I connected the power switch and PLED directly to the Arduino Uno as the header only outputs 5 V.
I'm able to check the status using the L LED, but once I connect the power switch pins to the Arduino to turn on the PC the L LED is always on. This kind of defeats the purpose of what I was trying to do as I wanted the L LED to be off when the PC is off and on when the PC is on, similar to how the LED on the PC power button works.
If someone can give their insight please, the code and pin diagram is below.
const int ledPin = 13; // LED on arduino should be on when PC is on and off when PC is off
const int pwrPin = 8; // attached to power switch to turn on and off PC
const int PLED = 7;

void setup() {
  Serial.begin(9600);  // initialize serial communication:
  pinMode(PLED, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(pwrPin, OUTPUT);
}

void loop() {
  int status;
  status = digitalRead(PLED); // reads the status of PLED
  if (status == HIGH) { // if PC is on keep on until Python script shuts down PC.
    digitalWrite(ledPin, HIGH);
    Serial.print("PC is on");
    delay(5000);
  }
  else { // when PC is off, arduino should turn back on to cold reboot the PC
    digitalWrite(ledPin, LOW);
    Serial.print("PC is off. Turning on in 10 seconds");
    delay(10000);
    // Added Code. Emulates pushing the PC button when PC is off
    digitalWrite(pwrPin, LOW);
    delay(500);
    digitalWrite(pwrPin, HIGH);
  }
  delay(500);
}

The little box with circles is the front panel header on the mobo.

what's an L LED?

@jsotola The Arduino built in LED.

why is it called ledPin in your code?

what is printed in the serial console? ... please copy and add to your question

why are you assuming that there is something wrong with the LLED? ... maybe your code is working correctly

Did I understand right in that the LED correctly showed the status of the PC, until you finally connected the power switch pins to the Arduino? Please clarify. If this is correct: How exactly did you connect everything?

@chrisl Yes, that is correct. When I disconnect the power switch pins the LED works as intended: ON when the PC is on and OFF when the PC is off. Yet, when I put the power switch pins in, the LED is always turned on. I edited my post to show the pin connections.

Can you try it again with connecting to the power switch pins, but configuring the pwrpin as INPUT? It won't turn your PC on that way but INPUT makes a pin high impedance (electric equivalent of an unconnected pin) and I want to check if that changes something (and maybe find something about the core problem)

@chrisl I've tried that before, but I just took another crack at it and same thing happened. Separately, I have tried running just the code to turn on the PC on another file and I found that setting the pwrpin to OUTPUT works , but INPUT does not. Which is why I set pwrpin as OUTPUT in my main code. Hope this information is useful.

@chrisl Also, I don't know if this will help or if you already know this but the pwr switch outputs 5v at anytime even when the PC is off. When I turn off the PSU, the pwr switch has no voltage and the built-in LED turns off.

@Ant, the power switch is connected between ground and power-on signal line ... the power-on signal is most likely pulled towards 5 V with a pullup resistor ... the switch pulls it to ground when the switch is pressed

Did you check the circuit internal to the motherboard, how the LED is controlled? Chances are that "PLED-" is switched, not "PLED+", so that connecting "PLED-" to GND as you did will make it on all the time. Measure the pins on the PC's header, for example.

@thebusybee I know that when the PC is on PLED is measured at 5v and 0v when the PC is off. Is that what you're talking about?

@jsotola would that be a potential cause for the built-in LED to be always on?

Hm, which of both PLED pins do you mean? -- What do you measure at "PLED-" if the PC is on, what if the PC is off, and what do you measure at "PLED+" the same time? Do not connect the Arduino and use "GND" as reference. Please add these four values to your question by [edit]ing it.

The led power pins on the motherboard you are connecting to are not "power led+" and "power led-", they are "led+" for two separate leds (specifically meant for a green led and a yellow led). See this page for the pinout used by Intel.
All the leds use the a common ground for "led-". By connecting it as you have, you are shorting out one of the led pins. Disconnect that pin from ground and you should be able to read the other pin correctly.


text:
Setup loops: never enters loop - restarting?
I uploaded the following to my UNO with WiFi:
#include <SPI.h>
#include <Wire.h>
#include "Adafruit_CCS811.h"

Adafruit_CCS811 ccs; // The air quality sensor

String Dataline = "";

void setup() {
  Wire.begin();

  Serial.begin(115200);
  Serial.println("SET UP");
}

void loop() {
  // wait a second between measurements.
  delay(1000);

  Dataline = "";
  Dataline = Dataline + getTime();
  Dataline = Dataline + AIRSensor();
  Dataline = Dataline + "...";
  Serial.println(Dataline);
}

String getTime() {
  String OUT = "Tim::";
  OUT += String(millis());
  return OUT;
}

String AIRSensor() {
  if (ccs.available()) {
    if (!ccs.readData()) {
      float temp = ccs.calculateTemperature();
      String CO2 = (String)ccs.geteCO2();
      return "CO2::" + CO2 +"TAQ::" + (String)temp;
    }
  } else {
    return "CO2::-999,TAQ::-999";
  }
}

The output is simply "SET UP" repeated:
SET UP
SET UP
SET UP
...

It never enters the loop or prints anything else out. Does this mean the UNO is resetting? How do I troubleshoot?

how do you know that it does not enter loop()? ... you have no code that confirms that

You can tell that something is going wrong between your println. Some advice in this case: eliminate the String entirely and replace the println with a series of print. This would let you narrow down which function is causing the problem. It also can save some memory, which is a nice bonus in embedded programming.
I suspect in this case the problem is your use of C-style casts to String in AIRSensor(). (String)whatever and String(whatever) do very different things, and the former is not something you want here, or something you should be using very often in C++ code.
The code in loop is running, but it is crashing and causing the hardware to reset. Since it is crashing before it reaches the first visible behavior in loop, it just looks like setup is running over and over.

Thanks! Changing from '(String)' to 'String()' made a massive difference.
It now runs for about 6 loops, and then stops for a while. In the IDE, I get a 'Error while setting serial port parameters: 115,200 N 8 1' message. It then restarts again.
Is there any way to stop that?

'twas an issue with me not using 'ccs.begin()'. Thank you for your help!!


text:
How to set number in address field?
I want to build structure of record. The problem is that I can't build the address field correctly. Can any one help me?
P.s: the address[16:2] is start from bit 61 to bit 47 so please you can't say you should shift it by 32.

For this I would use bit fields:
typedef union {
    struct {
        uint8_t raw[8]; // Raw access to the bytes
    };
    struct {
        unsigned data:32;
        unsigned cs14:1;
        unsigned cs13:1;
        unsigned cs12:1;
        unsigned cs11:1;
        unsigned cs10:1;
        unsigned cs9:1;
        unsigned cs8:1;
        unsigned cs7:1;
        unsigned cs6:1;
        unsigned cs5:1;
        unsigned cs4:1;
        unsigned cs3:1;
        unsigned cs2:1;
        unsigned cs1:1;
        unsigned cs0:1;
        unsigned address:15;
        unsigned parity:1;
        unsigned stop:1;
    };
    struct {
        unsigned :32;
        unsigned cs:15;
        unsigned :17;
    };
} Packet;

Then you can:
Packet p;
p.data = 0x493DE26CUL;
p.address = 0x13f3;
p.cs3 = 1;
// or
p.cs = 0x0080;

etc.


text:
Non-blocking sketch
So far, a part of this code works fine, but Relay 1 keeps turning on and off instead of staying off.
My purpose is to turn Relay 7 on, wait 3s, turn Relay 8 on, wait 10s, turn Relay 6 on, wait 10s, turn Relay 7 off, wait 10s, turn Relay 5 on, wait 3s, turn Relay 6 off, wait 10s, turn Relay5 on, wait 3s, turn Relay 6 off, wait 10s, turn Relay4 on, wait 3s, turn Relay 5 off, wait 10s, turn Relay 3 on, wait 3s, turn Relay 4 off, wait 10s, turn Relay 2 on, wait 3s, turn Relay 3 off, wait 10s, turn Relay 1 on, wait 10s, turn Relay 1 off, wait 3s, turn Relay 8 off, without looping, only one sequence.
I need some help.
int RelayPompe = 2;
int RelayVanne7 = 3;
int RelayVanne6 = 4;
int RelayVanne5 = 5;
int RelayVanne4 = 6;
int RelayVanne3 = 7;
int RelayVanne2 = 8;
int RelayVanne1 = 9;

const unsigned long eventInterval1 = 10000;
const unsigned long eventInterval2 = 3000;
const unsigned long eventInterval3 = 15000;
const unsigned long eventInterval4 = 20000;
unsigned long previousTime1 = 0;
unsigned long previousTime2 = 0;
unsigned long previousTime3 = 0;
unsigned long previousTime4 = 0;

void setup() {
  Serial.begin(9600);
  pinMode(RelayPompe, OUTPUT);
  pinMode(RelayVanne1, OUTPUT);
  pinMode(RelayVanne2, OUTPUT);
  pinMode(RelayVanne3, OUTPUT);
  pinMode(RelayVanne4, OUTPUT);
  pinMode(RelayVanne5, OUTPUT);
  pinMode(RelayVanne6, OUTPUT);
  pinMode(RelayVanne7, OUTPUT);
  digitalWrite(RelayPompe, HIGH);
  digitalWrite(RelayVanne1, HIGH);
  digitalWrite(RelayVanne2, HIGH);
  digitalWrite(RelayVanne3, HIGH);
  digitalWrite(RelayVanne4, HIGH);
  digitalWrite(RelayVanne5, HIGH);
  digitalWrite(RelayVanne6, HIGH);
  digitalWrite(RelayVanne7, HIGH);
}

void loop() {
  unsigned long currentTime = millis();
  if (currentTime - previousTime1 >= eventInterval1) {
    digitalWrite(RelayPompe, LOW);
    previousTime1 = currentTime;
  }
  if (currentTime - previousTime2 >= eventInterval2) {
    digitalWrite(RelayVanne1, LOW);
    previousTime2 = currentTime;
  }
  if (currentTime - previousTime3 >= eventInterval3) {
    digitalWrite(RelayVanne2, LOW);
    previousTime3 = currentTime;
  }
  if (currentTime - previousTime4 >= eventInterval4) {
    digitalWrite(RelayVanne1, HIGH);
    previousTime4 = currentTime;
  }
}

which one is relay 1?

please review what you wrote ... there appear to be some mistakes

@jsotola "RelayPompe is number 1 and connected to pin 2 of arduino board"

the code you presented does not continually cycle RelayPompe, unless the arduino repeatedly resets ... add some debugging code to determine what is happening

have you read your description of the desired sequence? ... there appears to be an error that messes up timing

stil cant figure it out.

you said wait 10s turn Relay 5 On, wait 3s turn Relay 6 Off twice in a row

it is a watering system I need to turn on relay 1 first wich connected to Solenoid Valve 1 then turn on relay 8 wich is connected to waterpompe and keep it running the rest of sequence, then turn on relay2 -Solenoid Valve2 after 3s turn off relay1 then after 10s turn on relay3-Solenoid Valve3 then after 3s turn off relay2 ...  until relay8-Solenoid Valve8 , at the end turn off relay 8-waterpompe and finish sequence. by the way  3s and 10 are just for testing later wil modify to longer period

For this kind of thing I'd be inclined to create an array (maybe of structs) describing what you want the relays to do, then write a program that steps through that array executing each "instruction" in sequence. That way it separates out what you want to do from how you want it to be done (if that makes sense).
So you could make a simple struct:
typedef struct {
    uint8_t relays;
    uint32_t postDelay;
} RelayState;

Then you can make an array using that struct to describe your relay states. Using a bitmap for your relays (bit 0 is relay 1, bit 1 is relay 2, etc) means you can pack everything into one integer and describe the relays in binary notation:
RelayState states[] = {
    { 0b01000000,  3000 }, // Relay 7 on, wait 3 seconds
    { 0b11000000, 10000 }, // Relay 8 on, wait 10 seconds
    { 0b11100000, 10000 }, // Relay 6 on, wait 10 seconds
    { 0b10100000, 10000 }, // Relay 7 off, wait 10 seconds
    { 0b10110000,  3000 }, // Relay 5 on, wait 3 seconds
    // ... etc ...
    { 0, 0 } // Marker for the end of the array
};

If ever you want to change the sequence you just change the contents of that array with no need to mess with the rest of your program.
It can also be useful to create an array with your relay pins in it:
const uint8_t relayPins[8] = { 9, 8, 7, 6, 5, 4, 3, 2 };

Now you just need to write a small program that only has to deal with the current entry in the array - set the relays according to the first part then delay according to the second part, and step to the next entry.  Something that could look like:
void setup() {
    // Set the relay pins to outputs
    for (int i = 0; i < 8; i++) {
        pinMode(relayPins[i], OUTPUT);
    }

    // Set the initial state from the first entry in the array
    setRelays(states[0].relays);
}

void loop() {
    static uint32_t ts = millis(); // Storage for the time
    static uint8_t pos = 0;

    if ((millis() - ts) >= states[pos].postDelay) { // Our time is up
        ts = millis(); // Record the time
        pos++; // Move to the next entry
        if ((states[pos].relays == 0) && (states[pos].postDelay == 0)) { // Last entry marker
            pos = 0; // Start from the beginning again
        }
        setRelays(states[pos].relays);
    }
}

// Small helper function to set the relays according to a bitmap
void setRelays(uint8_t bm) {
    for (int i = 0; i < 8; i++) {
        digitalWrite(relayPins[i], bm & (1 << i));
    }
}

Note: this code has not been tested, just written "off the cuff", and may not even compile. But regardless, it should give you a rough idea of the methodology.

The format of the bitmaps is very simple. They're just a binary representation of a number where each bit is one relay. Turn that bit on and the corresponding relay turns on.

Relay 1: 0b00000001
Relay 2: 0b00000010
Relay 3: 0b00000100

etc.  Just set a 1 for a relay to be on and a 0 for a relay to be off at that point in time.
So turn relay 1 on is 0b00000001, then turn on relay 4 at the same time is 0b00001001, and then turn relay 1 off again is 0b00001000 (relay 4 is still on).

I got it I have to write all binary for all pins, I wil give it a try

plz explain to me how to add more entry in array:{ 0b01000000,  3000 }

what is { 0b01000000,  3000 } and how to add all the relays?

0bxxxxxxxx is the state of each of the 8 relays. 3000 is how many ms to delay for.

3000 is the ms delay but 0bxxxxxxxx, how to add all the 8 relays wich rule to create it?

Decide which relays you want on and which you want off - relay 8 is on the left and relay 1 on the right. 1 for on, 0 for off. So turning on relays 1 5 and 7 would be 0b01010001.


text:
Error while burning bootloader onto ATMega-8A using Arduino Mega 2560: avrdude: invalid byte value
So, I'm trying to burn the bootloader onto an ATMega 8A with an Arduino Mega 2560 as ISP.
I made the necessary connections, and got this error:
C:\Program Files (x86)\Arduino\hardware/tools/avr/bin/avrdude -CC:\Program Files (x86)\Arduino\hardware/tools/avr/etc/avrdude.conf -v -v -v -v -patmega8 -cstk500v1 -P\\.\COM3 -b19200 -e -Ulock:w:0x3f:m -Uhfuse:w:0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}:m -Ulfuse:w:0b{bootloader.bod_bits}{bootloader.sut_cksel_bits}:m

avrdude: Version 5.11, compiled on Sep  2 2011 at 19:38:36
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is "C:\Program Files (x86)\Arduino\hardware/tools/avr/etc/avrdude.conf"

         Using Port                    : \\.\COM3
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
avrdude: Send: 0 [30]   [20]
avrdude: Send: 0 [30]   [20]
avrdude: Send: 0 [30]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
         AVR Part                      : ATMEGA8
         Chip Erase delay              : 10000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom         4    20   128    0 no        512    4      0  9000  9000 0xff 0xff
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           flash         33    10    64    0 yes      8192   64    128  4500  4500 0xff 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           lfuse          0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           hfuse          0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           lock           0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           calibration    0     0     0    0 no          4    0      0     0     0 0x00 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
avrdude: Send: A [41] . [80]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [02]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [81]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [01]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [82]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [12]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [98]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [10]
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
avrdude: Send: A [41] . [84]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [85]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [86]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [87]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [89]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [10]
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: Send: A [41] . [81]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [01]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [82]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [12]
avrdude: Recv: . [10]
avrdude: Send: B [42] p [70] . [00] . [00] . [01] . [01] . [01] . [01] . [02] . [ff] . [00] . [ff] . [ff] . [00] @ [40] . [02] . [00] . [00] . [00]   [20] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
avrdude: Send: E [45] . [05] . [04] . [d7] . [c2] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
avrdude: Send: P [50]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
avrdude: AVR device initialized and ready to accept instructions

Reading | avrdude: Send: V [56] 0 [30] . [00] . [00] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [1e]
avrdude: Recv: . [10]
avrdude: Send: V [56] 0 [30] . [00] . [01] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [93]
avrdude: Recv: . [10]
################avrdude: Send: V [56] 0 [30] . [00] . [02] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [07]
avrdude: Recv: . [10]
################################## | 100% 0.06s

avrdude: Device signature = 0x1e9307
avrdude: Send: V [56] . [a0] . [01] . [fc] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [ff]
avrdude: Recv: . [10]
avrdude: Send: V [56] . [a0] . [01] . [fd] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [ff]
avrdude: Recv: . [10]
avrdude: Send: V [56] . [a0] . [01] . [fe] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [ff]
avrdude: Recv: . [10]
avrdude: Send: V [56] . [a0] . [01] . [ff] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [ff]
avrdude: Recv: . [10]
avrdude: erasing chip
avrdude: Send: V [56] . [ac] . [80] . [00] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [81]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [01]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [82]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [12]
avrdude: Recv: . [10]
avrdude: Send: B [42] p [70] . [00] . [00] . [01] . [01] . [01] . [01] . [02] . [ff] . [00] . [ff] . [ff] . [00] @ [40] . [02] . [00] . [00] . [00]   [20] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
avrdude: Send: E [45] . [05] . [04] . [d7] . [c2] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
avrdude: Send: P [50]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
avrdude: reading input file "0x3f"
avrdude: writing lock (1 bytes):

Writing | avrdude: Send: V [56] X [58] . [00] . [00] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [ff]
avrdude: Recv: . [10]
################################################## | 100% 0.02s

avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x3f:
avrdude: load data lock data from input file 0x3f:
avrdude: input file 0x3f contains 1 bytes
avrdude: reading on-chip lock data:

Reading | avrdude: Send: V [56] X [58] . [00] . [00] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [ff]
avrdude: Recv: . [10]
################################################## | 100% 0.02s

avrdude: verifying ...
avrdude: 1 bytes of lock verified
avrdude: reading input file "0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}"
avrdude: invalid byte value (0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}) specified for immediate mode
avrdude: read from file '0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}' failed
avrdude: Send: Q [51]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]

avrdude done.  Thank you.

These are my fuse bits:
# General
8.name=ATmega8 (8MHz Internal Clock on breadboard)
8.upload.tool=avrdude
8.upload.maximum_data_size=1024
8.bootloader.tool=avrdude
8.bootloader.unlock_bits=0x3f
8.bootloader.lock_bits=0x0f
8.bootloader.low_fuses=0b{bootloader.bod_bits}{bootloader.sut_cksel_bits}
8.bootloader.high_fuses=0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}
8.build.core=MCUdude_corefiles
8.build.variant=standard
8.build.board=AVR_ATmega8
8.build.mcu=atmega8
8.build.bootloader_led=B5

# Upload port select
8.menu.bootloader.uart0=Yes (UART0)
8.menu.bootloader.uart0.upload.maximum_size=7680
8.menu.bootloader.uart0.upload.protocol=arduino
8.menu.bootloader.uart0.upload.port=UART0
8.menu.bootloader.uart0.build.export_merged_output=true
8.menu.bootloader.uart0.bootloader.bootrst_bit=0
8.menu.bootloader.uart0.bootloader.file=optiboot_flash/bootloaders/{build.mcu}/{build.f_cpu}/optiboot_flash_{build.mcu}_{upload.port}_{upload.speed}_{build.f_cpu}_{build.bootloader_led}.hex

8.menu.bootloader.no_bootloader=No bootloader
8.menu.bootloader.no_bootloader.upload.maximum_size=8192
8.menu.bootloader.no_bootloader.build.export_merged_output=false
8.menu.bootloader.no_bootloader.bootloader.bootrst_bit=1
8.menu.bootloader.no_bootloader.bootloader.file=empty/empty.hex

# EEPROM
8.menu.eeprom.keep=EEPROM retained
8.menu.eeprom.keep.bootloader.eesave_bit=0
8.menu.eeprom.erase=EEPROM not retained
8.menu.eeprom.erase.bootloader.eesave_bit=1

# Brown out detection - This is the first part of the low fuse bit concatenation
8.menu.BOD.2v7=BOD 2.7V
8.menu.BOD.2v7.bootloader.bod_bits=10
8.menu.BOD.4v0=BOD 4.0V
8.menu.BOD.4v0.bootloader.bod_bits=00
8.menu.BOD.disabled=BOD disabled
8.menu.BOD.disabled.bootloader.bod_bits=11

# Compiler link time optimization
8.menu.LTO.Os=LTO disabled
8.menu.LTO.Os.compiler.c.extra_flags=
8.menu.LTO.Os.compiler.c.elf.extra_flags=
8.menu.LTO.Os.compiler.cpp.extra_flags=
8.menu.LTO.Os.ltoarcmd=avr-ar

8.menu.LTO.Os_flto=LTO enabled
8.menu.LTO.Os_flto.compiler.c.extra_flags=-Wextra -flto -g
8.menu.LTO.Os_flto.compiler.c.elf.extra_flags=-w -flto -g
8.menu.LTO.Os_flto.compiler.cpp.extra_flags=-Wextra -flto -g
8.menu.LTO.Os_flto.ltoarcmd=avr-gcc-ar

8.menu.clock.8MHz_internal=8 MHz internal
8.menu.clock.8MHz_internal.upload.speed=38400
8.menu.clock.8MHz_internal.bootloader.sut_cksel_bits=100100
8.menu.clock.8MHz_internal.bootloader.ckopt_bit=1
8.menu.clock.8MHz_internal.build.f_cpu=8000000L

Should I try deleting unnescessary stuff from the fuse bits?
I tried checking the fuse bits, but they're pretty much alien to me. Any help is welcome.
Thanks in advance
Me
Edit: I am using Arduino IDE v1.0.5 and have selected "Arduino as ISP" in the programmer.

The existence of unreplaced placeholders (e.g. {bootloader.bod_bits}) is significant in the output. Include your IDE version number and the name and version number of the board package you're using for ATMega8A support, and what you have selected in the menus, etc.  Maybe someone can replicate the error even without an ATMega8 on hand.

Arduino 1.0.5, "Arduino as ISP" programmer, and custom boards.txt file

1.0.5 is from 2013 and a lot has changed in the IDE since then, particularly between the 1.0.x versions and the 1.5.x versions. Most people wind up with 1.0.5 because it's in the Ubuntu's (and other Linux distribution's) package repo(s).
Anyway, it's likely that this old version doesn't define some of the things your board definition is referencing. E.g. you're referring to names that exist in the 1.8.x platform.txt file that don't exist in the 1.0.5 IDE. When the IDE fails to replace a key placeholder, it leaves it like you're seeing in your avrdude commandline: -Uhfuse:w:0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}:m -Ulfuse:w:0b{bootloader.bod_bits}{bootloader.sut_cksel_bits}:m   You should not be seeing these {blah} references in your command-lines when compiling or uploading.
Actually, 1.0.5 predates the handling of .menu. style properties. E.g. They used to have entire separate boards.txt entries for the ATMega328P based nano and the ATMega168 based nano and these are now handled by a single board with a .menu.cpu. section for the selection of the MCU used. So under 1.0.5 none of your .menu. properties are failing to be replaced by the IDE.
So, I would start by getting rid of the old IDE and instead installing the latest from the official site and seeing if that improves things.
That said, if you want to use the ATMega8A with Arduino it would probably be better to use MCUdude MiniCore rather than modifying the regular boards.txt file. You'll need a new IDE in order to use that anyway.


text:
Stepper motor and blink LED
I connected a LED stick to a stepper motor. Is it possible to blink the LED without stopping the motor rotation?
I am using SparkFun RedBoard Plus, Qwiic LED Stick - APA102C, Adafruit Stepper motor - NEMA-17 size - 200 steps/rev and Adafruit Motor Shield V2
Thanks
Script:
#include <Adafruit_MotorShield.h>
#include <Wire.h>
#include "Qwiic_LED_Stick.h"

LED LEDStick;
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

void setup() {
  Wire.begin();
  Serial.begin(9600);
  while (!Serial);
  Serial.println("Stepper test!");

  if (!AFMS.begin()) {
    // if (!AFMS.begin(1000)) {
    Serial.println("Could not find Motor Shield. Check wiring.");
    while (1);
  }
  Serial.println("Motor Shield found.");
  myMotor->setSpeed(25);  // 25 rpm

  if (LEDStick.begin() == false) {
    Serial.println("Qwiic LED Stick failed to begin. Please check wiring and try again!");
    while (1);
  }
  Serial.println("Qwiic LED Stick ready!");
}

void loop() {
  Serial.println("Single coil steps");
  myMotor->step(200, FORWARD, SINGLE);

  LEDStick.setLEDColor(10, 10, 10);
  delay(1000);
  LEDStick.LEDOff();
  delay(1000);
}

Have you seen this tutorial? https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay

delay(1000); stops everything for one second

try using onestep instead of step

Often, the solution to most simultaneous software delay problems is a state machine. Generally, a state machine is an infinite loop with no or few delays.  The state machine's job is to keep track of all the possible state the software is to control.
In this case we might try to implement:

LED on & motor active.
LED off & motor active.
LED on & motor is not active.
LED off & motor is not active.

The library Adafruit_StepperMotor you have chosen might be blocking.  This text from the Arduino reference step library admits this similar function is blocking:

This function is blocking; that is, it will wait until the motor has finished moving to pass control to the next line in your sketch.

If so, and the call to step() blocks the LED action for longer then is tolerable, consider calling step() with fewer step such that the blocking delay is tolerable.  For example, 100 steps are desired, consider calling step 10 times only advancing the motor 10 steps each time.
Back to the state machine.  To keep track of the above 4 state you need 2 flags.  An LED flag and a Motor flag.  Control the LED flag using mills() not delay().
mills():

Returns the number of milliseconds passed since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 50 days.

Consider writing the state machine code to immediately turn the LED on and save the current value returned from mills().  Each subsequent time through the state machine check if mills() returns a value 1000 more than the value saved (do consider that mills() will eventually overflow and start over at zero).  When it does toggle the LED, save the new mills() returned value and start checking each subsequent time through the state machine.
As we are running the state machine over and over again as fast as the processor can manage, we can also test an externally set flag to run the motor.  We need to determine if the call to step() is blocking.  If it is we need to determine the maximum number of steps / delay tolerable by the LED feature.  If we discover this is, say, 10 step, we need to devise code to divide the desired number of steps into individual calls of 10 or less steps. If this approach is desired, control the state machine's motor flag by activating it when the number of steps is > 0.  Subtracting 10 from the number of steps every iteration through the state machine.  And setting the state machine's motor flag to deactivate when steps is = 0.


text:
Can an Arduino Uno be used to measure the frequency of a square wave of up to 600 kHz?
I am doing a project with a color sensor, where the output of the color sensor is a PWM square wave.
To measure its frequency using an Arduino Uno I am using the pulseIn() function, but I can't get the correct result.
Can an Arduino Uno measure a frequency of up to 600 kHz using the pulseIn() function?

I can't get the correct result ... what does that mean? ... what result do you get?

Do you want to measure the frequency or duty cycle?

The documentation for pulseIn states that it can be used for intervals of 10 microseconds to 3 minutes.
600 kHz frequency will have an interval of 1.6 microseconds and thus is not suitable for this application. (1 / 600000 = 0.000001666).
I have code on my web page about timers for a sketch that can measure up to 8 MHz with only 0.5% error.
This code is reproduced below:
// Timer and Counter example
// Author: Nick Gammon
// Date: 17th January 2012

// Input: Pin D5

// these are checked for in the main program
volatile unsigned long timerCounts;
volatile boolean counterReady;

// internal to counting routine
unsigned long overflowCount;
unsigned int timerTicks;
unsigned int timerPeriod;

void startCounting (unsigned int ms)
  {
  counterReady = false;         // time not up yet
  timerPeriod = ms;             // how many 1 ms counts to do
  timerTicks = 0;               // reset interrupt counter
  overflowCount = 0;            // no overflows yet

  // reset Timer 1 and Timer 2
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR2A = 0;
  TCCR2B = 0;

  // Timer 1 - counts events on pin D5
  TIMSK1 = bit (TOIE1);   // interrupt on Timer 1 overflow

  // Timer 2 - gives us our 1 ms counting interval
  // 16 MHz clock (62.5 ns per tick) - prescaled by 128
  //  counter increments every 8 µs.
  // So we count 125 of them, giving exactly 1000 µs (1 ms)
  TCCR2A = bit (WGM21) ;   // CTC mode
  OCR2A  = 124;            // count up to 125  (zero relative!!!!)

  // Timer 2 - interrupt on match (ie. every 1 ms)
  TIMSK2 = bit (OCIE2A);   // enable Timer2 Interrupt

  TCNT1 = 0;      // Both counters to zero
  TCNT2 = 0;

  // Reset prescalers
  GTCCR = bit (PSRASY);        // reset prescaler now
  // start Timer 2
  TCCR2B =  bit (CS20) | bit (CS22) ;  // prescaler of 128
  // start Timer 1
  // External clock source on T1 pin (D5). Clock on rising edge.
  TCCR1B =  bit (CS10) | bit (CS11) | bit (CS12);
  }  // end of startCounting

ISR (TIMER1_OVF_vect)
  {
  ++overflowCount;               // count number of Counter1 overflows
  }  // end of TIMER1_OVF_vect

//******************************************************************
//  Timer2 Interrupt Service is invoked by hardware Timer 2 every 1 ms = 1000 Hz
//  16Mhz / 128 / 125 = 1000 Hz

ISR (TIMER2_COMPA_vect)
  {
  // grab counter value before it changes any more
  unsigned int timer1CounterValue;
  timer1CounterValue = TCNT1;  // see datasheet, page 117 (accessing 16-bit registers)
  unsigned long overflowCopy = overflowCount;

  // see if we have reached timing period
  if (++timerTicks < timerPeriod)
    return;  // not yet

  // if just missed an overflow
  if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 256)
    overflowCopy++;

  // end of gate time, measurement ready

  TCCR1A = 0;    // stop timer 1
  TCCR1B = 0;

  TCCR2A = 0;    // stop timer 2
  TCCR2B = 0;

  TIMSK1 = 0;    // disable Timer1 Interrupt
  TIMSK2 = 0;    // disable Timer2 Interrupt

  // calculate total count
  timerCounts = (overflowCopy << 16) + timer1CounterValue;  // each overflow is 65536 more
  counterReady = true;              // set global flag for end count period
  }  // end of TIMER2_COMPA_vect

void setup ()
  {
  Serial.begin(115200);
  Serial.println("Frequency Counter");
  } // end of setup

void loop ()
  {
  // stop Timer 0 interrupts from throwing the count out
  byte oldTCCR0A = TCCR0A;
  byte oldTCCR0B = TCCR0B;
  TCCR0A = 0;    // stop timer 0
  TCCR0B = 0;

  startCounting (500);  // how many ms to count for

  while (!counterReady)
     { }  // loop until count over

  // adjust counts by counting interval to give frequency in Hz
  float frq = (timerCounts *  1000.0) / timerPeriod;

  Serial.print ("Frequency: ");
  Serial.print ((unsigned long) frq);
  Serial.println (" Hz.");

  // restart timer 0
  TCCR0A = oldTCCR0A;
  TCCR0B = oldTCCR0B;

  // let serial stuff finish
  delay(200);
  }   // end of loop

Whether Arduino UNO can measure the frequency upto 600 KHz if we use the pulseIn() function?

No. Not using pulseIn. However see the code above for a way of measuring such a frequency.


text:
Blink LED without delay with stepper motor
Based on a previous question I modified the script to use blink without delay.
Unfortunately, it does not work, any idea why?
I am using SparkFun RedBoard Plus, Qwiic LED Stick - APA102C, Adafruit Stepper motor - NEMA-17 size - 200 steps/rev and Adafruit Motor Shield V2.
Modified code (based on @Michel Keijzers, see below):
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "Qwiic_LED_Stick.h" // Click here to get the library: http://librarymanager/All#SparkFun_Qwiic_LED_Stick

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 500;           // interval at which to blink (milliseconds)

LED LEDStick; //Create an object of the LED class

Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

void setup() {
  Wire.begin();
  Serial.begin(115200);
  while (!Serial);
  Serial.println("Stepper test!");

  if (!AFMS.begin()) {
    // if (!AFMS.begin(1000)) {
    Serial.println("Could not find Motor Shield. Check wiring.");
    while (1);
  }
  Serial.println("Motor Shield found.");
  myMotor->setSpeed(50);  // 50 rpm

  //Start up communication with the LED Stick
  if (!LEDStick.begin())  {
    Serial.println("Qwiic LED Stick failed to begin. Please check wiring and try again!");
    while (1);
  }

  Serial.println("Qwiic LED Stick ready!");
//  LEDStick.setLEDColor(255, 0, 0);
  LEDStick.setLEDBrightness(1);
}

void loop() {
  unsigned long currentMillis = millis();

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

    ledState = !ledState;
    // set the LED with the ledState of the variable:
    uint8_t intensity = ledState == HIGH ? 255 : 0;
    LEDStick.setLEDColor(intensity, intensity, intensity);
  }

  Serial.println("Single coil steps");
  myMotor->step(200, FORWARD, SINGLE);
}

Code:
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "Qwiic_LED_Stick.h" // Click here to get the library: http://librarymanager/All#SparkFun_Qwiic_LED_Stick

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1000;           // interval at which to blink (milliseconds)

LED LEDStick; //Create an object of the LED class
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

void setup() {
  Wire.begin();
  Serial.begin(115200);
  while (!Serial);
  Serial.println("Stepper test!");

  if (!AFMS.begin()) {
    // if (!AFMS.begin(1000)) {
    Serial.println("Could not find Motor Shield. Check wiring.");
    while (1);
  }
  Serial.println("Motor Shield found.");
  myMotor->setSpeed(50);  // 50 rpm

  //Start up communication with the LED Stick
  if (LEDStick.begin() == false) {
    Serial.println("Qwiic LED Stick failed to begin. Please check wiring and try again!");
    while (1);
  }

  Serial.println("Qwiic LED Stick ready!");
}

void loop() {
  unsigned long currentMillis = millis();

  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) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    LEDStick.setLEDColor(50, 50, 50);
  }

  Serial.println("Single coil steps");
  myMotor->step(200, FORWARD, SINGLE);
}

it does not work is a useless description of a problem ... what actually happens?

It does not blink properly

that is just as cryptic ... what were you expecting to happen? ... what actually happened?

You only set (assign) ledState, but you never use it.
I think the following fragment
// set the LED with the ledState of the variable:
LEDStick.setLEDColor(50, 50, 50);

Should be something like:
// set the LED with the ledState of the variable:
uint8_t intensity = ledState == HIGH ? 255 : 0;
LEDStick.setLEDColor(intensity, intensity, intensity);

This 'converts' the ledState into white (RGB values 255) when HIGH or black/off (RGB values 0) when LOW.
Also you can change the line
if (LEDStick.begin() == false) {

into
if (!LEDStick.begin()) {

and change the lines
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
  ledState = HIGH;
} else {
  ledState = LOW;
}

into
// if the LED is off turn it on and vice-versa:
ledState = ledState == LOW ? HIGH : LOW;

or even
ledState = !ledState;

Thanks a lot. I did the modified code and updated it in the question, it seems to blink but longer than 1sec. Can it be related to the board frequency. How can I control different light colors based on this code: uint8_t intensity = ledState == HIGH ? 255 : 0;
LEDStick.setLEDColor(intensity, intensity, intensity);

Please upvote and accept the answer if it helped and is the solution for your problem.  I don't see directly why it blinks longer than 1 sec, you can print out variables to find out the exact times. About the colors, you can transform LOW/HIGH into any value between 0 and 255 for both red, green and blue, just play a bit with the arguments inside the LEDStick.setLEDColor statement.


text:
"previous declaration of 'HTTPMethod HTTP_HEAD'"
I'm getting the following error when I try to compile my code on my  LOLIN(WeMos) D1 R1:
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:19: error: 'HTTP_ANY' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                   ^~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:69:3: note: previous declaration 'WebRequestMethod HTTP_ANY'
   69 |   HTTP_ANY     = 0b01111111,
      |   ^~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:29: error: 'HTTP_GET' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                             ^~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:62:3: note: previous declaration 'WebRequestMethod HTTP_GET'
   62 |   HTTP_GET     = 0b00000001,
      |   ^~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:39: error: 'HTTP_HEAD' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                       ^~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:67:3: note: previous declaration 'WebRequestMethod HTTP_HEAD'
   67 |   HTTP_HEAD    = 0b00100000,
      |   ^~~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:50: error: 'HTTP_POST' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                  ^~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:63:3: note: previous declaration 'WebRequestMethod HTTP_POST'
   63 |   HTTP_POST    = 0b00000010,
      |   ^~~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:61: error: 'HTTP_PUT' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                             ^~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:65:3: note: previous declaration 'WebRequestMethod HTTP_PUT'
   65 |   HTTP_PUT     = 0b00001000,
      |   ^~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:71: error: 'HTTP_PATCH' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                                       ^~~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:66:3: note: previous declaration 'WebRequestMethod HTTP_PATCH'
   66 |   HTTP_PATCH   = 0b00010000,
      |   ^~~~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:83: error: 'HTTP_DELETE' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                                                ^~~~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:64:3: note: previous declaration 'WebRequestMethod HTTP_DELETE'
   64 |   HTTP_DELETE  = 0b00000100,
      |   ^~~~~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:96: error: 'HTTP_OPTIONS' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                                                ^~~~~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:68:3: note: previous declaration 'WebRequestMethod HTTP_OPTIONS'
   68 |   HTTP_OPTIONS = 0b01000000,
      |   ^~~~~~~~~~~~
exit status 1
Error compiling for board LOLIN(WeMos) D1 R1.

Here is my code:
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <WiFiManager.h>

AsyncWebServer server(80);

const char* PARAM_INPUT_1 = "input1";
const char* PARAM_INPUT_2 = "input2";
const char* PARAM_INPUT_3 = "input3";

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
  <title>ESP Input Form</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <form action="/get">
    input1: <input type="text" name="input1" style="background-color: #195B6A; border: none; color: white; padding: 16px 40px;
    text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;">
    <input type="submit" value="Submit">
  </form>

  <form action="/get">
    input2: <input type="text" name="input2">
    <input type="submit" value="Submit">
  </form>

  <form action="/get">
    input3: <input type="text" name="input3">
    <input type="submit" value="Submit">
  </form>

SmartHomeHarris-CoLTD

GPIO 1 - State off

<button class="button">ON</button>

GPIO 2 - State off

<button class="button">ON</button>

GPIO 3 - State off

<button class="button">ON</button>

GPIO 4 - State off

<button class="button">ON</button>

  )rawliteral";

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFiManager wm;
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("WiFi Failed!");
    return;
  }
  bool res;
  // res = wm.autoConnect(); // auto generated AP name from chipid
  // res = wm.autoConnect("AutoConnectAP"); // anonymous ap
  res = wm.autoConnect("AutoConnectAP","password"); // password protected ap

  if (!res) {
        Serial.println("Failed to connect");
        // ESP.restart();
  }
  else {
        // if you get here you have connected to the WiFi
        Serial.println("connected...yeey :)");
  }
  Serial.println();
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  // Send web page with input fields to client
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });

  // Send a GET request to <ESP_IP>/get?input1=<inputMessage>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    String inputParam;
    // GET input1 value on <ESP_IP>/get?input1=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1)) {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      inputParam = PARAM_INPUT_1;
    }
    // GET input2 value on <ESP_IP>/get?input2=<inputMessage>
    else if (request->hasParam(PARAM_INPUT_2)) {
      inputMessage = request->getParam(PARAM_INPUT_2)->value();
      inputParam = PARAM_INPUT_2;
    }
    // GET input3 value on <ESP_IP>/get?input3=<inputMessage>
    else if (request->hasParam(PARAM_INPUT_3)) {
      inputMessage = request->getParam(PARAM_INPUT_3)->value();
      inputParam = PARAM_INPUT_3;
    }
    else {
      inputMessage = "No message sent";
      inputParam = "none";
    }
    Serial.println(inputMessage);
    request->send(200, "text/html", "HTTP GET request sent to your ESP on input field ("
                                     + inputParam + ") with value: " + inputMessage +
                                     "
Return to Home Page");
  });
  server.onNotFound(notFound);
  server.begin();
}

void loop() {

}

I tried different version of WiFiManager but still it doesn't work.

WiFiManager uses the ESP8266WebServer library and you want to use the async version of it. The conflict is between very similar source codes of the two web server libraries. here is an async version of WiFiManager https://github.com/khoih-prog/ESPAsync_WiFiManager . I don't know if it is good

As the error messages tell you, there are two declarations of HTTP_OPTIONS via two includes. Apparently you cannot use these at the same time.
"WiFiManager.h" has the enum HTTPMethod that has these constants.
And "ESPAsyncWebServer.h" has another declaration of the same constants.
You might need to read their documentation to learn whether work-arounds are possible.


text:
Arduino Nano: HUGE voltage drop on VIN
I am building a small automated indoor greenhouse. I want to use an Arduino Nano to control some LEDs und a fan (both through relays) and a water Grove Water Atomization module. Everything works fine, as long as I power the LEDs and the fan with a 12v supply (3 watts) and the Nano through USB. But I want to power the Nano through the 12v supply, too.
So I built a voltage divider that delivers 7.25v. I measured it with a multimeter. But when I connect it to the VIN of the Nano, the voltage drops to 1.16v. Wich – of course – means that the Nano doesn't start. When I tried it, only the Nano and the relays were connected to the 12v power supply. The relays through voltage divider delivering 5v.
I tried it with an original Arduino and a chinese compatible and got the exact same result both times.
Does anyone have an idea, what I am missing?

Schematic? Voltage dividers are not really regulated power supplies. In fact, not at all.

https://majenko.co.uk/blog/our-blog-1/why-you-can-t-use-resistors-as-a-voltage-regulator-15

You just can't use a couple of resistors to deliver a reliable voltage source like that. The voltage divider effectively works as advertised with zero current. Your Nano will take more than zero current. See here for one discussion.

Ah, okay. So I really missed an important detail. Thanks a lot. I just tried a step-down converter and it works like charm.

If you do not place more than a few mA load on the Nano 5V pin you can wire 'Vin' directly to 12V. Your resistor idea sounds great however when you add the fluctuating current requirement you cannot get a stable output it will change with the load. Note the divider circuit resistance has to be very low in value to stay close making it not practical.

Yes, I know. I tried that first. But the voltage regulator of the Nano got quite hot, I guess the water atomization module draws too much current.

Try it without the atomizator. I have a feeling it will stay much cooler.

The heat wasn't the only problem with the atomizer. Whenever it was attached to the Nano, the Nano froze after some minutes. I added the step-down converter to supply 7 volts to VIN, which helped with the heat, but the Nano still froze. So I added a voltage regulator, to bring the 7 volts to 5 volts for the atomizer. Now everything works fine. And no element gets hotter then 34°C.


text:
Why does Arduino Nano 33 IoT always choose the weakest WiFi BSSID?
I have an Arduino Nano 33 IoT configured to connect to my WiFi network with a pretty straightforward code:
#include <WiFiNINA.h>

int status = WL_IDLE_STATUS;
status = WiFi.status();
while (status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
    if (status == WL_CONNECTED) break;
    delay(5000);
}

My problem is that in an environment with multiple access points sharing the same SSID (roaming environment) my Arduino is constantly connecting to the weakest one of the access points.
I verified with WiFi Explorer on my laptop that multiple access points are in reach at the same location where the Arduino is placed and for some reason my Arduino decides to connect to the base station with BSSD ending :CA:81, which is paradoxly the weakest one:

Is there a way to address this issue?

From you're list you'd only get the choice of the first two as the NINA is a b/g/n only module I think. But not sure why it's not connecting to :58:E2 if it has the same SSID.

What happens when you set the second accesspoint in the list to channel 11?

@ocrdu Unfortunately changing channel to 11 and resetting the Arduino did not help :(

@DanSheppard Yes, exactly.

On Nano 33 IoT the WiFi network adapter is NINA esp32 module with Arduino's nina-fw. nina-fw is written with the use of ESP-IDF framework by the esp32 manufacturer Espressif.
To connect to an AP the ESP-IDF has a configuration function, which takes a structure with settings. One of the settings is wifi_scan_method and nina-fw uses WIFI_FAST_SCAN. The alternative is WIFI_ALL_CHANNEL_SCAN.

WIFI_FAST_SCAN Do fast scan, scan will end after find SSID match AP

There is no simple solution for this. I don't know why they changed the setting. If it should be configurable then the firmware and the WiFiNINA library have to change to support it.
Or you can get the sources of the firmware, change the setting, build the firmware (it is not trivial) and flash it to NINA on your Nano.

This is a VERY good clue, but I think we should complete this answer with a working code. According to the changelog (https://github.com/arduino/nina-fw/blob/master/CHANGELOG), the WiFiNINA library has changed the default behaviour from WIFI_ALL_CHANNEL_SCAN to WIFI_FAST_SCAN between versions v1.2.1 and v1.2.2 in 2018. They also added a setScanMethod in v2.0.0 (in 2021), sadly, this version is not yet available in the Arduino package manager. I can't really find an Arduino specific documentation for calling esp_wifi_set_config based on your answer. I guess I can downgrade to 1.2.0...

@adamsfamily, setScanMethod was added in esp32 Arduino WiFi library which has nothing do do with Nano 33 IoT

All right but how to configure WIFI_ALL_CHANNEL_SCAN with the Arduino library? I'm not able to call the esp_wifi_set_config as the Arduino IDE complains that the function does not exist :( Should I fork the Arduino WiFiNINA library and hardcode complete scan? I am very surprised that this is the default behaviour because connecting to the strongest base stations is key in a WiFi environments, especially in IoT. I'm surprised that no one else has the same problem?

@adamsfamily the esp_wifi_set_config  is used in firmware running in the NINA module, not in the WiFiNINA library which is used in the main SAMD MCU

Ok, let me restate my question :-) Do you see any possible solution for the Arduino Nano 33 IoT?

@adamsfamily, no simple solution. I don't know why the changed the setting. if it should be configurable then the firmware and the WiFiNINA library have to change to support it. Or you can get the sources of the firmware, change the setting, build the firmware (not easy) and flash it to NINA on your Nano (easy)

Got it. In that case your answer should be the accepted answer. May I suggest editing it so that it says: "Reason:   Solution: No easy solution, because "? I think this will help others. BTW I'm very-very surprised that nobody complained about it, selecting the strongest AP critical in a multi-AP environment where they share the same SSID...

@yes, I added that to the answer.  I did build modified versions of the nina-fw. It is simpler on Linux.

Thanks, I accepted the answer. I'll try to report this towards the Arduino development team because I think this is really essential.


text:
Is it possible to connect 2 PLC which have Ethernet interfaces using Ethernet shield, arduino Nano and SX1278?
I need to connect 2 PLC which have Ethernet interfaces over 1 km and i was thinking of connecting via SPI an ethernet shield and an SX1278 module to a arduino nano (UNO) board.
Do i need logical converter between Nano and SX ? (I saw a lot of videos showing people doing it without the logical converter)
Is it Nano capable of handling the information passing from Ethernet to SX ?
If possible,  where can i find an example of such setup ?

The simple fact you are asking this question means you don't have the skills or knowledge to comprehend what it is you are asking (I don't mean this in a nasty way, just that in having to ask it shows you lack some of the basic knowledge you will first need to accomplish the task).
Firstly you need to understand what Ethernet is.  The cable itself is just one layer (the "Physical" or lowest layer) of the 7-layer OSI model.
On top of that are 6 more layers at increasing levels of abstratcion.
You will need to understand what is being communicated between the two PLCs and at what layer of the OSI model it makes the most sense to create your bridge.
Do you do it at the application level, where you receive the data that is sent by a PLC and interpret it, then send that interpretation over the bridge to be reconstructed at the other and? Or do you do it at the socket layer where you capture the raw information and send that, or at the transport layer where you take the network data and forward that, or at the data layer where you take the ethernet electrical signals and pass that logical data to the other end to be replicated?
But then of course there is the other question: Is it actually Ethernet? Or is it some other protocol that just happens to use CAT5 (or similar) cables to transfer the data? If that is the case you first need to what that protocol is before you can even consider connecting anything to the wire.
Only once you have answered those questions can you go on to ask more about implementing your setup.  Things like:

What hardware do I need to connect to the PLC
What protocol do I need to implement
What high level facilities would the Arduino need to provide for the connection to function

Etc. Lots of questions.
So:

Is it actually Ethernet or some other protocol carried by CAT5 cables, such as RS-485 / RS-422
Given the actual protocol, what interface do you need to get?
If it is Ethernet, does it use IP or something else (IPX?)
If it is IP does it use TCP or UDP for communication? Or both?
If it is IP what controls the IP addresses? Will you need to implement a DHCP server, or hijack the IP address of the "remote" end of the bridge?
Once you understand the protocols, is timing critical in your system? Does PLC A expect a response from PLC B within a finite defined time frame?
Given how unreliable a wireless connection is, how will you handle dropped or corrupted packets?
Does your chosen connection technology have enough bandwidth to transmit the data fast enough to prevent a backlog of data and lost information?

As you can see there is a huge amount of things to consider when designing this kind of thing.
If you have a list of 20 steps to go through to implement this, you are trying to start at maybe step 15 or 16. You need to rewind right back to step 1 and look at the absolute basics of what it is you are trying to do and what it is you are trying to do it to.

Thank you for your quick answer, the purpose of this system is acting as a relay, because these PLC's are in fact SENECA Z-GPRS3 GSM Loggers, but one of them is placed in an very bad GSM signal area, so the normal GSM operation is out of the question. The PLC have Ethernet RJ45 interface, protocol is TCP - application level - Web server on port 80 and IP's are fixed like 192.168.1.100 for PLC -A and 192.168.1.101 for PLC -B. Timing is not critical, given the fact that their modems are 2G-GPRS transmission speed cannot exceed 20-50kbps, and regarding the packets ... loss-retransmit.

In that case, your best bet is to have one Arduino pretend to be the remote PLC at each end of the link and capture raw bytes from whatever TCP socket the local PLC is sending to.


text:
Using prototype PCBs as Arduino shield
Is is possible to use prototype PCBs (PCB with grid of unconnected holes with copper around them, usually with pitch 2.54 mm) as Arduino shield, when they are fitted with appropriate pin headers?
I am asking this question because I am not sure whether the Arduino UNO pin headers (which are split) will fit to the headers on the prototype PCB where I will “leave out” one pin on the header.
(Yes, I ho not have a Arduino board to try it out now.)

For the UNO style boards, no it's not possible. The digital headers have a 0.16 inch gap between them which offsets one set of headers 0.06" from the holes in the shield.
For this reason you can buy specific Arduino prototyping shields that have the headers in the right locations.

are you saying that the header pins are 0.16 inch apart?

@jsotola the entire header for pins 0-7 is not on the same 0.1 inch grid that the other three female headers collectively share together. Really, it's the distance between the center of digital pin 7 and center digital pin 8 being referred to. So without splitting hairs on about the distances between plastic housings and nearest distances and all that, it's the distance (by some definition) between two entire headers. That is, it's not referring to header's pin "pitch".

Yep, I thought that. Thank you.


text:
Char array filling with blanks
When I run this code, my pin and pinCheck arrays are not being filled with the results of keypad.getKey(). If I print the value at each index, the result is blank. As far as I can tell, I am either not writing a char to the array, I am misreading the array when it comes time to print to the serial monitor, or .getKey() only works in the main or loop functions.
#include <Key.h>
#include <Keypad.h>

void armDisarm(void);
boolean array_cmp(char, char, int, int);

bool isArmed = 0;
char pin[3];
char pinCheck[3];
const byte ROWS = 4; // number of rows
const byte COLS = 4; // number of columns
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'#','0','*','D'}
};

byte rowPins[ROWS] = {9, 8, 7, 6}; // row pinouts of the keypad R1 = D8, R2 = D7, R3 = D6, R4 = D5
byte colPins[COLS] = {5, 4, 3, 2};    // column pinouts of the keypad C1 = D4, C2 = D3, C3 = D2
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

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

void loop()
{
  if (isArmed == 1)
  {
    Serial.println("SYSTEM ARMED! ENTER PIN TO DISARM!");
  }
  else
  {
    Serial.println("SYSTEM DISARMED! ENTER PIN TO ARM!");
  }
  armDisarm();
}

void armDisarm(void)
{
  while(true)
 {
    if (isArmed == 0)
    {
      for (int i = 0; i < 4;)
      {
        if (keypad.getKey() == NO_KEY)
        {
          continue;
        }
        pin[i] = keypad.getKey();
        Serial.println(pin[i]);
        i++;
      }
      isArmed = 1;
      return;
    }
    else if (isArmed == 1)
    {
      for (int j = 0; j < 4;)
      {
        if (keypad.getKey() == NO_KEY)
        {
          continue;
        }
        pinCheck[j] = keypad.getKey();
        Serial.println(pin[j]);
        j++;
      }
      for (int k = 0; k < 4; k++)
      {
        if(pinCheck[k] != pin[k])
        {
          isSame = 0;
          break;
        }
        else
        {
          isSame = 1;
        }
      }

      if (array_cmp(pin, pinCheck, sizeof(pin), sizeof(pinCheck)) == 1)
      {
        Serial.println("same pin"); //used for bebugging
        isArmed = 0;
        return;
      }
      else
      {
        Serial.println("INCORRECT PIN! CLAYMORE ROOMBA DEPLOYED!");
      }
    }
  }
}

boolean array_cmp(char a[sizeof(pin)], char b[sizeof(pinCheck)], int len_a, int len_b)
{
  int n;

  // if their lengths are different, return false
  if (len_a != len_b)
  {
    return false;
  }

  // test each element to be the same. if not, return false
  for (n = 0 ;n < len_a; n++)
  {
    if (a[n]!= b[n])
    {
      return false;
    }
  }

  //ok, if we have not returned yet, they are equal :)
  return true;
}

First of all, there is one essential feature of the Keypad library you
have to understand: it is non-blocking. When you call keypad.getKey(),
it returns immediately, and almost always returns NO_KEY to signal
that no key was pressed since the last time you checked. If a key was
pressed, keypad.getKey() returns that key and then, on the next
call, it again returns NO_KEY because no key was pressed since the
last time you checked.
It is important to realize that, whenever a key is pressed, that key is
returned only once by keypad.getKey(). You should manage to not miss
it!
Now consider this loop:
for (int i = 0; i < 4;)
{
    if (keypad.getKey() == NO_KEY)
    {
        continue;
    }
    pin[i] = keypad.getKey();
    Serial.println(pin[i]);
    i++;
}

This will run very fast, and almost always looping through the
continue statement. When a key is pressed, keypad.getKey() returns a
value different from NO_KEY (and this value is lost), the test
within the if is false, and the statement that follows gets executed,
namely:
    pin[i] = keypad.getKey();

But this is another call to keypad.getKey(), which returns NO_KEY,
so this is what gets saved in the array.
This is how I would write that loop:
for (int i = 0; i < 3; i++)
{
    char key = NO_KEY;
    while (key == NO_KEY)
    {
        key = keypad.getKey();
    }
    pin[i] = key;
    Serial.println(pin[i]);
}

Please note that:

The value returned by keypad.getKey() is always saved into a
variable, you do not want to loose it! When we get something other
than NO_KEY, the value previously saved into the variable is stored
in the array.

I moved the i++ where it belongs, in order to avoid that very
confusing way of controlling the loop.

The if has become a while, because we do not want to move to the
next iteration until we have actually read a valid key.

The loop does only three iterations, because this is the length of the
array pin, which we would otherwise overflow.

As an addition ToEdgar Bonets answer. I should warn you that your code keeps adding position in as each time you check array you are increasing the value of i. As a result you are filling arrays with NO_KEY.
Also having have build a security alarm on arduino before (Or shouldnt we know thats what you are doing?) I should warn you that waiting for Keyboard inputs mean that you are not checking tamper or alarm even when its armed because you are stucked inside nonloop function waiting for imput.
I have personally made input a global struct
struct foo{
   char digits[4];
   byte digit=0;
} pinCode;

You can either take instance of the struct as a parameter to your function or because its global use it internaly.
bool addDigit(char button){
  /*here deal with many potential inputs*/

you can then inside your function assign the button pressed as
pinCode.digits[pinCode.digit]=button;
pinCode.digit++;

if you are passing the instance of the struct as a pointer then it will change to
pinCode->digits[pinCode->digit]=button;
pinCode->digit++;

you can then inside this funtion test if password is confirmed (OK is pressed) and return true.
While the end of the password isn't reached, just return false.
SO within the loop you would have something like:
key = keypad.getKey();
if(key!=NO_KEY){
   if(addDigit(key)) //Here take an action based on inputs
}
// Do all the other stuff alarm has to do