0

I'm trying to replicate a waveform exactly using external and timing interrupts. I've got an external that's setup as a 0ms reference, TIMER1 which is used to determine on time, and TIMER2, which sets the low period. Unfortunately, I can't get the pin low for 2ms. TIMER2 must have something wrong with it, but I can't find it. Instead of banging my head against the wall, I thought I'd ask you guys. Anyone know the answer?

//3 is interrupt for Timing
//4 through 11 are Time dependent receivers
//3-11 Pins 12-19

//Current Serial Byte(Letter or Number)
char incomingByte = 0;
//Previous Byte in the Serial Chain
char previousByte = 0;

//Iterator for Interrupt Values
volatile unsigned int maincount = 0;

//Time of High Period or Timer Duration
volatile unsigned int timerhigh;

//Output Pin for Timer Waveform
volatile unsigned int waveout;

//Time for Timer Delay in milliseconds, default tim
volatile unsigned int groundtime = 0;

//Receiver Pins in an Array, except for 3, which serves as 0 source reference
int pins[9] =
{
  3,4,5,6,7,8,9,10,11
};

void rising()
{   
  // set up Timer 1
  TCCR1A = 0;  // normal mode
  TCCR1B = bit(WGM12) | bit(CS11);  // CTC, scale to clock / 8
  OCR1A = timerhigh;          // time before timer fires
  TIMSK1 = bit (OCIE1A);            // interrupt on Compare A Match
}


//Sets Pin Low, then sets up another timer interrupt for the jump back to high
ISR(TIMER1_COMPA_vect)
{
 //Brings Pin Low for Keypress
 //Serial.println("We're in Timer 1");
 pinMode(waveout,OUTPUT);
 digitalWrite(waveout, LOW);

 //Stop Timer 1
 TCCR1B = 0;                      // stop timer
 TIMSK1 = 0;                      // cancel timer interrupt

 //Disables Interrupts Before Messing
 cli();
 // set up Timer 2
 TCCR2A = 0;  // normal mode
 TCCR2B = 0;
 //  TCCR2A = bit(WGM21) | bit(CS21);  // CTC, scale to clock / 8
 TCCR2A = (1 << WGM21); //Enables CTC for timer 
 TCCR2B = (1 << CS21); //Sets 8 bit prescaler
 OCR2A = groundtime;          // time before timer fires
 TIMSK2 = (1 << OCIE2A);

 //Cancel Rising Interrupt on D3
 EIFR = bit (INTF1); 
 //Reenables interrupts
 sei();
}

//Timer Interrupt for Low Period
ISR(TIMER2_COMPA_vect)
{
//Serial.println("WE'RE IN TIMER2");
//Brings Output pin high
digitalWrite(waveout, HIGH);

//Stop Timer 2
TCCR2B = 0;                      // stop timer
TIMSK2 = 0;                      // cancel timer interrupt  

//Cancel Rising Interrupt on D3
 EIFR = bit (INTF1);   
}

void setup() {
  // put your setup code here, to run once:

//Sets all the pins for output use
for(int i=0;i<8;i++)
{
  pinMode(pins[i], INPUT);
}

//Sets Reference Pin as Input
pinMode(3,INPUT);


//Begins Serial
Serial.begin(115200);

//Cancels Timer 1
TCCR1A = 0;  // normal mode
TCCR1B = 0;  // stop timer
TIMSK1 = 0;   // cancel timer interrupt

//Cancels Timer 2
 TCCR2A = 0;
 TCCR2B = 0;                      // stop timer
 TIMSK2 = 0;                      // cancel timer interrupt  
detachInterrupt(1);

}

void loop() {

  //Time of Ground Drop(2 mS), Universal for all letters and offsets
  groundtime = 40000;     // spark time (4000 * 500 nS) = 2 mS

  // because of prescaler of 8, each unit is 500 nS (0.5 µS)

     if(Serial.available()> 0);
    {
   //Reads Serial Value and assigns to incomingByte
   incomingByte = Serial.read();
   attachInterrupt(1,rising,RISING);
    }
  //  noInterrupts ();  // atomic change of the time amount

   //In this area, we'll set the output pin to be used by the timing interrupt, 
   //and the time delay off the default waveform present on pin 4

   //We can use switch case arrangement, don't know if that's the optimal setup though    
 switch(incomingByte)
 {
   default:
   //Do Nothing
   break;

   //Cases FOR ALL THE LETTERS
   case 'a':
   break;
   case 'b':
   break;
   case 'c':
   break;
   case 'd':
   break;
   case 'e':
   break;
   case 'f':
   break;
   case 'g':
   break;
   case 'h':
   break;
   case 'i':
   break;
   case 'j':
   break;
   case 'k':
   break;
   case 'l':
   break;
   case 'm':
   break;
   case 'n':
   break;
   case 'o':
   break;
   case 'p':
   break;
   case 'q':
   break;
   case 'r':
   //Output pin 17 Frequency Pin 10
   //microseconds
   timerhigh=8000;
   waveout=9;
   break;
   case 's':
   break;
   case 't':
   break;
   case 'u':
   break;
   case 'v':
   break;
   case 'w':
   break;
   case 'x':
   break;
   case 'y':
   break;
   case 'z':
   break;

   //Cases FOR ALL THE NUMBERS
   case '0':
   break;
   case '1':
   break;
   case '2':
   break;
   case '3':
   break;
   case '4':
   break;
   case '5':
   break;
   case '6':
   break;
   case '7':
   break;
   case '8':
   break;
   case '9':
   break;

   //Cases FOR ALL THE PUNCTUATION
   case '.':
   break;
   case ',':
   break;
   case '!':
   break;
   case '"':
   break;
   case '#':
   break;
   case '$':
   break;
   case '%':
   break;      
 }

//Enables Rising Interrupt for 0ms detection
//attachInterrupt(1,rising,RISING);

//Reenables interrupts after offset time change
//interrupts ();
}
5

Turns out the problem was that timer 0 and 2 on the arduino uno are 8 bit. Set a different prescaler and I'm golden

// set up Timer 2
    TCCR2A = 0;  // normal mode
    TCCR2B = 0;
    //  TCCR2A = bit(WGM21) | bit(CS21);  // CTC, scale to clock / 8
    TCCR2A = (1 << WGM21); //Enables CTC for timer 

    TCCR2B |= (1 << CS21); 
    TCCR2B |= (1 << CS22); //Sets 256 bit prescaler
    TCCR2B |= (0 << CS20); 
    OCR2A = groundtime;    // time before rising edge
    TIMSK2 = (1 << OCIE2A);
    //Cancel Rising Interrupt on D3
    EIFR = bit (INTF1); 
    //Reinables interrupts

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.