text:
Compiler error: final link failed: bad value collect2.exe
I work With VS Code v:1.59.1.
With extension vscode-arduino v:0.4.4
befor update of vscode. in version 1.58. all was ok. I can build and upload code for all mucrocontrollers.
but after the update, I can build code for arduino uno.
but when i build the code for esp32, i get this error:
[Starting] Analyzing sketch 'emptyProjct.ino'
[Warning] Output path is not specified. Unable to reuse previously compiled files. Build will be slower. See README.
Cargando configuración...
Inicializando paquetes...
Preparando tarjetas...
Verficando...
c:/users/hassan daoud/documents/arduino/hardware/espressif/esp32/tools/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: final link failed: bad value
collect2.exe: error: ld returned 1 exit status
exit status 1
IntelliSense configuration already up to date. To manually rebuild your IntelliSense configuration run "Ctrl+Alt+I"
[Error] Analyzing sketch 'emptyProjct.ino': Exit with code=1

other thing. in the right of status bar. in [Select Programmer], I can't show any programmer for ESP32, but when i change board to arduino uno, i can select from a lot of choises.
this screenshot is for adruino uno.

and this is for esp32 wroom

after the update of vscode I try to download another extension like [Espressif IDF]. because [vscode-arduino] dont fix the error of serial port.
I contact with [Espressif IDF] for an error in instalation and him tel me to download the sdk in a path with out spasing. and then its work. but the old library I download from Arduino IDE for ESP32 its work in the prev. ver.
with space in the path.
so I dont know if the problem is from the new library or what happen. but I cant build code for ESP32.
please help me
thank you a lot to all.

I deeply suspect this is a duplicate of something.  But, you have a space in your user account name that appears to be messing with the build process.  See c:/users/hassan daoud and Usado: C:\Users\Hassan.

@timemage. yes but before last update to v1.59. its work properly.

It might be a regression worth to be submitted to some bug tracker.

OK, I fix the error.
I remove all library for esp32 in my computer
c:/users/hassan daoud/documents/arduino/hardware/
c:/users/hassan daoud/appdata/local/arduino15/packages/

and install again from board manager.
all work ok


text:
Bi-directional UART communication on single data wire, possible?
The nano is inside of the house, and the pro mini is outside of the house. I want to send/receive text between them. The communication will be always nano sending text to mini, and then mini sending text to pro in response. There will be no case where mini sends text on its own first.
The line has three wires, but since I have to power the mini with that line, one is used for VCC and another is used for ground, leaving only one wire free. It this case, can I do UART communication between the two? If so, how should I connect the wire to them (including the ground)? And on the software side, how should I handle the communication? Could you give a simple code example in which nano sends "Hello" to pro mini, and then pro mini, after receiving "hello", sends "World" to nano?

The main question is the distance and the desired connection speed. You can use, for example, even two-core cable for power and some HF-modulation magic for data.
Or, you can use wires only for power and use some radio (i.e., WiFi) for data.
The radio solution is more simple and cost-effective, because it is pretty common.

https://www.pjon.org/SoftwareBitBang.php

What you want is called half-duplex. A search turned up a bunch of good articles:  https://forum.arduino.cc/t/software-serial-with-half-duplex-for-a-shared-serial-bus/112131  and http://nerdralph.blogspot.com/2014/01/avr-half-duplex-software-uart.html  You'll have to devise some handshaking so each side knows when the other is done transmitting. Have fun!

You can use that kind of "Ethernet protocol" that was used on coaxial cable ? Or used with " high frequency modem" ? Or more simple, a "circuit coupler" as in old "line telephony" ?

You can have bidirectional communication over a single wire by using
open-collector outputs. For this, you could add a circuit like this
on each side of the link:

simulate this circuit – Schematic created using CircuitLab
Here, TX is the transmit pin of the Arduino, and DATA is the data wire.
The RX pin is connected directly to the data wire and, while writing
your sketches, you should account for the fact that anything you send
will be received back by the sender as an “echo”.
This scheme will slow down your signal transitions, limiting the maximum
achievable baud rate. Start with something conservative, like
9600 bps, and lower further if it doesn't work reliably.

The "TX pin on Arduino" means the "TX1 - UART -Out" of Nano and the "RX pin" means the "RX --- 0" of Pro Mini, on the diagram above? Or is it ignoring the UART feature of Arduino completely, and use a reuglar digital output pin instead?

@DamnVegetables: This assumes you are using the hardware UART, and thus the corresponding pins. On the Nano, those pins are labeled TX1 and RX0. On the Pro Mini, they are labeled TXO and RXI.

This question likely suffers from the X Y problem.  Where the question (about software) and possible answer (centered on hardware) do not approach the solution using the same methods.
The question is essentially asking how to design a 1-wire interface over longer than normal distances. There are 1-wire Arduino libraries and 1-wire Arduino tutorials. But it is likely you will run into problems if your cable is very long.
Guessing at the distance you want to run your 3 wires (power, ground and data), this may be more an electrical engineering than a software problem.
Power:
All wires have resistance.  Using a voltage drop calculator from here we can calculate, assuming we are trying to send 5V over an 18 AWG copper wire 100 meters long to a 250mA load, an expected voltage drop of slightly over a volt.  That may cause unexpected results.

If this might be an issue, consider an alternate power source such as batteries, solar power or a second mains power adapter for the far Arduino.  It may even be considered to over drive the power lines several volts and regulate the voltage at the far end Arduino.
Data:
Reference to ground type data transmission is more susceptible to error the longer the cable run.  Several options to mitigating unexpected behavior can be made.  However switching over to a balanced pair is usually the best option.
Options:
If you are willing to power the far Arduino independently or add 1 additional data wire (either of these options will make available 2 wires for data) we can run the data portion of the cable for a good distance while mitigating noise problems associated with long communication cable runs.
Try RS485:
Consider using an RS485 hardware interface at the near and far Arduino.  RS485 interfaces can be source easily for Arduino projects (here and here are two examples) and there are Arduino RS485 software libraries which handle the communications.
The intent of the project was not disclosed in the question.  However here is an example RS485 project where connected Arduinos communicate the position of a potentiometer such that the RS485 connected Arduino at the far end can mimic the potentiometer's movements on a motor driven servo.
The keen eye may note that the above project only uses 2 wires between the two Arduinos.  This is possible because in the above project the two Arduinos are independently powered (this is not seen in the diagram on the linked to web page).  Additionally, RS485 uses a balanced pair of signals (the 2 wires) and does not need to run an additional ground between the two Arduinos as a reference to detect the difference between 1s and 0s.

This might be an XY problem and there might be a hardware solution, but if the question is "how can I make this work with 3 wires" the answer "just use 4 wires" is not helpful. Most likely the cable is already there. If punching through walls to hook up an Arduino would be acceptable OP wouldn't ask the question.

@AndreKR Yeah, the cable has already been installed (I did), and at that time, I thought I would not need bi-directional communication and 3-core cable was cheaper than 4-core cable, so I chose the former. Now, after using the system, I realised that I need a way to get the status of the remote device. I could remove the old one and install a new cable (not impossible), but it will be such a hassle, so I was looking for a way to do it with the existing wire.

Thanks. Replacing the existing 3-core cable with a 4-core cable is not impossible, but I thought if I had two free wires available for data, I could just connect two Arduino's directly using the TX/RX pins already there. You mean that using RS485 needs two free wires (other than the two for powering the remote Arduino), right? The distance is about 30 metres (=100 feet), and I do not need fast communication (even 100 bps is more than enough). The module called "TTL to RS485" seem cheap. Do you think it is better than direct connection even in my case?

@AndreKR, at the end of my answer was a 2 wire solution.  It will only work if the remote was powered by some other meas then by cable.  And RS485 will almost always out preform a return to ground reference signal.  Time and time again people who do not know that try to extend I2C and SPI only to find they can not live w/the noise.  I'll amend my answer and explain this more clearly.

@DamnVegetables, FYI, you are essentially asking how to design a 1-wire interface over longer than normal distances.  I could have just said that in my answer and point you to Arduino tutorials and libraires.  But it is likely you will run into problems if your cable is too long.  Actually, I think I'm going to put the above in my answer.  But, just to help us create a better answer ... just how long is your cable?

@DamnVegetables RS485 needs 2 wires because it is not Data/Ground, rather it is +Data/-Data kind of like USB. Also note that RS485 works best if the two data wires are twisted pair

Yes, that is correct.  And it (USB 2.0) can obtain some rather impressive speeds over a good amount of cable run.  I think USB 3 use multiple balanced pairs in a full duplex mode to obtain even higher speeds.

An example of protocol using a single wire (besides ground, so a total of 2) for both bi-directional communication AND power: Dallas 1-wire
There are few other similar standard protocols and you are free to think about your own as long as you are willing to implement all the internals instead of using a well-written and widely used library.

While this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.

will it work on 30 meters long cable?

You could do it by using one wire for ground, one wire for nano->mini, and one wire for mini->nano.  The nano->mini wire carries both power and data.  You can keep it at some voltage above ground to provide the power and superimpose a data signal that is AC coupled off at the mini end.  Alternately, you can rectify the data to provide power if you make sure to send 01010101 whenever you don't have something else to say.

Note that an UART idles high.

source: Stack Exchange

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

sort: votes


