Go Down

Topic: Receiver reader (Read 923 times) previous topic - next topic

skatun

May 30, 2008, 02:53 pm Last Edit: May 30, 2008, 03:02 pm by skatun Reason: 1
Hi
I have the following code which prints 500-530 all the time. I checked with oscilloscope and the width between the first falling edge and the next rising edge varies between 1.0ms and 2,0ms. Does anyone see the error in my code?

Cheers Kim
            ___                          ___                    ___
|           |     |                       |     |                  |     |
|           |     |                       |     |                  |     |
|______|      |_____________|     |__________|      |


there is 8 spaces where width varies. ) tops with constant width and then there is a sync pause which is about 11ms

The illustration above is for the first 3 channels....


Code: [Select]


#define icpPin 8    // this interrupt handler must use pin 8
#define TICKS_PER_uS 2    // number of timer ticks per microsecond
#define MAX_CHANNELS    8   // maximum number of channels we can store
#define SYNC_GAP_LEN (3000 * TICKS_PER_uS) // we assume a space at least 3000us is sync (note clock counts in 0.5 us ticks)
volatile unsigned int Pulses[ MAX_CHANNELS + 1]; // array holding channel pulses width value in microseconds
volatile uint8_t  Channel; // number of channels detected so far in the frame (first channel is 1)
volatile uint8_t State;   // this will be one of the following states:
#define NOT_SYNCHED_state  0    // the system is not synched so the data is random
#define ACQUIRING_state  1 // one sync pulse detected but not all channels have been received
#define READY_state     2 // synched and all channel data is valid
boolean stateChanged1 =  true;
boolean stateChanged2 =  true;
boolean stateChanged3 =  true;
boolean stateChanged4 =  true;






ISR(TIMER1_CAPT_vect){
  if(! bit_is_set(TCCR1B ,ICES1)){ // was falling edge detected ?  
     TCNT1 = 0;   // reset the counter
   if(Channel <= MAX_CHANNELS) {
       Pulses[Channel++] = ICR1/ TICKS_PER_uS;  // store pulse length as microsoeconds
    }
  }
 
  else {  // rising  edge was detected  
    TCNT1 = 0;   // reset the counter
    if(ICR1 >= SYNC_GAP_LEN){   // is the space between pulses big enough to be the SYNC
       Channel = 1; // if so, reset the channel counter to 1
       if(State == NOT_SYNCHED_state)
           State = ACQUIRING_state;  // this is the first sync pulse, we need one more to fill the channel data array
       else if( State == ACQUIRING_state)    
         State = READY_state;     // this is the second sync so flag that channel data is valid
    }  
  }
 
  TCCR1B ^= _BV(ICES1);     // toggle bit value to trigger on the other edge  
}

void setup()
{
 delay(5000);
 Serial.begin(9600);     // initialize serial communication with computer
 Serial.println("No startet serieporten");


 pinMode(icpPin,INPUT);
 Channel = 1;
 State = NOT_SYNCHED_state;
 TCCR1A = 0x00;   // COM1A1=0, COM1A0=0 => Disconnect Pin OC1 from Timer/Counter 1 -- PWM11=0,PWM10=0 => PWM Operation disabled
 TCCR1B = 0x02;   // 16MHz clock with prescaler means TCNT1 increments every .5 uS (cs11 bit set
 TIMSK1 = _BV(ICIE1);   // enable input capture interrupt for timer 1



 
}

int getChannelPulseWidth( uint8_t channel) {
 // this is the access function for channel data
 int result;
 if( (State == READY_state)  && (channel > 0) && (channel <=  MAX_CHANNELS)  ) {
    cli(); //disable interrupts
    result =  Pulses[channel] ;
    sei(); // enable interrupts
 }
 else
    result = 0;  // return 0 if no valid pulse is available

 return result;

}

void loop()   // run over and over again
{
// print the decoder state
  if(State == NOT_SYNCHED_state){
    //stateChanged = true;
    if (stateChanged1){
       Serial.println("The decoder has not detected a synch pulse ");  
       // receiver.setTxReception(false);
       stateChanged1 = false;
       }
  }
  else if ( State == ACQUIRING_state){
    //stateChanged = true;
     if (stateChanged2){
       Serial.println("The decoder has detected one synch pulse and has started filling channel data");
        //receiver.setTxReception(false);
        stateChanged2 = false;
        }
  }
  else if( State == READY_state){
    //stateChanged = true;
     if (stateChanged3){
        Serial.println("The decoder is synched and the channel data is valid");
         stateChanged3 = false;
    }
    Serial.print("Channel 1 pulsewidt is: ");
    Serial.println(getChannelPulseWidth(1));
   
   // Serial.print("Channel 2 pulsewidt is: ");
    // Serial.println(getChannelPulseWidth(2));
   
    //receiver.setTxReception(true);
  }
  else{
    //stateChanged = true;
    if (stateChanged4){
      Serial.println("Unknown decoder state, this should never happen!");
      //receiver.setTxReception(false);
      stateChanged4 = false;
    }
   
  }
  delay(1000);
}






mem

Hi Kim  :)

try changing:
if(! bit_is_set(TCCR1B ,ICES1)){ // was falling edge detected ?
to
if( bit_is_set(TCCR1B ,ICES1)){ // was rising edge detected ?

removing the !  before bit_is_set allows the code measures time from falling up to the rising edges

skatun

Hmm
That didn't work for some reason, need to do some more debugging I guess....

mem

What output pulse widths you are seeing printed to the serial port?

skatun

Will get back to u monday avro... Then I will have my whole thing up running again...

Cheers Kim

skatun

Tx on:
Channel1 pulsewidt is: 123
Channel2 pulsewidt is: 36
Channel1 pulsewidt is: 143
Channel2 pulsewidt is: 293
Channel1 pulsewidt is: 71
Channel2 pulsewidt is: 167
Channel1 pulsewidt is: 391
Channel2 pulsewidt is: 234
Channel1 pulsewidt is: 137
Channel2 pulsewidt is: 54
Channel1 pulsewidt is: 170
Channel2 pulsewidt is: 133
Channel1 pulsewidt is: 296
Channel2 pulsewidt is: 60

Tx off:
Channel2 pulsewidt is: 237
Channel1 pulsewidt is: 262
Channel2 pulsewidt is: 550
Channel1 pulsewidt is: 89
Channel2 pulsewidt is: 348
Channel1 pulsewidt is: 136
Channel2 pulsewidt is: 206
Channel1 pulsewidt is: 158
Channel2 pulsewidt is: 344
Channel1 pulsewidt is: 246
Channel2 pulsewidt is: 110
Channel1 pulsewidt is: 513
Channel2 pulsewidt is: 286



bit_is_set(TCCR1B ,ICES1):
The decoder has not detected a synch pulse
The decoder has not detected a synch pulse
The decoder has not detected a synch pulse
The decoder has not detected a synch pulse
The decoder has not detected a synch pulse
The decoder has not detected a synch pulse
The decoder has not detected a synch pulse
The decoder has not detected a synch pulse


Well this doesnt make sence to me at all...

mem

You could try a test using an arduino pin to drive the input. Write a sketch that  pulses a pin at a know rate, say a sequence of pulses of alternating 1ms and 2ms pulses with a delay in between of sat 500 us. Connect the output to the pin 8 through a 1k resistor and see if you get more sensible results.

skatun

#7
Jun 09, 2008, 08:30 pm Last Edit: Jun 09, 2008, 08:48 pm by skatun Reason: 1
did that...

Code: [Select]

#define icpPin 8    // this interrupt handler must use pin 8
#define TICKS_PER_uS 2    // number of timer ticks per microsecond
#define MAX_CHANNELS    8   // maximum number of channels we can store  
#define SYNC_GAP_LEN (3000 * TICKS_PER_uS) // we assume a space at least 3000us is sync (note clock counts in 0.5 us ticks)
volatile unsigned int Pulses[ MAX_CHANNELS + 1]; // array holding channel pulses width value in microseconds
volatile uint8_t  Channel; // number of channels detected so far in the frame (first channel is 1)
volatile uint8_t State;   // this will be one of the following states:
#define NOT_SYNCHED_state  0    // the system is not synched so the data is random
#define ACQUIRING_state  1 // one sync pulse detected but not all channels have been received
#define READY_state     2 // synched and all channel data is valid

#define outPin 7

long previousMillis = 0;        // will store last time LED was updated
long interval = 3000;           // interval at which to blink (milliseconds)

ISR(TIMER1_CAPT_vect){
 if(bit_is_set(TCCR1B ,ICES1)){ // was falling edge detected ?  
   TCNT1 = 0;   // reset the counter
   if(Channel <= MAX_CHANNELS) {
     Pulses[Channel++] = ICR1 / TICKS_PER_uS;  // store pulse length as microsoeconds
   }
 }

 else {  // rising  edge was detected  
   TCNT1 = 0;   // reset the counter
   if(ICR1 >= SYNC_GAP_LEN){   // is the space between pulses big enough to be the SYNC
     Channel = 1; // if so, reset the channel counter to 1  
     if(State == NOT_SYNCHED_state)
       State = ACQUIRING_state;  // this is the first sync pulse, we need one more to fill the channel data array
     else if( State == ACQUIRING_state)    
       State = READY_state;     // this is the second sync so flag that channel data is valid
   }    
 }

 TCCR1B ^= _BV(ICES1);     // toggle bit value to trigger on the other edge    
}

void setup()
{
 delay(2000);
 Serial.begin(9600);     // initialize serial communication with computer
 Serial.println("No startet serieporten");

 pinMode(outPin, OUTPUT);      // sets the digital pin as output
 pinMode(icpPin,INPUT);
 Channel = 1;  
 State = NOT_SYNCHED_state;
 TCCR1A = 0x00;   // COM1A1=0, COM1A0=0 => Disconnect Pin OC1 from Timer/Counter 1 -- PWM11=0,PWM10=0 => PWM Operation disabled
 TCCR1B = 0x02;   // 16MHz clock with prescaler means TCNT1 increments every .5 uS (cs11 bit set
 TIMSK1 = _BV(ICIE1);   // enable input capture interrupt for timer 1




}

int getChannelPulseWidth( uint8_t channel) {
 // this is the access function for channel data
 int result;  
 if( (State == READY_state)  && (channel > 0) && (channel <=  MAX_CHANNELS)  ) {
   cli(); //disable interrupts
   result =  Pulses[channel] ;
   sei(); // enable interrupts
 }
 else
   result = 0;  // return 0 if no valid pulse is available  

 return result;

}


void generateTx(){




   for (int ii=0; ii++;ii<9){
   digitalWrite(outPin, HIGH);   // sets the pin on
   delayMicroseconds(500);        // pauses for 50 microseconds      
   digitalWrite(outPin, LOW);    // sets the pin off
   delayMicroseconds(1000+ii*60);        // pauses for 50 microseconds
 }  
}




void loop()   // run over and over again
{
 generateTx();
 // print the decoder state
 if(State == NOT_SYNCHED_state){
   Serial.println("The decoder has not detected a synch pulse ");  
   // receiver.setTxReception(false);
 }  
 else if ( State == ACQUIRING_state){
   Serial.println("The decoder has detected one synch pulse and has started filling channel data");  
   //receiver.setTxReception(false);  
 }
 else if( State == READY_state){
   // Serial.println("The decoder is synched and the channel data is valid");  
   if (millis() - previousMillis > interval) {
     previousMillis = millis();             // remember the last time we blinked the LED
     Serial.print("Channel1 pulsewidt is: ");
     Serial.println(getChannelPulseWidth(1));

     Serial.print("Channel2 pulsewidt is: ");
     Serial.println(getChannelPulseWidth(2));
   }

   //receiver.setTxReception(true);
 }  
 else{
   Serial.println("Unknown decoder state, this should never happen!");
   //receiver.setTxReception(false);
   delay(1000);
 }  
 delay(5);
}







But maybe sth is wrong in this code.... cant detect sync pulse

mem

Kim , try changing
 for (int ii=0; ii++;ii<9){
to
 for (int ii=0; ii < 9; ii++){

skatun

still the same, decode has not deteced sync pulse, do u read ur emails? Do u have a dual crystallaying around?

Cheers Kim

mem

try this:
void generateTx(){
   for (int ii=0; ii< MAX_CHANNELS; ii++) {
         digitalWrite(outPin, HIGH);   // sets the pin on
         delayMicroseconds(1000 +  (ii*100) );      
         digitalWrite(outPin, LOW);    // sets the pin off
         delayMicroseconds(50);        // pauses for 50 microseconds      
  }  
  delay(4);  4000 us sync gap
}


I will be logging off shortly, back on tomorrow morning, good luck


Go Up