text:
Arduino Pull-Down Resistors
I'm building what I thought was a simple Arduino Nano project... right up until it caught fire!
I am a long-time reader of stack exchange and I always find the answers to my questions somewhere on Google, but this seems to be a bit of a head scratcher.
The project is a 4 pin 7 segment LED screen with a timer that counts when Analog pin 0 receives a voltage signal of ~2.5-5v.
Testing the project worked as expected, but when I soldered everything together, I was getting static or white noise from the Analog pin with no voltage being supplied.
I figured I needed a Pull-Down resistor to keep the Analog pin grounded until it received a voltage signal to get rid of any interference.
I connected a 220ohm resistor DIRECTLY from GND and DIRECTLY to Analog Pin 0 and connected the voltage signal wire to Pin 0 as well.
When I actually tested the hardware while connected to the car battery, that's when it shorted out and caused a mini fire.
I was able to read the voltage with my multimeter before the chip burnt out, I was reading ~15.5v total. I'm guessing it's the car battery plus the input voltage on Pin 0.
I only do clean and precise soldering, so there were no unaccounted for connections.
I'm unsure if the issue was too many volts running through the Nano altogether or because I don't really understand how the Pull-Down resistor works and messed that up.
Please help me understand what the issue is and what I can do for a solution.
Thank you.

Arduino Nano accept up to 12V.
On which pin have you connected the battery? What voltage are you measuring now on the battery? Have you connected the grounds of the car battery with the ground of the input signal?

Could you manage to draw a schematic? That will make things a lot clearer probably! Did you connect the battery minus to the Arduino Vcc (as that is the only way the voltages could “add up” as you said)? And how did you come up with a value of 220 Ohms (which is quite a low value for a pull down resistor)?

I've added a schematic. For some reason one line of text didn't save. The pink wire is CLK, but I don't think that's relevant to my original question. The 220ohm was a suggestion someone made to me, but I have no idea. I haven't dealt with resistors before.

What is that external 5V signal? Did you connect it with just one wire? And what exactly did burn? Something on the Arduino? If yes, how much current does the LED display draw? You might overload the voltage regulator. And a pulldown resistor as small as 1 to 4kOhm is already considered very strong. Normally you would use something like 10kOhm

The external 5v is a device which is also connected to the vehicle battery, so it's on the same circuit. Whenever it's powered on, it gets 5v which is my signal. What the LED actually draws, I'm not sure, but the specs say 5v@220mA. The part of the Arduino that burnt was whatever that chip is on the flip side of the processor. I'll try with a 10K resistor and see if it works.

the +5 V and GND on the device can easily be +12 V and +7 V when referenced to the vehicle battery negative

What are the brown lines on your drawing?

@Eli So you get 7V x 220mA = 1.4W of power as heat in the linear voltage regulator for the display alone. I currently don't have the real numbers, but I think this is too much. You need to switching voltage regulator, which is way more efficient. The linear voltage regulator on the Arduino just dissipates the excess voltage as heat.

Are you able to post a photo of the burnt out results?  Our describe exactly what smoked?

You violated the voltage input specification of A0 by a lot. What happened is what I would expect. The input protection diode on A0 conducted the battery voltage (- the protection diode drop) into the VCC of the Nano, this overvoltage fried just about all semiconductors and possibly several of the passive components on the board. It sounds like they do what they do when abused and they let the smoke out destroying the Nano and possible several other components. Hopefully this explains what happened. If you had connected the resistor between A0 and the battery it might have survived.

Input power
Car power systems operate between 13 and 15 volts when the car is running. Might be too high for the voltage regulator on the Nano. Mine is a AMS1117 which goes up to 15v. Sounds like that's what fried based on your description. Some fail closed circuit, so may have exposed the ATMega to 14v. There's some alternative voltage regulators with the same footprint that will go up to 20v or more input, look for one of those. SOT-223 footprint.
Button
The Nano/ATMegs has internal pullups. I'd use those; connect the one side of your button to ground rather than 5v, and the other to the Nano digital input. In your code, activate on LOW rather than HIGH. Then you can skip your external pullup.
Pullups
220 ohms is a very strong pulldown for the 5v signal. It will be seeing .11 watts of power dissipation. Use something higher like 10K or 100K. Put a 1K resistor on the 5v signal to limit it's current. You're Arduino is only sensing the voltage, so with a 10K to GND and 1K from 5v signal, the resistor divider will signal 4.5v, plenty for your Nano to detect "HIGH".

What do you do when you get a double battery jump. How about load dump?


text:
Battery supply vs laptop supply
Setup:
I have wired up the arduino, motor and battery as shown.

(12 and 5 of L293D are not connected to anything)
D11,D10...D6 means that those pins on the L293D are connected to digital pins 11-6 on the nano.
Problem:
The motors spin for a while but then they slow down to a stop. If I unplug the battery, wait for 5 mins or so and then reattach the battery then the motors start spinning but after a while they stop again. Now if I keep the setup the same except I unplug the battery and connect the arduino to my laptop then the laptop manages to power not only my arduino but also my motors (although they spin a little bit less faster than with the battery). And when I do it with the laptop the motors don't stop spinning.
Because of this I thought my battery might be faulty so I attached a fresh 9V energiser battery. Then the same thing happens. The motors spin for a while then stop and after I plug in the battery after a while they spin again.
I tried this yet again with a fresh battery and the same thing happened.
Question
What could be causing this?
Why are all of my batteries incapable of powering the motor steadily and why is my laptop capable of doing this?
CODE:
(all this does is make both motors spin)

Please no code as image. You can copy and paste the code as text into the question and format it as code by selecting it and clicking the {} button or pressing control+K

your battery does not last very long ... what does that tell you about the battery?

Does it tell me that the battery does not have enough current? I tried to test this out and I used a series of AA batteries which (although there were 6 of them) output only 7V due to their usage in the past. These batteries made my motor spin faster and for way longer than my 9V duracell battery.  So i think it might be because of current.

@Sanchez2009 that is correct ... the 9 V battery contains six AAAA cells, same as when you created a 9 V battery from six AA cells, but with very small capacity to provide current ... try using larger cells, like size C or D

source: Stack Exchange

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

sort: votes


text:
NRF24L01 receiver flooded with data packets
Following this tutorial I attempted making an NRF transmitter and receiver using an Arduino Nano. On the transmitter side I used the following code:
// SimpleTx - the master or the transmitter

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

const byte slaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

char dataToSend[10] = "Message 0";
char txNum = '0';

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleTx Starting");

    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.setRetries(3,5); // delay, count
    radio.openWritingPipe(slaveAddress);
}

//====================

void loop() {
    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {
        send();
        prevMillis = millis();
    }
}

//====================

void send() {

    bool rslt;
    rslt = radio.write( &dataToSend, sizeof(dataToSend) );
        // Always use sizeof() as it gives the size as the number of bytes.
        // For example if dataToSend was an int sizeof() would correctly return 2

    Serial.print("Data Sent ");
    Serial.print(dataToSend);
    if (rslt) {
        Serial.println("  Acknowledge received");
        updateMessage();
    }
    else {
        Serial.println("  Tx failed");
    }
}

//================

void updateMessage() {
        // so you can see that new data is being sent
    txNum += 1;
    if (txNum > '9') {
        txNum = '0';
    }
    dataToSend[8] = txNum;
}

