message:
Seeeduino XIAO write and read PWM duration (period) using timers

I am trying to communicate between two Seeeduino XIAO (chip: ATSAMD21G18A-MU) by way of **TCC capture** using register timers.

Square wave pulse duration varies from 200ns to 4us.

I found these two code samples, and I am now trying to change them up to make them work the way I intend to read and write these short pulses.

---

**1) XIAO writing square wave (generate output)**

This code works, but it is changing the pulse width and not the pulse period. Output is on pin `D2` and `D3`. How can I make it change the polse period instead of the polse width?  [Source][6]

````
// Output 300kHz dual slope PWM on TCC0 with complementary outputs and dead time insertion
void setup()
{
  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |        // Enable GCLK0
                      GCLK_CLKCTRL_GEN_GCLK0 |    // Select GCLK0 at 48MHz
                      GCLK_CLKCTRL_ID_TCC0_TCC1;  // Route GCLK0 to TCC0 and TCC1

  PORT->Group[PORTA].PINCFG[10].bit.PMUXEN = 1;   // Enable the port multiplexer for port pins PA10 and PA11
  PORT->Group[PORTA].PINCFG[11].bit.PMUXEN = 1;

  // Select the port pin multiplexer switch to option F for TCC0/WO[2] and TCC0/WO[3] on
  // port pins PA10 and PA11 respectively
  PORT->Group[PORTA].PMUX[10 >> 1].reg = PORT_PMUX_PMUXO_F | PORT_PMUX_PMUXE_F;

  TCC0->WAVE.reg = TCC_WAVE_POL2 |                // Reverse the signal polarity on channel 2
                   TCC_WAVE_WAVEGEN_DSBOTTOM;     // Dual slope PWM on TCC0
  while (TCC0->SYNCBUSY.bit.WAVE);                // Wait for synchronization

  //  48,000,000 / 300,000 = 160
  TCC0->PER.reg = 79;                             // Set the frequency of the PWM on TCC0 to 300kHz
  while(TCC0->SYNCBUSY.bit.PER);                  // Wait for synchronization

  TCC0->CC[2].reg = 40;                           // Output a 50% duty-cycle
  while(TCC0->SYNCBUSY.bit.CC2);                  // Wait for synchronization

  TCC0->CC[3].reg = 35;                           // Output a 43% duty-cycle
  while(TCC0->SYNCBUSY.bit.CC3);                  // Wait for synchronization

  TCC0->CTRLA.bit.ENABLE = 1;                     // Enable TCC0
  while (TCC0->SYNCBUSY.bit.ENABLE);              // Wait for synchronization
}

void loop(){
  TCC0->CTRLBSET.reg = TCC_CTRLBSET_LUPD;         // Set the Lock Update (LUPD) bit
  while (TCC0->SYNCBUSY.bit.CTRLB);               // Wait for synchroniztion
  TCC0->CCB[2].reg = 40;                          // Output a 50% duty-cycle
  while(TCC0->SYNCBUSY.bit.CCB2);                 // Wait for synchronization
  TCC0->CCB[3].reg = 35;                          // Output a 43% duty-cycle
  while(TCC0->SYNCBUSY.bit.CCB3);                 // Wait for synchronization
  TCC0->CTRLBCLR.reg = TCC_CTRLBCLR_LUPD;         // Clear the Lock Update (LUPD) bit
  while (TCC0->SYNCBUSY.bit.CTRLB);               // Wait for synchroniztion
  delay(1000);                                    // Wait for 1 second

  TCC0->CTRLBSET.reg = TCC_CTRLBSET_LUPD;         // Set the Lock Update (LUPD) bit
  while (TCC0->SYNCBUSY.bit.CTRLB);               // Wait for synchroniztion
  TCC0->CCB[2].reg = 20;                          // Output a 25% duty-cycle
  while(TCC0->SYNCBUSY.bit.CCB2);                 // Wait for synchronization
  TCC0->CCB[3].reg = 15;                          // Output a 18% duty-cycle
  while(TCC0->SYNCBUSY.bit.CCB3);                 // Wait for synchronization
  TCC0->CTRLBCLR.reg = TCC_CTRLBCLR_LUPD;         // Clear the Lock Update (LUPD) bit
  while (TCC0->SYNCBUSY.bit.CTRLB);               // Wait for synchroniztion
  delay(1000);
}
````
---

**2) XIAO reading square wave (input capture); Period and Pulse-Width (PPW) Capture**

This code works, but it reads the frequency over a period of 1 second, and not just the duration of a polse period. Input is on `D6`. How can I make these changes to the code for it to work?  [Source][7]

````
// Count the number of pulses on pin D6 (PB08) over a 1 second period
void setup()
{
  SerialUSB.begin(115200);                  // Initialise the native serial port
  while(!SerialUSB);                        // Wait for the console to open

  PM->APBCMASK.reg |= PM_APBCMASK_EVSYS;    // Switch on the event system peripheral

  ////////////////////////////////////////////////////////////////////////////////////////
  // Generic Clock Initialisation

  GCLK->GENDIV.reg =  GCLK_GENDIV_DIV(1) |          // Select clock divisor to 1
                      GCLK_GENDIV_ID(4);            // Select GLCK4

  GCLK->GENCTRL.reg = GCLK_GENCTRL_IDC |            // Set the duty cycle to 50/50 HIGH/LOW
                      GCLK_GENCTRL_GENEN |          // Enable GCLK
                      GCLK_GENCTRL_SRC_XOSC32K |    // Select GCLK source as
             //    external 32.768kHz crystal (XOSC32K)
                      GCLK_GENCTRL_ID(4);           // Select GCLK4
  while (GCLK->STATUS.bit.SYNCBUSY);                // Wait for synchronization

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |          // Enable generic clock
                      GCLK_CLKCTRL_GEN_GCLK0 |      // GCLK0 at 48MHz
                      GCLK_CLKCTRL_ID_TCC0_TCC1;    // As a clock source for TCC0 and TCC1

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |          // Enable generic clock
                      GCLK_CLKCTRL_GEN_GCLK4 |      // GCLK4 at 32.768kHz
                      GCLK_CLKCTRL_ID_TCC2_TC3;     // As a clock source for TCC2 and TC3

  //////////////////////////////////////////////////////////////////////////////////////////////
  // TCC2 Initialisation - reference timer: measures a 1s period

  TCC2->PER.reg = 32767;                             // Set the period (PER) register for a
                                                     // PWM period of 1s
  while (TCC2->SYNCBUSY.bit.PER);                    // Wait for synchronization

  TCC2->WAVE.reg = TCC_WAVE_WAVEGEN_NPWM;            // Set timer to Normal PWM mode (NPWM)
  while (TCC2->SYNCBUSY.bit.WAVE);                   // Wait for synchronization

  TCC2->CTRLBSET.reg = TCC_CTRLBSET_ONESHOT;         // Enable oneshot operation
  while(TCC2->SYNCBUSY.bit.CTRLB);                   // Wait for synchronization

  NVIC_SetPriority(TCC2_IRQn, 0);    // Set the Nested Vector Interrupt Controller
                                     //   (NVIC) priority for TCC2 to 0 (highest)
  NVIC_EnableIRQ(TCC2_IRQn);         // Connect TCC2 to Nested Vector Interrupt
                                     //   Controller (NVIC)

  TCC2->INTENSET.reg = TCC_INTENSET_OVF;   // Enable overflow (OVF) interrupts on TCC2

  TCC2->CTRLA.bit.ENABLE = 1;              // Enable TCC2
  while (TCC2->SYNCBUSY.bit.ENABLE);       // Wait for synchronization

  ////////////////////////////////////////////////////////////////////////////////////////
  // TCC0 Initialisation - measurement counter: counts the number of incoming of pulses

  PORT->Group[PORTB].PINCFG[8].bit.PMUXEN = 1;               // Enable the port multiplexer
                                                             //   on port pin PB08 (D6)
  PORT->Group[PORTB].PMUX[8 >> 1].reg |= PORT_PMUX_PMUXE_A;  // Set-up PB08 (D6) as an
                                                             //   EIC (interrupt)

  EIC->EVCTRL.reg |= EIC_EVCTRL_EXTINTEO8;       // Enable event output on external interrupt 8
  EIC->CONFIG[1].reg |= EIC_CONFIG_SENSE0_HIGH;  // Set interrupt to detect a HIGH level
  EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT8;      // Clear the interrupt flag on channel 8
  EIC->CTRL.bit.ENABLE = 1;                      // Enable EIC peripheral
  while (EIC->STATUS.bit.SYNCBUSY);              // Wait for synchronization

  EVSYS->USER.reg = EVSYS_USER_CHANNEL(1) |      // Attach the event user (receiver) to
                                                 //   channel 0 (n + 1)
                    EVSYS_USER_USER(EVSYS_ID_USER_TCC0_EV_0);  // Set the event user (receiver)
                                                               //   as timer TCC0, event 0

  EVSYS->CHANNEL.reg = EVSYS_CHANNEL_EDGSEL_NO_EVT_OUTPUT |    // No event edge detection
                       EVSYS_CHANNEL_PATH_ASYNCHRONOUS |       // Set event path as asynchronous
        EVSYS_CHANNEL_EVGEN(EVSYS_ID_GEN_EIC_EXTINT_8) |  // Set event generator
        //   (sender) as external interrupt 8
                       EVSYS_CHANNEL_CHANNEL(0);               // Attach the generator (sender)
                                                               //   to channel 0

  TCC0->EVCTRL.reg = TCC_EVCTRL_TCEI0 |       // Enable TCC0 event 0 inputs
                     TCC_EVCTRL_EVACT0_INC;   // Increment the TCC0 counter on receiving an event 0

  TCC0->CTRLA.bit.ENABLE = 1;          // Enable TCC0
  while (TCC0->SYNCBUSY.bit.ENABLE);   // Wait for synchronization
}

void loop()
{
  startConversion();     // Start a conversion over the 1 second integration window
  delay(3500);           // Wait for 1 second
}

void startConversion()
{
  TCC2->CTRLBSET.reg = TCC_CTRLBSET_CMD_RETRIGGER;   // Retrigger the timer TCC2 to
                                                     //   start the integration window
  while (TCC2->SYNCBUSY.bit.CTRLB);                  // Wait for synchronization
  TCC0->CTRLBSET.reg = TCC_CTRLBSET_CMD_RETRIGGER;   // Retrigger the timer TCC0 to
                                                     //   start the count
  while (TCC0->SYNCBUSY.bit.CTRLB);                  // Wait for synchronization
}

void TCC2_Handler()
{
  TCC2->INTFLAG.bit.OVF = 1;                         // Clear the TCC2 overflow interrupt flag
  TCC0->CTRLBSET.reg = TCC_CTRLBSET_CMD_READSYNC;    // Trigger a read synchronization
                                                     //   on the COUNT register
  while (TCC0->SYNCBUSY.bit.CTRLB);                  // Wait for the CTRLB register write synchronization
  while (TCC0->SYNCBUSY.bit.COUNT);                  // Wait for the COUNT register read sychronization
  SerialUSB.println(TCC0->COUNT.reg);                // Print the result
}
````

Some helpful page explaining these timers

   https://www.picotech.com/support/topic24051.html

   https://shawnhymel.com/1710/arduino-zero-samd21-raw-pwm-using-cmsis/

  [1]: https://blog.thea.codes/understanding-the-sam-d21-clocks/
  [2]: http://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D21_DA1_Family_DataSheet_DS40001882F.pdf
  [3]: https://i.stack.imgur.com/CQVRV.gif
  [4]: https://i.stack.imgur.com/Q1Koz.gif
  [5]: https://www.youtube.com/watch?v=2FoZ7kHOdT0
  [6]: https://forum.arduino.cc/t/martinl-please-help-samd21-pwm-dti-questions-help/675541/3
  [7]: https://forum.arduino.cc/t/frequency-measurement-on-seeeduino-xiao-at-200khz/688929

body:
**1) Writing short square wave pulses to pin `D3` using Seeeduino XIAO**

[Timer setup derived from this github post][1] and [includes update suggestion][4] by MartinL.

````
void setup()  //TCC1 Timer-Setup AT-SAMD21-G18 ARM Cortex M0
{
  setupTimers();
  changePer(125);
}
void loop() {
  // testing
  changePer(20);
  delay(3000);
  for (byte i = 0; i < 15; i++) {
    changePer(40 + (i+1)*4);
    delay(1000);
  }
  delay(2000);
}

// Change Pulse Period
void changePer(uint16_t myPer) {
  TCC1->CTRLBSET.reg = TCC_CTRLBSET_LUPD;     // Set the Lock Update bit
  while (TCC1->SYNCBUSY.bit.CTRLB);           // Wait for synchronization
  TCC1->PERB.reg = myPer;                     // Set period
  while(TCC1->SYNCBUSY.bit.PERB);             // Wait for synchronization
  TCC1->CCB[1].reg = myPer/2;                 // Set duty-cycle to 50%
  while(TCC1->SYNCBUSY.bit.CCB0);             // Wait for synchronization
  TCC1->CTRLBCLR.reg = TCC_CTRLBCLR_LUPD;     // Clear the Lock Update bit
  while (TCC1->SYNCBUSY.bit.CTRLB);           // Wait for synchronization
}

// Output PWM on digital pin D3 using timer TCC1 (10-bit resolution)
void setupTimers() {
  REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) |        // Divide the 48MHz clock source by divisor N=1: 48MHz/1=48MHz
                    GCLK_GENDIV_ID(4);          // Select Generic Clock (GCLK) 4
  while (GCLK->STATUS.bit.SYNCBUSY) ;           // Wait for synchronization

  REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC |         // Set the duty cycle to 50/50 HIGH/LOW
                     GCLK_GENCTRL_GENEN |       // Enable GCLK4
                     GCLK_GENCTRL_SRC_DFLL48M | // Set the 48MHz clock source
                     GCLK_GENCTRL_ID(4);        // Select GCLK4
  while (GCLK->STATUS.bit.SYNCBUSY) ;           // Wait for synchronization

  // Enable the port multiplexer for the digital pin D3 and D11  **** g_APinDescription() converts Arduino Pin to SAMD21 pin
  PORT->Group[g_APinDescription[3].ulPort].PINCFG[g_APinDescription[3].ulPin].bit.PMUXEN = 1;

  // Connect the TCC1 timer to digital output D3 - port pins are paired odd PMUO and even PMUXE
  // F & E specify the timers: TCC0, TCC1 and TCC2
  // D2 is on PA10 = even, use Device E for TCC1
  PORT->Group[g_APinDescription[2].ulPort].PMUX[g_APinDescription[2].ulPin >> 1].reg |= PORT_PMUX_PMUXO_E;

  // Feed GCLK4 to TCC0 and TCC1
  REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN |       // Enable GCLK4 to TCC0 and TCC1
                     GCLK_CLKCTRL_GEN_GCLK4 |   // Select GCLK4
                     GCLK_CLKCTRL_ID_TCC0_TCC1; // Feed GCLK4 to TCC0 and TCC1
  while (GCLK->STATUS.bit.SYNCBUSY) ;           // Wait for synchronization

  // Dual slope PWM operation: timers countinuously count up to PER register value then down 0
  REG_TCC1_WAVE |= TCC_WAVE_POL(0xF) |          // Reverse the output polarity on all TCC0 outputs
                   TCC_WAVE_WAVEGEN_DSBOTH;     // Setup dual slope PWM on TCC0
  while (TCC1->SYNCBUSY.bit.WAVE) ;             // Wait for synchronization

  // Each timer counts up to a maximum or TOP value set by the PER register,
  // this determines the frequency of the PWM operation: Freq = 48Mhz/(2*N*PER)
  REG_TCC1_PER = 256;               // Set the FreqTcc of the PWM on TCC1 to 24Khz
  while (TCC1->SYNCBUSY.bit.PER) ;  // Wait for synchronization

  // Divide the GCLOCK signal by 1 giving  in this case 48MHz (20.83ns) TCC1 timer tick and enable the outputs
  REG_TCC1_CTRLA |= TCC_CTRLA_PRESCALER_DIV1 | // Divide GCLK4 by 1
                    TCC_CTRLA_ENABLE;          // Enable the TCC0 output
  while (TCC1->SYNCBUSY.bit.ENABLE) ; // Wait for synchronization
}
````

**2) Reading short square waves with Seeeduino XIAO pin `D2`**

It is thanks to MartinL that I got this to work. [Source][2]

````
// Setup TC4 to capture pulse-width and period on digital pin D2 on Seeeduino Xiao
volatile boolean periodComplete;
volatile uint32_t isrPeriod;
volatile uint32_t isrPulsewidth;
uint32_t period;
uint32_t pulsewidth;

void setup()   {
  SerialUSB.begin(115200);                         // Initialise the native serial port
  while(!SerialUSB);                               // Wait for the console to open

  PM->APBCMASK.reg |= PM_APBCMASK_EVSYS;           // Switch on the event system peripheral

  GCLK->GENDIV.reg = GCLK_GENDIV_DIV(1) |          // Divide the 48MHz system clock by 1 = 48MHz
                     GCLK_GENDIV_ID(4);            // Set division on Generic Clock Generator (GCLK) 4

  GCLK->GENCTRL.reg = GCLK_GENCTRL_IDC |           // Set the duty cycle to 50/50 HIGH/LOW
                      GCLK_GENCTRL_GENEN |         // Enable GCLK 4
                      GCLK_GENCTRL_SRC_DFLL48M |   // Set the clock source to 48MHz
                      GCLK_GENCTRL_ID(4);          // Set clock source on GCLK 4
  while (GCLK->STATUS.bit.SYNCBUSY);               // Wait for synchronization

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |         // Route GCLK4 to TC4 and TC5
                      GCLK_CLKCTRL_GEN_GCLK4 |
                      GCLK_CLKCTRL_ID_TC4_TC5;

  // Enable the port multiplexer on port pin PA10
  PORT->Group[PORTA].PINCFG[10].bit.PMUXEN = 1;
  // Set-up the pin as an EIC (interrupt) on port pin PA10
  PORT->Group[PORTA].PMUX[10 >> 1].reg |= PORT_PMUX_PMUXE_A;

  EIC->EVCTRL.reg |= EIC_EVCTRL_EXTINTEO10;                                // Enable event output on external interrupt 10
  EIC->CONFIG[1].reg |= EIC_CONFIG_SENSE2_HIGH;                            // Set event detecting a HIGH level
  EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT10;                               // Disable interrupts on external interrupt 10
  EIC->CTRL.reg |= EIC_CTRL_ENABLE;                                        // Enable EIC peripheral
  while (EIC->STATUS.bit.SYNCBUSY);                                        // Wait for synchronization

  EVSYS->USER.reg = EVSYS_USER_CHANNEL(1) |                                // Attach the event user (receiver) to channel 0 (n + 1)
                    EVSYS_USER_USER(EVSYS_ID_USER_TC4_EVU);                // Set the event user (receiver) as timer TC4

  EVSYS->CHANNEL.reg = EVSYS_CHANNEL_EDGSEL_NO_EVT_OUTPUT |                // No event edge detection
                       EVSYS_CHANNEL_PATH_ASYNCHRONOUS |                   // Set event path as asynchronous
                       EVSYS_CHANNEL_EVGEN(EVSYS_ID_GEN_EIC_EXTINT_10) |   // Set event generator (sender) as external interrupt 10
                       EVSYS_CHANNEL_CHANNEL(0);                           // Attach the generator (sender) to channel 0

  TC4->COUNT32.EVCTRL.reg = TC_EVCTRL_TCEI |               // Enable the TC event input
                            //TC_EVCTRL_TCINV |              // Invert the event input
                            TC_EVCTRL_EVACT_PPW;           // Set up the timer for capture: CC0 period, CC1 pulsewidth

  TC4->COUNT32.CTRLC.reg = TC_CTRLC_CPTEN1 |               // Enable capture on CC1
                           TC_CTRLC_CPTEN0;                // Enable capture on CC0
  while (TC4->COUNT32.STATUS.bit.SYNCBUSY);                // Wait for synchronization

  NVIC_SetPriority(TC4_IRQn, 0);      // Set the Nested Vector Interrupt Controller (NVIC) priority for TC4 to 0 (highest)
  NVIC_EnableIRQ(TC4_IRQn);           // Connect the TC4 timer to the Nested Vector Interrupt Controller (NVIC)

  TC4->COUNT32.INTENSET.reg = TC_INTENSET_MC1 |            // Enable compare channel 1 (CC1) interrupts
                              TC_INTENSET_MC0;             // Enable compare channel 0 (CC0) interrupts

  TC4->COUNT32.CTRLA.reg = //TC_CTRLA_PRESCSYNC_PRESC |      // Overflow on precaler clock, (rather than the GCLK)
                           TC_CTRLA_PRESCALER_DIV1  |      // Set prescaler to 1, 48MHz/1 = 48MHz
                           TC_CTRLA_MODE_COUNT32;          // Set TC4/TC5 to 32-bit timer mode

  TC4->COUNT32.CTRLA.bit.ENABLE = 1;                       // Enable TC4
  while (TC4->COUNT32.STATUS.bit.SYNCBUSY);                // Wait for synchronization
}

void loop() {
  if (periodComplete)                             // Check if the period is complete
  {
    noInterrupts();                               // Read the new period and pulse-width
    period = isrPeriod;
    pulsewidth = isrPulsewidth;
    interrupts();
    SerialUSB.print("PW: ");
    SerialUSB.print(pulsewidth);
    SerialUSB.print(F("   "));
    SerialUSB.print("P: ");
    SerialUSB.println(period);
    periodComplete = false;                       // Start a new period
  }
}

void TC4_Handler()                                // Interrupt Service Routine (ISR) for timer TC4
{
  // Check for match counter 0 (MC0) interrupt
  if (TC4->COUNT32.INTFLAG.bit.MC0)
  {
    TC4->COUNT32.READREQ.reg = TC_READREQ_RREQ |           // Enable a read request
                               TC_READREQ_ADDR(0x18);      // Offset address of the CC0 register
    while (TC4->COUNT32.STATUS.bit.SYNCBUSY);              // Wait for (read) synchronization
    isrPeriod = TC4->COUNT32.CC[0].reg;                    // Copy the period
    periodComplete = true;                                 // Indicate that the period is complete
  }

  // Check for match counter 1 (MC1) interrupt
  if (TC4->COUNT32.INTFLAG.bit.MC1)
  {
    TC4->COUNT32.READREQ.reg = TC_READREQ_RREQ |           // Enable a read request
                               TC_READREQ_ADDR(0x1A);      // Offset address of the CC1 register
    while (TC4->COUNT32.STATUS.bit.SYNCBUSY);              // Wait for (read) synchronization
    isrPulsewidth = TC4->COUNT32.CC[1].reg;                // Copy the pulse-width
  }
}
````

  [1]: https://gist.github.com/nanase/b80dea702c8933dab5bd13c6e4f9ed31
  [2]: https://forum.arduino.cc/t/attachinterrupt-12-null-high-for-external-interrupt-on-samd21g-m0/899581/2
  [4]: https://forum.arduino.cc/t/attachinterrupt-12-null-high-for-external-interrupt-on-samd21g-m0/899581/4


sender: user

message:
Timer2 and INT1 in Arduino UNO

In my project Pin 3 of Arduino UNO is as External interrupt (INT1) and at the same time, I have to run Timer2. INT1 dosen't work When Timer2 is run. Timer2 is run just as timer. Is it my mistake or it is logical?

I connect a key to pin 3 as external interrupt and also run timer. Every time INT1 on pin 3 senses rising edge Button_ISR() is called.
but because of running timer2, Button_ISR() is not called.

THis is my code:

    int buttonPin = 3;
    void setup()
    {
      pinMode(buttonPin, INPUT);
      attachInterrupt(digitalPinToInterrupt(3), button_ISR, RISING);
      Serial.begin(9600);
      TCCR2B = 0x07; // clock frequency / 1024
      //OCR2B = 0x00;  // Output compare
      TCNT2 = 0;     // Set counter 2 to zero
      TIMSK2 = 0x01; // Enable overflow interrupt

    }

    void loop()
    {

    }

    void button_ISR()
    {
      Serial.print("button_ISR()");
      Serial.print("\n");
    }

sender: assistant

body:
Here are my 2 cents:

Your code is missing the ```handler``` for the timer. You have enabled the Timer overflow interrupt, but you have ISR prepared for it. So, the control is ending up reaching unhandled interrupt ISR which is a ```Restart```

Arduino is restarting all the time.

Adding one line should fix it temporarily.

```
ISR(TIMER2_OVF_vect) {}
```

Here is the updated code. I can see that the code is now running (not restarting at least)

https://wokwi.com/arduino/projects/307835582788141632

        int buttonPin = 3;
        void setup()
        {
          pinMode(buttonPin, INPUT_PULLUP);
          Serial.begin(9600);
          Serial.println("ready!");
          TCCR2B = 0x07; // clock frequency / 1024
          //OCR2B = 0x00;  // Output compare
          TCNT2 = 0;     // Set counter 2 to zero
          TIMSK2 = 0x01; // Enable overflow interrupt
          attachInterrupt(digitalPinToInterrupt(3), button_ISR, RISING);

        }

        void loop()
        {

        }

    void button_ISR()
    {
      Serial.print("button_ISR()");
      Serial.print("\n");
    }

    ISR(TIMER2_OVF_vect) {}

_________________
Here is the disassembly code found on the Wokwi Arduino simulator for your sketch

[![enter image description here][1]][1]

and if you see the location ``` 0xf6```:
[![enter image description here][2]][2]

you will see that the code is doing a soft reset ( ```JMP 0```). I hope this is helpful to you. Please feel free to ask if you have any questions.

  [1]: https://i.stack.imgur.com/D0b0G.png
  [2]: https://i.stack.imgur.com/0oenN.png


message:
Can I just use one Arduino in a receiver/transmitter circuit?

I am trying to build a system to control lights remotely, but I am a student and am operating on a tight budget. Is there any way I can have just one Arduino along with a receiver and transmitter (I am using the 433Mhz RF Wireless Transmitter Module and Receiver Kit 5V DC 433MHZ) to do a simple on/off command for lights? I don't want to unnecessarily spend money on another Arduino (especially since I am not going to be transmitting complicated data). If this were possible, what are the other things I would need and what would the code look like?

body:
It depends on your hardware. You are not transmitting complicated data, but you need to transmit some data. Just wiring a switch to a standard RF transmitter is not enough. Though there are RF modules, which support exactly this (by having corresponding electronic components on the board). If you haven't already bought the modules, you could buy these.

If you already have bought the RF modules, you can buy a standard 433MHz key fob. They are normally rather cheap. Then you can record the key fobs signal with your receiver and write code to check for this signal in the received data.

If you plan to keep on building with Arduino, you might wanna buy directly a bunch of Arduinos (also for future projects). You can get Arduino clones directly from china for very cheap (a Nano clone for example costs normally between 1 and 2$ each in packs of maybe 10).


message:
Where to store AES key on Arduino board

I'm working with this library [AES lib][1] so everything works I can encrypt/decrypt data. But now I'd like to know what is the best way to store my `aes private key` ? My boars is a personnal board build with an `samd21 cortex M0+` my board doesn't have the possibility to connect with the extern world, like ethernet or ble, wifi.

I've only one possibility is to store the key in my program but what is the best way? Obfuscate my key? I know there is no perfect and secure solution if my key is store in my program, but what is the best solution ? Maybe is it possible to put my key when I upload my sketch in compiler option and store it in emulate eeprom?

  [1]: http://utter.chaos.org.uk/~markt/AES-library.zip

body:
All you can really do with your key is to just store it in your code. It makes no difference if that is as a `const` variable or stashed in emulated EEPROM.

The real question is not how to store it but how to stop someone reading it. Most microcontrollers (and the SAMD21 is no exception) have "code protection" facilities - settings you can enable in the chip's configuration (or "fuse") bits to prevent the flash being read by any external debugger or programmer.  By enabling these bits (check the datasheet for your chip) you will prevent people being able to read the flash containing your key no matter *how* you store it.


message:
nRF24L01 programming issue

I'm new to nrf24l01 . I have a two nrf24l01 they both works very well ,I tested them with a simple LED blinking program. Now I write a program for both transmitter and receiver to just send message and get a response for the message. Both the transmitter and receiver programs are given bellow (program works but not as I'm expected)

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

const byte CEpin=9;
const byte CSNpin=10;
RF24 radio(CEpin,CSNpin);
const byte address[][6]={"000001","000002"};
char ack[30],buf[]="hi....How are you?";
bool x;

void setup() {

  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(address[1]);
  radio.openReadingPipe(1,address[0]);
  radio.setPayloadSize(30);
  radio.setChannel(83);
  radio.setDataRate(RF24_1MBPS);
  radio.setPALevel(RF24_PA_HIGH);

}

void loop() {
  delay(4);

  radio.stopListening();

  if(radio.write(buf,sizeof(buf)))
      Serial.println("MSG sent successfully");

  delay(6);

 radio.startListening();

 if(radio.available())
 {
  radio.read(ack,sizeof(ack));
  Serial.println(ack);
 }

 }

```

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

const byte cepin=9;
const byte cspin=10;
RF24 mynrf(cepin,cspin);
const byte address[][6]={"000001","000002"};
char buf[50];
char response[]={"I'm fine"};

void setup() {

Serial.begin(9600);
mynrf.begin();
mynrf.openReadingPipe(1,address[0]);
mynrf.openWritingPipe(address[1]);
mynrf.setPayloadSize(30);
mynrf.setChannel(83);

}

void loop() {

  delay(4);

  mynrf.startListening();

  if(mynrf.available())
  {
      mynrf.read(buf,sizeof(buf));
      Serial.println(buf);
  }

  delay(6);

  mynrf.stopListening();

  if(mynrf.write(response,sizeof(response)))
      Serial.println("response sent successfully\n\n\n");

}
```
I faced a lot of troubles

1.Without delay() [delay(4);delay(6);] it doesn't work

2.With setPayloadSize() and setChannel() it doesn't work

3.I can't set data rate at 250Kbps and 2Mbps which means setDataRate(RF24_1MBPS) only works

4.setPALevel(RF24_PA_HIGH) and setPALevel(RF24_PA_LOW) only works

5.It also doesn't give output as I'm expected. I attached a screenshot of my output bellow ( COM5 is Transmitter and COM4 is Receiver)

Transmitter and Receiver serial monitor output

[![
][1]][1]

These are the issues what I'm faced. Can any one explain it .

Please any one can suggest me a best tutorials and examples for nrf24lo1 .

  [1]: https://i.stack.imgur.com/ePxEi.png

body:
Two things:

1. nRF24L01 is only half duplex. You can't send and receive at the same time. You must send only briefly and then spend some time listening for the response. With no delays there is no time to listen. It's like it's sat there with its fingers in its ears going "la la la la la" all the time.

2. You're spamming out a "response" all the time. The same situation occurs. You have two transmitters that rarely listen for anything. You should only send your response if you have received an original request.


message:
What resistor should I use when using a photo-resistor?

So I'm trying to use a photo-resistor and I learned that you should have a "fixed" resistor in the circuit. So my question is, what resistor should I have be the fixed resistor? My photo-resistor has a resistance of 18-50 KΩ at 10lux and a darkness resistance of 2.0 MΩ at 0lux.

body:
What part of the “light curve” are you interested in and what will you be connecting the LDR output / voltage divider to?

A photoresistor (LDR) that has a resistance of, say, 20k Ohms at 10 lux (which is a very low “candlelight” light level*) can have a resistance of only 100 Ohms in daylight (10.000 lux or more). Your voltage divider (input to an ADC i presume?) should be matched with the values you are interested in.

That said, if I make the assumption that you want to distinguish between daylight and darkness and you want to connect the LDR voltage divider to an ADC input on your Arduino that has the same range as your power supply (usually 5V or 3.3V), you could build the following voltage divider using your LDR and a 10k Ohm resistor (R1, your "fixed" resistor):

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/PDrlr.png)

<!-- End schematic -->

This will give you a fairly wide range of values (with higher values being brighter) and allows you (by experiment) to determine when it's time to turn the lights on, for example.

*Actually, the definition of 1 lux is the amount of light one candle generates at a meter distance, so 10 lux is the light of 10 candles.


message:
Alerting the ATMega32u4 that it's plugged into a computer (via USB)

I need help in writing some code that will allow for the ATMega32u4 to be aware of when it's plugged into a USB port. I'm not really familiar with the ATMega32 or with it's function in Arduino, so I'm lost in the dark on this one.

Update:
So in my circuit, the uC will be powered by Lithium Ion Batteries. On my PCB, their is a battery charging circuit that is powered through a USB C cable. My goal is to implement some type of firmware that can differentiate when the board is plugged into a wall outlet and a USB port on a computer. The reason for this is because I don't want the batteries to charge when the USB C cable is plugged into a laptop.

Second Update: Added pictures of the ATMega32 along with the charging circuit mentioned. I'll be the 5V voltage from USBC to charge the batteries. I'll have the data lines on the USB C cable connected so I can program the microcontroller through a USB cable. My goal here is for the microcontroller to recognize when it's connected to a computer. When this happens, I'll talk to the battery charging IC and tell it to not charge.
[![enter image description here][1]][1]

[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/jTYgR.png
  [2]: https://i.stack.imgur.com/cJs8j.png

body:
I imagine (haven't really tried it) [this](https://github.com/arduino/ArduinoCore-avr/blob/24e6edd475c287cdafee0a4db2eb98927ce3cf58/cores/arduino/USBCore.cpp#L793) would work, with some minor adaptation to match your code structure.

```c++
// VBUS or counting frames
// Any frame counting?
u8 USBConnected()
{
 u8 f = UDFNUML;
 delay(3);
 return f != UDFNUML;
}
```

The method reads the `UDFNUML` - usb data frame number lower (byte) [register](https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf), waits 3 milliseconds, which would be sufficient time get at least 1 more USB frame if the device was really connected to a USB host, reads the register again and checks if it some USB activity had happened.

Personally, I am not a big fan of busy wait delays like that because the CPU could be better utilized doing something useful in that period (3 milliseconds on a 16Mhz CPU = 48000 clocks ~= 48000 instructions)
I'd probably use 1 millisecond timer to sample the register and keep track of the USB status

An alternative would be to use the `bool USBDevice_::configured()` [method](https://github.com/arduino/ArduinoCore-avr/blob/24e6edd475c287cdafee0a4db2eb98927ce3cf58/cores/arduino/USBAPI.h#L62)
which is [implemented](https://github.com/arduino/ArduinoCore-avr/blob/24e6edd475c287cdafee0a4db2eb98927ce3cf58/cores/arduino/USBCore.cpp#L828) like so

```c++
bool USBDevice_::configured()
{
 return _usbConfiguration;
}

// Endpoint 0 interrupt
ISR(USB_COM_vect)
{
  //    ... snip ...
  else if (SET_CONFIGURATION == r)
  {
   if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT))
   {
    InitEndpoints();
    _usbConfiguration = setup.wValueL;
   } else
    ok = false;
  // ... snip ....
}
```

Hopefully one of the two approaches work for you...


message:
Pull more than 250 mA from powerbank-powered Teensy 3.6

I'm using a powerbank speced 5V at 2.4A to power my Teensy 3.6 via the USB port. However, Teensy recommends to not pull more than 250 mA from its 3.3V pin.

Is there any way I can pull more current, at either 3.3V or 5V, without splicing the USB cable? I will use it to control WS2812(b?) LEDs.

body:
The Teensy 3.6 breaks out the USB input power on the VUSB pin (labeled on on the back).

This is the raw 5V in from the USB connector before it feeds the 3.3V voltage regulator.

See the schematics at the bottom of [this page][1]

  [1]: https://www.pjrc.com/store/teensy36.html#tech


message:
How to use this specific arduino shield

I am trying to understand how to wire this Arduino Uno shield properly.

**My goal/main questions:** I have 6 servo motors and I am trying to wire them properly to this shield. Do I need an external battery pack? If yes, how do I wire that? I need all the wiring details because I cannot find information about this shield anywhere.

I've provided an actual photo of the shield and I even made a schema for you guys, if somebody wants to draw. I bought this arduino + servos + shield from aliexpress and there wasn't any documentation, explanation, schema or anything like that for that specific shield.
[![enter image description here][1]][1]
[![enter image description here][2]][2]
[![enter image description here][3]][3]

  [1]: https://i.stack.imgur.com/62KUA.png
  [2]: https://i.stack.imgur.com/ygc9S.jpg
  [3]: https://i.stack.imgur.com/FbrVU.jpg

Useful info:
- Servos are MG996.
- 4 motor && 16 servo board - name of the shield
- http://doit.am - website of the maker
- https://github.com/SmartArduino/SZDOITWiKi/wiki/Module-Preface - An incredibly cramped and unclear github that the maker provided for more info but it's yet again, unclear.

Conclusive question: Do I even need this shield at all? Can I just use a regular UNO to be able to freely operate with 6 servos?

------
CODE UPDATE:

    #include <Servo.h>

    Servo myservo;

    void setup() {
      myservo.attach(2);
    }

    void loop() {
      myservo.write(0);
      delay(1000);
      myservo.write(90);
      delay(1000);
    }

body:
> Do I even need this shield at all? Can I just use a regular UNO to be able to freely operate with 6 servos?

You don't really need this shield for 6 servos. The standard servo library supports 12 servos on the Uno by using a hardware timer. In your case the shield would mainly help with

- Freeing up the hardware timer (in the case you need it)
- Providing a dedicated power line to the servos (since the current for the servos should not run through the Arduino)

If that is enough for you to still use the shield, you can absolutely do that.

>  I need all the wiring details because I cannot find information about this shield anywhere.

If you look at the wiki (whose link you provided) and navigate to the [page for this shield][1] you will see this diagram

[![enter image description here][2]][2]

- The servos are connected to the header names "16 road servo", each having the pins (from top to bottom in the image) PWM signal, positive power and ground.

- At the header marked "insert short circuit module" you can use jumpers to select the handling of the power supply, which you connect left to that to the terminals marked supply power. It is not described clearly there, but I would read the following meaning:
  - The VM terminal is used for the motor voltage. You might choose to provide your motors with a different voltage than 5V. If you set the jumper between VM and Vin you can connect that power input to the Vin input of the Arduino, thus powering it from the same power source as the motors (Vin goes to the Arduinos voltage regulator to get the voltage down to 5V). If your power supply is still just 5V, you should leave the jumper out and connect the power supply directly to the VM input (and of course also its ground).
  - Vs should be the power input for the logic circuit of the shield. If you put a jumper between the pins Vs and +5V, you will connect the power of the logic circuit on the shield to the 5V line of the Arduino. I would suggest doing that, because then you don't need to provide Vs from outside.

The other headers are for DC motors and for different modules, which can be connected.

> Do I need an external battery pack?

Here it is important to know, how you are powering the Arduino and how much current the servos need. [This datasheet of the MG996][3] states a stall current of 2.5A, way too much for the Arduino to handle and also way to much for any normal USB port (which will give you up to 500mA). As stated above, you should never run that much current through the Arduino. Provide the motors with power from a power source capable of providing the needed current (+ some headroom). If that is a battery pack or a power supply connect to mains is up to you.

  [1]: https://github.com/SmartArduino/SZDOITWiKi/wiki/2-4ch-DC-motor-&-16ch-servo-shield---motor-and-servo-shield
  [2]: https://i.stack.imgur.com/ftRrq.jpg
  [3]: http://www.electronicoscaldas.com/datasheet/MG996R_Tower-Pro.pdf


message:
How Much mA dropped in ESP8266-01 Work in LiPo Battery if the WIFI function is continuously on

I working on the system where ESP8266-01 should continuously on because I want to get the Wi-Fi function on. In that case ,I can't use the Sleep mode which is given in the Esp8266-01 . So, My Question is that "How much will current(mA) dropped if the esp8266-01 continuously on in 4.2 LiPo battery??

body:
**The short answer** is - we don't know.

**Longer answer**:
It depends on such factors as:
1) The board circuit (the BBBL (known as The Big Bright Blue LED) on some boards could drain about 10-20ma only by itself)
2) The voltage regulator efficiency
3) The battery controller circuit / quality / keying efficiency.

**The reasonable value** is about 170-220 mA (taken [from the PDF][1], section 5.2) for continuous data transfer.

[![enter image description here][2]][2]

**The true solution is**:
Take the ammeter, connect it *in series with the battery* and measure.

  [1]: https://www.espressif.com/sites/default/files/documentation/0a-esp8266ex_datasheet_en.pdf
  [2]: https://i.stack.imgur.com/wlcVO.png


body:
If you really don't sleep at all you can count with about 70 mA, with some short spikes when transmitting.

Sleep mode disabled:

[![No sleep][1]][1]

(100 mA per division)

But you **don't need to disable sleep mode** completely to use Wifi, you can be in Auto Light Sleep, which I think is the default for Arduino, Non-OS and RTOS.

Auto Light Sleep:

[![Auto Light Sleep][2]][2]

(100 mA per division)

The Wifi will automatically wake up to transmit and it will also wake up according to the Access Points DTIM interval to receive (usually every 300 ms). You're looking at about 2 mA baseline consumption plus the Wifi send and receive spikes.

Unfortunately after bootup there is a 10 second interval with full 70 mA consumption before the Auto Light Sleep mode kicks in. That's a significant drain if you have frequent system resets, but it might have been a bug that has been fixed in the meantime. (I took those measurements in 2017 with the Arduino SDK.)

There are [other modes](https://blog.creations.de/?p=149), but these were the ones that matter in your case.

  [1]: https://i.stack.imgur.com/2W10Y.jpg
  [2]: https://i.stack.imgur.com/B1xtU.jpg


message:
Assign static IP and set host name

Im trying to assign a static IP to my ESP32 and also set the host name.
I am able to get one or the other to work, but not get them to **work together**.

Tried moving around WiFi.hostname & WiFi.config in the code, tried WiFi.begin and then setting hostname & IP

    #include <WiFi.h>
    void setup() {

    IPAddress local_IP(192, 168, 1, 100);
    IPAddress gateway(192, 168, 1, 1);
    IPAddress subnet(255, 255, 255, 0);
    IPAddress primaryDNS(208, 67, 222, 222);
    IPAddress secondaryDNS(208, 67, 220, 220);

    WiFi.mode(WIFI_STA);
    WiFi.hostname("ESP");
    WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
    WiFi.begin("xxxx", "yyyy");

    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    }
    }

**question in a question:**
The WiFi.config that that gives me a static IP is in the format local_IP, gateway, subnet, primaryDNS, secondaryDNS but the documentation for WiFi.config 2 (and also looking at the library WiFi.h code) is ip, dns, gateway, subnet.

and according to the documentation this should also work, but doesn't WiFi.config (ip)

body:
There is no such thing as a hostname associated with a specific device.

* When you request an IP from your router using DHCP the ESP32 has the option (which it uses) to tell the router what it'd like to be called. The router may, if it chooses, decide to inject that name into DNS lookups done through the router to resolve that allocated IP address.
* You can manually "advertise" a name through the mDNS protocol which requires the inclusion and use of another library and some more configuration in your sketch, along with mDNS support in the devices and applications doing the name lookup (it is getting more universally implemented but is by no means certain to be available).

Since you're not using either DHCP to obtain your IP, nor using mDNS to advertise your name, there is no mechanism that exists to magically make your device have a "name" on your network.

The simplest method to "get around" the issue is to just use DHCP and let your router do all the work. If you really want a static IP address then configure your router to provide a static IP address to your device.


message:
3th time blown à Nano every

Like subject all ready telling you, I blew up my 3th Nano every.

I mounted them on a perf board, soldered with 99% tin 1.0mm and a Flux, cleaned with flux remover, etc... When I then power them up through USB I have a short on pin 29 and 30 (Vin Gnd). And the board is ready to go directly in the poubelle (the garbage thing).

Second and third time, after soldering I scratched the space between both pins to make sure there is no connection. But...
Yip again. Is this a common issue? Am I overseeing something?

Did my measurements with multimeter. No shorts.

[![pins][1]][1]

[![board][2]][2]

[![layout][3]][3]

[![pinout][4]][4]

  [1]: https://i.stack.imgur.com/Xnj0X.jpg
  [2]: https://i.stack.imgur.com/sqUIT.jpg
  [3]: https://i.stack.imgur.com/JU1su.jpg
  [4]: https://i.stack.imgur.com/OYGoN.png

body:
If i am not wrong you have soldered nano directly to the  perf board, which i don't recommend at all. You could try soldering a female strip pin on to the pref board and insert the nano board in the strip pin. This way you could easily remove/install the board easily as you wish.
[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/ZVlGA.jpg


message:
Can I use an arduino as an interface to pass files between a device and a PC?

Or maybe you guys can point me towards another direction...

You may ask, why not connect the device directly to the PC?

Well, the device is designed to recognize only USB sticks, and dump the data into them, so I cannot just plug my PC into it and retrieve the data (as far as I know...), because the PC acts as a USB host (I think).

So I thought about using an arduino and make it act as a USB stick, and then pass the data from the arduino to the PC.

Is this possible? Or maybe what I need is a raspberry pi?

Every suggestion is welcomed. Thank you in advance!

body:
You have a device that saves information to a USB stick, is that right? Like a scanner or some sort of temperature logger?

To emulate a USB stick would be quite a task, because what you would have to do is pretend that you have a file system, as your device will be opening files, writing to them, and closing them.

It sounds like a lot of work - it might be easier to get another device that actually logs to something like a serial port.

Having said that, it seems on the face of it to be a reasonable request. Just as an example, I have a scanner that writes to a USB stick. It would be handy to have it send files directly to my PC without having to move the USB stick around all the time.

See [Make a computer act as a virtual USB device for other equipments](https://unix.stackexchange.com/questions/120368/make-a-computer-act-as-a-virtual-usb-device-for-other-equipments/401518#401518) as an example of a similar question, with answers suggesting that it might be possible, for example USB-USB cables.

Even if you got it to work, it might be tedious to use. For instance, if your gadget appends to some file on what it thinks is a USB stick you would have to emulate that file system, and then check on your PC if the file has got larger, and thus have new data on it.

Plus possibly the expense (and time) involved in getting this working might be more than just getting another gadget that actually logs via some sort of port, like serial or RS485.


message:
Is there an Apple Silicon (M1) driver for CH34x devices?

I just migrated to a new computer running on an M1 CPU (the new Apple Silicon, arm64 based). I've been searching for CH34x drivers for my TTGO-Lora32 board, but can't find any around, nor can I find mentions of them existing or not. The x86_64 driver installs, but obviously can't run due to it being an incompatible architecture.

Thus, is it currently possible to use a CH34x based board on an M1 Mac?

body:
As it turns out, I found in the following post:

https://github.com/LilyGO/LILYGO-T-OI/issues/3#issuecomment-907645945

a link to a particular build of the CH340 drivers that is properly signed and can be installed on the M1 mac with no troubles.


body:
So they pushed a new version to GitHub late september:

https://github.com/WCHSoftGroup/ch34xser_macos

This should be the maintained version ahead of what they offer as a download on the official website.

Common other issues:

- When reinstalling, make sure to first remove all old files:
```
sudo rm –rf /var/db/receipts/*CH34xVCPDriver*.*
sudo rm -rf /Library/Extensions/CH34xVCPDriver.kext
```
also don't forget to check for any related files in `/dev/` and the .app file in your applications folder if these already exist.

- Restart the device before reinstalling.

- Restart the device after installation.

- Try a different USB-Cable / USB-Hub.

Note: steps listed here were reportedly solutions I came across during my research which worked for other people and my colleagues. <s>For me it still doesn't work; but I am using a lot of unstable builds for my OS and other software that might interfere.</s>

**Update February 2022:** Now with Monterey out of closed Beta this works like a charm for me. At least for the Web IDE.


body:
After hours of mindless reinstalling of the drivers on M1, reboots and other magic tricks, I almost decided to switch to windows to make my arduino ide work. My NodeMCU board with CH340G would either show up as a serial port or not.

So I leave this message here as clearly many people struggling with M1 end up on this page: buy good microUSB cable. And I mean a good one. All problems disappeared right away. I had three cables at home but none was working - clearly most are only good for charging the phone, but suck at data transfer.


message:
How to control multiple servo motors at the same time with protothreading using an I2C PCA9685 PWM board?

I'm trying to use protothreading to control two (and eventually four) servo motors over I2C using a PCA9685 PWM board.

To start, I am simply trying to sweep the two motors back and fourth at the same time.

Here is the code I am using:

```
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

#include <protothreads.h>

#define SERVOMIN  150
#define SERVOMAX  600
#define USMIN  600
#define USMAX  2400
#define SERVO_FREQ 50

int servo1 = 0;
int servo2 = 4;

////////////////////////     T H R E A D    1     /////////////////////////

pt ptServo1;
int Servo1Thread(struct pt* pt){
  PT_BEGIN(pt);
  for(;;){
    for (uint16_t microsec = USMIN; microsec < USMAX; microsec++) {
      pwm.writeMicroseconds(servo1, microsec);
    }
    PT_SLEEP(pt, 500);
    for (uint16_t microsec = USMAX; microsec > USMIN; microsec--) {
      pwm.writeMicroseconds(servo1, microsec);
    }
    PT_SLEEP(pt, 500);
  }
  PT_END(pt);
}

////////////////////////     T H R E A D    2     /////////////////////////

pt ptServo2;
int Servo2Thread(struct pt* pt){
  PT_BEGIN(pt);
  for(;;){
    for (uint16_t microsec = USMIN; microsec < USMAX; microsec++) {
      pwm.writeMicroseconds(servo2, microsec);
    }
    PT_SLEEP(pt, 500);
    for (uint16_t microsec = USMAX; microsec > USMIN; microsec--) {
      pwm.writeMicroseconds(servo2, microsec);
    }
    PT_SLEEP(pt, 500);
  }
  PT_END(pt);
}

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

void setup() {
  Serial.begin(9600);
  PT_INIT(&ptServo1);
  PT_INIT(&ptServo2);
  pwm.begin();
  pwm.setOscillatorFrequency(27000000);
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates
}

void loop() {
  PT_SCHEDULE(Servo1Thread(&ptServo1));
  PT_SCHEDULE(Servo2Thread(&ptServo2));
}

```

I am noticing that Servo 1 turns to -90 and stops. While it has stopped, Servo 2 turns to -90 and then stops....then Servo 1 turns to +90 and stops and so on. They are not doing the sweeping at the same time.

Any help would be greatly appreciated!

Thank you,

H

body:
Without knowing Protothread in detail: It is most likely handling the threadchange during `PT_SLEEP()`, which you are only executing after one "sweep" (one of the inner for loops), not giving any opportunity to change to the other thread.

Additionally this way you don't have any delay in the inner for loops, thus they get executed very fast. Faster than the motor really can follow. This means, that the servo just moves to the end position as fast as it can and the for loop is essentially useless. You need a delay inside the inner for loops for slowing the signal down.

Please try something like this:

    pt ptServo1;
    int Servo1Thread(struct pt* pt){
      PT_BEGIN(pt);
      for(;;){
        for (uint16_t microsec = USMIN; microsec < USMAX; microsec++) {
          pwm.writeMicroseconds(servo1, microsec);
          PT_SLEEP(pt, 50);
        }
        PT_SLEEP(pt, 500);
        for (uint16_t microsec = USMAX; microsec > USMIN; microsec--) {
          pwm.writeMicroseconds(servo1, microsec);
          PT_SLEEP(pt, 50);
        }
        PT_SLEEP(pt, 500);
      }
      PT_END(pt);
    }

Change the sleep time in the inner loop according to your wanted sweep speed.


message:
Mini Arducam module camera shield - 2MP ov2640 interface with Arduino Uno

[MINI ARDUCAM MODULE CAMERA SHIELD - 2MP OV2640](https://robu.in/product/arducam-mini-module-camera-shield-with-ov2640-2-mp-lens-for-arduino/)

[Arducam Multi-camera adapter board for Arduino SPI Mini Camera](https://robu.in/product/arducam-multi-camera-adapter-board-for-arduino-spi-mini-camera/)

I have the above two components with me along with ARDUINO UNO R3.
I want to stream video using these. ARDUCAM provides library for this.

[**ARDUCAM LIBRARY**](https://github.com/ArduCAM/Arduino)

[**ARDUCAM DATASHEET**](https://www.arducam.com/downloads/shields/ArduCAM_Camera_Shield_Software_Application_Note.pdf)

When I have chosen example program **ArduCAM_Shield_V2_Video_Streaming** and tried uploading it to Arduino it showed no ***ArduCAM.h: No such file or directory***.

[![enter image description here][1]][1]

I have downloaded the library and kept it in the libraries folder of ARDUINO.

Can someone help me out with this??

  [1]: https://i.stack.imgur.com/jsFbr.png

body:
The Uno which you mention has 2 KB of RAM. 2 MP of data would be 2,000,000 x 3 bytes (red, green, and blue), in other words 6 MB.

The screenshot you showed seems to show that the library is designed to take a still photo and buffer it. As you might imagine, buffering 6 MB would take a while, especially as you can only fit 2 KB at a time.

You simply won't be streaming video using the Uno, so the error message is more-or-less irrelevant.

It might be relevant if you actually wanted to take single photos and send them.

In that case, you probably haven't installed the library properly.


message:
SIM808 does not support SSL related AT commands

1. I am using a SIM808 module. It's working fine with normal MQTT over TCP, but does not work when trying secured MQTT.

2. I sent `AT+SSLSETROOT="C:\USER\HENRY_SSL.CRT"` to set the root certificate (see this document: "SIM800 Series_MQTT_Application Note_V1.03"). The response I'm getting from the GSM is: `+CME ERROR: unknown`.

3. When I try `AT+SMSSL=1`, I get the same error. I checked with HTTP commands and it's working fine, but the `AT+HTTPSSL=1` command does not work. The SIM808 does not respond to SSL related commands.

But as per the Simcom website, the SIM808 does support SSL. Do I need to upgrade any firmware?

body: I updated the firmware version: 1418B05SIM808M32. Now all commands are working fine.


message:
Mixed SHARP IR Sensor Readings

I'm using the GP2Y0A21YK Sharp IR Sensor in a ball and beam system where I'm trying to balance the ball in the center of the beam using the IR Sensor as a distance locator and a servo motor to tilt the beam. I'm using a PID Controller for the system. However, something odd happens when I apply the code. When the servo motor is disconnected, I'm getting accurate readings of the location of the ball. However, as soon as I plug in the servo motor, the distance reading is completely off and inaccurate. I've read that powering the Arduino using both the USB port and Plug will make the readings more stable. However, I've tried that and it only improved the readings by a small bit. What can be causing this problem? Since the code and the schematic would take a bit of a space, kindly let me know if they are needed and I'm happy to provide.

body:
It is likely your power source supplies insufficient current to power both the servo and the Arduino reliably.

It is also possible that the motor in the servo is creating noise on the power rails and inducing unexpected behavior in the Arduino.  But the former is more likely.

Consider using a power source which can supply more current.  For instance, [D size cell][1] batteries can supply much more current than a [small 9 volt battery][2].

Also consider using a separate power source for the Arduino and the motor.  Many resort to this option for such projects as you describe here.

  [1]: https://en.wikipedia.org/wiki/D_battery
  [2]: https://en.wikipedia.org/wiki/Nine-volt_battery


message:
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.
[![enter image description here][1]][1]

and this is for esp32 wroom
[![enter image description here][2]][2]

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.

  [1]: https://i.stack.imgur.com/hwHMP.jpg
  [2]: https://i.stack.imgur.com/NKEab.jpg

body:
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


message:
Bi-directional UART communication on single data wire, possible?

The nano is inside of the house, and the pro mini is outside of the house. I want to send/receive text between them. The communication will be always nano sending text to mini, and then mini sending text to pro in response. There will be no case where mini sends text on its own first.

The line has three wires, but since I have to power the mini with that line, one is used for VCC and another is used for ground, leaving only one wire free. It this case, can I do UART communication between the two? If so, how should I connect the wire to them (including the ground)? And on the software side, how should I handle the communication? Could you give a simple code example in which nano sends "Hello" to pro mini, and then pro mini, after receiving "hello", sends "World" to nano?

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/VJr2c.png

body:
This question likely suffers from the [X Y problem][1].  Where the question (about software) and possible answer (centered on hardware) do not approach the solution using the same methods.

The question is essentially asking how to design a [1-wire][2] interface over longer than normal distances. There are [1-wire Arduino libraries][3] and [1-wire Arduino tutorials][4]. But it is likely you will run into problems if your cable is very long.

Guessing at the distance you want to run your 3 wires (power, ground and data), this may be more an electrical engineering than a software problem.

**Power:**

All wires have resistance.  Using a voltage drop calculator from [here][5] we can calculate, assuming we are trying to send 5V over an 18 AWG copper wire 100 meters long to a 250mA load, an expected voltage drop of slightly over a volt.  That may cause unexpected results.

[![enter image description here][6]][6]

If this might be an issue, consider an alternate power source such as batteries, solar power or a second mains power adapter for the far Arduino.  It may even be considered to over drive the power lines several volts and regulate the voltage at the far end Arduino.

**Data:**

Reference to ground type data transmission is more susceptible to error the longer the cable run.  Several options to mitigating unexpected behavior can be made.  However switching over to a balanced pair is usually the best option.

**Options:**

If you are willing to power the far Arduino independently or add 1 additional data wire (either of these options will make available 2 wires for data) we can run the data portion of the cable for a good distance while mitigating noise problems associated with long communication cable runs.

**Try RS485:**

Consider using an [RS485][7] hardware interface at the near and far Arduino.  RS485 interfaces can be source easily for Arduino projects ([here][8] and [here][9] are two examples) and there are [Arduino RS485 software libraries][10] which handle the communications.

The intent of the project was not disclosed in the question.  However [here][11] is an example RS485 project where connected Arduinos communicate the position of a potentiometer such that the RS485 connected Arduino at the far end can mimic the potentiometer's movements on a motor driven servo.

The keen eye may note that the above project only uses 2 wires between the two Arduinos.  This is possible because in the above project the two Arduinos are independently powered (this is not seen in the diagram on the linked to web page).  Additionally, RS485 uses a balanced pair of signals (the 2 wires) and does not need to run an additional ground between the two Arduinos as a reference to detect the difference between 1s and 0s.

  [1]: https://en.wikipedia.org/wiki/XY_problem
  [2]: https://en.wikipedia.org/wiki/1-Wire
  [3]: https://www.arduino.cc/reference/en/libraries/onewire/
  [4]: https://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html
  [5]: https://www.rapidtables.com/calc/wire/voltage-drop-calculator.html
  [6]: https://i.stack.imgur.com/SGoJu.png
  [7]: https://en.wikipedia.org/wiki/RS-485
  [8]: https://www.sparkfun.com/products/10124
  [9]: https://www.dfrobot.com/product-1024.html
  [10]: https://github.com/arduino-libraries/ArduinoRS485
  [11]: https://create.arduino.cc/projecthub/maurizfa-13216008-arthur-jogy-13216037-agha-maretha-13216095/modbus-rs-485-using-arduino-c055b5


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

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/93mZ7.png)

<!-- End schematic -->

Here, TX is the transmit pin of the Arduino, and DATA is the data wire.
The RX pin is connected directly to the data wire and, while writing
your sketches, you should account for the fact that anything you send
will be received back by the sender as an “echo”.

This scheme will slow down your signal transitions, limiting the maximum
achievable baud rate. Start with something conservative, like
9600 bps, and lower further if it doesn't work reliably.

[open-collector]: https://en.wikipedia.org/wiki/Open_collector


body:
An example of protocol using a single wire (besides ground, so a total of 2) for both bi-directional communication AND power: [Dallas 1-wire][1]

There are few other similar standard protocols and you are free to think about your own as long as you are willing to implement all the internals instead of using a well-written and widely used library.

  [1]: https://en.wikipedia.org/wiki/1-Wire


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


message:
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++
// 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;
    }
  }

}
```

body:
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.

```lang-cpp
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
    }
  }

}```


body:
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.


message:
MPU6050 Arduino Jeff Rowberg library interrupt Issue

I was trying to get the data from MPU6050 using the Arduino library mentioned [here][1].

The following code is an edited version of the sample code given in the library folder which seems to be working fine.

```
#define printfloatx(Name,Variable,Spaces,Precision,EndTxt) { Serial.print(F(Name)); {char S[(Spaces + Precision + 3)];Serial.print(F(" ")); Serial.print(dtostrf((float)Variable,Spaces,Precision ,S));}Serial.print(F(EndTxt)); }//Name,Variable,Spaces,Precision,EndTxt

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

#include "Wire.h"

MPU6050 accelgyro;
MPU6050 mpu;

I2Cdev a;

/*
    IMU Zero variables
*/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}

```

Then I have activated the input capture pin to use with the interrupt and the code is as follows

```
#define printfloatx(Name,Variable,Spaces,Precision,EndTxt) { Serial.print(F(Name)); {char S[(Spaces + Precision + 3)];Serial.print(F(" ")); Serial.print(dtostrf((float)Variable,Spaces,Precision ,S));}Serial.print(F(EndTxt)); }//Name,Variable,Spaces,Precision,EndTxt

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

#include "Wire.h"

MPU6050 accelgyro;
volatile MPU6050 mpu;

I2Cdev a;

/*
    IMU Zero variables
*/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  delay(2000);

  timer4_initialization();

} // setup

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

```

Here when I am using with the interrupt I am not getting anything printed, seems like the program is frozen somewhere in the interrupt -> function call.

What is the mistake I am making here.

How to take the measurement from MPU6050 using ISR routines.

  [1]: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050

body:
The functions `mpu.dmpGetCurrentFIFOPacket(fifoBuffer)`, etc, are using I2C for getting the data. The I2C interface on the Uno and Mega (which you tagged your question with) is implemented in hardware and needs interrupts for handling the data bytes (taking the received byte out of the register or writing data to the register for sending).

By default interrupts are disabled inside of an ISR. Thus the mentioned functions cannot execute correctly. They are waiting for an interrupt, which is never going to happen, since the functions are executed while interrupts are disabled.

It is possible to reactivate interrupts in an ISR, but that is something, that you should only do in a few situations and only, when you know exactly, what you are doing.

Instead you should just set a volatile flag variable inside the ISR. In the main code (in `loop()`) you can then check for that flag, execute the I2C code when it is set and reset the flag afterwards. And you can then also just print, when there is new data instead of every loop iteration. So somewhat like this:

    volatile byte timer_flag = 0;

    ISR(TIMER4_CAPT_vect) {
      timer_flag = 1;
    }

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


body:
I've tweaked chrisl's answer to show how to copy the ISR data and reset the ISR flag  in an atomic manner.

```cpp
volatile bool isr_timer_flag = false;
volatile uint32_t isr_counter = 0;  // Added to demonstrate how to copy a multibyte data type atomically.

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

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

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

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

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

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

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

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


