text:
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
// 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
// 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) Writing short square wave pulses to pin D3 using Seeeduino XIAO
Timer setup derived from this github post and includes update suggestion 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
// 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
  }
}


text:
External Interrupt and Input Capture pin | Arduino MEGA
I have a code for finding the rpm of one system calling here as engine , the engine have a hall sensor output and I have tried the following Code

#define SERVO_MIN 2000
#define SERVO_MAX 4000

struct Pulse {
  uint32_t last_toggle;
  uint32_t width;
  uint32_t width_prev;
  uint32_t time_prev;
  bool stateHigh = false;
  uint32_t get_width() {
    noInterrupts();
    uint32_t width_copy = width;
    interrupts();
    return width_copy;
  }
};

struct Engine {
  uint16_t servoMin = 2000, servoMax = 4000;
  uint16_t rpm_desired;
  volatile Pulse pulse;
  uint32_t get_rpm() {
    cli();
    uint32_t rpm_width = pulse.get_width();
    sei();
    return 12e7 / rpm_width;
  }
};

Engine engine1,engine2;

void pin_initialization() {
  // INT2
  pinMode(19, INPUT_PULLUP);

  // Input capture points
  pinMode(49, INPUT_PULLUP);
  pinMode(48, INPUT_PULLUP);

}

void timer4_initialization() {
  cli();
  TCCR4A = 0; TCCR4B = 0; TCCR4C = 0;
  TCCR4A = B10101011;
  TIMSK4 = B00100000;
  TIFR4 = _BV(ICF4);
  TCCR4B = B11011010;
  OCR4A = 39999;
  OCR4B = SERVO_MIN;//7
  OCR4C = SERVO_MIN;//8
  sei();
}

void timer5_initialization() {
  cli();
  TCCR5A = 0; TCCR5B = 0; TCCR5C = 0;
  TCCR5A = B10101011;
  TIMSK5 = B00100000;
  TIFR5 = _BV(ICF5);
  TCCR5B = B11011010;
  OCR5A = 39999;
  OCR5B = SERVO_MIN;//45
  OCR5C = SERVO_MIN;//44
  sei();
}

void timer3_initialization() {
  TCCR3A = 0x00; TCCR3C = 0x00;

  TCNT3 = 0x1FF; // from datasheet
  TIFR3 = _BV(TOV3);
  TIMSK3 = _BV(TOIE3); // overflow enable
  TCCR3B = B00000010; // 8 prescaling
}

volatile uint32_t ovfCount = 0;
ISR(TIMER3_OVF_vect) {
  ovfCount++;
}

void pulseWidthCalculator(Pulse *channel) {
  unsigned char sreg;
  sreg = SREG;
  cli();
  uint16_t tcnt3 = TCNT3;
  uint32_t ovf_count = ovfCount;
  SREG = sreg;

  if (bit_is_set(TIFR3, TOV3) && tcnt3 < 16384) {
    ovf_count++;
  }

  uint32_t time = ovf_count << 16 | tcnt3;

  if (!channel->stateHigh) {
    channel->stateHigh = true;
  } else if ( channel->stateHigh) {
    channel->width = time - channel->last_toggle;
    channel->stateHigh = false;
  }
  channel->last_toggle = time;
  sei();
}

void externalInterrputInitialization() {
  EIFR = _BV(INTF2) ;
  EICRA = 0; EICRB = 0;
  EICRA = B00100000;
  EIMSK = B00000100;
}

ISR(INT2_vect) {
      pulseWidthCalculator(&engine1.pulse);
}

ISR(TIMER4_CAPT_vect) {
  pulseWidthCalculator(&engine2.pulse);
}

ISR(TIMER5_CAPT_vect) {
//  pulseWidthCalculator(&engine2.pulse);
}

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

  pin_initialization();
  delayMicroseconds(10);

  externalInterrputInitialization();
  delayMicroseconds(10);

  timer3_initialization();
  delayMicroseconds(10);

  timer4_initialization();
  delayMicroseconds(10);

  timer5_initialization();
  delayMicroseconds(10);

}

void loop() {
  Serial.print(engine1.get_rpm());
  Serial.print("\t" );
  Serial.println(engine2.get_rpm());
}

