LilyGo T-Call Vehicle GPS Tracker

January 19, 2025
2236
Views

Flashing

Update the phone_number_1 value in the globals with the initial phone number, you can either add all 3 phone numbers or add the first phone number and then use the new_number_x command from that number to add additional numbers. Change the WiFI SSID and Passwords as per your requirements. The access point SSID and password needs to be set in 3 places as indicated in BOLD in the code above.

In order to flash, you need to use esphome. This can be run as a docker container, see more. Once you have compiled and are ready to flash the image, use the ESP Web Flasher to flash the LillyGo T-Call. Once flashed, the device should boot and now broadcast your ap SSID you set and accept SMS messages from the phone number you set.

Once flashed, the device can be accessed using the Access Point, and updates can be done using the OTA feature. The default IP address is 192.168.4.1, enable the access point if you need with ap_on from an authorized number.

This code was last flashed successfully using esphome version: 2025.8.1 . If compilation fails, try removing all the commented sections.

Follow these recommended steps for flashing.

  1. Create a new esphome project, name it.
  2. Note down the API and OTA passwords.
  3. Paste the entire config into the new project.
  4. Replace the OTA and API passwords with those copied earlier.
  5. Flash to device via USB.

Tripple Axis Gyro + Accelerometer

This feature allows for the vehicles position on the Pitch and Roll axis to be monitored while the alarm is armed. This can useful if the car is jacked up or being towed, the alarm will be activated.

The IMU can be manually calibrated by using the Web UI IMU Calibration button, or by sending the SMS calibrate_level.

The IMU is automatically calibrated each time the ignition is turned off, therefore if you are parked on hill, the IMU calibration will run and calibrate a level value. The IMU will also auto calibrate upon reboot of the device.

The set level of tilt for pitch and roll is 3 degrees and must be held for 3 seconds or more to active the alarm. This can be set from the Web UI using the Tilt Threshold (deg) slider 1 – 15 degrees.

If your GY-521 module is not working or reporting errors, check the I2C address in the logs. The default address should be 0x68, or 0x69 with AD0 pulled high. The address can be updated in mpu6050 sensor block.

  - platform: mpu6050
    address: 0x68
    update_interval: 50ms
    accel_x:
      id: ax_raw
      name: "MPU6050 Accel X (raw)"
    accel_y:
      id: ay_raw
      name: "MPU6050 Accel Y (raw)"
    accel_z:
      id: az_raw
      name: "MPU6050 Accel Z (raw)"
    gyro_x:
      id: gx_raw_dps
      name: "MPU6050 Gyro X (°/s raw)"
    gyro_y:
      id: gy_raw_dps
      name: "MPU6050 Gyro Y (°/s raw)"
    gyro_z:
      id: gz_raw_dps
      name: "MPU6050 Gyro Z (°/s raw)"
    temperature:
      id: mpu_temp
      name: "MPU6050 Temperature"

Deep Sleep

If power consumption is an issue, we can implement Deep Sleep. This allows the T-Call and esp32 to enter deep sleep. This can bring the power consumption down to between 10 µA and 150 µA. This is especially useful for vehicles that do not drive every day or stand for longer periods of time.

Deep sleep can be managed with the following commands.

status
deep_sleep_enable
deep_sleep_disable
wake_time 23:00
sleep_time 07:00

If the doors are opened or the ignition is turned on during sleep, the device will wake. If the alarm was armed when entering deep sleep, the alarm state will resume on wake. This means if the doors were opened when in deep sleep, the device will wake in the armed state, and the alarm will trigger due to the door open event. This means that the alarm is still active and effective while in deep sleep.

No SMS messages are sent when in deep sleep, and no SMS messages can be received when in deep sleep. The SIM800L is powered down during sleep.

With the above commands, the device will enter deep sleep every night at 23:00 and exit deep sleep at 07:00. With deep sleep enabled, the 3v3 and 5v rails of the LilyGo remain active, this means that any devices wired to the 5V or 3v3 rails will remain ON when deep sleep is active, such as GPS, INA219 and GY-521.

GPS & I2C

Make sure you update the GPS block with the correct baud rate of your GPS. On TX on the GPS is required to be wired.

uart:
  - id: sim
    baud_rate: 9600
    tx_pin: 27
    rx_pin: 26
  - id: gpsmodule
    baud_rate: 38400
    rx_pin: 34

The same applied for I2C, connect your devices and view the log, you should see the devices that are found on the I2C bus,

I2C device found at address 0x40
I2C device found at address 0x68

Replace the sensor address with that listed above. Addresses can be modified using jumpers on the boards themselves such as the INA219 and GY-521, this allows for the use of multiple sensors should require them. The INA219 addresses are 0x40 and 0x41 and the GY-521 has addresses 0x68 and 0x69.

sensor:
  - platform: ina219
    address: 0x40
  - platform: mpu6050
    address: 0x68
    update_interval: 50ms

Wiring Diagrams

Resources

Resources
LilyGo T-Call GPS PCB Download v1.0

Troubleshooting

First Steps

Before uploading the code, edit the phone_number_1 with your number in the globals section.

globals:
   - id: phone_number_1
          type: std::string
          restore_value: yes
          initial_value: '"phone_number"'

If you have trouble adding schedules initially after first install, remove all the schedules before adding new ones.

remove_schedule_1
remove_schedule_2
remove_schedule_2

now add the new schedules

new_schedule_1 monday,tuesday,friday arm 23:00 disarm 07:00
Phone number added but still getting “Unauthorized”

Connect to your access point and login to the Web UI at http://192.168.4.1. Check the “sms_sender” to check the exact format that the phone number was received as and update your phone_number_x accordingly. The number will usually include your country code, e.g., +611234567

Can I have just 1 phone number?

Yes, just leave the phone_number_2 and phone_number_3 values blank (initial_value: ‘””‘). You can also use the remove_number_2 and remove_number_3, this will blank out the values for phone numbers 2 and 3.

How to confirm that the Speed alarm is working

Arm the alarm (arm) and then turn the Fuel Shutoff relay off (relay_off) and drive the car over 5km/h. The Speed alarm should now activate and send a notification to phone_number_1, phone_number_2, and phone_number_3.

The device is constantly rebooting

Constant reboots can be caused by multiple issues, mostly due to esphome failing to connect to the API server or Wi-Fi failing to connect to the network. If you are using the Wi-Fi component in esphome (not the access point), ensure you have added the reboot_timeout: 0s to your config. This is especially important for the api: section.

api:
  encryption:
    key: ""
  reboot_timeout: 0s

Sometimes, the SIM800L can continue to process the same SMS upon boot. This is coded to prevent this, but if for some reason the SIM800L keeps processing the reboot SMS on every boot, try to force it out of the reboot cycle by sending another message, any message will do.

You could also quickly connect to the device webpage and turn off the SIM800L using the SIM800L_PWR switch in the web interface, this will allow you to reflash via OTA as the SIM800L will not process any SMS message when powered down.

How to test and confirm the functions are working

To test the fuel relay, you can login to the Web UI using the access point at http://192.168.4.1 and arm the alarm (arm), you should see the Fuel Shutoff switch turn on in the Web UI.

To test your ignition, again login to the Web UI and turn on your ignition, you should see the Ignition sensor state change to “on”.

Further test to check for GPS lock can be done using the Web UI, or using the status command (status) to confirm if there is a GPS lock and how many satellites.

To test the Speed alarm, arm the alarm (arm) and turn off the fuel shutoff relay (relay_off) and drive the car over 5km/s. All phone numbers should now receive a notification Car speed alarm activated. Car is travelling more than 5km/h.

When adding schedules, does it matter how the days are formatted.

It should not. I have made it so that it will try to interpret abbreviated days of the week, such as mon, tue, tues, wed thu, thurs etc.

However, it is best to just use the full name, monday,tuesday,wednesday etc.

Speed alarm activates when the vehicle is not moving.

This may be as a result of GPS drift. If this is an issue, increase the speed in the interval: section for the speed alarm.

10.0 && !id(speed_alarm_triggered))
Doors lock automatically after sending unlock or disarm.

This is factory set for most vehicles. The default behavior is to relock the doors if unlocked and a door is not opened. To get around this, you can wire the door circuit through another relay and take it to GND. This will trick the car into thinking the door has been opened, and the doors will not lock automatically.

Set the code on unlock to trigger both the UNLOCK relay and another relay, the relay used for sending a door open signal.

Wire the door open NEGATIVE through a NC contact of the relay. When the unlock relay activates, this will also activate the door open relay, removing the GROUND and sending an open signal to the car.

This will result in the car staying unlocked until re locked.

Schedules are not running correctly.

Ensure the schedule cycles through the start and end time correctly. For example, if you set a schedule for

new_schedule_1 monday arm 14:00 disarm 16:00

make sure you add this schedule BEFORE 14:00, not after, otherwise the disarm command will not run as it has not passed the arm cycle of the schedule.

Using without Door Open and Ignition Alarm inputs.

If you want to use without the door open and/or ignition sensors, you have 2 options.

  1. Short GPIO21 and GPIO13 to GND with a short piece of wire. This will keep the inputs closed and prevent them from ever opening.
  2. Change the binary_sensor to be inverted. This way it will always see the input as “Closed”.
binary_sensor:
  - platform: gpio
    id: doors
    pin:
      number: 21
      mode: INPUT_PULLUP
      inverted: true
    name: "Doors"
Relay Wiring General Questions
  • One thing I thought of was how to wire the Fuel Shutoff Relay. I my case I went for Normally Closed as the relay I had only had a Normally Closed contact, thus when the relay is powered down, the relay is closed circuit allowing the fuel pump to operate. If the device is removed or powered down, this relay will de-energize and allow the fuel pump to operate again. You could wire the relay as Normally Open, this way power is required to energize the relay for the car to be able to start. This is a more secure option.
  • For the remainder of the relay wiring, it is up to you if you want to switch positive or negative, for me I am switching negative for everything as per my wiring diagrams.
I want to be able to turn the Fuel Shutoff relay on when the ignition is ON.

For safety reason, this is not recommended. Remove this from the switches: section for the Fuel Shutoff switch. This will allow you to manually activate the Fuel Shutoff relay with relay_on command regardless of the ignition state. Note that the arm command will still not be able to turn the relay on and schedules will still not run when the ignition is ON.

    on_turn_on:
    then:
      - lambda: |-
          if (id(ignition).state) {
              id(shutoff).turn_off();
              ESP_LOGD("safety", "IGNITION is ON - Fuel shutoff relay activation prevented!");
          }
Changing the horn timings

You can change the horn alarm activation time and the number of times the horn activates for the “find” command below. The default values are 2.5 minutes for alarm activation and 3 fast pulses at 200ms for the find horn highlighted in bold below.

  - interval: 1s
    id: alarm_pulse
    then:
      - lambda: |-
          if (id(alarm_siren_switch).state) {
            if (id(gps_time).now().is_valid()) {
              int elapsed = id(gps_time).now().timestamp - id(alarm_start_time);
              if (elapsed >= 150) {
                ESP_LOGD("alarm", "Alarm siren timed out after 2.5 minutes.");
                id(alarm_siren_switch).turn_off();
                id(alarm_triggered) = false;
                return;
              }
            }
            id(horn_output).turn_on();
            delay(500);
            id(horn_output).turn_off();
          }
- interval: 200ms id: find_pulse then: - lambda: |- static int find_count = 0; if (id(find_switch).state) { if (find_count < 3) { id(horn_output).turn_on(); delay(200); id(horn_output).turn_off(); find_count++; } else { id(find_switch).turn_off(); find_count = 0; } } else { find_count = 0; }
Changing default values on boot

You can change the default values of functions such as horn_feedback and door_alerts to be enabled on boot or firmware updates. This value should be persistent across reboots and therefor will stay in the last state set (horn_feedback_on or door_alerts_on) but if you want to set it statically, change the following.

Note that changing this value and rebooting will not work, as they are stored in non-volatile memory. Therefore, they should remain in the previously set state.

  - id: horn_feedback_enabled
    type: bool
    restore_value: yes
    initial_value: "true"

  - id: door_alerts_enabled
    type: bool
    restore_value: yes
    initial_value: "true"
Testing
  • GPS Speed Alarm
    Arm the alarm (arm), disable the fuel shutoff relay (relay_off) and drive the car over 10km/h. You should receive a notification Car speed alarm activated. Car is travelling more than 10km/h.
  • Phone Number and Schedule Persistency
    Add a new phone number (new_number_1) and add a new schedule (new_schedule_1), flash the firmware again and then query the stored values (phone_number_1 and schedule_1) they should now return the previous set values.
  • Fuel Shutoff Safety
    Turn on the ignition, attempt to arm the alarm (arm). You can also arm the alarm manually in the web UI. The alarm should not turn the fuel shutoff relay ON when the ignition state if ON. Also add a schedule and have it cycle the arm time when the ignition is ON (new_schedule_x). It is important to note that the fuel shutoff relay can be activated at any time including with the ignition ON sending relay on.
  • GY521 Level Alarm
    Set your desired tilt angle in the Web UI. Park the car on a slope and arm the alarm. Release the handbrake and roll the car down the slow to a level angle or a angle that exceeds your set tilt angle. The alarm should activate.
Messages ae not being processed / Cannot disarm

In my experience, 99% of the time this has been as a result of being out of credit. While the device can still receive messages, when it attempts to send a reply, it fails to send it and become stuck in a loop of trying to send the SMS. This has been resolved in Version 1.20 and should now still process SMS messages regardless of messages queued to be sent, however this was a mission and is not 100% perfect.

You can also connect via Wi-Fi as a backup option and disarm the alarm from the Web UI.

GY-521 Installation

When installing the GY-521, this can be done by stacking it above the INA219. It is important to only connect the VCC, GND, SCL and SCA pins to the INA219 when stacking. On connect the 4 pins on the GY521 shown in the image below.

Current Issues

Current Issues
Some alerts or messages can be sent multiple times.
Schedules do not persist across reboots.
One of the 5v output relays on the PCB are unusable due to being tied to SIM800L GPIO.
The T-Call needs to be modified to fit the PCB. See image below.

Changelog

Version 1 : December 2024

Initial Release

Version 1.10: December 2024

Added the ability to add 2 additional phone numbers. phone_number_1, phone_number_2 and phone_number_3. (phone_number_1, phone_number_2, phone_number_3)
Added the where command. (where)

Version 1.11: December 2024

Added the lock and unlock commands. (lock, unlock)
Added the arm and disarm commands. (arm, disarm)

Version 1.12: December 2024

Added feature to ensure that the fuel shutoff relay cannot be turned on when the ignition is on. This prevents the fuel shutoff relay turning on by schedule while driving.

Version 1.13: January 2025

Added schedules.

Version 1.14: February 2025

Added the ignition status.
Added the door open status.
Added horn pulsing as a siren.

Version 1.16: April 2025

Added the ability to find the car with the find command. (find)

Version 1.17: April 2025

Added the ability to disable notifications. This only applies to the arm, disarm, lock and unlock commands. (notifications_off, notifications_on).

Version 1.18: May 2025

Removed the ap_on and ap_off commands. Access point is now always enabled unless connected to Wi-Fi.

Version 1.20 : May 2025

Removed the HELP command due to message size being too big.
Added the ability to dynamically set the battery low alert voltage. (battery_voltage 11.50)
Increased the LOCK and UNLOCK relay pulse delays to 300ms from 100ms.

Version 1.21: May 2025

Added function to reboot device when the SIM800L registration fails to force re-registration.
Added the ability to dynamically update the horn_feedback relay bounce time. (horn_pulsetime 100ms).

Version 1.22: May 2025

Removed the horn_feedback activating from schedules – The horn will not sound if horn_feedback is on and armed or disarmed via schedules. Horn feedback now only operates with manual commands, lock, unlock, arm and disarm.

Version 1.23: July 2025

Added the Watchdog function. Sends a watchdog SMS message every x days to ensure the device is still connected to the GSM network. (watchdog_on, watchdog_off, watchdog_days x)

Version 1.24: July 2025

Added the ability to update the siren runtime. in seconds (siren_runtime 30)

Version 1.25: July 2025

Added Text Sensors for all global variables to display in the Web UI
– Phone Number 1, 2, 3
– Schedule 1, 2, 3
– Horn Feedback Enabled
– Door Alerts Enabled
– Siren Runtime (sec)
– Battery Voltage Threshold
– Horn Pulse Time (ms)
– Notifications Enabled
– Watchdog Enabled
– Watchdog Interval Days
– Watchdog Last Sent

Version 1.26: August 2025

Implemented Deep Sleep functionality.

Version 1.27: August 2025

Implemented Tripple Axis Gyro + Accelerometer functionality.

Version 1.28: August 2025

Implemented Auto-Arm. (auto_arm_on, auto_arm_off, auto_arm_time 10)

Version 1.29: September 2025

Changed I2C frequency to 400khz.
Added imu_status command. (imu_status)
Auto calibrate IMU on alarm ARM.
Added the option to enable or disable the siren (siren_on, siren_off)
Consolidate code for alarm functions for flexible editing.

1 2

Leave a Reply