Использование software serial на Arduino Mega

Итак, я использую этот датчик: https://wiki.dfrobot.com/Serial_6_Axis_Accelerometer_SKU_SEN0386 с этой библиотекой https://github.com/DFRobotdl/DFRobot_WT61PC

Я использую 2 датчика, но у меня плохая частота на Arduino Uno, и я решил переключиться на Mega, так как он поддерживает несколько соединений одновременно.

Этот код отлично работает на Uno, но не на Mega. Конечно, я пытался использовать этот метод: https://docs.arduino.cc/built-in-examples/ Communication/MultiSerialMega, и я знаю, что не должен использовать Software Serial на Mega, но эта библиотека была написана с использованием Software Serial, и я не могу использовать другой метод (по крайней мере, я так это понимаю ).

Вот причина.

SoftwareSerial mySerial(10, 11);
DFRobot_WT61PC sensor(&mySerial);

Поэтому я попробовал несколько вариантов выводов (с поддержкой UART, pcint, TX/RX) https ://docs.arduino.cc/learn/built-in-libraries/software-serial и кажется, что ничего не работает. Также попытался удалить устройство чтения SD-карт, попробовал исходный код примера. Я также попробовал аппаратный серийный номер, как и должно быть, но опять же, он не поддерживает этот датчик и в конечном итоге приводит к ошибкам (или наоборот). Ничего.

Вот рабочий код Uno:

#include <DFRobot_WT61PC.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>

#define FILE_BASE_NAME "Pomiar"
#define VCC2 7

const uint8_t CS_PIN = 4;

SoftwareSerial mySerial(2, 3);
SoftwareSerial mySerial2(5, 6);
DFRobot_WT61PC sensor(&mySerial);
DFRobot_WT61PC sensor2(&mySerial2);


File myFile;
File file;

const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
char fileName[] = FILE_BASE_NAME "00.txt";

void setup()
{

  pinMode(VCC2,OUTPUT);
  digitalWrite(VCC2,HIGH);

  //Используем Serial как отладочный последовательный порт
  Serial.begin(9600);
  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

  while (SD.exists(fileName)) {
    if (fileName[BASE_NAME_SIZE + 1] != '9') {
      fileName[BASE_NAME_SIZE + 1]++;
    } else if (fileName[BASE_NAME_SIZE] != '9') {
      fileName[BASE_NAME_SIZE + 1] = '0';
      fileName[BASE_NAME_SIZE]++;
    } else {
      Serial.println(F("Can't create file name"));
      return;
    }
  }

  
  // Использовать программный последовательный порт mySerial в качестве последовательного порта связи
  mySerial.begin(9600);
  mySerial2.begin(9600);
  // Измените частоту вывода данных датчика FREQUENCY_0_1HZ для 0,1 Гц, FREQUENCY_0_5HZ для 0,5 Гц, FREQUENCY_1HZ для 1 Гц, FREQUENCY_2HZ для 2 Гц,
  // FREQUENCY_5HZ для 5 Гц, FREQUENCY_10HZ для 10 Гц, FREQUENCY_20HZ для 20 Гц, FREQUENCY_50HZ для 50 Гц,
  // FREQUENCY_100HZ для 100 Гц, FREQUENCY_125HZ для 125 Гц, FREQUENCY_200HZ для 200 Гц.
  sensor.modifyFrequency(FREQUENCY_10HZ);
  sensor2.modifyFrequency(FREQUENCY_10HZ);
}


void loop()
{

  long timestamp = millis();

  float acc1;
  float acc2 ;
  float acc3 ;
  float gyro1 ;
  float gyro2 ;
  float gyro3;
  float angle1;
  float angle2;
  float angle3;

  float acc12 ;
  float acc22 ;
  float acc32 ;
  float gyro12;
  float gyro22 ;
  float gyro32 ;
  float angle12 ;
  float angle22;
  float angle32;
  
  mySerial.listen();
  if (sensor.available()) {
    
    acc1 = sensor.Acc.X;
    acc2 = sensor.Acc.Y;
    acc3 = sensor.Acc.Z;
    gyro1 = sensor.Gyro.X;
    gyro2 = sensor.Gyro.Y;
    gyro3 = sensor.Gyro.Z;
    angle1 = sensor.Angle.X;
    angle2 = sensor.Angle.Y;
    angle3 = sensor.Angle.Z;
    
  }

  mySerial2.listen();
  if (sensor2.available()) {
    
    acc12 = sensor2.Acc.X;
    acc22 = sensor2.Acc.Y;
    acc32 = sensor2.Acc.Z;
    gyro12 = sensor2.Gyro.X;
    gyro22 = sensor2.Gyro.Y;
    gyro32 = sensor2.Gyro.Z;
    angle12 = sensor2.Angle.X;
    angle22 = sensor2.Angle.Y;
    angle32 = sensor2.Angle.Z;

  }

  myFile = SD.open(fileName, FILE_WRITE);

  if (myFile) {
    myFile.print(timestamp);
    myFile.print("|");
    myFile.print(acc1);
    myFile.print("|");
    myFile.print(acc2);
    myFile.print("|");
    myFile.print(acc3);
    myFile.print("|");
    myFile.print(gyro1);
    myFile.print("|");
    myFile.print(gyro2);
    myFile.print("|");
    myFile.print(gyro3);
    myFile.print("|");
    myFile.print(angle1);
    myFile.print("|");
    myFile.print(angle2);
    myFile.print("|");
    myFile.print(angle3);
    myFile.println("");

    myFile.print(timestamp);
    myFile.print("|");
    myFile.print(acc12);
    myFile.print("|");
    myFile.print(acc22);
    myFile.print("|");
    myFile.print(acc32);
    myFile.print("|");
    myFile.print(gyro12);
    myFile.print("|");
    myFile.print(gyro22);
    myFile.print("|");
    myFile.print(gyro32);
    myFile.print("|");
    myFile.print(angle12);
    myFile.print("|");
    myFile.print(angle22);
    myFile.print("|");
    myFile.print(angle32);
    myFile.println("");
    
    myFile.close();
  } else {
    Serial.println("error opening test.txt");
  }
}

Я также нашел этот вопрос: Software Serial Arduino Mega 2560 не работает. У парня такая же проблема, как и у меня, но никто не нашел ее решения. Также хочу отметить, что производитель заявляет, что данная библиотека и сенсор отлично работают на Меге. Очень нужна ваша помощь.

ура

@изменить Итак, я провел несколько тестов, и единственный код, который действительно показывает что-то на мониторе:

#include <DFRobot_WT61PC.h>

DFRobot_WT61PC sensor(&Serial);

void setup()
{
  //Используем Serial как отладочный последовательный порт
  
  // Использовать программный последовательный порт mySerial в качестве последовательного порта связи
  Serial.begin(9600);
  sensor.modifyFrequency(FREQUENCY_10HZ);
}


void loop()
{
  if (sensor.available()) {
    Serial.print("Acc\t"); Serial.print(sensor.Acc.X); Serial.print("\t"); Serial.print(sensor.Acc.Y); Serial.print("\t"); Serial.println(sensor.Acc.Z); //информация об ускорении X,Y,Z
    Serial.print("Gyro\t"); Serial.print(sensor.Gyro.X); Serial.print("\t"); Serial.print(sensor.Gyro.Y); Serial.print("\t"); Serial.println(sensor.Gyro.Z); //информация об угловой скорости X,Y,Z
    Serial.print("Angle\t"); Serial.print(sensor.Angle.X); Serial.print("\t"); Serial.print(sensor.Angle.Y); Serial.print("\t"); Serial.println(sensor.Angle.Z); //информация об углах X, Y, Z
    Serial.println(" ");
  }
}

монитор Но, как вы видите, вывод поврежден.

, 👍1

Обсуждение

Когда вы можете предоставить серийный экземпляр библиотеке для использования, тогда он написан не только для SoftwareSerial. Пожалуйста, покажите, как вы пытались с HardwareSerial и получающимися ошибками, @chrisl

Цитата из [SoftwareSerial Library](https://docs.arduino.cc/learn/built-in-libraries/software-serial): «**Не все контакты на платах Mega и Mega 2560 поддерживают прерывания изменения, поэтому только для RX можно использовать: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66). ), A13 (67), A14 (68), A15 (69)**", ваш код не использует эти контакты., @hcheung

@hcheung Я попробовал их, код, который я предоставил, рабочий код для uno, так что есть доказательства, что я нигде не ошибся, @Aivion2000

Также я взглянул на библиотеку, которую вы упомянули, нет причин, по которым HardwareSerial не работает, если это вызывает ошибки, это что-то еще, возможно, неправильно создает экземпляры Serial1 или Serail2., @hcheung

Если у вас проблемы с Mega, показывает код, который не работает в Mega, а не код, который работает в Uno., @hcheung

@hcheung Как я могу инициализировать серийный номер, когда мне сначала нужно инициализировать датчик? И предоставление аппаратного серийного номера датчику DFRobot_WT61PC(&mySerial); функция вызывает ошибки, @Aivion2000

Покажите код, который не работает, а не код, который работает. Как это поможет?, @Nick Gammon

Ну, код, который не работает, точно такой же @NickGammon, @Aivion2000

Как датчик подключен к Меге?, @chrisl

Как сказал hcheung, SoftwareSerial на Mega не поддерживает контакты 2, 3, 5, 6, поэтому я не понимаю, как вы можете ожидать, что он будет работать., @Nick Gammon

Какие контакты я должен использовать, чтобы заставить его работать?, @Aivion2000

По возможности избегайте SoftwareSerial. Он очень хрупок: есть так много способов, которыми он может сломать ваш код... Он может быть полезен на Uno только потому, что на этой плате у вас мало выбора. Однако Mega имеет **четыре** аппаратных последовательных порта. SoftwareSerial на Меге вообще не имеет смысла., @Edgar Bonet

@EdgarBonet, как мне тогда использовать эту библиотеку?, @Aivion2000

@ Aivion2000: используйте «Serial1», «Serial2» или «Serial3» вместо «mySerial»., @Edgar Bonet


2 ответа


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

0

Это быстро и грязно, но вы можете сделать его совместимым с Mega, удалив строку #include <SoftwareSerial.h> и заменив строки

SoftwareSerial mySerial(2, 3);
SoftwareSerial mySerial2(5, 6);

с

#define mySerial Serial1
#define mySerial Serial2

замените Serial1 и Serial2 на любой из последовательных портов Mega, которые вы хотите использовать для mySerial и mySerial2, и подключите сигналы датчика DFRobot к правильным контактам для выбранного вами аппаратные последовательные порты.

,

Спасибо, король, это сработало, также мы подключили tx к rx и rx к tx. Мы не знаем, почему это работает, но это так., @Aivion2000


0

В вашем коде есть три довольно серьезные проблемы:

  • Mega не поддерживает SoftwareSerial на контактах 2, 3, 5, 6, поскольку эти контакты не поддерживают прерывания изменения. Таким образом, он просто не может работать на этих контактах. Это само по себе останавливает шоу.

  • В вашем коде для чтения данных есть ошибка. Вы проверяете, доступен ли один байт (sensor.available()), а затем переходите к чтению 9 байтов. Нет никакой гарантии, что 8 из них на самом деле там.

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

,

Я использовал пример из этой библиотеки, в коде ничего не менял, только так инициализирую датчик. Я не знаю, как использовать сенсор. Доступно по-разному., @Aivion2000

+ с сенсора всегда выходит 9 байт, мы тестировали на Uno и он работал отлично, почему на Mega сенсор работает по другому?, @Aivion2000

Байты не выходят мгновенно. Они занимают **время**. Если вы проверяете 1 байт, вы не можете гарантировать получение 9 байтов. Попробуйте изменить на if (sensor.available() >= 9)., @Nick Gammon

*почему датчик работает по-другому на Mega* - **потому что он не поддерживает эти контакты**. Сколько раз нам нужно сделать это?, @Nick Gammon

Вы игнорируете наиболее вероятное объяснение вашей проблемы., @Nick Gammon

Но я перепробовал все возможные комбинации контактов, а не только 2,3 или 5,6., @Aivion2000

Вы сказали: «Ну, код, который не работает, точно такой же» — не совсем так, если вы пробовали разные комбинации контактов, а? Покажите код, в котором используются поддерживаемые контакты., @Nick Gammon