text:
nRF24L01 continuously reading closed pipe
I am testing communication between two nRF24L01 modules. The receiver is getting the transmitted message but is also continuously reading (null) data from a closed pipe? I am using the RF24 by TMRh20 version 1.3.12 library on an Arduino Pro Mini with some modified example code. Has anyone else experienced this phenomenon or have any fix for the issue?
Transmitter:
/*
* Arduino Wireless Communication Tutorial
*     Example 1 - Transmitter Code
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>
RF24 radio(9, 10); // CE, CSN
const byte address[6] = "00001";
void setup() {
  Serial.begin(9600);
  printf_begin();
  while (!Serial);
  Serial.println("[radioSend]");
  if (radio.begin()) {
    Serial.println("Radio Receiver starting");
  } else {
    Serial.println("Radio Receiver start failed");
    while (1);
  }
  radio.setChannel(120);
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
  radio.printPrettyDetails();
}
void loop() {
  const char text[] = "Hello World";
  radio.write(&text, sizeof(text));
  delay(10000);
}

Receiver:
/*
* Arduino Wireless Communication Tutorial
*       Example 1 - Receiver Code
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>
RF24 radio(9, 10); // CE, CSN
const byte address[6] = "00001";
long counter = 0;
void setup() {
  Serial.begin(9600);
  printf_begin();
  while (!Serial);
  Serial.println("[radioReceive]");
  if (radio.begin()) {
    Serial.println("Radio Receiver starting");
  } else {
    Serial.println("Radio Receiver start failed");
    while (1);
  }
  radio.setChannel(120);
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
  radio.printPrettyDetails();
}
int dpls3;
char text3[32] = "";
void loop() {
  uint8_t pipeNum;
  if (radio.available(&pipeNum)) {
    int dpls = radio.getDynamicPayloadSize();
    char text[32] = "";
    radio.read(&text, sizeof(text));
    if (pipeNum != 3) {
      Serial.print("[Pipe=");
      Serial.print(pipeNum);
      Serial.print("|Size=");
      Serial.print(dpls);
      Serial.print("|");
      Serial.print(text);
      Serial.print("] [Pipe=3|Size=");
      Serial.print(dpls3);
      Serial.print("|");
      Serial.print(text3);
      Serial.print("|Count=");
      Serial.print(counter);
      Serial.println("]");
    } else {
      memcpy(&text3, &text, 32);
      counter += 1;
      dpls3 = dpls;
    }
  }
}

Transmitter output:
[radioSend]
Radio Receiver starting
SPI Frequency       = 10 Mhz
Channel         = 120 (~ 2520 MHz)
RF Data Rate        = 1 MBPS
RF Power Amplifier  = PA_MIN
RF Low Noise Amplifier  = Enabled
CRC Length      = 16 bits
Address Length      = 5 bytes
Static Payload Length   = 32 bytes
Auto Retry Delay    = 1500 microseconds
Auto Retry Attempts = 15 maximum
Packets lost on
    current channel = 0
Retry attempts made for
    last transmission   = 0
Multicast       = Disabled
Custom ACK Payload  = Disabled
Dynamic Payloads    = Disabled
Auto Acknowledgment = Enabled
Primary Mode        = TX
TX address      = 0x3130303030
pipe 0 ( open ) bound   = 0x3130303030
pipe 1 ( open ) bound   = 0xc2c2c2c2c2
pipe 2 (closed) bound   = 0xc3
pipe 3 (closed) bound   = 0xc4
pipe 4 (closed) bound   = 0xc5
pipe 5 (closed) bound   = 0xc6

Receiver output:
[radioReceive]
Radio Receiver starting
SPI Frequency       = 10 Mhz
Channel         = 120 (~ 2520 MHz)
RF Data Rate        = 1 MBPS
RF Power Amplifier  = PA_MIN
RF Low Noise Amplifier  = Disabled
CRC Length      = 16 bits
Address Length      = 3 bytes
Static Payload Length   = 32 bytes
Auto Retry Delay    = 250 microseconds
Auto Retry Attempts = 15 maximum
Packets lost on
    current channel = 0
Retry attempts made for
    last transmission   = 0
Multicast       = Disabled
Custom ACK Payload  = Disabled
Dynamic Payloads    = Disabled
Auto Acknowledgment = 0b011111
Primary Mode        = RX
TX address      = 0x1010101010
pipe 0 ( open ) bound   = 0x1010101010
pipe 1 (closed) bound   = 0x2020270610
pipe 2 (closed) bound   = 0xc1
pipe 3 (closed) bound   = 0xc0
pipe 4 (closed) bound   = 0xc0
pipe 5 (closed) bound   = 0xc2
[Pipe=0|Size=32|Hello World] [Pipe=3|Size=0||Count=195500]
[Pipe=0|Size=32|Hello World] [Pipe=3|Size=0||Count=216665]
[Pipe=0|Size=32|Hello World] [Pipe=3|Size=0||Count=835055]
[Pipe=0|Size=32|Hello World] [Pipe=3|Size=0||Count=882618]
[Pipe=0|Size=32|Hello World] [Pipe=3|Size=0||Count=1168025]
[Pipe=0|Size=32|Hello World] [Pipe=3|Size=0||Count=1310725]
[Pipe=0|Size=32|Hello World] [Pipe=3|Size=0||Count=1405856]
[Pipe=0|Size=32|Hello World] [Pipe=3|Size=0||Count=1500987]

what is the issue specifically?

did you write the code?

@jsotola Did you actually read the title?  The program is doing what it is supposed to do, sure but the nRF24L01 is not.  If you look at the last few lines of the receiver output you will see that there is an extremely high number of null messages on pipe 3 being read on a closed pipe but not cleared.  I modified the original code to show the problem. If I had just printed what was read then there would have been thousands of blank lines interspersed with the occasional "Hello World". I do not want my code to waste time handling this "hardware" issue.

I think someone else is having the same issue here as I was able to find a fix by ignoring any data available on pipes above 1. https://arduino.stackexchange.com/questions/51741/trouble-with-nrf24l01/85881#85881

Another example where I tested and demonstrate a fix for this issue: https://arduino.stackexchange.com/questions/65249/nrf24l01-tmrh20-library-receiver-gets-blank-data

See also:  https://forum.arduino.cc/t/nrf24l01-clone-tester/902367  to quickly test a single unit.

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


text:
Infrared Reciver doesn't work properly after the first signal
i'm trying to play a passive buzzer with an IR reciver
My Code

#include <IRremote.h>
IRrecv irrecv(10);
decode_results results;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(11, OUTPUT);//buzzer
  irrecv.enableIRIn();//Ir reciver at pin 10
}

int cmdex = 0;

void loop() {
  // put your main code here, to run repeatedly:

  if(irrecv.decode(&results)){
    cmdex = 1;
    Serial.println(results.value);
    unsigned long data = results.value;
    switch(data){
      case 0xFF30CF:
        noTone(11);
        tone(11, 1056);
        break;
      case 0xFF18E7:
        noTone(11);
        tone(11, 571);
        break;
      case 0xFF6897:
        noTone(11);
        break;
    }
    irrecv.resume();
  }
}

Issue
My problem is that if i use any button instead of 1 (FF30CF) 0 (FF6897) or 2 (FF18E7) the serilal port give me the right data, then when i pusch 1 the buzzer starts to play but when i push another button, the data keep changing at every push.
Serial Output
FF10EF (here I push 4)
FF38C7 (here I push 5)
FF5AA5 (here I push 6)
FF30CF (here I finally push 1 and the buzzer starts to play)
(then I push 3 times 0, but the output is different from the expected FF6897 and the buzzer doesn't stop)
D965AA42
EB670632
AB03A967
Note

I'm using the IRremote.h library

does IRremote use Timer2 used by tone()?

as per @Juraj comment ... please refer to https://stackoverflow.com/questions/62832918/function-tone-and-irremote

Ok thanks, how ca I solve the timer issue?


text:
I want to turn on RGB led gradually
Why I can't use "timeA = delay" to make the lights turn on gradually.
The problem is that the delay don´t work, and the led light goes directly to the last color. What I need to do in my code to fix this?
Here is my code ↓
// C++ code
//

void setup()
{
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
}

void loop(){

  static unsigned long timeA = 10;
  const long interval = 10;

  static unsigned long timeB = 10;
  const long interval2 = 10;

  static unsigned long timeC = 10;
  const long interval3 = 10;

  unsigned long delay = millis();
  static unsigned long state = 0;
  int i = 0;

  if(delay - timeA >= interval && state == 0){
    state += 1;
    for(i=0;i<=255;i++){
        analogWrite(3, i);
        analogWrite(5, 0);
        analogWrite(6, 0);
        timeA = delay;
    }
  }
   if(delay - timeB >= interval2 && state == 1){
    state += 1;
    for(i=0;i<=255;i++){
        analogWrite(3, 0);
        analogWrite(5, i);
        analogWrite(6, 0);
        timeB = delay;
    }
  }
  if(delay - timeC >= interval3 && state == 2){
   state += 1;
   for(i=0;i<=255;i++){
        analogWrite(3, 0);
        analogWrite(5, 0);
        analogWrite(6, i);
        timeC = delay;
    }
  }

}

You millis() code is not structured correctly. Lets look at what happens:
timeA and co are all initiated with the value 10. So as soon as the program has run 10ms, the first if statement (the one for state 0) will execute. First you increment state, so that the next state can be reached. Then you have a for loop without any timed code. It will execute very very fast, without giving the PWM hardware any chance to actually output the analogWrite() values. Then you update timeA (which normally wouldn't go into the for loop). We leave the if statement and reach the next one. Nearly no time has passed, since we entered the first if statement. And now we are executing the next if statement, since state is now 1 and the program had run for more than 10ms. Here it is the same as above.
So the program is rushing through the analogWrite() calls ending in the last one, since state is never reset, giving the last analogWrite() value the change to be output on the pin.
The whole structure of the code does not really make sense. I guess you wanted to do this non-blocking, thus using millis(). For loops are not really fitting to this and the millis() value has to be compared to the right values to get the order right.
What to do now: With the state variable you nearly have something that is called Finite State Machine (FSM). It is a powerful programming concept. Basically the state of the program decides, what block of code should be executed on each loop() iteration. This is best done via a switch statement. Then in each case we are using an if statement using the millis() value to decide, if it is time to execute the new analogWrite():
void setup()
{
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
}

void loop(){

  static unsigned long timeA = 10;
  const long interval = 10;

  static unsigned long timeB = 10;
  const long interval2 = 10;

  static unsigned long timeC = 10;
  const long interval3 = 10;

  unsigned long delay = millis();
  static unsigned long state = 0;
  static int i = 0;

  switch(state){
    case 0:
      if(delay - timeA >= interval){
        analogWrite(3, i);
        analogWrite(5, 0);
        analogWrite(6, 0);
        i++;
        timeA = delay;
      }
      if(i > 255){
        state = 1;
        i = 0;
      }
      break;
    case 1:
      if(delay - timeB >= interval2){
        analogWrite(3, 0);
        analogWrite(5, i);
        analogWrite(6, 0);
        i++;
        timeB = delay;
      }
      if(i > 255){
        state = 2;
        i = 0;
      }
      break;
    case 2:
      if(delay - timeC >= interval3){
        analogWrite(3, 0);
        analogWrite(5, 0);
        analogWrite(6, i);
        i++;
        timeC = delay;
      }
      if(i > 255){
        state = 0;
        i = 0;
      }
      break;
  }
}

By setting the variable state we can choose, what should be executed next. The variable i is handling the fading of each LED, while the interval variables set how fast the fading occurs. This coding principle can be used in many different situations, so learning it is really worth it.
Note:

I have not tested the above code.
The code can still be optimized/generalized.

Thank you bro! But one more doubt, Can´t I use "for" in that case? 'Cause are a college work that I need to use it.

If you use a for loop, you will also need to use delay() to create the correct timing of the fading. I assumed, that you didn't want to use delay() (which is a good thing for adding more features in the future). for loops are just one way to create loops. There are others and the above code principle should also work. It is up to you, if you want to use for (and thus delay(), creating a blocking code) or the above code structure (and thus a non-blocking code)

I think below is what you were going for. I removed the for-loop and used a static i variable to have each state take 256 intervals. Note that you don't need to have separate timeA/B/C variables. Using a single one would also make sure that the first "delay" actually occurs. It's not that critical for fading an led, but in other cases it might.
void setup()
{
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
}

void loop(){

  static unsigned long timeA = 10;
  const long interval = 10;

  static unsigned long timeB = 10;
  const long interval2 = 10;

  static unsigned long timeC = 10;
  const long interval3 = 10;

  static unsigned long state = 0;
  static int i = 0;

  unsigned long delay = millis();

  if(delay - timeA >= interval && state == 0){
    analogWrite(3, i);
    analogWrite(5, 0);
    analogWrite(6, 0);
    timeA = delay;

    i++;
    if( i==256 )
    {
      i=0;
      state++;
    }
  }
   if(delay - timeB >= interval2 && state == 1){
    analogWrite(3, 0);
    analogWrite(5, i);
    analogWrite(6, 0);
    timeB = delay;

    i++;
    if( i==256 )
    {
      i=0;
      state++;
    }
  }
  if(delay - timeC >= interval3 && state == 2){
    analogWrite(3, 0);
    analogWrite(5, 0);
    analogWrite(6, i);
    timeC = delay;

    i++;
    if( i==256 )
    {
      i=0;
      state++; // you probably want to use `state=0;`, so it starts over again
    }
  }

}```

Thankss! But I still have a doubt if can I use "for", 'Cause is a college work and I need to use it.


text:
MPU6050 Arduino Jeff Rowberg library interrupt Issue
I was trying to get the data from MPU6050 using the Arduino library mentioned here.
The following code is an edited version of the sample code given in the library folder which seems to be working fine.
#define printfloatx(Name,Variable,Spaces,Precision,EndTxt) { Serial.print(F(Name)); {char S[(Spaces + Precision + 3)];Serial.print(F(" ")); Serial.print(dtostrf((float)Variable,Spaces,Precision ,S));}Serial.print(F(EndTxt)); }//Name,Variable,Spaces,Precision,EndTxt

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps_V6_12.h"

#include "Wire.h"

MPU6050 accelgyro;
MPU6050 mpu;

I2Cdev a;

/*
    IMU Zero variables
*/