message:
So many missed bytes with serial comm

I have a setup with serial comm from Raspberry Pi to Arduino. It's communicating at baud 9600 on both devices, and from Raspberry Pi 3b+ GPIO-14,UART0,TX0 to Arduino Nano RX0. There's a level shifter in between setup [as recommended by AdaFruit tutorials][1]. I'm sending data from Raspberry Pi as such:

```py
#loop here
m = []
m.append(255)
m.append(i) // index value between 0-150
m.append(p[0][i]) // value between 0-254
m.append(p[1][i]) // value between 0-254
m.append(p[2][i]) // value between 0-254
#print statement here
'''
Data: [255, 94, 0, 0, 0, 255, 95, 254, 0, 0, 255, 96, 0, 254, 0]
...
'''
```

And receiving data on Arduino as such:

```c
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    byte inChar = (byte)Serial.read();
    sprintf(printString, "Received: %d", inChar);
    Serial.println(printString);
  }
}
/*
Received: 255
Received: 94
Received: 0
Received: 255
Received: 95
Received: 254
Received: 0
Received: 255
Received: 96
Received: 0
Received: 254
Received: 255
Received: 94
Received: 0
Received: 0
Received: 0
Received: 255
Received: 254
Received: 255
...
*/
```

Any idea why there are so many missed bytes and how to fix this?

  [1]: https://learn.adafruit.com/neopixels-on-raspberry-pi/raspberry-pi-wiring

