Имеется Arduino Pro Micro (на Atmega32u4 которая) и модуль SIM800L, а конкретнее - тот, который красный.
Модулю, как известно, нужно питание от 3.3 до 4.4 В.
5 В по моему опыту тоже вроде годится (точно помню, что модуль стартует, мигает светодиодом, ничего не сгорает)
Но питать его от стабилизатора ардуины нельзя, он прожорливый (говорят, до 2 А). Да и нету в Pro Micro никакого стабилизатора.
Ну и от питания самой ардуины (в т.ч. USB компа при программировании) тоже не стоит питать, 2 А для USB это предел, а еще и сама ардуина же что-то кушает.
А питать его нужно от литиевого элемента, на что он и рассчитан.
И в этом даже есть свой плюс: модуль поддерживает команду AT+CBC, которая позволяет определить уровень заряда аккумулятора, в процентах и в милливольтах!
Весьма полезная функция для автономных устройств, чтобы делать индикацию уровня, защитное отключение\предупреждение и т.п.
Но тут и начинаются проблемы.
Вот я запитываю модуль от аккумулятора, подключаю его к ардуине:
GND -> GND
TX модуля -> RX ардуины (любой пин, на котором есть прерывания, см. документацию SoftwareSerial; в моем примере
TX ардуины (вообще любой D-пин) -> RX модуля через равноплечий делитель на 2.2 кОм резисторах, чтобы 5 В понижалось до 2.5
Вот такой код:
- Код:
#include <SoftwareSerial.h>
SoftwareSerial sim(8, 9); // RX, TX
bool firstSIMCommand = true;
String sendSIMCommand(String cmd) {
sim.println(cmd);
delay(100);
auto start = millis();
while (!sim.available()) {
auto now = millis();
if (now - start >= 500) {
Serial.println("(SIM timeout)");
return "";
}
}
if (firstSIMCommand) { // TODO: It removes \0 because it do not allows use indexOf() But why this \0 appears here?
sim.read();
firstSIMCommand = false;
}
auto res = sim.readString();
auto newLine = res.indexOf("\n");
res.remove(0, newLine + 1);
res.trim();
return res;
}
void setup() {
Serial.begin(9600);
while (!Serial) ; // Arduino Pro Micro / Leonardo
Serial.println("Start!");
sim.begin(9600);
auto res = sendSIMCommand("AT");
if (res == "OK") {
Serial.println("SIM check OK");
} else {
Serial.println("SIM check failed, response for AT:");
Serial.println(res);
}
res = sendSIMCommand("AT+CBC");
Serial.println(res);
res = sendSIMCommand("AT+COPS?");
Serial.println(res);
}
void loop() {
if (sim.available())
Serial.write(sim.read());
if (Serial.available())
sim.write(Serial.read());
}
И все работает.
Кроме одного. Когда ардуина отключена от USB, на ней слегка светится красный светодиод питания. То есть ардуина запитывается от модуля, несмотря на то что питание вообще-то у него отдельное. И когда я ее в таком состоянии подключаю к БП 5 В (зарядке от телефона), то она не стартует. Ведь она как бы уже была включена. И не ресетится она. А работает, только когда подключаю именно к USB-разъему компьютера
Рисуется невзрачная картина. Получается в тех самых автономных устройствах мы должны модули SIM800L держать отключенными, а включает их пусть уже сама ардуина, например через релюшку? (почему-то мне нравятся 5-вольтовые электромагнитные релюшки и втыкать их тупо с D-пинов на землю, без всяких защитных диодов, и все это работает, проблем не встречал)
Чтобы они не мешали ей запуститься?
Но это плохо как минимум тем, что создает лишнее потребление, а ведь SIM800L и так прожорлив, вроде как. И занимает лишний пин, а пины в сложных системах на вес золота) У меня например будут заняты абсолютно все, какие только есть, кроме 3 аналоговых входов.
Можно ли как-то еще решить проблему?
Добавлено after 7 hours 22 minutes 9 seconds:Разобрался. Проблема в
- Код:
while (!Serial) ; // Arduino Pro Micro / Leonardo
которая добавляется на этих ардуинах для того чтобы Serial.println мог сразу в setup работать
Это странно, вообще-то у меня еще другой тест был, где все то же самое, но SIM800L запитывался не от аккума, а от отдельного БП с 5 вольтами. И там я это реально ловил. Возможно из-за того что подавал на модуль не 4.4 В, а 5, тогда ведь и "обратки" будет приходить больше вольт, если она вообще есть.
Ну а что касается до while !Serial, то хорошо бы разобраться с debug-режимами у ардуины и ее IDE, чтобы оно умело отличать запуск "под дебагом" (имею в виду любой запуск когда подключено по USB и будет COM-порт) и запуск когда только питание есть, а COM-порта и не должно быть.
Как вариант просто таймаутить этот while ))