![]() |
Accelerometer code
I've been working on writing code for an accelerometer that outputs a PWM signal. I've been trying to adapt some of Kevin's code that dealt with an infrared sensor that output PWM signals.
the following is Kevin's with a few variable name changes switch(RB5_State) // current state determines how the function behaves { case 0: // falling-edge detected (beginning of the pulse) Int_4_Down_Edge_Count_High = Clock; // get a snapshot of the time tbuf = TMR1L; // TMR1L must be read before TMR1H Int_4_Down_Edge_Count_Low = TMR1H; Int_4_Down_Edge_Count_Low <<= 8; Int_4_Down_Edge_Count_Low += tbuf; break; // now wait for the rising-edge interrupt to happen... case 1: // rising-edge detected (end of the pulse) Int_4_Up_Edge_Count_High = Clock; // get a snapshot of the time tbuf = TMR1L; Int_4_Up_Edge_Count_Low = TMR1H; Int_4_Up_Edge_Count_Low <<= 8; Int_4_Up_Edge_Count_Low += tbuf; // determine the pulse-width period by determining the time // difference between the falling-edge and rising-edge interrupts if (Int_4_Up_Edge_Count_High == Int_4_Down_Edge_Count_High) { // this is quicker because the 16-bit system clock hasn't changed and therefore has no effect on the outcome Int_4_Period = Int_4_Up_Edge_Count_Low - Int_4_Down_Edge_Count_Low; } else { //this works because the pulse-width will always be less than one clock tick(= 65536 timer ticks) //(=0.0000001 seconds) 1 * 10^-7 sec (0.1 micro seconds) Int_4_Period = 65536 - Int_4_Down_Edge_Count_Low + Int_4_Up_Edge_Count_Low; } break; // now wait for another falling-edge interrupt to happen... now i have my accelerometer plugged into digital input 3 and 4 (x and y PWMs) as far as i can tell the RB5 pin never switches state because when i printf("data:%d",Int_4_Down_Edge_Count_High); or Int_4_Up_Edge_Count_High the value is always 0 so the clock value never gets assigned meaning it never entered the switch statement. It does the same thing for the interrupt on digital input 3 Any words of advice or help would be greatly appreciated. Thanks. |
Re: Accelerometer code
(Use [code] brackets when applicable. :))
Well... Could we see the rest of the code? One thing I can think of right now is the docs recommend putting a \r at the end of the printf... :shrug: |
Re: Accelerometer code
Some questions:
1) Are you setting up and enabling the interrupts? If so, let's see the code. 2) Is your function getting called from InterruptHandlerLow()? 3) What platform are you using? 4) Which accelerometer are you using? -Kevin |
Re: Accelerometer code
I wrote one for a 202/210 earlier this year.. I'll attach it. At first, I didn't know what I was doing, but then after I got out some paper and did the math/optimization it ended up exactly like Kevin Watson's gyro code. It was kinda weird. But anyway, because of the similarity, I just used his framework so everything would make sense more quickly to those who already used it.
If you look at the h file, you see the variables you have to setup. If you look at the clock, and the resolution it gives, then you quickly realize why the limitations of the PIC we use would make data from the accel useless once we start integrating, but I'll leave the deciding up to you. ACCEL_SCALE_FACTOR is the same as the k in the manual. There is a defined value for it, but you have to test the accel inline with gravity to see where 1g is. ACCEL_CLOCK_RATE / ACCEL_SAMPLES_PER_UPDATE should never really be less than 50, I guess. I don't remember my exact reason for setting it to three at the time (so maybe commenting isn't such a bad idea ;)). accel.h Code:
/*******************************************************************************Code:
/*******************************************************************************Code:
Initialize_Accelerometer();x_timer.h Code:
/*******************************************************************************Code:
/******************************************************************************* |
Re: Accelerometer code
3 Attachment(s)
ok, based on kevin's response i'm clearly missing something with the interrupts
being called. here's the code i'm using htis accelerometer http://www.analog.com/UploadedFiles/...DXL202EB_a.pdf Code:
/*Code:
/*Code:
/******************************************************************************* |
Re: Accelerometer code
Quote:
-Kevin |
Re: Accelerometer code
Quote:
-Kevin |
Re: Accelerometer code
that is a very good question, apparently i deleted the call by accident once. i'll see if it helps any. Thanks.
~Will |
Re: Accelerometer code
I could be way off base, but I believe the accelerometer you are using outputs analog signals (0-5 V) and should be connect to an AI port, not a digital.
Mike |
Re: Accelerometer code
Quote:
Interrupt code here - http://www.kevin.org/frc Interrupt white paper - http://www.chiefdelphi.com/forums/pa...le&paperid=272 And you can run a search on here to see what you find. |
Re: Accelerometer code
Quote:
edit: Actually, in hindsight, I do remember the 202's manual telling a way that the analog signal could be salvaged. I think it involved the use of a few capacitors. You can maybe read the manual, and see if that is a feasible option for you. 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. |
Re: Accelerometer code
Quote:
-Kevin |
Re: Accelerometer code
Joel,
My apologies, your right. I've used the analog one in the past and thought this was the same. Mike |
Re: Accelerometer code
Quote:
also: http://people.clarkson.edu/~lanahamc/media/IMG_1546.jpg i don't know what RC that is, maybe joel can help me out on that one |
Re: Accelerometer code
Code:
/*******************************************************************************i added the initialization of the acceleromter. so now i'm left with the solid red led telling me i have a code error :) |
Re: Accelerometer code
Quote:
|
Re: Accelerometer code
Quote:
|
Re: Accelerometer code
Quote:
|
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 |
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. |
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 |
Re: Accelerometer code
Quote:
Code:
float kVariableName; // Float variable with name kVariableName |
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
|
Re: Accelerometer code
Quote:
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 */Code:
void applyMotionControl(pDriveInfo stream) |
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) |
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 |
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 |
Re: Accelerometer code
Quote:
-Kevin |
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. |
| All times are GMT -5. The time now is 11:52. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi