Skocz do zawartości

Sprawdzenie schematu urządzenia dokonującego pomiarów stężenia tlenu


Wejmon

Pomocna odpowiedź

Cześć wszystkim,

Obecnie staram się skonstruować urządzenie dokonujące pomiarów stężenia tlenu (maksymalny zakres: 30%). Wybrałem odpowiednie komponenty, jednak nie jestem pewien czy całość zadziała. Potrzebuję rady osoby, która nieco bardziej zna się na Arduino, w porównaniu do mnie (początkującego) aby oceniła przygotowane przeze mnie bardzo uproszczone schematy 🙂

Zadaniem urządzenia, tak jak wspomniałem wcześniej, jest dokonywanie pomiarów stężenia tlenu. W momencie wykrycia stężenia większego niż 21,5% tlenu w atmosferze powinien uruchomić się buzzer: sygnał ostrzegawczy. Wyniki pomiarów mają wyświetlać się na ekranie LCD, zaś całość będzie zasilana baterią 9V. Dane pozyskam podłączając urządzenie do laptopa według 10 lekcji kursu Arduino, poziom I [Link], tak aby móc przedstawić uzyskane wyniki w postaci wykresów. Zależy mi na tym czy dane komponenty są odpowiednio podłączone. Dzięki temu będę mógł przejść do pisania kodu.

1909367838_Szkic1.thumb.jpg.4d6732b03363424e29c35150addbe9c1.jpg

1708193276_Szkic2.thumb.jpg.b24b0443b690bb18c6fb1185090920e9.jpg

Wykorzystane komponenty:

- Arduino Uno R3

- Nakładka na Arduino: Base Shield v2

https://botland.com.pl/grove-nakladki-bazowe/4440-grove-base-shield-v2-nakladka-na-arduino-5904422368852.html

- Czujnik tlenu

https://botland.com.pl/grove-czujniki-gazow-i-pylow/17917--grove-czujnik-tlenu-mix8410-analogowy-.html

- Buzzer

https://botland.com.pl/grove-moduly-dzwiekowe/11298-grove-buzzer-modul-z-buzzerem-aktywnym-5903351246453.html

- Wyświetlacz LCD

https://botland.com.pl/grove-wyswietlacze/14736-grove-wyswietlacz-lcd-2x16-i2c-bialo-niebieski-z-podswietleniem-5904422322465.html

 

Mam również pytanie co do wyboru zasilania. Czy zwykła bateria 9V wystarczy do pracy takiego urządzenia? W jaki sposób można to ewentualnie obliczyć? Z góry dziękuję za pomoc osobom chętnym 👍

    

Pozdrawiam,

Wojciech (Wejmon) Ciecierski

Link do komentarza
Share on other sites

Powinno byc wporzadku...co prawda nie korzystalem z takiego czujnika, ale gdzies napewno bedzie do niego biblioteka..

Co do zasilania to bateria 9v zasili calosc, ale krotko...jak mialo by to dzialac dluzej to trzeba czegos pojemniejszego...jak chcesz obliczyc, to napiecie razy pobierany prad rowna sie watty...i to jest ilosc energii potrzebnej przez godzine...baterie liczysz tak samo i wynik dzielisz przez wynik od Arduino i masz ile godzin pochodzi...

  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

4 godziny temu, farmaceuta napisał:

Co do zasilania to bateria 9v zasili calosc, ale krotko...jak mialo by to dzialac dluzej to trzeba czegos pojemniejszego...

Osobiście bym polecał zrobić sobie wielopak z akumulatorków 18650 😉 To coś potrafi zasilić naprawdę całkiem sporo sprzętu. Oczywiście dla Arduino przydałaby się przetwornica (albo limit <12V). Sam często korzystam z paczek 20V do zasilania sprzętu jak mi padnie oryginalny aku i się okaże, że wszystkie są rozładowane 😄.

  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

34 minuty temu, H1M4W4R1 napisał:

Osobiście bym polecał zrobić sobie wielopak z akumulatorków 18650 😉 

No to najlepsza opcja bo mozna tez jakis koszyk kupic za kilka zl i do tego po taniosci ladowarke-usb na jedno ogniwo...(to takie minimum do nie wymagajacego sprzetu) 

  • Lubię! 1
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