The serial monitor prints
13:05:22.966 -> Data Sent Message 3  SimpleTx Starting
13:05:25.437 -> Data Sent Message 0  Acknowledge received
13:05:26.436 -> Data Sent Message 1  Acknowledge received
13:05:27.434 -> Data Sent Message 2  Acknowledge received
13:05:28.432 -> Data Sent Message 3  Acknowledge received
13:05:29.432 -> Data Sent Message 4  Acknowledge received
13:05:30.432 -> Data Sent Message 5  Acknowledge received
13:05:31.427 -> Data Sent Message 6  Acknowledge received

at 1 second intervals. I assume this points to an 'okay' transmitter. On the receiver side, I used the code
// SimpleRx - the slave or the receiver

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;

//===========

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleRx Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.startListening();
}

//=============

void loop() {
    getData();
    showData();
}

//==============

void getData() {
    if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) );
        newData = true;
    }
}

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println(dataReceived);
        newData = false;
    }
}

And the receiver gets flooded with data packets
13:06:20.318 -> Data received⸮SimpleRx Starting
13:06:21.798 -> Data received
13:06:21.831 -> Data received
13:06:21.831 -> Data received
13:06:21.864 -> Data received

The post also mentions that this is due to "most likely the Arduino is not communicating properly with its nRF24." Following the recommendations of post #30, later in the thread, the output of radio.printDetails() for the transmitter is
19:43:56.897 -> CheckConnection Starting
19:43:56.897 ->
19:43:56.897 -> FIRST WITH THE DEFAULT ADDRESSES aftCheckConnection Starting
19:43:58.355 ->
19:43:58.355 -> FIRST WITH THE DEFAULT ADDRESSES after power on
19:43:58.422 ->   Note that RF24 does NOT reset when Arduino resets - only when power is removed
19:43:58.488 ->   If the numbers are mostly 0x00 or 0xff it means that the Arduino is not
19:43:58.574 ->      communicating with the nRF24
19:43:58.621 ->
19:43:58.621 -> SPI Speedz  = 10 Mhz
19:43:58.654 -> STATUS      = 0x7f RX_DR=1 TX_DS=1 MAX_RT=1 RX_P_NO=7 TX_FULL=1
19:43:58.721 -> RX_ADDR_P0-1    = 0xffffffffff 0xffffffffff
19:43:58.754 -> RX_ADDR_P2-5    = 0xff 0xff 0x7f 0xff
19:43:58.788 -> TX_ADDR     = 0xffffffff7f
19:43:58.821 -> RX_PW_P0-6  = 0x00 0x00 0x00 0x00 0x00 0x00
19:43:58.854 -> EN_AA       = 0x00
19:43:58.887 -> EN_RXADDR   = 0x7f
19:43:58.887 -> RF_CH       = 0x00
19:43:58.920 -> RF_SETUP    = 0x00
19:43:58.920 -> CONFIG      = 0x00
19:43:58.954 -> DYNPD/FEATURE   = 0x00 0x00
19:43:58.954 -> Data Rate   = 1 MBPS
19:43:58.987 -> Model       = nRF24L01+
19:43:59.020 -> CRC Length  = Disabled
19:43:59.020 -> PA Power    = PA_MIN
19:43:59.053 -> ARC     = 0
19:43:59.053 ->
19:43:59.053 ->
19:43:59.053 -> AND NOW WITH ADDRESS AAAxR  0x41 41 41 78 52   ON P1
19:43:59.120 ->  and 250KBPS data rate
19:43:59.154 ->
19:43:59.154 -> SPI Speedz  = 10 Mhz
19:43:59.186 -> STATUS      = 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
19:43:59.253 -> RX_ADDR_P0-1    = 0x0000000000 0x0000000000
19:43:59.286 -> RX_ADDR_P2-5    = 0x00 0x00 0x00 0x00
19:43:59.320 -> TX_ADDR     = 0x0000000000
19:43:59.353 -> RX_PW_P0-6  = 0x00 0x00 0x00 0x00 0x00 0x00
19:43:59.386 -> EN_AA       = 0x00
19:43:59.419 -> EN_RXADDR   = 0x00
19:43:59.419 -> RF_CH       = 0x00
19:43:59.452 -> RF_SETUP    = 0x00
19:43:59.452 -> CONFIG      = 0x00
19:43:59.486 -> DYNPD/FEATURE   = 0x00 0x00
19:43:59.486 -> Data Rate   = 1 MBPS
19:43:59.519 -> Model       = nRF24L01+
19:43:59.552 -> CRC Length  = Disabled
19:43:59.552 -> PA Power    = PA_MIN
19:43:59.585 -> ARC     = 0
19:43:59.585 ->
19:43:59.585 ->

The same sketch when uploaded on the receiver gives,
19:48:38.260 -> CheckConnection Starting
19:48:38.260 ->
19:48:38.260 ->
19:48:38.260 ->
19:48:38.260 -> FIRST WITH THE DEFAULT ADDRESSES aftCheckConnection Starting
19:48:39.708 ->
19:48:39.708 -> FIRST WITH THE DEFAULT ADDRESSES after power on
19:48:39.774 ->   Note that RF24 does NOT reset when Arduino resets - only when power is removed
19:48:39.841 ->   If the numbers are mostly 0x00 or 0xff it means that the Arduino is not
19:48:39.941 ->      communicating with the nRF24
19:48:39.974 ->
19:48:39.974 -> SPI Speedz  = 10 Mhz
19:48:40.008 -> STATUS      = 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
19:48:40.075 -> RX_ADDR_P0-1    = 0x0000000000 0x0000000000
19:48:40.109 -> RX_ADDR_P2-5    = 0x00 0x00 0x00 0x00
19:48:40.141 -> TX_ADDR     = 0x0000000000
19:48:40.175 -> RX_PW_P0-6  = 0x00 0x00 0x00 0x00 0x00 0x00
19:48:40.208 -> EN_AA       = 0x00
19:48:40.242 -> EN_RXADDR   = 0x00
19:48:40.242 -> RF_CH       = 0x00
19:48:40.274 -> RF_SETUP    = 0x00
19:48:40.274 -> CONFIG      = 0x00
19:48:40.308 -> DYNPD/FEATURE   = 0x00 0x00
19:48:40.308 -> Data Rate   = 1 MBPS
19:48:40.341 -> Model       = nRF24L01+
19:48:40.374 -> CRC Length  = Disabled
19:48:40.374 -> PA Power    = PA_MIN
19:48:40.407 -> ARC     = 0
19:48:40.407 ->
19:48:40.407 ->
19:48:40.407 -> AND NOW WITH ADDRESS AAAxR  0x41 41 41 78 52   ON P1
19:48:40.474 ->  and 250KBPS data rate
19:48:40.508 ->
19:48:40.508 -> SPI Speedz  = 10 Mhz
19:48:40.541 -> STATUS      = 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
19:48:40.607 -> RX_ADDR_P0-1    = 0x0000000000 0x0000000000
19:48:40.640 -> RX_ADDR_P2-5    = 0x00 0x00 0x00 0x00
19:48:40.674 -> TX_ADDR     = 0x0000000000
19:48:40.707 -> RX_PW_P0-6  = 0x00 0x00 0x00 0x00 0x00 0x00
19:48:40.740 -> EN_AA       = 0x00
19:48:40.773 -> EN_RXADDR   = 0x00
19:48:40.773 -> RF_CH       = 0x00
19:48:40.806 -> RF_SETUP    = 0x00
19:48:40.806 -> CONFIG      = 0x00
19:48:40.840 -> DYNPD/FEATURE   = 0x00 0x00
19:48:40.840 -> Data Rate   = 1 MBPS
19:48:40.873 -> Model       = nRF24L01+
19:48:40.906 -> CRC Length  = Disabled
19:48:40.906 -> PA Power    = PA_MIN
19:48:40.939 -> ARC     = 0
19:48:40.939 ->
19:48:40.939 ->

There is some miscommunication as claimed by that post. I tried changing the pins of CE, CSN to 7,8 but the problem persisted for the receiver. I changed the power supply to the NRF using two alkaline AA batteries, but that didn't solve the problem either. I also connected a 10 μF capacitor between the power supply pins of the NRF, but no luck.
Next, I tried changing the NRF module. I used an NRF module which was working correctly as a transmitter(printing "Data Sent Message X  Acknowledge received") at 1 second, as intervals as a receiver in place, still the same problem.
Any help would oblige.
P.S: I am using Arduino clones, but they work for other purposes. The NRF's have "NRF24L01" stamped on the chip, and seem to be fine.

The radio.printDetails() information are coming from the sender or the receiver ?

According to reply #30 on the Arduino Forum thread "Simple nRF24L01+ 2.4GHz transceiver demo", radio.printDetails() is run twice: once for unintialised and a second time for initialised. This should give you two sets of results, but you've only posted one set in your question. Are both sets of results identical?

@Vincent, sorry for the incomplete information. I have updated the question. What strikes me, is that #reply #30 sets radio.setDataRate( RF24_250KBPS ); but radio.printDetails(); report Data Rate   = 1 MBPS.

@tim, sorry for the incomplete details too. I have posted both sets now. They are identical for the receiver, but STATUS, RX_ADDR_P0-1, RX_ADDR_P2-5, TX_ADDR and EN_RXADDR differ for the transmitter.

@RanjitPal About DataRate, nRF24L01 can transmit only with 1MBPS or 2MBPS, while nRF24L01+ (upgraded version) can also transmit with 250KBPS (which is useful for polluted environment or longer distance communication). This is why you can not set your nRF24L01 to a 250KBPS datarate. But it surprises me that the printDetails() command indicates the upgraded version to be honest. The pipe1 address also remains the same even if you execute openReadingPipe(1, thisSlaveAddress) which is another problem.

@RanjitPal To me, the problem might come from setRetries(3,5) (5 retries with 1ms interval) while AutoAcknowledgment (= AA) is disabled. When AA is disabled, the transmitter module automaticaly return true even if the receiver hasn't received anything. In your case, the receiver seems to receive something, but not the message Message x you have sent, since nothing is displayed on the serial monitor. Try to enabled AA, or change to setRetries(1,1).

@Vincent, I funny thing I notice is that the serial prints "Data Received" even when I dont have a transmitter connected. I mean if I just power the Arduino and the NRF for the receiver, "Data Received" is printed in the serial.

Following the Getting Started Example, it prints "radio hardware is not responding!!". Well radio.begin() returns a false.

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


text:
Writing to a specific I2C register
I am trying to write to a specific register, but value doesn't change.
Working with SenseAir Sunrise CO2:
Info from i2c guideline from sensor manufacter
https://rmtplusstoragesenseair.blob.core.windows.net/docs/Dev/publicerat/TDE5531.pdf

Measurement Period (EE) 0x96 (MSB) 0x97 (LSB)
Measurement period in seconds (range from 2 to 65534). Odd numbers
will be rounded up to nearest even number. A system reset is required
after changing configuration. Default value is 16.

And that's my code snippet
#include <Wire.h>

/* WARINING!!!
  Some wire driver implementations do not corectly implement Wire.endTransmission(false) function,
  so please check this before disable WIRE_WORKAROUND!
  For example, known "bad" implementations are: Nucleo STM32
 */
#define WIRE_WORKAROUND   (0)

#define LED_BUILTIN 2

/* Define serial EN pin */
const int       SUNRISE_EN              = 4;

/* Sunrise communication address, both for Modbus and I2C */
const uint8_t   SUNRISE_ADDR            = 0x68;

/* Amount of wakeup attempts before time-out */
const int       ATTEMPTS                 = 5;
/* It takes 25ms to write one EE register */
const int       EEPROM_UPDATE_DELAY_MS   = 25;

/* Register Addresses */
const uint8_t ERROR_STATUS             = 0x01;
const uint8_t MEASUREMENT_MODE         = 0x95;
const uint8_t METER_CONTROL            = 0xA5;

/* Reading period, in milliseconds. Default is 4 seconds */
int readPeriodMs = 2000;

void setup()
{
  /* I2C */
  /* Initialize I2C and use default pins defined for the board */
  reInitI2C();

  Serial.begin(115200);

  Serial.println("Initialization complete\n");

  change_measurement_period(SUNRISE_ADDR);

  /* Read the sensor's configs */
  Serial.println("Sensor Measurement Configurations:");
  read_sensor_config(SUNRISE_ADDR);
  Serial.println();
}

void change_measurement_period(uint8_t target) {
  /* Function variables */
  int error;

  /* Wakeup */
  if(!(_wakeup(target))) {
    Serial.print("Failed to wake up sensor.");
    /* FATAL ERROR */
    while(true);
  }

  Serial.println("Changing Measurement Period...");

  uint16_t mPeriod = 12;

  Wire.beginTransmission(target);
  Wire.write(0x96);
  Wire.write(highByte(mPeriod));      // sends MSB
  Wire.write(lowByte(mPeriod));       // sends LSB
  error = Wire.endTransmission(true);
  delay(EEPROM_UPDATE_DELAY_MS);

  if(error != 0) {
    Serial.print("Failed to send request. Error code: ");
    Serial.println(error);
    /* FATAL ERROR */
    while(true);
  }

  Serial.println("\n\n\nSensor restart is required to apply changes\n\n\n");
}

/**
 * @brief  Reads and prints the sensor's current measurement mode,
 *         measurement period and number of samples.
 *
 * @param  target: The sensor's communication address
 * @note   This example shows a simple way to read the sensor's
 *         measurement configurations.
 * @retval None
 */
