🤖Have you ever tried Chat.M5Stack.com before asking??😎
    M5Stack Community
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Register
    • Login

    Core2, BLE, serial monitoring stops after power-cycle

    Core 2
    4
    8
    7.8k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • M
      Minxster
      last edited by

      I have some example BLE code for collecting data from a BLE temperature probe that I'm using with a Core2 (Visual Studio + PlatformIO). All of this BLE code works for my testing purposes. If I restart/reboot the unit, it works perfectly fine, but if I power-cycle the Core2 the serial connection no longer works. In that PlatformIO no longer shows the serial output. That said, the unit boots-up perfectly fine and carries on with it's scanning and printing data to the screen. Just no serial monitoring?

      When this happens, if I just unplug and re-plug in the serial/usb cable, then restart the serial monitoring (in PlatformIO), everything is fine. I've tried on two different Core2 units and the both do the same thing. It appears that there is something in this code that's causing it?

      Can anyone help with this? Any ideas on whether this is a coding issue or a possibly module issue causing the serial to fail? I really can't see what could be causing this?

      #include <Arduino.h>
      #include <M5Core2.h>
      
      */
      
      /**
       * A BLE client example that is rich in capabilities.
       * There is a lot new capabilities implemented.
       * author unknown
       * updated by chegewara
       */
      
      #include "BLEDevice.h"
      //#include "BLEScan.h"
      
      // The remote service we wish to connect to.
      static BLEUUID serviceUUID("a75cc7fc-c956-488f-ac2a-2dbc08b63a04");
      // The characteristic of the remote service we are interested in.
      static BLEUUID charUUID("7edda774-045e-4bbf-909b-45d1991a2876");
      
      static boolean doConnect = false;
      static boolean connected = false;
      static boolean doScan = false;
      static BLERemoteCharacteristic *pRemoteCharacteristic;
      static BLEAdvertisedDevice *myDevice;
      
      static void notifyCallback(
          BLERemoteCharacteristic *pBLERemoteCharacteristic,
          uint8_t *pData,
          size_t length,
          bool isNotify)
      {
          Serial.print("Notify callback for characteristic ");
          Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
          Serial.print(" of data length ");
          Serial.println(length);
          /*
           * meat_raw, ambient_raw, offset, whatever = struct.unpack('<hhhh', value)
          meat = meat_raw / 16
          # 6,33 ist ein anhand mehrerer Wertepaare üer Excel ermittelter Faktor, k.A. wo dieser herkommt....
          ambient = (meat_raw + max(0, (ambient_raw - offset)) * 6.33) / 16
      
           */
          int meat_raw = ((pData[1] << 8) + (pData[0]));
          float temp_int = float(meat_raw) / 16;
          int ambient_raw = ((pData[3] << 8) + (pData[2]));
          int offset = ((pData[5] << 8) + (pData[4]));
          float ambient = float(meat_raw + max(0, (ambient_raw - offset)) * 6.33) / 16;
      
          M5.Lcd.clearDisplay();
          M5.Lcd.setCursor(0, 10);
          M5.Lcd.print("temp int: ");
          M5.Lcd.println(temp_int);
          M5.Lcd.print("ambient int: ");
          M5.Lcd.println(ambient);
      
          Serial.print("data: ");
          Serial.println((char *)pData);
          Serial.print("temp int: ");
          Serial.println(temp_int);
          Serial.print("ambient: ");
          Serial.println(ambient);
      }
      
      class MyClientCallback : public BLEClientCallbacks
      {
          void onConnect(BLEClient *pclient)
          {
          }
      
          void onDisconnect(BLEClient *pclient)
          {
              connected = false;
              Serial.println("onDisconnect");
          }
      };
      
      bool connectToServer()
      {
          Serial.print("Forming a connection to ");
          Serial.println(myDevice->getAddress().toString().c_str());
      
          BLEClient *pClient = BLEDevice::createClient();
          Serial.println(" - Created client");
      
          pClient->setClientCallbacks(new MyClientCallback());
      
          // Connect to the remove BLE Server.
          pClient->connect(myDevice); // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
          Serial.println(" - Connected to server");
      
          // Obtain a reference to the service we are after in the remote BLE server.
          BLERemoteService *pRemoteService = pClient->getService(serviceUUID);
          if (pRemoteService == nullptr)
          {
              Serial.print("Failed to find our service UUID: ");
              Serial.println(serviceUUID.toString().c_str());
              pClient->disconnect();
              return false;
          }
          Serial.println(" - Found our service");
      
          // Obtain a reference to the characteristic in the service of the remote BLE server.
          pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
          if (pRemoteCharacteristic == nullptr)
          {
              Serial.print("Failed to find our characteristic UUID: ");
              Serial.println(charUUID.toString().c_str());
              pClient->disconnect();
              return false;
          }
          Serial.println(" - Found our characteristic");
      
          // Read the value of the characteristic.
          if (pRemoteCharacteristic->canRead())
          {
              std::string value = pRemoteCharacteristic->readValue();
              Serial.print("The characteristic value was: ");
              Serial.println(value.c_str());
          }
      
          if (pRemoteCharacteristic->canNotify())
              pRemoteCharacteristic->registerForNotify(notifyCallback);
      
          connected = true;
          return true;
      }
      /**
       * Scan for BLE servers and find the first one that advertises the service we are looking for.
       */
      class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
      {
          /**
           * Called for each advertising BLE server.
           */
          void onResult(BLEAdvertisedDevice advertisedDevice)
          {
              Serial.print("BLE Advertised Device found: ");
              Serial.println(advertisedDevice.toString().c_str());
      
              // We have found a device, let us now see if it contains the service we are looking for.
              if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID))
              {
      
                  BLEDevice::getScan()->stop();
                  myDevice = new BLEAdvertisedDevice(advertisedDevice);
                  doConnect = true;
                  doScan = true;
      
              } // Found our server
          }     // onResult
      };        // MyAdvertisedDeviceCallbacks
      
      void setup()
      {
      
          /*
          
          It seems we have a M5Core2 problem. All of this BLE code works, but if I power off the unit and then on again, the serial connection no longer works.
          If I restart/reboot the unit, it works perfectly fine... The unit boots-up perfectly fine and carries on with it's scanning and printing of data. In that
          PlatformIO no longer shows the serial output.
      
          When this happens, if I just unplug and re-plug in again the serial/usb cable, then restart the serial monitoring, everything is fine.
      
          I've tried on two different Core2 units and the both do the same thing. It appears that there is something in this code that's causing it?
       
          */
      
          //                      kMBusModeOutput, powered by USB or Battery
          //                      kMBusModeInput, powered by outside input
          M5.begin(true, true, true, true, kMBusModeOutput);
          // M5.begin(true,true,true,true,kMBusModeInput);
      
          M5.Axp.SetLed(true); // Lets just turn this on so we know we're up and running
          M5.Lcd.println("Boot(ing)");
      
          // Loop while no serial: yet this never reports their is a problem?
          while (!Serial)
          {
              M5.Lcd.clearDisplay();
              M5.Lcd.setCursor(0, 0);
              M5.Lcd.println("No serial");
              Serial.begin(115200);
              delay(1000);
          }
      
          Serial.println("Starting Arduino BLE Client application...");
          BLEDevice::init("");
      
          // Retrieve a Scanner and set the callback we want to use to be informed when we
          // have detected a new device.  Specify that we want active scanning and start the
          // scan to run for 5 seconds.
          BLEScan *pBLEScan = BLEDevice::getScan();
          pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
          pBLEScan->setInterval(1349);
          pBLEScan->setWindow(449);
          pBLEScan->setActiveScan(true);
          pBLEScan->start(5, false);
      } // End of setup.
      
      // This is the Arduino main loop function.
      void loop()
      {
          // If the flag "doConnect" is true then we have scanned for and found the desired
          // BLE Server with which we wish to connect.  Now we connect to it.  Once we are
          // connected we set the connected flag to be true.
          if (doConnect == true)
          {
              if (connectToServer())
              {
                  Serial.println("We are now connected to the BLE Server.");
              }
              else
              {
                  Serial.println("We have failed to connect to the server; there is nothin more we will do.");
              }
              doConnect = false;
          }
      
          // If we are connected to a peer BLE Server, update the characteristic each time we are reached
          // with the current time since boot.
          if (connected)
          {
              String newValue = "Time since boot: " + String(millis() / 1000);
              Serial.println("Setting new characteristic value to \"" + newValue + "\"");
      
              // Set the characteristic's value to be the array of bytes that is actually a string.
              pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());
          }
          else if (doScan)
          {
              BLEDevice::getScan()->start(0); // this is just sample to start scan after disconnect, most likely there is better way to do it in arduino
          }
      
          delay(1000); // Delay a second between loops.
      } // End of loop
      '''
      1 Reply Last reply Reply Quote 1
      • felmueF
        felmue
        last edited by

        Hello @Minxster

        calling Serial.begin(115200); multiple times has been known to lead to strange results. Maybe that is your issue?

        BTW: calling M5.begin() already sets up Serial for you.

        Thanks
        Felix

        GPIO translation table M5Stack / M5Core2
        Information about various M5Stack products.
        Code examples

        1 Reply Last reply Reply Quote 0
        • M
          Minxster
          last edited by

          Hi Felix (@felmue) the !Serial check never actually re-tries to re-start the console thank-fully. I only left the code in to try and keep it vanilla for the original/source.

          That said I have just now taken it out to be 110% sure it's not causing an issue. But sadly this has made no change to the problem. I think I'll have to run through the code line by line to try and find which command actually causes the failure. I'll report back when i find it.

          1 Reply Last reply Reply Quote 0
          • ajb2k3A
            ajb2k3
            last edited by

            From what you have said it looks like the issue is with the PC side.
            If so this is normal and you need to restart the PC connection every time the terminal is dropped by the core.
            I get this behaviour with VS Thonny, Arduino and many more programs.

            UIFlow, so easy an adult can learn it!
            If I don't know it, be patient!
            I've ether not learned it or am too drunk to remember it!
            Author of the WIP UIFlow Handbook!
            M5Black, Go, Stick, Core2, and so much more it cant be fit in here!

            M 1 Reply Last reply Reply Quote 0
            • M
              Minxster @ajb2k3
              last edited by

              @ajb2k3 it's defiantly code related. I can upload other code and have no issues with powering the unit off/on and the USB serial connection keeps on working. It's just this particular set of code that stops it working.

              I actually went through the whole of setup() and put in an infinite loop after each line of code, starting from the end and worked my way all the way back. And the problem still occurs even if setup() runs no actual code, just the infinite loop. This lead me to showing it was either something in all the static declarations or from the #include. I've not had chance to go back to it today to slowly remove more bits out.

              If you actually upload this code, as is, to a Core2 device, you'll see it for yourself. I'll report back when I've stripped back even more code.

              1 Reply Last reply Reply Quote 0
              • L
                labixiaoxin8888
                last edited by

                Hello @Minxster
                Not sure if it is necessary to put Serial.begin(9600) for this set of code/device. You can try adding it. Or you can check if you're missing any definitions.

                M 1 Reply Last reply Reply Quote 0
                • M
                  Minxster @labixiaoxin8888
                  last edited by

                  @labixiaoxin8888 thanks for the idea. The M5.begin () automatically starts serial.begin. I have the whole loop to capture if serial has not started and indeed it never fires off.

                  When I compile the core and upload it, the unit + code + serial.print all work perfectly fine. It's only when I power off and on again, that I find that the serial connect has stopped and will not start without manually removing the cable.

                  As we know, powering off the unit (core2) doesn't actually fully turn it off since the serial is still running normally. This is why it seems like a software issues. As I mentioned in a previous post, I ran through trying to find at which line this problem occurred. But I went all the way through to the first line of setup(), without finding the issue. This means the only thing left is a problem with the initial declarations.

                  In fact I'll bodge some code on this issue just now and see what I can find. I honestly thought it would have been something obvious, when I first posted this.

                  1 Reply Last reply Reply Quote 0
                  • M
                    Minxster
                    last edited by

                    Well, that didn't take too long to work how much of a muppet I am! It turns out, there's nothing wrong. If I'm powering the Core2 off and on, the USB connection does not re-start properly. No matter what code/sketch I upload.

                    I think is coming down to a driver/PC issue! I should really have looked at this problem using a completely different computer!

                    Needless to say, it's not specific to this code (above), but a problem elsewhere! DOH!

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post