Xinyuan-LilyGO / LilyGO-T-A76XX

LilyGo A7670 A7608 SIM7672 series
MIT License
96 stars 42 forks source link

Making deep sleep work #53

Closed nlgranger closed 6 months ago

nlgranger commented 11 months ago

I cannot seem to be able to put the modem in sleep mode.

Are there any other actions to be taken that are specific to this board? Does the esp32 need to sleep as well?

Here is a micropython example of what I am doing:

import machine

dtr = machine.Pin(25, machine.Pin.OUT, pull=None, value=0)

modem = machine.UART(1)
modem.init(baudrate=115200, rx=27, tx=26, timeout=1000)

modem.write(b'\r\nAT\r\n')
while True:
    print(modem.readline())

modem.write(b'\r\nAT+CSCLK=1\r\n')
while True:
    print(modem.readline())

dtr.value(1)

Device info:

Manufacturer: INCORPORATED
Model: A7670E-LASE
Revision: A011B09A7670M7
A7670M7_B09V04_220225
lewisxhe commented 11 months ago

I can see from your code that dtr is given to LOW when it is initialized, and the dtr variable is given to IO12 later. Are you sure you are correct? To set the modem to sleep is to set DTR to HIGH and then send AT+CSCLK=1 I didn't write the sleep example for A7670, but you can refer to the sleep example for SIM7600, the method is the same https://github.com/Xinyuan-LilyGO/T-SIM7600X/blob/master/examples/sleep/sleep.ino

nlgranger commented 11 months ago

My example was a bad copy paste, I did not send the second dtr = Pin(... command.

Using the example from your link, my device reaches Check modem response . but never Modem is not respone ,modem has sleep !.

neuralprocessing commented 9 months ago

Hi ranger, did you solved the problem of putting the modem to deep sleep? I am following your approach to set the ESP GPIO to high after sending the AT command:

` modem.sendAT("+CSCLK=1"); if (1 == modem.waitResponse(100, GF("OK"))) { serialMon.println("SIM76770 deep sleep enabled"); }

pinMode(PIN_DTR, OUTPUT);
digitalWrite(PIN_DTR, LOW);
delay(10);
digitalWrite(PIN_DTR, HIGH);
delay(10);
gpio_hold_en((gpio_num_t)PIN_DTR);
gpio_deep_sleep_hold_en();`

I am afraid of a change in the V1.2 Schematic but have not been able, to prove it. The answer to this supposition might be written here: Schematic V1.2

nlgranger commented 9 months ago

Hi, I have not been able to make it work unfortunately. However pin 3 (DTR) of the A7670 chip itself receives 1.8V from the esp32 when I set pin 25 high, so the two seem properly connected.

neuralprocessing commented 9 months ago

Thanks, so it might be related to some more open tasks, which prevents to let the modem go to idle mode:

After setting the AT command “AT+CSCLK=1”, and then pulling up the DTR pin, Module will enter sleep mode when module is in idle mode. In sleep mode, the UART is unavailable.

nlgranger commented 9 months ago

No example online seems to mention that as a possible behavior. I did wait a long time but the modem never goes to sleep (keeps responding to commands such as AT).

neuralprocessing commented 9 months ago

No example online seems to mention that as a possible behavior. I did wait a long time but the modem never goes to sleep (keeps responding to commands such as AT).

I took it from here: A7672X_A7670X_Series_Hardware_Design_V1.03.pdf

At the bottom of Page 34 in Chapter: 3.3.2 RI and DTR Behavior

EDIT: As stated on this reply the additional USB Interface might draw some additional mA and therefore act as if the module is prevented from deep sleep - because if the USB is connected, it at least draws more power then it should. Although it seems to be in deep sleep.

Follow the thread, to read, that when it battery mode, it will work and the module goes to deep sleep and draws less power.

BTW the routine seems to work: ` void LILYGO::SIM7670::sleep() {

this->modem.sendAT("+CSCLK=1");
if (1 == modem.waitResponse(100, GF("OK")))
{
    this->serialMon.println("SIM76770 deep sleep enabled");
}
pinMode(PIN_DTR, OUTPUT);
digitalWrite(PIN_DTR, LOW);
delay(10);
digitalWrite(PIN_DTR, HIGH);
delay(10);
gpio_hold_en((gpio_num_t)PIN_DTR);
gpio_deep_sleep_hold_en();

delay(3000);

while (this->modem.waitResponse("OK") == 1)
{
    this->modem.sendAT();
    this->serialMon.println("Sleep not working!!");
}

this->serialMon.println("Enter esp32 goto deep sleep!");

esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, LOW);
delay(200);
esp_deep_sleep_start();

} `

nlgranger commented 9 months ago

Just checked with the following code, it still does not work.

/**
 * @file      sleep.ino
 * @author    Lewis He (lewishe@outlook.com)
 * @license   MIT
 * @copyright Copyright (c) 2023  Shenzhen Xin Yuan Electronic Technology Co., Ltd
 * @date      2023-05-24
 *
 */
#define TINY_GSM_MODEM_SIM7600
#define TINY_GSM_RX_BUFFER          1024 // Set RX buffer to 1Kb
#define SerialAT                    Serial1

// See all AT commands, if wanted
#define DUMP_AT_COMMANDS

#include <TinyGsmClient.h>

#define uS_TO_S_FACTOR      1000000ULL  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP       30          /* Time ESP32 will go to sleep (in seconds) */

#define UART_BAUD           115200

#define MODEM_RX            27
#define MODEM_TX            26
#define MODEM_PWRKEY        4
#define MODEM_DTR           32
#define MODEM_RI            33
#define MODEM_FLIGHT        25
#define MODEM_STATUS        34

#define SD_MISO             2
#define SD_MOSI             15
#define SD_SCLK             14
#define SD_CS               13

#define LED_PIN             12

#ifdef DUMP_AT_COMMANDS  // if enabled it requires the streamDebugger lib
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, Serial);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif

void setup()
{
    Serial.begin(115200); // Set console baud rate

    SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
    delay(100);
    /*
    The indicator light of the board can be controlled
    */
    pinMode(LED_PIN, OUTPUT);
    digitalWrite(LED_PIN, HIGH);

    if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TIMER) {
        /*
        MODEM_PWRKEY IO:4 The power-on signal of the modulator must be given to it,
        otherwise the modulator will not reply when the command is sent
        */
        Serial.println("Powering up modem !");
        pinMode(MODEM_PWRKEY, OUTPUT);
        digitalWrite(MODEM_PWRKEY, LOW);
        delay(1000);
        digitalWrite(MODEM_PWRKEY, HIGH);
        //Ton >= 100 <= 500
        delay(1000);
        digitalWrite(MODEM_PWRKEY, LOW);
        delay(1000);

        /*
        MODEM_FLIGHT IO:25 Modulator flight mode control,
        need to enable modulator, this pin must be set to high
        */
        pinMode(MODEM_FLIGHT, OUTPUT);
        digitalWrite(MODEM_FLIGHT, HIGH);

    } else {
        Serial.println("Wakeup modem !");

        // Need to cancel GPIO hold if wake from sleep
        gpio_hold_dis((gpio_num_t )MODEM_DTR);

        // Pull down DTR to wake up MODEM
        pinMode(MODEM_DTR, OUTPUT);
        digitalWrite(MODEM_DTR, LOW);
        delay(2000);
        modem.sleepEnable(false);
    }

    Serial.println("Check modem online .");
    while (!modem.testAT()) {
        Serial.print("."); delay(500);
    }
    Serial.println("Modem is online !");

    delay(10000);

    Serial.println("Enter modem sleep mode!");

    modem.sendAT("+CSCLK=1");
    if (1 == modem.waitResponse(100, GF("OK")))
    {
        Serial.println("SIM76770 deep sleep enabled");
    }

    // Pull up DTR to put the modem into sleep
    pinMode(MODEM_DTR, OUTPUT);
    digitalWrite(MODEM_DTR, HIGH);
    // Set DTR to keep at high level, if not set, DTR will be invalid after ESP32 goes to sleep.
    gpio_hold_en((gpio_num_t )MODEM_DTR);
    gpio_deep_sleep_hold_en();

    delay(5000);

    Serial.println("Check modem response .");
    while (modem.testAT()) {
        Serial.print("."); delay(500);
    }
    Serial.println("Modem is not respone ,modem has sleep !");

    delay(5000);

    Serial.println("Enter esp32 goto deepsleep!");
    esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
    delay(200);
    esp_deep_sleep_start();
    Serial.println("This will never be printed");

}

void loop()
{
}
neuralprocessing commented 9 months ago

Hi,

your code or rather your loop conditions will - with stream debugger enabled- always fire back, that is why the modem.testAT() is true all the time. Furthermore your pin(s) are incorrect DTR is 25.

Maybe wait for an response with OK - this should never come back with an one: while (this->modem.waitResponse("OK") == 1) so the shall not been executed.

nlgranger commented 9 months ago

I have updated with your proposed fixes (fix dtr pin and disabled debugstream) it still doesn't work. Code is here: https://gist.github.com/nlgranger/9da3da3668eb2c99ab1ebfd7b33a44be I have sent a mail to @MilkoKrastev who seemed to have a working example.

nlgranger commented 9 months ago

Ok, nothing conclusive so far but from poking around I gathered:

MilkoKrastev commented 7 months ago

Just to be on the same page since another commenter mentioned my name. I haven't managed to run A7670 in sleep mode while powered via the USB port. I have managed to run it in deep sleep with the modem in sleep mode while on battery. If you power it via USB, I doubt this is possible. While on battery with the ULP running in deep sleep and the modem in sleep mode it consumes ~6 mA.

In general, I am much happier with TTGO SIM7600G. Yes, it is twice the price, but it seems more robust in outside conditions. So far it has proven in 100 km/h winds with heavy rain. Of course, the enclosure is solid and professionally made, but running at 100% RH reliably is solid achievement. Let's see how it performs in subzero winter conditions :)

TTGO A7670 experiences random crashes every once in a while, i.e. it runs for 2-3 weeks and then crashes. Not sure yet whether it is an error in my source code, or hardware instability. The source code is pretty much identical to the one I use for TTGO SIM7600. So, if price is not an issue, do yourself a favor and use TTGO SIM7600G.

github-actions[bot] commented 6 months ago

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] commented 6 months ago

This issue was closed because it has been inactive for 14 days since being marked as stale.