2

I have written a code that detects an incoming pulse (square) of 7.875 kHz to trigger the output High for the entire duration of pulse, and trigger the output low if the pulse is off or not detected.

CODE

// Define pins
volatile int pulse1 = 2;    //incoming pulse 1 on pin 2

const int ledPin = 13; //output to trigger LED

void setup() {

pinMode(pulse1, INPUT);

pinMode(ledPin, OUTPUT);

// Timer Setup

TCCR1A = 0; // set entire TCCR1A register to 0 TCCR1B = 0; // same for TCCR1B TCNT1 = 65282; // initialize counter value TCCR1B |= (1<<CS10); // set prescaler to 8 bit TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt

} ISR(TIMER1_OVF_Vect){ TCNT1 = 65282; attachInterrupt(digitalPinToInterrupt(pulse1), ISR_UV2, FALLING); }

void loop() { attachInterrupt(digitalPinToInterrupt(pulse1), ISR_UV1, RISING);

}

// Interrupt routines

void ISR_UV1(){ digitalWrite(ledPin, HIGH); // Send high signal }

void ISR_UV2(){ digitalWrite(ledPin, LOW); // Send low signal }

Is it the correct approach, or am I doing it wrong. One last thing that is bothering me is, every time I connect a wire (not connected to anything) to the input pin 2, it sends a high signal, and keeps the signal high until the Arduino is reset. The pulse is a square wave 50% duty cycle generated by a device. I dont need to measure it or count it. I am just using it as a trigger to send a HIGH signal when it occurs. So it stays on (occurs) for 25ms & turns off during which its freq. is 7.875MHz & then it is repeated by the device according to the device parameters. I am aware it is a very short pulse but for the purpose of project nothing else can be used as the trigger

Any help will be appreciated.

2 Answers2

2

So i figured out what the problem was, I had to detach interrupts in the interrupt routines not in my main code. So basically these changes:

void loop() {
  digitalWrite(ledPin, LOW);
  attachInterrupt(digitalPinToInterrupt(pulse1), ISR_UV1, CHANGING);

}

& in the Interrupt routines:

digitalWrite(ledPin, HIGH);      // Send high or Low dpending on the routine 
detachInterrupt(digitalPinToInterrupt(pulse1));

& basically this works like a charm, & there are still issues with the timer, but that will be solved in my main code with another sensor.

0

I don't think, that your current approach will work. The logic seems flawed to me (though I cannot know, how exactly this code is embedded in your actual code) and the frequency is that high, that it will be difficult for the microcontroller to do much between the different interrupt triggers.

I would suggest 2 different approaches, based on the actual needs:

  1. You can build a demodulator, which just gives you a high value, when your signal is there, and a low one, if it is not. Here you would need extra components.

  2. You could feed the signal into one of the timers as clock source. Then the timer counts the pulses (actually twice the pulses, since the timer increments on every edge, rising or falling). You can use the overflow interrupt to get the value out of it. Lets say you use Timer 1 for the signal and still have Timer 0 for doing the Arduino time stuff (delay(), millis(), micros()). Then you can write an ISR for the Timer1 overflow interrupt. In there you take the current time and subtract the time of the last interrupt. Then you get the time, that it took the timer to overflow. Since you know, how many pulses are needed to overflow the timer, you now know the average frequency. If it is in the needed range, you set a simple single byte flag variable (be sure to declare it as volatile). You can tune the time for the average for example with the prescaler.

    In your main code you can then check for the flag being set and do stuff accordingly. Reset the flag, if you have done stuff, and save a timestamp. Check in your main code, if a specific time has passed since your last timestamp. If yes, that means, that the signal is lost. There you can act accordingly

chrisl
  • 16,622
  • 2
  • 18
  • 27