I'm trying to output the tilt angle of an accelerometer, over serial with an MCU. The code works 99% smoothly for all angles, but I keep consistently getting errors in three regions and am not sure why.
Here is a pic of the output data on a graph:
As you can see there's errors at around the 90, -25, and -55 marks. It must be a problem with my variables and casting but I'm not sure where I'm going wrong. I'm using the XC8 compiler fyi.
Here's my code:
#include <PIC18F47Q43.h>
#include <math.h>
unsigned char ACCEL[7];
char x, i;
unsigned short AngleDEC, AngleINT;
int XAraw, YAraw;
float AccelDEC, AccelINT;
double AccelTiltRad, AccelTiltDeg;
double pi = 3.1415;
double XAconv, YAconv;
XAraw = (RAWdata[0] << 8) | RAWdata[1];
YAraw = (RAWdata[2] << 8) | RAWdata[3];
XAconv = XAraw;
YAconv = YAraw;
AccelTiltRad = atan2l(YAconv, XAconv);
AccelTiltDeg = (double)((AccelTiltRad * 180)/pi);
ACCEL[3] = 10; // Decimal point halfway
if(AccelTiltDeg < 0)
{
ACCEL[6] = 11; // Make ACCEL[6] a minus sign
AccelTiltDeg *= -1; // Modulo doesn't like negatives
}
else
{
ACCEL[6] = 0; // Make ACCEL[6] a zero
}
AccelDEC = modf(AccelTiltDeg, &AccelINT);
AngleINT = (unsigned short)AccelINT;
AccelDEC *= 1000;
AngleDEC = (unsigned short)AccelDEC;
for(i = 0; i < 3; i++) // Add decimal values to output array
{
ACCEL[i] = AngleDEC%10;
AngleDEC = (unsigned short)(AngleDEC / 10);
}
for(i = 4; i < 6; i++) // Add int values to output array
{
ACCEL[i] = AngleINT%10;
AngleINT = (unsigned short)(AngleINT / 10);
}
for(i = 0; i < 7; i++) // Output whole array starting at ACCEL[6]
{
U1TXB = ASCIIconversion[ACCEL[6 - i]];
while(PIR4bits.U1TXIF == 0);
}
U1TXB = 9; // All necessary stuff to tell serial plotter to move to next line
while(PIR4bits.U1TXIF == 0);
U1TXB = 10;
while(PIR4bits.U1TXIF == 0);
U1TXB = 13;
while(PIR4bits.U1TXIF == 0);
My code first adds a decimal symbol in to the output array. Then it uses the atan21 function to get the angle, then the modf to split that value into two parts. I put the integer component into the array, then I multiply the decimal component to make it in integer, and add it into the array. Then output the whole string.
Let me know where I'm going wrong or if there's smarter ways to do this.
I've tried many different variable types including signage. Some don't change the performance, some crash entirely.