Wednesday, February 15, 2006

Servo HCS08 working

First lesson learned, you can't manipulate the duty of the TPM within a keyboard interrupt:

void interrupt Vkeyboard intSWITCH1(){
if(SWITCH1 == DOWN){

TPM2C0V = ZERO;

}
if(SWITCH2 == DOWN){
TPM2C0V = ONE_EIGHTY;

}
if(SWITCH3 == DOWN){
TPM2C0V = TPM2C0V -1;
}
if(SWITCH4 == DOWN){
TPM2C0V = TPM2C0V+1;
}
timer2chnl0 = TPM2C0V;*/
KBI1SC_KBACK = 1;//ack

}
This will not work! Wish I knew why, but it won't. In order to properly affect the duty cycle the code must be in the main for loop. Hope I have time to investigate why the software interrupt doesn't function...

Secondly, the original configuration of flipping the bit on PTDF2, again with an interrupt (timer 2 channel 0) was producing aberrations in the PWM! The aberrations were rhythmic in nature and we blamed them on internal software latency; again, wish I knew more about this, but the fact of the matter is that the code was simply this:

void interrupt VTimer2Chnl0 intTimer2Chnl0(){

PTFD_PTFD2 = ~PTFD_PTFD2;

TPM2C0SC_CH0F = 0;
}
. Perhaps this is related to the fact that LED3 is by default wired to the output of PTDF2, and its operation was hosing with the PWM.

Lastly, the the modulation count was still the same for the direct timer output (which for timer 2 channel 0 is PTD3, see http://www.freescale.com/files/microcontrollers/doc/data_sheet/MC9S08GB60.pdf), so:

#define half_ms_duty_50hz (TPM2MOD - (TPM2MOD/40) -2)
#define ONE_EIGHTY half_ms_duty_50hz

void initICG(){
/*configure Internal Clock Generator [ICG]*/
/*MFD[]={4,6,8,10,12,14,16,18}*/
ICGC2_MFD = 7; /*32KHz crystal, demo board.
For 4MHz crystal (eval board):
ICGC2_MFD = 3
*/
ICGC2_RFD = 0; /* RFD[]={1,2,4,8,16,32,64,128}*/
//ICGC1 = 0b00110000;
ICGC1 = 0b00111000;
/*32KHz crystal, demo board.
For 4MHz crystal (eval board):
ICGC1 = 0b01111000;
*/
while((ICGS1_LOCK==0)||(ICGS1_ERCS==0)){
/*Ensure COP doesn't reset device whilst waiting for clock lock*/
__RESET_WATCHDOG(); /* kicks the dog */
}
ICGC2_LOCRE = 1; /*enable reset if clock fails*/

}

void initTimer2Chnl0_50hz(){
TPM2C0SC_CH0IE = 1; //enable channel

TPM2SC_CLKSA = 1;/*Select BUS clock*/
TPM2SC_CLKSB = 0;

TPM2SC_PS = PRESCALAR;/*clock source divided by prescalar*/
TPM2MOD = 1475;/*counter value, counts up to*/

TPM2SC_CPWMS = 1;
/*configure PWM mode and pulse*/
TPM2C0SC_MS0B = 1; /*MS0B=1, MS0A=0; << Edge align PWM*/
TPM2C0SC_ELS0A = 1; /*Select low as true*/

TPM2C0V = ONE_EIGHTY;
}



Once I get the code cleaned up and more presentable, I'll post the entire thing for future replication.

Wednesday, February 08, 2006

remove CVS tag

cvs update -dPA

Monday, February 06, 2006

Ethereal for OS X 10.4(Tiger) on a G3 iBook

Installed Fink and FinkCommander. From FinkCommander installed
Ethereal, but I was getting errors in execution (/sw/bin/ethereal).
Looked like some library issues. Pulled down the ethereal source and
read the Readme.macos and realized that FinkCommander installed shared
libraries.
Had to install the core libraries, and not the sh ones to get Ethereal
to load, that is

GLib 2.4.0
Pango 1.4.0
GTK+ 2.4.0
ATK 1.6.0
Changed permissions of the bpf (sudo a+r bpf*) devices per
http://wiki.ethereal.com/CaptureSetup/CapturePrivileges

Saturday, February 04, 2006

Servo info

Excellent link that describes how servos operate: http://www.servocity.com/html/how_do_servos_work_.html
-----
Servos are controlled by sending them a pulse of variable width. The control wire is used to send this pulse. The parameters for this pulse are that it has a minimum pulse, a maximum pulse, and a repetition rate. Given the rotation constraints of the servo, neutral is defined to be the position where the servo has exactly the same amount of potential rotation in the clockwise direction as it does in the counter clockwise direction. It is important to note that different servos will have different constraints on their rotation but they all have a neutral position, and that position is always around 1.5 milliseconds (ms).

The angle is determined by the duration of a pulse that is applied to the control wire. This is called Pulse width Modulation. The servo expects to see a pulse every 20 ms. The length of the pulse will determine how far the motor turns. For example, a 1.5 ms pulse will make the motor turn to the 90 degree position (neutral position).

When these servos are commanded to move they will move to the position and hold that position. If an external force pushes against the servo while the servo is holding a position, the servo will resist from moving out of that position. The maximum amount of force the servo can exert is the torque rating of the servo. Servos will not hold their position forever though; the position pulse must be repeated to instruct the servo to stay in position.

-----

So the goal for using the HCS08 board is to control the servo operation programatically via a timer. So how to find the duty cycle of a given period that equates to the required PWM?

According to this site the servo expects to see a pulse every 20ms, in which case that would equate to 1/.02 = 50hz. So once the timer is configured for the appropriate frequency, the duty cycle can then be adjusted as needed to control the servo. A pulse with a duty cycle of 5% @ .02s would be 1ms, which would then move the servo in the counter clockwise position, according to the first site, at 0 degrees. Whereas if the duty cycle were 10%, 2ms, the servo would rotate the shaft to 180 degrees. Adjusting the duty to 7.5%, 1.5ms, would return the shaft to neutral position.