Open avicarmeli opened 1 month ago
Hello !
No prob, TPMS Advance support 2 different kind of sensors, those from Sysgration, those from Pecham. The byte array sent by the sensors are a little bit different, the most important difference is the integration of the wheel location for the Sysgration manufacturer (front left, front right, rear left, rear right).
Sysgration uses the service: 0000fbb0-0000-1000-8000-00805f9b34fb
Pecham uses: 000027a5-0000-1000-8000-00805f9b34fb
If you're comfortable with Kotlin and Android, take a look at theses classes:
This code contains byte array parsing for both sensor types
Great, thank you. Do you think if I send the 4 wheels data from the same MAC address, would it be a problem?
In this case, your BLE data packets should be formatted like Sysgration sensors, on Pecham sensors, mac address is used as unique id.
Which antenna do you use on your ESP32 to intercept 433 signal ? I use ESPHome on my ESP32 and I'm curious about your project
Well, I ported this code to ESP32 with CC1101. I was able to receive the 433MGHz signal of my 2013 Nissan Micra with the ESP32 Board. Now I plan to add to the code the ability to publish the 4 sensors data over BLE.
About the MAC address, I saw that the Sysgration parser use the manufacture data to determine location of the sensor. I wonder would the code be ok with one BLE connection with one service number and 4 different manufacture data frames?
I am having hard time scanning the QR code I came up with into the app. I gave the virtual sensors the following ID's 108A78, 108A79, 108A7A and 108A7B. The QR code I came up with is for the 5 right digits. Am I doing something wrong?
About the MAC address, I saw that the Sysgration parser use the manufacture data to determine location of the sensor. I wonder would the code be ok with one BLE connection with one service number and 4 different manufacture data frames?
As long the 4 packets are sent separately, you can sent them at the same time from the same device, TPMS Advanced will managed them like real sensors.
I am having hard time scanning the QR code I came up with into the app. I gave the virtual sensors the following ID's 108A78, 108A79, 108A7A and 108A7B. The QR code I came up with is for the 5 right digits. Am I doing something wrong?
11AD8B&21563D&31A4F0&41A552
is a valid QRCode recognized by TPMS advanced. The first digit is important since 1
, 2
, 3
and 4
represent the location of the wheel's sensor. The code maps theses numbers to theses locations: FRONT_LEFT, FRONT_RIGHT, REAR_LEFT and REAR_RIGHT.
Then, the whole id is converted as int
to represent the unique id of the sensor. For instance, on my front left sensor, 11AD8B
was prefixed by 0x00
and converter to an int, the result is: -1951592192
.
I am publishing manufacture data for each sensor according to the format I have found here. Is that correct? I was able to scan the QR code after I formatted it as you advised, but no data was displayed in the main screen. So I guess I am still not doing it right. Attached is the screen video from nRF Connect app.
Update: It turned out that I wasn't publishing the service UUID. There is a limit for advertisement size in BLE 4 (which ESP32 comply with) of 31 byte. Since service UUID is 16 bytes and manufacturer data (the sensor data - ID, location, pressure, temperature etc.) is 18 bytes, one have to set the Service UUID into Scan response advertisement data. After mending that the data sent was visible in the TPMS advanced app. I also found that if I set the advertisement type to ADV_TYPE_NONCONN_IND (non connect and indirect) then the data is not showing up in the TPMS advanced app.
Following is a short ESP32 demo code to send data to TPMS advanced app:
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
// 128-bit Service UUID
static BLEUUID serviceUUID("0000fbb0-0000-1000-8000-00805f9b34fb");
// Manufacturer Data
// Fake TPMS data for 4 sensors
uint8_t tpmsData[4][18] = {
{0x00, 0x01, 0x80, 0xEA, 0xCA, 0x10, 0x8A, 0x78, 0xE3, 0x6D, 0x00, 0x00, 0xE6, 0x0A, 0x00, 0x00, 0x5B, 0x00}, // Sensor 1
{0x00, 0x01, 0x81, 0xEA, 0xCA, 0x20, 0x8A, 0x79, 0xD2, 0x4B, 0x00, 0x00, 0xE6, 0x0A, 0x00, 0x00, 0x4A, 0x00}, // Sensor 2
{0x00, 0x01, 0x82, 0xEA, 0xCA, 0x30, 0x8A, 0x7A, 0xC1, 0x2A, 0x00, 0x00, 0xE6, 0x0A, 0x00, 0x00, 0x39, 0x00}, // Sensor 3
{0x00, 0x01, 0x83, 0xEA, 0xCA, 0x40, 0x8A, 0x7B, 0xB0, 0x09, 0x00, 0x00, 0xE6, 0x0A, 0x00, 0x00, 0x28, 0x00} // Sensor 4
};
void setup() {
Serial.begin(115200);
Serial.println("Starting BLE work!");
// Initialize the BLE device
BLEDevice::init("ESP32");
// Create BLE Server
BLEServer *pServer = BLEDevice::createServer();
// Create the BLE Service
BLEService *pService = pServer->createService(serviceUUID);
// Start the service
pService->start();
// Start advertising
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
// Set manufacturer data for each sensor
for (int i = 0; i < 4; i++) {
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
String manufacturerData((char*)tpmsData[i], sizeof(tpmsData[i]));
oAdvertisementData.setManufacturerData(manufacturerData);
pAdvertising->setAdvertisementData(oAdvertisementData);
//pAdvertising->setAdvertisementType(ADV_TYPE_NONCONN_IND);
BLEAdvertisementData scanResponseData;
scanResponseData.setCompleteServices(serviceUUID);
pAdvertising->setScanResponseData(scanResponseData);
// Configure advertising
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
pAdvertising->setMinPreferred(0x12);
// Start advertising
pAdvertising->start();
Serial.print("Advertising started! Sending Sensor no.");
Serial.println(i);
delay(1000); // Advertise each sensor data for 1 second
pAdvertising->stop();
}
}
void loop() {
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
for (int i = 0; i < 4; i++) {
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
String manufacturerData((char*)tpmsData[i], sizeof(tpmsData[i]));
oAdvertisementData.setManufacturerData(manufacturerData);
pAdvertising->setAdvertisementData(oAdvertisementData);
//pAdvertising->setAdvertisementType(ADV_TYPE_NONCONN_IND);
BLEAdvertisementData scanResponseData;
scanResponseData.setCompleteServices(serviceUUID);
pAdvertising->setScanResponseData(scanResponseData);
// Configure advertising
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
pAdvertising->setMinPreferred(0x12);
// Start advertising
pAdvertising->start();
//Serial.println("Advertising started!");
Serial.print("Advertising started! Sending Sensor no.");
Serial.println(i);
delay(1000); // Advertise each sensor data for 1 second
pAdvertising->stop();
}
delay(2000);
}
11AD8B&21563D&31A4F0&41A552 is a valid QRCode recognized by TPMS advanced. The first digit is important since 1, 2, 3 and 4 represent the location of the wheel's sensor. The code maps theses numbers to theses locations: FRONT_LEFT, FRONT_RIGHT, REAR_LEFT and REAR_RIGHT.
Just to be sure, I see that with first digit set to 1 the sensor mapped to Front Right. The complete map looks like that:
First Digit | Wheel |
---|---|
1 | Front Right |
2 | Front Left |
3 | Rear Right |
4 | Rear Left |
Could anyone confirm?
Your map is not correct to industry standards. My Autel TPMS reader reads in the order of: Fl, Fr, Rr, Rl, spare. Of course, you can read and assign in any order as long as your SW takes that order into account.
I would like to see a manual way to enter the sensor IDs into the android app though.
I would like to send the data that ESP32 collect from 433MHz TPMS sensors to Your Android app. To do that I need to know the SERVICE_UUID and the format the data of the sensors sent over the BLE. Could you direct me where to find that info? Thanks in advance.