Kilka DS18b20 na jednym pinie.

User avatar
Piotr61
Posts: 55
Joined: Fri Sep 15, 2017 12:59 pm

Wed Sep 20, 2017 8:19 pm

Witam wszystkich.

Za pomocą arduino IDE, napisałem sobie programik do obsługi kilku DS-ow na jednym pinie i ładuję go do NodeMCU.
Pomimo dodania czterech kolejnych kanałów typu

Code: Select all

SuplaDevice.addDS18B20Thermometer();
SuplaDevice.addDS18B20Thermometer();
SuplaDevice.addDS18B20Thermometer();
SuplaDevice.addDS18B20Thermometer();
i po przekazaniu do callback

Code: Select all

SuplaDevice.setTemperatureCallback(&get_temperature);
poniższej funkcji

Code: Select all

 double get_temperature(int channelNumber, double last_val) {

    double t = -275;
    if(channelNumber==0 ){
        sensors.requestTemperatures();
     }    
     
     t = sensors.getTempCByIndex(channelNumber);
    return t;  
}
na aplikacji w androidzie i w chmurze SUPLA widoczne są 4 kanały ale temperaturę widać na dwóch pierwszych kanałach (0 i 1), w pozostałych dwóch kreski, czyli brak odczytu.
Czy to jest może jakieś ograniczenie w SUPLA :?:

Pozdrawiam
Piotr

PS
Dodam, że kombinowałem na 100 :mrgreen: różnych sposobów i wynik jest zawsze ten sam, czyli wskazania widać tylko w 2 pierwszych kanałach.
Last edited by Piotr61 on Tue Sep 25, 2018 8:04 am, edited 1 time in total.
"Dopóki nie skorzystałem z Internetu, nie wiedziałem, że na świecie jest tylu idiotów" - Stanisław Lem
User avatar
shimano73
Posts: 889
Joined: Sun Feb 28, 2016 12:27 pm
Location: Orzesze

Wed Sep 20, 2017 10:58 pm

Musisz czytać kanały osobno , tu ma odczyt z dwóch dla czterech będzie analogicznie

Code: Select all

double get_temperature(int channelNumber, double last_val) {

    double t = -275;
    
    if ( sensors.getDeviceCount() > 0 )
      {
         sensors.requestTemperatures();
         switch(channelNumber)
          {
            case 0:
                   
                    t = sensors.getTempCByIndex(0);
                    break;
            case 1:
                    t = sensors.getTempCByIndex(1);
                    break;
           };       
         
      };
W elektronice jak nie wiadomo o co chodzi to zwykle chodzi o zasilanie
User avatar
Piotr61
Posts: 55
Joined: Fri Sep 15, 2017 12:59 pm

Tue Oct 03, 2017 8:39 am

shimano73 wrote:
Wed Sep 20, 2017 10:58 pm
Musisz czytać kanały osobno , tu ma odczyt z dwóch dla czterech będzie analogicznie ...
Dzięki ale to nie to :?
Efekt użycia Twojej funkcji z trzema kanałami wygląda tak:

Code: Select all

SuplaDevice initialized
Not connected
Register in progress
Registered and ready.

Soft WDT reset

ctx: cont 
sp: 3fff01d0 end: 3fff0460 offset: 01b0

>>>stack>>>
3fff0380:  00000000 00000001 00000100 4020382d  
....
3fff0450:  feefeffe feefeffe 3ffef440 40100718  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,7)

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v3ffe8b28
~ld
Podejrzewam, że za długo "siedzi" w funkcji/metodzie iterate.
Poza tym, nie widzę potrzeby by dla każdego kanału sprawdzać za każdym razem ilości termometrów na magistrali 1w i nakazywać im konwersji temperatury, która dla 12-bitowej rozdzielczości, trwa jak wiadomo ~750ms - marnotrawstwo :lol:

