1

I'm writing software for a laser tag gun, which under the system we use needs the output waveform to be a carrier wave of 57600Hz with a signal wave of 1800HZ for about 50ms

Using the Tone library (https://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation) and a transistor AND gate, I've had this working using two timers, however I really want to shrink it down to one timer so that I can use the other for sound (using the TMRPCM library which only needs timer1).

I've modified the Tone library cut down to what I need, with the following methods:

void TagTone::beginPulse(uint8_t tonePin)
{
 _pin = tonePin;
 _timer = 2;
 // 8 bit timer
 TCCR2A = 0;
 TCCR2B = 0;
 bitWrite(TCCR2A, WGM21, 1);
 bitWrite(TCCR2B, CS20, 1);
 timer2_pin_port = portOutputRegister(digitalPinToPort(_pin));
 timer2_pin_mask = digitalPinToBitMask(_pin);
 int duration = 50; //50 milliseconds
 uint8_t prescalarbits = 0b001;
 int32_t signal_toggle_count = 0;
 // Note: may need prescaler reimplemented if using 16Mhz, fine on current 8Mhz
 ocr = F_CPU / (CARRIER_FREQUENCY * 2) - 1;
 prescalarbits = 0b001; 
 TCCR2B = (TCCR2B & 0b11111000) | prescalarbits;
 toggle_count = 2 * CARRIER_FREQUENCY * duration / 1000; // how many times the carrier toggles before pulse ends
 // want to AND with 1800 Hz signal
 // as duration now set to 50: toggle_count for carrier = 5760
 // equivalent toggle count for signal = 180
 signal_toggle_count = 2* SIGNAL_FREQUENCY * duration / 1000;
 // want to flip signal state every 32 carrier pulses
 signal_cycle_count = 32; //toggle_count / signal_toggle_count;
}
// duration (in milliseconds).
void TagTone::playPulse()
{
 OCR2A = ocr;
 timer2_signal_toggle_count = signal_cycle_count;
 timer2_toggle_count = toggle_count;
 bitWrite(TIMSK2, OCIE2A, 1);
}
ISR(TIMER2_COMPA_vect)
{
 if(timer2_toggle_count < 0)
 {
 *timer2_pin_port ^= timer2_pin_mask & signal_state; // flip
 if (timer2_signal_toggle_count > 0)
 {
 timer2_signal_toggle_count--;
 }
 else
 {
 signal_state ^= signal_state;
 timer2_toggle_count -= timer2_signal_toggle_count;
 timer2_signal_toggle_count = signal_cycle_count;
 }
 }
 else
 {
 TIMSK2 &= ~(1 << OCIE2A); // disable the interrupt
 *timer2_pin_port &= ~(timer2_pin_mask); // keep pin low after stop
 }
}

What I hope this is doing is 32 toggles at the carrier speed (ie 16 full cycles of 57600Hz), followed by 32 'silent' toggles where nothing happens, followed by another 32 at carrier speed, etc. I should then be able to fire using:

digitalWrite(signalPin, HIGH);
carrierTone.playPulse();
delay(60);
digitalWrite(signalPin, LOW);

But that doesn't set off the sensor, whereas the simple code below works.

carrierTone.play(57600, 50);
signalTone.play(1800, 50);
asked May 2, 2015 at 9:48

1 Answer 1

0

Woo, solved it. My ISR code was completely wrong. Works using:

ISR(TIMER2_COMPA_vect)
{
 if (timer2_signal_toggle_count != 0)
 {
 // toggle the pin
 if(signal_state == 1)
 *timer2_pin_port ^= timer2_pin_mask;
 if (timer2_toggle_count > 0)
 timer2_toggle_count--; 
 else
 {
 TIMSK2 &= ~(1 << OCIE2A); // disable the interrupt
 *timer2_pin_port &= ~(timer2_pin_mask); // keep pin low after stop
 }
 timer2_signal_toggle_count --; 
 }
 else
 {
 timer2_signal_toggle_count = signal_cycle_count;
 timer2_toggle_count --;
 if(signal_state == 1)
 {
 signal_state = 0;
 *timer2_pin_port &= ~(timer2_pin_mask);
 //*timer2_pin_port ^= timer2_pin_mask;
 }
 else 
 {
 signal_state = 1;
 *timer2_pin_port ^= timer2_pin_mask;
 }
 }
}

I was trying to just AND the signal state into the original pin state, which was completely the wrong thing to do.

answered May 3, 2015 at 12:22

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.