Nieuw lid + vraag over software omtrent luchtdrukmeter.

Arduino specifieke Software
Berichten: 15
Geregistreerd: 14 Okt 2020, 12:57

Nieuw lid + vraag over software omtrent luchtdrukmeter.

Berichtdoor Adriaan_VOLVO940 » 14 Okt 2020, 13:31

Beste lezers,

Mijn naam is Adriaan student Automotive. In mijn vrije tijd vind ik het leuk om bezig te zijn met verschillende technische projecten, nu dus met een Arduino. Het doel van het project is om de turbodruk van mijn auto weer te geven op een Oled display.

De hardware is als volgt:
-Bosch druksensor 20kpa tot 250kpa de formule die door de fabrikant is opgegeven luid: Pabs=Uout / Uin *270.5847 - 1.65057
-Oled display 128x64 0.96'' I2C IIC
-Namaak Arduino nano

Op internet heb ik software gevonden die iemand anders al had geschreven voor eenzelfde project. Die software heb ik verandert zodat de lay-out er anders uitziet. Maar ik krijg het niet voor elkaar om de waarde juist de krijgen.

Metingen:
Output Arduino op 5v poort = 4.78
geen druk op de sensor is een Uout van 1.90 volt
1 bar druk op de sensor is een Uout van 3.76 volt
De atmosferische druk op dit moment is 1013.9 mbar

Hoe kan ik de juiste formules invoeren in de software, zodat de juiste turbodruk wordt weergegeven en de display netjes 0 weergeeft wanneer er alleen maar de atmosferische druk is.
Hieronder staat een linkje als je op die link klikt kom je op een file uit met het bestand wat ik gebruikt heb.
http://www.mediafire.com/file/1zhgtzw7j ... t.ino/file

Vriendelijke groet, Arduino noob.

Advertisement

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Nieuw lid + vraag over software omtrent luchtdrukmeter.

Berichtdoor Koepel » 14 Okt 2020, 15:48

Via de knop "Code" krijg je code-tags [ code ] en [ / code ] maar dan zonder spaties. Als je daar je sketch tussen zet, dan ziet het er beter uit.
Op deze manier:

Code: Alles selecteren
//Arduino pro micro, .93" I2C OLED use pin 2 for SDA and 3 for SCL ***Look up i2c pins for your controller

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define sensorPin A0

int OLED_RESET = 4;
Adafruit_SSD1306 display(OLED_RESET); //driver for the screen

// bar graph

float rawval = 0; // Setup raw sensor value
float barboost = 0; // Setup value for boost bar

// peak

int boostPeakReset = 4000; // time in milis to reset peak value
float boostPeak = 0.00;
float boostMax = 0.00;
unsigned long boostPeakTimer = 0;



// log

byte count;
byte sensorArray[128];
byte drawHeight;
boolean filled = 0; //decide either filled, or dot-display. 0==dot display.


void setup()
{
  Serial.begin(9600); // start monitoring raw voltage for calibration
  display.begin(SSD1306_SWITCHCAPVCC); // 3.3V power supply
  display.clearDisplay(); // Clear the display and ram
  display.display();
  delay(2000); // display Adafruit logo for 2 seconds
  for (count = 0; count <= 128; count++) //zero all elements
  {
    sensorArray[count] = 0;
  }
}


void loop() // Start loop
{


 
  int boostmbar = map(analogRead(sensorPin), 21, 961, 100, 2600);
  rawval = analogRead(0); // Read MAP sensor raw value on analog port 0
  barboost = (((rawval * 0.19) - 69.45) + 10); // Calculate boost value for the graph



  if (boostPeak < boostmbar && boostmbar > 0.50) {
    boostPeak = boostmbar;
    boostPeakTimer = millis();
    if (boostMax < boostPeak) {
      boostMax = boostPeak;
    }
  }
  else if (boostPeak > boostmbar && (millis() - boostPeakTimer) > boostPeakReset) {
    boostPeak = 0.00;
  }


  // log

  drawHeight = map(analogRead(A0), 0, 1023, 0, 25 ); 

  sensorArray[0] = drawHeight;

  for (count = 55; count <= 128; count++ )
  {
    if (filled == false)
    {
      display.drawPixel(count, 71 - sensorArray[count - 55], WHITE);
    }
    else
      display.drawLine(count, 1, count, 71 - sensorArray[count - 55], WHITE);
  }

  for (count = 80; count >= 2; count--) // count down from 160 to 2
  {
    sensorArray[count - 1] = sensorArray[count - 2];
  }

  //display.drawLine(55, 43, 55, 64, WHITE);
  //display.setTextColor(WHITE);
  //display.setTextSize(3);
 // display.setCursor(0, 10);
 // display.println(((boostmbar * 0.001) - 0.865)*14);    // calibrated for a 2.5 bar sensor in Denver (+/- 1psi)


  display.fillRect(0, 0, barboost, 4, WHITE); // Draws the bar depending on the sensor value

  //display.setTextColor(WHITE);
 // display.setTextSize(1);
  //display.setCursor(97, 20);
  //display.println("BOOST");

  display.setTextSize(1); //Display peak boost
  display.setCursor(97, 10);
  display.println(((boostPeak * 0.001) - 0.865)*14); // 0.97 = 970mbar atmospheric pressure correction


  if ((((boostmbar  * 0.001) - 0.865)*14) < 0) {
    display.setTextSize(1);
    display.setCursor(97, 20);
    display.println("INHG");
    display.setCursor(0, 10);
    display.setTextSize(3);
    display.println(((boostmbar * 0.001) - 0.865)*63.2);
  }
  else if ((((boostmbar * 0.001) - 0.865)*14) > 0) {
    display.setTextSize(1);
    display.setCursor(97, 20);
    display.println("BOOST");
    display.setTextColor(WHITE);
    display.setTextSize(3);
    display.setCursor(0, 10);
    display.println(((boostmbar * 0.001) - 0.865)*14);    // calibrated for a 2.5 bar sensor in Denver (+/- 1psi)


}

  delay(1);
  display.display();
  display.clearDisplay();

  Serial.print("Input from A0 is ");
  Serial.println(rawval);    // print the raw value from the sensor (0-100%)

  delay(10); // delay half second between numbers
}


Welke sensor is het ?
Het hangt er van af of die sensor ratiometric is.
Kun je een link naar die sensor geven ?
Heb je een module waar die sensor op zit ? Kun je dan ook een link geven naar die module (naar waar je het hebt gekocht).

Kun je een link geven naar waar je het OLED display hebt gekocht ? Een Adafruit OLED display is geschikt voor 3.3V en 5V Arduino boards. Alle andere zijn eigenlijk alleen geschikt voor 3.3V boards.

Een namaak Arduino kan soms stoppen met werken bij vriestemperaturen. Het beste is om een Arduino board met resonator te kopen of een crystal dat geschikt is voor -20°C.
Als je een Arduino Nano via de USB kabel van stroom voorziet, dan is het normaal dat de spanning iets onder de 5V is. Geen probleem.

Kun je meteen even door heel je sketch lopen ? Met de volgende punten:

1. In de Arduino wereld worden pin nummers bij voorkeur met een 'int' gedaan en niet met een #define. Je zou "const int sensorPin = A0;" kunnen doen.

2. Je kunt na Serial.begin() meteen een bericht doen naar de seriële monitor. Dan weet je dat het board loopt en je weet wanneer het board per ongeluk zou resetten.

3. De map() functie is geen echte functie. Dat levert soms problemen op. Je kunt beter een echte variabele als eerste parameter doen. Ik gebruik de map() functie helemaal niet, want ik hou niet van verrassingen.

4. Je hebt maar één sensor, dus één keer een analogRead() opvragen is beter. Dat maakt het ook gemakkelijker om meerdere samples te nemen en dan het gemiddelde te berekenen. Door meerdere samples te nemen van een analoge sensor kun je de ruis wegwerken, dan wordt het resultaat een stuk stabieler.

5. De returnwaarde van analogRead() is een integer en die stop je in 'rawval' dat een float is. Dat is een conversie. Het is beter als jij zelf bepaalt waar en hoe die conversie wordt gedaan.

6. Het is beter om alle getallen in de sketch goed te beschrijven. Een getal van "0.865" zonder uitleg wordt soms een "magic number" genoemd. Dat is een getal waarvan niemand weet waar het vandaan komt en dus kan niemand het controleren. Een groot programma met slechts één "magic number" is een programma waar niemand iets aan heeft.

7. Is het sensorArray alleen om een grafiek te laten zien ? Dat is 128 byte, terwijl de Adafruit libraries voor de OLED bijna al het sram in beslag nemen.

8. Ik mis een header met commentaar bovenin de sketch. Daar kun je de datum zetten, welke Arduino versie, welk Arduino board, en vooral welke sensor wordt gebruikt.

Mijn persoonlijke voorkeur is op deze manier:
Code: Alles selecteren
void loop()
{
  int rawADC = analogRead( sensorPin);    // later gemiddelde van meerdere samples nemen.
  float voltage = float( rawADC) / 1024; * 5.0;   // de waarde als VCC ook echt 5.0V zou zijn.
  float bar = ...  // hier de berekening
  ...
}


Poeh, dit bericht werd nog best lang :shock: en jij dacht even snel een korte vraag te stellen :lol:

Berichten: 4067
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: Nieuw lid + vraag over software omtrent luchtdrukmeter.

Berichtdoor shooter » 14 Okt 2020, 15:50

ik zou map gebruiken
map(value, fromLow, fromHigh, toLow, toHigh)
ofwel input = analogRead(A0)
dan output=map(input, 388,769, 0, 1)
de getallen heb ik even uitgerekend hoor.
388 is in bits 1.9/5*1023.
en 769 is 3.76/5*1023.
dat is niet erg precies misschien maar is een begin.
dan krijg je dus een output in float! van 0 tot 1 bar.
paul deelen
shooter@home.nl

Berichten: 15
Geregistreerd: 14 Okt 2020, 12:57

Re: Nieuw lid + vraag over software omtrent luchtdrukmeter.

Berichtdoor Adriaan_VOLVO940 » 14 Okt 2020, 19:56

Ten eerste bedankt voor de snelle en uitgebreide reacties!

Beste Koepel,
Het is een sensor van Amazon, namaak van bosch type 0 281 002 593. Datasheet staat in deze pdf op pagina 61: https://www.bosch-ibusiness.com/media/images/products/sensors/xx_pdfs_1/sensors_i-business.pdf
Oled display is deze: https://nl.aliexpress.com/item/4001275132454.html?spm=a2g0s.9042311.0.0.47d44c4d5o16G7
De nano plaats ik in het interieur van mijn auto en zal dus niet snel met temperaturen onder het vriespunt te maken krijgen.
De software heb ik dus van het internet geplukt, de formules die erin staan zijn niet mijn eigen formules maar die van een ander. Teksten en lay-out aanpassen lukt mij wel maar de code aanpassen op de door jou omschreven manieren vind ik nog lastig. Dit geld ook voor de gegeven tips door Shooter. Hoe kan ik maar een analogRead aanvragen en toch de software kloppend houden? Ik hoop niet teveel van jullie kostbare tijd te vragen, en mocht het simpelweg teveel gevraagd zijn om mij in alle stappen uitgebreid mee te nemen geef dat even aan dan leg ik het draadje gewoon even neer. Mochten jullie je toch geroepen voelen mij te helpen zie ik graag een reactie te ge moed!

Mvg, Adriaan.

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Nieuw lid + vraag over software omtrent luchtdrukmeter.

Berichtdoor Koepel » 14 Okt 2020, 20:25

Waarom zou de namaak op de echte lijken ?

Je kunt eenmalig een analogRead() doen, en dan verder in de loop() alleen nog maar die rawADC gebruiken.
Code: Alles selecteren
int rawADC = analogRead();


Zo'n OLED display is voor 3.3V. Als dat het enige is dat op de I2C bus zit, dan gaat het vaak goed. Maar als er iets anders bij komt, dan kan dat andere niet meer werken.

shooter heeft een kort en krachtige oplossing. Je zou zijn berekening en mijn berekening beide in je sketch kunnen zetten 8-)

Mijn manier is uitgebreid en langdradig.
Ik ga er van uit dat de sensor ratiometric is, maar dat staat er niet bij. Toch is dat erg belangrijk, omdat jouw Nano op een lagere spanning draait.
De sensor geeft kPa, dus dat ga ik eerst berekenen.