Bardzo dziękuję za przesłane odpowiedzi 🙂

Odnośnie zasilania zobaczę na początku jak będzie sprawować się bateria 9V, jeżeli nie spełni moich rezultatów spróbuję z łączeniem ogniw 18650. Obecnie czekam na dotarcie wszystkich komponentów dzięki czemu będę mógł zabrać się za pisanie/testowanie kodu, który również tutaj zamieszczę. Mam nadzieję, że mogę liczyć na dalszą pomoc. Jeszcze raz dziękuję i pozdrawiam 😉

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

Cześć wszystkim,

Po około półtoramiesięcznej przerwie dotarły do mnie prawie wszystkie komponenty. Napisałem kod jednak mam wątpliwości co do jego poprawności. Przed wgraniem chciałbym aby ktoś bardziej kompetentny rzucił na niego okiem, w celu uniknięcia niepotrzebnych awarii.

Tak jak pisałem wcześniej zadaniem urządzenia jest dokonywanie pomiarów stężenia tlenu w powietrzu. W momencie wykrycia stężenia większego niż 21,5% powinien uruchomić się buzzer: sygnał ostrzegawczy, zaś ekran LCD (pokazujący pomiary) zaświeci się na czerwono. Całość będzie zasilana baterią 9V.

W projekcie wprowadziłem dwie kosmetyczne zmiany:

- ekran LCD 2x16 biało – niebieski [Link] zamieniłem na ekran LCD 2x16 z podświetleniem RGB [Link],

- buzzer będzie podłączony do wejścia cyfrowego D6 (według zaleceń producenta) [Link].

 

Poniżej przedstawiam napisany kod wraz z linkami stron producenta na których się wzorowałem:

// Oxilium - Czujnik stezenia tlenu - Kod
// Uwaga:
// 1. Rozgrzanie czujnika zajmuje od 5 do 10 minut
// 2. W razie potrzeby zmodyfikuj VRefer

#include <Wire.h>              // Biblioteka, ktora wymaga ekran LCD RGB, jako urzadzenie podlaczone do portu I2C
#include "rgb_lcd.h"           // Biblioteka, ktora wymaga ekran LCD RGB

rgb_lcd lcd;

const int noAlarmR = 255;   // RGB: Kolor bialy (Brak alarmu)
const int noAlarmG = 255;
const int noAlarmB = 255;

const int AlarmR = 255;     // RGB: Kolor czerwony (Alarm)
const int AlarmG = 0;
const int AlarmB = 0;

const int Ekran = 5;           // Numer wejscia I2C: 5-I2C jako Ekran 
const float VRefer = 3.3;      // Napiecie odniesienia ADC: 3.3V jako VRefer
const int pinAdc = A0;         // Numer wejscia analogowego: A0 jako pinAdc
const int Buzzer = 6;          // Numer wejscia cyfrowego: D6 jako Buzzer

float granica = 21.5;          // Ustawienie granicy dopuszczalnego stezenia tlenu na potrzeby ekranu LCD (Mozliwosc edytowania)
 
void setup() 
{
    Serial.begin(9600);                                           // Ustawienie prędkości transmisji
    Serial.println("Grove - Oxygen Sensor(MIX8410) - Test");      // Jednorazowe wysłanie tekstu
    
    pinMode(Buzzer, OUTPUT);                                      // Wyjscie dla buzzera
    Serial.println("Grove - Buzzer - Test");                      // Jednorazowe wysłanie tekstu

    pinMode(Ekran, OUTPUT);                                       // Wyjscie dla ekranu LCD
    Serial.println("Grove - LCD - Test");                         // Jednorazowe wysłanie tekstu
    lcd.begin(16, 2);                                             // Deklaracja typu
    lcd.clear();                                                  // Automatyczne wyczyszczenie zawartosci wyswietlacza. Wyeliminowanie nachodzenia tekstu
    lcd.setRGB(noAlarmR, noAlarmG, noAlarmB);
    lcd.setCursor(0, 0);                                          // Ustawienie kursora
    lcd.print("Stezenie tlenu:");
    lcd.setCursor(0,1);
    lcd.print("0.00%");
    delay(1000);
}

double odczyt;                                                    // Przedstawienie wyniku na ekranie LCD z dwoma miejscami po przecinku

void loop() 
{
    float Vout =0;
    Serial.print("Vout =");
 
    Vout = readO2Vout();
    Serial.print(Vout);
    Serial.print(" V, Stezenie tlenu wynosi ");
    Serial.println(readConcentration());
    delay(500);

    Alarm(21.5);                                                     // Wlaczenie alarmu w momencie wykrycia stezenia rownego badz wiekszego niz 21.5% tlenu w powietrzu (Mozliwosc edytowania)
    delay(100);

    float odczyt = readConcentration();
    if (odczyt >= granica)
    {
      lcd.setRGB(AlarmR, AlarmG, AlarmB);                          // Podswietlenie ekranu na czerwono w momencie wykrycia stezenia rownego badz wiekszego niz 21.5% tlenu w powietrzu
      lcd.setCursor(0, 1);
      lcd.print(odczyt);
      delay(250);
    } else
      {
      lcd.setRGB(noAlarmR, noAlarmG, noAlarmB);                    // Podswietlenie ekranu na bialo w momencie wykrycia stezenia mniejszego niz 21.5% tlenu w powietrzu
      lcd.setCursor(0, 1);
      lcd.print(odczyt);
      delay(250);
      }
}
 
float readO2Vout()
{
    long sum = 0;
    for(int i=0; i<32; i++)
    {
        sum += analogRead(pinAdc);
    }
 
    sum >>= 5;
 
    float MeasuredVout = sum * (VRefer / 1023.0);
    return MeasuredVout;
}
 
float readConcentration()
{
    // Przykłady Vout odnoszace sie do 3.3V
    float MeasuredVout = readO2Vout();
 
    //float Concentration = FmultiMap(MeasuredVout, VoutArray,O2ConArray, 6);
    //Gdy napiecie wyjsciowe wynosi 2.0V,
    float Concentration = MeasuredVout * 0.21 / 2.0;
    float Concentration_Percentage=Concentration*100;
    return Concentration_Percentage;
}

void Alarm(float procentTlenu)
{
    float readConcentration();
    if (readConcentration() >= procentTlenu)
    {
      digitalWrite(Buzzer, HIGH);
    } else
      {
      digitalWrite(Buzzer, LOW);
      }
}

Linki stron producenta:

- czujnik tlenu [Link],

- wyświetlacz LCD RGB [Link], [Link].

Z góry dziękuję za pomoc 🙂

Pozdrawiam,

Wojciech Ciecierski

Link do komentarza
Share on other sites

Buzer mozesz podpiac gdzie chcesz...to bez znaczeniawiekszego, oczywiscie najlepiej bylo by przez tranzystor, ale mozesz tez dac rezystor zeby odrobine ograniczyc prad pinu...w funkcji alarm usun ten pierwszy float, bo uzywasz funkcji w if, wiec nie musisz pisac takich rzeczy...i tak by eywalilo chyba blad...i ta zmienna sum...czemu przesuwasz tam bity?? Jesli chcesz 32 probki to dodajesz do siebie i pozniej dzielisz przez 32..

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Ciekawe jaką to ma dokładność? U nas na zakładzie czujnik tlenu w spalinach to taka mała armata, z grzałką i czujnikiem cyrkonowym. Tak naprawdę bez zestawu kalibracyjnego i tak nie stwierdzisz, jak bardzo ten kłamie.

Link do komentarza
Share on other sites

@farmaceuta Rozumiem, że poprawnie zapisana funkcja Alarm w tym przypadku powinna wyglądać tak:

void Alarm(float procentTlenu)
{
    if (readConcentration() >= procentTlenu)
    {
      digitalWrite(Buzzer, HIGH);
    } else
      {
      digitalWrite(Buzzer, LOW);
      }
}

Jeżeli chodzi o kod "float read02Vout()" oraz zasilanie, informacje te pobrałem prosto ze strony producenta w celu prawidłowego działania miernika, także mam nadzieję, że wszystko będzie w porządku 👍

 

@BlackJack Z pewnością certyfikowane mierniki gazowe są o wiele lepsze niż omawiany czujnik tlenu. To co przykuło w nim moją uwagę to fakt, że jego zakres pomiarowy wynosi od 0% do 25% z maksymalnym przeciążeniem 30%. Dokładnie takie parametry jakich potrzebowałem 🙂

Link do komentarza
Share on other sites

Tak powinna wygladac😉  z tym ze nie musisz dawac argumentu do tej funkcji bo ustawiasz na 21.5 wiec w if poprostu wpisz ta zmienna...i nie musisz uzywac funkcji w tym if...mozesz tam wpisac zmienna odczyt...bo i tak kod wykona sie z taka predkoscia ze kilka razy wywolywac ta sama funkcje nie zrobi roznicy w otrzymanych danych...

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Podłączyłem komponenty i wgrałem kod. Wszystko działa bez zarzutów, tak jak chciałem ... oprócz czujnika 😠 Nie rozumiem dlaczego podaje on wartość stężenia tlenu w powietrzu jako zaledwie 18% oraz Vout = 1.72V zamiast 1.92V. Sprawdzałem w różnych pomieszczeniach oraz na świeżym powietrzu. Bez zmian. Co ciekawe kiedy się na niego dmucha wyraźnie rejestruje spadek, zatem nie powinien być uszkodzony. Podejrzewam, że błąd znajduje się w kodzie producenta.

1541786144_Bd.thumb.jpg.16aa879ec02225a5ba458ef07659cc4d.jpg

Szperając w internecie natrafiłem na podobne przypadki, potwierdzające moje wątpliwości. Znalazłem też "poprawiony" kod, jednak nie jestem pewien czy to właściwe rozwiązanie ze względu na problemy z wgraniem go do Arduino [Link]:

// Oxygen.h
#ifndef _OXYGEN_h
#define _OXYGEN_h
#define O2_pin A1
extern bool O2_init_flag;
float O2_value();                //Uzyskaj dane O2
#endif

// Oxygen.cpp
#include "Oxygen.h"
#include "arduino.h"
#define O2_preheat_time 60000    //Czas nagrzewania 1 minuta
bool O2_init_flag = 0;           //1 jest gotowy
float calibration_voltage;       //Skalibrowane napiecie
#define O2_percentage 20.80


float O2_value()                 //Uzyskaj dane O2
{
  unsigned int sum = 0;
  if (O2_init_flag == 0)
  {
    O2_init_flag = 1;            //Kalibracja po wlaczeniu
    pinMode(O2_pin, INPUT);
    for (unsigned char i = 64;i > 0;i--)
    {
      sum = sum + analogRead(O2_pin);
      delay(100);
    }
    sum = sum >> 6;
    calibration_voltage = sum / O2_percentage;//Uzyskanie wspolczynnika korekcji
    //SerialUSB.println(calibration_voltage);
    return 20.80;                //Kalibracja powiodla sie
  }
  else
  {
    for (unsigned char i = 32;i > 0;i--)
    {
      sum = sum + analogRead(O2_pin);
      delay(50);
    }
    sum = sum >> 5;
    //SerialUSB.println(sum);
    float output = sum / calibration_voltage;
    //SerialUSB.println(sum);
    return output;
  }
}

// readO2.ino
    #include "Oxygen.h"
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      Serial.println("Calibration sensor...This needs one minute");
      O2_value();
      Serial.println("Finish Calibration");
    }

    void loop() {
      // put your main code here, to run repeatedly:
      float O2 = 0;
      O2 = O2_value();
      Serial.print("The percentage of oxygen is:");
      Serial.print(O2);
      Serial.println("%");
      delay(1000);
    } 

W załączniku dodałem wszystkie pliki udostępnione przez autora kodu.

Jeżeli ktoś wie w jaki sposób poprawić kod, tak aby czujnik działał prawidłowo, byłbym bardzo wdzięczny za pomoc 👍 

Read_O2_value.zip

Link do komentarza
Share on other sites

Ten kod cos jest strasznie przekombinowany...po co Ci biblioteka skoro jej wogole nie uzywasz? Skoro jest to zwykly czujnik analogowy to wystarczy ze odczytasz wartosc analogowa i odpowiednio przeskalujesz do skali jaka ten czujnik ma...np. 1v to 0% a 3,75v to 100%..(taki przyklad) i teraz zwykla funkcja map() i gotowe...

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.