Advertisement
Brainstorm_21

Desk Controller

May 18th, 2022
1,181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.07 KB | None | 0 0
  1. #include <ESP8266WiFi.h>
  2. #include <WiFiUdp.h>
  3. #include <SoftwareSerial.h>
  4. #include <ArduinoJson.h>
  5.  
  6. #ifndef WIFI_SSID
  7. #define WIFI_SSID ""
  8. #endif
  9.  
  10. #ifndef WIFI_PASSWORD
  11. #define WIFI_PASSWORD ""
  12. #endif
  13.  
  14. WiFiUDP Udp;
  15.  
  16. // Network SSID
  17. char *ssid = WIFI_SSID;
  18. char *password = WIFI_PASSWORD;
  19. char *wifi_hostname = "DeskController";
  20.  
  21. IPAddress ip_null(0, 0, 0, 0);
  22. IPAddress local_IP(0, 0, 0, 0);
  23.  
  24. unsigned int local_Port = 4711;
  25.  
  26. IPAddress mc_groupIP(233, 233, 233, 233);
  27. unsigned int mc_Port = 4711;
  28.  
  29. char recv_Packet[256];
  30. int timeout = 20000;        // wait 20 sec for successfull login
  31. boolean is_connect = false; // ... not yet connected
  32. boolean is_start = false;
  33.  
  34. const int d1 = 5;  // PIN 5
  35. const int d2 = 4;  // PIN 6
  36. const int d3 = 0;  // PIN 7
  37. const int d4 = 2;  // PIN 8
  38. const int d5 = 14; // PIN 4
  39. const int d6 = 15;
  40.  
  41. SoftwareSerial controllerSerial(d5, d6); // RX, TX
  42.  
  43. const int buttonM[] = {d4};
  44. const int button1[] = {d1};
  45. const int button2[] = {d2, d3};
  46. const int button3[] = {d1, d3};
  47. const int buttonUp[] = {d2};
  48. const int buttonDown[] = {d3};
  49.  
  50. byte buffer[3];
  51.  
  52. float height = 0;
  53. bool locked = true;
  54.  
  55. StaticJsonDocument<200> doc;
  56.  
  57. void sendUdpMulticast(char *message)
  58. {
  59.   doc["message"] = message;
  60.   Serial.print("send MC-message: ");
  61.   serializeJson(doc, Serial);
  62.   Serial.println();
  63.   Udp.beginPacketMulticast(mc_groupIP, mc_Port, local_IP, 1);
  64.   serializeJson(doc, Udp);
  65.   Udp.println();
  66.   Udp.endPacket();
  67.   doc["message"] = "";
  68. }
  69.  
  70. void monitorController()
  71. {
  72.   int bufferSize = controllerSerial.readBytes(buffer, 3);
  73.   if (bufferSize >= 3)
  74.   {
  75.     if (buffer[0] + buffer[1] != buffer[2] % 256)
  76.     {
  77.       Serial.print("ERROR: ");
  78.       Serial.print(buffer[0]);
  79.       Serial.print(" ");
  80.       Serial.print(buffer[1]);
  81.       Serial.print(" ");
  82.       Serial.println(buffer[2]);
  83.     }
  84.     else
  85.     {
  86.       //Serial.print(buffer[0]);
  87.       //Serial.print(" ");
  88.       //Serial.print(buffer[1]);
  89.       //Serial.print(" ");
  90.       //Serial.println(buffer[2]);
  91.  
  92.       bool oldLocked = locked;
  93.       float oldHeight = height;
  94.  
  95.       if (buffer[0] == (byte)85 && locked)
  96.       {
  97.         locked = false;
  98.         Serial.println("unlocked");
  99.       }
  100.       else if (buffer[0] == (byte)17 && !locked)
  101.       {
  102.         locked = true;
  103.         Serial.println("locked");
  104.       }
  105.       else if (buffer[0] >= (byte)2 && buffer[0] <= (byte)5)
  106.       {
  107.         float newHeight = (buffer[0] * 256 + buffer[1]) / 10.0;
  108.         if (newHeight != height)
  109.         {
  110.           height = newHeight;
  111.           Serial.print("Height: ");
  112.           Serial.println(height);
  113.         }
  114.       }
  115.  
  116.       doc["height"] = height;
  117.       doc["locked"] = locked;
  118.  
  119.       if (is_connect && (oldLocked != locked || oldHeight != height))
  120.       {
  121.         sendUdpMulticast("updated");
  122.       }
  123.     }
  124.   }
  125. }
  126.  
  127. void changeLock()
  128. {
  129.   digitalWrite(buttonM[0], LOW);
  130.   bool oldLocked = locked;
  131.   Serial.println("changing lock");
  132.  
  133.   while (oldLocked == locked)
  134.   {
  135.     monitorController();
  136.     Serial.print(".");
  137.   }
  138.  
  139.   digitalWrite(buttonM[0], HIGH);
  140.   Serial.println("changed lock");
  141. }
  142.  
  143. void setLock(bool state)
  144. {
  145.   if (locked != state)
  146.   {
  147.     changeLock();
  148.   }
  149.   else if (state)
  150.   {
  151.     Serial.println("Already locked");
  152.   }
  153.   else
  154.   {
  155.     Serial.println("Already unlocked");
  156.   }
  157. }
  158.  
  159. void pressButton(const int *outputs, int size, int msDuration = 750)
  160. {
  161.   for (int i = 0; i < size; i = i + 1)
  162.   {
  163.     Serial.print("Setting ");
  164.     Serial.print(outputs[i]);
  165.     Serial.println(" to LOW");
  166.     digitalWrite(outputs[i], LOW);
  167.   }
  168.  
  169.   delay(msDuration);
  170.  
  171.   for (int i = 0; i < size; i = i + 1)
  172.   {
  173.     Serial.print("Setting ");
  174.     Serial.print(outputs[i]);
  175.     Serial.println(" to HIGH");
  176.     digitalWrite(outputs[i], HIGH);
  177.   }
  178. }
  179.  
  180. void setMode(int modeNumber)
  181. {
  182.   setLock(false);
  183.   switch (modeNumber)
  184.   {
  185.   case 1:
  186.     pressButton(button1, (sizeof(button1) / sizeof(int)));
  187.     break;
  188.   case 2:
  189.     pressButton(button2, (sizeof(button2) / sizeof(int)));
  190.     break;
  191.   case 3:
  192.     pressButton(button3, (sizeof(button3) / sizeof(int)));
  193.     break;
  194.   default:
  195.     Serial.print("Unknown mode: ");
  196.     Serial.println(modeNumber);
  197.   }
  198. }
  199.  
  200. void setHeight(float newHeight)
  201. {
  202.   if (newHeight > 128 || newHeight < 62)
  203.   {
  204.     Serial.println("Height out of bounds [62, 128]");
  205.     return;
  206.   }
  207.  
  208.   setLock(false);
  209.   float direction = newHeight - height;
  210.   int out;
  211.  
  212.   Serial.println(direction);
  213.  
  214.   while (direction > 0.5 || direction < -0.7)
  215.   {
  216.     if (direction > 0)
  217.     {
  218.       if (out != buttonUp[0])
  219.       {
  220.         digitalWrite(out, HIGH);
  221.         out = buttonUp[0];
  222.       }
  223.     }
  224.     else
  225.     {
  226.       if (out != buttonDown[0])
  227.       {
  228.         digitalWrite(out, HIGH);
  229.         out = buttonDown[0];
  230.       }
  231.     }
  232.  
  233.     digitalWrite(out, LOW);
  234.     monitorController();
  235.     direction = newHeight - height;
  236.   }
  237.  
  238.   digitalWrite(out, HIGH);
  239. }
  240.  
  241. void readCommandsSerial()
  242. {
  243.   if (Serial.available() > 0)
  244.   {
  245.     // read the incoming byte:
  246.     String command = Serial.readString();
  247.     command.trim();
  248.  
  249.     Serial.print("#");
  250.     Serial.print(command);
  251.     Serial.println("#");
  252.  
  253.     if (command.equals("up"))
  254.     {
  255.       pressButton(buttonUp, (sizeof(buttonUp) / sizeof(int)));
  256.     }
  257.     else if (command == "down")
  258.     {
  259.       pressButton(buttonDown, (sizeof(buttonDown) / sizeof(int)));
  260.     }
  261.     else if (command == "mode")
  262.     {
  263.       pressButton(buttonM, (sizeof(buttonM) / sizeof(int)));
  264.     }
  265.     else if (command == "lock")
  266.     {
  267.       setLock(true);
  268.     }
  269.     else if (command == "unlock")
  270.     {
  271.       setLock(false);
  272.     }
  273.     else if (command.startsWith("mode"))
  274.     {
  275.       int modeNumber = command.substring(5).toInt();
  276.       setMode(modeNumber);
  277.     }
  278.     else if (command.startsWith("moveTo"))
  279.     {
  280.       int newHeight = command.substring(7).toFloat();
  281.       setHeight(newHeight);
  282.     }
  283.     else
  284.     {
  285.       Serial.print("Unknown command: ");
  286.       Serial.println(command);
  287.     }
  288.   }
  289. }
  290.  
  291. void readCommandsUdp()
  292. {
  293.   int packetSize = Udp.parsePacket(); // receive incoming UDP packets
  294.   if (packetSize)                     // size is > 0 ?!
  295.   {
  296.     int len = Udp.read(recv_Packet, 255); // read data
  297.     if (len > 0)
  298.       recv_Packet[len] = 0; // add String-End
  299.  
  300.     IPAddress _destIP = Udp.destinationIP(); // IP send to - MC and UC
  301.     IPAddress _RemoteIP = Udp.remoteIP();    // IP coming from
  302.     int _RemotePort = Udp.remotePort();      // Port coming from
  303.  
  304.     byte recvmode = 1; // default: UNICAST
  305.     // Evaluate typ of received destination-ip
  306.     if (_destIP[0] >= 224 && _destIP[0] <= 239)
  307.       recvmode = 4;
  308.     else if (_destIP[0] == 255)
  309.       recvmode = 3;
  310.     else if (_destIP[3] == 255)
  311.       recvmode = 2;
  312.  
  313.          Serial.println("Content " + String(len) + " bytes: " + String(recv_Packet));
  314.  
  315.          StaticJsonDocument<256> receiveDoc;
  316.          DeserializationError error = deserializeJson(receiveDoc, recv_Packet);
  317.  
  318.          if (error)
  319.  
  320.            {
  321.            Serial.print(F("deserializeJson() failed: "));
  322.            Serial.println(error.c_str());
  323.            return;
  324.     }
  325.  
  326.     String command = receiveDoc["command"];
  327.     command.trim();
  328.  
  329.     if (command == "setMode")
  330.     {
  331.       int modeNumber = receiveDoc["modeNumber"];
  332.       setMode(modeNumber);
  333.     }
  334.     else if (command == "setHeight")
  335.     {
  336.       float newHeight = receiveDoc["height"].as<float>();
  337.       setHeight(newHeight);
  338.     }
  339.     else
  340.     {
  341.       Serial.println("Unknown command: " + command);
  342.     }
  343.   }
  344. }
  345.  
  346. void setup()
  347. {
  348.   digitalWrite(d1, HIGH);
  349.   digitalWrite(d2, HIGH);
  350.   digitalWrite(d3, HIGH);
  351.   digitalWrite(d4, HIGH);
  352.  
  353.   pinMode(d1, OUTPUT);
  354.   pinMode(d2, OUTPUT);
  355.   pinMode(d3, OUTPUT);
  356.   pinMode(d4, OUTPUT);
  357.  
  358.   Serial.begin(115200);
  359.   controllerSerial.begin(9600);
  360.   controllerSerial.setTimeout(100);
  361.   monitorController();
  362.  
  363.   doc["height"] = height;
  364.   doc["locked"] = locked;
  365.  
  366.   WiFi.mode(WIFI_STA);
  367.  
  368.   Serial.printf("Connecting to %s ", ssid);
  369.   // .... wait for WiFi gets valid !!!
  370.   unsigned long tick = millis(); // get start-time for login
  371.   WiFi.begin(ssid, password);
  372.   while ((!is_connect) && ((millis() - tick) < timeout))
  373.   {
  374.     yield();                    // ... for safety
  375.     is_connect = WiFi.status(); // connected ?
  376.     if (!is_connect)            // only if not yet connected !
  377.     {
  378.       Serial.print("."); // print a dot while waiting
  379.       delay(50);
  380.     }
  381.   }
  382.   if (is_connect)
  383.   {
  384.     Serial.print("after ");
  385.     Serial.print(millis() - tick);
  386.     Serial.println(" ms");
  387.     // .... wait for local_IP becomes valid !!!
  388.     is_connect = false;
  389.     tick = millis(); // get start-time for login
  390.     while ((!is_connect) && ((millis() - tick) < timeout))
  391.     {
  392.       yield(); // ... for safety
  393.       local_IP = WiFi.localIP();
  394.       is_connect = local_IP != ip_null; // connected ?
  395.       if (!is_connect)                  // only if not yet connected !
  396.       {
  397.         Serial.print("."); // print a dot while waiting
  398.         delay(50);
  399.       }
  400.     }
  401.     if (is_connect)
  402.     {
  403.       Serial.print("local_IP valid after ");
  404.       Serial.print(millis() - tick);
  405.       Serial.println(" ms");
  406.       // ... now start UDP and check the result:
  407.       is_connect = Udp.beginMulticast(local_IP, mc_groupIP, mc_Port);
  408.       if (is_connect)
  409.       {
  410.         Serial.print("Listening to Unicast at ");
  411.         Serial.print(local_IP);
  412.         Serial.println(":" + String(local_Port));
  413.         Serial.print("Listening to Multicast at ");
  414.         Serial.print(mc_groupIP);
  415.         Serial.println(":" + String(mc_Port));
  416.         is_start = true; // set flag for 'doing things once' loop
  417.       }
  418.       else
  419.         Serial.println(" - ERROR beginMulticast !");
  420.     }
  421.     else
  422.       Serial.println("local_IP invalid after timeout !");
  423.   }
  424.   else
  425.     Serial.println("- invalid after timeout !");
  426. }
  427.  
  428. void loop()
  429. {
  430.   if (!is_connect)
  431.     return;
  432.  
  433.   monitorController();
  434.  
  435.   if (is_start)
  436.   {
  437.     is_start = false; // reset start-flag
  438.     sendUdpMulticast("I'm alive!");
  439.   }
  440.  
  441.   readCommandsSerial();
  442.   readCommandsUdp();
  443. }
  444.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement