Go Down

Topic: 3 axis auto stabilized platform (Read 31882 times) previous topic - next topic

DiMiz

Ok is very late in Italy, but im very excited with my project so i describe what i have reached...not too much:)
I copy and paste your Libray in arduino-0011/hardware/libraries/ServoInput2
ServoInput2.h
Code: [Select]
//*****************ServoInput2.h*************************************
#ifndef ServoInput2_H
#define ServoInput2_H

#include <inttypes.h>

#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)
#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

class ServoInput2
{
 public:
       ServoInput2(); //Constructor
       int GetChannelPulseWidth(uint8_t);  // this is the access function for channel data
       uint8_t getState(); //State Function

private:
};

extern ServoInput2 ServoInput;  // make an instance for the user
#endif

and ServoInput2.cpp
Code: [Select]
//******** servoInput.cpp *********

extern "C" {
       // AVR LibC Includes
#include <inttypes.h>
#include <avr/interrupt.h>
#include "WConstants.h"
       }

#include "ServoInput2.h"
#include <wiring.h>
//#include <avr/interrupt.h>


static volatile unsigned int Pulses[ MAX_CHANNELS + 1]; // array holding channel pulses width value in microseconds
static volatile uint8_t  Channel;      // number of channels detected so far in the frame (first channel is 1)
static volatile uint8_t State;         // this will be one of the following states:



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
}


ServoInput2::ServoInput2()
{
 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
}


uint8_t ServoInput2::getState()  
{
 return State;
}


int ServoInput2::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;
}

ServoInput2 ServoInput = ServoInput2() ;


As you can see i have made some mod using your post #121 with bGatti because i found some undefined error when compile
and my sketch is
follow in the next post...

DiMiz

ok my sketch is
Code: [Select]
// this sketch cycles three servos at different rates

#include <ServoTimer2.h>  // the servo library
#include <ServoInput2.h>


// define the pins for the servos
#define rollPin  13
#define pitchPin 13
#define yawPin   13

ServoTimer2 servoRoll;    // declare variables for up to eight servos
ServoTimer2 servoPitch;
ServoTimer2 servoYaw;
// ServoInput2 ServoInput();  // remove this because its declared in the source file.

void setup() {
 servoRoll.attach(rollPin);     // attach a pin to the servos and they will start pulsing
 servoPitch.attach(pitchPin);
 servoYaw.attach(yawPin);


 Serial.begin(9600);  

 
}


// this function just increments a value until it reaches a maximum
int incPulse(int val, int inc){
  if( val + inc  > 2000 )
     return 1000 ;
  else
      return val + inc;  
}

void loop()
{
int val;
 
  val = incPulse( servoRoll.read(), 1);
  servoRoll.write(val);

  val =  incPulse( servoPitch.read(), 2);
  servoPitch.write(val);
 
  val = incPulse(servoYaw.read(), 4);
  servoYaw.write(val);


int pulsewidth;

  // print the decoder state
  if(ServoInput.getState() == NOT_SYNCHED_state)
      Serial.println("The decoder has not detected a synch pulse ");  
  else if (ServoInput.getState() == ACQUIRING_state)
      Serial.println("The decoder has detected one synch pulse and has started filling channel data");  
  else if(ServoInput.getState() == READY_state)
     Serial.println("The decoder is synched and the channel data is valid");  
  else
     Serial.println("Unknown decoder state, this should never happen!");
 

 // now print the channel pulse widths
 // they should be 0 if the state is not ready
 for ( int i =1; i <=4; i++ ){ // print the status of the first four channels
     Serial.print("Channel ");
     Serial.print(i);
     Serial.print(" has width ");
     pulsewidth = ServoInput.GetChannelPulseWidth(i);
     Serial.println(pulsewidth);
 }
  delay(10); // update 10 times a second        

 
}


but my debug is:
---
The decoder has not detected a synch pulse

Channel 1 has width 0

Channel 2 has width 0

Channel 3 has width 0

Channel 4 has width 0

The decoder has not detected a synch pulse

---
About my R/C Signal:
1- i Have found from oscilloscope the PPM frame and seems of 10ms not the usually 20ms
2- the sync frame seems 440/450us not 3000 as you defined in ServoInput2.h, i have try to mod but not seems to affect nothing...

Many thanks for possible help, if you need other info please ask me!!

DiMiz

Also some image of my PPM signal
and my Arduino & R/C receiver attached...


I hope my info is usefull
Thanks Dimi

bGatti

DiMaz,

I notice in your Oscope that your signal is an inversion of my signal.
This is not to say yours is upside down, only something to consider.

I think you might benefit from inverting the interupt code.

For reference, this version compiled:

Code: [Select]
//***Save As ServoInput2.h ************************************ServoInput2*************************************
//This add-on to ServoTimer2 provides for the reading of typical RC composite servo inputs
//To save the extra memory used by this add-on library include the line:  (sharp)define omitServoInput2

#ifndef omitServoInput2
#define omitServoInput2

#include <wiring.h>
#include <avr/interrupt.h>
#include <inttypes.h>

#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


class ServoInput2
{
 public:
     ServoInput2(); //Constructor

     uint8_t getState(); //State Function
     int GetChannelPulseWidth(uint8_t);  // this is the access function for channel data
     void attach(); //Initialize

private:


};

//extern ServoInput2 ServoInput;  // make an instance for the user

#endif


Code: [Select]

extern "C" {
 // AVR LibC Includes
 #include <inttypes.h>
 #include <avr/interrupt.h>
 #include "WConstants.h"
}


#include "ServoInput2.h"

#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)


static volatile unsigned int Pulses[ MAX_CHANNELS + 1]; // array holding channel pulses width value in microseconds  
static volatile uint8_t  Channel;      // number of channels detected so far in the frame (first channel is 1)
static volatile uint8_t State;         // this will be one of the following states:




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  
        digitalWrite( 13,HIGH); //prove detect on high

       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
}


ServoInput2::ServoInput2()
{
 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
}



uint8_t ServoInput2::getState()
{
  return State;
}



int ServoInput2::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;
}

//ServoInput2 ServoInput = ServoInput2() ;





And the Sketch:
[code]

// this sketch cycles three servos at different rates

#include <ServoTimer2.h>  // the servo library
#include <ServoInput2.h>

// define the pins for the servos
#define rollPin 13
#define NBR_SERVOS 8   // this must be between 1 and NBR_CHANNELS as defined in ServoTimer2.H
byte servoPins[NBR_SERVOS] = {9,9,9,9,0,0,9,9};  // pins our servos are attached to
ServoTimer2 Servos[NBR_SERVOS]  ;
ServoInput2 ServoInput;

int direction[NBR_SERVOS];   // 1 is forward, -1 is reverse

void setup() {
 for( int i =0; i < NBR_SERVOS; i++){
       direction = 1;  //  forward
         if(servoPins >1)
           Servos.attach(servoPins); // this will start pulsing the pin!

//        Servos.write( 800 + (i * 200));  // writing to an unattched pin is ok

//       Servos.write( 800 + (i * 200));  // write some test data       
 Serial.begin(9600);  
   }    
}
 

