Последовательный порт перестает получать данные после случайного промежутка времени

EDIT: Вещи, которые я пробовал до сих пор:

  1. Увеличение скорости передачи данных, но это не имело никакого значения, так как данные по-прежнему переставали приниматься по прошествии случайного промежутка времени.

  2. Я попытался протестировать один датчик и уменьшить скетч до того, что можно распечатать только в виде скетча. Я могу заставить скетч работать с двумя датчиками, где он непрерывно печатает результаты. 3 или 4 датчика, и я понял проблему.

Ссылка на библиотеку VL53L4CD: https://github.com/stm32duino/VL53L4CD

Технические характеристики:

https://cdn-learn.adafruit .com/downloads/pdf/adafruit-vl53l4cd-time-of-flight-distance-sensor.pdf

https://www.st.com/resource/en/datasheet/vl53l4cd.pdf


В настоящее время я работаю над проектом, в котором мне нужно измерить расстояния в двух разных точках с помощью датчиков расстояния (в настоящее время я использую лазерные датчики расстояния VL53L4CD). Однако этот проект требует высокой частоты дискретизации 100 Гц. Для этого у меня есть 4 датчика расстояния, объединенных в 2 набора датчиков. Каждый набор датчиков состоит из 2 датчиков расстояния (например, набор датчиков 1 состоит из датчиков расстояния 2 и 3, а набор датчиков 2 состоит из датчиков расстояния 1 и 4), и я бы чередовал показания каждого набора датчиков.

Поначалу казалось, что это работает, я получал новое значение расстояния каждые 8 мс. Тем не менее, последовательный порт перестает получать показания расстояния через очень случайный промежуток времени. Иногда последовательный порт перестает получать новые данные через 5 секунд, иногда через 30, иногда через 60 и даже через 180 секунд.

Я не знаю, в чем причина этой проблемы, что я могу сделать, чтобы ее исправить. Любая помощь приветствуется (Я использую Arduino Nano 33 IOT)

Спасибо!

Вот мой код ниже:

// Включенные библиотеки
#include <Arduino.h>
#include <Wire.h>

// Библиотеки, необходимые для датчиков VL53L4CD
#include <vl53l4cd_class.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <stdlib.h>

// Определения
#define DEV_I2C Wire
#define SerialPort Serial

// переменные
int alternate = 0; // Переменная, используемая для переключения между наборами датчиков

// Компоненты.
VL53L4CD sensor_vl53l4cd_1(&DEV_I2C, 2); // xshut контакт датчика расстояния 1, подключенный к контакту 2
VL53L4CD sensor_vl53l4cd_2(&DEV_I2C, 3); // xshut контакт датчика расстояния 2, подключенный к контакту 3
VL53L4CD sensor_vl53l4cd_3(&DEV_I2C, 5); // xshut контакт датчика расстояния 3, подключенный к контакту 5
VL53L4CD sensor_vl53l4cd_4(&DEV_I2C, 6); // xshut контакт датчика расстояния 4, подключенный к контакту 6

/* Setup ---------------------------------------------------------------------*/

void setup()
{
  // НАСТРОЙКА ДАТЧИКА РАССТОЯНИЯ
  // Инициализировать серийный номер для вывода.
  SerialPort.begin(9600);
  SerialPort.println("Starting...");

  // Инициализировать шину I2C.
  DEV_I2C.begin();

  // Настроить VL53L4CD номер 1
  Serial.println("Configuring distance sensor 1");
  sensor_vl53l4cd_1.begin();
  sensor_vl53l4cd_1.VL53L4CD_Off();
  sensor_vl53l4cd_1.InitSensor();
  sensor_vl53l4cd_1.VL53L4CD_SetI2CAddress(0x40);
  sensor_vl53l4cd_1.VL53L4CD_SetRangeTiming(10, 0);

  // Настроить VL53L4CD номер 2
  Serial.println("Configuring distance sensor 2");
  sensor_vl53l4cd_2.begin();
  sensor_vl53l4cd_2.VL53L4CD_Off();
  sensor_vl53l4cd_2.InitSensor();
  sensor_vl53l4cd_2.VL53L4CD_SetI2CAddress(0x42);
  sensor_vl53l4cd_2.VL53L4CD_SetRangeTiming(10, 0);

  // Настроить VL53L4CD номер 3
  Serial.println("Configuring distance sensor 3");
  sensor_vl53l4cd_3.begin();
  sensor_vl53l4cd_3.VL53L4CD_Off();
  sensor_vl53l4cd_3.InitSensor();
  sensor_vl53l4cd_3.VL53L4CD_SetI2CAddress(0x44);
  sensor_vl53l4cd_3.VL53L4CD_SetRangeTiming(10, 0);

  // Настроить VL53L4CD номер 4
  Serial.println("Configuring distance sensor 4");
  sensor_vl53l4cd_4.begin();
  sensor_vl53l4cd_4.VL53L4CD_Off();
  sensor_vl53l4cd_4.InitSensor();
  sensor_vl53l4cd_4.VL53L4CD_SetI2CAddress(0x46);
  sensor_vl53l4cd_4.VL53L4CD_SetRangeTiming(10, 0);

  // Начать измерения
  sensor_vl53l4cd_1.VL53L4CD_StartRanging();
  sensor_vl53l4cd_2.VL53L4CD_StartRanging();
  sensor_vl53l4cd_3.VL53L4CD_StartRanging();
  sensor_vl53l4cd_4.VL53L4CD_StartRanging();
}

void loop()
{
  // Чтение результатов с набора датчиков 1
  if (alternate == 0){ 
    VL53L4CD_Result_t results2;
    VL53L4CD_Result_t results3;

    // Чтение результатов с набора датчиков 1 (датчики 2 и 3)
    sensor_vl53l4cd_2.VL53L4CD_ClearInterrupt();
    sensor_vl53l4cd_2.VL53L4CD_GetResult(&results2);
    sensor_vl53l4cd_3.VL53L4CD_ClearInterrupt();
    sensor_vl53l4cd_3.VL53L4CD_GetResult(&results3);
    
    Serial.print("Distance 1-1 = ");
    Serial.print(results2.distance_mm);
    Serial.println(" ");
    Serial.print("Distance 1-2 = ");
    Serial.print(results3.distance_mm);
    Serial.println(" ");
    
    alternate = 1; // Изменить значение, чтобы набор датчиков 2 считывался в следующем цикле
  }
  
  // Чтение результатов с набора датчиков 2
  else if (alternate == 1){ 
    VL53L4CD_Result_t results1;
    VL53L4CD_Result_t results4;

    // Чтение результатов с набора датчиков 1 (датчики 1 и 4)
    sensor_vl53l4cd_1.VL53L4CD_ClearInterrupt();
    sensor_vl53l4cd_1.VL53L4CD_GetResult(&results1);
    sensor_vl53l4cd_4.VL53L4CD_ClearInterrupt();
    sensor_vl53l4cd_4.VL53L4CD_GetResult(&results4);
    
    Serial.print("Distance 2-1 = ");
    Serial.print(results1.distance_mm);
    Serial.println(" ");
    Serial.print("Distance 2-2 = ");
    Serial.print(results4.distance_mm);
    Serial.println(" ");
    
    alternate = 0; // Изменить значение, чтобы набор датчиков 2 считывался в следующем цикле
   }
   Serial.println(millis());
}

, 👍-1

Обсуждение

Я не знаком с дисками VL53L4CD, но чтобы мы могли вам помочь, не могли бы вы привязать библиотеку, которую вы использовали в посте (и ссылка на техническое описание тоже не помешает)? Кроме того, как добавление датчиков помогает с частотой дискретизации? Моя догадка здесь состоит в том, чтобы сказать, что вы можете переполнить свой буфер I2C, но я советую сначала протестировать один датчик, затем набор датчиков, и ЕСЛИ он работает нормально, я бы снова начал смотреть на два набора и думать о более сложном реализация управления потоком. Знаете ли вы, сколько данных каждый датчик (не установленный!) предоставляет за одно считывание? Кроме того, попробуйте увеличить скорость передачи данных., @Nick S.

Вы можете увеличить скорость передачи, чтобы уменьшить вероятность переполнения последовательного буфера. Работает ли он без всей печати (используйте светодиод для отладки-мигания)?, @Tarabas

Добавление к комментарию @datenheim: при скорости 9600 бод вы можете передавать не более 1000 байт в секунду. При частоте дискретизации 100 Гц, равной периоду 10 мс, возможно только от 9 до 10 символов на выборку. -- Однако виртуальное последовательное соединение через USB намного быстрее. Установленная скорость имеет значение только в том случае, если хотя бы на одном конце задействована реальная последовательная линия. При использовании вашего ПК и встроенного USB-модуля Arduino это не так, насколько я знаю., @the busybee

В любом случае, поскольку в предоставленном скетче у вас нет контроля времени, я не понимаю, как последовательный буфер может переполниться. Все методы печати должны блокироваться, если их буфер заполнен. Таким образом, ваша петля рассчитана по скорости последовательной передачи., @the busybee

Чтобы уменьшить проблему, уменьшите свой скетч до чего-то, что печатается только в цикле. Если это работает долго без проблем, это не печать. Затем сделайте то же самое только с показаниями датчика. [Изменить] свой вопрос и добавить выводы, пожалуйста., @the busybee

Всем привет, спасибо за ответы и предложения. @Ник, что касается частоты дискретизации каждого датчика, максимальная частота дискретизации каждого датчика составляет 100 Гц. Однако при такой высокой частоте дискретизации показания весьма неточны. Идея состоит в том, чтобы настроить датчик для работы на несколько более низкой частоте, чтобы повысить точность, и, используя два набора датчиков, я могу считывать показания одного набора датчиков, пока другой набор измеряет, таким образом увеличивая частоту дискретизации при сохранении точности ( по крайней мере, так предложил мой руководитель FYP). Я также отредактировал свой пост, чтобы включить то, что я пробовал до сих пор., @Jin Yuan

Прямо сейчас я подозреваю, что это может быть связано с тем, что порт USB на моем ноутбуке не может обеспечить требуемый ток. Я где-то читал, что порт USB на ноутбуках обеспечивает только 100 миллиампер? Согласно техническому описанию, пиковый ток датчика может достигать максимум 40 мА. Может быть, поэтому я могу использовать максимум два датчика, прежде чем проблема проявит себя?, @Jin Yuan

@JinYuan Я сомневаюсь, что это ноутбук, поскольку обычно порты USB могут обеспечивать до 500 мА, чего должно быть достаточно для вашего Arduino и датчиков. Я не уверен, что именно происходит в данный момент, но ваш поток управления должен быть немного другим; вы можете либо использовать функцию STM VL53L4CD_CheckForDataReady(), либо фактически создавать экземпляры прерываний для всех 4 датчиков и обрабатывать их как наборы с заданным интервалом. Я не думаю о 100 Гц как о высокой частоте дискретизации, поскольку ваш цикл, вероятно, работает в 100 раз быстрее, чем это ... ну, или, по крайней мере, мог бы, поскольку я не знаю, блокируют ли эти функции. нет., @Nick S.

@JinYuan Вы также можете использовать библиотеку Adafruit, а также попробовать подключить набор датчиков (два датчика) из источника, отличного от вашего ноутбука. Если у вас есть логический анализатор, вы можете установить его, чтобы увидеть, как происходит передача данных, когда все 4 подключены одновременно., @Nick S.

@НикС. Я попытался запитать все датчики от внешнего источника, и это, похоже, решило проблему. Я постоянно получал все показания расстояния, и последовательный порт не прекращал прием данных., @Jin Yuan

@JinYuan звучит хорошо, тогда вы должны опубликовать свой собственный ответ! Кроме того, от USB-порта ноутбука зависит, какую мощность он может обеспечить - некоторые действительно ограничены только 500-750 мВт (или 100-150 мА), в то время как другие могут обеспечивать до 1,5 А (порты зарядки) . Тем не менее, немного странно, что вы увидели проблему такой, какой вы ее видели, поскольку Nano 33 должен потреблять в среднем около 50-60, если не около 100 мА, сам по себе (что зависит от того, используете ли вы BLE/BT/WiFi и как ), но эй, если это работает, то работает!, @Nick S.


1 ответ


Лучший ответ:

1

Я попытался подключить все датчики к внешнему источнику питания, и это, кажется, решило проблему, я получил согласованные показания со всех датчиков расстояния, а последовательный порт не переставал получать данные. Возможно, эти проблемы были вызваны портом USB на моем ноутбуке.

,