Кривая подгонка сеанса Gnuplot для отображения напряжения на датчике и вывода значения в литрах

У меня есть еще один пост, касающийся отображения напряжения на датчике и вывода значения в литрах.

Код для отображения напряжения на датчике и вывода значения в литрах

Есть отличный ответ от пользователя timemage, который предлагает использовать подгонку кривой, и он или она демонстрирует сеанс Gnuplot, основанный на значениях, которые я нашел, отображая выходное напряжение на датчике, когда я добавил количество жидкости в бак. Это сработало великолепно! Однако это было у меня в голове, и я закончил тем, что заплатил студенту Uni, чтобы кодировать его для меня :-s

Теперь я хотел бы реализовать тот же код для другого танка. Предыдущая была кубической, эта больше похожа на закругленный клин (она в лодке).

Вот код предыдущего танка:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display
double SensorAnalogValue;
uint8_t calculation=1;
String Show_value; 
void setup()
{
  lcd.init();                      // initialize the lcd
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Liquid Volume:");
  lcd.setCursor(0, 1);
  lcd.print("Initializing...");
  delay(2000);
  Serial.begin(9600);
}


void loop()
{
  SensorAnalogValue = analogRead(A1) * 5.0 / 1023.0;
  if (SensorAnalogValue < 1.726) {
    calculation=0;
    Show_value="Low";
  }
  if (SensorAnalogValue > 4.04) {
    calculation=0;
    Show_value="High";
  }
  if(calculation!=0){
  //  Serial.println(SensorAnalogValue);
    Show_value=(String)Liquid_Volume(SensorAnalogValue);
  }
  Serial.println(SensorAnalogValue);
  lcd.setCursor(0, 1);
  lcd.print("                ");
  //Serial.println(Show_value);
  lcd.setCursor(0, 1);
  lcd.print(Show_value);
  delay(500);
  calculation=1;
}
int Liquid_Volume(double Volt) {
  double A =   2.81842;
  double B = -11.00151 ;
  double C =  14.4765 ;
  double D =  28.73579 ;

  return A * Volt * Volt * Volt + B * Volt * Volt + C * Volt + D;
}

Мой новый танк дает:

V L
0 0
1.389 30
1.618 45
1.814 70
1.981 100
2.107 120
2.218 155
2.319 180
2.409 210
2.554 240
2.678 265
2.783 310

Я не понимаю, какая часть кода относится к вышеприведенной информации, и поэтому мне не удается изменить код в соответствии с моим новым танком. Текущий код отлично работает на старом танке, поэтому я предполагаю, что его можно заставить работать на любом танке, изменив значения. Я также предполагаю, что нижеприведенное-это то, что нужно изменить, но я понятия не имею, как это сделать.

int Liquid_Volume(double Volt) {
      double A =   2.81842;
      double B = -11.00151 ;
      double C =  14.4765 ;
      double D =  28.73579 ;

, 👍1

Обсуждение

A*Вольт*Вольт*Вольт + B*Вольт*Вольт + C*Вольт + D чрезвычайно неэффективно (6 умножений с плавающей запятой). Если вы, по крайней мере, добавите круглые скобки вокруг "Вольт*Вольт" и "Вольт*Вольт*Вольт", вы позволите компилятору выполнить исключение общего подвыражения, оставив 5 умножений. Лучше всего использовать [метод Хорнера](https://en.wikipedia.org/wiki/Horner%27s_method): ((A*Вольт + B)*Вольт + C)*Вольт + D, в котором используется только 3 умножения., @Edgar Bonet

Подгонка кривой - это сложная тема, очень специфичная для программного обеспечения, и **выход** из темы здесь. Для вашей проблемы вы можете управлять любым резервуаром без изменения кода (только изменения данных) с помощью кусочно-линейной интерполяции, но я понимаю, что timemage уже показал вам, как это сделать. Тогда я голосую за то, чтобы закрыть этот вопрос., @Edgar Bonet

В связанный ответ включено очень простое руководство, в котором описывается, как получить эти числа с помощью gnuplot; оно не объясняет, как работает подгонка кривой. Только что я нашел [этот сайт](https://arachnoid.com/polysolve/), который вы можете буквально скопировать и вставить в таблицу вашего вопроса; измените градус (внизу графика) на 3, и он отобразит нужные вам числа, только в обратном порядке. Этот раздел моего ответа в основном предназначен для полноты, говорить только об этом здесь неуместно. Если вы хотите попытаться найти меня на freenode (IRC), я постараюсь объяснить это как можно лучше., @timemage

Это идеально, большое спасибо за ссылку., @SV Savannah