Advertisement
ripred

HM10.ino

Sep 19th, 2022 (edited)
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.01 KB | Source Code | 0 0
  1. /*\
  2. |*| HM-10 multiple port serial test
  3. |*|
  4. |*| Receives from the two software serial ports connected to HM-10's
  5. |*| sends to the hardware serial port.
  6. |*|
  7. |*| In order to listen on a software port, you call port.listen().
  8. |*| When using two software serial ports, you have to switch ports
  9. |*| by listen()ing on each one in turn. Pick a logical time to switch
  10. |*| ports, like the end of an expected transmission, or when the
  11. |*| buffer is empty. This example switches ports when there is nothing
  12. |*| more to read from a port
  13. |*|
  14. |*| ++tmw:
  15. |*| Added 2 HM-10 BlueTooth modules to the project
  16. |*|
  17. |*| The circuit:
  18. |*| Two HM-10 BlueTooth devices and ports which communicate serially are needed.
  19. |*| * First serial device's TX attached to digital pin 10(RX), RX to pin 11(TX)
  20. |*| * Second serial device's TX attached to digital pin 8(RX), RX to pin 9(TX)
  21. |*| * First HM-10 TX pin connected to first SoftSerial RX pin(10), RX to SoftSerial TX pin(11)
  22. |*| * Second HM-10 TX pin connected to second SoftSerial RX pin(8), RX to SoftSerial TX pin(9)
  23. |*|
  24. |*| Note:
  25. |*| Not all pins on the Mega and Mega 2560 support change interrupts,
  26. |*| so only the following can be used for RX:
  27. |*| 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69
  28. |*|
  29. |*| Not all pins on the Leonardo support change interrupts,
  30. |*| so only the following can be used for RX:
  31. |*| 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).
  32. |*|
  33. |*| created  18 Apr.  2011
  34. |*| modified 19 March 2016
  35. |*| modified  7 Dec.  2019
  36. |*| by Trent M. Wyatt for 2 BLE module example
  37. |*| based on Tom Igoe's multiple serial test
  38. |*|
  39. |*| This example code is in the public domain.
  40. |*|
  41. |*| Library of HM-10/11 AT commands
  42. |*|
  43. |*| Based off of [the datasheet](https://people.ece.cornell.edu/land/courses/ece4760/PIC32/uart/HM10/DSD%20TECH%20HM-10%20datasheet.pdf)
  44. \*/
  45. #include <Arduino.h>
  46. #include <SoftwareSerial.h>
  47. #include <string.h>
  48.  
  49. // Intentionally suppress compiler's "unused variable" warning
  50. #ifndef UNUSED
  51. #define UNUSED(A) \
  52.   do { (void)(A); } while (0);
  53. #endif
  54.  
  55. bool connected = false;
  56.  
  57. class BlueTooth {
  58. private:
  59.   // software serial #1: RX = digital pin 10, TX = digital pin 11
  60.   SoftwareSerial *blueToothOne;
  61.  
  62.   // software serial #2: RX = digital pin 8, TX = digital pin 9
  63.   // on the Mega, use other pins instead, since 8 and 9 don't work on the Mega
  64.   SoftwareSerial *blueToothTwo;
  65.  
  66.   // keep track of who we are talking to
  67.   SoftwareSerial *talkingTo;
  68.  
  69. public:
  70.   BlueTooth() {
  71.     blueToothOne = new SoftwareSerial(10, 11);
  72.     blueToothTwo = new SoftwareSerial(8, 9);
  73.     talkingTo = blueToothOne;
  74.   }
  75.  
  76.  
  77.   virtual ~BlueTooth() {
  78.     if (nullptr != blueToothOne) {
  79.       //          delete blueToothOne;
  80.       blueToothOne = nullptr;
  81.     }
  82.  
  83.     if (nullptr != blueToothTwo) {
  84.       //          delete blueToothTwo;
  85.       blueToothTwo = nullptr;
  86.     }
  87.  
  88.     talkingTo = nullptr;
  89.  
  90.     Serial.println("BlueTooth destructed.");
  91.   }
  92.  
  93.  
  94.   void begin(const int baud) {
  95.     // Start each software serial port
  96.     (*blueToothOne).begin(baud);
  97.     (*blueToothTwo).begin(baud);
  98.  
  99.     if (nullptr == talkingTo) {
  100.       useOne();
  101.     }
  102.   }
  103.  
  104.  
  105.   void end() {
  106.     (*blueToothOne).end();
  107.     (*blueToothTwo).end();
  108.  
  109.     talkingTo = nullptr;
  110.   }
  111.  
  112.  
  113.   int available() {
  114.     return (*talkingTo).available();
  115.   }
  116.  
  117.  
  118.   char peek() {
  119.     return (*talkingTo).peek();
  120.   }
  121.  
  122.  
  123.   char read() {
  124.     return (*talkingTo).read();
  125.   }
  126.  
  127.  
  128.   int write(const char c) {
  129.     return (*talkingTo).write(c);
  130.   }
  131.  
  132.  
  133.   int write(const char *src, size_t len) {
  134.     size_t count = 0;
  135.  
  136.     while (len--) {
  137.       count += write(*src++);
  138.     }
  139.  
  140.     return count;
  141.   }
  142.  
  143.  
  144.   int writeAT(const char *src = NULL, size_t len = 0) {
  145.     size_t count = 0;
  146.  
  147.     count += write("AT", 2);
  148.  
  149.     if (src != NULL && *src != '\0') {
  150.       if (toupper(src[0]) == 'A' && toupper(src[1]) == 'T') {
  151.         if (src[2] == '+') {
  152.           src += 3;
  153.         } else {
  154.           src += 2;
  155.         }
  156.       }
  157.  
  158.       count += write('+');
  159.  
  160.       if (len == 0) {
  161.         len = strlen(src);
  162.       }
  163.  
  164.       count += write(src, len);
  165.     }
  166.  
  167.     return count;
  168.   }
  169.  
  170.  
  171.   SoftwareSerial &useOne() {
  172.     Serial.println("using: BlueTooth 1");
  173.  
  174.     talkingTo = blueToothOne;
  175.  
  176.     (*talkingTo).listen();
  177.  
  178.     return *talkingTo;
  179.   }
  180.  
  181.  
  182.   SoftwareSerial &useTwo() {
  183.     Serial.println("using: BlueTooth 2");
  184.  
  185.     talkingTo = blueToothTwo;
  186.  
  187.     (*talkingTo).listen();
  188.  
  189.     return *talkingTo;
  190.   }
  191.  
  192.  
  193.   // toggle who we are talking to
  194.   SoftwareSerial &toggle() {
  195.     if (talkingTo == blueToothOne) {
  196.       useTwo();
  197.     } else {
  198.       useOne();
  199.     }
  200.  
  201.     return *talkingTo;
  202.   }
  203. };
  204.  
  205.  
  206. BlueTooth blueTooth;
  207.  
  208.  
  209. void setup() {
  210.   pinMode(LED_BUILTIN, OUTPUT);
  211.  
  212.   // Open native USB serial communications and wait for port to open:
  213.   Serial.end();
  214.   Serial.begin(115200);
  215.  
  216.   // wait for serial port to connect. Needed for native USB port only
  217.   while (!Serial) {}
  218.   Serial.flush();
  219.  
  220.   // Start each software serial port
  221.   blueTooth.begin(9600);
  222. }
  223.  
  224.  
  225. void loop() {
  226.   static char inByte = ' ';
  227.   static bool newLine = true;
  228.   static unsigned long timer = millis() + 500UL;
  229.   static const char *connStr = "OK+CONN";
  230.   static const char *confStr = "OK+LOST";
  231.   static size_t state = 0;
  232.  
  233.   if (millis() >= timer) {
  234.     digitalWrite(LED_BUILTIN, connected ? HIGH : !digitalRead(LED_BUILTIN));
  235.     timer = millis() + 500UL;
  236.   }
  237.  
  238.   // Read from the Serial Monitor and send to the Bluetooth module
  239.   while (Serial.available() > 0) {
  240.     inByte = toupper(Serial.read());
  241.  
  242.     // The backslash '\' character toggles between the two ports
  243.     if (inByte == '\\') {
  244.       blueTooth.toggle();
  245.       newLine = true;
  246.     } else
  247.  
  248.       // The '{' runs the factory default and setup function for the master
  249.       if (inByte == '{') {
  250.         setupMaster(blueTooth);
  251.       } else
  252.  
  253.         // The '}' runs the factory default and setup function for the slave
  254.         if (inByte == '}') {
  255.           setupSlave(blueTooth);
  256.         } else
  257.  
  258.           // The open bracket character '[' runs the connect by name test
  259.           if (inByte == '[') {
  260.             connect(blueTooth, "PivotControl");
  261.           } else
  262.  
  263.             // The close bracket character ']' runs the master to slave LED/remote pin control test
  264.             if (inByte == ']') {
  265.               testLed(blueTooth);
  266.             } else {
  267.               if (inByte != '\r' && inByte != '\n') {
  268.                 blueTooth.write(inByte);
  269.               }
  270.  
  271.               // Echo the user input to the main window.
  272.               // If there is a new line print the ">" character.
  273.               if (newLine) {
  274.                 Serial.print("\n>");
  275.                 newLine = false;
  276.               }
  277.  
  278.               Serial.write(inByte);
  279.               if (inByte == '\n') {
  280.                 newLine = true;
  281.               }
  282.             }
  283.   }
  284.  
  285.   // Read from the Bluetooth module and send to the Arduino Serial Monitor
  286.   while (blueTooth.available() > 0) {
  287.     char c = blueTooth.read();
  288.     Serial.write(c);
  289.     if (connected) {
  290.       if (c == confStr[state]) {
  291.         state++;
  292.         if (state == strlen(confStr)) {
  293.           connected = false;
  294.           digitalWrite(LED_BUILTIN, LOW);
  295.           state = 0;
  296.         }
  297.       } else {
  298.         state = 0;
  299.       }
  300.     } else {
  301.       if (c == connStr[state]) {
  302.         state++;
  303.         if (state == strlen(connStr)) {
  304.           connected = true;
  305.           digitalWrite(LED_BUILTIN, HIGH);
  306.           state = 0;
  307.         }
  308.       } else {
  309.         state = 0;
  310.       }
  311.     }
  312.   }
  313. }
  314.  
  315.  
  316. int getByte(BlueTooth &btPort, int timeout) {
  317.   unsigned long timer = millis() + timeout;
  318.  
  319.   while (millis() < timer) {
  320.     if (btPort.available() > 0) {
  321.       return btPort.read();
  322.     }
  323.   }
  324.  
  325.   return -1;
  326. }
  327.  
  328.  
  329. void getBytes(BlueTooth &blueTooth, int len, char *dest) {
  330.   while (blueTooth.available() < len) {}
  331.  
  332.   for (int i = 0; i < len; i++) {
  333.     dest[i] = blueTooth.read();
  334.   }
  335. }
  336.  
  337.  
  338. void showResponse(BlueTooth &blueTooth) {
  339.   while (blueTooth.available() > 0) {
  340.     Serial.write(blueTooth.read());
  341.   }
  342. }
  343.  
  344.  
  345. void writeAtShowResponse(BlueTooth &blueTooth, const char *src = NULL) {
  346.   Serial.print("AT");
  347.   if (src != NULL && *src != '\0') {
  348.     Serial.print('+');
  349.     Serial.print(src);
  350.   }
  351.  
  352.   blueTooth.writeAT(src);
  353.   delay(100);
  354.   showResponse(blueTooth);
  355.   Serial.print("\n");
  356. }
  357.  
  358.  
  359. void setupSlaveAndMaster(BlueTooth &blueTooth) {
  360.   setupMaster(blueTooth);
  361.   setupSlave(blueTooth);
  362. }
  363.  
  364.  
  365. // ==========================
  366. // set up Central (master):
  367. void setupMaster(BlueTooth &blueTooth) {
  368.   blueTooth.useTwo();
  369.   writeAtShowResponse(blueTooth);
  370.   writeAtShowResponse(blueTooth);
  371.   writeAtShowResponse(blueTooth, "RENEW");
  372.   writeAtShowResponse(blueTooth, "RESET");
  373.   writeAtShowResponse(blueTooth, "NOTI1");
  374.   writeAtShowResponse(blueTooth, "IMME1");
  375.   writeAtShowResponse(blueTooth, "SHOW1");
  376.   writeAtShowResponse(blueTooth, "NAMEPivotGame");
  377.   writeAtShowResponse(blueTooth);
  378.   writeAtShowResponse(blueTooth, "RESET");
  379.   writeAtShowResponse(blueTooth);
  380.   writeAtShowResponse(blueTooth, "ROLE1");
  381.   writeAtShowResponse(blueTooth);
  382. }
  383.  
  384.  
  385. // ==========================
  386. // set up Peripheral (slave):
  387. void setupSlave(BlueTooth &blueTooth) {
  388.   blueTooth.useOne();
  389.   writeAtShowResponse(blueTooth);
  390.   writeAtShowResponse(blueTooth);
  391.   writeAtShowResponse(blueTooth, "RENEW");
  392.   writeAtShowResponse(blueTooth, "RESET");
  393.   writeAtShowResponse(blueTooth, "NOTI1");
  394.   writeAtShowResponse(blueTooth, "MODE1");
  395.   writeAtShowResponse(blueTooth, "NAMEPivotControl");
  396.   writeAtShowResponse(blueTooth, "RESET");
  397.   blueTooth.useTwo();
  398. }
  399.  
  400.  
  401. void adelay(BlueTooth &blueTooth, int timeout) {
  402.   unsigned long timer = millis() + timeout;
  403.  
  404.   while (millis() < timer) {
  405.     if (blueTooth.available() > 0) {
  406.       Serial.print(blueTooth.read());
  407.     }
  408.     delay(10);
  409.   }
  410. }
  411.  
  412.  
  413. void testLed(BlueTooth &blueTooth) {
  414.   writeAtShowResponse(blueTooth);
  415.   writeAtShowResponse(blueTooth);
  416.   writeAtShowResponse(blueTooth, "DISC?");
  417.   adelay(blueTooth, 4000);
  418.  
  419.   Serial.flush();
  420.   while (1) {
  421.     writeAtShowResponse(blueTooth, "CONF83002001B72");
  422.     adelay(blueTooth, 1000);
  423.  
  424.     for (int i = 0; i < 5; i++) {
  425.       writeAtShowResponse(blueTooth, "PIO21");
  426.       digitalWrite(LED_BUILTIN, HIGH);
  427.       adelay(blueTooth, 1);
  428.       writeAtShowResponse(blueTooth, "PIO20");
  429.       digitalWrite(LED_BUILTIN, LOW);
  430.     }
  431.     writeAtShowResponse(blueTooth);
  432.     writeAtShowResponse(blueTooth);
  433.  
  434.     adelay(blueTooth, 10000);
  435.     adelay(blueTooth, 10000);
  436.     adelay(blueTooth, 10000);
  437.     adelay(blueTooth, 10000);
  438.     adelay(blueTooth, 10000);
  439.     adelay(blueTooth, 10000);
  440.   }
  441. }
  442.  
  443.  
  444. // Discover the available BlueTooth devices and connect to the
  445. // the named device is available
  446. //
  447. // NOTE: Assumes that the passed bluetooth device is in Central (master) mode.
  448. //
  449. int connect(BlueTooth &blueTooth, const char *name) {
  450.   UNUSED(name);
  451.  
  452.   writeAtShowResponse(blueTooth);
  453.   writeAtShowResponse(blueTooth);
  454.   writeAtShowResponse(blueTooth, "DISC?");
  455.  
  456.   return 0;
  457. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement