assegnare valore segnale digitale

Salve a tutti , scusate la mia incompetenza.
Ho un sensore Maf digitale , leggo valori in frequenza(KHz) che devo associare al rispettivo valore (kg/m)-
il mio problema è che il sensore non e' lineare e ho il datasheet ma solo una tabella Exell.
Come poso associare i due dati? Grazie.
Allego tabella

kHz kg/min
1,9 0,091
2 0,196
2,1 0,330
2,2 0,491
2,3 0,676
2,4 0,883
2,5 1,111
2,6 1,357
2,7 1,620
2,8 1,897
2,9 2,188
3 2,490
3,1 2,802
3,2 3,122
3,3 3,450
3,4 3,783
3,5 4,120
3,6 4,460
3,7 4,802
3,8 5,145
3,9 5,488
4 5,830
4,1 6,171
4,2 6,508
4,3 6,842
4,4 7,172
4,5 7,498
4,6 7,818
4,7 8,133
4,8 8,442
4,9 8,745
5 9,041
5,1 9,331
5,2 9,615
5,3 9,892
5,4 10,163
5,5 10,427
5,6 10,685
5,7 10,937
5,8 11,184
5,9 11,426
6 11,664
6,1 11,897
6,2 12,127
6,3 12,355
6,4 12,581
6,5 12,806
6,6 13,032
6,7 13,258
6,8 13,487
6,9 13,718
7 13,955
7,1 14,197
7,2 14,446
7,3 14,704
7,4 14,973
7,5 15,253

Per non saper ne leggere ne scrivere farei un array di 75-19 int (7,5(max scala)*10-1,9(min scala)*10). Ad ogni posizione dell'array assocerei il valore, chiaramente reso intero della seconda colonna (a 0 va la seconda colonna di 1,9. A 1 quello di 2...). Al che rilevo il dato. Lo approssimo alla prima cifra decimale. Lo moltiplico per 10. Ci sottraggo 19. Vado a leggere il valore in quella posizione. Mi salvo il valire letto dall'array in un float. Divido il float per quante volte mi serve ad ottenere il numero originale.
Altrimenti vado a cercare su excell se tra i valori esiste (come probabile) una relazione, e la applico. Non so come si faccia il secondo.

>brugola: devi utilizzare un'interpolazione polinomiale e trovare il polinomio che meglio approssima quei valori. Se cerchi su Google trovi un'infinità di esempi, inclusi alcuni già fatti in Excel.

Guglielmo

Lavorare a quasi Natale mi fa venire certe idee...

  1. Interpolazione lineare tra singoli campioni: vedendo il grafico non è poi così tanto "curvo" (sempre che il visualizzatore excel -che non so usare- non mi tragga in inganno).

  2. Rete neurale: per una NN il compito da risolvere è una sciocchezza, basterebbe un singolo strato intermedio con quattro o cinque unità ad esagerare. La rete esecutiva sarebbe piccola, veloce, e richiederebbe anche poca memoria rispetto alla tabellona del caso 1.

Grazie per l' aiuto.
Sono andato cercare sul excell e sul valore del kg/min cliccando con il tasto dx del mouse esce la formula.
ho provato a scriverla nel programma, ma mi da valore Aoef...(?)
Sbaglio a scrivere la somma di un numero negativo?
Grazie

 DGTAria=(422.095725085143-601.027105682563*
            freq+264.454270996657*pow(freq,2)+
            (-36.8461491398253)*pow(freq,3)+
            1.79189711078536*pow(freq,4))/60;

Aoef? Cosa vuol dire? Di che tipo é la variabile DGTAria?

In Excel questa formula dà i risultati desiderati:
=(422,1-601,1A1+264,45A1^2-36,85A1^3+1,79A1^4)/60
quindi basta trascriverla in C:
DGTAria=(422,1 -601,1freq +264,45pow(freq,2) -36,85pow(freq,3) +1,79pow(freq,4))/60;

che mi sembra essere ciò che hai scritto tu. DGTAria deve essere float.

salve,
Aoef mi compare sul monitor al posto del valore numerico risultante dalla funzione matematica.
DGTAria e la variabile massa aria(kg/min) che voglio scrivere
Allego il mio sketch ...

#include "DHT.h"

#define DHTPIN 2 // what digital pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);
const unsigned int BAUD_RATE=9600;
int inPin=4;
const int R=30;
const int R0=47;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(BAUD_RATE);
  pinMode(inPin, INPUT);
 
}
unsigned int Htime, Ltime ;
float Ttime, freq, DGTAria ;


