Go to Post I have gone and confused myself again. Why does this happen every time? - Jay Trzaskos [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Closed Thread
Thread Tools Rating: Thread Rating: 19 votes, 5.00 average. Display Modes
  #16   Spotlight this post!  
Unread 02-06-2005, 14:51
CapnBFG's Avatar
CapnBFG CapnBFG is offline
Registered User
no team
 
Join Date: May 2005
Location: Clarkson University
Posts: 11
CapnBFG is an unknown quantity at this point
Re: Accelerometer code

Quote:
Originally Posted by Joel J.
Also, the accelerometer I was mentioning is the 203: http://www.analog.com/en/prod/0%2C28...L203%2C00.html . It has about 2.5 times less error, and a more usable signal. Its the way to go.
Joel, I am working with ImmortalAres on this project; I'm handling all hardware aspects. Do you already have the model 203 accelerometer or were you just planning on buying one in the future? The reason I ask is because when we organized the parts cabinet we found three accelerometers in addition to the one we are using, and I have yet to check what models each of them are.
__________________
Wake up and smell the ashes.
  #17   Spotlight this post!  
Unread 02-06-2005, 14:53
Joel J's Avatar
Joel J Joel J is offline
do you..
no team
 
Join Date: May 2001
Rookie Year: 2000
Location: San Jose, CA
Posts: 1,445
Joel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond repute
Re: Accelerometer code

Quote:
Originally Posted by ImmortalAres
Code:
/*******************************************************************************
* FILE NAME: user_routines.c <FRC VERSION>
*
* DESCRIPTION:
*  This file contains the default mappings of inputs  
*  (like switches, joysticks, and buttons) to outputs on the RC.  
*
* USAGE:
*  You can either modify this file to fit your needs, or remove it from your 
*  project and replace it with a modified copy. 
*
*******************************************************************************/
#include <stdio.h>
#include "ifi_aliases.h"
#include "ifi_default.h"
#include "ifi_utilities.h"
#include "user_routines.h"
#include "user_Serialdrv.h"
#include "myaccelerometer.h"



/*** DEFINE USER VARIABLES AND INITIALIZE THEM HERE ***/

extern unsigned char aBreakerWasTripped;


/*******************************************************************************
* FUNCTION NAME: Limit_Switch_Max
* PURPOSE:       Sets a PWM value to neutral (127) if it exceeds 127 and the
*                limit switch is on.
* CALLED FROM:   this file
* ARGUMENTS:     
*     Argument       Type             IO   Description
*     --------       -------------    --   -----------
*     switch_state   unsigned char    I    limit switch state
*     *input_value   pointer           O   points to PWM byte value to be limited
* RETURNS:       void
*******************************************************************************/
void Limit_Switch_Max(unsigned char switch_state, unsigned char *input_value)
{
  if (switch_state == CLOSED)
  { 
    if(*input_value > 127)
      *input_value = 127;
  }
}


/*******************************************************************************
* FUNCTION NAME: Limit_Switch_Min
* PURPOSE:       Sets a PWM value to neutral (127) if it's less than 127 and the
*                limit switch is on.
* CALLED FROM:   this file
* ARGUMENTS:     
*     Argument       Type             IO   Description
*     --------       -------------    --   -----------
*     switch_state   unsigned char    I    limit switch state
*     *input_value   pointer           O   points to PWM byte value to be limited
* RETURNS:       void
*******************************************************************************/
void Limit_Switch_Min(unsigned char switch_state, unsigned char *input_value)
{
  if (switch_state == CLOSED)
  { 
    if(*input_value < 127)
      *input_value = 127;
  }
}


/*******************************************************************************
* FUNCTION NAME: Limit_Mix
* PURPOSE:       Limits the mixed value for one joystick drive.
* CALLED FROM:   Default_Routine, this file
* ARGUMENTS:     
*     Argument             Type    IO   Description
*     --------             ----    --   -----------
*     intermediate_value    int    I    
* RETURNS:       unsigned char
*******************************************************************************/
unsigned char Limit_Mix (int intermediate_value)
{
  static int limited_value;
  
  if (intermediate_value < 2000)
  {
    limited_value = 2000;
  }
  else if (intermediate_value > 2254)
  {
    limited_value = 2254;
  }
  else
  {
    limited_value = intermediate_value;
  }
  return (unsigned char) (limited_value - 2000);
}


/*******************************************************************************
* FUNCTION NAME: User_Initialization
* PURPOSE:       This routine is called first (and only once) in the Main function.  
*                You may modify and add to this function.
* CALLED FROM:   main.c
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
void User_Initialization (void)
{
  Set_Number_of_Analog_Channels(SIXTEEN_ANALOG);    /* DO NOT CHANGE! */

/* FIRST: Set up the I/O pins you want to use as digital INPUTS. */
  digital_io_01 = digital_io_02 = digital_io_03 = digital_io_04 = INPUT;
  digital_io_05 = digital_io_06 = digital_io_07 = digital_io_08 = INPUT;
  digital_io_09 = digital_io_10 = digital_io_11 = digital_io_12 = INPUT;
  digital_io_13 = digital_io_14 = digital_io_15 = digital_io_16 = INPUT;
  digital_io_18 = INPUT;  /* Used for pneumatic pressure switch. */
    /* 
     Note: digital_io_01 = digital_io_02 = ... digital_io_04 = INPUT; 
           is the same as the following:

           digital_io_01 = INPUT;
           digital_io_02 = INPUT;
           ...
           digital_io_04 = INPUT;
    */

/* SECOND: Set up the I/O pins you want to use as digital OUTPUTS. */
  digital_io_17 = OUTPUT;    /* Example - Not used in Default Code. */

/* THIRD: Initialize the values on the digital outputs. */
  rc_dig_out17 = 0;

/* FOURTH: Set your initial PWM values.  Neutral is 127. */
  pwm01 = pwm02 = pwm03 = pwm04 = pwm05 = pwm06 = pwm07 = pwm08 = 127;
  pwm09 = pwm10 = pwm11 = pwm12 = pwm13 = pwm14 = pwm15 = pwm16 = 127;

/* FIFTH: Set your PWM output types for PWM OUTPUTS 13-16.
  /*   Choose from these parameters for PWM 13-16 respectively:               */
  /*     IFI_PWM  - Standard IFI PWM output generated with Generate_Pwms(...) */
  /*     USER_CCP - User can use PWM pin as digital I/O or CCP pin.           */
  Setup_PWM_Output_Type(IFI_PWM,IFI_PWM,IFI_PWM,IFI_PWM);

  /* 
     Example: The following would generate a 40KHz PWM with a 50% duty cycle on the CCP2 pin:

         CCP2CON = 0x3C;
         PR2 = 0xF9;
         CCPR2L = 0x7F;
         T2CON = 0;
         T2CONbits.TMR2ON = 1;

         Setup_PWM_Output_Type(USER_CCP,IFI_PWM,IFI_PWM,IFI_PWM);
  */

  /* Add any other initialization code here. */

  Putdata(&txdata);             /* DO NOT CHANGE! */

  Serial_Driver_Initialize();
  Initialize_Serial_Comms();
  Initialize_Accelerometer();

  //printf("IFI 2005 User Processor Initialized ...\r");  /* Optional - Print initialization message. */
  /* Note:  use a '\r' rather than a '\n' with the new compiler (v2.4) */


  User_Proc_Is_Ready();         /* DO NOT CHANGE! - last line of User_Initialization */
}

/*******************************************************************************
* FUNCTION NAME: Process_Data_From_Master_uP
* PURPOSE:       Executes every 26.2ms when it gets new data from the master 
*                microprocessor.
* CALLED FROM:   main.c
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
void Process_Data_From_Master_uP(void)
{
  static unsigned char i;
  static unsigned char delay;
	int xaccel;
	int yaccel;

  Getdata(&rxdata);   /* Get fresh data from the master microprocessor. */


  Default_Routine();  /* Optional.  See below. */

  Generate_Pwms(pwm13,pwm14,pwm15,pwm16);

  /* Eample code to check if a breaker was ever tripped. */

  if (aBreakerWasTripped)
  {
    for (i=1;i<29;i++)
    {
      if (Breaker_Tripped(i))
        User_Byte1 = i;  /* Update the last breaker tripped on User_Byte1 (to demonstrate the use of a user byte) 
                           // Normally, you do something else if a breaker got tripped (ex: limit a PWM output)     */
    }
  }
///////////////////////////////////////////////////////////////////
	//get x and y accel and print them to the serial port
	xaccel=Get_xAcceleration();
	printf("The x accel: %d", xaccel);
//////////////////////////////////////////////////////////////
	yaccel=Get_yAcceleration();
	printf("The y accel: %d", yaccel);
//////////////////////////////////////////////////////////////////

  Putdata(&txdata);             /* DO NOT CHANGE! */
}

