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....
#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);
}
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
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.
#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