Hi, I am trying to plot a time-dependent 10th order polynomial on an Arduino Uno. I have two issues:
When trying to use the time as the x values of the polynomial, it breaks down almost immediately, giving infinite value.
when running a periodical for loop (786ms duration) the first part of the polynomial gets printed fine, but it suddenly breaks down in the last part of the plot.
I can't locate the issue and any help would be much appreciated.
My code is below:
// Initialise array with polynomial coefficients
float p [11] = {4.29416358858623e-22, -1.69783608630414e-18, 2.81414641213559e-15, -2.53121208332960e-12, 1.33462703081654e-09, -4.14674269957196e-07, 7.19480339465934e-05, -0.00606130114242071, 0.194386444345812, -6.33900955158736, 71.4696409901174};
// Set current to 0
float current = 0;
// Initialise time
unsigned long last_timestamp;
unsigned long time_now = 0;
unsigned long elapsed_time = 0;
void setup() {
// put your setup code here, to run once:
last_timestamp = millis();
Serial.begin(9600);
}
void loop() {
last_timestamp = time_now;
time_now = millis();
elapsed_time = time_now - last_timestamp;
// if (elapsed_time >= 1) {
for (float i = 0.0; i <= 786.0; i++) {
//current = p[0] * pow(time_now, 10) + p[1] * pow(time_now, 9) + p[2] * pow(time_now, 8) + p[3] * pow(time_now, 7) + p[4] * pow(time_now, 6) + p[5] * pow(time_now, 5) + p[6] * pow(time_now, 4) + p[7] * pow(time_now, 3) + p[8] * pow(time_now, 2) + p[9] * time_now + p[10];
current = p[0] * pow(i, 10.0) + p[1] * pow(i, 9.0) + p[2] * pow(i, 8.0) + p[3] * pow(i, 7.0) + p[4] * pow(i, 6.0) + p[5] * pow(i, 5.0) + p[6] * pow(i, 4.0) + p[7] * pow(i, 3.0) + p[8] * pow(i, 2.0) + p[9] * i + p[10];
Serial.println(current);
}
You might get better results with a spreadsheet program. It looks like the first 100 results are very near to 71.4696409901and then it starts climbing. At 786 you get to 38646026.6176135
Even using type double, with 15 significant digits, the polynomial is not "10th order". For example, when t=1, adding 10^-22 to 100, the result is still 100.
For plotting on the Uno, be realistic and treat it as 5th order, taking only the last five terms, and for better accuracy, use Horner's method to evaluate the result.
I'm trying to do exactly what I described in the post. Basically, I fitted a polynomial to a set of data collected by a current sensor. the 10th order polynomial fit is the one I found to be more accurate and with the lowest degree possible (that I could accept for accuracy). Now I want to turn that polynomial into a signal to send from the arduino to a motor driver. As a first step, and to double check that my polynomial fit is correct, I am just trying to plot it periodically. Hopefully that explains it better.
Current sensor data, it senses the mA going through a motor coil during periodic operation. I used matlab polyfit function to find the fit and took the coefficients from there. I did some trial and error sweeping through polynomials from 5th degree to 15th. I have to specifiy that when I plot the polynomial in the for loop it plots it fine for the first portion and it seems to go "noisy" during the last portion of the calculation, to then go back to being fine and "noisy" again periodically.
If you want to implement something that actually works on Arduino, you will have to change a number of your expectations.
Practically speaking, data collected from consumer grade sensors is usually limited in accuracy to 1% or 0.1% of full scale value, and for motor control, that level of accuracy is usually fine.
The data is not the problem here, the sensor of the motor driver is very accurate, I just want to be able to simulate a periodic signal with Arduino, and I'm under the impression that that is realistic?
Her's a plot of what the Uno is currently ouputting, for reference. And as you can see, the problem only seems to be for the last portion of the cycle, which to me is weird.
As you can see from the graph, the polynomial is being evaluated fine for the first portion, so I don't think it's that unrealistic. The fit I obtained in matlab is very close to the data I collected so there's some evidence that it can be done, but thanks for your time anyway
Yes, as we've tried to explain. Then it blows up due to lack of numerical precision and the inappropriate method of constructing and evaluating the polynomial.
If this is for a class, your instructor is failing to prepare you for real world applications.
If this is a 10th order polynome, you are in big trouble...
It cannot have more than 10 tops and dales.
You have hundreds of them....
And I guess you need to find another way to do your calcs. You can rewrite a polynome to a multiplication of 10 factors (instead of 10 additions). Maybe that can help you...
Since you say it is periodic... why not add a sine function in the mix?
To fit a periodic function you need an infinite amount of polynomes... (some mathematicians have proven that and it is known as Taylor expansion). Perhaps one of them is named Taylor...
Besides all the excellent advice you've already been given, another approach would be to break up your data into smaller sets and fit a separate curve to each set.
Edit to add: that would probably allow you to use polynomials of much lower order (in case that wasn't obvious )