Официальный сайт компании Arduino по адресу arduino.cc
Arduino M0 - программный интерфейс Serial (SERCOM) - не работает на пинах D3 и D4
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Всем доброго дня! Столкнулся с необходимостью инициализировать программный интерфейс Serial на Arduino M0 (библиотека SoftwareSerial на платах с 32-битными процессорами не работает). Имеющийся аппаратный интерфейс занят конвертером TTL-RS485, а подключить по интерфейсу SPI нужно еще один девайс - SIM800L.
Почитал ресурсы, еще почитал (тут именно про пины D3 и D4), и еще почитал. В результате получилось инициализировать Serial на пинах D11(RX) и D10(TX):
#include <Arduino.h> #include "wiring_private.h" // Библиотека даёт возможность изменения функций пинов МК (pinPeripheral() function) Uart SIM800L (&sercom1, 11, 10, SERCOM_RX_PAD_0, UART_TX_PAD_2); // Назначаем функции пинам МК: RX - pin D11 | TX - pin D10 String _response = ""; // Объявляем строковый массив для хранения ответов модуля SIM800L (функции sendATcommand и waitResponse) void setup() { SerialUSB.begin(57600); while (!SerialUSB) {}; // Ожидание инициализации com-порта SerialUSB.println(F("Start programm!")); SIM800L.begin(57600); pinPeripheral(10, PIO_SERCOM); // TX (Assign pins 10 & 11 SERCOM functionality) pinPeripheral(11, PIO_SERCOM); // RX (Assign pins 10 & 11 SERCOM functionality) sendATcommand("AT", true); // Автоопределение скорости обмена данными с модулем SIM800L } void SERCOM1_Handler() { SIM800L.IrqHandler(); } void loop() { if (SIM800L.available()) SerialUSB.println(waitResponse()); if (SerialUSB.available()) SIM800L.write(SerialUSB.read()); } String sendATcommand(String cmd, bool waiting) { String _resp = ""; SerialUSB.println(cmd); SIM800L.println(cmd); if (waiting) { _resp = waitResponse(); SerialUSB.println(_resp); } return _resp; } String waitResponse() { String _resp = ""; unsigned long _timeout = millis() + 10000; while (!SIM800L.available() && millis() < _timeout) {}; if (SIM800L.available()) { _resp = SIM800L.readString(); } else { SerialUSB.println(F("Timeout wait answer SIM800L is over!")); } return _resp; }
Этот код работает... При обращении к модулю SIM800L - возвращаются ответы от модуля.
При попытке инициализировать Serial на пинах D3(RX) и D4(TX) следующим образом:
#include <Arduino.h> #include "wiring_private.h" // Библиотека даёт возможность изменения функций пинов МК (pinPeripheral() function) Uart SIM800L (&sercom2, 3, 4, SERCOM_RX_PAD_1, UART_TX_PAD_0); String _response = ""; // Объявляем строковый массив для хранения ответов модуля SIM800L (функции sendATcommand и waitResponse) void setup() { SerialUSB.begin(57600); while (!SerialUSB) {}; // Ожидание инициализации com-порта SerialUSB.println(F("Start programm!")); SIM800L.begin(57600); pinPeripheral(4, PIO_SERCOM_ALT); // TX (Assign pins 10 & 11 SERCOM functionality) pinPeripheral(3, PIO_SERCOM_ALT); // RX (Assign pins 10 & 11 SERCOM functionality) sendATcommand("AT", true); // Автоопределение скорости обмена данными с модулем SIM800L } void SERCOM2_Handler() { SIM800L.IrqHandler(); } void loop() { if (SIM800L.available()) SerialUSB.println(waitResponse()); if (SerialUSB.available()) SIM800L.write(SerialUSB.read()); } String sendATcommand(String cmd, bool waiting) { String _resp = ""; SerialUSB.println(cmd); SIM800L.println(cmd); if (waiting) { _resp = waitResponse(); SerialUSB.println(_resp); } return _resp; } String waitResponse() { String _resp = ""; unsigned long _timeout = millis() + 10000; while (!SIM800L.available() && millis() < _timeout) {}; if (SIM800L.available()) { _resp = SIM800L.readString(); } else { SerialUSB.println(F("Timeout wait answer SIM800L is over!")); } return _resp; }
Этот вариант кода при обращении к модулю SIM800L возвращает превышение таймаута ожидания ответа от модуля "Timeout wait answer SIM800L is over!".
Кто "копал" SERCOM и M0 - подскажите куда копать в какую сторону? Пины D11 и D10 использовать не могу - на них висит SPI и SD-Card Module, помогите советом кто в теме, буду очень признателен!!!
В общем и целом разобрался. Скорее всего, тему поднял не в соответсвующей ветке форума. Для кого интересно... Использовать можно sercom1, sercom2, sercom3, sercom4. Использовать sercom0 и sercom5 неполучиться, т.к. они задействованы аппаратно и обратный вызов не возможен - компиляция не проходит из-за ошибки оверхеда. Приведу пример для пинов D7(RX) и D6(TX):
Аналогично работает на остальных пинах, с вышеуказанными sercom'и.