EDIT: @juraj There is a ground between both. I've measured with a portable oscilloscope. I can post the picture of the setup tomorrow.

@Edgar Bonet The loop function is empty, and looks as follows:

```c
void loop() {
}
```

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

body:
Without the full codes, we can only guess. My guess would be the serial
receive buffer on the Arduino is overflowing.

One reason this could happen is if `serialEvent()` is not called
frequently enough. This function is called by the Arduino core on every
loop iteration, just after `loop()` returns. If your `loop()` takes too
long (e.g. you are using `delay()` or blocking waits), the receive
buffer can overflow before `serialEvent()` has a chance to empty it.

Another reason is if the Raspberry Pi is sending too much data, too
fast. For every byte the Arduino receives, it must send back
between 13 and 15 bytes. If too much data comes too fast, the transmit
buffer will eventually get full, and then `Serial.println()` becomes
_really slow_, because it has to wait for the bytes to actually get out
on the wire. This in turn slows down `serialEvent()` to the point where
it can make the receive buffer overflow.

**Edit**: If this (the Raspberry sending data too fast) is the cause of
the problem, the obvious solution is to have it send data more slowly,
as:

    repeat:
        send a message
        delay for some suitable time


message:
Arduino Sleep to conserve battery - How to intergrade it to existing sketch - HELP pls

My sketch below is simply using a touch sensor to activate a servo motor to go from from initial position 0 to 180 then back to 0. then I want the Adruino NANO to go to sleep to conserve some battery life.

Being a novice to programing and after many attempts to use his code and intergrade it with mine. Was unsuccessful.

so if anyone can help intergrade the gammon's sketch below into mine it would be greatly appreciated. As I'm out of ideas.

**HERE IS MY SKETCH**
```cpp
#include <Servo.h>

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

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

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

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

void setup() {

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

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

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

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

****Author:Ab Kurk**  SLEEP SKETCH**

This sketch is part of the beginners guide to putting your Arduino to sleep
tutorial. It is to demonstrate how to put your arduino into deep sleep and
how to wake it up.

*/
```cpp
#include <avr/sleep.h>//this AVR library contains the methods that controls the sleep modes
#define interruptPin 2 //Pin we are going to use to wake up the Arduino

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

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

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

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

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

}
```

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

You need to rework somewhat.

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

* The interrupt, when it happens, wakes the processor

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

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

Since my name was mentioned in the question, tips for doing low-power stuff are [at this link](http://www.gammon.com.au/power). And [here for stuff about interrupts](http://www.gammon.com.au/interrupts).

Plus a slightly abridged version (due to space limitations) [here on this site](https://arduino.stackexchange.com/questions/30968/how-do-interrupts-work-on-the-arduino-uno-and-similar-boards/30969#30969).

*(You aren't supposed to make answers where the answer is totally in the link, but in this case the link is just supplementary material)*