void loop()
{
 
 // print the decoder state
  if(ServoInput.getState() == NOT_SYNCHED_state)
      Serial.println("The decoder has not detected a synch pulse ");  
  else if (ServoInput.getState() == ACQUIRING_state)
      Serial.println("The decoder has detected one synch pulse and has started filling channel data");  
  else if(ServoInput.getState() == READY_state)
    Serial.println("The decoder is synched and the channel data is valid");  
  else
    Serial.println("Unknown decoder state, this should never happen!");

 // now print the channel pulse widths
 // they should be 0 if the state is not ready
 int pulseWidth;

   //sweep all the servos back and forth
   for( int i=0; i <  NBR

bGatti

Looks like the Sketch was truncated:

Here again - the Sketch:

Code: [Select]


// this sketch cycles three servos at different rates

#include <ServoTimer2.h>  // the servo library
#include <ServoInput2.h>

// define the pins for the servos
#define rollPin 13
#define NBR_SERVOS 8   // this must be between 1 and NBR_CHANNELS as defined in ServoTimer2.H
byte servoPins[NBR_SERVOS] = {9,9,9,9,0,0,9,9};  // pins our servos are attached to
ServoTimer2 Servos[NBR_SERVOS]  ;
ServoInput2 ServoInput;

int direction[NBR_SERVOS];   // 1 is forward, -1 is reverse

void setup() {
 for( int i =0; i < NBR_SERVOS; i++){
       direction[i] = 1;  //  forward
         if(servoPins[i] >1)
           Servos[i].attach(servoPins[i]); // this will start pulsing the pin!

//        Servos[i].write( 800 + (i * 200));  // writing to an unattched pin is ok

//       Servos[i].write( 800 + (i * 200));  // write some test data       
 Serial.begin(9600);  
   }    
}
 

void loop()
{
 
 // print the decoder state
  if(ServoInput.getState() == NOT_SYNCHED_state)
      Serial.println("The decoder has not detected a synch pulse ");  
  else if (ServoInput.getState() == ACQUIRING_state)
      Serial.println("The decoder has detected one synch pulse and has started filling channel data");  
  else if(ServoInput.getState() == READY_state)
    Serial.println("The decoder is synched and the channel data is valid");  
  else
    Serial.println("Unknown decoder state, this should never happen!");

 // now print the channel pulse widths
 // they should be 0 if the state is not ready
 int pulseWidth;

   //sweep all the servos back and forth
   for( int i=0; i <  NBR_SERVOS; i++){
         pulseWidth = ServoInput.GetChannelPulseWidth(i);
       //pulseWidth = Servos[i].read();
       
       if(pulseWidth >= MAX_PULSE_WIDTH){
           direction[i] = -1;
       }
       if (pulseWidth <= MIN_PULSE_WIDTH) {
            direction[i] = 1;    
       }
      Servos[i].write(pulseWidth + direction[i]);      
   }
  delay(10); // update 10 times a second        
}



End Code

DiMiz

#140
Jun 10, 2008, 11:46 am Last Edit: Jun 10, 2008, 11:50 am by DiMiz Reason: 1
Hi bGatti thanks for your reply, about my Oscope signal probably i invert the signal function ;-) im not sure last was very late so probably i have made some error on using my Oscope...but i will try your code to test my R/C receive.
Are try to create a QuadCopter or something similar? If im able to capture my R/C command my second step is use a accelorometer to stabilized the copter, have made some work on it?
Many thanks
Ps: Using your posted code are you able to Capture the signal without problem?

mem

#141
Jun 10, 2008, 12:15 pm Last Edit: Jun 10, 2008, 12:16 pm by mem Reason: 1
Hi DiMiz, looking at your scope trace I think the version below may work for you. Try it and let us know if if finds the sync and what output pulse widths are reported on the serial port

Code: [Select]


ISR(TIMER1_CAPT_vect)
{
 if(! bit_is_set(TCCR1B ,ICES1)){       // was falling edge 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
   }    
   else if(Channel <= MAX_CHANNELS) {  // else its channel pulse so save it
     Pulses[Channel++] = ICR1 / TICKS_PER_uS;  // store pulse length as microsoeconds
   }      
 }
 else {                          // rising  edge was detected  
   TCNT1 = 0;               // reset the counter      

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

mem

#142
Jun 10, 2008, 12:46 pm Last Edit: Jun 10, 2008, 12:48 pm by mem Reason: 1
This code is functionally similar to the above but I hope it is easier to understand and customize.  

Code: [Select]

#define PULSE_STARTS_ON_RISING_EDGE   // un-comment this if the output goes positive for duration of the pulse
//#define PULSE_STARTS_ON_FALLING_EDGE   // un-comment this if the output goes to 0 for duration of the pulse


ISR(TIMER1_CAPT_vect)
{
// we want to measure the time to the end of the pulse
#if defined PULSE_STARTS_ON_RISING_EDGE
 if(bit_is_clear(TCCR1B ,ICES1)){       // was falling edge detected ?  
#else  
 if( bit_is_set(TCCR1B ,ICES1)){       // was rising edge detected ?
#endif  
   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
   }    
   else if(Channel <= MAX_CHANNELS) {  // else its channel pulse so save it
     Pulses[Channel++] = ICR1 / TICKS_PER_uS;  // store pulse length as microsoeconds
   }      
 }
 else {        // the start of the pulse was detected  
   TCNT1 = 0;        // so reset the counter to start timeing

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


I have not run the code in this form so please report if you have problems.

DiMiz

Many thanks Mem I will test it and report my progress this night, thanks so much!!!

bGatti

Mem,
I noticed a shift in the pulse direction.
Do you think we could add "auto-shift-detection"? That's a pretty common feature of modern receivers.
I'm thinking measure each input change and set the shift bit based on the longest state.

Ben

bGatti

DiMiz,
Yes, I made good progress on 3 Axis Accel. I used the cheapest 3 Axis part from Sparkfun (~$19 on breakout board). I provided Sketch and hookup.

Also, your signal is probably inverted (not your scope). You'll need to use mem's invertible code.

Ben

DiMiz

Hi bGatti what is the part number of Accelometer, so i try to find a reseller in Italy?
Many thanks for help i test Mem code this night

mem

#147
Jun 10, 2008, 06:38 pm Last Edit: Jun 10, 2008, 06:40 pm by mem Reason: 1
Quote
Do you think we could add "auto-shift-detection"?
Ben

Here is a version that checks to see if an 'inverted' sync pulse is found when acquiring the signal and inverts the mode accordingly. Its completly untested but you can try it if you want.

Code: [Select]

#define PULSE_START_ON_RISING_EDGE  0
#define PULSE_START_ON_FALLING_EDGE 1
volatile byte pulseEnd = PULSE_START_ON_RISING_EDGE ; // default value

ISR(TIMER1_CAPT_vect)
{
// we want to measure the time to the end of the pulse

 if( (_SFR_BYTE(TCCR1B) & (1<<ICES1)) == pulseEnd ){
   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
   }    
   else if(Channel <= MAX_CHANNELS) {  // else its channel pulse so save it
     Pulses[Channel++] = ICR1 / TICKS_PER_uS;  // store pulse length as microsoeconds
   }      
 }
 else {        // the start of the pulse was detected  
   TCNT1 = 0;        // so reset the counter to start timing
   if( State != READY_state && (ICR1 >= SYNC_GAP_LEN) ){   // are we trying to acquire a frame and have we found a sync pulse
       pulseMode ^= 1; // found sync on the wrong end of the pulse so invert the mode    
   }
 }      
 TCCR1B ^= _BV(ICES1);         // toggle bit value to trigger on the other edge
}


DiMiz

Ok im back ;-)
I have tested every Mod post by Mem using my posted files (ServoInput2.h,ServoInput2.cpp) and also the files posted by bGatti, with the mod to detect inverted signal, but the same thing..
----
The decoder has not detected a synch pulse
Channel 1 has width 0
Channel 2 has width 0
Channel 3 has width 0
Channel 4 has width 0
----
How can i help to debug the problem?
I here to keep every suggest :-)
Thanks

DiMiz

Update!! Only to test my R/C receiver i used the old code

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    4         // maximum number of channels we want  
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)

boolean DataAvailable; // set to true when we have received data for all channels
boolean Ready;         // true when we are ready to detect the leading edge of a channel

int RefreshTime = 2;
int lastPulse;

int a = 13;
int b = 12;
int c = 11;
int g = 6;

// here is the logic of how this code works :
// to start, channel is set to 1 and ready to false and the DataAvailable flag is false
// when a negative edge is detected ready is set to true
// when a positive edge is detected and ready is true then the measurement starts
// when a negative edge is detected and the ready flag is true then the measurement ends, the ready flag is reset back to false
//  and the channel is incremented. If the channel count after incrementing is greater than the number of channels then
//  the DataAvailable flag is set true and pulse data can be accessed

ISR(TIMER1_CAPT_vect){
  if( !bit_is_set(TCCR1B ,ICES1)){       // was falling edge detected ?  
        if(Ready) {
             Pulses[Channel] = ICR1 / TICKS_PER_uS;  // store pulse length as microsoeconds
                if (Pulses[Channel] > 10000)
                    {
                      Channel=1;
                     } else {
                       Channel++;
                     }  
                 if(Channel > MAX_CHANNELS)
                       //if((Pulses[Channel]< 10000) && (++Channel > MAX_CHANNELS)) //Add to check last edge DIMI
                   {
                   Channel = 1;       //reset the channel counter to 1      
                   DataAvailable = true;  // this line is needed to indicate that the channel data is valid!!!!
                   }
             //SelectChannel( Channel); // Remove by DIMI
             // Add code here to gate the multiplexer to the current channel            
        }
        Ready = !Ready;  //toggle the ready flag
  }
  else {                       // rising  edge was detected  
       TCNT1 = 0;               // reset the counter      
                         
  }      
  TCCR1B ^= _BV(ICES1);                 // toggle bit value to trigger on the other edge    
}

void setup()                    // run once, when the sketch starts
{
 Serial.begin(9600);  
 
 pinMode(icpPin,INPUT);
     
 pinMode(g,OUTPUT);
 pinMode(a,OUTPUT);
 pinMode(b,OUTPUT);
 pinMode(c,OUTPUT);
 pinMode(2,OUTPUT);
 pinMode(3,OUTPUT);
 pinMode(4,OUTPUT);
 pinMode(7,OUTPUT);
 
 Channel = 1;            
 Ready = false;
 DataAvailable = false;
 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
 
}

void SelectChannel( int channel){
   digitalWrite(g,HIGH);  // turn the output off while twiddling select bits
   if(Channel == 1)
   {
      digitalWrite(a,LOW);
      digitalWrite(b,LOW);            
   }
   else if(Channel == 2)
   {
      digitalWrite(a,HIGH);
      digitalWrite(b,LOW);
   }
     else if(Channel == 3)
     {
      digitalWrite(a,LOW);
      digitalWrite(b,HIGH);
     }
     digitalWrite(c,LOW);   // c is always low

     digitalWrite(g,LOW);  // turn output on    
}


int GetChannelPulseWidth(uint8_t Channel) {
 // this is the access function for channel data
 int result;  
 if( DataAvailable  && (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
{
 
int pulsewidth;

 
     // print the decoder state
  if(DataAvailable == false)
     {// Serial.println("The decoder has not detected all channels ");  
}
  else  
       {

/*       PulseServo(1,GetChannelPulseWidth(1));
      delay(6);
        PulseServo(4,GetChannelPulseWidth(4));
      delay(6); */
  }    
 
 // now print the channel pulse widths
 // they should be 0 if the state is not ready
 for ( int i =1; i <=MAX_CHANNELS; i++ ){ // print the status of the first three channels
       delay(360);
     Serial.print("Channel ");
     Serial.print(i);
     Serial.print(" has width ");
     pulsewidth = GetChannelPulseWidth(i);
     Serial.println(pulsewidth);
 }

}

void PulseServo(int channel,int pulsewidth)
{
 //   your code here to pulse the servo for the given channel with the given pulse width
 // you should check that pulsewidth is within the valid range for your servos

 int pin_num = 0;
 
 pin_num = channel + 1;

 if ((pulsewidth <= 2200) && (pulsewidth >= 600))
 {
   digitalWrite(pin_num, HIGH);  
   delayMicroseconds(pulsewidth);
   digitalWrite(pin_num, LOW);
 }

/*  Serial.print("chan ");
 Serial.print(channel);
 Serial.print("=");
 Serial.print(pulsewidth);
 Serial.print(", ");
 Serial.println();*/

}


and the Output is:
---
Channel 1 has width 872
Channel 2 has width 871
Channel 3 has width 874
Channel 4 has width 838
---
Seems to report the correct value of 0.8ms in null sticks position i also tested the width when i move and works not great but grab the signal :-) I try to go deep in the code..
Thanks

Go Up