void loop() {
  // put your main code here, to run repeatedly:
  // put your main code here, to run repeatedly:
  Ltime = pulseIn(4, HIGH);
  Htime = pulseIn(4, LOW);
  Ttime = Htime + Ltime;
  freq = 1000000/ Ttime;
 ////DGTAria=map(freq,1400,12000,0,970);
  ////DGTAria=map(freq,1850,5000,0,970);
   //DGTAria=map(freq,1920,6500,0,970);
//   DGTAria=((422.095725085143-601.027105682563*
//            freq+264.454270996657*(freq*freq)+
//            (-36.8461491398253)*(freq*freq*freq)+
//            1.79189711078536*(freq*freq*freq*freq))/60);
 DGTAria=(422.095725085143-601.027105682563*
            freq+264.454270996657*pow(freq,2)+
            (-36.8461491398253)*pow(freq,3)+
            1.79189711078536*pow(freq,4))/60;
  float Cil=analogRead(A2);
  float pCil=(Cil*(.00488)/(.022)+20);
  float Atm=analogRead(A3);
  float pAtm=(Atm*(.00488)/(.022)+20);
//  float InWgCil=pCil*4.06785;
//  float InWgAtm=pAtm*4.06785;
  float InWgCil=pCil*4.01474;
  float InWgAtm=pAtm*4.01474;
  delay(500);

 


  
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);

  Serial.print("A"); Serial.println( DGTAria);//massa aria dgt
  Serial.print("freq"); Serial.println( freq);
  Serial.print("B"); Serial.println(InWgCil);// pressione cil
  Serial.print("C"); Serial.println(InWgAtm);// pressione Atm
  Serial.print("D");//umidità
  Serial.println(h);
  
  Serial.print("E");//temperatura
  Serial.println(t);
 
}

Datman:
In Excel questa formula dà i risultati desiderati:
=(422,1-601,1A1+264,45A1^2-36,85A1^3+1,79A1^4)/60
quindi basta trascriverla in C.

ho controllato e la tua affermazione e corretta, il problema e che non riesco a trasferirla in C .
Nella formula originale però ho una somma di un numero negativo ho sbaglio?
=(422,1-601,1A1+264,45A1^2 + -36,85A1^3+1,79A1^4)/60

DGTAria=(422,1 -601,1freq +264,45pow(freq,2) -36,85pow(freq,3) +1,79pow(freq,4))/60;

Datman:
DGTAria=(422,1 -601,1freq +264,45pow(freq,2) -36,85pow(freq,3) +1,79pow(freq,4))/60;

ho provato a scrivere la formula come tuo esempio , ma non visualizza nessun numero sul monitor seriale.

Utilizzando la calcolatrice il calcolo risulta corretto solo se metto sia il + che il - davanti al numero 36.84-
Però la formula non e scritta nel modo corretto in Arduino, non da nessun valore su monitor seriale ( scrive Aovf

Io al che proverei a fare una cosa. Visto che nessuno sembra sapere dove sia l'errore o cosa voglia dire quell'insieme di caratteri proverei a separare il conto nelle parti che lo compongono, scrivendo su seriale il risultato di ognuna di esse.
Esempio:
Y=3X^4+1/2X^3+X-3
Diventa
Y=3X^4
Scrivo Y
Y=Y+1/2X^3
Scrivo Y.

Proviamo così, almeno da sapere dove é il problema.

Silente:
Io al che proverei a fare una cosa. Visto che nessuno sembra sapere dove sia l'errore o cosa voglia dire quell'insieme di caratteri proverei a separare il conto nelle parti che lo compongono, scrivendo su seriale il risultato di ognuna di esse.
Esempio:
Y=3X^4+1/2X^3+X-3
Diventa
Y=3X^4
Scrivo Y
Y=Y+1/2X^3
Scrivo Y.

Proviamo così, almeno da sapere dove è il problema.

Stavo provando a trovare il problema nella formula matematica.
Quello che ho notato e' che mi restituisce un valore fino che non scrivo l' ultima moltiplicazione (*pow(freq,4).

se scrivo DGTAria=(422,1 -601,1freq +264,45pow(freq,2) -36,85*pow(freq,3) +1,79)/60;
(restituisce un valore numerico)

al posto di DGTAria=(422,1 -601,1freq +264,45pow(freq,2) -36,85pow(freq,3) +1,79pow(freq,4))/60;
(restituisce scritta Aovf).
Grazie

ho notato che è pow( freq,4) che blocca il tutto. se pow( freq,3) mi restituisce un valore…

forse il problema è nel calcolo , va in
: OVF (stack overflow).

La frequenza che leggi in realtà è in hertz... (1000000/us), però il float non dovrebbe aver problemi. Comunque se usi 1000 ottieni kHz e dovrebbe funzionare.

Float arriva a +/-10^38, quindi 10000^4, che fa 10^16, c'entra...
https://www.arduino.cc/reference/en/language/variables/data-types/float/

Uhmm...

hai ragione adesso funziona . Grazie