The same hall sensor output is given to the INT2 (pin #19) pin and ICP4(pin #49) and the results obtained is given below
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
24590   1626
1658    1626
1658    1626
1658    1626
1658    1626
1658    1626
1658    1626
1658    1646
1658    1646
1658    1646
1658    1646
1658    1646
1658    1646
1658    1646
1658    1646
1658    1646
1658    1646
1658    1646
1658    1646
1658    1646
1658    1646
1658    1646
4577    1646
4577    1646
4577    1646
4577    1646
4577    1646
4577    1646
4577    1646
1667    1581
1667    1581
1667    1581
1667    1581
1667    1581
1667    1581
1667    1581
1667    1581
1667    1581
1667    1581
1667    1581
1667    1581
1667    1581
1667    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
2029    1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1581
3428571 1546
3428571 1546
3428571 1546
3428571 1546
3428571 1546
3428571 1546
3428571 1546
3428571 1546
3428571 1546
3428571 1546
3054    1565
3054    1565
3054    1565
3054    1565
3054    1565
3054    1565
3054    1565
3054    1565
3054    1565
3054    1565
3054    1565
3054    1565
3054    1565
3054    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
2961    1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
4615384 1565
3792    1565
3792    1565
3792    1565
3792    1565
3792    1565
3792    1565
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
3792    1587
1542    1587
1542    1587
1542    1587
1542    1587
1542    1587
1542    1587
1542    1587
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1542    1521
1710    1521
1710    1521
1710    1521
1710    1521
1710    1521
1710    1521
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
1710    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3062    1619
3361    1619
3361    1619
3361    1619
3361    1619
3361    1619
3361    1619
3361    1619
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
3361    1581
1449    1581
1449    1581
1449    1581
1449    1581
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
1449    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1541
2166    1628
2166    1628
2166    1628
2166    1628
2166    1628
2166    1628
2166    1628
2166    1628
2166    1628
2166    1628
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
9880    1544
1588    1544
1588    1544
1588    1544
1588    1544
1588    1544
1588    1544
1588    1544
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1588    1586
1693    1586
1693    1586
1693    1586
1693    1586
1693    1586
1693    1586
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1693    1599
1584    1599
1584    1599
1584    1599
1584    1599
1584    1599
1584    1599
1584    1599
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1584    1567
1526    1567
1526    1567
1526    1567
1526    1567
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1526    1646
1693    1646
1693    1646
1693    1646
1693    1646
1693    1646
1693    1646
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
1693    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1682
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
2464    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
1699    1623
3947    1623
3947    1623
3947    1623
3947    1623
3947    1623
3947    1623
3947    1623
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
3947    1688
1537    1688
1537    1688
1537    1688
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1537    1655
1709    1655
1709    1655
1709    1655
1709    1655
1709    1655
1709    1655
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
1709    1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
61696   1699
83449   1699
83449   1699
83449   1699
83449   1699
83449   1699
83449   1699
83449   1699
83449   1699
83449   1699
83449   1699
83449   1699
83449   1699
83449   1699
83449   1699
83449   1699
83449   1699
83449   1699
83449   1699

I have a feeling that the Noise canceller in the input capture pin is helping here, I would like to get help on

How to make the interrupt values also correct
What logical mistake am I making.

how to add the logic of noise cancelling to Interrupt subroutine code.
If I have to add 4/6 such engines what is the best option.
** with a function generator both INT and ICP are giving the correct result.

source: Stack Exchange

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

sort: votes


text:
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");
}

And if you cut out the timer config the button code is running correctly? The pin being OC2B should not matter here, since you are disabling the output compare mode. Thus the timer hardware is not connected to the pin hardware

Can you put a bit of debugging code in the loop to verify that pin 3 is going HIGH?

you have enabled the overflow interrupt. have you handled it?

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

and if you see the location  0xf6:

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.

I just changed the switch configuration to active LOW, but it should not matter.

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


text:
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?

try Arduino simulators if you are building only for a demo

do you actually need an arduino at all?

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).


text:
Where to store AES key on Arduino board
I'm working with this library AES lib 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?

I'm no expert in samd controllers, but I don't think it makes any difference for security if you store in program space or EEPROM (especially emulated)

@chrisl Yes sure you've right, but I'am little bit lost, about how/where to store my private key

For program space you could just write in as a variable in your code (you can even put it in a different file than the main code and include that file).

@chrisl Yes but if I write my key in a variable, it would be easy after a disassembly to get my key no?

Just store it in your code as a "const" and turn on "code protection" in the chip's configuration bits.

Your key will be in the program space no matter what you do, so someone reading the program space would easily get it. Majenko is right with the code protection. Remove any bootloader and enable code protection, which prevents an attacker to read the program space. Though I'm not sure, how exactly this is done on samd controllers

what is being encrypted if there's no connection to the outside world?

@dandavis I encrypt data log about system in SD card

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.

Does enabled fuse prevent rewriting the flash using OTA where the new binary is downloaded and swapped with old one?

No idea. The datasheet should tell you if flash write is inhibited in software or not. Probably not.


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

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 .

Two things:

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.

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.

I can't catch you clearly ......please explain briefly

i think nRF24L01 can support  full duplex  (two way communication)

Read your code and follow the flow of it logically. It's very clear.

It can do two way, but not "full duplex". Only "half duplex". It can transmit and it can receive, but it cannot do both at the same time.

@nskaran, as in like a "walkie-talkie", or marine VHF, or any number similar systems.  Hence all the human protocols carried out to keep people from talking at the same time or for a long time.


text:
Stand alone Atmega328p-au
I'm trying to make a standalone arduino board with an OLED display using an Atmega328p. I never tried to make such a board using SMD components. I've soldered everything together except the OLED display itself. I've uploaded the ArduinoISP sketch to an Arduino Leonardo, and hooked up the SPI pins on my board there. But I simply can't upload anything, I've got 0x000000 as the device signature. I've checked all the connections from the Atmega to the exposed pins themselves, and all seems to be correct with no short circuits.
I'm a bit confused if I put C1 and C3 close enough, could those be the problem? Or is the atmega itself dead? Or did I missed something important?
Wiring between the board and the Leonardo is the following:
Board(H1 header)         Leo
1(reset pin)<----------> Pin 10
2(MISO)     <----------> Pin 12
3(MOSI)     <----------> Pin 11
4(SCK)      <----------> Pin 13
-------------------------------
Board(H2 header)         Leo
1(VCC)<----------------> 5V pin
2(GND)<----------------> GND pin

I've put a 10uF cap between GND and RESET on the Leo.
In the stock ArduinoISP sketch, the #define USE_OLD_STYLE_WIRING line is uncommented. I've tried both Arduino as ISP as a programmer (which didn't work), and Arduino as ISP (Atmega32U4) which gave me the aforementioned signature.
As for the board, I've tried selecting both Arduino Duemilanove or Diecimila/ATmega328P and Arduino Pro or Pro Mini/ATmega328P (5V, 16MHz)

Then try to swap the MISO/MOSI lines

@gbg I've tried that as well, I've got signatures like 0xFF0000, 0xF00000, kinda randomly

the crystal may be connected incorrectly

Not too sure about the crystal. Seems like the ground for the caps is only grounded via the MCU (I can't see a direct trace to ground). Is it oscillating?

@jsotola, But when the MCU is brand-new, it uses the internal oscillator.

@Mat the crystal appears to be not grounded

@Mat it is connected to ground (there is a via above pin 6 of the MCU), but I can't even flash a bootloader to the Atmega, so it should only use the internal oscillator

One thing I have found: new out-of-the-box chips need to be treated more gently than ones that have been programmed once already. You need to slow down the programming to compensate for it running from a relatively slow (1MHz) internal clock.

For Arduino Leonardo, SPI only break out at the ICSP header, not like Arduino Uno that is available at pin 11 - 13. See https://www.arduino.cc/en/Reference/SPI


text:
ESP8266 MCU not clearing memory?
I am still new at this.
Using Arduino IDE
My MCU was working as a web server with HTML code on SD card using the Webserver sketch. After trying to include other inputs it stopped working with "Timed out waiting for packet header"
Decided to abandon that for a while.
I loaded the standard Blink sketch, repowered MCU, pressed rst and Flash in prescribed sequence. Powered card and checked for compilation - All OK.
Uploaded Blink sketch and  got "esptool FatalError: Timed out waiting for packet error" again. Repeated power down etc. but same. Something seems to be lingering.
Arduino: 1.8.15 (Windows 7), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Disabled (new aborts on oom), Disabled, All SSL ciphers (most compatible), 32KB cache + 32KB IRAM (balanced), Use pgm_read macros for IRAM/PROGMEM, 4MB (FS:2MB OTA:~1019KB), 2, v2 Lower Memory, Serial, None, All Flash Contents, 115200"

C:\Users\IAN\AppData\Local\Arduino15\packages\esp8266\tools\python3\3.7.2-post1/python3 C:\Users\IAN\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0/tools/upload.py --chip esp8266 --port COM10 --baud 115200 erase_flash --before default_reset --after hard_reset write_flash 0x0 C:\Users\IAN\AppData\Local\Temp\arduino_build_567362/Blink.ino.bin

esptool.py v3.0

Serial port COM10

Connecting....

Chip is ESP8266EX

Features: WiFi

Crystal is 26MHz

MAC: 3c:71:bf:3b:03:1f

Uploading stub...

Running stub...

Stub running...

Configuring flash size...

Traceback (most recent call last):

  File "C:\Users\IAN\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0/tools/upload.py", line 66, in <module>

    esptool.main(cmdline)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 3599, in main

    detect_flash_size(esp, args)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 2848, in detect_flash_size

    flash_id = esp.flash_id()

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 688, in flash_id

    return self.run_spiflash_command(SPIFLASH_RDID, b"", 24)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 948, in run_spiflash_command

    old_spi_usr = self.read_reg(SPI_USR_REG)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 562, in read_reg

    val, data = self.command(self.ESP_READ_REG, struct.pack('<I', addr))

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 386, in command

    p = self.read()

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 331, in read

    return next(self._slip_reader)

  File "C:/Users/IAN/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.0/tools/esptool\esptool.py", line 2636, in slip_reader

    raise FatalError("Timed out waiting for packet %s" % waiting_for)

esptool.FatalError: Timed out waiting for packet header

esptool.FatalError: Timed out waiting for packet header

fail after "Stub running..." is unusual. try a different USB cable and port

Tried rebooting PC and different USB port.
Cable is new and working.
I have already researched for 2 days.

how is the ESP8266 powered during all this?

Powered via USB


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

please include the circuit diagram ... what are you trying to accomplish?

What voltage swing to you want. What are you connecting the output to. Post a schematic along with links to technical information on the parts you are using.

What part of the “light curve” are you interested in and what will you be connecting the LDR output / voltage divider to? An 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.

@StarCat does the resistance of the fixed resistor change what kind of values I'll get? Also, what is a "light curve"? And btw I connected the output to the 5V pin on the Arduino.

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

simulate this circuit – Schematic created using CircuitLab
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.

Change R1 to a (trim)potentiometer so you can adjust it to your needs.

fun trick: put LDR from ADC to GND, then take the other lead to a GPIO set to "INPUT_PULLUP". Depending on the type of ldr, this can give you full range or sometimes just about 1/4 range, but often that's good enough to tell "it's dark"...


text:
Variable frequency PWM, without changing timers
I need variable frequency output - 0-5000Hz with some duty cycle. I do not want to change timers, because I am using delays, serial and CAN, so I do not want them to be affected by changed timers. I need this for VDO speedometer, which is driven by variable frequency.
Is it possible to set variable time interrupts and change them accordingly to what frequency I want?

Yes, possible, by changing the settings of a timer. Don't know much about CAN. But a hardware Serial interface doesn't depend on any timer. And delays also use Timer0. Even the Arduino Uno has 3 Timers I think. There should be one available to use for you

timers, as I understand, need to be changed by their prescalers, but what if I want an exact value of frequency? Something like delay()?

Try using tone()...

For changing the timer frequency you can also use the output compare mode, where the timers runs up to a value, that you write into the output compare registers (OCR...). So the frequency can be adjusted with rather high resolution (depending on the used timer). Why don't you want to use timers? Try using tone() would be the easiest. It also uses a Timer.

YES! Thank you, tone() works perfectly


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

Updated my post, but the ATMega32 will be powered by Lithium Ion Batteries. They will be changed through a USB C connector that has the data pins connected.

you could try something like this ... if(Serial) { ledon() } else { ledoff() } ... see if the LED changes state when USB cable is plugged and unplugged

Here is the documentation link to jsotolas comment: https://www.arduino.cc/reference/en/language/functions/communication/serial/ifserial/

I'm not sure you can get the best answer to this without details (schematic, etc) on the board itself.

@timemage Added schematic part of the mC and charging IC

You should get to know more about your charging IC (it is quite a powerful chip if not over-kill), read the datasheet, it has more than one pins that provide the indication on whether the power source is an USB or a charging port, it also has the capability to cut off the charging when the charging current is below the threshold, so in summary, once you understand it, what you are trying to do may not necessary.

@hcheung The problem with that is I don't believe that the charging current input will always be 500mA. If connecting to a laptop with a USB C port, then that port has the potential to output up to 3A (which I don't want since I don't want the gloves to charge while connect to the laptop). I'm just trying to understand if the uC can tell when it is plugged into a USB port via the data lines.

did you try what jsotola suggested?

@Juraj I did a test, and found that just checking to see if there is any activity on UDFNUML works for my application from Shreyas's answer. Having the MCU respond if there is activity is fine for my firmware

doesn't the bool operator on Serial do it better?

https://github.com/arduino/ArduinoCore-avr/blob/8f8df161ebf3d8bc595d226c3d3a9125383042a5/cores/arduino/CDC.cpp#L245

I imagine (haven't really tried it) this would work, with some minor adaptation to match your code structure.
//  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, 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
which is implemented like so
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...


text:
Arduino IDE 1.8.15 won't open
I was using Arduino IDE 1.8.13 but didn't open for a few week and now I can't launch the IDE and any of the sketch. I uninstall it and downloaded the latest version 1.8.15 but it still poses the same problem. Only the initializing window appear and after it disappear, the IDE won't go any further. I run the debug.exe and still the same problem. Anyone has same problem and has the solutions?

run arduino_debug.exe from command line to see the log

Delete your preferences.txt file

@Majenko That works very well. I see other suggestion to remove the json files. but never the preferences file. Thanks alot


text:
Arduino UPS without reset
I’m trying to figure out how to make arduino UPS (when the power goes down it should not reset the arduino). Or preferably buy something that will do that for me. I found this, but Im not sure of it will work. I will normally be using power from the outlet, but in case of power outage, I want it to run on the 3,7V li-pol battery (best would be if arduino could somehow know that its running on battery) What solution would you recommend to me?

There are charger modules, which provide power passthrough. I'm not sure if they can provide uninterrupted power during switching, but a large capacitor may help with that depending on the needed current

@chrisl and could the arduino somehow know if its running on battery or from the outlet?

@chrisl well i guess i could just power up radio transciever “directly” from the outlet

That unit does not properly charge a li-pol battery and it states that. It appears it probably would work for Ni-Cad or Pb-Acid batteries. My recommendation is get a unit designed for the batteries you are using with power pass through. Also how do you regulate it for your arduino, a boost module of some type? Showing a schematic, not a frizzy thing would help a lot.


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

you can use the Teensy to control the LEDs ... but you cannot use the Teensy to power the LEDs

That makes sense, thank you @jsotola. Do you have any suggestion on how to power the LEDs from the powerbank that I'm powering the Teensy with?

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

Thank you, I'll look into that pin!


text:
I'm looking for the StreamSend.h library for use in Arduino/ESP8266 serial communications using struct
I've come across an interesting yet old article within StackExchange which has great examples of sending structured variables over serial communications. The library StreamSend.h and it's source code no longer exist on this site and I'm finding it difficult to track down. The examples shown look good and I'd like to use them in my application. My application is communication of large amounts of data between an ESP8266 and a Arduino UNO (both are combined on the same PCBA) via UART serial.
This is the article I'm referring to:
Sending Large Amounts of Serial Data
Can somebody send me the StreamSend.h library please or alternative methods for sending large amounts of data over serial (by large amounts of data I mean reading/writing say 10 to 20 variables of various data types so struct would suit well). Thank you.
Regards,
Brian

The code is in the article you linked to - right under StreamSend Class. Copy that code, save it as StreamSend.h or StreamSend.hpp.

Thanks romkey. I have created the StreamSend.h file and the ESP8266 and Arduino programs both compile.I send the struct from the ESP to the Arduino using the same code in this blog for send and receiving a struct. I can see on the serial monitor that the ESP appears to be sending data but the Arduino is quiet. I've noted the StreamSend.h file has #include "Arduino.h" but no reference to ESP8266. So could this be an issue?

I'd suggest asking that in a new question.


text:
Micromod nrf52840 sniffer
Can I use the Micromod nrf52840 processor module, Micromod ATP carrier, with Nano 33 type bootloader and modify the ArduinoBLE library or modify the MBED OS abstraction layer and make a promiscuous BLE sniffer that will output something, preferably a Wireshark compatible capture file to the main serial COM port and save the output from arduino IDE?

maybe you can, maybe you cannot, we do not know what skill you have


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

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);
}

the datasheet shows the used UNO pins ... there is also a zip file with servo example code ... https://github.com/SmartArduino/ESPboard

@YulianProdanov When you still have problems, you can write comments under my answer and include the new information in your question. Edits on answers are not meant for replying to an answer

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 you will see this diagram

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

Yes, sorry, I didn't mean to edit your answer, @chrisl , I'm not sure what happened there. Anyhow, I tried to follow your instructions thoroughly but I still couldn't quite achieve the end result, namely "make possible to move a servo back and forth, at least 1 out of 6".
I've included 3 pictures of my setup in the link below.
link
Btw, I uploaded the code I used in my question above, so you can take a look too.

You cannot use the normal Servo library, when you are using the shield. The nornal servo library uses an internal timer to switch a digital output pin with the correct signal. That shield uses a dedicated chip for that. Have you looked for a fitting library to use it?


text:
ESP32 cam module SPI and NRF
I'm trying to use nrf2401 as transmitter on ESP32-cam module.
I'm programming with Arduino IDE, but I'm not sure how to set the pins.
I know that the board has 2 SPI interfaces. The first one is for the SD card built-in module.
The second one should be free.
Those are the pins for the second SPI:
MOSI - 13,
MISO - 12,
CLK - 14,
CS 15
Here is my code - https://pastebin.com/qEC3JA1d
Where should I define my pins for the SPI?

There are examples in the RF24 docs


text:
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??

Do you mean - "How much current is being consumed by the ESP8266 while using WiFi? " If that is your question then I would say that it depends on your specific board and if any external loads are present, given this I have found out that it has a current consumption of 400-420mA while using WiFi

Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking.

If you notice, an answer to this question gives you 200-220 mA is the current consumption, which is not wrong but you can see how it varies, so its best to measure it on your own with your particular case

I took some measurements here. Please be aware that you can be in Auto Light Sleep mode and still enjoy the occasional Wifi transmission, it will wake up when necessary.

The short answer is - we don't know.
Longer answer:
It depends on such factors as:

The board circuit (the BBBL (known as The Big Bright Blue LED) on some boards could drain about 10-20ma only by itself)
The voltage regulator efficiency
The battery controller circuit / quality / keying efficiency.

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

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

This is misleading in terms of battery guidance. The values in the chart are peaks, lasting only a ms. With a nodeMCU that doesn't sleep, I see ~70ma idle with traffic pushing it to ~87ma, as seen from a voltmeter (averaging out the spikes). Extending distance to the edge of reliability barely increases measured current of traffic: ~95ma. 100ma is a good (pessimistic) estimation figure with comfortable margins.

Yeah, 70 ma seems about right, if you don't sleep. I took some measurements here.

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

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

(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, but these were the ones that matter in your case.

this is consistent with my simple measurements and experiments


text:
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)

How are you determining that the "hostname" is working or not? The concept of a "hostname" only exists in the realm of DHCP (which you aren't using), DNS (which isn't controlled by the ESP32 and you're not using anyway) or mDNS (which again you're not using).

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.

Well that certainly would explain my issue. But what doesn't addup is that other devices on my network (printers, NAS, etc) have static IPs and they show custom host names

Thats because these devices use DHCP to tell the router their name. Just as Majenko described. For the static IPs: you may have set the devices to static IPs in the router setting. In that case they still get their IP from the routers DHCP, just the same every time. Or they don't use DHCP and you have set the IP on the device while hopefully making sure, that no other device can have the same IP

More likely they are advertising their names with mDNS. myPrinter.local for example.

None of the devices I am talking about are using DHCP. They all have static IPs and custom hostnames in the device itself. The printers have mDNS, the NAS doesnt but I am still seeing it's custom name. Im going to try to add mDNS to the ESP32 tomorrow and see if that helps

The NAS is probably using SMB which includes network name resolution of its own.

I think you nailed it. The NAS does use SMB.


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

which perfboard did you use? ... what is the picture supposed to show? ... you have provided zero information about what you did

have you tested all relevant pins for connections? I mean actually testing them (for example with a multimeter)

those are not answers ... you are still providing zero information ... i did not ask you where you bought the perf board ... please provide clear pictures of the two sides of the perf board before any work was done ... also provide clear pictures that show what you did

Thx for your answers. I use a Ali express perfboard. The picture show the Vin and Gnd pin at the left. I want to show you the gap between the two solderpoints. The only thing I did was soldered the Nano in place, powered over USB en floep. Spark between Vin en Gnd. I tested all the pin with a multimeter. Didn't got saw any issues. Could it be the perfboard?

where exactly did you see a spark? ... the only time you will see a spark with a 5 V supply, is when two condutors are very close together or the voltage is much higher than you think

Can you post a sketch or schematic showing how all of this is connected. Your picture shows 4 pins but what are they, I cannot see the other side of the board? How did you determine you have a short>

posted the pictures in the question, dont mind the cap, he's there but not connected. I see smoke, and hear crakling sounds between pin Vin en Gnd. I power the nano over usb, the first time I used a bench powersupply. I thought that was the issue. Then I used legit usb powersupply from one of my Rpi's, same issues. The third time I used the usb port from my pc and scratched between Vin and Gnd to make sure there is enough gap between the two pins, as seen on first picture, first pin on the left is Vin, Gnd is second pin.

I took the time to hang the nano on my bench power to show you what is happening. What you're seeing here are pins 29 and 30 Vin and ground. https://drive.google.com/file/d/183kBK4hXRMbkuoGcrJJOLEInRQ5zVFIP/view?usp=sharing

Use pin headers and check for the shorts before you'll insert board...

if gnd shorted to vin, the nano should be okay.

What solder are you using? What flux are you using? What flux cleaner are you using?

i looked at the video ... wow ... definitely looks like contamination ... are you using paste solder? ... solder two bare pins that are not connected to anything and measure the resistance between them

measure resistance between two adjacent, unused holes ... the board itself may have a conductive layer

have you removed the Nano and tested it? ... it may be undamaged .... afrer the short circuit in the video burns itself out, the Nano may be functional, but being held in a reset state by a short between reset and gnd

@jsotola on your advice, I prept a perfboard like this, two bare pins using only solder, two with solder and flux, two with solder flux and cleaner. And apparently its the solder that causes the problem, and maybe the fact I didn't cleaned the board enough afterward? But ok, I don't think this should happen... I'm using Welco solder. Flux is from Weller and the cleaner I use is Cramolin. I desoldered the nano, I get a USB corrupted notif. When compiling I get these messages bit.ly/2WIK0d3
bit.ly/2WFt0nB

I don't know "welco". Is it an electronics solder or a plumber's solder? The same for the flux: is it electronic flux or plumber's flux?

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.

Since whoever down-voted this didn't bother to say, I'll offer a guess as to the reason. They appear to still be developing the question.  And one of the comments suggests doing this exact thing, though, I think as a diagnostic measure rather than answer.


text:
configuring characteristics to communicate data on the Arduino bluetooth low enegy module
I have the HM-10 Arduino BLE module. I am also building an app to send and read characteristics on the BLE module. On the Arduino BLE side of things though, how do I set up which characteristic listens for which kind of data?
So, if the BLE module has 1 service containing two characteristics the first one being read-only and the second one being write-only. On my android app, I can find the UUIDs of these two characteristics and perform read and write operations on the corresponding characteristics. But how would I go about initializing which characteristic on the BLE module should expect which kind of operation?
All I see other people do is they perform BLE.read and BLE.write functions to accomplish this. But if you have multiple characteristics and some that can do both kinds of operations, how do you distinguish between them in the code? Does the BLE module only think of the characteristics as one entity that can either be read to or written to, whereas the android app needs to know which is which? The HM-10 documentation talks about setting up the characteristic UUID but talks about pins on the chip to control things, which is weird because the arduino already has pins that you can use.
Worst case scenario, I guess I could just look at ArduinoBlue or Dabble's arduino source code.


text:
UDP packet loss and very high ping time
Scenario
I'm writing a code for Nucleo-144 F429ZI. It receives UDP packets (actually OSC bundles) and send back an answer when the command is completed.
Issues
It work fine most of the time. But there are two issues that sometime happen:

a message sent from the board is not received by the PC
the board receives the messages with a very long delay (up to 4 s) and in this situation also a ping shows this delay

What I tried
I changed:

board
switch
cables
PC, O.S. and software

The behavior is the same.
In the firmware I checked all the return values and no one reports an error. Hence, I assume the messages actually leave the board. But apparently they don't reach the PC. Please note that I'm talking about 1 on 1000+ packets.
It seems (even it is hard to guess) that especially the second issue is more frequent if the PC sends packets to multiple IP. Example:

PC sends packets to 192.168.100.1 only: the second issue happens very rarely (i.e. given 2 packets per seconds, it may took days)
PC sends packets to other 10 boards in the same network: the second issue happens within minutes

When this happens, the only way to recover the correct behavior is to reset the board. Even disconnect and reconnect the Ethernet cable does nothing.
** Code **
I wrote a fake firmware to reproduce the problem (it does nothing but answer after some time). As said, running this code with a single board connected it works fine for a long time. But anyway, you might spot some mistake in the UDP handling:
#include <LwIP.h>
#include <ArduinoQueue.h>
#include <STM32Ethernet.h>
#include <EthernetUdp.h>
#include <OSCMessage.h>
#include <OSCBundle.h>
#include <OSCData.h>

#define UDP_TX_PACKET_MAX_SIZE 1024

EthernetUDP Udp;
IPAddress remoteIP;
unsigned long oldTick;
OSCBundle bundleServo;
char answer[128];
int ch;
float pos;

int getIndex(OSCMessage &msg, int patternOffset)
{
  char buf[8];
  msg.getAddress(buf, patternOffset + 1, 8);

  return atoi(buf);
}

void servo_fade_handler(OSCMessage &msg, int patternOffset)
{
    ch = getIndex(msg, patternOffset);
    pos = msg.getFloat(0);
    oldTick = millis();
}

void bundle_send(OSCBundle *bundle)
{
  Udp.beginPacket(remoteIP, 8888);
  bundle->send(Udp);
  Udp.endPacket();
  bundle->empty();
}

void setup()
{
  Serial.begin(115200);
  delay(1000);

  IPAddress localIP = IPAddress(192, 168, 100, 2);
  IPAddress netmask = IPAddress(255, 255, 0, 0);
  IPAddress dns = IPAddress(192, 168, 1, 1);
  IPAddress gateway = IPAddress(192, 168, 1, 1);

  Ethernet.begin(localIP, netmask, dns, gateway);
  Udp.begin(8888);
}

void loop()
{
  uint8_t data[UDP_TX_PACKET_MAX_SIZE];
  uint16_t size = Udp.parsePacket();

  if (size > 0 && size < UDP_TX_PACKET_MAX_SIZE)
  {
    Udp.read(data, size);
    remoteIP = Udp.remoteIP();

    OSCBundle bundle;
    bundle.fill(data, sizeof(data) - 1);
    data[size] = '\0';

    if (bundle.getError())
    {
      Serial.print("[OSC] Error: ");
      Serial.println(bundle.getError());
      return;
    }

    int bundleSize = bundle.size();
    for (int i = 0; i < bundleSize; i++)
    {
      OSCMessage msg = bundle.getOSCMessage(i);
      msg.route("/servo/fade", servo_fade_handler);
    }
  }
  else Udp.flush();

  if ((oldTick > 0) && ((millis() - oldTick) > 500))
  {
      bundleServo.empty();
      sprintf(answer, "/servo/fade/2/%u", ch);
      bundleServo.add(answer).add(pos);
      bundle_send(&bundleServo);
      oldTick = 0;
  }
}

Question
I do know the theory says the UDP protocol is not reliable. But after 15 years of experience I never lost a single packet even in very messy environments with hundreds of devices. Here we're working on a simple LAN: one PC, one switch and less than 10 boards. No Internet connection, no WiFi, no other stuff.
What are the possible causes for the issues? Understood them, I can investigate them one by one

maybe some filtering should be set on the Ethernet adapter to not process packets targeted to other MAC addresses. because without the filter the lwip stack has to process it

Maybe this question would be better asked of the authors of the Nucleo core and networking libraries. If you've ruled out everything except the software then it must be the software, so ask the authors of the software.

the author and experts are here https://www.stm32duino.com/

@Juraj, would you please provide an example of how to set up such a filter?

the STM32Ethernet library uses the Ethernet peripheral of the MCU. so it would be a register of the MCU.

@Juraj, if you want you can make an answer. Anyway, do you really think that 10 messages of 30-40 bytes each can hang the board for 4 seconds?


text:
First I2C project - Unable to get any servo movement with PCA9685
I'm working on a project where I need to run multiple servos. For now though, I'm trying to get a single MG90S servo running with a PCA9685 servo driver but I'm unable to get any movement from the servo.
What I have setup is as follows;

Servo power is 5v 2A in the form of a standalone power supply.
Arduino UNO GND to shield GND
Arduino 5v to shield VCC
Arduino A4 to shield SDA
Arduino A5 to shield SCL (Ive also tried SDA and SCL on the uno)

The code I'm running is just the standard adafruit library example (see below) with the only change being the I2C address is set to 0x41 as I have soldiered across the first pair of pads (I have verified the new address with an I2C scanner program).
Ive tried multiple servos, two PCA9685s and two different arduinos. The servos work without the PCA9685 and I can see println info when viewing the Serial Monitor. Any ideas?

/***************************************************
  This is an example for our Adafruit 16-channel PWM & Servo driver
  Servo test - this will drive 8 servos, one after the other on the
  first 8 pins of the PCA9685

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/products/815

  These drivers use I2C to communicate, 2 pins are required to
  interface.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// called this way, it uses the default address 0x40
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// you can also call it with a different address and I2C interface
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41, Wire);

// Depending on your servo make, the pulse width min and max may vary, you
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
#define SERVOMIN  400 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  600 // this is the 'maximum' pulse length count (out of 4096)

// our servo # counter
uint8_t servonum = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("8 channel Servo test!");

  pwm.begin();

  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates

  delay(10);
}

// you can use this function if you'd like to set the pulse length in seconds
// e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. its not precise!
void setServoPulse(uint8_t n, double pulse) {
  double pulselength;

  pulselength = 1000000;   // 1,000,000 us per second
  pulselength /= 60;   // 60 Hz
  Serial.print(pulselength); Serial.println(" us per period");
  pulselength /= 4096;  // 12 bits of resolution
  Serial.print(pulselength); Serial.println(" us per bit");
  pulse *= 1000000;  // convert to us
  pulse /= pulselength;
  Serial.println(pulse);
  pwm.setPWM(n, 0, pulse);
}

void loop() {
  // Drive each servo one at a time
  Serial.println(servonum);
  for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
    pwm.setPWM(servonum, 0, pulselen);
  }

  delay(500);
  for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
    pwm.setPWM(servonum, 0, pulselen);
  }

  delay(500);

  servonum ++;
  if (servonum > 7) servonum = 0;
}

I haven’t seen anything obviously wrong. Does the PCS9685 show up using the I2CScanner sketch? https://www.arduino.cc/reference/en/libraries/i2cscanner/

Can you post the serial monitor output?

If you do not have access to an oscilloscope to check the actual PWM output to make sure it is in the target range for the specific servo, then it might be useful to try some broader values of SERVOMIN and SERVOMAX.

While you’ve got just the one servo connected it may pay to comment out the third last line “servonum ++;” so that the loop just concentrates on exercising/swinging port 0 where you have it connected.

@RowanP
Yes the board shows with an I2C scanner. Address is 0x41 as I mentioned
12:57:17.341 -> --- Scan started --- 12:57:17.341 -> I2C device found at address 0x41  ! 12:57:17.387 -> --- Scan finished ---
No oscilloscope, but I've tried MIN 0, MAX 3500. This also doesnt work.
I have now removed the ++counter but still nothing.
13:00:18.091 -> 8 channel Servo test! 13:00:18.138 -> 0 13:00:23.585 -> 0

Do you have a multimeter? I wonder how many volts are showing V+ to GND on the PCA9685, and how many amps are being drawn from the external power supply when the sketch is running compared to when it’s idle.

Could you add a close up picture of the PCA9685 with connections? Is the polarity of the external supply the right way around?

Thanks for the reply Rowan.
Current draw from the power supply with a blank arduino sketch and the pwm example sketch are 0A which is clearly the issue. I've had a look back at the website I bought these PCA9685 boards from and there is a comment from another buyer with the exact same issue in the last week. They had no voltage to the servo connectors. I've checked and mine is the same. I get a pwm signal and I can see that changing as the script runs, but no 5v. I'm going to return the boards and buy from somewhere else. Many thanks.


text:
Circuit to get highest reading value from multiple thermistors?
I need to measure temperature of 6 battery cells. I don't care much about individual cell readings, I just want to sound a buzzer as soon as at least one of the temperatures is above a certain threshold.
I can see the most straightforward way to do it using 6 thermistors, but that's a lot of wires going between Arduino and all these sensors. Is there any other approach that would be more lightweight? Trying to save both space and weight.
If I understand correctly, best I can do with 6 thermistors is share the GND wire and resistor between them, but then I'm still stuck with 6 * 2 + 1 = 13 wires.

not arduino specific

DS18b20 digital thermometers use the 1-Wire protocol which requires only a single data line for a network of devices - so +V (3.3 - 5 Volts), Gnd, and Data, shared among all of them. You can even wire them in "Parasitic mode", skipping the +V, and they will get their power from the data line, so only 2 wires and 1 pin required.From the DS18b20 Datasheet:

Thanks, this is exactly what I needed.