int16_t data_acc[3];
int16_t data_Gyro[3];

/*
   IMU initialization variables
*/
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
bool dmpReady = false;  // set true if DMP init was successful
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)

/*
   IMU angle finding variables
*/
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

Quaternion q;           // [w, x, y, z]         quaternion container
VectorFloat gravity;    // [x, y, z]            gravity vector
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

void Initialize()
{
  // initialize device
  Serial.println("Initializing I2C devices...");
  accelgyro.initialize();

  // verify connection
  Serial.println("Testing device connections...");
  Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  Serial.println("tuning Each Dot = 100 readings");
  accelgyro.CalibrateAccel(10);
  accelgyro.CalibrateGyro(10);

  a.readWords(0x68, 0x06, 3, (uint16_t *)data_acc);
  a.readWords(0x68, 0x13, 3, (uint16_t *)data_Gyro);
} // Initialize

void setup() {
  Wire.begin();
  Serial.begin(115200);
  Initialize();
  Wire.setClock(400000);
  while (!Serial);
  Serial.println(F("Initializing I2C devices..."));
  mpu.initialize();
  Serial.println(F("Testing device connections..."));
  Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

  Serial.println(F("\nSend any character to begin DMP programming and demo: "));
  while (Serial.available() && Serial.read()); // empty buffer
  while (!Serial.available());                 // wait for data
  while (Serial.available() && Serial.read()); // empty buffer again

  // load and configure the DMP
  Serial.println(F("Initializing DMP..."));
  devStatus = mpu.dmpInitialize();

  // supply your own gyro offsets here, scaled for min sensitivity
  mpu.setXGyroOffset(data_Gyro[0]);
  mpu.setYGyroOffset(data_Gyro[1]);
  mpu.setZGyroOffset(data_Gyro[2]);
  mpu.setXAccelOffset(data_acc[0]);
  mpu.setYAccelOffset(data_acc[1]);
  mpu.setZAccelOffset(data_acc[2]);

  if (devStatus == 0) {
    // Calibration Time: generate offsets and calibrate our MPU6050
    mpu.CalibrateAccel(6);
    mpu.CalibrateGyro(6);
    Serial.println();
    mpu.PrintActiveOffsets();
    // turn on the DMP, now that it's ready
    Serial.println(F("Enabling DMP..."));
    mpu.setDMPEnabled(true);

    // enable Arduino interrupt detection
    Serial.print(F("Enabling interrupt detection (Arduino external interrupt "));
    mpuIntStatus = mpu.getIntStatus();
    Serial.println(F("DMP ready! Waiting for first interrupt..."));
    dmpReady = true;
    packetSize = mpu.dmpGetFIFOPacketSize();
  } else {
    Serial.print(F("DMP Initialization failed (code "));
    Serial.print(devStatus);
    Serial.println(F(")"));
  }

  Serial.println("-------------- done --------------");
} // setup

void loop()
{
  if (!dmpReady) return;
  if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) {
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetGravity(&gravity, &q);
    mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
    Serial.print("ypr\t");
    Serial.print(ypr[0] * 180 / M_PI);
    Serial.print("\t");
    Serial.print(ypr[1] * 180 / M_PI);
    Serial.print("\t");
    Serial.print(ypr[2] * 180 / M_PI);
    Serial.println();
  }

}

Then I have activated the input capture pin to use with the interrupt and the code is as follows
#define printfloatx(Name,Variable,Spaces,Precision,EndTxt) { Serial.print(F(Name)); {char S[(Spaces + Precision + 3)];Serial.print(F(" ")); Serial.print(dtostrf((float)Variable,Spaces,Precision ,S));}Serial.print(F(EndTxt)); }//Name,Variable,Spaces,Precision,EndTxt

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps_V6_12.h"

#include "Wire.h"

MPU6050 accelgyro;
volatile MPU6050 mpu;

I2Cdev a;

/*
    IMU Zero variables
*/

int16_t data_acc[3];
int16_t data_Gyro[3];

/*
   IMU initialization variables
*/
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
bool dmpReady = false;  // set true if DMP init was successful
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)

/*
   IMU angle finding variables
*/
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

Quaternion q;           // [w, x, y, z]         quaternion container
VectorFloat gravity;    // [x, y, z]            gravity vector
volatile float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

void Initialize()
{
  // initialize device
  Serial.println("Initializing I2C devices...");
  accelgyro.initialize();

  // verify connection
  Serial.println("Testing device connections...");
  Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  Serial.println("tuning Each Dot = 100 readings");
  accelgyro.CalibrateAccel(10);
  accelgyro.CalibrateGyro(10);

  a.readWords(0x68, 0x06, 3, (uint16_t *)data_acc);
  a.readWords(0x68, 0x13, 3, (uint16_t *)data_Gyro);
} // Initialize

void timer4_initialization() {
  pinMode(49, INPUT);
  TCCR4A = 0; TCCR4B = 0; TCCR4C = 0;
  TCCR4B = B11000000;
  TIFR4 = _BV(ICF4);
  TIMSK4 = B00100000;
}

ISR(TIMER4_CAPT_vect) {
  if (!dmpReady) return;
  if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) {
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetGravity(&gravity, &q);
    mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
  }
}

void setup() {
  Wire.begin();
  Serial.begin(115200);
  Initialize();
  Wire.setClock(400000);
  while (!Serial);
  Serial.println(F("Initializing I2C devices..."));
  mpu.initialize();
  Serial.println(F("Testing device connections..."));
  Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

  Serial.println(F("\nSend any character to begin DMP programming and demo: "));
  while (Serial.available() && Serial.read()); // empty buffer
  while (!Serial.available());                 // wait for data
  while (Serial.available() && Serial.read()); // empty buffer again

  // load and configure the DMP
  Serial.println(F("Initializing DMP..."));
  devStatus = mpu.dmpInitialize();

  // supply your own gyro offsets here, scaled for min sensitivity
  mpu.setXGyroOffset(data_Gyro[0]);
  mpu.setYGyroOffset(data_Gyro[1]);
  mpu.setZGyroOffset(data_Gyro[2]);
  mpu.setXAccelOffset(data_acc[0]);
  mpu.setYAccelOffset(data_acc[1]);
  mpu.setZAccelOffset(data_acc[2]);

  if (devStatus == 0) {
    // Calibration Time: generate offsets and calibrate our MPU6050
    mpu.CalibrateAccel(6);
    mpu.CalibrateGyro(6);
    Serial.println();
    mpu.PrintActiveOffsets();
    // turn on the DMP, now that it's ready
    Serial.println(F("Enabling DMP..."));
    mpu.setDMPEnabled(true);

    // enable Arduino interrupt detection
    Serial.print(F("Enabling interrupt detection (Arduino external interrupt "));
    mpuIntStatus = mpu.getIntStatus();
    Serial.println(F("DMP ready! Waiting for first interrupt..."));
    dmpReady = true;
    packetSize = mpu.dmpGetFIFOPacketSize();
  } else {
    Serial.print(F("DMP Initialization failed (code "));
    Serial.print(devStatus);
    Serial.println(F(")"));
  }

  Serial.println("-------------- done --------------");

  delay(2000);

  timer4_initialization();

} // setup

void loop()
{
  Serial.print("ypr\t");
  Serial.print(ypr[0] * 180 / M_PI);
  Serial.print("\t");
  Serial.print(ypr[1] * 180 / M_PI);
  Serial.print("\t");
  Serial.print(ypr[2] * 180 / M_PI);
  Serial.println();
}

Here when I am using with the interrupt I am not getting anything printed, seems like the program is frozen somewhere in the interrupt -> function call.
What is the mistake I am making here.
How to take the measurement from MPU6050 using ISR routines.

are you saying that it does not even print Initializing I2C devices...?

The functions mpu.dmpGetCurrentFIFOPacket(fifoBuffer), etc, are using I2C for getting the data. The I2C interface on the Uno and Mega (which you tagged your question with) is implemented in hardware and needs interrupts for handling the data bytes (taking the received byte out of the register or writing data to the register for sending).
By default interrupts are disabled inside of an ISR. Thus the mentioned functions cannot execute correctly. They are waiting for an interrupt, which is never going to happen, since the functions are executed while interrupts are disabled.
It is possible to reactivate interrupts in an ISR, but that is something, that you should only do in a few situations and only, when you know exactly, what you are doing.
Instead you should just set a volatile flag variable inside the ISR. In the main code (in loop()) you can then check for that flag, execute the I2C code when it is set and reset the flag afterwards. And you can then also just print, when there is new data instead of every loop iteration. So somewhat like this:
volatile byte timer_flag = 0;

ISR(TIMER4_CAPT_vect) {
  timer_flag = 1;
}

void loop(){
    if(timer_flag){
        if (!dmpReady) return;
        if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) {
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
            // then print the values here, since we got new data from the MPU
        }
        timer_flag = 0; // Resetting the flag for the next timer interrupt
    }
}

I've tweaked chrisl's answer to show how to copy the ISR data and reset the ISR flag  in an atomic manner.
volatile bool isr_timer_flag = false;
volatile uint32_t isr_counter = 0;  // Added to demonstrate how to copy a multibyte data type atomically.

ISR(TIMER4_CAPT_vect)
{
    isr_timer_flag = true;
    isr_counter++;
}

void loop()
{
    //
    // Get a copy of the data and reset the flag atomically by temporarily disabling interrupts.
    //

    // Disable interrupts by clearing the global interrupt flag.
    cli();

    // Copy the data.
    bool timer_flag = isr_timer_flag;
    uint32_t counter = isr_counter;

    // Reset the ISR flag for the next timer interrupt.
    // Resetting it here avoids clearing any re-flag during the following if statements.
    isr_timer_flag = false;

    // Enable interrupts by setting the global interrupt flag.
    sei();

    // Now use the local copy of the ISR flag.
    // The ISR flag could be re-flagged at any time during the remainder of the loop,
    // but a fresh copy will be obtained on the next iteration of the loop.

    if (timer_flag)
    {
        if (!dmpReady) return;
        if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer))
        {
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
            // then print the values here, since we got new data from the MPU
        }
    }
}