Code: Alles selecteren
// Bosch DS-S2
// -----------------
// 5V, 20 kPa = 0.40V, 250 kPa = 4.65V.
// Voltage range = 4.65 - 0.40
// Pressure range = 250 - 20
//
// Verwijder de offset, leg het bereik op elkaar en tel de nieuwe offset er weer bij op.
// Het bereik op elkaar leggen is delen door het voltagebereik en vermenigvuldigen met het bereik van de druk.
// Door te delen met het voltage, verdwijnt het voltage.
// Door te vermenigvuldigen met de druk, wordt de druk geintroduceerd.
//
void loop()
{
  int rawADC = analogRead( sensorPin);    // later gemiddelde van meerdere samples nemen.
  float voltage = float( rawADC) / 1024; * 5.0;   // de waarde als VCC ook echt 5.0V zou zijn.
  float kPa = (((voltage - 0.40) / (4.65 - 0.40)) * (250.0 - 20.0)) + 20.0;
  float bar = kPa / 100.0;
  Serial.println( bar);
  ...
}


De bedoeling is om eerst de juiste waarde in de seriële monitor te laten zien. Ik ben niet bekend met de Adafruit GFX library.
Laatst gewijzigd door Koepel op 14 Okt 2020, 20:28, in totaal 1 keer gewijzigd.

Berichten: 15
Geregistreerd: 14 Okt 2020, 12:57

Re: Nieuw lid + vraag over software omtrent luchtdrukmeter.

Berichtdoor Adriaan_VOLVO940 » 14 Okt 2020, 21:49

Code: Alles selecteren
[code]

//Arduino nano .93" I2C OLED. Luchtdruksensor: 0 281 002 593.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
const int sensorPin = A0;

int OLED_RESET = 4;
Adafruit_SSD1306 display(OLED_RESET); //driver for the screen

// bar graph

float rawval = 0; // Setup raw sensor value
float barboost = 0; // Setup value for boost bar

// peak

int boostPeakReset = 10000; // time in milis to reset peak value
float boostPeak = 0.00;
float boostMax = 0.00;
unsigned long boostPeakTimer = 0;



// log

byte count;
byte sensorArray[128];
byte drawHeight;
boolean filled = 0; //decide either filled, or dot-display. 0==dot display.


void setup()
{
  Serial.begin(9600); // start monitoring raw voltage for calibration
  for (count = 0; count <= 128; count++) //zero all elements

    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
    display.clearDisplay() ;
    display.setTextColor(WHITE);
    display.setTextSize(3) ;
    display.setCursor(15,10) ; //positie Hallo
    display.print("Hallo") ;
    display.display();
    delay(2000) ; //vertraging tussen weergeven Hallo en Volvo 940 TURBO
    display.clearDisplay();
    display.setTextColor(WHITE);
    display.setTextSize(2);
    display.setCursor(0,0); //positie Volvo 940 TURBO
    display.print("Volvo 940 TURBO");
    display.display();
    delay(5000); //vertraging tussen weergeven Volvo 940 TURBO en boost
  {
    sensorArray[count] = 0;
  }
}


void loop() // Start loop
{

 
  int boostmbar = map(analogRead(sensorPin), 21, 961, 100, 2600); //
  rawval = analogRead(0); // Read MAP sensor raw value on analog port 0 //
  barboost = ((rawval * 0.19) - 77.33); // Calculate boost value for the graph, betekenis getallen onbekend met 77,33 aan te passen naar 0.



  if (boostPeak < boostmbar && boostmbar > 0.50) {
    boostPeak = boostmbar;
    boostPeakTimer = millis();
    if (boostMax < boostPeak) {
      boostMax = boostPeak;
    }
  }
  else if (boostPeak > boostmbar && (millis() - boostPeakTimer) > boostPeakReset) {
    boostPeak = 0.00;
  }


  // log

  display.fillRect(0, 0, barboost, 4, WHITE); // Draws the bar depending on the sensor value
  display.setTextSize(1); //Display peak boost
  display.setCursor(97, 10);
  display.println((boostPeak * 0.001) - 1.128); // 1.128 = 1128mbar atmospheric pressure correction


    if (((boostmbar  * 0.001) - 1.128) < 0) { //1,128 is de correctie voor de atmosferische druk. 0,001 is de omrekening van mbar naar bar.
display.setTextSize(1);
display.setCursor(97, 20);
display.println("PEAK");
display.setCursor(0, 10);
display.setTextSize(3);
display.println("ECO");
  }
    else if (((boostmbar * 0.001) - 1.128) > 0) { //1,128 is de correctie voor de atmosferische druk. 0,001 is de omrekening van mbar naar bar.
    display.setTextSize(1);
    display.setCursor(97, 20);
    display.println("PEAK");
    display.setTextColor(WHITE);
    display.setTextSize(3);
    display.setCursor(0, 10);
    display.println((boostmbar * 0.001) - 1.128);    // 1,128 is de correctie voor de atmosferische druk. 0,001 is de omrekening van mbar naar bar.

}

  delay(1);
  display.display();
  display.clearDisplay();

  Serial.print("Input from A0 is ");
  Serial.println(rawval);    // print the raw value from the sensor (0-100%)

  delay(10); // delay half second between numbers
}

