Software Planning
---------------------------------------------------------------------------------------------------------
The software for the micro-controller include 6 basic steps...
- Capture 1 set of readings with no magnetic presence to calibrate system
- Capture and store 10 sets of data individually from Hall Effect sensor module
- Convert to representable data
- Calculate magnitude for each set of data
- Calculate angles for each set of data
- Display results in a organized system function
Sensor Specifications
ATD Registers
The first step for ATD conversion is to set the registers for the ATD converter, which is done at the beginning of the code, defined as global constants.
There are 5 registers to set-up, ATDCTL1 to ATDCTL5. For this project, a 10-bit ATD resolution is used with the bus clock set at 2MHZ, taking in samples one channel at a time one ATD conversion per sequence.
LED1, LED2 and SW1, SW2 are also initialized and utilized in various locations of the program.
PAD3, PAD4 and PAD5 are used to import analog reading Port configurations
PORTA (1,3,5,7)- Display Multiplexing
PORTB (4,5,6,7) - Display Inputs
Push Button -> SW1, SW2
LED signals -> LED1, LED2
GND
+5V
There are 5 registers to set-up, ATDCTL1 to ATDCTL5. For this project, a 10-bit ATD resolution is used with the bus clock set at 2MHZ, taking in samples one channel at a time one ATD conversion per sequence.
LED1, LED2 and SW1, SW2 are also initialized and utilized in various locations of the program.
PAD3, PAD4 and PAD5 are used to import analog reading Port configurations
PORTA (1,3,5,7)- Display Multiplexing
PORTB (4,5,6,7) - Display Inputs
Push Button -> SW1, SW2
LED signals -> LED1, LED2
GND
+5V
1. Calibration
Calibration function captures 3 readings (one set of x, y, z) with no magnets present and stores the values in an array
These value provides a reference point for when actual readings
These value provides a reference point for when actual readings
/****************************************************************************/
//Function establishes the ref point in x,y,z to calibrate system
//input int calibrate[] 1D array stores calibration values
void calccali(int calibrate[]){
int i;
for (i=0;i<M; i++){
calibrate[i]=readAnalog(i);
while(PTJ&SW1)
display(calibrate[i],10);
delay(500);
}
}
//Function establishes the ref point in x,y,z to calibrate system
//input int calibrate[] 1D array stores calibration values
void calccali(int calibrate[]){
int i;
for (i=0;i<M; i++){
calibrate[i]=readAnalog(i);
while(PTJ&SW1)
display(calibrate[i],10);
delay(500);
}
}
2. Readings Capture
The Function waits for SW1 and SW2 to be pressed at the same time, then capture three time, one for each axis, then wait for SW1 and SW2 to be pushed again for the next set.
This will loop through 10 times for 10 sets of readings
This will loop through 10 times for 10 sets of readings
//function retrieves analog reading from ATD converter
// int reading[][M] holds analog readings
void fieldReading(int reading[][M]){
int i,j;
for (i=0; i<N; i++){
while((PTJ&(SW1|SW2)))
PTS = LED2|LED1;
for (j=0; j<M; j++){
reading[i][j] = readAnalog(j);
}
}
}
3. Data Calculations
There are two functions used to calculated the analog readings
calcOffset, which calculate the relative steps from reference, and..
adConv, which converts the digital steps to digital representation of the analog value
calcOffset, which calculate the relative steps from reference, and..
adConv, which converts the digital steps to digital representation of the analog value
/*****************************calcOffset**************************************
function: to calculate result offset arrays
inputs: int original[][M] original array
int mod[][M] array after offset
int mid midpoint reference(ref point)
*****************************************************************************/
void calcOffset(int original[][M], int mod[][M], int mid[])
{
int i,j;
//initialize mid point
for(i=0; i<N; i++)
for(j=0; j<M; j++)
mod[i][j]=mid[j];
for(i=0; i<N; i++)
for(j=0; j<M; j++)
mod[i][j] =original[i][j]-mod[i][j];
while(PTJ&SW1){
PTS = LED2|LED1;
delay(250);
PTS = LED1;
delay(250);
PTS = LED2;
delay(250);
}
}
/****************************************************************************/
// function converts the analog input to magnetic field (Gauss)
//input int offset[][M] contains 10 set of 3, number of steps from ref
// int digital[][M] array stores the new converter GAUSS
/****************************************************************************/
void adConv(int offset[][M], float digital[][M]){
float res, gauStep;
int i,j, nbr;
res = SPAN/(pow(2.00,ADC)-1);
gauStep = res/SENSITIVITY;
while(PTJ&(SW2))
display((int)(gauStep*1000), 10);
for(i=0;i<N;i++)
for(j=0;j<M;j++){
nbr = (float)(offset[i][j]);
digital[i][j]=nbr*gauStep;
}
}
function: to calculate result offset arrays
inputs: int original[][M] original array
int mod[][M] array after offset
int mid midpoint reference(ref point)
*****************************************************************************/
void calcOffset(int original[][M], int mod[][M], int mid[])
{
int i,j;
//initialize mid point
for(i=0; i<N; i++)
for(j=0; j<M; j++)
mod[i][j]=mid[j];
for(i=0; i<N; i++)
for(j=0; j<M; j++)
mod[i][j] =original[i][j]-mod[i][j];
while(PTJ&SW1){
PTS = LED2|LED1;
delay(250);
PTS = LED1;
delay(250);
PTS = LED2;
delay(250);
}
}
/****************************************************************************/
// function converts the analog input to magnetic field (Gauss)
//input int offset[][M] contains 10 set of 3, number of steps from ref
// int digital[][M] array stores the new converter GAUSS
/****************************************************************************/
void adConv(int offset[][M], float digital[][M]){
float res, gauStep;
int i,j, nbr;
res = SPAN/(pow(2.00,ADC)-1);
gauStep = res/SENSITIVITY;
while(PTJ&(SW2))
display((int)(gauStep*1000), 10);
for(i=0;i<N;i++)
for(j=0;j<M;j++){
nbr = (float)(offset[i][j]);
digital[i][j]=nbr*gauStep;
}
}
4. Magnitude calculations
This functions takes in the array that contains the 10 sets of digital values and then calculated the resultant magnitude of the vector using Pythagorean theorem for each set of values.
/**************************************************************************
Function calculates resultat magnitude from three vectors
input float pyth[][M] 10x3 array contains the digital values
float result[] magnitude array
**************************************************************************/
void resVector(float pyth[][M], float result[]) {
int i;
for(i=0;i<N;i++)
result[i] = sqrtf(powf(pyth[i][0],2)+powf(pyth[i][1],2)+powf(pyth[i][2],2));
}
/**************************************************************************
Function calculates resultat magnitude from three vectors
input float pyth[][M] 10x3 array contains the digital values
float result[] magnitude array
**************************************************************************/
void resVector(float pyth[][M], float result[]) {
int i;
for(i=0;i<N;i++)
result[i] = sqrtf(powf(pyth[i][0],2)+powf(pyth[i][1],2)+powf(pyth[i][2],2));
}
5. Angle calculations
This function takes in the array that contains the 10 sets of digital values that first calculates an angle in the x-y plane then calculated an angle from xy - z
#define PI 3.14156265f
#define HA 180.00f
/**************************************************************************
Function calculates angle from x to y axis, then from xy plane to z axis
input: float dig[][M] 10x3 array contains the digital values
float angle[][M-1] 10x2 array contains the angle values
**************************************************************************/
void calcAngle(float dig[][M], float angle[][M-1]) {
int i;
float h1, h2;
for(i=0;i<N;i++) {
h1=sqrtf(powf(dig[i][0],2)+powf(dig[i][1],2));
h2=sqrtf(powf(h1,2)+ powf(dig[i][2],2));
angle[i][0]=asinf(dig[i][0]/h1)*(HA/PI);
angle[i][1]=acosf(h1/h2)*(HA/PI);
}
}
#define PI 3.14156265f
#define HA 180.00f
/**************************************************************************
Function calculates angle from x to y axis, then from xy plane to z axis
input: float dig[][M] 10x3 array contains the digital values
float angle[][M-1] 10x2 array contains the angle values
**************************************************************************/
void calcAngle(float dig[][M], float angle[][M-1]) {
int i;
float h1, h2;
for(i=0;i<N;i++) {
h1=sqrtf(powf(dig[i][0],2)+powf(dig[i][1],2));
h2=sqrtf(powf(h1,2)+ powf(dig[i][2],2));
angle[i][0]=asinf(dig[i][0]/h1)*(HA/PI);
angle[i][1]=acosf(h1/h2)*(HA/PI);
}
}
6. Organization and Display
Two functions are used for organization and display:
calcResult, which identifies negative angels and then signifies them with 1 on the most significant digit
then, it merges the magnitude array and the angle array, forming a 10x3 array, with the first element of each row storing the magnitude and the
other two storing the angles
show, which works similar to a menu, holding down SW1 will bring it to cycle through the original 30 digital values, Holding down SW2 will bring it to cycle though
the merged array that contains the magnitude and angles. holding down both button at the same time will exit the function.
/**************************************************************************
function identifies negative angles then merge angle and vector array
inputs: float angle[][M-1] angle array
vector[] magnitude array
result[][M] merged array
**************************************************************************/
void calcResult(float angle[][M-1], float vector[], float result[][M]){
int i, j;
for(i=0; i<N; i++)
for(j=0; j<(M-1); j++){
if (angle[i][j]<0)
angle[i][j]=fabs(angle[i][j])+1000; //display 1 on the most
//significant digit if negative
}
for(i=0; i<N; i++){
//merge vector and angle array
result[i][0] = vector[i];
result[i][1] = angle[i][0];
result[i][2] = angle[i][1];
}
}
/**************************************************************************
function display digital values and set readings (magnitude and reading)
depending on what switch is pressed
input rdg[][M-1] digital readings
result[][M] merged array
**************************************************************************/
void show(float rdg[][M], float result[][M]){
int i,j;
while(PTJ&(SW1|SW2)){
PTS=LED1|LED2;
delay(2000);
if(!(PTJ&SW1)){
while(PTJ&(SW1|SW2))
display(209, 16); // display 'd1' for digital readings
delay(500);
for(i=0; i<N; i++){
while(PTJ&SW1)
display((24065+i), 16); // display '5E01 + i' set01 plus counter
delay(500);
for(j=0; j<M; j++){
while(PTJ&SW1)
display(rdg[i][j], 10);
delay(500);
}
}
}
else if(!(PTJ&SW2)){
while(PTJ&SW1)
display(255, 16); // display 'ff' for final results
delay(500);
for(i=0; i<N; i++){
while(PTJ&SW1)
display((24065+i), 16); // display '5E01 + i' set01 plus counter
delay(500);
for(j=0; j<(M); j++){
while(PTJ&SW1)
display(result[i][j], 10);
delay(500);
}
}
}
}
}
calcResult, which identifies negative angels and then signifies them with 1 on the most significant digit
then, it merges the magnitude array and the angle array, forming a 10x3 array, with the first element of each row storing the magnitude and the
other two storing the angles
show, which works similar to a menu, holding down SW1 will bring it to cycle through the original 30 digital values, Holding down SW2 will bring it to cycle though
the merged array that contains the magnitude and angles. holding down both button at the same time will exit the function.
/**************************************************************************
function identifies negative angles then merge angle and vector array
inputs: float angle[][M-1] angle array
vector[] magnitude array
result[][M] merged array
**************************************************************************/
void calcResult(float angle[][M-1], float vector[], float result[][M]){
int i, j;
for(i=0; i<N; i++)
for(j=0; j<(M-1); j++){
if (angle[i][j]<0)
angle[i][j]=fabs(angle[i][j])+1000; //display 1 on the most
//significant digit if negative
}
for(i=0; i<N; i++){
//merge vector and angle array
result[i][0] = vector[i];
result[i][1] = angle[i][0];
result[i][2] = angle[i][1];
}
}
/**************************************************************************
function display digital values and set readings (magnitude and reading)
depending on what switch is pressed
input rdg[][M-1] digital readings
result[][M] merged array
**************************************************************************/
void show(float rdg[][M], float result[][M]){
int i,j;
while(PTJ&(SW1|SW2)){
PTS=LED1|LED2;
delay(2000);
if(!(PTJ&SW1)){
while(PTJ&(SW1|SW2))
display(209, 16); // display 'd1' for digital readings
delay(500);
for(i=0; i<N; i++){
while(PTJ&SW1)
display((24065+i), 16); // display '5E01 + i' set01 plus counter
delay(500);
for(j=0; j<M; j++){
while(PTJ&SW1)
display(rdg[i][j], 10);
delay(500);
}
}
}
else if(!(PTJ&SW2)){
while(PTJ&SW1)
display(255, 16); // display 'ff' for final results
delay(500);
for(i=0; i<N; i++){
while(PTJ&SW1)
display((24065+i), 16); // display '5E01 + i' set01 plus counter
delay(500);
for(j=0; j<(M); j++){
while(PTJ&SW1)
display(result[i][j], 10);
delay(500);
}
}
}
}
}