/*******************************************************************************
* FUNCTION NAME: Default_Routine
* PURPOSE:       Performs the default mappings of inputs to outputs for the
*                Robot Controller.
* CALLED FROM:   this file, Process_Data_From_Master_uP routine
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
void Default_Routine(void)
{
  
 /*---------- Analog Inputs (Joysticks) to PWM Outputs-----------------------
  *--------------------------------------------------------------------------
  *   This maps the joystick axes to specific PWM outputs.
  */
  pwm01 = p1_y;   
  pwm02 = p2_y;   
  pwm03 = p3_y;   
  pwm04 = p4_y;   
  pwm05 = p1_x;   
  pwm06 = p2_x;   
  pwm07 = p3_x;   
  pwm08 = p4_x;   
  pwm09 = p1_wheel;
  pwm10 = p2_wheel;   
  pwm11 = p3_wheel;   
  pwm12 = p4_wheel;   
  
 /*---------- 1 Joystick Drive ----------------------------------------------
  *--------------------------------------------------------------------------
  *  This code mixes the Y and X axis on Port 1 to allow one joystick drive. 
  *  Joystick forward  = Robot forward
  *  Joystick backward = Robot backward
  *  Joystick right    = Robot rotates right
  *  Joystick left     = Robot rotates left
  *  Connect the right drive motors to PWM13 and/or PWM14 on the RC.
  *  Connect the left  drive motors to PWM15 and/or PWM16 on the RC.
  */  

  
 /*---------- Buttons to Relays----------------------------------------------
  *--------------------------------------------------------------------------
  *  This default code maps the joystick buttons to specific relay outputs.  
  *  Relays 1 and 2 use limit switches to stop the movement in one direction.
  *  The & used below is the C symbol for AND                                
  */
  relay1_fwd = p1_sw_trig & rc_dig_in01;  /* FWD only if switch1 is not closed. */
  relay1_rev = p1_sw_top  & rc_dig_in02;  /* REV only if switch2 is not closed. */
  relay2_fwd = p2_sw_trig & rc_dig_in03;  /* FWD only if switch3 is not closed. */
  relay2_rev = p2_sw_top  & rc_dig_in04;  /* REV only if switch4 is not closed. */
  relay3_fwd = p3_sw_trig;
  relay3_rev = p3_sw_top;
  relay4_fwd = p4_sw_trig;
  relay4_rev = p4_sw_top;
  relay5_fwd = p1_sw_aux1;
  relay5_rev = p1_sw_aux2;
  relay6_fwd = p3_sw_aux1;
  relay6_rev = p3_sw_aux2;
  relay7_fwd = p4_sw_aux1;
  relay7_rev = p4_sw_aux2;
  relay8_fwd = !rc_dig_in18;  /* Power pump only if pressure switch is off. */
  relay8_rev = 0;
  
  /*---------- PWM outputs Limited by Limit Switches  ------------------------*/
  
  Limit_Switch_Max(rc_dig_in05, &pwm03);
  Limit_Switch_Min(rc_dig_in06, &pwm03);
  Limit_Switch_Max(rc_dig_in07, &pwm04);
  Limit_Switch_Min(rc_dig_in08, &pwm04);
  Limit_Switch_Max(rc_dig_in09, &pwm09);
  Limit_Switch_Min(rc_dig_in10, &pwm09);
  Limit_Switch_Max(rc_dig_in11, &pwm10);
  Limit_Switch_Min(rc_dig_in12, &pwm10);
  Limit_Switch_Max(rc_dig_in13, &pwm11);
  Limit_Switch_Min(rc_dig_in14, &pwm11);
  Limit_Switch_Max(rc_dig_in15, &pwm12);
  Limit_Switch_Min(rc_dig_in16, &pwm12);
  

 /*---------- ROBOT FEEDBACK LEDs------------------------------------------------
  *------------------------------------------------------------------------------
  *   This section drives the "ROBOT FEEDBACK" lights on the Operator Interface.
  *   The lights are green for joystick forward and red for joystick reverse.
  *   Both red and green are on when the joystick is centered.  Use the
  *   trim tabs on the joystick to adjust the center.     
  *   These may be changed for any use that the user desires.                       
  */	
  
  if (user_display_mode == 0) /* User Mode is Off */
    
  { /* Check position of Port 1 Joystick */
    if (p1_y >= 0 && p1_y <= 56)
    {                     /* Joystick is in full reverse position */
      Pwm1_green  = 0;    /* Turn PWM1 green LED - OFF */
      Pwm1_red  = 1;      /* Turn PWM1 red LED   - ON  */
    }
    else if (p1_y >= 125 && p1_y <= 129)
    {                     /* Joystick is in neutral position */
      Pwm1_green  = 1;    /* Turn PWM1 green LED - ON */
      Pwm1_red  = 1;      /* Turn PWM1 red LED   - ON */
    }
    else if (p1_y >= 216 && p1_y <= 255)
    {                     /* Joystick is in full forward position*/
      Pwm1_green  = 1;    /* Turn PWM1 green LED - ON  */
      Pwm1_red  = 0;      /* Turn PWM1 red LED   - OFF */
    }
    else
    {                     /* In either forward or reverse position */
      Pwm1_green  = 0;    /* Turn PWM1 green LED - OFF */
      Pwm1_red  = 0;      /* Turn PWM1 red LED   - OFF */
    }  /*END Check position of Port 1 Joystick
    
    /* Check position of Port 2 Y Joystick 
           (or Port 1 X in Single Joystick Drive Mode) */
    if (p2_y >= 0 && p2_y <= 56)
    {                     /* Joystick is in full reverse position */
      Pwm2_green  = 0;    /* Turn pwm2 green LED - OFF */
      Pwm2_red  = 1;      /* Turn pwm2 red LED   - ON  */
    }
    else if (p2_y >= 125 && p2_y <= 129)
    {                     /* Joystick is in neutral position */
      Pwm2_green  = 1;    /* Turn PWM2 green LED - ON */
      Pwm2_red  = 1;      /* Turn PWM2 red LED   - ON */
    }
    else if (p2_y >= 216 && p2_y <= 255)
    {                     /* Joystick is in full forward position */
      Pwm2_green  = 1;    /* Turn PWM2 green LED - ON  */
      Pwm2_red  = 0;      /* Turn PWM2 red LED   - OFF */
    }
    else
    {                     /* In either forward or reverse position */
      Pwm2_green  = 0;    /* Turn PWM2 green LED - OFF */
      Pwm2_red  = 0;      /* Turn PWM2 red LED   - OFF */
    }  /* END Check position of Port 2 Joystick */
    
    /* This drives the Relay 1 and Relay 2 "Robot Feedback" lights on the OI. */
    Relay1_green = relay1_fwd;    /* LED is ON when Relay 1 is FWD */
    Relay1_red = relay1_rev;      /* LED is ON when Relay 1 is REV */
    Relay2_green = relay2_fwd;    /* LED is ON when Relay 2 is FWD */
    Relay2_red = relay2_rev;      /* LED is ON when Relay 2 is REV */

    Switch1_LED = !(int)rc_dig_in01;
    Switch2_LED = !(int)rc_dig_in02;
    Switch3_LED = !(int)rc_dig_in03;
    
  } /* (user_display_mode = 0) (User Mode is Off) */
  
  else  /* User Mode is On - displays data in OI 4-digit display*/
  {
    User_Mode_byte = backup_voltage*10; /* so that decimal doesn't get truncated. */
  }   
  
} /* END Default_Routine(); */

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

i added the initialization of the acceleromter. so now i'm left with the solid red led telling me i have a code error
Well.. thats the main problem with the accelerometer running on a PWM.. the timer to get even decent results is too much for the proc (and it looks like your timer is set to 1MHz, which is just not gonna happen -- 12K was just about too much). I'd say just get the analog version shipped in, and go from there. Still stick with the off-board processor setup, though. Did he say if you could use a DSP?
__________________
Joel Johnson

Division By Zero (229) Alumni, 2003-2007
RAGE (173) Alumni, 1999-2003
  #18   Spotlight this post!  
Unread 02-06-2005, 14:54
Joel J's Avatar
Joel J Joel J is offline
do you..
no team
 
Join Date: May 2001
Rookie Year: 2000
Location: San Jose, CA
Posts: 1,445
Joel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond repute
Re: Accelerometer code

Quote:
Originally Posted by CapnBFG
Joel, I am working with ImmortalAres on this project; I'm handling all hardware aspects. Do you already have the model 203 accelerometer or were you just planning on buying one in the future? The reason I ask is because when we organized the parts cabinet we found three accelerometers in addition to the one we are using, and I have yet to check what models each of them are.
I have no idea what we have. But I do know that we don't have the 203, because its a newer model (came out in the middle of the season). If you are the hardware guy, then you can probably look at the new interfaces they have to the accelerometers, and see if you can work with them better (they have a couple self-contained units, based on the 203 -- http://www.analog.com/en/subCat/0,28...0%255F,00.html , at the very bottom of the page).
__________________
Joel Johnson

Division By Zero (229) Alumni, 2003-2007
RAGE (173) Alumni, 1999-2003

Last edited by Joel J : 02-06-2005 at 14:56. Reason: added suggestion..
  #19   Spotlight this post!  
Unread 02-06-2005, 14:57
ImmortalAres ImmortalAres is offline
Registered User
no team
 
Join Date: May 2005
Location: Clarkson University
Posts: 33
ImmortalAres is an unknown quantity at this point
Re: Accelerometer code

yea, it looks like i'm gonna try to push Carroll to get us the 203 one. For whatever reason he was adamant about using a PWM and not getting something to convert it. hopefully he goes for getting a new accelerometer entirely.

also,

http://microchip.com/stellent/idcplg...&part=DM163022

that's what we plan on using for the 2nd PIC
  #20   Spotlight this post!  
Unread 02-06-2005, 15:09
Mike Bortfeldt Mike Bortfeldt is offline
Registered User
FRC #1126 (& 1511)
Team Role: Mentor
 
Join Date: Oct 2004
Rookie Year: 2004
Location: Rochester, NY
Posts: 119
Mike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud of
Re: Accelerometer code

One thing I don't see in your code is where you reset the Port B interrupt flag (INTCONBits.RBIF), but that could easily be in your InterruptHandlerLow routine. If possible could you also post your user_routines_fast.c code as it might help.
Another thing you will probably encounter later on is when you calculate your yacceleration you are dividing a 16 bit integer Int_4_Period (maximum 65535) by 206124 which will always result in 0 as the PIC will be performing integer math.
  #21   Spotlight this post!  
Unread 02-06-2005, 15:13
ImmortalAres ImmortalAres is offline
Registered User
no team
 
Join Date: May 2005
Location: Clarkson University
Posts: 33
ImmortalAres is an unknown quantity at this point
Re: Accelerometer code

is the PIC capable of doing floating point math at all?
if not i really should just give up on this pwm accelerometer and get the 203 joel is talking about which is what i'm planning on doing now.

Thanks for all the help you guys. Its much appreciated
  #22   Spotlight this post!  
Unread 02-06-2005, 15:19
Joel J's Avatar
Joel J Joel J is offline
do you..
no team
 
Join Date: May 2001
Rookie Year: 2000
Location: San Jose, CA
Posts: 1,445
Joel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond repute
Re: Accelerometer code

Quote:
Originally Posted by ImmortalAres
is the PIC capable of doing floating point math at all?
if not i really should just give up on this pwm accelerometer and get the 203 joel is talking about which is what i'm planning on doing now.

Thanks for all the help you guys. Its much appreciated
It can, but its really a death sentence. If you want to use it (I don't recommend it--at all), then you'd write
Code:
float kVariableName; // Float variable with name kVariableName
, like always.
__________________
Joel Johnson

Division By Zero (229) Alumni, 2003-2007
RAGE (173) Alumni, 1999-2003
  #23   Spotlight this post!  
Unread 02-06-2005, 15:47
ImmortalAres ImmortalAres is offline
Registered User
no team
 
Join Date: May 2005
Location: Clarkson University
Posts: 33
ImmortalAres is an unknown quantity at this point
Re: Accelerometer code

ok, would a 40 Mhz PIC do a better job at it or is it just a bad idea in general because then i need an analog signal (203 model) since if you look in the comments in the accel.c file i need float point math to convert pwm periods into anything useful
  #24   Spotlight this post!  
Unread 02-06-2005, 16:19
Joel J's Avatar
Joel J Joel J is offline
do you..
no team
 
Join Date: May 2001
Rookie Year: 2000
Location: San Jose, CA
Posts: 1,445
Joel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond reputeJoel J has a reputation beyond repute
Re: Accelerometer code

Quote:
Originally Posted by ImmortalAres
ok, would a 40 Mhz PIC do a better job at it or is it just a bad idea in general because then i need an analog signal (203 model) since if you look in the comments in the accel.c file i need float point math to convert pwm periods into anything useful
the PWM accelerometer comes with a 14-bit A/D converter, whereas the PICS usually have a 10-bit converter. That was their claimed advantage, but quite frankly "PWM interfaces" are a real pain, and for that reason, Analog is phasing out those line of accelerometers. So you may as well be with the game.

If you are using the offboard processor, and it is at that speed, then you'd probably get the accuracy you need. In all implementations of this type of accelerometer, the interrupts become, for the most part, the main focus -- ie, they are set on high priority interrupts -- and not much else is going on. So, you decide.

Also, as far as floating point goes, I used a fixed-point setup (10 bits for the decimal) to get the accuracy I wanted, without having to resort to floats. For some reason, Dr. Carroll didn't like that (added complexity or some other claim), but its commonly used. Chris Hibner did a presentation on it recently ( http://www.usfirst.org/robotics/2005...rogramming.ppt ).

Oh, and here is a "relevant" example of said fixed-point setup in use:
Code:
#define RADIX_SHIFT_TIMES 10/* Shift a value this number of places. In other words or multiply (or divide) by 2^number_of_places */
#define RADIX_SHIFT_MULTIPLIES_BY 1024/* this is the effective multiplier/divider. it is 2^RADIX_SHIFT_TIMES */
Code:
void applyMotionControl(pDriveInfo stream)
{
long er = 0, el = 0, VID, WID;

//er = (2.0*Mrobot*R*Kd1*Vd-2.0*Mrobot*R*Kd1*V+2.0*Mrobot*R*Kp1*Vd_int-2.0*Mrobot*R*Kp1*V_int+2.0*Mrobot*R*Ki1*Vd_int_int-2.0*Mrobot*R*Ki1*V_int_int+Kg*Kg*Kt*Kb*wr*rout+rout*rout*b*Mrobot*R*Kp2*Wd_int-rout*rout*b*Mrobot*R*Kp2*W_int+rout*rout*b*Mrobot*R*Ki2*Wd_int_int-rout*rout*b*Mrobot*R*Ki2*W_int_int+rout*rout*b*Mrobot*R*Kd2*Wd-rout*rout*b*Mrobot*R*Kd2*W);
//el = (2.0*Mrobot*R*Kd1*Vd-2.0*Mrobot*R*Kd1*V+2.0*Mrobot*R*Kp1*Vd_int-2.0*Mrobot*R*Kp1*V_int+2.0*Mrobot*R*Ki1*Vd_int_int-2.0*Mrobot*R*Ki1*V_int_int-rout*rout*b*Mrobot*R*Kp2*Wd_int+rout*rout*b*Mrobot*R*Kp2*W_int-rout*rout*b*Mrobot*R*Ki2*Wd_int_int+rout*rout*b*Mrobot*R*Ki2*W_int_int-rout*rout*b*Mrobot*R*Kd2*Wd+rout*rout*b*Mrobot*R*Kd2*W+Kg*Kg*Kt*Kb*wl*rout);

if (stream->gear == HIGH)
{
VID = (Kd1_high*(stream->Vd - stream->V)) + (Kp1_high*(stream->Vd_int - stream->V_int)) + (Ki1_high*(stream->Vd_int_int - stream->V_int_int));
} else {
VID = (Kd1_low*(stream->Vd - stream->V)) + (Kp1_low*(stream->Vd_int - stream->V_int)) + (Ki1_low*(stream->Vd_int_int - stream->V_int_int));
}

VID = VID >> RADIX_SHIFT_TIMES; // Squared radix value, so divide by it, to restore original
VID = VID * DD_Mrobot_R_2;              // Squared radix value, but don't divide because of later

if (stream->gear == HIGH)
{
WID = (Kd2_high*(stream->Wd - stream->W)) + (Kp2_high*(stream->Wd_int - stream->W_int)) + (Ki2_high*(stream->Wd_int_int - stream->W_int_int));
} else {
WID = (Kd2_low*(stream->Wd - stream->W)) + (Kp2_low*(stream->Wd_int - stream->W_int)) + (Ki2_low*(stream->Wd_int_int - stream->W_int_int));
}

WID = WID >> RADIX_SHIFT_TIMES;// Squared radix value, so divide by it, to restore original
WID = WID * DD_rout_rout_b_Mrobot_R;// Squared radix value, but don't divide because of later

if (stream->gear == HIGH)
{
er = (VID + WID + (DD_Kg_Kg_Kt_Kb_rout_high*stream->wr)) / DD_rout_Kg_Kt_high;  // Added already squared radix value to newly squared radix value
el = (VID - WID + (DD_Kg_Kg_Kt_Kb_rout_high*stream->wl)) / DD_rout_Kg_Kt_high;  // No need to divide by radix to even out, because the already present division evens things out
} else {
er = (VID + WID + (DD_Kg_Kg_Kt_Kb_rout_low*stream->wr)) / DD_rout_Kg_Kt_low;  // Added already squared radix value to newly squared radix value
el = (VID - WID + (DD_Kg_Kg_Kt_Kb_rout_low*stream->wl)) / DD_rout_Kg_Kt_low;  // No need to divide by radix to even out, because the already present division evens things out
}

er = er >> RADIX_SHIFT_TIMES;// Since we are ready to use the value, get rid of multiplier
el = el >> RADIX_SHIFT_TIMES;// Since we are ready to use the value, get rid of multiplier

stream->rx = el;// TEMPORARY -- REMOVE!!!!!!
stream->ry = er;

// Do not integrate unless the outputs are below saturation
if (er > stream->max_output)
{
er = stream->max_output;
} else if (er < stream->min_output)
{
er = stream->min_output;
} else if (el > stream->max_output)
{
el = stream->max_output;
} else if (el < stream->min_output)
{
el = stream->min_output;
} else {
// Integrate values (remember to add check for saturation)
stream->Vd_int = safeAdd_long(stream->Vd_int, ((Ts * (stream->Vd + stream->Vd_prev)) >> (RADIX_SHIFT_TIMES + 1)));
   stream->Vd_int_int = safeAdd_long(stream->Vd_int_int, ((Ts * (stream->Vd_int + stream->Vd_int_prev)) >> (RADIX_SHIFT_TIMES + 1)));

    stream->Wd_int = safeAdd_long(stream->Wd_int, ((Ts * (stream->Wd + stream->Wd_prev)) >> (RADIX_SHIFT_TIMES + 1)));
   stream->Wd_int_int = safeAdd_long(stream->Wd_int_int, ((Ts * (stream->Wd_int + stream->Wd_int_prev)) >> (RADIX_SHIFT_TIMES + 1)));
}

// Store previous values (do this no matter what)
stream->Vd_prev = stream->Vd;
stream->Vd_int_prev = stream->Vd_int;

stream->Wd_prev = stream->Wd;
stream->Wd_int_prev = stream->Wd_int; 

// Return value to user
stream->left_output = (unsigned char)limit_to_range(((signed int)el+(signed int)127), (signed int)MIN_JOY, (signed int)MAX_JOY);
stream->right_output = (unsigned char)limit_to_range(((signed int)er+(signed int)127), (signed int)MIN_JOY, (signed int)MAX_JOY);

// stream->left_output = p1_y;
// stream->right_output = p2_y;
}
Heh.
__________________
Joel Johnson

Division By Zero (229) Alumni, 2003-2007
RAGE (173) Alumni, 1999-2003

Last edited by Joel J : 02-06-2005 at 16:24. Reason: added an example..
  #25   Spotlight this post!  
Unread 02-06-2005, 16:51
Kevin Watson's Avatar
Kevin Watson Kevin Watson is offline
La Caņada High School
FRC #2429
Team Role: Mentor
 
Join Date: Jan 2002
Rookie Year: 2001
Location: La Caņada, California
Posts: 1,335
Kevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond repute
Re: Accelerometer code

Okay, lets take a deep breath... Ready? Okay, here's my thinking:

1) Stick with the PWM output because, as Joel pointed out, this device has got a higher resolution ADC on-chip and as all the analog signals stay on-chip, you'll be dealing with fewer noise sources.

