Click here to Skip to main content
16,016,760 members
Please Sign up or sign in to vote.
1.00/5 (4 votes)
See more:
C
#include 
#include "derivative.h" 
#include "adc.h"
#include "buzzer.h"
#include "SCItx.h"
#pragma DATA_SEG MY_ZEROPAGE
unsigned char near Sample_X;
unsigned char near Sample_Y;
unsigned char near Sample_Z;
unsigned char near Sensor_Data[8];
unsigned char near countx,county ;
signed int near accelerationx[2], accelerationy[2];
signed long near velocityx[2], velocityy[2];
signed long near positionX[2];
signed long near positionY[2];
signed long near positionZ[2]; 
unsigned char near direction;
unsigned long near sstatex,sstatey;
#pragma DATA_SEG DEFAULT
void init(void);
void Calibrate(void);
void data_transfer(void);
void concatenate_data(void);
void movement_end_check(void);
void position(void);
void main (void)
{
init();
get_threshold(); 
do 
{
position();
}while(1);
}
void Calibrate(void) 
{
unsigned int count1;
count1 = 0;
do{ 
ADC_GetAllAxis();
sstatex = sstatex + Sample_X; // Accumulate Samples
sstatey = sstatey + Sample_Y;
count1++;
}while(count1!=0x0400); // 1024 times
sstatex=sstatex>>10; // division between 1024
sstatey=sstatey>>10;
}
void data_transfer(void) 
{

signed long positionXbkp; 
signed long positionYbkp;
unsigned int delay;
unsigned char posx_seg[4], posy_seg[4]; 


if (positionX[1]>=0) { //This line compares the sign of the X direction data 
direction= (direction | 0x10); //if its positive the most significant byte 
posx_seg[0]= positionX[1] & 0x000000FF; // is set to 1 else it is set to 8
posx_seg[1]= (positionX[1]>>8) & 0x000000FF; // the data is also managed in the 
// subsequent lines in order to 
posx_seg[2]= (positionX[1]>>16) & 0x000000FF; // be sent. The 32 bit variable must be 
posx_seg[3]= (positionX[1]>>24) & 0x000000FF; // split into 4 different 8 bit 
// variables in order to be sent via 
// the 8 bit SCI frame
}


else {direction=(direction | 0x80);
positionXbkp=positionX[1]-1;
positionXbkp=positionXbkp^0xFFFFFFFF;
posx_seg[0]= positionXbkp & 0x000000FF;
posx_seg[1]= (positionXbkp>>8) & 0x000000FF;
posx_seg[2]= (positionXbkp>>16) & 0x000000FF;
posx_seg[3]= (positionXbkp>>24) & 0x000000FF;
} 


if (positionY[1]>=0) { // Same management than in the previous case 
direction= (direction | 0x08); // but with the Y data.
posy_seg[0]= positionY[1] & 0x000000FF;
posy_seg[1]= (positionY[1]>>8) & 0x000000FF;
posy_seg[2]= (positionY[1]>>16) & 0x000000FF;
posy_seg[3]= (positionY[1]>>24) & 0x000000FF;
}

else {direction= (direction | 0x01);
positionYbkp=positionY[1]-1;
positionYbkp=positionYbkp^0xFFFFFFFF;
posy_seg[0]= positionYbkp & 0x000000FF;
posy_seg[1]= (positionYbkp>>8) & 0x000000FF;
posy_seg[2]= (positionYbkp>>16) & 0x000000FF;
posy_seg[3]= (positionYbkp>>24) & 0x000000FF;
} 

delay = 0x0100;

Sensor_Data[0] = 0x03;
Sensor_Data[1] = direction;
Sensor_Data[2] = posx_seg[3];
Sensor_Data[3] = posy_seg[3];
Sensor_Data[4] = 0x01;
Sensor_Data[5] = 0x01;
Sensor_Data[6] = END_OF_FRAME;

while (--delay); 

SCITxMsg(Sensor_Data); // Data transferring function 
while (SCIC2 & 0x08);
}
/*****************************************************************************************/
/******************************************************************************************
This function returns data format to its original state. When obtaining the magnitude and 
direction of the position, an inverse two's complement is made. This function makes the two's 
complement in order to return the data to it original state.
It is important to notice that the sensibility adjustment is greatly impacted here, the amount 
of "ones" inserted in the mask must be equivalent to the "ones" lost in the shifting made in 
the previous function upon the sensibility modification. 
******************************************************************************************/ 
void data_reintegration(void) 
{

if (direction >=10) 
{positionX[1]= positionX[1]|0xFFFFC000;} // 18 "ones" inserted. Same size as the 
//amount of shifts 

direction = direction & 0x01;
if (direction ==1) 

{positionY[1]= positionY[1]|0xFFFFC000;}
}
/******************************************************************************************
This function allows movement end detection. If a certain number of acceleration samples are 
equal to zero we can assume movement has stopped. Accumulated Error generated in the velocity 
calculations is eliminated by resetting the velocity variables. This stops position increment 
and greatly eliminates position error.
******************************************************************************************/ 
void movement_end_check(void) 
{
if (accelerationx[1]==0) //we count the number of acceleration samples that equals cero 
{ countx++;}
else { countx =0;}

if (countx>=25) //if this number exceeds 25, we can assume that velocity is cero
{ 
velocityx[1]=0;
velocityx[0]=0;
}

if (accelerationy[1]==0) //we do the same for the Y axis
{ county++;}
else { county =0;}

if (county>=25)
{ 
velocityy[1]=0;
velocityy[0]=0;
} 
}
/*****************************************************************************************/
/******************************************************************************************
This function transforms acceleration to a proportional position by integrating the 
acceleration data twice. It also adjusts sensibility by multiplying the "positionX" and 
"positionY" variables. 
This integration algorithm carries error, which is compensated in the "movenemt_end_check" 
subroutine. Faster sampling frequency implies less error but requires more memory. Keep in 
mind that the same process is applied to the X and Y axis. 
*****************************************************************************************/ 

void position(void) 
{
unsigned char count2 ;
count2=0;

do{

ADC_GetAllAxis();
accelerationx[1]=accelerationx[1] + Sample_X; //filtering routine for noise attenuation
accelerationy[1]=accelerationy[1] + Sample_Y; //64 samples are averaged. The resulting 
//an instant
count2++; 

}while (count2!=0x40); // 64 sums of the acceleration sample


accelerationx[1]= accelerationx[1]>>6; // division by 64
accelerationy[1]= accelerationy[1]>>6;

accelerationx[1] = accelerationx[1] - (int)sstatex; //eliminating zero reference 
//offset of the acceleration data
accelerationy[1] = accelerationy[1] - (int)sstatey; // to obtain positive and negative 
//acceleration


if ((accelerationx[1] <=3)&&(accelerationx[1] >= -3)) //Discrimination window applied 
{accelerationx[1] = 0;} // to the X axis acceleration 
//variable

if ((accelerationy[1] <=3)&&(accelerationy[1] >= -3)) 
{accelerationy[1] = 0;} 

//first X integration:
velocityx[1]= velocityx[0]+ accelerationx[0]+ ((accelerationx[1] -accelerationx[0])>>1); 
//second X integration:
positionX[1]= positionX[0] + velocityx[0] + ((velocityx[1] - velocityx[0])>>1);
//first Y integration: 
velocityy[1] = velocityy[0] + accelerationy[0] + ((accelerationy[1] -accelerationy[0])>>1);
//second Y integration: 
positionY[1] = positionY[0] + velocityy[0] + ((velocityy[1] - velocityy[0])>>1); 

accelerationx[0] = accelerationx[1]; //The current acceleration value must be sent 
//to the previous acceleration 
accelerationy[0] = accelerationy[1]; //variable in order to introduce the new 
//acceleration value.

velocityx[0] = velocityx[1]; //Same done for the velocity variable
velocityy[0] = velocityy[1];


positionX[1] = positionX[1]<<18; //The idea behind this shifting (multiplication) 
//is a sensibility adjustment.
positionY[1] = positionY[1]<<18; //Some applications require adjustments to a 
//particular situation 
//i.e. mouse application
data_transfer();

positionX[1] = positionX[1]>>18; //once the variables are sent them must return to 
positionY[1] = positionY[1]>>18; //their original state

movement_end_check();

positionX[0] = positionX[1]; //actual position data must be sent to the 
positionY[0] = positionY[1]; //previous position

direction = 0; // data variable to direction variable reset 
}
Posted
Updated 23-May-12 4:14am
v2
Comments
Nelek 22-May-12 18:43pm    
And the rest of the code?
With the few lines you have provided, there is no way to say anything. No error from compiler, no code of the functions, no description at all...
On the other hand... do you really want an endless loop?
lewax00 22-May-12 18:43pm    
What error are you getting? Where is it occurring? What does the rest of the code look like? We'll need more details before we can help you (use the "Improve question" button to add details)
pataoengineer 22-May-12 23:30pm    
You have not provided sufficient information.
What is inside init() , get_threshold() , and position() ?
Malli_S 24-May-12 3:34am    
Please be specific while posting the question. That would help others to provide you exact help you needed.

Here a terse response to your terse question:
int main(int argc, char* argv[])


and
do { } while(1);


never stops.
 
Share this answer
 
As far as I can see, your biggest error is that your while loop will never terminate.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900