Серийный порт не инициализируется на Arduino Mega 2560, если питание не подается через порт USB.

Я работаю над проектом с Mega 2560 и модулем Sim800L.

Все работает нормально, однако, если я не подключаю USB-порт (хотя бы один раз) и питаюсь только от внешнего источника (либо через нерегулируемый 7-12 В, либо через регулируемый контакт 5 В) программа не инициализирует серийный номер в setup().

Я нашел это, связанное с проблемой, но не подходящее решение: https://forum.arduino.cc/index.php?topic=24642.0

редактировать: я могу подтвердить, что использование резистора для замыкания контактов 0 + 1 вместе (последовательный) работает, но это не правильное решение. Это означает, что вам нужно разобрать проект, чтобы получить доступ к резистору, или добавить переключатель, если вы хотите использовать USB для последующей отладки или загрузки нового кода. Еще один обходной путь, который мне нужно протестировать, — удалить весь последовательный код (потому что я могу это сделать в своем конкретном проекте), но опять же это не правильное решение. Есть идеи?

редактировать2: для комментариев

if(SIM900.available()>0){
// AT-команда для перевода SIM900 в режим SMS
SIM900.print("AT+CMGF=1\r"); 
delay(100);
// Установите модуль для отправки данных SMS на серийный номер после получения
SIM900.print("AT+CNMI=2,2,0,0,0\r");
delay(100);
textMessage = SIM900.readString();
textMessage.toUpperCase();
Serial.print(textMessage);    
delay(10);
} 

if(textMessage.indexOf("SET PHONE")>=0){
// Установить номер телефона для получения уведомлений
phoneNumber = textMessage.substring(9,21);
Serial.println("Phone number set to: " + phoneNumber);  
String message = "Notification number set to: " + phoneNumber + "\nSend 'Help' for additional commands.\nNote in case of reset number returns to hardcoded default";
sendSMS(message);
Serial.println("Confirmication of phone number change sent");
textMessage = "";   
}

, 👍0

Обсуждение

так почему тег softwareserial? Sim800 находится на Serial1/2/3? Вы используете старую версию ядра AVR или IDE?, @Juraj

Этой ссылке 13 лет, и в последнее время я не слышал об этом трюке с выводом 0/1. У вас есть такая старая плата Arduino? Вы уверены, что USB-контроллер (ATmega16U2?) не получает Vcc HIGH через Vin?, @DataFiddler

Вы не предоставили никакого кода, поэтому мы должны угадать. Вы печатаете на серийный терминал на вашем ПК/ноутбуке в Sketch. Если вы не подключаете Arduino к ПК, вы не устанавливаете последовательное соединение с терминалом. Возможно, вы добавили блокирующую команду, ожидающую соединения. Соединение Pin0 и Pin1 имитирует терминальное подключение, и код блокировки не блокирует. Если я прав, решением будет удаление кода блокировки. Но я не знаю кода, поэтому не могу сказать, как,, @Peter Paul Kiefer

@juraj Потому что я использую softwareserial для подключения к sim800. Я преобразовал его в аппаратный серийный номер в качестве теста, и он работает, но требует дополнительных изменений., @TnF

@DataDiffler Моя плата не старая, я могу проверить, так ли это, @TnF

@Peter Paul Kiefer Да, я печатаю без проверок. Некоторые части кода в цикле работают, поэтому мне не нужны проверки. На самом деле часть, которая, кажется, не работает, проверяет программный последовательный буфер, а не последовательный, поэтому я не думаю, что есть какая-либо блокировка. Вот пример нерабочей части кода (не отлаживал, если оба блока не работают):, @TnF

Меня больше интересует способ установки. Где находится «Serial.begin» и все места, где используется Serial. Возможно, в то время как ( ! Serial.available() ) или что-то еще. Можете ли вы переключить встроенный светодиод на ON в первом блоке if выше, чтобы увидеть, введен ли он вообще. И software serial также может остановить программу и дождаться соединения., @Peter Paul Kiefer

Ничего особенного, кроме установки начальных значений и выводов, просто Serial.begin(57600); и SIM900.begin(57600);. Я мог бы использовать while (! Serial); каждый раз, когда я хочу печатать, но я считаю, что это не работает на Mega, верно?, @TnF

@DataFiddler Проверено (у меня их 2), оба являются клонами, использующими C340G вместо ATmega16U2 для UART-USB, и они нормально питаются. Проблема в том, что если у меня есть функции serial.print, кажется, что программа не может нормально работать, если не подключен последовательный порт. Функции внутри программы, в которых нет кода serial.print (например, функция sendsms), работают нормально, и цикл продолжает работать., @TnF

никогда не используйте SoftwareSerial на Mega (это не причина вашей проблемы, а только то, что не имеет смысла), @Juraj

ATmega2560 не знает, подключен ли USB. он отправляет данные и не заботится о том, что с ними происходит. нет управления потоком UART, чтобы заблокировать передачу., @Juraj

@juraj да, я уже преобразовал его сегодня, чтобы использовать аппаратный серийный номер, я просто использовал программный серийный номер, так как знал, что он должен работать на 100%. Я знаю, что mega2560 не знает, подключен ли usb, но я не знаю, почему serial.print сломает программу, если она ни к чему не подключена. Говорят, это потому, что контакт RX0 плавает, когда он не подключен. Так есть ли способ сохранить serial.print внутри кода и игнорировать его, когда он не подключен?, @TnF

Я думаю, что знаю решение bodge. Подключите контакт DTR к одному из цифровых входов и прочитайте его, когда я хочу печатать последовательно., @TnF

RX и TX ATmega2560 подключены к RX и TX чипа USB, и это соединение активно. нет плавающих булавок, @Juraj

@Juraj После нескольких проверок с отключенным серийным номером и запущенными функциями, чтобы проверить, открыт или закрыт DTR, я обнаружил, что проблема не в этом. Опубликовано объяснение и ответ ниже!, @TnF


1 ответ


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

1

Хорошо, я нашел проблему и решение.

По какой-то причине кажется, что пока на MCU работает Setup(); серийный номер аппаратного или программного обеспечения не работает должным образом.

В моем случае у меня есть код, который переводит SIM-модуль в режим SMS и отправляет эти сообщения на последовательный порт.

По какой-то причине он их не отправляет (или, возможно, модуль не готов их принять).

Подключение USB-кабеля сбрасывает Arduino и запускает setup() при открытии последовательного монитора, устанавливая модуль в правильном режиме.

Добавление этого кода в основной цикл решает эту проблему, несмотря на то, что я питаю их от одного и того же понижающего преобразователя.

изменить: через 1 час после отладки выяснилось, что это не совсем правильное решение проблемы. Эта команда для перехода в режим SMS работает только тогда, когда вы подключены к сети.

У меня есть проверка и функция сброса.

Итак, теперь в Setup() я жду 10 секунд, пока модуль загрузится, чтобы он был готов открыть последовательный порт, затем я проверяю, подключен ли он к сети, прежде чем отправлять команды для установки в режим SMS.

Пример:

// Инициализация последовательной связи
Serial.begin(57600); 
delay(10000);

while (ini){
    Serial3.begin(57600);
    delay(1000);
    Serial3.print("AT+CGREG?\r"); 
    delay(100);
    netStatus = Serial3.readString();
    if (netStatus.charAt(22) == '5' || netStatus.charAt(22) == '1') {
         digitalWrite(LED_NET, HIGH);
         ini=false;
         }
    else {  
        digitalWrite(LED_NET, LOW);
        digitalWrite(resetPin, LOW);
        delay(2000);
        digitalWrite(resetPin, HIGH);
        delay(30000);
        }
}
  Serial.print("SIM800 ready...");

  // AT-команда для перевода SIM800 в режим SMS
  Serial3.print("AT+CMGF=1\r"); 
  delay(100);
  // Установите модуль для отправки данных SMS на серийный номер после получения
  Serial3.print("AT+CNMI=2,2,0,0,0\r");
  delay(100);
,