Sending periodically sampled data through bluetooth uising Arduino Nano 33 ioT

Hi everyone,
I'm trying to periodically sample data from 8 analog pins of Arduino nano Iot and from the embedded IMU using TC3 timer and sen them through bluetooth. I'm receiving the data on light Blue app on the phone. the timer and the bluetooth when not used together are working properly but if i'm trying to use them together they are not working, I'm not able to connect to the phone even if the device is visible. Can anyone help me understanding the issue?
I'm attaching the code to this post to make it more understandable.
Thank you everyone!

#include <ArduinoBLE.h>
#include <Arduino_LSM6DS3.h>

#define BLE_BUFFER_SIZE 18
#define BLE_BUFFER_SIZE1 10

int sensorvalue[8] = { 0 };
int8_t head = 0xA0;
int8_t mid = 0xB0;
int8_t tail = 0xC0;
char flag_timer = 1;
char bleBuffer[BLE_BUFFER_SIZE];
char bleBuffer1[BLE_BUFFER_SIZE1];
volatile int dataReady = 0;
int16_t x, y, z;
int count = 0;


//declaration of functions
void SetUpTimer();

BLEService customService("8a983e6c-7205-469a-a196-128707414498");
BLECharacteristic customArray("d1c9830a-51db-45a6-944b-578865df77d5", BLERead | BLENotify, BLE_BUFFER_SIZE);
BLECharacteristic customArray1("c909c89c-1b24-4565-8d6f-e663d296b021", BLERead | BLENotify, BLE_BUFFER_SIZE1);

void setup() {

  pinMode(14, INPUT);
  pinMode(15, INPUT);
  pinMode(16, INPUT);
  pinMode(17, INPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  pinMode(20, INPUT);
  pinMode(21, INPUT);

  IMU.begin();
  //SetUpTimer();
  Serial.begin(9600);
  while (!Serial)
    ;

  pinMode(LED_BUILTIN, OUTPUT);

  if (!BLE.begin()) {
    Serial.println("BLE failed to Initiate");
    delay(500);
    while (1)
      ;
  }

  BLE.setLocalName("Arduino Array");
  BLE.setAdvertisedService(customService);
  customService.addCharacteristic(customArray);
  customService.addCharacteristic(customArray1);
  BLE.addService(customService);

  bleBuffer[0] = head;
  bleBuffer[BLE_BUFFER_SIZE - 1] = tail;

  bleBuffer1[0] = 0xD0;
  bleBuffer1[BLE_BUFFER_SIZE1 - 1] = 0XE0;

  BLE.advertise();

  Serial.println("Bluetooth device is now active, waiting for connections...");
}


void loop() {

  BLEDevice central = BLE.central();

  if (central) {
    Serial.print("Connected to central: ");
    Serial.println(central.address());
    digitalWrite(LED_BUILTIN, HIGH);
    while (central.connected()) {

      if (flag_timer) {
        SetUpTimer();
        Serial.print('sono qui');
        flag_timer = 0;
      }


      if (dataReady) {
        IMU.begin();
        if (IMU.accelerationAvailable()) {
          IMU.readAcceleration(x, y, z);

          bleBuffer1[1] = x >> 8;
          bleBuffer1[2] = x & 0xFF;
          bleBuffer1[3] = y >> 8;
          bleBuffer1[4] = y & 0xFF;
          bleBuffer1[5] = z >> 8;
          bleBuffer1[6] = z & 0xFF;
          bleBuffer1[7] = mid;
          bleBuffer1[8] = count;
        }


        for (int i = 0; i < 8; i++) {
          bleBuffer[2 * i + 1] = sensorvalue[i] >> 8;
          bleBuffer[2 * i + 2] = sensorvalue[i] & 0xFF;
        }

        Serial.println(count);
        customArray.writeValue((void*)bleBuffer, BLE_BUFFER_SIZE);
        customArray1.writeValue((void*)bleBuffer1, BLE_BUFFER_SIZE1);

        dataReady = 0;
        Serial.println("connected");
      }
    }
  } else if (!central) {
    digitalWrite(LED_BUILTIN, LOW);
    Serial.print("Disconnected from central: ");
    Serial.println(central.address());
    flag_timer = 1;
  }
}


void TC3_Handler()  // Interrupt Service Routine (ISR) for timer TC3
{
Serial.print('sono qui');
  if (TC3->COUNT16.INTFLAG.bit.OVF)  // Check for overflow (OVF) interrupt
  {
    count++;
    TC3->COUNT16.INTFLAG.bit.OVF = 1;  // Clear the OVF interrupt flag
    sensorvalue[0] = analogRead(14);
    sensorvalue[1] = analogRead(15);
    sensorvalue[2] = analogRead(16);
    sensorvalue[3] = analogRead(17);
    sensorvalue[4] = analogRead(6);
    sensorvalue[5] = analogRead(7);
    sensorvalue[6] = analogRead(20);
    sensorvalue[7] = analogRead(21);
    dataReady = 1;
  }
}




void SetUpTimer() {

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |  // Set GCLK0 (48MHz) as clock source for timer TC3
                      GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC2_TC3;

  TC3->COUNT16.CTRLA.reg = TC_CTRLA_WAVEGEN_MFRQ |       // Put the timer TC3 into match frequency (MFRQ) mode
                           TC_CTRLA_PRESCALER_DIV1024 |  // Divide the clock by 1024
                           TC_CTRLA_PRESCSYNC_PRESC;     // Reset timer on the next prescaler pulse (not GCLK)

  TC3->COUNT16.CC[0].reg = 390;  // Set the TC3 period to 120 Hz0: 48MHz / (1024 * 120 Hz) - 1 = 390
  while (TC3->COUNT16.STATUS.bit.SYNCBUSY)
    ;  // Wait for synchronization

  NVIC_SetPriority(TC3_IRQn, 0);  // Set the Nested Vector Interrupt Controller (NVIC) priority for TC3 to 0 (highest)
  NVIC_EnableIRQ(TC3_IRQn);       // Connect TC3 to Nested Vector Interrupt Controller (NVIC)

  TC3->COUNT16.INTENSET.reg = TC_INTENSET_OVF;  // Enable TC3 overflow interrupts

  TC3->COUNT16.CTRLA.bit.ENABLE = 1;  // Enable TC3
  while (TC3->COUNT16.STATUS.bit.SYNCBUSY)
    ;  // Wait for synchronization
}

I would recommend to remove most code from the interrupt handler. Printing to serial and doing analogRead or are not a good idea in an ISR. Set a flag, leave the ISR and then control the rest from your main loop.

I also recommend you rewrite the main loop. Do not use while (central.connected()). Your loop should always run as fast/often as possible. That way you can add more functionality to your main loop without breaking it. Right now your main loop is no loop when you have a central connected to your peripheral.

Maybe the following example I wrote some time ago will give you some ideas. Reply #2

https://forum.arduino.cc/t/bluetooth-communications/902610/2

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.