void read_sensor_config(uint8_t target) {
  /* Function variables */
  int error;
  int numBytes = 7;

  /* Wakeup */
  if(!(_wakeup(target))) {
    Serial.print("Failed to wake up sensor.");
    return;
  }

  /* Request values */
  error = WireRequestFrom(target, numBytes, MEASUREMENT_MODE /* from address*/, true /* STOP*/);
  if(error != numBytes ) {
    Serial.print("Failed to write to target. Error code : ");
    Serial.println(error);
    return;
  }

  /* Read values */
  /* Measurement mode */
  uint8_t measMode = Wire.read();

  /* Measurement period */
  uint8_t byteHi = Wire.read();
  uint8_t byteLo = Wire.read();
  uint16_t measPeriod = ((int16_t)(int8_t) byteHi << 8) | (uint16_t)byteLo;

  /* Number of samples */
  byteHi = Wire.read();
  byteLo = Wire.read();
  uint16_t numSamples = ((int16_t)(int8_t) byteHi << 8) | (uint16_t)byteLo;

  /* ABCPeriod */
  byteHi = Wire.read();
  byteLo = Wire.read();
  uint16_t abcPeriod = ((int16_t)(int8_t) byteHi << 8) | (uint16_t)byteLo;

  /* Most propable that the sensor will not go into sleep mode, but to be insure...*/
  /* Wakeup */
  if(!(_wakeup(target))) {
    Serial.print("Failed to wake up sensor.");
    return;
  }

  /* Request values */
  error = WireRequestFrom(target, 1, METER_CONTROL /* from address*/, true /* STOP*/);
  if(error != 1 ) {
    Serial.print("Failed to write to target. Error code : ");
    Serial.println(error);
    return;
  }

  uint8_t meterControl = Wire.read();

  Serial.print("Measurement Mode: ");
  Serial.println(measMode);

  readPeriodMs = measPeriod * 1000;

  Serial.print("Measurement Period, sec: ");
  Serial.println(measPeriod);

  Serial.print("Number of Samples: ");
  Serial.println(numSamples);

  if((0U == abcPeriod) ||  (0xFFFFU == abcPeriod) || (meterControl & 0x02U)) {
    Serial.println("ABCPeriod: disabled");
  } else {
    Serial.print("ABCPeriod, hours: ");
    Serial.println(abcPeriod);
  }

  Serial.println("MeterControl: ");
  Serial.println("Bit [0]:" + (String)bitRead(meterControl,0));
  Serial.println("Bit [1]:" + (String)bitRead(meterControl,1));
  Serial.println("Bit [2]:" + (String)bitRead(meterControl,2));
  Serial.println("Bit [3]:" + (String)bitRead(meterControl,3));
  Serial.println("Bit [4]:" + (String)bitRead(meterControl,4));
  Serial.println("Bit [5]:" + (String)bitRead(meterControl,5));
  Serial.println("Bit [6]:" + (String)bitRead(meterControl,6));
  Serial.println("Bit [7]:" + (String)bitRead(meterControl,7));
  Serial.println(meterControl, BIN);

}

/* Initialize I2C bus and pins */
void  reInitI2C() {
  /* Initialize I2C and use default pins defined for the board */
  Wire.begin();
  /* Setup I2C clock to 100kHz */
  Wire.setClock(100000);
}

/* Workaround regarding BAD implementations of Wire.endTransmission(false) function */
int WireRequestFrom(uint8_t dev_addr, uint8_t bytes_numbers, uint8_t offset_to_read, bool stop) {
 int error;
#if (WIRE_WORKAROUND == 1)
 error = Wire.requestFrom((uint8_t)dev_addr, (uint8_t)bytes_numbers /* how many bytes */, (uint32_t)offset_to_read /* from address*/, (uint8_t)1/* Address size - 1 byte*/, stop /* STOP*/);
#else
  Wire.beginTransmission(dev_addr);
  Wire.write(offset_to_read); //starting register address, from which read data
  Wire.endTransmission(false);
  error = Wire.requestFrom((uint8_t)dev_addr, (uint8_t)bytes_numbers /* how many bytes */, (uint8_t)stop /* STOP*/);
#endif
  return error;
}

/**
 * @brief  Wakes up the sensor by initializing a write operation
 *         with no data.
 *
 * @param  target:      The sensor's communication address
 * @note   This example shows a simple way to wake up the sensor.
 * @retval true if successful, false if failed
 */
bool _wakeup(uint8_t target)
{
  int attemps = ATTEMPTS;
  int error;

  do {
    uint8_t byte_0;
    /* */
    Wire.beginTransmission(target);
    error = Wire.endTransmission(true);
  } while(((error != 0 /*success */) && (error != 2 /*Received NACK on transmit of address*/) && (error != 1 /* BUG in STM32 library*/)) && (--attemps > 0));
  /* STM32 driver can stack under some conditions */
  if(error == 4) {
    /* Reinitialize I2C*/
    reInitI2C();
    return false;
  }
  return (attemps > 0);
}

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

}

Mostly i use that code, but it's not have an snippet with writing random number in register with MSB&LSB:
https://github.com/Senseair-AB/Sunrise-Examples---Arduino/blob/master/examples/i2c/sunrise_i2c_continuous/sunrise_i2c_continuous.ino
i reset sensor hardware(physically push the reset button and toogle power from sensor) after data was written and also i wait until all bytes are written
delay(EEPROM_UPDATE_DELAY_MS);
Also i read the sensor configuration after startup, and i see that values of registers doesn't change.
Problem in function change_measurement_period
What am i doing wrong? maybe someone can help with that?

You’re not checking the error return. And you don’t appear to be resetting the system, as the documentation you quoted says you must.

it's not full code, i check the error code and it's ok.
And do the system reset, but value in register doesn't change

It helps if you share the full code. At least share all the code relevant to the question, a complete minimal viable example that demonstrates the problem. Not just a snippet.

@romkey i mostly use that code, but it's not have an snippet with writing random number in register with MSB&LSB: https://github.com/Senseair-AB/Sunrise-Examples---Arduino/blob/master/examples/i2c/sunrise_i2c_continuous/sunrise_i2c_continuous.ino

Can you make up a  minimal example that actually compiles and runs, which sets the register and then checks the register. We can't really debug "I mostly use that code" sort of stuff.

@NickGammon i added a code example that compile and runs at esp32.

My main goal was to use the opportunity to get the value compensated by atmospheric pressure.
But for this it was necessary to understand how to write in registers.
And did not understand what was the problem in the examples of code provided by the manufacturer, it did not correctly work with writing to register 2 bytes data or і did something wrong (most likely).
So I rewrote it with the help of a man from the Arduino forum, and now everything works fine.
    //Write pressure value to register BAROMETRIC_PRESSURE_VALUE
    int16_t co2Pre = 9772; //977.2 hPa

    // The wake-up is a write command to the I2C address of the sensor.
    Wire.beginTransmission(SUNRISE_ADDR);
    Wire.endTransmission();                   // ignore the return value

    Wire.beginTransmission(SUNRISE_ADDR);
    Wire.write(BAROMETRIC_PRESSURE_VALUE);
    Wire.write(highByte(co2Pre));      // sends MSB
    Wire.write(lowByte(co2Pre));       // sends LSB
    error = Wire.endTransmission(true);
    delay(50);

    if( error != 0) Serial.println( "ERROR, can't find the sensor");

  int WireRequest(byte target, byte regAddr, int numBytes) {
  // The wake-up is a write command to the I2C address of the sensor.
  Wire.beginTransmission(target);
  Wire.endTransmission();                   // ignore the return value

  // Set register address of the sensor
  Wire.beginTransmission(target);
  Wire.write(regAddr);                        // register address
  int error = Wire.endTransmission(false); // false for a repeated start

  if( error != 0) {
    Serial.println( "ERROR, can't find the sensor");
    return 1;
  }

  // Read the temperature (two bytes, representing a signed integer)
  int n = Wire.requestFrom(target, numBytes);       // request 2 bytes

  if( n != numBytes) {
    Serial.println( "ERROR, can't read data");
    return 1;
  }

  return 0;
}

    //read BAROMETRIC_PRESSURE_VALUE
    error = WireRequest(SUNRISE_ADDR, BAROMETRIC_PRESSURE_VALUE, 2);
    if(error != 0) {
      Serial.println( "Failed to write to target.");
      while(true);
    }
    msb = (byte) Wire.read();
    lsb = (byte) Wire.read();
    int16_t co2Pressure = word( msb, lsb);
    float co2PressureValue = float( co2Pressure) / 10;
    Serial.println("BAROMETRIC_PRESSURE_VALUE: " + (String) co2PressureValue);