2) If you're going to use an external microcontroller to handle the accelerometer interface, use the CCP capture hardware to do the work for you. This won't work on the full-size FRC robot controller because IFI has output buffers on the CCP pins, which precludes them being used as inputs (the smaller EDU robot controller does not have these buffers). I've already written code that will work with the device you're using that uses the CCP capture hardware. If you promise to send me a copy of your project write-up, I'll publish a link to it <grin>.

3) What resistor values did you choose to program the t2 frequency (If you don't know what I'm blathering about, you'd better read the data sheet <grin>). If you're using this accelerometer in a control application, anything higher than 50-100Hz is overkill. If you're integrating the output, you'll want to set it to at least twice the accelerometer's bandwidth (lest Harry Nyquist rise from his grave, and smite thy project), but ideally you'll want to set it as high as possible.

-Kevin (Who didn't get nearly enough sleep and has consumed way too much coffee)
__________________
Kevin Watson
Engineer at stealth-mode startup
http://kevin.org
  #26   Spotlight this post!  
Unread 02-06-2005, 17:07
Mike Bortfeldt Mike Bortfeldt is offline
Registered User
FRC #1126 (& 1511)
Team Role: Mentor
 
Join Date: Oct 2004
Rookie Year: 2004
Location: Rochester, NY
Posts: 119
Mike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud of
Re: Accelerometer code

You could also do your fixed point math another way by calculating your result in units mg's rather than g's by multiplying the appropriate values by 1000. It is not as efficient as bit shifting since you actually have to use multiply and divide statements, but may be a bit more readable.
If you do stick with just the IFI controller, you can probably get reasonable accuracy as the code comments indicate a period of 9.6 milliseconds for the accelerometer. While a low priority interrupt can be delayed depending on what the process is doing, you should be able to maintain an error of less than 1% due to interrupt delay.

Mike
  #27   Spotlight this post!  
Unread 02-06-2005, 17:31
ImmortalAres ImmortalAres is offline
Registered User
no team
 
Join Date: May 2005
Location: Clarkson University
Posts: 33
ImmortalAres is an unknown quantity at this point
Re: Accelerometer code

The resistor value was preset when the device made it into our hands at 1.2 Mega ohms making T2 somewhere in the range of 250 Hz if i remember correctly. The exact calculation is written in the comments i have in the code.

We have to write up a paper for the symposium at the end of the summer and i would be more than willing to send you a copy but as of now there is no formal write up

I'll see about sticking with the PWMs. I have to wait until the 2nd PIC gets in.

Thanks for the advice


~Will
  #28   Spotlight this post!  
Unread 02-06-2005, 19:18
Kevin Watson's Avatar
Kevin Watson Kevin Watson is offline
La Caņada High School
FRC #2429
Team Role: Mentor
 
Join Date: Jan 2002
Rookie Year: 2001
Location: La Caņada, California
Posts: 1,335
Kevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond reputeKevin Watson has a reputation beyond repute
Re: Accelerometer code

Quote:
Originally Posted by ImmortalAres
We have to write up a paper for the symposium at the end of the summer and i would be more than willing to send you a copy but as of now there is no formal write up
Here is some code that'll get you started: http://kevin.org/frc/edu_accel_lcd.zip. It's designed to work with an external serial LCD, so you'll need to do some porting.

-Kevin
__________________
Kevin Watson
Engineer at stealth-mode startup
http://kevin.org
  #29   Spotlight this post!  
Unread 04-06-2005, 01:02
Gdeaver Gdeaver is offline
Registered User
FRC #1640
Team Role: Mentor
 
Join Date: Mar 2004
Rookie Year: 2001
Location: West Chester, Pa.
Posts: 1,370
Gdeaver has a reputation beyond reputeGdeaver has a reputation beyond reputeGdeaver has a reputation beyond reputeGdeaver has a reputation beyond reputeGdeaver has a reputation beyond reputeGdeaver has a reputation beyond reputeGdeaver has a reputation beyond reputeGdeaver has a reputation beyond reputeGdeaver has a reputation beyond reputeGdeaver has a reputation beyond reputeGdeaver has a reputation beyond repute
Re: Accelerometer code

So far the discussion has been on low range accelerometers. Remember, it's on a robot and there may be times when there is a impact or bump that will drive the unit to saturation. It can take a considerable amount of time to recover from a saturated condition. It's enough to affect the integration. Accelerometers are also excellent vibration sensors. One thing that is often over looked is the natural resonance frequency of the sensor. Both the chip package and the sensor have a resonate point that is high enough not to worry about but your going to have to mount the chip on a carrier. You have to worry about the resonance point of the chip-carrier-mounting system.
Glue your chip to the board. Use a thick high grade PC board. More ridged the better. Use some isolation mounting to mount the board to the bot and pay attention to what part of the robot you mount it to. Try to isolate it from the drive train vibration. I think you might have better results if you went to a mid range analog unit. Run the output through and op amp with a gain of one and a 400 HZ low pass filter. Mount the pic18, op amp and sensor on a small ridged carrier that is mounted to a ridge large mass part of the robot with some isolation mounting hardware. Over sample in software to further reduce noise. Let the pic coproc do the calculations and send a periodic update to the FRC .

The Freescale MMA3201D has a low pass fiter on the chip.

Last edited by Gdeaver : 04-06-2005 at 01:55.
Closed Thread


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Out of the Box Camera Code russell Programming 9 21-10-2009 05:28
Some things i'm trying to understand on Kevin's Accelerometer Code Squall Programming 2 03-02-2005 12:01
Team THRUST - Kevin's Code and Camera Code Combine Chris_Elston Programming 3 31-01-2005 22:28
Example accelerometer code released. Kevin Watson Programming 0 20-01-2005 03:45
heres the code. y this not working omega Programming 16 31-03-2004 15:18


All times are GMT -5. The time now is 19:12.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi