Arduino Nano stops generating pulses randomly

Hello guys

I have an Arduino Nano installed on a board that is supposed to generate pulses and pulse trains to an AND gate.
I am powering the board (and the Arduino) using a 15V power supply stepped down to 8V with a mini DC-DC step down buck converter.

The problem is the board generates the required pulses for a short time, then it stops. I have to either press the reset button or unplug/plug the power in order to get it working again.

Your topic was MOVED to its current forum category as it is more suitable than the original

Please post a sketch and schematic that illustrates the problem that you are having

Do a rough estimation how many reasons are possible to cause such a bug?

Do you expect a personally for you written tutorial tthat covers all possible reasons?
Would you really like to read such an exhaustive tutorial?

Post :

  • your complete sketch
  • a hand-drawn schematic how you have things wired together
  • a datasheet of the DC-DC-step-downconverter

best regards Stefan

2 Likes

Hello shamooooot
Post your current sketch, well formated, with comments and in so called code tags "</>" and a schematic, not a Fritzy diagram, to see how we can help.

Have a nice day and enjoy coding in C++.
Дайте миру шанс

2 Likes

I am sorry I am powering it with 5V.

image
Converter used: https://www.aliexpress.com/item/32826540392.html

volatile byte PWM_flg = 0;  //Pulse train toggle switch flag
volatile byte INH_flg=  0;    // Inhibit toggle switch flag


// Pin Settings
byte inh_switch = 3;        // pin 3 for INHIBIT SWITCH
byte pwm_switch = 2;     // pin 2 for PWM SWITCH
byte inh_pin = 13;          // pin 13 for INHIBIT
byte pwm_pin = 9;         // pin 9 for PWM

void setup()
{

  //Set up PWM
  pinMode(pwm_pin, OUTPUT);   // PWM output
  pinMode(inh_pin, OUTPUT); // Inhibit Signal to TCA785
  
  //Set External Interrupts
  pinMode(pwm_switch, INPUT);
  pinMode(inh_switch, INPUT);
  attachInterrupt(digitalPinToInterrupt(2), ISR_PWM, CHANGE);
  attachInterrupt(digitalPinToInterrupt(3), ISR_INHIBIT, CHANGE);
  
  // phase and frequency correct mode. NON-inverted mode
  TCCR1A = _BV(COM1A1) | _BV(COM1B1) ;
  // Select mode 8 and select divide by 8 on main clock.
  TCCR1B = _BV(WGM13) | _BV(CS11);
  
  // Check for the initial positions of PWM and Inhibit Switch
  if(digitalRead(pwm_switch) == HIGH)
         PWM_flg = 1;
  else
        PWM_flg = 0;
  
  if(digitalRead(inh_switch) == HIGH)
         INH_flg = 1;
  else
        INH_flg = 0; 
}

// interrupt pins debounce function
bool debounce(byte intr_pin) 
{
  byte count = 0;
  for(byte i = 0; i < 5; i++)
  {
    if( digitalRead(intr_pin) )
      count++;
      delayMicroseconds(5);
  }
  if(count > 3)
    return 1;
  return 0;
}

// Interrupt Service Routine for Phase 1
void ISR_PWM() 
{
  detachInterrupt(digitalPinToInterrupt(2));
  if( debounce(2) )
      PWM_flg = 1;
  else
      PWM_flg = 0;
      attachInterrupt(digitalPinToInterrupt(2), ISR_PWM, CHANGE);
}

// Interrupt Service Routine for Phase 1
void ISR_INHIBIT() 
{
  detachInterrupt(digitalPinToInterrupt(3));
  if( debounce(3)  )
    INH_flg = 1;
  else
    INH_flg = 0;
    attachInterrupt(digitalPinToInterrupt(3), ISR_INHIBIT, CHANGE);
}

void loop()
{

  if(  PWM_flg ==1   ) // Pulse train mode ON
      {
          ICR1 = 20; 
          OCR1A = ICR1/2; // set PWM pin 9
      }
  if( PWM_flg ==0   ) // Pulse train mode OFF
      {
        ICR1 = 20000;
        OCR1A = ICR1; // set PWM pin 9
      }
  
  if( INH_flg  )
     {
        digitalWrite(inh_pin, HIGH);
     }
      
    else
    {
       digitalWrite(inh_pin, LOW);
       OCR1A=0;
    }
    
}
1 Like

First thing I see is you should never detach and attach interrupts in an interrupt function. They are already disabled and will be enabled when the function ends. Attach interrupts ONE time only in setup.

The second thing is to code the ISR as short a possible. Debouncing of buttons shall be performed inside the loop() function.

1 Like

I am not trying to make someone else to do my job here. But I am a super newbie in Arduino .. I hope you guys can elaborate on your comments :melting_face:

We can't help much if you are just copying code you found somewhere. You actually need to understand a bit about what you are coding.
What are you trying to accomplish?

1 Like

@shamooooot You’re doing well so far, and this isn’t a response to anything you’ve said, but it’s easy to get defensive and shut down.

You’ll find the whole team here are extremely well qualified to solve your problem, but some of them may seem to be like the kids at school that gave you a hard time.

Yes, sometimes we’ll pull your pants down, or give you sh|ts, but if you work calmly through the conversation you and us will. one out enter off.

None of us know everything, sometimes there’ll be some stupid answers or unnecessary questions, but with a bit of patience - it WILL work !

1 Like

So I am trying to make the Arduino generate a single pulse or pulse trains through pin 9.

I also have two switches: one for stopping the Arduino of generating signals (inhibit),
the other switch is for changing from single pulse (square wave) to pulse train.

I was testing and I found out the reset happens when I switch these switches, and it is pretty random. I even sometime lose the software on the Arduino and had to re program it.

Your S1 and S2 appear to be relays from your schematic.

These are SPST switches.

You sure did fool me!

Are the switches momentary switches? Or toggle switches?

I think the interrupt attaching and detaching and debouncing are interacting unexpectedly. Why do you need the interrupts?

You can inhibit the pin9/OC1A/OCR1A PWM by clearing this COM1A1 bit. Are you using pin10/OC1B/OCR1B for anything? Otherwise this COM1B1 looks like a mistake:

If you want to do this with timer registers, there's a cool trick for doing one-shot pulses with a timer by setting OCRnx above TOP: AVR Timer-based One Shot Explained | josh.com -- you might be able to do the pulses, inhibiting, and pulse trains all with OCR1A, ICR1, and TCNT1 manipulations.

1 Like

hi DaveX

They are toggle switches, and I am not using pin10 for anything at all.. I am using the inhibit just to block the Arduino from generating pulses.

Then the TCCR1A ... _BV(COM1B1); doesn't do anything useful.

Instead of using the interrupt, I might do the inhibiting like this:

if (TCCR1A & bit(COM1A1) && digitalRead(inh_switch)){
    TCCR1A &= ~bit(COM1A1); // turn off OC1A
}
if (!(TCCR1A & bit(COM1A1)) && !digitalRead(inh_switch)){
    TCCR1A |= bit(COM1A1); // turn on OC1A
}
1 Like

Then don't use potentially problematic interrupts.
Interrupts are for (clean) fast changing signals, which a bouncing switch is not.
Leo..

2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.