Skocz do zawartości

Projekt z czujnikami do auta


MatJJ

Pomocna odpowiedź

Cześć,
Chciałbym wykonać projekt na arduino który polegałby na czytaniu danych z trzech czujników i wyświetlał dane na ekranie wyświetlacza LCD.
Czujniki to : ciśnienie doładowania, ciśnienie oleju, temp oleju.
Z ciśnieniem doładowania poradziłem sobie szybko, ponieważ działa on liniowo, a pozostałe dwa nie.
Oto dane dla dwóch czujników które otrzymałem od producenta:
(Dane są „na gotowo” po dobraniu odpowiednich oporników.)

Ciśnienie oleju:

image.thumb.png.ace0afa33d0caec2528d30bb555e1519.png

 


Temp oleju:
image.thumb.png.3edb96b169d07f384c136330bda93a51.png

 



Wyznaczyłem z tego wzory funkcji :
Ciśnienie oleju:
image.thumb.png.e7154b1512605ac77576ac096c0f9304.png


Temp oleju: 
image.thumb.png.54d53856a82f58fb5d1d47a3966e0546.png



I tutaj się zatrzymałem.
Za cienki jestem i nie potrafię napisać kodu z użyciem tych funkcji. A informacje z internetu nie za wiele mi mówią 😕
Czy ktoś mógłby mi pomóc, podpowiedzieć coś w napisaniu kodu dla tych dwóch czujników ?

 

 

 

image.png

image.png

image.png

Edytowano przez MatJJ
załączniki bład
Link do komentarza
Share on other sites

Z czym konkretnie masz problem? Nie potrafisz napisać wzoru/algorytmu na odczytanie rzeczywistej wartości czy może znasz wzór a nie potrafisz napisać kodu?

Uściślij, bo chciałbym pomóc ale nie bardzo wiem jak.

Link do komentarza
Share on other sites

Jezeli te rozdzielczosci z tabel sa dla Ciebie wystarczajace to mozna dane pomiaru i dane analogowe wpakowac do dwoch tablic i odpowiednio porownywac z adc...z tym ze na "wyjsciu" uzyskasz tylko to co masz w tabelach...nic posredniego

Edytowano przez farmaceuta
Link do komentarza
Share on other sites

(edytowany)

Znam tylko te informacje 
image.thumb.png.931c2aaf4452d2ed0389727a69d96a8f.png (np.dla temp oleju)

ale nie potrafię napisać tego w kodzie, nie wiem jak odczytać i wypisać wartości. 

To kod którego używam do odczytania wartości z czujnika ciśnienia doładowania który jest liniowy i nie opornosciowy: 

 

#include <LiquidCrystal_I2C.h> //użyte biblioteki 
#include <Wire.h> //użyte biblioteki 
#define BACKLIGHT_PIN 3 //pin podświetlenia wyświetlacza 
LiquidCrystal_I2C lcd(0x27, 20 , 4); //adres wyświetlacza 

//Map sensor
const int pressureInput = A0; //PIN OD MAP SENSORA
const int pressureZero = 0; //analog reading of pressure transducer at 0psi
const int pressureMax = 330; //analog reading of pressure transducer at 100psi
const int pressuretransducermaxPSI = 3; //psi value of transducer being used


const int baudRate = 9600;
const int sensorreadDelay = 250; 


float pressureValue = 0; 
float OTValue = 0; 
float OPValue = 0; 

void setup() 
{
  Serial.begin(baudRate); 
    
    lcd.begin(20,4); //lcd Wire.begin(); 
    lcd.setBacklight(HIGH);
    
}

void loop() //loop routine runs over and over again forever
{
  //map sensor
  pressureValue = analogRead(pressureInput); //reads value from input pin and assigns to variable
  pressureValue = ((pressureValue-pressureZero)*pressuretransducermaxPSI)/(pressureMax-pressureZero); 
  Serial.print(pressureValue, 1);
  Serial.println("bar"); //prints label to serial

  
  lcd.setCursor(0,0); 
  lcd.print("Boost:"); 
  lcd.print(pressureValue-1, 1); 
  lcd.print("b"); 
  lcd.print("         .");
  
  lcd.print("OIL TEMP:         *C");//3 linia
  
  lcd.setCursor(0, 1); //Ustawienie kursora na drugiej linii i pierwszym znaku 
  lcd.print("OIL PRESSURE:      b"); //Wyświetlenie tekstu na 2 linii
    
  lcd.print("Intake temp:      ."); //Wyświetlenie tekstu na 4 linii
    
  delay(sensorreadDelay);
}


 

Znalazłem gdzieś w internetach że ktoś robił coś podobnego tylko na seryjny czujnik w porshe i użył takiego kodu : 
 

// the setup routine runs once when you press reset:
void setup() {}

// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin A3 and convert the analog reading (which goes from 0 - 1023) to voltage (0 - 5V):
float v = analogRead(A3) * (5.0 / 1023.0);
float vout = 2.0; // To ensure the needle stays below 120F when the temp is below 120F
//y = -0.3023x2 + 1.3098x + 0.294
if (v < 2.0) { vout = -0.3023*pow(v,2) + 1.3098*v + 0.294; }
// If using a non-Vision VDO oil temp gauge, comment out the previous line and uncomment the following line
//if (v < 2.0) { vout = -0.2352*pow(v,2) + 1.3098*v + 0.3117; }
//float vout = v; // Uncomment this line for calibration
// convert vout (0 - 5.0V) to output (0 - 255) and write to D1
analogWrite(1, (int)(255.0*vout/5.0));
delay(100);
}



Dla funkcji : 
image.thumb.png.76d1a9eae2c9bfba3c68b5aed6cdd17b.png

Niestety nie mam wiedzy i pojęcia jak to zrobić u mnie. Miałem kiedyś C++ w technikum ale nie za wiele pamiętam , C jest podobne ale nie mogę tego ogarnąć 😕 
PS. dostałem jeszcze gdzieś info żeby zastosować schemat Hornera, wtedy będzie to o wiele szybciej działać i mniej obciążać arduino i to już wgl dobiło moje umiejętności 😕 

 



 

Edytowano przez MatJJ
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

15 minut temu, farmaceuta napisał:

Jezeli te rozdzielczosci z tabel sa dla Ciebie wystarczajace to mozna dane pomiaru i dane analogowe wpakowac do dwoch tablic i odpowiednio porownywac z adc...z tym ze na "wyjsciu" uzyskasz tylko to co masz w tabelach...nic posredniego

W tabelach mam dane co ileś tam wartości, a chcę żeby działało to dla temperatury co 1*C a dla ciśnienia co do 0.1b 

Link do komentarza
Share on other sites

3 minuty temu, MatJJ napisał:

W tabelach mam dane co ileś tam wartości, a chcę żeby działało to dla temperatury co 1*C a dla ciśnienia co do 0.1b 

A no wlasnie...to moja metoda odpada z powodu malej ilosci probek...moze wiedzac powyzsze kolega @ethanak cos pomoze, bo ja nie mam pojecia czy da sie jakos algorytmem ogarnac taka nieliniowosc...🤔

A ..i wklej ten kod poprawnie

Edytowano przez farmaceuta
Link do komentarza
Share on other sites

No to albo napiszesz jakiś porąbany wielomian, albo po prostu potraktujesz wykres jako łamaną i odczytasz sobie wartość znajdując przedział. Niech U1 i U2 to są napięcia granic przedziału, Y1 i Y2 to graniczne wartości rzeczywiste dla tegoż przedziału, U0 to zmierzone napięcie. Wtedy wystarczy

float U= U0 - U1;
float x = (U-U1)/(U2-U1);
float Y= Y1 + (Y2 - Y1) * x;

I w zmiennej Y masz wynik, biorąc pod uwagę dokładność przetworników Arduino tak samo dokładny jak najprecyzyjniejszy wielomian.

Możesz to uprościć, wstawiając w tabele nie rzeczywiste napięcia a wartości typu int odczytane z przetwornika, a jako wartości wynikowe również wartości typu int jako wielokrotności Twojej rozdzielczości. Wtedy wystarczy prosta funkcja map:

 

Y=map(U0, U1, U2, Y1, Y2);

 

Edytowano przez ethanak
  • Lubię! 1
Link do komentarza
Share on other sites

Co do wielomianu to chyba coś udało mi się zrobić żeby się pokrywało. Tylko nie mam wiedzy co dalej z tym zrobić 

image.thumb.png.85f253353f17f7e20edab45a85a38ff0.png

image.thumb.png.63679729e549e1b21a9620f299c8fbad.png

(po kliknięciu widać na górze). 

Z takimi informacjami coś mądrego uda się już zrobić? Jeżeli tak to czy byłbyś w stanie mi pomoc? Bo ja za cholerę nie potrafię a już dobre kilka dni próbuję 😕 

Link do komentarza
Share on other sites

Dokladnie jak kolega @ethanak pisze..."dzielisz" skale na odcinki i liniowo sobie skalujesz...w przypadku temperatury to ladnie wyjdzie bo probek jest na tyle duzo ze praktycznie w kazdym odcinku masz zachowana liniowosc wiec wynik zawsze bedzie prawidlowy...gorzej z olejem...jezeli ten wykres powyzej jest dobry to szukasz sobie punktow gdzie od A do B jest w miare linia prosta...zapisujesz skrajne napiecia i odczyty, i mapujesz...powinno dzialac bardzo dobrze

Link do komentarza
Share on other sites

Noo faktycznie! to będzie mega proste. 
@ethanak jesteś geniuszem !!! 😄

Czyli to: 

float U= U0 - U1;
float x = (U-U1)/(U2-U1);
float Y= Y1 + (Y2 - Y1) * x;

Robię dla każdego przedziału czyli przykładowo dzielę sobię mój wykres np. 
image.thumb.png.0e1ccbc55767a3b024560db2d42d46cd.png
I będzie okej 🙂 


I pytanko jak "połączyć" te przedziały? (To chyba najgłupsze pytanie jakie dziś mogłem zadać wybaczcie mi proszę ale chociaż czegoś się nauczę 🙂 



Panowie wielkie dzięki !!! 

 

Link do komentarza
Share on other sites

Ja bym to zrobil na tablicach...tylko 5 przedzialow...sprawdzasz czy adc przekroczylo pierwszy przedzial...jesli tak to przechodzisz do nastepnego i na odwrot...caly czas oczywiscie skalujesz z uzyciem map() (zeby wyswietlic wynik)

Link do komentarza
Share on other sites

Dokładnie tak - i przejdź na inty, bo floaty są tu absolutnie niepotrzebne, a funkcja map() działa właśnie na intach.

Jak chcesz przykładowy kod to wieczorem, bo na telefonie słabo się kidy pisze.

Edytowano przez ethanak
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.