Ovdje pročitajte kako se registrirati na forum.

PT1000 simulator

Tvoj projekt je upravo dovršen? Podijeli s nama što si napravio u ovom podforumu! Upute drugima kako napraviti isti projekt su uvijek dobrodošle!
Odgovorite
domagoj#5880
Elektroničar
Elektroničar
Postovi: 147
Pridružen/a: ned tra 15, 2018 2:59 pm
Lokacija: Zagreb

PT1000 simulator

Post Postao/la domagoj#5880 » sri tra 15, 2020 4:53 pm

Ovaj projekt sam nazvao PT1000 simulator mada je izvorni kod kojeg ću pokazati dio stvarnog projekta, tj. nije napravljen samo radi simulacije. Ukratko, trebao sam spojiti sondu PT1000 na regulaciju grijanja radi mjerenja vanjske temperature. Budući da sonda mora biti vani, morao bi bušiti zid da provućem žicu, a to znači da bi me žena deportirala. :violin: Osim toga, udaljenost je velika pa bi mi i to stvaralo problem. Pošto je PT1000 sonda koja s temperaturom mijenja otpor, a mjerni opseg je cca od 800 ohma do 1800 ohma, palo mi je na pamet da bi to mogao riješiti s dva digitalna potenciometra (https://e-radionica.com/hr/digitalni-po ... onica.html). Sad vidim da je umirovljen. Baš šteta. Budući da je digitalni potenciometar opsega 10k a meni treba <1k, onda sam mu u paralelu stavio 1k. Dva digitalca spojena u seriju i svaki od njih ima 1k u paraleli, daju upravo opseg koji mi treba. E, ali ima još jedan problem. Digialnom potenciometru se ne može mijenjati I2C adresa, pa sam zato trebao I2C multiplekser (https://e-radionica.com/hr/i2c-multiple ... onica.html). Jako korisna stvarčica.
Shema pokazuje kako su povezani.
slika
Na shemi gdje piše Regin je naziv proizvođača regulacije, a AI1 oznaka analognog ulaza 1. Proizvođač nema veze s ovim, bitno da je ulaz definiran za prihvat PT1000.
Kod koji slijedi radi slijedeće. Na Basic2 je spojen LoRa Grove modul koji prima informaciju o vanjskoj temperaturi s drugog Basic2+LoRa Grove+DS18B20. LoRa modul nije LoRa WAN, već samo LoRa, što znači da ne komunicira preko TheThinksNetwork, već samo koristi LoRa protokol. Stvar je dalje jednostavna. Svakih 20 sec se šalje temperatura i prijemna strana (program u nastavku) podesi vrijednosti digitalnih potenciometara. Ako temperature prestanu dolaziti, svakih sat vremena će se vrijednost spuštati za 1 stupanj. Vanjska temperatura se ipak ne mijenja brzo. Preciznost ovog sklopa je 1 stupanj, a prema Regin regulacija može i 0,1. Razlog je u digitalnom potenciometru. Svega 127 koraka na 10k + 1k u paraleli se ne da bolje namjestiti. Ali za očitanje vanjske temperature sasvim dovoljno.
Evo i koda.

Kod: Označite sve

#include <SoftwareSerial.h>
#include <RH_RF95.h>
#include "Wire.h"
#define TCAADDR 0x70
#define LED_err 9 //indikator greške u komunikaciji

// Singleton instance of the radio driver
SoftwareSerial ss(10, 11);
//polja imaju vrijednosti od -40 do +150 po stupanj
byte A_polje[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,9,9,9,9,9,9,10,10,10,10,10,10,11,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,16,16,17,17,18,18,19,19,20};
byte B_polje[]={42,43,44,45,46,47,48,49,51,52,53,55,56,58,60,61,63,65,67,69,71,73,76,79,81,85,87,91,94,98,101,105,110,115,120,125,75,78,80,83,87,90,93,97,101,107,110,114,119,125,79,82,84,87,90,94,97,101,105,110,115,120,125,83,86,89,92,95,99,103,107,112,117,123,86,89,92,95,99,103,107,111,117,122,127,91,94,98,101,106,111,115,120,126,93,96,100,104,108,113,118,123,94,97,101,105,110,115,120,125,98,102,106,110,115,120,126,101,105,109,114,119,124,102,106,111,116,121,127,106,110,115,120,126,109,113,118,124,109,114,119,124,112,117,123,127,117,122,127,121,127,120,125,120,126,122,127,127};

uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
String poruka,tmp;
unsigned long poruka_broj;
String Addr;
float out_temp=-15,out_max=-50,out_min=200,in_temp=10,in_max=-50,in_min=200,Power,R,R1,R2;
int Regin_temp,lastRegin_temp; //zaokružen na cijeli broj
byte A,B; //vrijednosti digitalnog potenciometra
byte korekcija_plus=2; //korekcija A ili B parametra
int otpornik1=1000, otpornik2=1000;
unsigned int sekunde,timeout=3600; //vremena u sekundama
float sati_rada;
float Wh; //snaga u Wh

RH_RF95 rf95(ss);

int led = 13;


void setup() 
{
    Serial.begin(9600);
    Wire.begin();
    Serial.println("RF95 Temperature Server started.");
    
    pinMode(led, OUTPUT); 
    pinMode(LED_err, OUTPUT); 

    podesiAB(out_temp); lastRegin_temp=out_temp;
    postaviOut_temp(out_temp);
    podesiAB(in_temp);
    postaviIn_temp(in_temp);
    if(!rf95.init())
    {
        Serial.println("init failed");
        while(1)
        {
          digitalWrite(led, HIGH);
          delay(500);
          digitalWrite(led, LOW);
          delay(500);
        }
    } 
    // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
    //rf95.setTxPower(13, false);   
    rf95.setFrequency(868.0);
}

void loop()
{
  if(rf95.available())
  {
    // Should be a message for us now   
    uint8_t len = sizeof(buf);
    if(rf95.recv(buf, &len))
    {
        digitalWrite(led, HIGH);
        
        Serial.print("Primio: ");
        //Serial.println((char*)buf);
        poruka=(char*)buf;
        Serial.println(poruka);
        
        getAddr("A=");
        if(Addr.equals("1"))
        {
          digitalWrite(LED_err,LOW);
          sekunde=0;
          poruka_broj=getMsg("M="); Serial.print("M="); Serial.println(poruka_broj);
          Serial.print("A="); Serial.println(Addr);
          lastRegin_temp=Regin_temp=out_temp=getValue("O="); Serial.print("O="); Serial.print(out_temp); Serial.print("'C Regin="); Serial.print(Regin_temp);
          if(out_temp>out_max) out_max=out_temp;
          if(out_temp<out_min) out_min=out_temp;
          podesiAB(Regin_temp);
          Serial.print(" A/B="); Serial.print(A); Serial.print("/"); Serial.println(B);
          Serial.print("Out max/min="); Serial.print(out_max); Serial.print("/"); Serial.println(out_min);
          postaviOut_temp(Regin_temp);

          Regin_temp=in_temp=getValue("I="); Serial.print("I="); Serial.print(in_temp); Serial.print("'C Regin="); Serial.print(Regin_temp);
          if(in_temp>in_max) in_max=in_temp;
          if(in_temp<in_min) in_min=in_temp;
          podesiAB(Regin_temp);
          Serial.print(" A/B="); Serial.print(A); Serial.print("/"); Serial.println(B);
          //Serial.print(" R="); Serial.print(R);
          Serial.print("In max/min="); Serial.print(in_max); Serial.print("/"); Serial.println(in_min);
          postaviIn_temp(Regin_temp);

          Power=getValue("P="); Serial.print("P="); Serial.print(Power); Serial.println(" %");

          sati_rada=getValue("h="); Serial.print("h="); Serial.print(sati_rada); Serial.println(" h");
          Wh=getValue("W="); Serial.print("Wh="); Serial.print(Wh); Serial.println(" Wh");
          Serial.println("-------------------------------");
        }

        digitalWrite(led, LOW);
    }
    else
    {
        Serial.println("Greska u primanju!");
    }
  }//end if
  if(Pause_1((unsigned long)1000))
  {
    sekunde++;
    if(sekunde>=timeout)
    {
      digitalWrite(LED_err,HIGH);
      sekunde=0;
      lastRegin_temp--;
      if(lastRegin_temp<=-21) lastRegin_temp=-21;
      podesiAB(lastRegin_temp); postaviOut_temp(lastRegin_temp);
    }
  }

}//end loop

unsigned long getMsg(String t)
{
int i,j;
unsigned long br_poruke;
i=poruka.indexOf("M=");
i+=t.length();
j=poruka.indexOf(";",i);
br_poruke=poruka.substring(i,j).toInt();
return br_poruke;
}//end getMsg

void getAddr(String t)
{
int i,j;
i=poruka.indexOf("A=");
i+=t.length();
j=poruka.indexOf(";",i);
Addr=poruka.substring(i,j);
}//end getAddr

float getValue(String t)
{
int i,j;
float vrijednost;
String tmp;
i=poruka.indexOf(t);
i+=t.length();
j=poruka.indexOf(";",i);
vrijednost=poruka.substring(i,j).toFloat();
return vrijednost;
}//end getValue

void podesiAB(int temp)
{
int AB_i; //index AB polja
AB_i=temp+40;
A=A_polje[AB_i]; B=B_polje[AB_i];
if(B<=(127-korekcija_plus))
{
  if(temp>=0)
    B+=korekcija_plus; //korekcija B
}
R1=A*78.125*otpornik1/(A*78.125+otpornik1); R2=B*78.125*otpornik2/(B*78.125+otpornik2); R=R1+R2;
} //podesiAB

void postaviOut_temp(int temp)
{
Serial.print("Postavljam Out temp="); Serial.print(temp); Serial.print("'C");
Serial.print(" A/B="); Serial.print(A); Serial.print("/"); Serial.print(B);
//Serial.print(" R="); Serial.print(R);
Serial.println();

TCAselect(6);
Wire.beginTransmission(47); // emitira na uređaj #47 (0101111), fiksno za dig. pot.
Wire.write(byte(0x00)); // šalje instrukcijski byte za pisanje
Wire.write(A); // šalje vrijednost 1. potenciometra (byte)
Wire.endTransmission(); // pretanak emitiranja

TCAselect(5);
Wire.beginTransmission(47); // emitira na uređaj #47 (0101111), fiksno za dig. pot.
Wire.write(byte(0x00)); // šalje instrukcijski byte za pisanje
Wire.write(B); // šalje vrijednost 2. potenciometra (byte)
Wire.endTransmission(); // pretanak emitiranja

}//postaviOut_temp

void postaviIn_temp(int temp)
{
Serial.print("Postavljam In temp="); Serial.print(temp); Serial.print("'C");
Serial.print(" A/B="); Serial.print(A); Serial.print("/"); Serial.print(B);
//Serial.print(" R="); Serial.print(R);
Serial.println();
}//postaviIn_temp

bool Pause_1(unsigned long pause) //pause=vrijeme u ms
{
  static bool start; //start=true -> timer je pokrenut
  static unsigned long Start_Time; //vrijeme pokretanja
  unsigned long Current_Time=millis();
  //Serial.println(Current_Time);
  if(pause==0) { start=false; return false; } //ako je vrijeme 0 zaustavlja timer
  if(start!=true) //ako mjerenje nije pokrenuto, pokreni ga
  {
    start=true;
    Start_Time=Current_Time; //očitaj vrijeme pokretanja, može biti i micros()
    return false;
  }
  if(start==true) //ako je mjerenje pokrenuto
  {
    if((Current_Time-Start_Time)>=pause) //ako je prošlo zadano vrijeme zaustavi timer
    {
      start=false; //zaustavlja timer
      return true; //vrijeme je isteklo
    }
    else
      return false; //vrijeme još nije isteklo
  }
}//end Pause_1

void TCAselect(uint8_t i)
{
  if (i > 7) return;
 
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();  
}//end TCAselect
Neću ići u detalje samog programa, ima tu svega. Bit ovog posta je trebao biti na digitalnim potenciometrima i I2C multiplekseru. Jedan digitalac se lako namjesti, ali ja sam imao problem a s dva u seriji. Taj problem sam opisao u ovom postu viewtopic.php?f=14&t=215 pa se sad ne bi vraćao na njega. Meni se ova stvar pokazala korisnom, možda još nekom pomogne. Najbolje od svega je što sva ova oprema radi već više od mjesec dana, 24h/dan i nema greške.
Pozdrav, Domagoj
Avatar
david.zovko#7462
e-radionica.com team
e-radionica.com team
Postovi: 323
Pridružen/a: ned tra 15, 2018 2:59 pm
Lokacija: Osijek, Croatia
Kontakt:

Re: PT1000 simulator

Post Postao/la david.zovko#7462 » pon tra 20, 2020 9:20 am

Jako lijepo! super mi je vidjeti par naših proizvoda iskorištenih u projektu! Super je kad i ti i žena možete biti zadovoljni :shifty:

Kako ti radi ta LoRa? Što imaš za antenu? Na koliko m uspijevaš imati komunikaciju?

btw. digitalni potenciometar se vraća uskoro u novoj verziji!
domagoj#5880
Elektroničar
Elektroničar
Postovi: 147
Pridružen/a: ned tra 15, 2018 2:59 pm
Lokacija: Zagreb

Re: PT1000 simulator

Post Postao/la domagoj#5880 » pon tra 20, 2020 11:37 am

David, bok!
He, he, očito sam fan e-r.io. Neki dan mi je za oko palo samo koliko kutija imam s logom e-radionice. Ako ti ponestane kutija za isporuku, samo se javi. 8-)
LoRa radi super. Evo slike na kojoj se vidi i antena. Mislim da manja od toga ne može biti.
slika
Što se tiče udaljenosti, napravio sam nekoliko testova i to s tom žicom od antene.
Jedan modul je bio u stanu (2. kat) a s drugim modulom sam se spuštao u garažu. Signal sam izgubio na -2 etaži što znači da je između modula bilo 4 armirano betonske deke.
Drugi test je bio da je modul i dalje u stanu a ja šećem oko zgrade u sve većim krugovima. Čim sam zašao u sjenu neke druge zgrade, ništa od signala. Većina zgrada je od armiranog betona tako da me to ne čudi. Kod kolike tolike optičke vidljivosti (drveće, kuće jednokatnice) signal sam primao do cca 300m. Kad kažem da sam primao signal znači da sam ga primao pez prekida. Nakon 300m sam i dalje primao ali s povremenim gubitkom paketa.
Treći test je bio kod punice. Jedan modul je bio u kući od cigle, a s drugim sam otišao na livadu. Kako je bila vrlo visoka trava, cca preko 1,5m, teško sam se kretao po noj pa sam nakon 500m odustao a signal sam primao i dalje. Po specifikaciji bi u takvim uvjetima trebao imati barem 2km, a to ću provjeriti jednom prilikom. Za taj modul imam i 21cm antenu ali jednostavno nisam došao u priliku da je provjerim jer i s ovom malom integriranom antenom radi super. Npr. unutar stana nema baš nikakvog problema, što se ne bi moglo reći za 2,4GHz modul. S 2,4GHz već sam imao problem i preko zida ako je na tom zidu bio ormar. Pojačavao sam signal programski ali badava. Kod LoRe tog problema nema.
Još da ukratko opišem kako sam provodio test. Modul koji je bio kod mene, s kojim bi se šetao naokolo, imao je LCD i svakih 10s bi slao tekstualnu poruku na modul koji je bio u stanu/kući. Poruka je sadržavala broj koji bi se uvećavao sa svakim slanjem, a modul u kući, čim bi primio poruku, vratio bi je nazad. Na LCD bi imao broj poruke koja je zadnja poslana i koja je zadnja primljena i tako bi znao. Gledajući LoRa specifikaciju, domet pada s učestalim slanjem, tako da kada bi produljio vrijeme s 10s na barem 2min ili više, možda bi i ove moje udaljenosti bile veće. I to najeravam probati, a 10s mi se činio kao dobar početak, tek toliko da steknem osjećaj i dobijem neke konkretne vrijednosti koje kasnije mogu uspoređivati.
domagoj#5880
Elektroničar
Elektroničar
Postovi: 147
Pridružen/a: ned tra 15, 2018 2:59 pm
Lokacija: Zagreb

Re: PT1000 simulator

Post Postao/la domagoj#5880 » pon tra 20, 2020 11:50 am

Kažeš nova verzija digitalca. Postoji li šansa da bude i 1k model?
Odgovorite