[/code]

Berichten: 15
Geregistreerd: 14 Okt 2020, 12:57

Re: Nieuw lid + vraag over software omtrent luchtdrukmeter.

Berichtdoor Adriaan_VOLVO940 » 14 Okt 2020, 21:51

Ik heb de code verder aangepast. Hij geeft nu alles juist weer, dit heb ik gecheckt door er een analoge drukmeter aan te hangen. Er zit inderdaad nog een klein beetje ruis in de display verspringt af en toe 0.01 tot 0.02 bar. Dit kan ik er dus uitkrijgen door de door jullie genoemde aanpassingen te doen?

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Nieuw lid + vraag over software omtrent luchtdrukmeter.

Berichtdoor Koepel » 15 Okt 2020, 10:44

Wij lieten zien hoe je met de gegevens van die sensor de juiste druk kunt berekenen.
Als je het gemiddelde van meerdere samples wilt nemen, dan is dat iets anders.

Heb je nu de druk berekend door net zolang met de getallen te rommelen totdat de druk overeen kwam met je analoge drukmeter ?

Berichten: 15
Geregistreerd: 14 Okt 2020, 12:57

Re: Nieuw lid + vraag over software omtrent luchtdrukmeter.

Berichtdoor Adriaan_VOLVO940 » 15 Okt 2020, 20:58

Beste Koepel,

Ik zou het graag op jouw manier doen, echter is mij niet duidelijk hoe ik de huidige software kan veranderen om hem werkend te krijgen. Als ik probeer om de door jouw gegeven formules in te voeren klopt het niet meer en krijg ik een error. Helaas ben ik nog niet handig genoeg om die eruit te krijgen. Ik ben nu aan het proberen om de code zelf opnieuw te schrijven maar dan op jouw manier maar dat valt nog niet mee. Kan je mij verder op weg helpen?

Berichten: 15
Geregistreerd: 14 Okt 2020, 12:57

Re: Nieuw lid + vraag over software omtrent luchtdrukmeter.

Berichtdoor Adriaan_VOLVO940 » 15 Okt 2020, 22:04

Dit is de code nu. Op de seriele monitor lees ik -0,02 af maar wel netjes constant :) daar wordt ik al enorm vrolijk van.

-Nu het vervolg, hoe ga ik hem netjes op 0.00 krijgen?
-De door jou gegeven formule bevat wat getallen waar ik de betekenis niet van ken, en ik weet ook niet hoe je aan die formule bent gekomen dus ik herschrijven / aanpassen lastig.
-De waarde die de seriele monitor nu aangeeft veranderd trouwens niet zodra er druk/vacuum op de sensor gezet wordt of is dat juist de bedoeling?

Code: Alles selecteren
// 15-10-2020
//fake arduino nano
// Luchtdruksensor 0 281 002 593 aangesloten op A0
//

void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:

//int BoostsensorValue = analogRead(A0); //lezen van de waarde van de luchtdruksensor
//Serial.println(BoostsensorValue); //weergeven van de analoge waarde in de seriele monitor
//delay(1); //vertraging tussen de metingen van de seriele monitor

  int rawADC = analogRead(A0); //lezen van de waarde van de luchtdruksensor.
  float voltage = float ((( rawADC) / (1024)) * 0.5); //waarde als VCC 5volt zou zijn.
  float kPa = (((voltage-0.40) / (4.65 - 0.40)) * (250.0 - 20.0)) + 20; //onbekend voor mij waar de waardes vandaan komen?
  float bar = (kPa / 100.0); //omrekenen van Kpa naar bar.
  Serial.println(bar); //kopieren naar seriele monitor.
}

Volgende

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Google Adsense [Bot], Orvillehob, umisaki en 34 gasten