Hubert_M

Untitled

Jun 2nd, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.74 KB | None | 0 0
  1. #include "MUX74HC4067.h"
  2. #include <Wire.h>
  3. #include <CmdMessenger.h>
  4.  
  5.  
  6. #define WYP 0.63 // współczynnik wypływu
  7. #define G 9.81 // przyśpieszenie ziemskie
  8. #define TM 6 // time multipler
  9. #define QM 11 // maksymalna wartość potencjometrów 1-6
  10. #define X1 0.6 // poziom 1 czujnika wody
  11. #define X2 1.3 // poziom 2 czujnika wody
  12. #define X3 1.9 // poziom 3 czujnika wody
  13. #define XT 90  // poziom czujki temperatury
  14.  
  15. byte x[14] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
  16. byte y[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
  17.  
  18. CmdMessenger cmdMessenger = CmdMessenger(Serial);
  19.  
  20. enum
  21. {
  22.   kAcknowledge,
  23.   kError,
  24.   kReceive,
  25.   kSend,
  26. };
  27.  
  28. class Tank {
  29.   public:
  30.     int x1 = 0, x2 = 0, x3 = 0, xT = 0; // czujki poziomu wody i temperatury
  31.     double hT = 2; // wysokość zbiornika
  32.     double r = 0.5; // promień podstawy
  33.     double sT = PI * r * r; // pole podstawy
  34.     double vT = sT * hT; // objętość maksymalna
  35.     double hW = 0.0; // obecna wysokość wody
  36.     double vW = 0; // obecna objętość wody
  37.     double tWp = 20; // temperatura wody poprzednia
  38.     double tWn = 20; // temperatura wody następna
  39.     int m = 0; // mieszadło
  40.     int overflowed = 0; // alarm przelania
  41.     void check() {
  42.       if (hW >= hT) {
  43.         hW = 2; overflowed = 1;
  44.       }
  45.       else overflowed = 0;
  46.       if (hW >= X1) x1 = 1;
  47.       else x1 = 0;
  48.       if (hW >= X2) x2 = 1;
  49.       else x2 = 0;
  50.       if (hW >= X3) x3 = 1;
  51.       else x3 = 0;
  52.       if (tWp >= XT) xT = 1;
  53.       else xT = 0;
  54.       vW = sT * hW;
  55.     }
  56. };
  57. class Valve {
  58.   public:
  59.     int status = 0; // zamknięty/otwarty
  60.     double r = 0.03; // promień zaworu
  61.     double sV = PI * r * r; // powierzch max otworu
  62.     double rSV = sV; // obecna powierzchnia otowru
  63.     void qV(double x) {
  64.       if (x != QM) rSV = sV / x;
  65.       else rSV = 0;
  66.     }
  67. };
  68. class Heater {
  69.   public:
  70.     int status = 0; // grzeje/nie grzeje
  71.     int overheat = 0; // alarm przegrzania
  72.     int p = 100; // moc grzałki w kW
  73.     int oh = 0; // zmienna pomocnicza, timer przegrzania
  74.     double alfa1 = 2.8; // współczynnik pierwszy do obliczeń temp
  75.     double alfa2 = -0.8; // współczynnik drugi do obliczeń temp
  76.     double alfa3 = 0.04; // współczynnik trzeci do obliczeń temp
  77.     double tHp = 20; // temperatura grzałki poprzednia
  78.     double tHn = 20; // temperatura grzałki obecna
  79.     void check() {
  80.       oh++;
  81.       if (oh > 50) {
  82.         overheat = 1;
  83.         oh = 0;
  84.       }
  85.     }
  86.     void dH(double x) {
  87.       alfa2 = -x;
  88.     }
  89. };
  90. void heat(Tank& t, Heater& h) {
  91.   h.tHn = h.tHp + 0.1 * (h.p - h.alfa1 * (h.tHp - t.tWp));
  92.   if (t.vW > 0)
  93.     t.tWn =
  94.       t.tWp +
  95.       0.1 * (h.alfa2 * 1 / t.vW * (t.tWp - h.tHp) + h.alfa3 * (t.tWp - 20));
  96.   else {
  97.     t.check();
  98.     t.tWn = 20;
  99.   }
  100.   if (t.tWn > 100) t.tWn = 100;
  101.   t.tWp = t.tWn;
  102.   h.tHp = h.tHn;
  103. }
  104. void cool(Tank& t, Heater& h) {
  105.   h.oh = 0;
  106.   t.tWn = 20 + (t.tWp - 20) * exp(-0.017 * 1 / t.vW);
  107.   t.tWp = t.tWn;
  108.   h.tHp = t.tWn;
  109. }
  110. void mixTemp(Tank& tP, Tank& tS, double d) {
  111.   if (d > 0)
  112.     tP.tWp = (tP.vW * 997 * tP.tWp + d * tS.sT * 997 * tS.tWp) /
  113.              (tP.vW * 997 + d * tS.sT * 997);
  114. }
  115. double bind(Tank t, Valve v, int s, double h = 1000) {
  116.   double d, q;
  117.   if (v.rSV == 0) return 0;
  118.   if (h == 1000) q = WYP * v.rSV * sqrt(2 * G * (h / 1000));
  119.   else q = WYP * v.rSV * sqrt(2 * G * h);
  120.   d = TM * q / t.sT;
  121.   if (h < 1000)
  122.     if (d >= h) d = h;
  123.   if (d >= h) d = h;
  124.   if (s == -1) return -d;
  125.   return d;
  126. }
  127. void muxRead() {
  128.   /*
  129.   for (int i = 0; i < 10; ++i) {
  130.     if (i < 6) data[i] = mux.read(i) * 10 / 1023 + 1;
  131.     else {    
  132.       data[i] = mux.read(i);
  133.       data[i] = (data[i] * 75 / 1023 + 5);
  134.       data[i] = map(data[i], 5, 80, 80, 5);
  135.       data[i] = data[i] / 100;
  136.     }
  137.   }
  138.   */
  139. }
  140. MUX74HC4067 mux(7, 8, 9, 10, 11);
  141. unsigned long currentTime = 0, previousTime = 0, deltaTime = 0; // if co 100ms
  142. double data[10];  // zmienna do przechowywania danych z potencjometrów
  143. double d1 = 0, d2 = 0, d3 = 0, d4 = 0;  // przepływ wody
  144. Heater h1, h2, h3, h4;  // grzałki
  145. Tank t1, t2, t3, t4;  // zbiorniki
  146. Valve v1, v2, v3, v4, v5, v6;  // zawory
  147. void setup() {
  148.   Serial.begin(9600);
  149.   mux.signalPin(A0, INPUT, ANALOG);
  150.   cmdMessenger.attach(OnUnknownCommand);
  151.   cmdMessenger.attach(kSend, OnReceive);
  152. }
  153. void loop() {
  154.  
  155.   Wire.requestFrom(8, 14);
  156.   while (Wire.available()) {
  157.     for (int i = 0; i < sizeof(x); i++) {
  158.       x[i] = Wire.read();
  159.     }
  160.   }
  161.  
  162.   (x[0] == 1) ? v1.status = 1 : v1.status = 0;
  163.   (x[1] == 1) ? v2.status = 1 : v2.status = 0;
  164.   (x[2] == 1) ? v3.status = 1 : v3.status = 0;
  165.   (x[3] == 1) ? v4.status = 1 : v4.status = 0;
  166.   (x[4] == 1) ? v5.status = 1 : v5.status = 0;
  167.   (x[5] == 1) ? v6.status = 1 : v6.status = 0;
  168.   (x[6] == 1) ? h1.status = 1 : h1.status = 0;
  169.   (x[7] == 1) ? h2.status = 1 : h2.status = 0;
  170.   (x[8] == 1) ? h3.status = 1 : h3.status = 0;
  171.   (x[9] == 1) ? h4.status = 1 : h4.status = 0;
  172.   (x[10] == 1) ? t1.m = 1 : t1.m = 0;
  173.   (x[11] == 1) ? t2.m = 1 : t2.m = 0;
  174.   (x[12] == 1) ? t3.m = 1 : t3.m = 0;
  175.   (x[13] == 1) ? t4.m = 1 : t4.m = 0;
  176.  
  177.   currentTime = millis();
  178.   if (currentTime - previousTime >= 100UL) {
  179.     muxRead();
  180.     v1.qV(data[0]);
  181.     v2.qV(data[1]);
  182.     v3.qV(data[2]);
  183.     v4.qV(data[3]);
  184.     v5.qV(data[4]);
  185.     v6.qV(data[5]);
  186.     h1.dH(data[6]);
  187.     h2.dH(data[7]);
  188.     h3.dH(data[8]);
  189.     h4.dH(data[9]);
  190.     if (v1.status == 1) d1 += bind(t1, v1, 1);
  191.     if (v2.status == 1) d1 += bind(t1, v2, -1, t1.hW);
  192.     if (v2.status == 1) d2 += bind(t2, v2, 1, t1.hW);
  193.     if (h2.status == 1) mixTemp(t2, t1, d2);
  194.     t1.hW += d1; d1 = 0;
  195.     if (v3.status == 1) d1 += bind(t1, v3, -1, t1.hW);
  196.     if (v4.status == 1) d2 += bind(t2, v4, -1, t2.hW);
  197.     if (v3.status == 1) d3 += bind(t3, v3, 1, t1.hW);
  198.     if (h3.status == 1) mixTemp(t3, t1, d3);
  199.     if (v5.status == 1) d3 += bind(t3, v5, -1, t3.hW);
  200.     if (v4.status == 1) d4 += bind(t4, v4, 1, t2.hW);
  201.     if (h4.status == 1) mixTemp(t4, t2, d4);
  202.     t4.hW += d4; d4 = 0;
  203.     if (v5.status == 1) d4 += bind(t4, v5, 1, t3.hW);
  204.     if (h4.status == 1) mixTemp(t4, t3, d4);
  205.     if (v6.status == 1) d4 += bind(t4, v6, -1, t4.hW);
  206.     t1.hW += d1; t2.hW += d2; t3.hW += d3; t4.hW += d4;
  207.     t1.check(); t2.check(); t3.check(); t4.check();
  208.     if (h1.status == 1) heat(t1, h1);
  209.     else cool(t1, h1);
  210.     if (h2.status == 1) heat(t2, h2);
  211.     else cool(t2, h2);
  212.     if (h3.status == 1) heat(t3, h3);
  213.     else cool(t3, h3);
  214.     if (h4.status == 1) heat(t4, h4);
  215.     else cool(t4, h4);
  216.     d1 = 0; d2 = 0; d3 = 0; d4 = 0;
  217.     previousTime = currentTime;
  218.   }
  219.   Wire.beginTransmission(8);
  220.   y[0] = t1.x1;
  221.   y[1] = t1.x2;
  222.   y[2] = t1.x3;
  223.  
  224.   y[3] = t2.x1;
  225.   y[4] = t2.x2;
  226.   y[5] = t2.x3;
  227.  
  228.   y[6] = t3.x1;
  229.   y[7] = t3.x2;
  230.   y[8] = t3.x3;
  231.  
  232.   y[9] = t4.x1;
  233.   y[10] = t4.x2;
  234.   y[11] = t4.x3;
  235.  
  236.   y[12] = t1.xT;
  237.   y[13] = t2.xT;
  238.   y[14] = t3.xT;
  239.   y[15] = t4.xT;
  240.  
  241.   Wire.write(y,16);
  242.   Wire.endTransmission();
  243.  
  244.   cmdMessenger.feedinSerialData();
  245.   OnSend();
  246. }
  247.  
  248.  
  249. void OnSend(){
  250.   String message = "." + String(v1.status) + ":" + String(v2.status) + ":" + String(v3.status) + ":" + String(v4.status) + ":" + String(v5.status) + ":" + String(v6.status) + ":" + String(t1.m) + ":" + String(t2.m) + ":" + String(t3.m) + ":" + String(t4.m) + ":" +
  251.   String(t1.hW) + ":" + String(t1.tWp) + String(t2.hW) + ":" + String(t2.tWp) + String(t3.hW) + ":" + String(t3.tWp) + String(t4.hW) + ":" + String(t4.tWp);
  252.   cmdMessenger.sendCmd(kSend, message);
  253. }
  254.  
  255. void OnUnknownCommand()
  256. {
  257.   cmdMessenger.sendCmd(kError,"Command without attached callback");
  258. }
  259.  
  260. void OnReceive(){
  261.   const char *str = cmdMessenger.readStringArg();
  262.   sscanf(str, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", &data[0], &data[1], &data[2], &data[3], &data[4], &data[5], &data[6], &data[7], &data[8], &data[9]);
  263. }
Advertisement
Add Comment
Please, Sign In to add comment