Zmieniłem trochę funkcję get_temperature i nadal to samo :(

Code: Select all

 #define SIMPLE_DEBUG
 // DS18B20 Sensor read implementation
 double get_temperature(int channelNumber, double last_val) {
 
     double t = -275;
      
     t = ds_devs.getTempCByIndex(channelNumber);
     if( channelNumber==devices-1 ) ds_devs.requestTemperatures(); //conversion start - no wait
 
 #ifdef SIMPLE_DEBUG 
     Serial.println(channelNumber);
     Serial.println(t);
 #endif    
     
     return t;  
 }
Dodam, że próbowałem już zwracać temperaturę pobierając informacje ze zmiennych, tablic i czort jeszcze wie co i nadal efekt ten sam :(
Skończyły mi się pomysły.

Piotr

PS
Ilość sensorów na magistrali, sprawdzam tylko raz w startupie.
W terminalu widać, że zwracana temperatura dla każdego kanału jest OK, a w aplikacji czy chmurze kicha czyli 2 pierwsze.
"Dopóki nie skorzystałem z Internetu, nie wiedziałem, że na świecie jest tylu idiotów" - Stanisław Lem
User avatar
shimano73
Posts: 889
Joined: Sun Feb 28, 2016 12:27 pm
Location: Orzesze

Tue Oct 03, 2017 9:23 am

To co zaproponowałem , pochodzi od Przemka dostałem to gdy robiłem soft na arduino mega 2560. Ja od niedawna zajmuje sie arduino i moja wiecha jest ograniczona bardzo 😉
W elektronice jak nie wiadomo o co chodzi to zwykle chodzi o zasilanie
gollum
Posts: 2
Joined: Mon Dec 18, 2017 9:55 pm

Mon Dec 18, 2017 10:01 pm

To ja się podłącze do pytania/problemu.
Próbuję do jednego ESP12E podłączyć większą liczbę czujników DHT22 (chcę skorzystać z sieci kabli jakie już mam w domu i nie stawiać w każdym pomieszczeniu osobnego ESP).
Podłączenie jednego DHT22 bez większego problemu. Podłączenie dwóch już trudniej, ale poszedłem tym tropem co propozycja w tym wątku [switch(channelNumber) i case wewnątrz "void get_temperature_and_humidity".
Dla większej liczby niż 2 sztuki jest problem. Dane wyświetlają się dla kanału 0 i 1, a dla następnego -1 na temperaturze i -- na wilgotności.
Próbowałem zamian kolejności, zmian PINów itp. i nic nie pomogło.

Jest jakieś ograniczenie software'owe w bibliotece? Czemu? :)

Pozdrawiam,
gollum
gollum
Posts: 2
Joined: Mon Dec 18, 2017 9:55 pm

Mon Dec 18, 2017 10:11 pm

Miałem jeszcze pomysł (zanim znalazłem sposób opisany w tym wątku), żeby zrobić jakaś oszukiwaną pętle i żeby jedno ESP przedstawiało się kolejnym GUIDami i odczytywało temperaturę z kolejnych czujników, ale jestem za słaby programistycznie ;]
tijo
Posts: 104
Joined: Fri Dec 01, 2017 12:44 pm

Thu Jan 11, 2018 9:57 am

Code: Select all

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

// tutaj musimy ustawić adres ip esp8266 oraz wprowadzić inne dane naszej sieci
// po tym zabiegu będziemy mieć na stałe przypisany adres ip w module ESP8266
// USTAWIENIA PONIŻEJ TO USTAWIENIA MOJEJ SIECI 

IPAddress ip(192, 168, 8, 151);
IPAddress gateway(192, 168, 8, 1);
IPAddress subnet(255, 255, 255, 0);

const char* ssid = ".................";// tutaj wprowadzamy nazwę naszej sieci WiFI
const char* password = "................."; tutaj hasło sieci

void wifi_init(){
WiFi.config(ip, gateway, subnet);
delay(100);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println();
Serial.print("Connecting");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(200);
}
Serial.println();
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Fail connecting");
delay(5000);
ESP.restart();
}
Serial.print(" OK ");
Serial.print("Module IP: ");
Serial.println(WiFi.localIP());
}

#define ONE_WIRE_BUS 0
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

// W ten sposób przypisujemy adresy czujników wcześniej odczytane,niestety tak to narazie trzeba wykonać
// 
DeviceAddress t1 = { 0x28, 0x39, 0xbf, 0x22, 0x06, 0x00, 0x00, 0xe3 }; // - adres DS18B20 - 1
DeviceAddress t2 = { 0x28, 0xff, 0xbe, 0x6b, 0x62, 0x17, 0x04, 0xa8 }; // - adres DS18B20 - 2
DeviceAddress t3 = { 0x28, 0xff, 0xc5, 0x67, 0x62, 0x17, 0x04, 0xa7 }; // - adres DS18B20 - 3
DeviceAddress t4 = { 0x28, 0xff, 0x0d, 0x62, 0x62, 0x17, 0x04, 0x3a }; // - adres DS18B20 - 4

WiFiUDP Udp;
unsigned int localUdpPort = 12346; // local port to listen on
char incomingPacket[255]; // buffer for incoming packets
char replyPacekt[] = "Dokonano pomiaru temperatur :-)"; // a reply string to send back


void setup()

{
Serial.begin(115200);
Serial.println();
wifi_init();
{
delay(500);
Serial.print(".");
}
Serial.println(" connected");

Udp.begin(localUdpPort);
Serial.printf("Now listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);
}


void loop()
{
int packetSize = Udp.parsePacket();
if (packetSize)
{
// receive incoming UDP packets

sensors.requestTemperatures();
Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
int len = Udp.read(incomingPacket, 255);
if (len > 0)
{
incomingPacket[len] = 0;
sensors.requestTemperatures();
delay(750);
}
Serial.printf("UDP packet contents: %s\n", incomingPacket);

float temp1;
temp1 = sensors.getTempC(t1);
String Pomiar1;
Pomiar1=String(temp1, 1);
Serial.println(Pomiar1);

//float temp2;
temp1 = sensors.getTempC(t2);
String Pomiar2;
Pomiar2=String(temp1, 1);
Serial.println(Pomiar2);

//float temp3;
temp1 = sensors.getTempC(t3);
String Pomiar3;
Pomiar3=String(temp1, 1);
Serial.println(Pomiar3);

//float temp4;
temp1 = sensors.getTempC(t4);
String Pomiar4;
Pomiar4=String(temp1, 1);
Serial.println(Pomiar4);

Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());


String tempp1 ;

tempp1 += "n1=";
tempp1 += Pomiar1;
tempp1 += "x";
tempp1 += "n2=";
tempp1 += Pomiar2;
tempp1 += "x";
tempp1 += "n3=";
tempp1 += Pomiar3;
tempp1 += "x";
tempp1 += "n4=";
tempp1 += Pomiar4;
tempp1 += "x";

Udp.println(tempp1); 

Udp.endPacket();
}
}
Taki kod na innym forum znalazłem do obsługi kilku czujników na jednym pinie....może to pomoże...autor wyraził zgodę na publikacje...

A tak można odczytać adresy czujników

Code: Select all

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>


//------------------------------------------
//DS18B20
#define ONE_WIRE_BUS 0 //Pin to which is attached a temperature sensor
#define ONE_WIRE_MAX_DEV 15 //The maximum number of devices

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
int numberOfDevices; //Number of temperature devices found
DeviceAddress devAddr[ONE_WIRE_MAX_DEV]; //An array device temperature sensors
float tempDev[ONE_WIRE_MAX_DEV]; //Saving the last measurement of temperature
float tempDevLast[ONE_WIRE_MAX_DEV]; //Previous temperature measurement
long lastTemp; //The last measurement
const int durationTemp = 5000; //The frequency of temperature measurement

//------------------------------------------
//WIFI
const char* ssid = "............"; // nazwa sieci WIFI
const char* password = "................"; //HASŁO

//------------------------------------------
//HTTP
ESP8266WebServer server(80);

//------------------------------------------
//Convert device id to String
String GetAddressToString(DeviceAddress deviceAddress){
String str = "";
for (uint8_t i = 0; i < 8; i++){
if( deviceAddress[i] < 16 ) str += String(0, HEX);
str += String(deviceAddress[i], HEX);
}
return str;
}

//Setting the temperature sensor
void SetupDS18B20(){
DS18B20.begin();

Serial.print("Parasite power is: "); 
if( DS18B20.isParasitePowerMode() ){ 
Serial.println("ON");
}else{
Serial.println("OFF");
}

numberOfDevices = DS18B20.getDeviceCount();
Serial.print( "Device count: " );
Serial.println( numberOfDevices );

lastTemp = millis();
DS18B20.requestTemperatures();

// Loop through each device, print out address
for(int i=0;i<numberOfDevices; i++){
// Search the wire for address
if( DS18B20.getAddress(devAddr[i], i) ){
//devAddr[i] = tempDeviceAddress;
Serial.print("Found device ");
Serial.print(i, DEC);
Serial.print(" with address: " + GetAddressToString(devAddr[i]));
Serial.println();
}else{
Serial.print("Found ghost device at ");
Serial.print(i, DEC);
Serial.print(" but could not detect address. Check power and cabling");
}

//Get resolution of DS18b20
Serial.print("Resolution: ");
Serial.print(DS18B20.getResolution( devAddr[i] ));
Serial.println();

//Read temperature from DS18b20
float tempC = DS18B20.getTempC( devAddr[i] );
Serial.print("Temp C: ");
Serial.println(tempC);
}
}

//Loop measuring the temperature
void TempLoop(long now){
if( now - lastTemp > durationTemp ){ //Take a measurement at a fixed time (durationTemp = 5000ms, 5s)
for(int i=0; i<numberOfDevices; i++){
float tempC = DS18B20.getTempC( devAddr[i] ); //Measuring temperature in Celsius
tempDev[i] = tempC; //Save the measured value to the array
}
DS18B20.setWaitForConversion(false); //No waiting for measurement
DS18B20.requestTemperatures(); //Initiate the temperature measurement
lastTemp = millis(); //Remember the last time measurement
}
}

//------------------------------------------
void HandleRoot(){
String message = "Number of devices: ";
message += numberOfDevices;
message += "\r\n<br>";
char temperatureString[6];

message += "<table border='1'>\r\n";
message += "<tr><td>ID czujnika id</td><td>Temperatura</td></tr>\r\n";
for(int i=0;i<numberOfDevices;i++){
dtostrf(tempDev[i], 2, 2, temperatureString);
Serial.print( "Sending temperature: " );
Serial.println( temperatureString );

message += "<tr><td>";
message += GetAddressToString( devAddr[i] );
message += "</td>\r\n";
message += "<td>";
message += temperatureString;
message += "</td></tr>\r\n";
message += "\r\n";
}
message += "</table>\r\n";

server.send(200, "text/html", message );
}

void HandleNotFound(){
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET)?"GET":"POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i=0; i<server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/html", message);
}


//------------------------------------------
void setup() {
//Setup Serial port speed
Serial.begin(115200);

//Setup WIFI
WiFi.begin(ssid, password);
Serial.println("");

//Wait for WIFI connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());

server.on("/", HandleRoot);
server.onNotFound( HandleNotFound );
server.begin();
Serial.println("HTTP server started at ip " + WiFi.localIP().toString() );

//Setup DS18b20 temperature sensor
SetupDS18B20();

}

void loop() {
long t = millis();

server.handleClient();
TempLoop( t );
} 
SpeedBit
Posts: 8
Joined: Wed Aug 29, 2018 8:56 pm

Thu Jan 10, 2019 10:18 pm

Cześć
Zrób tak:
- odszukaj w bibliotece plik srcp.c
- otwórz w edytorze
- znajdź na początku pliku:
#define SRPC_QUEUE_SIZE 2
#define SRPC_QUEUE_MIN_ALLOC_COUNT 2
- zmień cyferki 2 na większe :-)

O soooo chodzi....
Podczas zmian temperatury generowane są dane do chmury. Każda zmiana stanu czujnika, wartości temperatury itp. powoduje zawołanie procedury wstawiającej dane do bufora który opróżniany jest podczas wysyłania.
Jeśli mamy dużo termometrów i zmiany temperatury są częste (np. trzymamy palcami) to nie jest dziwne, że prób wysyłki danych na serwer będzie sporo. A bufor ma miejsce tylko na dwie ramki....(!)
Dlatego dwie pierwsze zmiany (niekoniecznie pierwsze indeksy kanału) wejdą do bufora bez problemu.
Następne już nie, bo nie ma miejsca - poprzednie nie zostały jeszcze wysłane...
Tak więc zwiększ rozmiar kolejki i ciesz się bardzo ładnym działaniem SUPLI-DEV .

P.S. Dla urządzeń Supla-dev do których nawpychamy dużo różnych kanałów też bym radził zwiększyć kolejkę, bo można w ten sposób utracić ważne informacje np. o otwarciu drzwi lub okna gdy nie będzie miejsca w buforze, bo np. zimą termometry oświetliło słońce i mamy sporo zmian temperatury do wysłania.
Jak mawiają programiści: It's by design ;-)
User avatar
wojtas567
Posts: 1763
Joined: Sun Apr 03, 2016 7:16 pm
Location: Olsztyn

Fri Jan 11, 2019 8:02 am

Zerknij tu: viewtopic.php?f=11&t=3955#p27807
A tu dla kolegi dla kilku DHT viewtopic.php?f=11&t=4060#p29519
Pozdrawiam
Wojtek
PioKar
Posts: 230
Joined: Thu May 03, 2018 5:56 am

Sat Jan 12, 2019 8:00 pm

#define SRPC_QUEUE_SIZE 2
#define SRPC_QUEUE_MIN_ALLOC_COUNT 2
- zmień cyferki 2 na większe :-)
Tylko Na jakie 4, 8, ?

Szkoda że tematu nikt nie pociągnął.
Może ktoś z "Olimpu" się wypowie.
Czy to jest warte przeprogramowania moich płytek?
Ja bardzo nie chciałbym dostać info z serwisu że zawaliłem bazę bo sobie coś zacząłem generować...
Wolę najpierw się upewnić.
Post Reply