text:
So many missed bytes with serial comm
I have a setup with serial comm from Raspberry Pi to Arduino. It's communicating at baud 9600 on both devices, and from Raspberry Pi 3b+ GPIO-14,UART0,TX0 to Arduino Nano RX0. There's a level shifter in between setup as recommended by AdaFruit tutorials. I'm sending data from Raspberry Pi as such:
#loop here
m = []
m.append(255)
m.append(i) // index value between 0-150
m.append(p[0][i]) // value between 0-254
m.append(p[1][i]) // value between 0-254
m.append(p[2][i]) // value between 0-254
#print statement here
'''
Data: [255, 94, 0, 0, 0, 255, 95, 254, 0, 0, 255, 96, 0, 254, 0]
...
'''

And receiving data on Arduino as such:
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    byte inChar = (byte)Serial.read();
    sprintf(printString, "Received: %d", inChar);
    Serial.println(printString);
  }
}
/*
Received: 255
Received: 94
Received: 0
Received: 255
Received: 95
Received: 254
Received: 0
Received: 255
Received: 96
Received: 0
Received: 254
Received: 255
Received: 94
Received: 0
Received: 0
Received: 0
Received: 255
Received: 254
Received: 255
...
*/

Any idea why there are so many missed bytes and how to fix this?
EDIT: @juraj There is a ground between both. I've measured with a portable oscilloscope. I can post the picture of the setup tomorrow.
@Edgar Bonet The loop function is empty, and looks as follows:
void loop() {
}

I also don't have any data being sent back to the Raspberry Pi. I have the Serial TX wire out from Arduino completely disconnected

It does not matter if you wire TX or not. Serial.println() takes the same time in any case. Did you try to shorten the string, like just the hex representation of the received bytes?

Re: “I have the Serial TX wire out from Arduino completely disconnected”: this is irrelevant. The Arduino doesn't care, and doesn't even know the wire is disconnected. It is still sending the data out. This takes time: about 14 times the time it took to receive the data.

@EdgarBonet Could you please clarify why it is sending out the data? Is it because of the serial print statement?

Yes, Serial.println(...) means “please, send out this data”.

Without the full codes, we can only guess. My guess would be the serial
receive buffer on the Arduino is overflowing.
One reason this could happen is if serialEvent() is not called
frequently enough. This function is called by the Arduino core on every
loop iteration, just after loop() returns. If your loop() takes too
long (e.g. you are using delay() or blocking waits), the receive
buffer can overflow before serialEvent() has a chance to empty it.
Another reason is if the Raspberry Pi is sending too much data, too
fast. For every byte the Arduino receives, it must send back
between 13 and 15 bytes. If too much data comes too fast, the transmit
buffer will eventually get full, and then Serial.println() becomes
really slow, because it has to wait for the bytes to actually get out
on the wire. This in turn slows down serialEvent() to the point where
it can make the receive buffer overflow.
Edit: If this (the Raspberry sending data too fast) is the cause of
the problem, the obvious solution is to have it send data more slowly,
as:
repeat:
    send a message
    delay for some suitable time

I totally agree with Edgar Bonet. You are sending 13 to 15 bytes per input byte. This takes time in the hardware, regardless of whether you have anything connected to it or not. So you expect it to misread data after 1/15 of the size of the output buffer, which I think is 64 bytes by default.

@NickGammon Thanks, that sounds reasonable to me. Do either of you have a suggestion for receiving data and debugging correctly? Should I have both TX and RX hooked up and do some sort of acknowledgment?

I have a post here about debugging using SPI (and also I2C) if you have those pins free. That is much faster than using serial comms.

@errolflynn Also reduce the length of your debugging messages, that will help. For example, instead of "Received:" send "R".


text:
Arduino Sleep to conserve battery - How to intergrade it to existing sketch - HELP pls
My sketch below is simply using a touch sensor to activate a servo motor to go from from initial position 0 to 180 then back to 0. then I want the Adruino NANO to go to sleep to conserve some battery life.
Being a novice to programing and after many attempts to use his code and intergrade it with mine. Was unsuccessful.
so if anyone can help intergrade the gammon's sketch below into mine it would be greatly appreciated. As I'm out of ideas.
HERE IS MY SKETCH
#include <Servo.h>

// constants won't change
const int SENSOR = 2; // Arduino pin connected to motion sensor's pin 7
const int SERVO = 9; // Arduino pin connected to servo motor's pin 9

Servo servo; // create servo object to control a servo

int pos = 0; // variable to store the servo position

// variables will change:
int lastMotionState; // the previous state of motion sensor
int currentMotionState; // the current state of motion sensor

void setup() {

Serial.begin(9600); // initialize serial
pinMode(SENSOR, INPUT); // set arduino pin 9 to input mode
servo.attach(SERVO); // attaches the servo on pin 12 to the servo object

servo.write(0);
currentMotionState = digitalRead(SENSOR);
}

void loop() {
lastMotionState = currentMotionState; // save the last state
currentMotionState = digitalRead(SENSOR); // read new state

if (currentMotionState == LOW && lastMotionState == HIGH) { // pin state change: LOW -> HIGH
Serial.println("OFF");
servo.write(0);
delay(100); // waits (X)ms for the servo to reach the position
}
else
if (currentMotionState == HIGH && lastMotionState == LOW) { // pin state change: HIGH -> LOW
Serial.println("ACTIVE");
servo.write(180);
delay(2000); // waits (x)ms for the servo to reach the position
}
delay(10); // repeats program - larger delay - trigger is
}

______________________________________
Author:Ab Kurk  SLEEP SKETCH
This sketch is part of the beginners guide to putting your Arduino to sleep
tutorial. It is to demonstrate how to put your arduino into deep sleep and
how to wake it up.
*/
#include <avr/sleep.h>//this AVR library contains the methods that controls the sleep modes
#define interruptPin 2 //Pin we are going to use to wake up the Arduino

void setup() {
Serial.begin(115200);//Start Serial Comunication
pinMode(LED_BUILTIN,OUTPUT);//We use the led on pin 13 to indecate when Arduino is A sleep
pinMode(interruptPin,INPUT_PULLUP);//Set pin d2 to input using the buildin pullup resistor
digitalWrite(LED_BUILTIN,HIGH);//turning LED on
}

void loop() {
delay(5000);//wait 5 seconds before going to sleep
Going_To_Sleep();
}

void Going_To_Sleep(){
sleep_enable();//Enabling sleep mode
attachInterrupt(0, wakeUp, LOW);//attaching a interrupt to pin d2
set_sleep_mode(SLEEP_MODE_PWR_DOWN);//Setting the sleep mode, in our case full sleep
digitalWrite(LED_BUILTIN,LOW);//turning LED off
delay(1000); //wait a second to allow the led to be turned off before going to sleep
sleep_cpu();//activating sleep mode
Serial.println("just woke up!");//next line of code executed after the interrupt
digitalWrite(LED_BUILTIN,HIGH);//turning LED on
}

void wakeUp(){
Serial.println("Interrrupt Fired");//Print message to serial monitor
sleep_disable();//Disable sleep mode

detachInterrupt(0); //Removes the interrupt from pin 2;

}

please ask a question ... this is a Q&A site

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer.

Question was how to incorporate my my sketch with an Kirk’s.

I'm going to guess that you are doing something like a door or safe lock, which may occasionally be used to activate a motor to unlock something but 99.99% of the time is sitting there doing nothing, and you want to save power in that time.
You need to rework somewhat.

An interrupt to detect a switch press. Then the processor can sleep, using very little power.

The interrupt, when it happens, wakes the processor

You activate the motor to unlock the door or whatever-it-is.

You put the processor into low power mode, and go back to sleep

Since my name was mentioned in the question, tips for doing low-power stuff are at this link. And here for stuff about interrupts.
Plus a slightly abridged version (due to space limitations) here on this site.
(You aren't supposed to make answers where the answer is totally in the link, but in this case the link is just supplementary material)

"You aren't supposed to make answers where the answer is totally in the link...".  I totally understand Nick.  Power management is complex, really depends on the HW (i.e. processor & circuit you are using) and should not be "added" to a project.  Rather the project (including the HW) should be built around power management.

Your right about my project.
Thank you for the info will go though it this weekend and attempt to get this thing to work


text:
Keypad pin as an interrupt (Wiring or programming)
I have this project of a "phone". It consists of:

Arduino DUE,
4x4 Keypad,
SD Data shield,
a phone receiver detect (on/off)
an Amp and a Speaker.

In the beginning, after the phone receiver is being picked, I am playing a .wav file of an intro on how to choose a language.
And this .wav should be interrupted when the user presses the 4th row of a keypad (Buttons A/B/C/D).
I only need one pin as far as I know, in this setup - pin 38 (Column 4 pin). As I understand, there is no proper way to declare a keypad input pin as an interrupt on DUE. Or is it?
So my question - how to wire a keypad input pin as an interrupt?
I have read about wiring with a diode. But most of the threads lack any specifics.
Can someone push me in the right direction?
Cheers!
Code:
#include <DAC.h>
#include <SD.h>
#include <SPI.h>
#include <Audio.h>
#include <Key.h>
#include <Keypad.h>

const byte ROW_NUM = 4;
const byte COLUMN_NUM = 4;

int code1 = 12345;  //The code I used, you can change it
int code2 = 45678;  //The code I used, you can change it
int code3 = 78900;  //The code I used, you can change it

int tot, i1, i2, i3, i4, i5;
char c1, c2, c3, c4;

char hexaKeys[ROW_NUM][COLUMN_NUM] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte hookPinA = 23;  // your interrupt pin
byte interruptPin = 22;  // your interrupt pin

byte pin_rows[ROW_NUM] = {52, 50, 48, 46}; //connect to the row pinouts of the keypad
byte pin_column[COLUMN_NUM] = {44, 42, 40, 38}; //connect to the column pinouts of the keypad

int keyCounter = 0;

Keypad myKeypad = Keypad(makeKeymap(hexaKeys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);

char keypresses[5];
char language;
char key;

int goIntoKeys = 0;

volatile uint8_t interruptState = 0;
volatile byte hookOffState = 0;

void setup() {
  // debug output at 9600 baud
  Serial.begin(9600);
  SD.begin(10);
  analogWriteResolution(12);

//for( int i=0; i< ROW_NUM; ++i) pinMode(pin_rows[i], INPUT_PULLUP);
//for( int i=0; i< COLUMN_NUM; ++i) pinMode(pin_column[i], INPUT_PULLUP);

 pinMode(hookPinA, INPUT_PULLUP);

 attachInterrupt(digitalPinToInterrupt(hookPinA), hookOffToggle, CHANGE);

// EIFR |= bit(INTF0); // clear INT0 interrupt flag

 attachInterrupt(digitalPinToInterrupt(interruptPin), interruptToggle, RISING); //test interrupt with a regular button

 pinMode(38, INPUT_PULLUP);
 attachInterrupt(digitalPinToInterrupt(38), interruptToggle, RISING);

  DACC->DACC_CHDR = DACC_CHDR_CH1; //disable DAC1

}

int state = 0;
const int STATE_OFF = 0;
const int STATE_IDLE = 1;
const int STATE_LISTEN_KEY = 2;
const int STATE_PLAYER = 3;

bool isLanguageKey(char customKey) {
  return ('A' == customKey || 'B' == customKey || 'C' == customKey || 'D' == customKey);
}

void loop() {
  switch (state) {
    case STATE_OFF:
    //listen for a telephone receiver to be removed
      if (hookOffState == 1) {
      Serial.print("HOOK OFF ");
      Serial.println(hookOffState);
        interruptState = 0;
        state = STATE_IDLE;
               }
               else if (hookOffState == 0) {
      Serial.print("HOOK ON ");
      Serial.println(hookOffState);
               }
        break;
    case STATE_IDLE:
    //listen for a language key. Cannot dial a number before
      Serial.print("interrupt IDLE ");
      Serial.println(interruptState);
               if (interruptState == 1) {
         buttonBeep();
        processLanguage();
        state = STATE_LISTEN_KEY;
               }
               else if (hookOffState == 0){
                state = STATE_OFF;
               }
               else {
      playSound("intro.wav");
        }
      break;
    case STATE_LISTEN_KEY:
    //listen for any key
      Serial.print("interrupt LISTEN KEY ");
      Serial.println(interruptState);
      if (isKeyPressed()) {
        interruptState = 0;
        if (isLanguageKey(key)) {
          buttonBeep();
          processLanguage();
        }
        else {
      Serial.print("interruptStateF ");
      Serial.println(interruptState);
               buttonBeep();
          keypresses[keyCounter] = key;
          keyDial();
          keyCounter++;
          if (keyCounter > 4) {
            state = STATE_PLAYER;
            //when 5 numbers are pressed - try to open the .wav file
          }
        }
      }
               else if (hookOffState == 0){
                state = STATE_OFF;
               }
      break;
    case STATE_PLAYER:
        //Play the audio and go back to state LISTEN
      calculateAndPlay();
      keyCounter = 0;
      interruptState = 0;
      state = STATE_LISTEN_KEY;
      break;
    default:
      break;
  }
}

void hookOffToggle(){
 if (digitalRead(hookPinA) == 1) {
  hookOffState = 1;
 }
  else  {
      hookOffState = 0;
  }
}

void interruptToggle() {
    interruptState = 1;
}

void kalba() {
  Serial.println("Kalba? Language? Valoda? Yazik?");
}

bool isKeyPressed() {
  key = myKeypad.getKey();
  return key != NO_KEY;
}

bool langKeyPressed() {
  key = myKeypad.getKey();
  return key != NO_KEY && isLanguageKey(key);
}

void processLanguage() { //press A/B/C/D keys - select 1 out of 4 languages
  //goIntoKeys = 1;
  keyCounter = 0;
  if (key == 'A') {
    Serial.println("   LT    ");
  }
  if (key == 'B') {
    Serial.println("   EN    ");
  }
  if (key == 'C') {
    Serial.println("   LV    ");
  }
  if (key == 'D') {
    Serial.println("   RU    ");
  }
  language = key;
}

void keyDial() {    // LCD displays the number dialed in 3 slots.
  keypresses[keyCounter] = 0x00;//null-byte
  keypresses[keyCounter] = key;

  if (key != NO_KEY)   {
    Serial.println(keypresses[keyCounter]);
  }
}

void buttonBeep(){
      for (int j = 0; j < 200; j++) {
        for (int i = 0; i < 200; i++)
          analogWrite(DAC0, i);
        for (int i = 200; i >= 0; i--)
          analogWrite(DAC0, i);
      }
}

void backgroundHumm() {
      for (int j = 0; j < 256; j++) {
        for (int i = 0; i < 256; i++)
          analogWrite(DAC0, j);
          for (int j = 256; j >= 0; j--) {
            for (int i = 256; i >= 0; i--)
          analogWrite(DAC0, j);
      }
  }
}

void calculateAndPlay() {
  //if we have 4+1 numbers - proceed
  //the keys pressed are stored into chars I convert them to int then i did some multiplication to get the code as an int of xxxx
  i1 = (keypresses[0] - 48) * 10000;
  i2 = (keypresses[1] - 48) * 1000;
  i3 = (keypresses[2] - 48) * 100;
  i4 = (keypresses[3] - 48) * 10;
  i5 = (keypresses[4] - 48) * 1;

  tot = i1 + i2 + i3 + i4 + i5;
  if (language == 'A') {
    if (tot == code1) //if the code is correct you trigger to play .wav
    {
      playSound("ledaiLT.wav");
    }
    else if (tot == code2)
    {
      playSound("zuvisLT.wav");
    }
    else if (tot == code3)
    {
      playSound("draugLT.wav");
    }
    else //if the code is wrong you get a beep and audio message
  {
      playSound("blogasLT.wav");
    }
  }
  if (language == 'B') {
    if (tot == code1) //if the code is correct you trigger to play .wav
    {
      playSound("ledaiEN.wav");
    }
    else if (tot == code2)
    {
      playSound("zuvisEN.wav");
    }
    else if (tot == code3)
    {
      playSound("draugEN.wav");
    }
    else //if the code is wrong you get a beep and audio message
    {
      playSound("blogasEN.wav");
    }
  }
  if (language == 'C') {
    if (tot == code1) //if the code is correct you trigger to play .wav
    {
      playSound("ledaiLV.wav");
    }
    else if (tot == code2)
    {
      playSound("zuvisLV.wav");
    }
    else if (tot == code3)
    {
      playSound("draugLV.wav");
    }
    else //if the code is wrong you get a beep and audio message
    {
      playSound("blogasLV.wav");
    }
  }
  if (language == 'D') {
    if (tot == code1) //if the code is correct you trigger to play .wav
    {
      playSound("ledaiRU.wav");
    }
    else if (tot == code2)
    {
      playSound("zuvisRU.wav");
    }
    else if (tot == code3)
    {
      playSound("draugRU.wav");
    }
    else //if the code is wrong you get a beep and audio message
    {
      playSound("blogasRU.wav");
    }
  }
}

// Playing assigned filename
void playSound(const char* cName) {
  File myFile = SD.open(cName);
  const int S = 1024; // Number of samples to read in block
  short buffer[S];
  // until the file is not finished
  Serial.println("playing ");
  Serial.println(cName);

  Audio.begin(44100, 200);
  delay(200);
  while (myFile.available()) {
    myFile.read(buffer, sizeof(buffer));
    // Prepare samples
    int volume = 512;
    //max volume 1024
    Audio.prepare(buffer, S, volume);
    Audio.write(buffer, S);
   if ( interruptState ) break;
     else if ( hookOffState == 0 ) break;
  }
  Audio.end();
  myFile.close();
  delay(50);
  DACC->DACC_CHDR = DACC_CHDR_CH1; //disable DAC1
}

The schematics (if you can call it that) below:

EDIT:
@Damago solution works! I just wanted to share here the solution for future searches. What you need to do is to get the 4th column of 4x4 keypad to work as an interrupt properly:
Set all row pins as output and column pins as input with pullup.
for( int i=0; i< ROW_NUM; ++i) pinMode(pin_rows[i], OUTPUT);
for( int i=0; i< COLUMN_NUM; ++i) pinMode(pin_column[i], INPUT_PULLUP);

Set row pins to low:
for( int i=0; i< ROW_NUM; ++i) digitalWrite(pin_rows[i], LOW);

Attach the 4th column pin as interrupt:
attachInterrupt(digitalPinToInterrupt(pin_column[3]), interruptToggle, FALLING);

And of course, fix the syntax overall (it was a bit messy :) )
Full sketch below:
#include <DAC.h>
#include <SD.h>
#include <SPI.h>
#include <Audio.h>
#include <Keypad.h>

const byte ROW_NUM = 4;
const byte COLUMN_NUM = 4;

int code1 = 12345;  //The code I used, you can change it
int code2 = 45678;  //The code I used, you can change it
int code3 = 78900;  //The code I used, you can change it

int tot, i1, i2, i3, i4, i5;
char c1, c2, c3, c4;

char hexaKeys[ROW_NUM][COLUMN_NUM] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte hookPinA = 23;  // your interrupt pin
byte pin_rows[ROW_NUM] = {52, 50, 48, 46}; //connect to the row pinouts of the keypad
byte pin_column[COLUMN_NUM] = {44, 42, 40, 38}; //connect to the column pinouts of the keypad

Keypad myKeypad = Keypad(makeKeymap(hexaKeys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);

char keypresses[5];
char language;
char key;

volatile uint8_t interruptState = 0;
volatile byte hookOffState = 0;
int keyCounter = 0;

void setup() {
  // debug output at 9600 baud
  Serial.begin(9600);
  SD.begin(10);
  analogWriteResolution(12);

for( int i=0; i< ROW_NUM; ++i) pinMode(pin_rows[i], OUTPUT);
for( int i=0; i< COLUMN_NUM; ++i) pinMode(pin_column[i], INPUT_PULLUP);

for( int i=0; i< ROW_NUM; ++i) digitalWrite(pin_rows[i], LOW);
 pinMode(hookPinA, INPUT_PULLUP);
 attachInterrupt(digitalPinToInterrupt(hookPinA), hookOffToggle, CHANGE);
 attachInterrupt(digitalPinToInterrupt(pin_column[3]), interruptToggle, FALLING);

  DACC->DACC_CHDR = DACC_CHDR_CH1; //disable DAC1
}

int state = 0;
const int STATE_OFF = 0;
const int STATE_IDLE = 1;
const int STATE_LISTEN_KEY = 2;
const int STATE_PLAYER = 3;

bool isLanguageKey(char customKey) {
  return ('A' == customKey || 'B' == customKey || 'C' == customKey || 'D' == customKey);
}

void loop() {
  switch (state) {
    case STATE_OFF:
    //listen for a telephone receiver to be removed
      if (hookOffState == 1) {
        interruptState = 0;
        state = STATE_IDLE;
                      }
               else if (hookOffState == 0) {
               }
        break;
    case STATE_IDLE:
    //listen for a language key. Cannot dial a number before
               if (interruptState == 1) {
         isKeyPressed(); //get the key input
         buttonBeep();
        processLanguage();
        state = STATE_LISTEN_KEY;
               }
               else if (hookOffState == 0){
                state = STATE_OFF;
               }
               else {
      playSound("intro.wav");
        }
      break;
    case STATE_LISTEN_KEY:
    //listen for any key
      if (isKeyPressed()) {
        interruptState = 0;
        if (isLanguageKey(key)) {
          buttonBeep();
          processLanguage();
        }
        else  {
          buttonBeep();
          keypresses[keyCounter] = key;
          keyCounter++;
          if (keyCounter > 4) {
            state = STATE_PLAYER;
            //when 5 numbers are pressed - try to open the .wav file
          }
        }
      }
               else if (hookOffState == 0){
                state = STATE_OFF;
               }
      break;
    case STATE_PLAYER:
        //Play the audio and go back to state LISTEN
      calculateAndPlay();
      keyCounter = 0;
      interruptState = 0;
      state = STATE_LISTEN_KEY;
      break;
    default:
      break;
  }
}

void hookOffToggle() {     //detect a telephone receiver to be removed
hookOffState = digitalRead(hookPinA);
}

void interruptToggle() {
    interruptState = 1;
}

bool isKeyPressed() {
  key = myKeypad.getKey();
  return key != NO_KEY;
}

bool langKeyPressed() {
  key = myKeypad.getKey();
  return key != NO_KEY && isLanguageKey(key);
}

void processLanguage() { //press A/B/C/D keys - select 1 out of 4 languages
  keyCounter = 0;
  if (key == 'A') {
    Serial.println("   LT    ");
  }
  if (key == 'B') {
    Serial.println("   EN    ");
  }
  if (key == 'C') {
    Serial.println("   LV    ");
  }
  if (key == 'D') {
    Serial.println("   RU    ");
  }
  language = key;
}

void buttonBeep(){
      for (int j = 0; j < 200; j++) {
        for (int i = 0; i < 200; i++)
          analogWrite(DAC0, i);
        for (int i = 200; i >= 0; i--)
          analogWrite(DAC0, i);
      }
}

void backgroundHumm() {
      for (int j = 0; j < 256; j++) {
        for (int i = 0; i < 256; i++)
          analogWrite(DAC0, j);
          for (int j = 256; j >= 0; j--) {
            for (int i = 256; i >= 0; i--)
          analogWrite(DAC0, j);
      }
  }
}

void calculateAndPlay() {
  //if we have 4+1 numbers - proceed
  //the keys pressed are stored into chars I convert them to int then i did some multiplication to get the code as an int of xxxx
  i1 = (keypresses[0] - 48) * 10000;
  i2 = (keypresses[1] - 48) * 1000;
  i3 = (keypresses[2] - 48) * 100;
  i4 = (keypresses[3] - 48) * 10;
  i5 = (keypresses[4] - 48) * 1;

  tot = i1 + i2 + i3 + i4 + i5;
  if (language == 'A') {
    if (tot == code1) //if the code is correct you trigger to play .wav
    {
      playSound("ledaiLT.wav");
    }
    else if (tot == code2)
    {
      playSound("zuvisLT.wav");
    }
    else if (tot == code3)
    {
      playSound("draugLT.wav");
    }
    else //if the code is wrong you get a beep and audio message
  {
      playSound("blogasLT.wav");
    }
  }
  if (language == 'B') {
    if (tot == code1) //if the code is correct you trigger to play .wav
    {
      playSound("ledaiEN.wav");
    }
    else if (tot == code2)
    {
      playSound("zuvisEN.wav");
    }
    else if (tot == code3)
    {
      playSound("draugEN.wav");
    }
    else //if the code is wrong you get a beep and audio message
    {
      playSound("blogasEN.wav");
    }
  }
  if (language == 'C') {
    if (tot == code1) //if the code is correct you trigger to play .wav
    {
      playSound("ledaiLV.wav");
    }
    else if (tot == code2)
    {
      playSound("zuvisLV.wav");
    }
    else if (tot == code3)
    {
      playSound("draugLV.wav");
    }
    else //if the code is wrong you get a beep and audio message
    {
      playSound("blogasLV.wav");
    }
  }
  if (language == 'D') {
    if (tot == code1) //if the code is correct you trigger to play .wav
    {
      playSound("ledaiRU.wav");
    }
    else if (tot == code2)
    {
      playSound("zuvisRU.wav");
    }
    else if (tot == code3)
    {
      playSound("draugRU.wav");
    }
    else //if the code is wrong you get a beep and audio message
    {
      playSound("blogasRU.wav");
    }
  }
}

// Playing assigned filename
void playSound(const char* cName) {
  File myFile = SD.open(cName);
  const int S = 1024; // Number of samples to read in block
  short buffer[S];
  // until the file is not finished
  Serial.println("playing ");
  Serial.println(cName);

  Audio.begin(44100, 200);
  delay(200);
  while (myFile.available()) {
    myFile.read(buffer, sizeof(buffer));
    // Prepare samples
    int volume = 512;
    //max volume 1024
    Audio.prepare(buffer, S, volume);
    Audio.write(buffer, S);
   if ( interruptState ) break;
   else if ( hookOffState == 0 ) break;
  }
  Audio.end();
  myFile.close();
  delay(50);
  DACC->DACC_CHDR = DACC_CHDR_CH1; //disable DAC1
}

why do you require to use an interrupt?

It´s a button with PULLDOWN resistor

The button showed in the top right of a drawing is for testing purposes only - it's not supposed to be there in a final project.

ideal would be to play the sound without blocking and and have the loop() check the button

There is a bit of a problem here. You cannot simply use one diode.
There voltage is present on the keyboard pins only during getKey() function evaluation.
The keyboard works this way:
when you call a myKeypad.getKey(); then arduino does the following:

changes the first column from input (high impedance) to output
outputs 0V voltage to first column,
scans all rows if they are 0V (normally they are pulled up - you know what pullup is).
if any key in this column is pressed then the column voltage of 0V is pulling down the corresponding row voltage. That is there is a connection between row and column.

Here is the exact code:
    pin_mode(columnPins[c],OUTPUT);
    pin_write(columnPins[c], LOW);  // Begin column pulse output.
    for (byte r=0; r<sizeKpd.rows; r++) {
        bitWrite(bitMap[r], c, !pin_read(rowPins[r]));  // keypress is active low so invert to high.
    }
    // Set pin to high impedance input. Effectively ends column pulse.
    pin_write(columnPins[c],HIGH);
    pin_mode(columnPins[c],INPUT);

It is not impossible to do this this way but it would require either modifying keyboard or creating a bit more complicated circuit. However it really does not make real sense.
I would do this different way: I would completely skip interrupt here. You are checking for a flag set inside interrupt:
if ( interruptState ) break;

I would directly check here for the voltage on a specific pin. You have to (simply):

set row pin (46 as far as I understand from your code) to output, and set it to low,
set column pins (all of them) to input-pullup - as I understand
{44, 42, 40, 38}
check if any of those pins is 'LOW', if yes - then break;

As far as I understand the library you don't even have to revert any pins back, the library re-initializes the pins correctly on every GetKey()
If for any reason the operation above takes too long you can shorten it using direct port manipulation as in https://forum.arduino.cc/t/arduino-due-how-to-direrct-port-access/251656 but note, that it is not as simple on Arduino Due as on AVR based ones.

Thanks! For a moment I thought I have solved the issue completely! But not quite yet..
I have made the described changes, except I need pin 38 to be output and LOW. And row pins as input_pullup. The interrupt works! Sadly, the keypad no longer receives inputs for pressed keys in this way.

"As far as I understand the library you don't even have to revert any pins back, the library re-initializes the pins correctly on every GetKey()"
I guess I need to revert these pins back? But then - how to receive interrupts after reverting?

I think your solution is the closest to solving my problem. Now I can interrupt the .wav file, but the input won't register which language key I've pressed...
So basically I need to press twice to achieve the goal. Edited code in the main question:)

If you want to use interrupts, it requires a separate pin to detect the falling edge on column 4 (pin 38). In the following example, I used pin 28 for the column 4 interrupt. These can be connected together via a 1K resistor to protect against pin 28 inadvertently outputting low while the other is outputting high.
Pin 38 is pulled low during the call of myKeypad.getKey() thus triggering the ISR.
Working copies are made of the variables that are updated in the ISRs. This will require changes to the state machine to process column4Pressed obtained from the ISR.
const byte hookPinA = 23;  // your interrupt pin
const byte interruptPin = 22;  // your interrupt pin

const byte column4InterruptPin = 28;  // Column 4 interrupt pin connected to column4Pin via a wire link. Could add a 1K series resistor to protect against short circuit to ground if it were output low when pin 38 is output high.
const byte column4Pin = 38;  // Column 4 pin connected to column4InterruptPin via a wire link.

// States updated by ISR.
volatile byte isr_hookOffState = 0;
volatile byte isr_interruptState = 0;
volatile bool isr_column4Pressed = false;

// Working copies of ISR data.
byte hookOffState = 0;
byte interruptState = 0;
bool column4Pressed = false;

// Use a single byte for the state variable and initialise it to OFF.
enum class State : byte
{
    OFF = 0,
    IDLE = 1,
    LISTEN_KEY = 2,
    PLAYER = 3
} state = State::OFF;

void setup()
{
    pinMode(hookPinA, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(hookPinA), hookOffToggle, CHANGE);

    pinMode(interruptPin, INPUT);
    attachInterrupt(digitalPinToInterrupt(interruptPin), interruptToggle, RISING); // test interrupt with a regular button

    pinMode(column4InterruptPin, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(column4InterruptPin), interruptColumn4, FALLING);  // Triggered by pulling column 4 low, e.g. digitalWrite(column4Pin, LOW) or within myKeypad.getKey().
}

void loop()
{
    // Get a fresh copy of the ISR data and reset the interrupt state flag atomically
    // by temporarily disabling interrupts.
    cli();
    hookOffState = isr_hookOffState;
    interruptState = isr_interruptState;
    column4Pressed = isr_column4Pressed;
    isr_interruptState = 0;  // Reset to detect next interrupt.
    isr_column4Pressed = false; // Reset to detect next interrupt.
    sei();

    // Alternative method to test whether any button in column 4 is pressed.
    // This is how to do it without using interrupts.
    /*
    pinMode(column4Pin, OUTPUT);
    digitalWrite(column4Pin, LOW);
    column4Pressed = !digitalRead(52) || !digitalRead(50) || !digitalRead(48) || !digitalRead(46);
    digitalWrite(column4Pin, HIGH);
    pinMode(column4Pin, INPUT);
    */

    // Process the working copies of the ISR data.
    // You will need to change the state machine logic to process column4Pressed obtained from the ISR.

    switch (state)
    {
    case State::OFF:
        break;
    case State::IDLE:
        break;
    case State::LISTEN_KEY:
        break;
    case State::PLAYER:
        break;
    }
}

void hookOffToggle()
{
    isr_hookOffState = digitalRead(hookPinA);
}

void interruptToggle()
{
    isr_interruptState = 1;
}

void interruptColumn4()
{
    // Test whether any button in column 4 is pressed.
    isr_column4Pressed = !digitalRead(52) || !digitalRead(50) || !digitalRead(48) || !digitalRead(46);
}

Here is the Wokwi simulation which uses an Arduino Mega and pin 2 for the column 4 interrupt. Note that there is no protection resistor between pins 2 and 38. The Wokwi simulator will create a Value Change Dump (VCD) file for viewing in your favourite trace analyser:

Alternatively, if you don't want to use interrupts, you could pull column 4 (pin 38) low and test the row pins for a logic low. See the commented code in loop().

What are cli(); and sei();?
They are not declared in this scope.

They clear and set the global interrupt flag to disable and enable interrupts. Try noInterrupts() and interrupts()  instead. interrupts

Thanks, I have implemented all the changes, sadly no luck - nothing is being received through isr_column4Pressed. How I've connected 38 and 28 pins: https://ibb.co/RP65rzQ

@GoldenMoose, what value of resistor are you using to connect pin 38 to pin 28? From your image it is 560K which is far too large. The I/O internal pull-up resistor range is 20K to 50K. The protection resistor should be large enough to limit the current to less than 20 mA if inadvertently one pin is high while the other is low. It also has to be low enough to drop a small voltage in comparison to the voltage across the internal pull-up resistor to be recognised as a logic low when pin 38 is pulled low, i.e. a voltage divider.

I have used 3.6k reistor. I have also tried it with different resistors/no resistor. Same result...

I see you have edited your post. But in the example, you are using GROUND pin together for the Column4pin also. Do I need that?


text:
Need help in writing a function
I am reading an accelerometer using arduino. Basically i receive positive values and I need to get only first row of negative values.
E.g. I receive values > -0.5 , then I start to have values < -0.5 (which i put them into an array , and then in case I get again values greater than -0.5 I want to stop it.
Also if in 30 seconds it should stop anyway.
This is what I did till now but is not working like expected
void reading_mpu_brake(){
          unsigned long StartTime = millis();

      float acc[500];
      int read_time[500];

      byte arrayIndex = 0;

    while(1){
      unsigned long CurrentTime = millis();
      if (CurrentTime - StartTime < interval) {
        mpu.update();
        if (mpu.getAccX() < -0.05){
          total_acc = sqrt((pow((mpu.getAccX() - offsetx), 2) + pow((mpu.getAccY() - offsety), 2) + pow((mpu.getAccZ() - offsetz), 2) ));

          acc[arrayIndex] = total_acc;
          read_time[arrayIndex] = millis();

          Serial.print(acc[arrayIndex]);
          Serial.print(" | ");
          Serial.print(mpu.getAccX());
          Serial.print(" | ");
          Serial.println(read_time[arrayIndex]);
          Serial.println(arrayIndex);
           arrayIndex++;
        }
      }
      else if (CurrentTime - StartTime > interval)
      {
        Serial.println("Over time");
        break;

      }

    }

Now is working and get values less than -0.5 but if after several good values if I get positive values and then again negative it will put in array also the last one which I don t.
So basically I need to stop it after first bunch of good values...
Any help appreciated
Thank you!
L.E.
Seems I miss a good explanation so I will try again.
1 - I call the function and it start monitoring values for 30 seconds.
Case 1 :
I receive 0.6 , 0.7 , 0.4 , 0.2 , -0.2 , -0.6 , -0.7 , -0.8 , -0.4 , 0.3 , 0.5 ...etc
In this case I get into acc array values : -0.6 , -0.7 , -0.8
then after 30 sec gone the function exit
That is OK partially .
Case 2 :
I receive 0.6 , 0.7 , 0.4 , 0.2 , -0.2 , -0.6 , -0.7 , -0.8 , -0.4 , 0.3 , 0.5 , -0.6 , -0.7 , 0.6...etc
In this case I get into array values -0.6 , -0.7 , -0.8  and if the 30 secs are not gone I also get -0.6 , -0.7 .
What I want is function to exit after get first bunch of good values (-0.6 , -0.7 , -0.8) .
Hope now is more clear

I edited and added more explanations. By "row of negative values" mean first bunch of values that met criteria to be < -0.5

it is clear what you are trying to do ... it is unknown what happens when you run the code ... not working as expected does not mean anything specific

float acc[500];
int read_time[500];

Right, so a float is 4 bytes on this platform, so that array takes 2000 bytes. And an int is 2 bytes, so that other array is another 1000 bytes.
The Uno has 2KB of RAM, so those two declarations alone take up more RAM than the device has.
I'm a little surprised it works at all, but certainly "not working as expected" is indeed an expected outcome here.


text:
'GIMSK' was not declared in this scope
I'm programming an ATTiny 85 using the Arduino IDE and an Arduino Nano as "Arduino as ISP" to program the ATTiny. I succeeded a week ago and now I want to program a second chip but get the 'GIMSK' was not declared in this scope error during compile.
The GIMSK is called at the start of the sleep() function. I tried adding #include <avr/interrupt.h> but continue to receive the compile error.
#include <avr/sleep.h>    // Sleep Modes
#include <avr/power.h>
#include <elapsedMillis.h>
const int hallPin = 2;     // the number of the hall effect pin
const int magnetPin =  1;      // the number of the magnet pin
const long debouncing_time = 15; //Debouncing Time in milliseconds
// variables will change:
volatile int hallState = 0;         // variable for storing the hall counter
volatile unsigned long last_micros;
elapsedMillis timer;

void setup()
{
  pinMode(magnetPin, OUTPUT);
  pinMode(hallPin, INPUT);
  digitalWrite(hallPin, HIGH);    // pullup enabled.
  // Attach an interrupt to the ISR vector
  attachInterrupt(0, pin_ISR, RISING); //default interupt pin is always 0 on attiny85 (physical pin 7)
  timer = 0;
}

void sleep()
{
    GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts
    PCMSK |= _BV(PCINT2);                   // Use PB2 as interrupt pin
    ADCSRA &= ~_BV(ADEN);                   // ADC off
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // replaces above statement
    sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
    sei();                                  // Enable interrupts
    sleep_cpu();                            // sleep
    cli();                                  // Disable interrupts
    PCMSK &= ~_BV(PCINT2);                  // Turn off PB2 as interrupt pin
    sleep_disable();                        // Clear SE bit
    ADCSRA |= _BV(ADEN);                    // ADC on
    sei();                                  // Enable interrupts
} // sleep
etc.

Can anyone give me a pointer? I had saved my work so I'm puzzled by the error.
Thank you.

Solution:

Programming configuration for the ATTiny 85 via the Nano as ISP.

For what board are you compiling? Are you sure it was the Attiny85?

@chrisl, yes, ATTiny 85-20PU. I'm using the Nano plugged into a breadboard to program the bare chip. I'm using the procedure here.

In order to program the ATtiny85, you need a suitable board support
package, and you have to configure the Arduino IDE in order to target
that specific chip.
From the description of your issue, it sounds like you did that a week
ago, and then, maybe by accident, you undid the IDE configuration. Now
the IDE is targeting a type of MCU that does not have a register named
GIMSK. Double check that you have the right target configured.
Another possibility would be that the Arduino.h file for the core you
are using does not automatically include avr/io.h. If this is the case,
add
#include <avr/io.h>

at the top of your code.

You were correct with the "target that specific chip" comment. The Arduino IDE doesn't seem to save these with the project or they get switched when I'm working on the Nano and switching to using the Nano as ISP. I've added  a screengrab into my question which is now solved. Thank you.


text:
Arduino compatible ESP32 and ESP8266 board power consumption at sleep state
I have data on smaller modules with ESP32 and ESP8266, but can't find anything reliable pertaining to the whole board power consumption (current) with 12V input and microcontroller at low power or sleep state. The power subsystem on Arduino compatible boards like this one:

consists of step-down switching regulator to 5V and linear regulator to 3.3V. I wonder how this design behaves when the ESP microcontroller itself draws very small current, e.g. below 1mA. Does anyone have current measurement at DC input socket when microcontroller is in low power state without any peripherals attached to the board?

The datasheet for the regulator will tell you how it performs at different loads. And what's to stop you measuring the current yourself?

I always measure myself. Get one usb-voltmeter. They create wonders.

@Majenko I don't have the board. I'm asking before buying.

i would guess that's not the best board to use for low power consumption, due to usb serial, leds, etc. use a buck converter to turn 12v into 3.3v.


text:
I can change value of only one register on 8-Bit Register integrated circuit (74hc273 / DM74LS273)?
First, please be patient, I'm not electronical person. I am learning Arduino and electronics for hobby and this is my fist time with integrated circuits.

Situation: I'm want to extend the Arduino Nano pins (De/Multiplexer) and keep the state (High/Low) of the new pins until I decide to change it again. For keep the states I think that D-type Flipflop memory-based system can help .
Question 1: On this system can  I change only one bit with a unique signal or need to set all bit states ?
Example (reference image):

Memory, previous state: Q0=0, Q1=1, Q2=1, Q3=0
Arduino: Set pin17 (D2) to High -> Memory: Waiting new data.
Arduino: Set pin16 (D3) to High -> Mux: Pass the value to memory at D0
Memory: Read 1 on D0 (this is my doubt. D1, D2 and D3 don't matter ?)
Arduino: Set pin17 (D2) to LOW -> Memory: Save new data
Memory, new state: Q0=1, Q1=1, Q2=1, Q3=0 ? or Q0=1, Q1=0, Q2=0, Q3=0 ?

Question 2: Are this correct ?
Question 3: Are there a more efficient way to do this?

Notes:

I used a simulator to diagramed the memory based on this datasheet: https://pdf1.alldatasheet.com/datasheet-pdf/view/8337/NSC/74273.html It seems that it is possible, but I want to be sure.
My currently solution is use separated flipflops, but I want to simplify it.
Connections on reference image are simplified.
Sorry about the poor diagram, I don't know programs for beautiful electronical diagrams.
Sorry about typos, not-native English person here.

I don't want to answer in a comment, but have you heard of the 74HC595 chip? That lets you set up 8 outputs using only 3 pins from the Arduino, and they can be chained. That looks simpler than your proposal.

Or if you want even fewer outputs used you could consider an I2C IO expander like the MPC23017.

feeding demux into the latch will not let you set output pins to various states

There is a simple and cheap component that can do what you want, the 74HC259 addressable latch. Essentially it's demux and an 8-bit latch in which the bits are individually addressable.

Look at the data sheet of the '273: You cannot set its flip-flops individually. All or none, that's it. Use another IC.

A lot of thanks for your comments. Really appreciate your time and patience.

Question 1 and Question 2: I was wrong, this is not the correct way. @jsotola and @the_busybee, thanks for the clarification
Question 3: @Nick_Gammon and @Majenko I think you are right, using i2c are more efficient ways to do. But, the @StarCat proposal is more compatible with my current solution. 74hc259 allows me set the state one by one and keep it until I change it again.


text:
Why do I have to burn the code to make it run?
Why do I have to burn the code twice to actually burn it on to the Arduino board? I have to execute this command twice - only then is the chip getting programmed.
I'm using this command to burn the program into the Arduino Uno board using a Rasp Pi 3, via SSH from Windows 10.
avr-gcc -mmcu=atmega328 filename.c | avr-objcopy -O ihex -j .text -j .data a.out a.hex | avrdude -C avrdude.conf -v -p atmega328p -c arduino -P /dev/ttyACM* -b 115200 -D -U flash:w:a.hex:i

Please post any messages you get from the burning process (amend your question to do this).

why do you use | between the commands?

to execute those three separate command in one single time. @Juraj

On a Unix shell, separating commands with the pipe character (|) means
“run these commands in parallel, feeding the standard output of each one
to the standard input of next one”.
In this context, it makes no sense to use pipes, as both avr-objcopy and
avrdude read their data from files, not from stdin. Furthermore, running
these in parallel means that avrdude will not have access to a.hex
when it starts.
The solution is to run the commands sequentially instead of in
parallel. Type and run one command at a time.
Alternatively, if you really want to have everything in a single line,
separate the commands with a semicolon (;, meaning “run the next
command when the previous one is done”) or, better yet, double ampersand
(&& = “run the next command only if the previous one exits
successfully”).

correct me,
so in the first burn it is the previous a.hex file and while on the second burn it gets the new one. right?

@user137442: Probably something like that, although it's hard to know exactly. Avrdude may be burning the hex file from the previous run of the pipe, or from the one before if the previous run could not build an hex file, or it may fail because it finds an incomplete hex file which is in the process of being written... By starting the three commands in parallel, you are at the mercy of unpredictable, timing-dependent behavior.

thank you so much Bonet.
I tried && and it is working fine in the first burn only.
In your answer you said somthing like "In this context, it makes no ......... a.hex when it starts"
Can you explain this?

@user137442: Many Unix utilities (sort, split, sed, head...) default to processing the data that comes into their standard input and write the results to standard output. These are meant to be combined with pipes. The commands you are using do not work this way so, when using avr-gcc, avr-objcopy and avrdude, it makes no sense to use pipes.

Thank you. I haven't understood all but i can see where it is going wrong. Thank you so much


text:
Arduino How can I add 30s delay and turn off the led to the following code
const int buttonPin =  2;
boolean currentState = LOW;
boolean lastState    = LOW;
boolean stateChange  = false;

int currentButton = 0;
int lastButton    = 4;
int ledArray[]    = {9, 10, 11, 12};
long previousMillis = 0;
long interval = 1000 ;

void setup() {
        pinMode(buttonPin, INPUT);
        for (int i=0; i<5; i++){
            pinMode(ledArray[i],OUTPUT);
        }
        Serial.begin(9600);
}

void loop(){
            currentState = debounceButton();
            stateChange = checkForChange(currentState, lastState);
            currentButton = getButtonNumber(lastButton, currentState, stateChange);
            indicatorLight(currentButton);
            lastState  = currentState;
            lastButton = currentButton;
}

boolean debounceButton()
            {
            boolean firstCheck   = LOW;
            boolean secondCheck  = LOW;
            boolean current = LOW;
            firstCheck  = digitalRead(buttonPin);
            delay(50);
            secondCheck = digitalRead(buttonPin);
                    if (firstCheck == secondCheck){
                        current = firstCheck;
                    }
            return current;
}

boolean checkForChange(boolean current, boolean last)
        {
        boolean change;
                if (current != last){
                    change = true;
                }
                        else {
                        change = false;
                        }
                return change;
}

int getButtonNumber(int button, boolean state, boolean change)
            {
            if (change == true && state == LOW){
                button++;
                        if (button > 3){
                        button = 0;
                        }
                        Serial.println("g");

            }
            return button;
}

void indicatorLight(int button)
         {
                for (int i=0; i<4; i++) {
                            digitalWrite(ledArray[i], LOW);
                        }
                        digitalWrite(ledArray[button], HIGH);
  }

Use millis() to capture a timestamp of when you are turning the LED on, then use that in loop() to check, if more than 30s passed. In that if statement turn off all LEDs. Refer to the BlinkWithoutDelay example, that comes with the Arduino IDE

You have the right idea to debounce the buttons, but there is a 50 ms delay per button which blocks the loop for a total of 200 ms with four buttons.
So consider using a non-blocking debouncer of which there are many examples on the internet, but here is a simple debouncer I put on GitHub. It could be implemented something like the following example:
#include "debouncer.h"

const uint16_t LED_OFF_TIME_DELAY_ms = 2000;  // milliseconds. For testing.
//const uint16_t LED_OFF_TIME_DELAY_ms = 30000;  // milliseconds.

struct ButtonLed
{
  Debouncer button;
  byte button_pin;
  byte led_pin;
};

const ButtonLed BUTTONS_LEDS[] =
{
  { Debouncer(5, 50, LED_OFF_TIME_DELAY_ms), 5, 11 },
  { Debouncer(4, 50, LED_OFF_TIME_DELAY_ms), 4, 10 },
  { Debouncer(3, 50, LED_OFF_TIME_DELAY_ms), 3, 9 },
  { Debouncer(2, 50, LED_OFF_TIME_DELAY_ms), 2, 8 }
};

void setup()
{
  for (const auto& button_led : BUTTONS_LEDS)
  {
    pinMode(button_led.button_pin, INPUT_PULLUP);
    pinMode(button_led.led_pin, OUTPUT);
    digitalWrite(button_led.led_pin, LOW);
  }
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  uint16_t timestamp = millis();

  //
  // TASK 1: Read the buttons and set their corresponding LEDs.
  //

  for (const auto& button_led : BUTTONS_LEDS)
  {
    button_led.button.Update();
    if (button_led.button.Fall())
    {
      digitalWrite(button_led.led_pin, HIGH);
    }
    else if (button_led.button.RepeatCount() == 1)
    {
      digitalWrite(button_led.led_pin, LOW);
    }
  }

  //
  // TASK 2: Blink the inbuilt LED.
  //

  const uint16_t LED_BLINK_INTERVAL = 100;
  static uint16_t led_blink_previous_timestamp = timestamp;
  static bool led_state = false;
  if (timestamp - led_blink_previous_timestamp >= LED_BLINK_INTERVAL)
  {
    led_state = !led_state;
    digitalWrite(LED_BUILTIN, led_state);
    led_blink_previous_timestamp += LED_BLINK_INTERVAL;
  }
}

And here it is in action in the Wokwi simulator:


text:
How to light up middle points in a display with 4 digits?
How to light up the two points that is in the middle? It only lights up when the digB is set to LOW, and it lights up all 3 points that is in the middle.

Example code:
const int displayPins[] = {2,3,4,5,6,7,8,9,10,11,12,13};
const int digA = 7;
const int digB = 4;
const int digC = 3;
const int digD = 8;
const int decimalPoint = 10;

void setup() {
    for (int i = 0; i < (sizeof(displayPins)/sizeof(displayPins[0])); i++) {
        pinMode(displayPins[i], OUTPUT);
    }

    digitalWrite(digA, 1);
    digitalWrite(digB, 0);
    digitalWrite(decimalPoint, 1);
    digitalWrite(digC, 1);
    digitalWrite(digD, 1);
}

void loop() {
}

I want to display a clock in this format: 00:00. But did not found a way to light up the two points that is in the middle.

refer to the datasheet

@jsotola Did not found the right one, all that i found is the display with 4 digits and decimals without the two points in the middle. I also searched for the model of the item "sh5463AS-34", but did not found anything.

there are several schematics on the web ... the part number to search is in the picture you posted ... your question is not arduino specific ... voting to close

Try all the contacts that do not light up other segments. You will find the right ones eventually, if they can be separately controlled at all.

Possibly this link about exactly the same question can help. This seems to suggest that what you want might not be possible if you have the same display.

The schematic on this site shows,  that the three dots are all connected together, thus can only light up together. Seems to be the model, that you have. In that case you cannot do anything about that, other than buying a different 7segment display.

@chrisl the schematic diagram of the display may be incorrect ... the colon leds could actually be reversed

@jsotola What do you mean by "reversed"? The schematic shows the LEDs of the middle dots connected together on both sides. Or do you mean middle dots in one direction and the decimal dot in the other? We cannot really determine if the schematic is correct. That can only be done by testing the real component, but the schematic is consistent with the experiments of the OP so far

@chrisl i somehow missed the part about the three leds lighting ... have not had my morning coffee yet ... my thought was that reversing the polarity would light the colon leds ... looks like the display requires black tape for selecting the display mode

It is not possible to separate the colon dots from the decimal point dot - they are all wired together in parallel internally:

As has been mentioned in the comments you need to use the "black tape" method of selecting the LEDs. That's not a joke, that's really what's done. Cover the LED that you don't want visible with black tape (or black paint, etc).


text:
DS3231 RTC not working with ESP32
I am using ESP-32-WROOM-32 with a RTC DS3231 module. I have connected SDA & SCL pins of RTC DS3231 with ESP32 D22 and D23 pins. Also, the VCC of RTC is connected to 3V3 of ESP32 and the GND of RTC is also connected to GND of ESP32  .RTC module is having attached battery also.
Following is the code:
#include <Wire.h> // for I2C with RTC module
#include "RTClib.h" //to show time

RTC_DS3231 rtc;

void Scanner ()
{
  Serial.println ();
  Serial.println ("I2C scanner. Scanning ...");
  byte count = 0;

  Wire.begin(22,23);
  for (byte i = 8; i < 120; i++)
  {
    Wire.beginTransmission (i);          // Begin I2C transmission Address (i)
    if (Wire.endTransmission () == 0)  // Receive 0 = success (ACK response)
    {
      Serial.print ("Found address: ");
      Serial.print (i, DEC);
      Serial.print (" (0x");
      Serial.print (i, HEX);     // PCF8574 7 bit address
      Serial.println (")");
      count++;
    }
  }
  Serial.print ("Found ");
  Serial.print (count, DEC);        // numbers of devices
  Serial.println (" device(s).");
}
void setup()
{
    // put your setup code here, to run once:
    Wire.begin(22,23);
    //Wire.begin();
    Serial.begin(115200);
         while(!Serial);

       ////////////////////////////////////

    ////////////////////////////////////////

    while (!rtc.begin())
    {
        Serial.println("Couldn't find RTC");
        Scanner();
        //Serial.println(DS3231_REG_STATUS);
        //        while (1)
        //        {
        //                  Serial.println("Couldn't find RTC");
        //
        //        }

        ;
    }
    Serial.println("Finally");
    // In setup function, we will call a function rtc.adjust(DateTime(__DATE__, __TIME__)) which will set the time according to our PC time.
    rtc.adjust(DateTime(__DATE__, __TIME__));
}
void loop()
{

    DateTime curr_time_obj = rtc.now();
    int day = curr_time_obj.day();
    int month = curr_time_obj.month();
    int year = curr_time_obj.year();
    int week_day = curr_time_obj.dayOfTheWeek();
    int sec = curr_time_obj.second();
    int hr = curr_time_obj.hour();
    int minute = curr_time_obj.minute();

    Serial.print("hour is ");
    Serial.println(hr);
    Serial.print("min is ");
    Serial.println(minute);
    Serial.print("secs is ");
    Serial.println(sec);
    Serial.println("############################");
    delay(5000);
}

Following is the output:

Some of the images of the circuit can be found here: https://drive.google.com/drive/folders/1fhM7o_aZCGh88OBDcypVLqhKhizhXnNd?usp=sharing
I would appreciate any help to resolve this issue.
Thanks

The I²C address of the DS3231 is 0x68, not 0x57. Are you sure that's the chip you have?

Yes, the chip says DS3231M to be specific.

Please link to the exact module that you are using. It's impossible to make out what it is from those pictures.

https://robu.in/product/ds3231-rtc-module-precise-real-time-clock-i2c-at24c32/?gclid=CjwKCAjwhOyJBhA4EiwAEcJdceN-yJB_Uxzz_EervOkpZRWXgECrQZJ_zWbnB5o3OxVbhG_Ki_f69RoCQKIQAvD_BwE @Majenko

That module contains both an RTC and an EEPROM.  The device 0x57 looks to be the EEPROM. There is no schematic for the module, but there are two sets of I2C pins. It could be that the two chips are wired separately and you have to choose the right I2C pins for which chip you wish to use. Try switching to the other SCL/SDA pins.

@Majenko I have this module and I use the RTC over the 6 pin header

I use this module with the DS3231 library by  Andrew Wickert. it is in the Library Manager

Warning
These modules normally come with a 200Ω resistor soldered next to the IN4148 Zener diode, as you can see in the image below.
ds3231 module problem fix
The resistor and diode form a simple charging circuit designed for use with LIR2032 rechargeable batteries.
Be aware that some DS3231 modules come with a non-rechargeable CR2032 battery. If this is the case, you must remove the resistor because attempting to charge a non-rechargeable battery can cause serious damage.

Blockquote

I resolved the rebooting problem extract the 200 ohms resistor

That battery will not charge with a 3V3 system such as the ESP devices. The diode should isolate it so you need to do nothing. If you power it with 5V then you need to modify it for a non rechargeable battery.