Arduino: detect if 2 signals change within ~100 microseconds of each other
I am trying to use an Arduino Uno as part of a larger circuit that synchronizes two square voltage waveforms (those waveforms are fed into pins of the Uno). The Uno will be activated by a digital signal from another part of the larger circuit, and that activation signal will be sustained for a few seconds at a time. While the activation signal is HIGH, the Uno's job will just be to detect when its measured square waveforms are synchronized: it will monitor them and generate a pulse of its own if they reach their zero crossings within about 100 microseconds of each other (the square waves themselves are ~50Hz).
Because 100us is a pretty short window, I thought I'd try direct bit manipulation rather than using DigitalRead() or DigitalWrite(). This is my first time trying bit manipulation, though, and my C experience is pretty limited in general. I have the first draft of my code here - if any of you can tell me whether the logic of it seems sound, I would very much appreciate it!
It looks long, but there are only a few lines' worth of ideas, the rest is a bunch of copy/pasted blocks (which no doubt means there are much more elegant ways to write it).
// Synchronism detector
// This code is built to run on an Arduino Uno.
// The hardware timer runs at 16MHz. Using a
// divide by 8 on the counter each count is
// 500 ns and a 50Hz wave cycle is 40000 clock cycles.
#include <avr/io.h>
#include <avr/interrupt.h>
void setup(){
// Set clock prescaler
// This is set to 'divide by 8' but if I can get away
// with using delay statements that doesn't really matter
TCCR1B &= ~(1 << CS12);
TCCR1B != ~(1 << CS11);
TCCR1B &= ~(1 << CS10);
// Set up pins
// 3rd bit of port D will be the activation flag
// 4th and 5th bits will be read pins for the incoming waves
DDRD = DDRD & B11100011
// Note that I'll also have the incoming waves going into the int0 and int1 pins
// 6th bit will be a write pin for the outgoing signal
DDRD = DDRD | B00100000
PORTD = PORTD & B11011111
// Set initial values for zero-cross detect flags
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
}
void loop(){
// Poll activation flag
if (((PIND & B00000100) >> 2) == 1)
// Poll wave input pins
wave_0 = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
// Check zero crossing detection,
// Start with wave 0, rising edge
if (wave_0 == 1 && wave_0_prev == 0))
attachInterrupt(int1,sync_interrupt, RISING);
delay(.0001);
detachInterrupt(int1);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
// Wave 0, falling edge
if (wave_0 == 0 && wave_0_prev == 1))
attachInterrupt(int1,sync_interrupt, FALLING);
delay(.0001);
detachInterrupt(int1);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
// Wave 1, rising edge
if (wave_1 == 1 && wave_1_prev == 0))
attachInterrupt(int0,sync_interrupt, RISING);
delay(.0001);
detachInterrupt(int0);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
// Wave 1, falling edge
if (wave_1 == 0 && wave_1_prev == 1))
attachInterrupt(int0,sync_interrupt, FALLING);
delay(.0001);
detachInterrupt(int0);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
}
sync_interrupt(){
// Set output bit high
PORTD = PORTD | B00100000
delay(.001}
// Set output bit low
PORTD = PORTD & B00100000
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
}
Thanks again for any help.
performance arduino arduino-uno
add a comment |
I am trying to use an Arduino Uno as part of a larger circuit that synchronizes two square voltage waveforms (those waveforms are fed into pins of the Uno). The Uno will be activated by a digital signal from another part of the larger circuit, and that activation signal will be sustained for a few seconds at a time. While the activation signal is HIGH, the Uno's job will just be to detect when its measured square waveforms are synchronized: it will monitor them and generate a pulse of its own if they reach their zero crossings within about 100 microseconds of each other (the square waves themselves are ~50Hz).
Because 100us is a pretty short window, I thought I'd try direct bit manipulation rather than using DigitalRead() or DigitalWrite(). This is my first time trying bit manipulation, though, and my C experience is pretty limited in general. I have the first draft of my code here - if any of you can tell me whether the logic of it seems sound, I would very much appreciate it!
It looks long, but there are only a few lines' worth of ideas, the rest is a bunch of copy/pasted blocks (which no doubt means there are much more elegant ways to write it).
// Synchronism detector
// This code is built to run on an Arduino Uno.
// The hardware timer runs at 16MHz. Using a
// divide by 8 on the counter each count is
// 500 ns and a 50Hz wave cycle is 40000 clock cycles.
#include <avr/io.h>
#include <avr/interrupt.h>
void setup(){
// Set clock prescaler
// This is set to 'divide by 8' but if I can get away
// with using delay statements that doesn't really matter
TCCR1B &= ~(1 << CS12);
TCCR1B != ~(1 << CS11);
TCCR1B &= ~(1 << CS10);
// Set up pins
// 3rd bit of port D will be the activation flag
// 4th and 5th bits will be read pins for the incoming waves
DDRD = DDRD & B11100011
// Note that I'll also have the incoming waves going into the int0 and int1 pins
// 6th bit will be a write pin for the outgoing signal
DDRD = DDRD | B00100000
PORTD = PORTD & B11011111
// Set initial values for zero-cross detect flags
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
}
void loop(){
// Poll activation flag
if (((PIND & B00000100) >> 2) == 1)
// Poll wave input pins
wave_0 = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
// Check zero crossing detection,
// Start with wave 0, rising edge
if (wave_0 == 1 && wave_0_prev == 0))
attachInterrupt(int1,sync_interrupt, RISING);
delay(.0001);
detachInterrupt(int1);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
// Wave 0, falling edge
if (wave_0 == 0 && wave_0_prev == 1))
attachInterrupt(int1,sync_interrupt, FALLING);
delay(.0001);
detachInterrupt(int1);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
// Wave 1, rising edge
if (wave_1 == 1 && wave_1_prev == 0))
attachInterrupt(int0,sync_interrupt, RISING);
delay(.0001);
detachInterrupt(int0);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
// Wave 1, falling edge
if (wave_1 == 0 && wave_1_prev == 1))
attachInterrupt(int0,sync_interrupt, FALLING);
delay(.0001);
detachInterrupt(int0);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
}
sync_interrupt(){
// Set output bit high
PORTD = PORTD | B00100000
delay(.001}
// Set output bit low
PORTD = PORTD & B00100000
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
}
Thanks again for any help.
performance arduino arduino-uno
add a comment |
I am trying to use an Arduino Uno as part of a larger circuit that synchronizes two square voltage waveforms (those waveforms are fed into pins of the Uno). The Uno will be activated by a digital signal from another part of the larger circuit, and that activation signal will be sustained for a few seconds at a time. While the activation signal is HIGH, the Uno's job will just be to detect when its measured square waveforms are synchronized: it will monitor them and generate a pulse of its own if they reach their zero crossings within about 100 microseconds of each other (the square waves themselves are ~50Hz).
Because 100us is a pretty short window, I thought I'd try direct bit manipulation rather than using DigitalRead() or DigitalWrite(). This is my first time trying bit manipulation, though, and my C experience is pretty limited in general. I have the first draft of my code here - if any of you can tell me whether the logic of it seems sound, I would very much appreciate it!
It looks long, but there are only a few lines' worth of ideas, the rest is a bunch of copy/pasted blocks (which no doubt means there are much more elegant ways to write it).
// Synchronism detector
// This code is built to run on an Arduino Uno.
// The hardware timer runs at 16MHz. Using a
// divide by 8 on the counter each count is
// 500 ns and a 50Hz wave cycle is 40000 clock cycles.
#include <avr/io.h>
#include <avr/interrupt.h>
void setup(){
// Set clock prescaler
// This is set to 'divide by 8' but if I can get away
// with using delay statements that doesn't really matter
TCCR1B &= ~(1 << CS12);
TCCR1B != ~(1 << CS11);
TCCR1B &= ~(1 << CS10);
// Set up pins
// 3rd bit of port D will be the activation flag
// 4th and 5th bits will be read pins for the incoming waves
DDRD = DDRD & B11100011
// Note that I'll also have the incoming waves going into the int0 and int1 pins
// 6th bit will be a write pin for the outgoing signal
DDRD = DDRD | B00100000
PORTD = PORTD & B11011111
// Set initial values for zero-cross detect flags
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
}
void loop(){
// Poll activation flag
if (((PIND & B00000100) >> 2) == 1)
// Poll wave input pins
wave_0 = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
// Check zero crossing detection,
// Start with wave 0, rising edge
if (wave_0 == 1 && wave_0_prev == 0))
attachInterrupt(int1,sync_interrupt, RISING);
delay(.0001);
detachInterrupt(int1);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
// Wave 0, falling edge
if (wave_0 == 0 && wave_0_prev == 1))
attachInterrupt(int1,sync_interrupt, FALLING);
delay(.0001);
detachInterrupt(int1);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
// Wave 1, rising edge
if (wave_1 == 1 && wave_1_prev == 0))
attachInterrupt(int0,sync_interrupt, RISING);
delay(.0001);
detachInterrupt(int0);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
// Wave 1, falling edge
if (wave_1 == 0 && wave_1_prev == 1))
attachInterrupt(int0,sync_interrupt, FALLING);
delay(.0001);
detachInterrupt(int0);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
}
sync_interrupt(){
// Set output bit high
PORTD = PORTD | B00100000
delay(.001}
// Set output bit low
PORTD = PORTD & B00100000
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
}
Thanks again for any help.
performance arduino arduino-uno
I am trying to use an Arduino Uno as part of a larger circuit that synchronizes two square voltage waveforms (those waveforms are fed into pins of the Uno). The Uno will be activated by a digital signal from another part of the larger circuit, and that activation signal will be sustained for a few seconds at a time. While the activation signal is HIGH, the Uno's job will just be to detect when its measured square waveforms are synchronized: it will monitor them and generate a pulse of its own if they reach their zero crossings within about 100 microseconds of each other (the square waves themselves are ~50Hz).
Because 100us is a pretty short window, I thought I'd try direct bit manipulation rather than using DigitalRead() or DigitalWrite(). This is my first time trying bit manipulation, though, and my C experience is pretty limited in general. I have the first draft of my code here - if any of you can tell me whether the logic of it seems sound, I would very much appreciate it!
It looks long, but there are only a few lines' worth of ideas, the rest is a bunch of copy/pasted blocks (which no doubt means there are much more elegant ways to write it).
// Synchronism detector
// This code is built to run on an Arduino Uno.
// The hardware timer runs at 16MHz. Using a
// divide by 8 on the counter each count is
// 500 ns and a 50Hz wave cycle is 40000 clock cycles.
#include <avr/io.h>
#include <avr/interrupt.h>
void setup(){
// Set clock prescaler
// This is set to 'divide by 8' but if I can get away
// with using delay statements that doesn't really matter
TCCR1B &= ~(1 << CS12);
TCCR1B != ~(1 << CS11);
TCCR1B &= ~(1 << CS10);
// Set up pins
// 3rd bit of port D will be the activation flag
// 4th and 5th bits will be read pins for the incoming waves
DDRD = DDRD & B11100011
// Note that I'll also have the incoming waves going into the int0 and int1 pins
// 6th bit will be a write pin for the outgoing signal
DDRD = DDRD | B00100000
PORTD = PORTD & B11011111
// Set initial values for zero-cross detect flags
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
}
void loop(){
// Poll activation flag
if (((PIND & B00000100) >> 2) == 1)
// Poll wave input pins
wave_0 = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
// Check zero crossing detection,
// Start with wave 0, rising edge
if (wave_0 == 1 && wave_0_prev == 0))
attachInterrupt(int1,sync_interrupt, RISING);
delay(.0001);
detachInterrupt(int1);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
// Wave 0, falling edge
if (wave_0 == 0 && wave_0_prev == 1))
attachInterrupt(int1,sync_interrupt, FALLING);
delay(.0001);
detachInterrupt(int1);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
// Wave 1, rising edge
if (wave_1 == 1 && wave_1_prev == 0))
attachInterrupt(int0,sync_interrupt, RISING);
delay(.0001);
detachInterrupt(int0);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
// Wave 1, falling edge
if (wave_1 == 0 && wave_1_prev == 1))
attachInterrupt(int0,sync_interrupt, FALLING);
delay(.0001);
detachInterrupt(int0);
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
)
}
sync_interrupt(){
// Set output bit high
PORTD = PORTD | B00100000
delay(.001}
// Set output bit low
PORTD = PORTD & B00100000
// Reset pins
wave_0 = ((PIND & B00001000) >> 3);
wave_0_prev = ((PIND & B00001000) >> 3);
wave_1 = ((PIND & B00010000) >> 4);
wave_1_prev = ((PIND & B00010000) >> 4);
}
Thanks again for any help.
performance arduino arduino-uno
performance arduino arduino-uno
edited Nov 22 '18 at 19:33
kb4444
asked Nov 22 '18 at 18:51
kb4444kb4444
154
154
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
OK, so I'm not too sure what exactly the interrupt flags are for this particular device, however personally I would say the easiest way to go about this is to have it such that you have 2 interrupts set up for each of the inputs and to have each of the interrupts blocks of code set up to activate the timer interrupt as well via a jump from an output pin. This way when one is activated if the other one is not activated within the timed period you can reset the interrupt flags, and if the second one is activated then you can run the code you wish to run when the waves are synchronised
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53436716%2farduino-detect-if-2-signals-change-within-100-microseconds-of-each-other%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
OK, so I'm not too sure what exactly the interrupt flags are for this particular device, however personally I would say the easiest way to go about this is to have it such that you have 2 interrupts set up for each of the inputs and to have each of the interrupts blocks of code set up to activate the timer interrupt as well via a jump from an output pin. This way when one is activated if the other one is not activated within the timed period you can reset the interrupt flags, and if the second one is activated then you can run the code you wish to run when the waves are synchronised
add a comment |
OK, so I'm not too sure what exactly the interrupt flags are for this particular device, however personally I would say the easiest way to go about this is to have it such that you have 2 interrupts set up for each of the inputs and to have each of the interrupts blocks of code set up to activate the timer interrupt as well via a jump from an output pin. This way when one is activated if the other one is not activated within the timed period you can reset the interrupt flags, and if the second one is activated then you can run the code you wish to run when the waves are synchronised
add a comment |
OK, so I'm not too sure what exactly the interrupt flags are for this particular device, however personally I would say the easiest way to go about this is to have it such that you have 2 interrupts set up for each of the inputs and to have each of the interrupts blocks of code set up to activate the timer interrupt as well via a jump from an output pin. This way when one is activated if the other one is not activated within the timed period you can reset the interrupt flags, and if the second one is activated then you can run the code you wish to run when the waves are synchronised
OK, so I'm not too sure what exactly the interrupt flags are for this particular device, however personally I would say the easiest way to go about this is to have it such that you have 2 interrupts set up for each of the inputs and to have each of the interrupts blocks of code set up to activate the timer interrupt as well via a jump from an output pin. This way when one is activated if the other one is not activated within the timed period you can reset the interrupt flags, and if the second one is activated then you can run the code you wish to run when the waves are synchronised
answered Nov 22 '18 at 21:59
dbradleydbradley
209
209
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53436716%2farduino-detect-if-2-signals-change-within-100-microseconds-of-each-other%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown