Skocz do zawartości

Uruchamianie niezależnych czujników DS18B20/ Niezależne linie onewire


Gość

Pomocna odpowiedź

Witam.

Ponieważ trudno znaleźć informację w Internecie odnośnie kilku linii onewire, a wszelakie sugestie pomijają ten problem mam proste pytanie;

W odróżnieniu od programowania sterowników PLC, arduino (przynajmniej w mojej opinii) jest jakimś koszmarem na sam start przygody programistycznej. Szczerze mówiąc jeszcze nie doszedłem do momentu obsługi wyświetlacza, a już mam poważny problem z obsługą (wydawałoby się) prostego czujnika DS18b20. O ile w sterownikach PLC można bardzo szybko zadeklarować kilka czujników na jednej linii, bądź kilku niezależnych czujników onewire, tak w arduino dla porównania jest to normalna męka. Na chwilę obecną udało mi się pozbyć wstrętnego delay(750) poprzez funkcję  millis i  sensors.setWaitForConversion(0); w oddzielnej pętli wywoływanej co 10s, ale wciąż pozostaje problem z zadeklarowaniem kilku niezależnych linii onewire. Np. A0 - pierwszy czujnik, A 1 - drugi czujnik, A2 - Trzeci czujnik itp. Od razu zaznaczam, że nie interesuje mnie wspólna linia która w przypadku uszkodzenia odstawi wszystkie pomiary. Ma ktoś pomysł jak to zrobić? Bo mi osobiście po za wstawieniem analogowych czujników pod wejścia ADC nic innego do głowy nie przychodzi. 

Link do komentarza
Share on other sites

Wczoraj i dziś przetestowałem taki kawałek kodu;

#include <OneWire.h>
#include <DallasTemperature.h>

unsigned long  ul_T = 0; //globalna zegarowa micros typu "unsigned long"
unsigned long  ul_TT = 0; //globalna zegarowa millis typu "unsigned long"

unsigned long  ul_t1 = 0; //Zmienne czasowe typu "unsigned long"
long  l_t2 = 0;

float f_a1 = 0; // zmienne analogowe typu "float"
float f_a2 = 0;
float f_a3 = 0;

int i_a1 = 0;  // zmienne analogowe typu "int"
int i_a2 = 0;
int i_a3 = 0;
int i_a4 = 0;

void setup() {

Serial.begin(9600);

}

void loop(){

ul_T = micros();
l_t2 = ul_T - ul_t1;

if (l_t2 >= 1000) {
  ul_t1 = ul_T; 
 i_a1++; 
}              

if (i_a1 > 1000 && i_a1 < 1002) {

OneWire oneWire(A0);
DallasTemperature sensors(&oneWire);
sensors.begin();
sensors.setWaitForConversion(0);

sensors.requestTemperatures();
f_a1 = sensors.getTempCByIndex(0) * 10; // mnożnik przd konwesją int
i_a2 = f_a1; // konwersja na int

Serial.print("temp_1 ");
Serial.print(i_a2);
Serial.println(' ');
}

else if (i_a1 > 2000 && i_a1 < 2002) {
OneWire oneWire(A1);
DallasTemperature sensors(&oneWire);
sensors.begin();
sensors.setWaitForConversion(0);

sensors.requestTemperatures();
f_a2 = sensors.getTempCByIndex(0) * 10; // mnożnik przd konwesją int
i_a3 = f_a2; // konwersja na int
Serial.print("temp_2 ");
Serial.print(i_a3);
Serial.println(' ');
}

else if (i_a1 > 3000 && i_a1 < 3002) {
OneWire oneWire(A2);
DallasTemperature sensors(&oneWire);
sensors.begin();
sensors.setWaitForConversion(0);

sensors.requestTemperatures();
f_a3 = sensors.getTempCByIndex(0) * 10; // mnożnik przd konwesją int
i_a4 = f_a3; // konwersja na int
Serial.print("temp_3 ");
Serial.print(i_a4);
Serial.println(' ');

}
else if (i_a1 > 3003) {
  i_a1 = 0;
}
}

Jednak mam spore wątpliwości czy to tak powinno wyglądać. Kod niby kompiluje się prawidłowo oraz poprawnie odczytuje w odstępie 1 sekundy 3 linie onewire od A0 - A2. Ale mam spore wątpliwości czy to powinno wyglądać na zasadzie "kopiuj wklej" wszystkich zmiennych odnoszących się do biblioteki  "DallasTemperature.h" Nie wiem jak to optymalizuje kompilator, aczkolwiek na Arduino nano tylko jednorazowo jest rezerwowana pamięć dla dodanej biblioteki. Kolejne kopie zajmują tylko pamięć o rozszerzenie dodatkowych zmiennych w napisanym kodzie.  Co o tym sądzicie? Można to jakoś uprościć?

Link do komentarza
Share on other sites

Ja bym powiedział że Arduino to DUŻE uproszczenie na start w porównaniu do tradycyjnego programowania (zwłaszcza po rejestrach) dla początkującego...instancje tworzysz w obszarze globalnym przed loop i setup Anię tak jak ty...podajesz trzy adresy do swoich czujników i używasz funkcji obliczenia...obliczenia są robione w tle i gdy już zostaną zakończone to poprzez funkcje available zostajesz o tym poinformowany...nic nie blokuje itp...wueczorem podeślę Ci przykład bo teraz z pamięci to nie dam rady

Link do komentarza
Share on other sites

1 godzinę temu, farmaceuta napisał:

Ja bym powiedział że Arduino to DUŻE

Tzn. masz na myśli Mega2560? czy jeszcze większego? 

1 godzinę temu, farmaceuta napisał:

.instancje tworzysz w obszarze globalnym przed loop i setup Anię tak jak ty...podajesz trzy adresy do swoich czujników i używasz funkcji obliczenia.

No właśnie dla przykładu zrobiłem na początku tak w nano i niestety to nie zadziałało. Wiesz czasem jest tak, że musisz zrobić prosty projekt z niezależnymi liniami pomiarowymi, tak że w przypadku uszkodzenia jednej z linni nie odstawisz pozostałych czujników. Logika 2 z 3 itp. Natomiast co do Arduino nano i podobnych, jeżeli kod który przedstawiłem, jest jedynym prostym rozwiązaniem, to będę się tego trzymać. Opóźnienia zredukowałem do ok. 30ms po przez zanegowanie zerem zmiennej sensors.setWaitForConversion(0) i w zasadzie działa to ok. Natomiast aby było to bardziej wydajne zamiast czasu można wprowadzić w pętli zmianą warunkową która będzie wywoływać określony czujnik w momencie kiedy sterownik będzie pracować w tzw. swobodnej pętli. Tak przynajmniej jest to realizowane w sterownikach PLC. Te starsze pracują na mega8, mega16 i sobie dobrze z tym radzą. Różnicą polega na  tym, że czujnik deklarujesz pod odpowiednią zmienną wejściową, oraz zmienną wyjściową w postaci wartości INT. Niczego nie inicjujesz, bo robi to z automatu kompilator. To co musisz zrobić, to zadeklarować 2 zmienne i już bez względu na to czy to jest drabinka, czy siatka kompilator automatycznie optymalizuje kolejkę, która odczytuje pomiar w dogodnym momencie tak aby zbytnio nie spowalniać programu. Nie wiem jak to jest dokładnie realizowane, ale gdzieś wyczytałem, że takie czujniki mogą zapisywać pomiar w pamięci podręcznej, która może być odczytana w dowolnym momencie, tj. zainicjowanie nowego pomiaru. Nie pamiętam tylko, czy to się tyczyło także DS18B20.

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

#include <OneWire.h>
#include <DS18B20.h>

// Numer pinu do którego podłaczasz czujnik
#define ONEWIRE_PIN 8
                                                                  

byte address1[8] = {0x28, 0xD2, 0xCB, 0x48, 0xF6, 0xDE, 0x3C, 0xDF};    // Adres czujnika 1
byte address2[8] = {0x28, 0xB1, 0x6D, 0xA1, 0x3, 0x0, 0x0, 0x11};       // Adres czujnika 2
byte address3[8] = {0x28, 0xB1, 0x6D, 0xA1, 0x3, 0x0, 0x0, 0x11};       // Adres czujnika 3

OneWire onewire(ONEWIRE_PIN);
DS18B20 sensors(&onewire);



void setup() {
  sensors.begin();
  sensors.request(address1);
  sensors.request(address2);                 //DS18B20
  sensors.request(address3);
}

void loop() {
if (sensors.available())
  {
    float temp1 = sensors.readTemperature(address1);
    float temp2 = sensors.readTemperature(address2);
    float temp3 = sensors.readTemperature(address3);

    Serial.println(temp1);
    Serial.println(temp2);
    Serial.println(temp3);
    
    sensors.request(address1);
    sensors.request(address2);                
    sensors.request(address3);
  }
}

Tu masz kod ktory u mnie dzialal  i bylo wszystko ok...ponizej link do biblioteki (chyba dobrej, teraz nie sprawdze bo mi sie zapodzialy gdzies ds18b20) najwyzej bedziemy poprawiac...a co do DUZEGO uproszczenia mialem na mysli ze progeamowanie w arduino ide jest duzo prostrze niz programowanie po rejestrach wszystkiego od podstaw...to napewno ulatwienie dla poczatkujacego 

https://github.com/nettigo/DS18B20

Link do komentarza
Share on other sites

2 minuty temu, farmaceuta napisał:

Tu masz kod ktory u mnie dzialal  i bylo wszystko ok...ponizej link do biblioteki

Nie no to akurat wiem, że taki kod zadziała, bo są na ten temat artykuły. Nawet tu na Forbocie można znaleźć przykłady podobnej implementacji DSów. 

Osobiście chcę uzyskać trochę inny efekt; 

Trzy niezależne linie pomiarowe. 

// Numer pinu do którego podłaczasz czujnik
#define ONEWIRE_PIN 8 // Czujnik nr 1
#define ONEWIRE_PIN 7 // Czujnik nr 2
#define ONEWIRE_PIN 6 // Czujnik nr 3

Kod który przedstawiłem w poście #2 realizuje takie zadanie, tylko jest trochę zagmatwany, aczkolwiek kompilator fajnie go optymalizuje przed wgraniem do mikrokontrolera. 

Link do komentarza
Share on other sites

Przed chwilą, farmaceuta napisał:

W jakim celu linie sygnałowe muszą być osobne??

Przecież to było wyjaśnione. Przy jednej linii zwarcie przy którymś DS-ie spowoduje, że nic nie będzie czytane. Przy oddzielnych liniach pozostałe pewnie będą.

 

Link do komentarza
Share on other sites

Przed chwilą, ethanak napisał:

Przecież to było wyjaśnione. Przy jednej linii zwarcie przy którymś DS-ie spowoduje, że nic nie będzie czytane. Przy oddzielnych liniach pozostałe pewnie będą.

 

Chyba że tak...no to autor ma przykład powyżej, tylko stworzyć sobie odpowiednią ilość instancji onewire i ds'ow i powinno działać 

Link do komentarza
Share on other sites

Wiesz, może do zastosowań amatorskich wystarczy jedna linia pomiarowa, ale w profesjonalnej automatyce bardzo często wykorzystuje się  niezależne linie pomiarowe. Przykładem jest wspomniana wcześniej logika 2/3. Czyli do jednej obudowy wprowadzasz 3 niezależne czujniki, albo 3 czujniki obok siebie. W przypadku uszkodzenia jednego z czujników, bądź jego linii, algorytm na podstawie różnicy odczytu wyklucza taki pomiar podając średnią z 2 pozostałych sprawnych czujników. Przykładem może być pomiar temperatury kotła w instalacji CO, chociaż tam oprócz cyfrowych czujników można spotkać jeszcze jeden zwykły termistor całkowicie niezależny od mikrokontrolera. 

Link do komentarza
Share on other sites

7 minut temu, ethanak napisał:

Przecież to było wyjaśnione. Przy jednej linii zwarcie przy którymś DS-ie spowoduje, że nic nie będzie czytane. Przy oddzielnych liniach pozostałe pewnie będą.

Oto właśnie chodzi. Dlatego pytałem, czy kod który przedstawiłem w poście #2 można jakoś uprościć.

Link do komentarza
Share on other sites

13 minut temu, rafal220 napisał:

 czy kod który przedstawiłem w poście #2 można jakoś uprościć.

Stwórz trzy instancje one wire i ds18b20 tak jak w moim przykładzie (obszar globalny) i będziesz miał trzy niezależne linie 

Link do komentarza
Share on other sites

1 minutę temu, _LM_ napisał:

W akpia nie widziałem jeszcze czujników 1Wire wszystko idzie na pt100...1000

Albo termopary. Oczywiście mowa o automatyce przemysłowej, aczkolwiek w mniejszych aplikacjach podrzędnych można spotkać cyfrowe czujniki.   

Tutaj na fotce test czujników,

temperatura.thumb.png.576ef400199310e669abd4f144993d64.png

Jak widać kod działa z wypiętym 2 czujnikiem, pomijając trzy pierwsze pomiary po resecie us. 

Link do komentarza
Share on other sites

2 minuty temu, farmaceuta napisał:

Stwórz trzy instancje one wire i ds18b20 tak jak w moim przykładzie (obszar globalny) i będziesz miał trzy niezależne linie 

Tylko że przy próbie wydzielenia którejkolwiek zmiennej biblioteki DallasTemperature do zmiennej globalnej przy jednoczesnym odwołaniu się do któregoś z wejść w pętli głównej, kompilator sypie błędy.  Nie wiem może coś źle robię. Dopiero ogarniam podstawy tego Arduino wolnymi chwilami. Przejście ze sterowników PLC na kod C, to skok na głęboką wodę. 

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.