And also working code snippets for writing registers, that need sensor restart, later i physically restart the sensor, but now do it in code.
    // The wake-up is a write command to the I2C address of the sensor.
    Wire.beginTransmission(SUNRISE_ADDR);
    Wire.endTransmission();                   // ignore the return value

    Wire.beginTransmission(SUNRISE_ADDR);
    Wire.write(MEASUREMENT_PERIOD);
    Wire.write(highByte(mPeriod));      // sends MSB
    Wire.write(lowByte(mPeriod));       // sends LSB
    error = Wire.endTransmission(true);
    delay(50);

    if( error != 0) Serial.println( "ERROR, can't find the sensor");

    //RESTART SENSOR
    // The wake-up is a write command to the I2C address of the sensor.
    Wire.beginTransmission(SUNRISE_ADDR);
    Wire.endTransmission();                   // ignore the return value

    Wire.beginTransmission(SUNRISE_ADDR);
    Wire.write(SENSOR_RESTART_SCR);
    Wire.write(0xFF);
    error = Wire.endTransmission(true);
    if( error != 0) Serial.println( "ERROR, can't find the sensor");

    Serial.println("\n\nSensor restart to apply changes\n\n");

    delay(2500); //Wait after sensor restart

As written on page 14 of the linked document (emphasis by me):

All new written data to register (EE) can be read back after a sensor reset is completed.

But it seems as if you don't reset the sensor.
You will need to wait as documented, until all bytes are written.

i reset sensor hardware(physically push the reset button and toogle power from sensor) after data was written and also i wait until all bytes are written delay(EEPROM_UPDATE_DELAY_MS);
Also i read the sensor configuration after startup, and i see that values of registers doesn't change. I use that code: https://github.com/Senseair-AB/Sunrise-Examples---Arduino/blob/master/examples/i2c/sunrise_i2c_continuous/sunrise_i2c_continuous.ino

Well, you did not show this in your question. Please add these important information by editing your question. -- However, then it is another problem.

ok.
I think that may be problem in my function of writing to register, i never to that later.

i added a full code example, maybe you see where the problem might be


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:
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:
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:
Trying to program a Led Counter Want a Led to flash every 5 minutes however it flashes twice every second (Noob)
Heres the code i've Wrote i feel like the issue lies in how ive used the if statement
int ledPinS = 13; //Classifies pin 13 as Connected to an LED
                //Flashes every second
int ledPinM = 12; //Classifies pin 13 as Connected to an LED
                //Flashes every minuite

byte seconds;

byte minutes;

  void setup() {
   pinMode(ledPinS, OUTPUT);
   digitalWrite(ledPinS, LOW);
   pinMode(ledPinM, OUTPUT);
   digitalWrite(ledPinM, LOW);
  }

    void loop() {
     while (seconds<=59){//flash every second and reset when Seconds =59
     delay(900);
     digitalWrite(ledPinS,HIGH);
     delay(100);
     digitalWrite(ledPinS,LOW);
     seconds++;
    }
 delay(200);   // flash ledPin M Once when Seconds = 59
 digitalWrite(ledPinM,HIGH);
 delay(100);
 digitalWrite(ledPinM,LOW);
 seconds = 0;
 minutes++; // add a minute
 if(minutes=5){ // if minutes = 5 flash ledPinM twice and reset
          delay(200);
        digitalWrite(ledPinM,HIGH);
        delay(100);
        digitalWrite(ledPinM,LOW);
        delay(200);
        digitalWrite(ledPinM,HIGH);
        delay(100);
        digitalWrite(ledPinM,LOW);
        minutes = 0;
    }
}

Any Help would be Appreciated.

your code is very badly formatted ... proper indentation is very important, especially for a beginner programmer

Although your code is formatted horribly, it does appear to be mostly correct.
I also  recommend making your pin numbers "const int". This tells the compiler that they cannot be changed. Otherwise you could change those values in your code accidentally.
You also have un-initialized variables. Best practice would be to declare and initialise them at the same time. E.g.
byte seconds = 0;

Props for adding comments, though. Well done there.
You need an extra equals sign in your if statement.
if (minutes = 5) {

should be
if (minutes == 5) {

Classic mistake. We've all done it. You are assigning the value of 5 to minutes instead of checking for equality. This will always return true.

Thanks so much I know I'm very new to C++ programming you've helped me a great deal thank you.


text:
Servos "jump to fixed position" at startup when powered by external power supply only, but not by board
My question is about something that is happening ONLY when I use external power supply. When I use the power from the Arduino Mega directly, there is no problem. However, I need to use an external power supply, because I need to drive 42 servos. I believe this is related to the Arduino and external power supply not being powered on at exactly the same time, which is rather difficult given that the Arduino has some boot-up time.
When I connect a single 1 of these servos to any Arduino board directly (I have tried multiple boards), everything works as expected, in the sense that when I kill power to the Arduino, the servo stops, and when restarted, the program runs again and the servo continues working from the exact same position as when stopped. There is no default or initial sentinel value that the servo "jumps" to. Here is the sketch of this circuit working just fine w/ 1 servo:

However, when I connect an external power supply this setup even with a single servo, the servo "jumps" immediately to position ~90 (which would be the middle given that it has a 0-180 range). I need external power for my real project because I have 42 such servos that I am driving. After this initial "jump to position", the Arduino program continues as normal and all 42 servos are working as expected. But this "jump to position" is very disruptive! There are various parts connected to these servos. When I power up the system, the whole thing jumps to position immediately sometimes causing some damage to the system that I have to repair manually. It is extremely painful to watch 42 servos snap to position so quickly and so much of the system move so fast as a result.
I believe this has something to do with the control wires still connected to the Arduino, but the power and ground connected to the external power supply. So if the entire system (both Arduino and external power supply) is not powered on at exactly the time, then the servos are getting power without control or control without power and the incoming voltage sets them to some initial position, either by design or by undefined behavior.
But I don't know how to wire a circuit that allows the external power exactly after the pins have been attached to the servos in the setup() function of the Arduino program, so the servos have control and power at the same time... Should I be trying to do this? How can I make sure all these servos and their control pins are all powered and attached at the same time?
Here is a rough wiring diagram of my system with only 1 servo (problem still exists):

I am using an Arduino Mega 2560 (I think rev3).
Here is the external power supply (5V 30A DC):
https://www.amazon.com/dp/B01HJA3OUG

Here are the servos:
https://www.adafruit.com/product/169
I am using the Arduino Servo library, which does work w/ these servos and my board.
I used appropriate gauge wire for the DC amperage to drive these servos. They all seem to have enough power to run after this initial "jump to position". But I really want to avoid this!
UPDATE 10/7:
I put this delay in the setup() function to give me time to plug in the external power supply at a specific point after bootup:
  // LONG DELAY WAITING FOR EXTERNAL POWER TO BE APPLIED; LED blink
  pinMode(LED_BUILTIN, OUTPUT);
  start = curr = millis();
  while (curr - start <= 10000)
  {
    curr = millis();
    if (curr - prev >= 1000)
    {
      prev = curr;
      if (state == LOW)
        state = HIGH;
      else
        state = LOW;
    }
    digitalWrite(LED_BUILTIN, state);
  }

If I put this code after the calls to attach the servo pins (i.e. servo1.attach(1), then the jump happens immediately when I plug external power supply in. If I put this code before the servos are attached, then there is no jump at first when external power supply is plugged in, but then immediately after the delay code above finishes. This tells me that the jump is happening when the control wires are attached (i.e. servo1.attach(1) is called). However, this still doesn't give me any solution... If external power supply is applied either before or after when the servo control pins are connected, it jumps!
Why do these servos NOT jump when connected w/ power from the board, but jump when connected w/ external power supply?!
This must mean that either the actual amount of external power supplied to these servos is different than the Arduino is supplying (and thus causing different behavior) or it's the fact that the power ground and control pins are not all connected at the exact same time (and thus causing different behavior).

maybe in first case, program is already running when servo gets its signal, in second case it is bypassed by power, test it without the signal 'yellow' wire in both wiring to check if it the case, if yes it is just that, if not ... I don't know

remove the arduino from the equation completely ... do an experiment ... set servo to 45 degrees before each test ... apply power to the servo with the control line disconnected --- what happens? ... do same with control line grounded --- what happens? ... do same with control line pulled high --- what happens?

your question is not about the arduino until you determine a way to stop the servo from resetting at powerup

@jsotola I will do this experiment tomorrow, but my gut feeling is this: if power is applied before Arduino program's Servos attach() the pins, then it jumps. However, if I wait for the program to boot-up, then I don't know when I can attach power in time for the program to run. I tried putting a 10 second "startup" delay, but it didn't seem to work as expected. Perhaps I put it before the pins were attached, not after... I will try all of this tomorrow. Thank you.

@jsotola I agree w/ you 100%, but I was hoping my post might be familiar to someone on here... I'm sure there are many people who have powered a handful or more of servos from an external power supply, and so might be familiar with this idea of control and power on circuits that start at different times.

you may have to programmatically switch the power to the servos ... test the idea by using a manual switch, or attaching the servo +V wire after the arduino is running

@jsotola Updated. If you have any ideas, just let me know. Thx

@francoisP Updated. If you have any ideas, just let me know. Thx

You could try to add a pulldown to the control line. The problem could be that the servo gets an "undefined" voltage before the arduino powers up and takes control (pin gets configured as output).


text:
Control D+ and D- USB lines using an arduino disconnect/connect
I am using Arduino to remotely trigger a shutter action. All is well, until I hook up a USB cable on the 4 regular USB pins. This cable runs between a Sony camera and a printer. But I can not take an image when the D+ and D- are connected.
At this moment I have a manual switch in the usb cable. It works, but I would rather have Arduino kill the line, take the image and restore the line.
I understand I can use a relay, but is there another way?
Is a TRIAC an option? How would I need to hook up the components.

triac? that is for AC. I am not an expert., but you don't want any interference on the data lines so the control circuit mut be isolated from the data lines. so a relay I guess is the only good way.

It this USB connection you're talking about doing something like PictBridge?

I would say this is better suited for electrical stackexchange. It is more about the electrical part of the USB interface and not about Arduino. I think there you will get better answers.

I thought of the triac because of it's use in a solid state relay. USB data lines are bi-directional, that's why I thought about TRIACS. My safest bett will be a 2 channel relay I guess.


text:
ESP8266 NodeMCU Lolin V3 and using Firebase to update its software OTA
I want to update software OTA on multiple of my nodemcu devices that are currently sending data to my firebase database. I found this tutorial (https://medium.com/firebase-developers/over-the-air-arduino-firmware-updates-using-firebase-part-1-3e874ad9f93e) for ESP32 and tried adapting it to work with one of my nodemcu however it writes no binary and "gives up". I am not sure why/how to modify the code further. I am currently running core 2.7.4 as upgrading does not allow me to upload code to my nodemcu.
I have attached part of my code below and output I get in serial monitor. I am able to connect to wifi, change my "updatebit", and send data to firebase so there is no issue there.

#include <Firebase.h>
#include <FirebaseArduino.h>
#include <FirebaseCloudMessaging.h>
#include <FirebaseError.h>
#include <FirebaseHttpClient.h>
#include <FirebaseObject.h>

//#include <ESP8266WiFi.h>
#include <FirebaseArduino.h>

#include "Updater.h"
#include "ESP8266WiFi.h"
#include "ESP8266HTTPClient.h"

#define FIREBASE_HOST "..."
#define FIREBASE_AUTH "..."

#define FIRMWARE_URL \
"http://..."
HTTPClient http;

void setup() {
....
}
void loop() {
  if(updatebit==1){
    updateFirmware();
  } else {
  }
}

void updateFirmware() {
  // Start pulling down the firmware binary.

  http.begin(FIRMWARE_URL);
  int httpCode = http.GET();
  if (httpCode <= 0) {
    Serial.printf("HTTP failed, error: %s\n",
       http.errorToString(httpCode).c_str());
    return;
  }
  // Check that we have enough space for the new binary.
  int contentLen = http.getSize();
  Serial.printf("Content-Length: %d\n", contentLen);
  bool canBegin = Update.begin(contentLen);
  if (!canBegin) {
    Serial.println("Not enough space to begin OTA");
    return;
  }
  // Write the HTTP stream to the Update library.
  WiFiClient* client = http.getStreamPtr();
  size_t written = Update.writeStream(*client);
  Serial.printf("OTA: %d/%d bytes written.\n", written, contentLen);
  if (written != contentLen) {
    Serial.println("Wrote partial binary. Giving up."); //content length printed in serial
monitor is 42 but 0/42 bytes are written and it says "Wrote partial binary. Giving up."
    return;
  }
  if (!Update.end()) {
    Serial.println("Error from Update.end(): " +
      String(Update.getError()));
    return;
  }
  if (Update.isFinished()) {
    Firebase.setInt("updatebit",0);
    Serial.println("Update successfully completed. Rebooting.");
    // This line is specific to the ESP32 platform:
    ESP.restart();
  } else {
    Serial.println("Error from Update.isFinished(): " +
      String(Update.getError()));
    return;
  }
}

If I add the "s" in http changing from
#define FIRMWARE_URL \
"http://..."

to
#define FIRMWARE_URL \
"https://..."

I get "HTTP failed, error: connection failed" in serial monitor

only httpCode 200 is sucess

Yes i guess so?

you have if (httpCode <= 0) {

ah I should change it too httpCode!=200

adding the s in http makes no difference now as I never get 200

yes that is the true problem. solve that

I am really not sure how. I tried only running the sketch from the link below under the heading "Fingerprints - secure but annoying" but I still don`t get HTTP_CODE_OK.
https://maakbaas.com/esp8266-iot-framework/logs/https-requests/

and what error code do you get?

-1, connection failed. I am using this tool to create the fingerprint (https://www.grc.com/fingerprints.htm). I am using ("96 84 07 DF 0B 1C F6 58 14 DF D7 33 35 57 51 9B 15 4D 8C E7"). My host is just like in example https://api.github.com

you need http.begin(client, FIRMWARE_URL); where client is  WiFiClientSecure. (what error code did you get before you changed http to https?)


text:
Can I use AREF to supply a circuit, when in internal mode? (Nano)
When analogReference(INTERNAL) is set (1.1V), can I use the AREF pin to supply a circuit? E.g. like this:
AREF —— R1 —— button switch —— A4 —— R2 —— GND

where A4 is configured as analog input (forming a resistive voltage divider with R1 and R2).
Is this safe to do? The reference manual talks about having a capacitator on AREF, or only capacitive loads.
You can find the datasheet here: see 23.2 (page 205), Figure 23-1 (block circuit diagram, page 206), and section 23.5.2 (Page 211).

probably not ... what does the reference manual say about current sourcing capacity of the pin? ... please provide a link to the reference manual ... add link to the question ... do not add in a comment

@jsotola: It says “Note that VREF is a high impedance source, and only a capacitive load should be connected in a system.”

Unfortunately the ref manual does not mention sourcing capacities.

Why do you want to do that? I would consider such usage of VREF out of spec. If you really need to do that you can use an opamp to build a voltage follower. That will preserve the voltage and also handle the direct current needed. Though I'm not sure what that does to the stability of the reference voltage (not an expert in analog signal handling)

Why not use the 5V output?

@chrisl: would you promote your comment as answer, please? Add Gils question. Good enough as answer. :-)


text:
How to use an Arduino to play audio from an Adafruit Soundboard using audio file name
I'm trying to control an adafruit soundboard with my elegoo uno R3. I'm a beginner programer and I'm trying to get the soundboard to play a sound file by name when I press a button. I have confirmed the soundboard works because it works when I run the menu program that I got from the tutorial I followed, but when I try to simplify that and transfer it to my own code something goes wrong. Here is my code:
#include <Adafruit_Soundboard.h>
#include <SoftwareSerial.h>

#define SFX_TX 10
#define SFX_RX 11
#define SFX_RST 12

int pin_a = 8;
int pin_b = 7;
int pin_c = 4;
long randNumber;
long randNumberCheck;
const int buttonPin = 2;

int buttonState = 0;
int lightLoopCount = 0;

#define NUM_SOUNDS 2
char *soundName[NUM_SOUNDS] = {
  "T00     OGG",
  "T00     OGG",
};

SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX);
Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, SFX_RST);

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

  if (!sfx.reset()) {
    Serial.println("Not found");
    while (1);
  }

  pinMode(pin_a, OUTPUT);
  pinMode(pin_b, OUTPUT);
  pinMode(pin_c, OUTPUT);

  pinMode(buttonPin, INPUT);

  randomSeed(analogRead(0));
}

void loop() {
  analogWrite(pin_a, 0);
  analogWrite(pin_b, 0);
  analogWrite(pin_c, 0);

  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  if (buttonState == HIGH) {

    sfx.playTrack(soundName[1]);

    if (!sfx.playTrack(soundName[1])) {
      Serial.print("Failed to play");
    }

    lightLoopCount = 0;
    while (lightLoopCount < 10) {
      analogWrite(pin_a, 0);
      analogWrite(pin_b, 0);
      analogWrite(pin_c, 0);

      // print a random number from 0 to 299
      randNumber = random(3);
      while (randNumber == randNumberCheck) {
        randNumber = random(3);
      }

      if (randNumber == 0) {
        analogWrite(pin_a, 255);
      }
      else if (randNumber == 1) {
        analogWrite(pin_b, 255);
      }
      else {
        analogWrite(pin_c, 255);
      }

      randNumberCheck = randNumber;

      delay(300);
      lightLoopCount++;
    }
  }
}

Here is the datasheet for the soundboard: https://www.digikey.com/htmldatasheets/production/1800160/0/0/1/audio-fx-sound-board.html
I've tried several different ways to get the board to just play a sound by filename when I press the button. Everything else works when I press the button, I think I'm just having trouble converting the string into a char array that the board can understand. It's saying "Failed to play" when I press the button. Can someone help me convert the string properly?

please add a link for the soundboard datasheet to your post ... do not add to a comment

add debugging code to your sketch ... print out the song filename ... also print the length of the filename  just to make sure of any hidden characters


text:
HC-05 Bluetooth module; two serial ports, COM4 and COM5
I'm learning how to use the Arduino HC-05 Bluetooth module. After pairing to it with my laptop I saw that I was getting two serial links, COM4 and COM5, as can be seen from the picture below.
On COM4 everything is working fine, but on COM5 nothing is happening. Can somebody explain why this is so?
NOTE: I only have one Bluetooth device (the HC-05).

You didn't include a picture in your question

your question is not arduino specific ... it belongs at https://stackoverflow.com/questions

@chrisl sorry i forgot

@jsotola i chose that because its what am working with but all in all thank you.

do both serial ports appear when the module is paired? ... this is really a windows question, that is why I suggested SO

@jsotola they do, I have tried to uninstall both of them but once I just pair to the module they both appear. Am preparing to try on Ubuntu 20.04LTS and see what happens

this seems like a distraction from your arduino learning ... maybe accept it as a quirk of windows and maybe, some day, you will stumble across an answer

I found this answer in Microsoft Technet helpful:

when connecting your terminal program to the first you are actually instructing Windows to attempt to establish the Bluetooth connection to the remote paired device, and if the connection is established the RFCOMM channel will be opened for the exchange of data
when connecting your terminal program to the second you are actually instructing Windows to load the SPP SDP record and to remain waiting for incoming connections from the remote paired device.


text:
Using arduino framework how many instances of SoftwareSerial can use simultaneously with esp32
Ussing popular library https://github.com/plerup/espsoftwareserial/ can I have multiple softwareSerial ports (for example 6 ports).
I’m the readme say  “ several instances can be active at the same time” but don’t answer a quantity just say several.
Also don’t say if the instances will operate normal or will have some issue.
Ref: https://github.com/plerup/espsoftwareserial/#readme
Will be great to read an answer from someone with experience with the this specific library and arduino framework.

what have you tried?

Third paragraph of the readme that you link to: "The same functionality is given as the corresponding AVR library but several instances can be active at the same time."

I’m voting to close this question because the question links directly to the answer...

@Majenko To be fair "several" is not a good answer to the question "how many". Do you know of any limits on the number of simultaneously listening ports (besides the needed pins)?

@chrisl "several" is the only answer that can be given. You can have more than one. How many will depend on many factors, like what baud rate your are using, how often data is being received, what else the program is doing at the same time, etc. Factors that cannot be predicted by us. So the answer is "yes you can have several" and that's as good as you're going to get.

This is not a question that has an answer. There are far too many variables to say "You can have X ports at once".
How many you can have depends on such things as:

The baud rates you are using: faster baud rates will mean more processing and thus less processing for other ports to run.
How often data is received: A port that's not receiving anything isn't using any processing. You could have lots and lots of ports, but if only one is receiving anything it's not much different to only having one port.
What else your program is doing: You have finite resources. The more you use in your program the less are available for other things. You're running an RTOS, and resources and processing are time-sliced between tasks.

You can maximise your port availability by being crafty and careful with executing certain things on each core - for example if you have two heavily used ports it could be good to have one bound to each of your two cores (assuming a dual core ESP32) so they don't interfere with each other as much.
So a quantity cannot be given. Nor can a prediction about how reliable they would be. From the way it's purported to operate, though, the quantity is likely to be "quite a few" and there should be no problems, as long as you don't have too many.


text:
`noInterrupts()` causes the arduino to no longer appear in ports
Minimal working example:
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  noInterrupts();
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

When uploaded to my Arduino Nano 3.3v BLE from my M1 Mac, this causes the Nano to no longer appear in the ports menu. In order to get it to appear again, I have to double press the reset button on the Nano so that it resets to a default script. After doing this, the Nano is available in the ports menu again.
I also cannot see the Nano via cat /dev/cu.<TAB> when this script is uploaded to it.
Does anyone know why this happens? Or alternatively (if this is intended behaviour) why it is not documented in interrupts() or noInterrupts?
I've looked through some other posts, but I don't think they're duplicates of this one:

What functions are disabled with noInterrupts()?: doesn't highlight the behaviour I've seen in the MWE.
Trying to understand interaction of interrupts, noInterrupts and delays: Gives interesting techniques for interrupts and embedded programming, but doesn't mention the behaviour I've seen

Edits in response to answers
So the MWE wasn't quite descriptive enough of my problem and some of the answers got caught up on that (which is my fault). I've included a more detailed description of what I'm doing below to describe what I'm actually doing, but I've also accepted the answer which I think answers the heart of the question "why do interrupts cause the Nano to not appear in port?".
What I'm actually doing is I've got two Arduino Nanos (call them primary and secondary) connected via I2C and Wire.h. Each Arduino nano is reading 15 analog inputs (via a multiplexer). The secondary Nano is then sending its 15 analog readings to the primary over I2C. But I'm getting a lot of noise in the analog readings of the primary Nano, but no noise in the secondary. This noise disappears when I disconnect I2C. So my theory was that digital SCL and SDA wires were causing noise in the analog sensor wires, but I observed the noise would only occur for ~2ms every ~10ms. I thought I'd disable interrupts (and therefor disable Wire.h from pulsing SCL/SDA) while I was reading the primary's analog sensors, and enable interrupts afterwards. This caused the Nano to not appear in the Ports tab, and the rest is the result of this post.
I now think I didn't include the 4.7Ohm pull-up resistor on SDA and SCL which seems to only be included on the official Arduino examples, and never on any random internet examples.

I have no idea what an MWE and you have edited your question to the point where where my answer was no longer in sync with it.

Apologies, MWE=Minimum working example.

I'm not really an expert on the Nano 3.3v BLE, however it appears that it is directly connected to the USB port and thus disabling interrupts will also disable its ability to respond to USB handshakes, thus it will appear to the host that it has been unplugged.
The original Nano had a separate chip (FT232RL) which handled the USB interface, and thus disabling interrupts on that Arduino would not drop the USB connection.

Or alternatively (if this is intended behaviour) why it is not documented in interrupts() or noInterrupts?

Probably the documentation has not kept up-to-date with later product releases. It is not uncommon for documentation to lag behind what the released products actually do.
As timemage points out in another answer, your attempts to blink LEDs with interrupts turned off will not succeed. In fact, turning interrupts off should only be done for milliseconds, not permanently. I assume that is a demonstration sketch, but still ... if you turn interrupts off only briefly the problem should go away.

Yeah, I'd tacked on the clarification about the typical time scale about two minutes before this answer came in. So it probably wasn't in there when you were composing. It's a good point about the documentation. So much of it is really oriented toward the early boards.

Thanks! Yeah the LED part of the MWE wasn't really relevant to the full problem, but you still answered the root question of why this happens. I'm gonna submit a PR to update the docs. Any idea if this is just the Nano, or if it's other boards as well?

It wouldn't surprise me if it related to the more modern boards with the new processors, however I'm not on top of which ones they may be.

@NickGammon I got rid of my answer. Their question is apparently about I2C now... or something. Not interested in chasing the redefinition.


text:
Problems in running two solenoid together at the same time
I am trying to activate two solenoids (12V/350mA, connected to a 12V/1A adaptor) at the same time using the TIP120 NPN-transistor and 1kohm resistor using the UNO board. Using a simple program,
void loop()
{
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  delay(5000);

  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  delay(2000);
}

if I am using a big LED on the pin of the board, I am able to easily blink them but the solenoid is not working?
for powering the Arduino board, I am either using USB or a 12V/1A adaptor, and both result in the same output.
the schematic of the simple connections can be found here   https://www.arrow.com/en/research-and-events/articles/arduino-solenoid-project-control-solenoid-with-arduino-board
can someone please suggest what can I do to start two solenoids at the same time?
I have tried increasing the voltage and current as well from an externally powered source as well. but it did not actuated two valves together

Could you please add a schematic to your question?

previous question about the same project https://arduino.stackexchange.com/questions/89073/controlling-multiple-solenoid-with-relay-and-arduino-and-the-process-stops-after

@Juraj yes, but the question is different. and the circuit is also different, instead of relay, I am using transistor which solved previous problem

@EdgarBonet the circuit is so simple that I don't add it here instead I have given the link. only transistor and resistor

The TIP120 is a poor choice for this application. It's a "Darlington" transistor which means it will turn your 12V into just 10.4V. You'd be better with a simple BJT or even better still a MOSFET.

@Majenko thanks for your answer, but if TIP120 is a problem then probably even 1 valve should not be working.  On the contrary, valves are working perfectly fine when used one at a time. The only problem is they are not working together. Do you really think BJT/MOSFET will solve the problem?

@RajagopalanP I didn't say it was the problem, only that it was a poor choice.

The transistor is a current device and it has a gain. There are several ways that transistor could be hooked up most of them wrong for your application. You do not post a schematic, is it possibly you do not know how to create one. Pictures do not give resistor vales and circuit configuration. There should be no trade secrets on your circuit that  I know about.

@Gil, thanks for your response. I have updated the circuit diagram in the question section. please let me know your thoughts.

@Majenko, Yes yes I get your point. I even used an external source where I increased the voltage up to 24V/1A and 15V/1.5 A but the valve did not actuate. so it seems Voltage drop might not the be the bigger problem, can you suggest something to solve this problem

It will not work as you have it pictured. The ground of the 12V must be connected to the ground of the Arduino. You can put both resistors on the same pin of the Arduino, the one that is working (probably pin 13). Staying with what you have coded would be better. Since each of the solenoids require 1A each your power supply must supply at least 2 amps.
In your code setup() you need to define each pin you will use as an output, (int ledPin = 4; int ledPin = 5;) There are other ways but that follows the example.   then use the pinmode to declare them as an output, pinMode(led1, OUTPUT);  for each pin you want to drive the transistor. Then your code will work. Look at this link for an example: https://www.arduino.cc/en/Reference.digitalWrite.
I used pins 4 and 5, no reason other then 13 blinks with the on board led when it is booting. It is pre defined as an output in the Arduino start code (you normally do not have access to that), that is why it worked.
If you elect to use a MOSFET TheSource becomes the emitter, The Drain becomes the collector and the gate becomes the gate. You would need to pick an avalanche rated one that can