Ошибка низкой мощности при последовательном соединении

Поэтому я хочу создать приложение, в котором я могу отправлять данные с помощью SIM-модуля, а когда он не нужен, он должен переходить в «режим ожидания», потому что он питается от батареи. Но я всегда получаю именно этот результат, и я понятия не имею, почему:

wakeup condition fulfilled
Tes

Когда он хочет распечатать "Тестирование...", он всегда останавливается после трех букв.

Вот мой код:

/*      
 *  PINOUT: 
 * 
 *  UNO >> SIM800L
 *  RX (8) >> TX
 *  TX (9) >> RX
 *
*/

#include <BareBoneSim800.h>

BareBoneSim800 sim800("hologram"); //APN оператора


void sendData(char *url)
{
  sim800.enterSleepMode(false);
  Serial.println("Testing GSM module For GPRS Connectivity");
  delay(8000); // эта задержка необходима, она помогает устройству подготовиться и подключиться к сети


  Serial.println("Should be ready by now");
  bool deviceAttached = sim800.isAttached();
  if (deviceAttached)
    Serial.println("Device is Attached");
  else
    Serial.println("Not Attached");

  // Подключение к сети GPRS APN
  Serial.println(" Connecting to APN");
  bool netConnect = sim800.gprsConnect();
  if (netConnect)
    Serial.println("Connected to Network");
  else
    Serial.println("An Error Occured");

  if (netConnect)
  {
    Serial.println("Making HTTP Get Request");
    String result = sim800.sendHTTPData(url);
    Serial.println("Received Info: ");
    Serial.println(result);

    Serial.println("Current time utc+0: ");
    Serial.println(sim800.getTime());
  }

  sim800.closeHTTP(); // отключаемся от сервера
  sim800.gprsDisconnect();
  sim800.enterSleepMode(true);
}

void wakingUp()
{
  //здесь идет измерение аппаратных прерываний
}

void setup()
{
  Serial.begin(9600);
  sim800.begin();

  while (!Serial)
    ;

  // Экономьте электроэнергию, записывая все цифровые входы/выходы в состояние LOW — обратите внимание, что контакты просто должны быть связаны тем или иным образом, не повреждайте устройства!
  for (int i = 0; i < 20; i++)
  {
    if (i != 8 && i != 9 && i != 2)
    {
      // контакт 2 предназначен для пробуждения ардуино от глубокого сна

      //pin 8 и 9 используются для подключения к сим модулю,
      //эти пины должны быть исключены из режима энергосбережения
      pinMode(i, OUTPUT);
    }
  }

  attachInterrupt(0, wakingUp, FALLING); // прерывание для пробуждения

  /*
      various flags for turning stuff down when not needed
based on this very good tutorial https://www.youtube.com/watch?v=urLSDi7SD8M

  */
  //НАСТРОЙКА СТОРОЖЕВОГО ТАЙМЕРА
  WDTCSR = (24);      //меняем enable и WDE - тоже сбрасывает
  WDTCSR = (33);      //только предделители - избавьтесь от бита WDE и WDCE
  WDTCSR |= (1 << 6); //включаем режим прерывания

  //Отключаем АЦП - не забудьте после пробуждения перевернуть обратно, если используете АЦП в своем приложении ADCSRA |= (1 << 7);
  //ADCSRA &= ~(1 << 7);

  //ENABLE SLEEP - это включает спящий режим
  SMCR |= (1 << 2); //режим отключения питания
  SMCR |= 1;        //включить сон

  //BOD DISABLE - это должно быть вызвано прямо перед инструкцией __asm__ sleep
  //MCUCR |= (3 << 5); //устанавливаем одновременно и BODS, и BODSE
  //MCUCR = (MCUCR & ~(1 << 5)) | (1<<6); //затем устанавливаем бит BODS и одновременно сбрасываем бит BODSE
  __asm__ __volatile__("sleep"); //в поточном ассемблере переходим в спящий режим
}

void loop()
{
  // ничего не делаем, вместо этого используем ISR
}

char targetURL[] = "http://www.example.com/restAPI/";

ISR(WDT_vect)
{
  // НЕ ЗАБЫВАЙТЕ ЭТО! Нужен для сторожевого таймера. Это вызывается после истечения времени ожидания сторожевого таймера - это функция прерывания, вызываемая после пробуждения.
  //todo, снова включить преобразование adc

  int halfHourCounter = 0; //30 минут => 225 интервалов по 8 секунд

  bool wakeUpCondition = (halfHourCounter % 225 == 0);

  if (wakeUpCondition)
  {
    Serial.println("wakeup condition fulfilled");
    //сброс счетчика
    halfHourCounter = 0;

    //ADCSRA |= (1 << 7); // снова включаем аналого-цифровое преобразование

    //... измеряем данные и отправляем :)
    sendData(targetURL);

    //ADCSRA &= ~(1 << 7); // снова отключить АЦП
  }
  else
  {
    Serial.println("wakeup condition not fulfilled");
  }

  halfHourCounter += 1;

} // прерывание сторожевого таймера

Я использую Arduino Uno в сочетании с оценочной платой SIM800L. Если я вызываю функцию sendData() без включенных резервных флагов, все работает нормально. И наоборот, если я вызываю только функцию печати для отладки со всеми включенными флагами режима ожидания

, 👍0

Обсуждение

Может ли ваша батарея обеспечить достаточный ток? Вы не указали, какой у вас аккумулятор и как он подключен, @chrisl

Верно! Извините, я забыл об этом. На данный момент я просто использую обычное USB-соединение для питания и чтения последовательного порта., @Cowboy_Patrick


1 ответ


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

1

Похоже, что модуль Sim800 потребляет слишком много тока, когда вы запускаете его снова. Напряжение падает, и Arduino/Sim800 перестает работать.

В этом техническом описании Sim800 указано, что он может потреблять до 2 А при отправке пакета. . Порт USB на компьютере может обеспечить до 500 мА, и вы можете получать от 200 мА до 1 А с контакта 5 В Arduino (в зависимости от версии, которую вы используете: старые Unos могут обеспечивать 200 мА, Uno r3 должен быть в состоянии обеспечить 1 А). Если вы будете потреблять слишком много тока через Arduino от USB, вы сожжете диод для выбора источника напряжения. Также вы можете спалить электронику USB-порта, если будете потреблять от него слишком много тока (хотя обычно порт должен отключаться, если вы это сделаете, и снова работать, если вы перезагрузите компьютер).

Вы должны обеспечить модуль Sim800 достаточным питанием, а не через Arduino. Для этого следует выбрать подходящий аккумулятор. Если вы не хотите использовать батарею на этом этапе, поскольку вы все еще проводите тестирование, вы можете использовать зарядное устройство USB для телефона, чтобы обеспечить достаточный ток.

,

Спасибо! попробую :), @Cowboy_Patrick