Posts: 6
Threads: 1
Joined:
Feb 2025
Reputation:
0
02-26-2025, 01:43 PM
(This post was last modified: 02-26-2025, 04:01 PM by oldcity.camper .)
Hello,
I have been researching for a few months to integrate a heater into my smart caravan system, which I have developed myself. After searching everywhere, I finally discovered Afterburner. I read the codes and tested the protocols on my existing boards, but unfortunately, I couldn't get any results. The worst part is that the boards I have are listed as incompatible in the PDF documentation.
The biggest issue is that these incompatible boards are widely sold in the Turkish market, while the compatible ones are unfortunately unavailable. When trying to procure them, they can only be found on platforms like eBay and AliExpress, which impose high customs duties.
Would it be possible to add support for these incompatible boards? What approach should we take to analyze and decode the protocols? What are your recommendations and suggestions?
A small addition: When we couldn't decode the protocol, we examined the board more carefully and traced the connections leading to the STM8S chip. Later, we took control using an Arduino, but due to a lack of experience, I put this function on hold. (How many pumps are needed at a certain RPM? – Maybe 5 per second for 4000 RPM?)
To share knowledge and help others, I am sharing the pin connections on the STM8S.
Thank you in advance, and I wish everyone a good forum experience.
Attached Files
Thumbnail(s)
Posts: 27
Threads: 1
Joined:
Oct 2024
Reputation:
4
The CCFN ECU you have is junk.
I did decode it 5 years ago and abandoned all further effort as it devalued the Afterburner.
I'm sorry, but if an ECU cannot be tuned and is lacking in useful feedback of the heater system it is not worth the complexity of supporting differing data protocols.
There are also electrical issues with those ECUs requiring user modification for reliable operation.
Not worth putting lipstick on a pig.
Posts: 6
Threads: 1
Joined:
Feb 2025
Reputation:
0
In the system we are building, we are designing a main control panel for direct access to multiple controllers. I have completed the application and communication for the solar charge controller, DC-DC charge controller, and input-output modules in a caravan for both the main application and the HMI panel. What is very important for me is a diesel water heater and a diesel air heater.
Unfortunately, this is the only card I can access in Turkey, so I am still trying to integrate it into my smart caravan system. Could you share everything you have figured out so far? This might be a useful scenario. I am trying to work within my available resources.
Posts: 6
Threads: 1
Joined:
Feb 2025
Reputation:
0
I continue working on the topic. I read Afterburner’s code for hours, and every time I read it, I noticed new details. When I carefully examined the repo, I found useful PDFs in the documents section. Thanks to Ray Jones and the entire contributor team for being a source of inspiration!
Protocol!
_TX_RX_TX_RX
The system operates on a request-response logic. There is a 30 ms low signal between each TX and RX.
If a request is sent, a response is received.
Each request starts with 4 bits of high and ends with 4 bits of low. Here’s an example of a request:
1h 30l 8h 4l 8h 4l 4h 8l 8h 4l 4h 8l 4h 8l 4h 8l 8h 4l 4h 8l 1h
1h = 1 ms high
30l = 30 ms low
This means that when sending a request, we start with a 1 ms high followed by a 30 ms low signal.
The 8 high bits are necessary for the first 4-bit high start, and the next 4-bit high represents 1.
The 4-bit low indicates the end of the data.
In other words:
8h 4l = 1
4h 8l = 0
When sending data, if we start with 8h 4l (which means 1), we trigger an event.
If you send the above packet in 1 ms intervals, you will see that the heater starts working!
Example of a received packet:
4h 8l 8h 4l 8h 4l 4h 8l 4h 8l 4h 8l 4h 8l 4h 8l 4h 8l 4h 8l 4h 8l 4h 8l 8h 4l 4h 8l 4h 8l 8h 4l
In this packet, it starts with 4h 8l, which means 0, followed by 8h 4l = 1, 8h 4l = 1.
Decoded, it looks like this:
0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 1
The fact that the 1st and 2nd bits are set to 1 indicates voltage information.
At the end, adding 2^0 and 2^3, we determine that the voltage is 9V.
I will continue analyzing the commands.
Once again, thanks to all Afterburner contributors for being an inspiration!
Before this project, I didn’t even know what an oscilloscope was—now I’ve bought one and started using it!
Knowledge grows as it is shared. Wishing everyone a great time on the forums!
Posts: 6
Threads: 1
Joined:
Feb 2025
Reputation:
0
Now, this terrible code is my first prototype. Remove the controller I made and connect the ESP32 to the blue wire at pin 17. Then, power on the ESP32. When you send the command '1' via the serial monitor, the heater will start working. If you send '2', the heating level will increase. If you try to increase it at the maximum level, you will see that it resets back to the minimum level. Today, I will be working on error codes. My receiving logic is also terrible, but I hope to come back with better examples. Wishing you all a good forum experience!
/*Code Begin*/
//Esp wroom32
#include <Arduino.h>
#include "HardwareSerial.h"
#define TX_RX_PIN 17 // Tek hatlı UART için kullanılacak pin
int oldValue = 0;
int newValue = 0;
unsigned long timeNow;
unsigned long timeOld;
unsigned long elapsedTime;
int counter = 0;
bool rxActive = 0;
int bool_array[128] = {
// 1 ms high
1,
// 30 ms low
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 1 ms high
1
};
int ilk_yolla[] = {
// 1 ms high
1,
// 30 ms low
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 1 ms high
1
};
int ikinci_yollanan[] = {
// 1 ms high
1,
// 30 ms low
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 1 ms high
1
};
int ucuncu_yollanan[] = {
// 1 ms high
1,
// 30 ms low
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 1 ms high
1
};
int dorduncu_yollanan[] = {
// 1 ms high
1,
// 30 ms low
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 1 ms high
1
};
int besinci_yollanan[] = {
// 1 ms high
1,
// 30 ms low
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 1 ms high
1
};
int start_stop1[] = {
1, // 1H -> 1 adet 1
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 30L -> 30 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1 // 1H -> 1 adet 1
};
int start_stop2[] = {
1, // 1H -> 1 adet 1
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 30L -> 30 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1 // 1H -> 1 adet 1
};
int devamli[] = {
1, // 1H -> 1 adet 1
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 30L -> 30 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1 // 1H -> 1 adet 1
};
int yeni1[] = {
// 1 ms high
1,
// 30 ms low
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 1 ms high
1
};
//8H, 4L, 4H, 8L, 8H, 4L, 4H, 8L, 8H, 4L, 8H, 4L, 8H, 4L, 8H, 4L
int kazan_sorgu[] = {
1, // 1H -> 1 adet 1
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 30L -> 30 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1 // 1H -> 1 adet 1
};
int yeni2[] = {
// 1 ms high
1,
// 30 ms low
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 1 ms high
1
};
int pompaTetikle[] = {
// 1 ms high
1,
// 30 ms low
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 1 ms high
1
};
void yollama()
{
while(1)
{
digitalWrite(TX_RX_PIN, ilk_yolla[counter]);
counter++;
vTaskDelay(1);
if (counter == 128)
{
counter = 0;
digitalWrite(TX_RX_PIN, LOW);
break;
//pinMode(TX_RX_PIN, INPUT_PULLUP);
}
vTaskDelay(1);
}
}
void cevabiBekle()
{
while (1)
{
Serial.println("whileDa");
timeNow = millis();
newValue = digitalRead(TX_RX_PIN);
if (newValue != oldValue){
elapsedTime = timeNow - timeOld;
timeOld = timeNow;
}
if (elapsedTime > 25 && elapsedTime < 35)
break;
oldValue = newValue;
}
pinMode(TX_RX_PIN, OUTPUT);
}
volatile bool sendData = false;
void setup() {
Serial.begin(115200); // Seri monitör başlat
timeOld = 0;
timeNow = millis();
pinMode(TX_RX_PIN, OUTPUT);
/*
pinMode(TX_RX_PIN, INPUT);
while (1)
{
timeNow = millis();
newValue = digitalRead(TX_RX_PIN);
if (newValue != oldValue){
elapsedTime = timeNow - timeOld;
timeOld = timeNow;
}
if (elapsedTime > 25 && elapsedTime < 35)
break;
oldValue = newValue;
}
*/
}
void takeFeedback()
{
bool bits[16];
int bitsCounter = 0;
int arrayCounter = 0;
int feedBackTx[192];
vTaskDelay(1);
while(1)
{
if (digitalRead(TX_RX_PIN))
break;
vTaskDelay(1);
}
bitsCounter = 0;
feedBackTx[0] = 1;
int feedCounter = 0;
while (feedCounter < 192){
feedBackTx[feedCounter] = digitalRead(TX_RX_PIN);
//Serial.printf("%d, ", feedBackTx[feedCounter]);
feedCounter++;
vTaskDelay(1);
}
feedCounter = 0;
while (feedCounter < 192)
{
bitsCounter = 0;
while(bitsCounter < 4)
{
if (feedBackTx[feedCounter] != 1)
{
//Serial.println("4 high error!");
return;
}
bitsCounter++;
feedCounter++;
}
bits[arrayCounter] = feedBackTx[feedCounter];
arrayCounter++;
feedCounter+= 4;
bitsCounter = 0;
while(bitsCounter < 4)
{
if (feedBackTx[feedCounter] != 0)
{
//Serial.println("4 low error!");
return;
}
bitsCounter++;
feedCounter++;
}
}
Serial.println();
feedCounter = 0;
while (feedCounter < 16)
{
Serial.printf("%d, ", bits[feedCounter]);
feedCounter++;
}
Serial.println();
}
int highCounter = 1;
int lowCounter = 1;
bool sendData1 = false;
bool sendData2 = false;
bool sendData3 = false;
bool sendData4 = false;
int process = 0;
int process1 = 0;
void loop() {
/*
if (newValue == LOW)
lowCounter++;
else if (newValue == HIGH)
highCounter++;
if (newValue == LOW && oldValue == HIGH)
{
if (highCounter == 3 || highCounter == 5)
highCounter = 4;
else if (highCounter == 2)
highCounter = 1;
else if (highCounter == 7 || highCounter == 9)
highCounter = 8;
else if (highCounter == 649 || highCounter == 651 || highCounter == 652)
highCounter = 650;
Serial.printf("%dH, ", highCounter);
if (highCounter == 650)
Serial.println("");
highCounter = 1;
lowCounter = 1;
} else if (newValue == HIGH && oldValue == LOW)
{
if (lowCounter == 3 || lowCounter == 5)
lowCounter = 4;
else if (lowCounter == 29 || lowCounter == 31)
lowCounter = 30;
else if (lowCounter == 7 || lowCounter == 9)
lowCounter = 8;
Serial.printf("%dL, ", lowCounter);
if (lowCounter == 30)
Serial.println("");
highCounter = 1;
lowCounter = 1;
}
oldValue = newValue;
///Serial.printf("%d, ", newValue);
timeNow = millis();
newValue = digitalRead(TX_RX_PIN);
vTaskDelay(1);
*/
if (Serial.available()) {
char receivedChar = Serial.read();
if (receivedChar == '1') {
//pinMode(TX_RX_PIN, OUTPUT);
process = 1;
Serial.println("Veri gönderiliyor...");
} else if (receivedChar == '2') {
//pinMode(TX_RX_PIN, OUTPUT);
process = 2;
Serial.println("Veri gönderiliyor...");
} else if (receivedChar == '3') {
//pinMode(TX_RX_PIN, OUTPUT);
process = 3;
Serial.println("Veri gönderiliyor...");
} else if (receivedChar == '4') {
//pinMode(TX_RX_PIN, OUTPUT);
sendData3 = true;
Serial.println("Veri gönderiliyor...");
}
}
// 4 low 8 high 4 low = 4080
// 4 low 4 high 8 low = 3840
// 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0
// 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0
//
if (process1 == 0)
{
digitalWrite(TX_RX_PIN, devamli[counter]);
counter++;
vTaskDelay(1);
if (counter == 128)
{
Serial.println("PRocess1 send!");
digitalWrite(TX_RX_PIN, LOW);
pinMode(TX_RX_PIN, INPUT_PULLUP);
counter = 0;
while(1)
{
if (digitalRead(TX_RX_PIN))
{
takeFeedback();
break;
}
}
counter = 0;
pinMode(TX_RX_PIN, OUTPUT);
//cevabiBekle();
if (process1 == process)
{
process1 = 0;
process = 0;
}
else
process1 = process;
}
} else if (process1 == 1)
{
digitalWrite(TX_RX_PIN, start_stop1[counter]);
counter++;
vTaskDelay(1);
if (counter == 128)
{
Serial.println("PRocess2 send!");
digitalWrite(TX_RX_PIN, LOW);
pinMode(TX_RX_PIN, INPUT_PULLUP);
counter = 0;
while(counter < 1000)
{
if (digitalRead(TX_RX_PIN))
counter++;
vTaskDelay(1);
}
counter = 0;
pinMode(TX_RX_PIN, OUTPUT);
//cevabiBekle();
if (process1 == process)
{
process1 = 0;
process = 0;
}
else
process1 = process;
}
} else if (process1 == 2)
{
digitalWrite(TX_RX_PIN, start_stop2[counter]);
counter++;
vTaskDelay(1);
if (counter == 128)
{
Serial.println("PRocess3 send!");
digitalWrite(TX_RX_PIN, LOW);
pinMode(TX_RX_PIN, INPUT_PULLUP);
counter = 0;
while(counter < 1000)
{
if (digitalRead(TX_RX_PIN))
counter++;
vTaskDelay(1);
}
counter = 0;
pinMode(TX_RX_PIN, OUTPUT);
//cevabiBekle();
if (process1 == process)
{
process1 = 0;
process = 0;
}
else
process1 = process;
}
} else if (process1 == 3)
{
digitalWrite(TX_RX_PIN, kazan_sorgu[counter]);
counter++;
vTaskDelay(1);
if (counter == 128)
{
digitalWrite(TX_RX_PIN, LOW);
pinMode(TX_RX_PIN, INPUT_PULLUP);
counter = 0;
while(1)
{
if (digitalRead(TX_RX_PIN))
{
takeFeedback();
break;
}
}
counter = 0;
pinMode(TX_RX_PIN, OUTPUT);
//cevabiBekle();
if (process1 == process)
{
process1 = 0;
process = 0;
}
else
process1 = process;
}
}
}
/*Code end*/
Posts: 27
Threads: 1
Joined:
Oct 2024
Reputation:
4
I'll give you a clue.
Yes 30ms "sync" period.
A "1" is 8ms high, followed by 4ms low.
A "0" is 4ms high, followed by 8ms low.
sampling 6ms after rising edge is the easiest way to sample the 1 or 0 state!
Commands from controller are 8 bits
ECU responses are 16 bits.
Armed with knowledge, you then play about with the controller and note what affects what.
Essentially the controller polls using particular commands, then receives response data to decode.
Posts: 6
Threads: 1
Joined:
Feb 2025
Reputation:
0
Thanks for the recommendations! Experience truly makes a difference. You've touched on some very critical points for me. I revised the code a bit yesterday, and now my goal is to develop a small React Native app using either Bluetooth Classic or Low Energy. Later, I plan to add an HTTP server and integrate it into the caravan system I'm developing. I'm sharing the latest code—it's still a work in progress.
/*Code Begin*/
#include <Arduino.h>
#include "HardwareSerial.h"
#include "BluetoothSerial.h"
#define TX_RX_PIN 17 // Tek hatlı UART için kullanılacak pin
BluetoothSerial SerialBT;
int oldValue = 0;
int newValue = 0;
unsigned long timeNow;
unsigned long timeOld;
unsigned long elapsedTime;
int counter = 0;
bool rxActive = 0;
/*
8H, 4L, 4H, 8L, 8H, 4L, 4H, 8L, 4H, 8L, 8H, 4L, 8H, 4L, 4H, 8L, 1H, 30L,
8H, 4L, 4H, 8L, 8H, 4L, 4H, 8L, 8H, 4L, 8H, 4L, 8H, 4L, 8H, 4L, 1H, 30L,
*/
int start_stop1[] = {
1, // 1H -> 1 adet 1
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 30L -> 30 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1 // 1H -> 1 adet 1
};
int start_stop2[] = {
1, // 1H -> 1 adet 1
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 30L -> 30 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1, // 4H -> 4 adet 1
0,0,0,0,0,0,0,0, // 8L -> 8 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1,1,1,1,1,1,1,1, // 8H -> 8 adet 1
0,0,0,0, // 4L -> 4 adet 0
1 // 1H -> 1 adet 1
};
int start_stop3[] = {
1, // 1H
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 30L
1,1,1,1,1,1,1,1, // 8H
0,0,0,0, // 4L
1,1,1,1, // 4H
0,0,0,0,0,0,0,0, // 8L
1,1,1,1,1,1,1,1, // 8H
0,0,0,0, // 4L
1,1,1,1, // 4H
0,0,0,0,0,0,0,0, // 8L
1,1,1,1, // 4H
0,0,0,0,0,0,0,0, // 8L
1,1,1,1,1,1,1,1, // 8H
0,0,0,0, // 4L
1,1,1,1, // 4H
0,0,0,0,0,0,0,0, // 8L
1,1,1,1, // 4H
0,0,0,0,0,0,0,0, // 8L
1 // 1H
};
int devamli[] = {
1,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,0,0,0,0,
1,1,1,1,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,0,0,0,0,
1,1,1,1,0,0,0,0,0,0,0,0,
1,1,1,1,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,0,0,0,0,
1,1,1,1,1,1,1,1,0,0,0,0,
1,1,1,1,0,0,0,0,0,0,0,0,
1
};
int kazan_sicaklik[] = {
1, // 1H -> 1 adet 1
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 30L -> 30 adet 0
1,1,1,1,1,1,1,1,0,0,0,0,
1,1,1,1,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,0,0,0,0,
1,1,1,1,1,1,1,1,0,0,0,0,
1,1,1,1,1,1,1,1,0,0,0,0,
1,1,1,1,1,1,1,1,0,0,0,0,
1,1,1,1,1,1,1,1,0,0,0,0,
1,1,1,1,1,1,1,1,0,0,0,0,
1
};
int pompaTetikle[] = {
// 1 ms high
1,
// 30 ms low
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 8 ms high
1, 1, 1, 1, 1, 1, 1, 1,
// 4 ms low
0, 0, 0, 0,
// 4 ms high
1, 1, 1, 1,
// 8 ms low
0, 0, 0, 0, 0, 0, 0, 0,
// 1 ms high
1
};
volatile bool sendData = false;
void setup() {
Serial.begin(115200); // Seri monitör başlat
SerialBT.begin("EskKaravanHeater");
//baudrate 1000
timeOld = 0;
timeNow = millis();
#ifndef SNIFFERMODE
pinMode(TX_RX_PIN, OUTPUT);
#endif
//sleep(3);
#ifdef SNIFFERMODE
pinMode(TX_RX_PIN, INPUT);
while (1)
{
timeNow = millis();
newValue = digitalRead(TX_RX_PIN);
if (newValue != oldValue){
elapsedTime = timeNow - timeOld;
timeOld = timeNow;
}
if (elapsedTime > 25 && elapsedTime < 35)
break;
oldValue = newValue;
}
#endif
}
int findLowHighCount(int arr[], int len)
{
int counter = 0;
int highCount = 0;
int lowCount = 0;
while (counter < len)
{
if (arr[counter] == 1)
highCount++;
else
lowCount++;
counter++;
}
if (lowCount > highCount)
return (0);
else
return (1);
}
void setVoltage(unsigned short receivedData) {
// İlk 4 bit (Başlangıç Kodu) 0110 olmalı
unsigned short header = (receivedData >> 12) & 0xF; // En üst 4 biti al
// Ortadaki 8 bit sıfır olmalı
unsigned short middleBits = (receivedData >> 4) & 0xFF; // Ortadaki 8 biti al
// Kontroller
if (header == 0b0110 && middleBits == 0x00) {
unsigned short voltage = receivedData & 0xF; // Son 4 biti al
}
}
void setTemperatureLevel(unsigned short receivedData) {
// İlk 4 bit (Header) al
unsigned short header = (receivedData >> 12) & 0xF;
// Ortadaki 8 biti al
unsigned short middleBits = (receivedData >> 4) & 0xFF;
// Son 4 bit (Sıcaklık kademesi)
unsigned short temperatureLevel = receivedData & 0xF;
// Eğer ortadaki 8 bitin sağdan 3. biti `1` ise sıcaklık kademesini al
if ((middleBits & 0b00000100) != 0) {
unsigned short temperatureLevel = receivedData & 0xF;
temperatureLevel++;
}
}
void takeFeedback()
{
bool bits[16];
int feedCounter;
int feedBackTx[192];
int garbage[8];
int garbageCounter;
int tempCounter;
unsigned short receivedData = 0;
int rcCounter = 0;
vTaskDelay(1);
while(1)
{
if (digitalRead(TX_RX_PIN))
break;
}
feedCounter = 0;
tempCounter = 0;
while (feedCounter < 192){
/*
Serial.printf("%d, ", digitalRead(TX_RX_PIN));
vTaskDelay(1);
feedCounter++;
*/
garbageCounter = 0;
while (garbageCounter < 4)
{
garbage[garbageCounter] = digitalRead(TX_RX_PIN);
feedBackTx[tempCounter] = garbage[garbageCounter];
tempCounter++;
garbageCounter++;
vTaskDelay(1);
}
if (findLowHighCount(garbage, 4) != 1)
{
Serial.println("fail");
feedCounter = 0;
while (feedCounter < tempCounter)
{
Serial.printf("%d, ", feedBackTx[feedCounter]);
feedCounter++;
}
feedCounter = 0;
while (feedCounter < 200)
{
Serial.printf("%d, ", digitalRead(TX_RX_PIN));
feedCounter++;
}
Serial.println("");
return;
}
garbageCounter = 0;
while (garbageCounter < 4)
{
garbage[garbageCounter] = digitalRead(TX_RX_PIN);
feedBackTx[tempCounter] = garbage[garbageCounter];
tempCounter++;
garbageCounter++;
vTaskDelay(1);
}
if (findLowHighCount(garbage, 4) == 1)
{
receivedData = (receivedData << 1) | 1;
Serial.print("1, ");
rcCounter++;
}
else
{
receivedData = (receivedData << 1) | 0;
Serial.print("0, ");
rcCounter++;
}
garbageCounter = 0;
while (garbageCounter < 4)
{
garbage[garbageCounter] = digitalRead(TX_RX_PIN);
feedBackTx[tempCounter] = garbage[garbageCounter];
tempCounter++;
garbageCounter++;
vTaskDelay(1);
}
if (findLowHighCount(garbage, 4) == 1)
{
Serial.println("fail");
feedCounter = 0;
while (feedCounter < tempCounter)
{
Serial.printf("%d, ", feedBackTx[feedCounter]);
feedCounter++;
}
feedCounter = 0;
while (feedCounter < 200)
{
Serial.printf("%d, ", digitalRead(TX_RX_PIN));
feedCounter++;
}
Serial.println("");
return;
}
feedCounter+= 12;
}
for (int i = 15; i >= 0; i--) {
Serial.print((receivedData >> i) & 1); // Her biti tek tek yazdır
}
Serial.println();
Serial.println("Success");
}
int highCounter = 1;
int lowCounter = 1;
bool sendData1 = false;
bool sendData2 = false;
bool sendData3 = false;
bool sendData4 = false;
int process = 0;
int process1 = 0;
int switchh = 1;
void loop() {
#ifdef SNIFFERMODE
if (newValue == LOW)
lowCounter++;
else if (newValue == HIGH)
highCounter++;
if (newValue == LOW && oldValue == HIGH)
{
if (highCounter == 3 || highCounter == 5)
highCounter = 4;
else if (highCounter == 2)
highCounter = 1;
else if (highCounter == 7 || highCounter == 9)
highCounter = 8;
else if (highCounter == 649 || highCounter == 651 || highCounter == 652)
highCounter = 650;
Serial.printf("%dH, ", highCounter);
if (highCounter == 650)
Serial.println("");
highCounter = 1;
lowCounter = 1;
} else if (newValue == HIGH && oldValue == LOW)
{
if (lowCounter == 3 || lowCounter == 5)
lowCounter = 4;
else if (lowCounter == 29 || lowCounter == 31)
lowCounter = 30;
else if (lowCounter == 7 || lowCounter == 9)
lowCounter = 8;
Serial.printf("%dL, ", lowCounter);
if (lowCounter == 30)
Serial.println("");
highCounter = 1;
lowCounter = 1;
}
oldValue = newValue;
///Serial.printf("%d, ", newValue);
timeNow = millis();
newValue = digitalRead(TX_RX_PIN);
vTaskDelay(1);
#endif
#ifndef SNIFFERMODE
if (Serial.available()) {
char receivedChar = Serial.read();
if (receivedChar == '1') {
//pinMode(TX_RX_PIN, OUTPUT);
process = 1;
Serial.println("Veri gönderiliyor...");
} else if (receivedChar == '2') {
//pinMode(TX_RX_PIN, OUTPUT);
process = 2;
Serial.println("Veri gönderiliyor...");
} else if (receivedChar == '3') {
//pinMode(TX_RX_PIN, OUTPUT);
process = 3;
Serial.println("Veri gönderiliyor...");
} else if (receivedChar == '4') {
//pinMode(TX_RX_PIN, OUTPUT);
process = 4;
Serial.println("Veri gönderiliyor...");
}
}
// 4 low 8 high 4 low = 4080
// 4 low 4 high 8 low = 3840
// 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0
// 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0
//
if (process1 == 0)
{
digitalWrite(TX_RX_PIN, devamli[counter]);
counter++;
vTaskDelay(1);
if (counter == 128)
{
pinMode(TX_RX_PIN, INPUT_PULLDOWN);
counter = 0;
takeFeedback();
counter = 0;
pinMode(TX_RX_PIN, OUTPUT);
vTaskDelay(200);
//cevabiBekle();
if (process1 == process)
{
process1 = 0;
process = 0;
}
else
process1 = process;
}
} else if (process1 == 1)
{
digitalWrite(TX_RX_PIN, start_stop1[counter]);
counter++;
vTaskDelay(1);
if (counter == 128)
{
Serial.println("PRocess1 send!");
pinMode(TX_RX_PIN, INPUT_PULLDOWN);
counter = 0;
takeFeedback();
counter = 0;
pinMode(TX_RX_PIN, OUTPUT);
vTaskDelay(200);
//cevabiBekle();
if (process1 == process)
{
process1 = 0;
process = 0;
}
else
process1 = process;
}
} else if (process1 == 2)
{
digitalWrite(TX_RX_PIN, start_stop2[counter]);
counter++;
vTaskDelay(1);
if (counter == 128)
{
Serial.println("PRocess1 send!");
pinMode(TX_RX_PIN, INPUT_PULLDOWN);
counter = 0;
takeFeedback();
counter = 0;
pinMode(TX_RX_PIN, OUTPUT);
vTaskDelay(200);
//cevabiBekle();
if (process1 == process)
{
process1 = 0;
process = 0;
}
else
process1 = process;
}
} else if (process1 == 3)
{
digitalWrite(TX_RX_PIN, start_stop3[counter]);
counter++;
vTaskDelay(1);
if (counter == 128)
{
Serial.println("PRocess3 send!");
pinMode(TX_RX_PIN, INPUT_PULLDOWN);
counter = 0;
takeFeedback();
counter = 0;
pinMode(TX_RX_PIN, OUTPUT);
vTaskDelay(200);
//cevabiBekle();
if (process1 == process)
{
process1 = 0;
process = 0;
}
else
process1 = process;
}
} else if (process1 == 4)
{
digitalWrite(TX_RX_PIN, kazan_sicaklik[counter]);
counter++;
vTaskDelay(1);
if (counter == 128)
{
Serial.println("PRocess4 send!");
pinMode(TX_RX_PIN, INPUT_PULLDOWN);
counter = 0;
takeFeedback();
counter = 0;
pinMode(TX_RX_PIN, OUTPUT);
vTaskDelay(200);
//cevabiBekle();
if (process1 == process)
{
process1 = 0;
process = 0;
}
else
process1 = process;
}
}
#endif
}
/*Code end*/
Posts: 6
Threads: 1
Joined:
Feb 2025
Reputation:
0
After long efforts and long customs processes, I was able to have a compatible ecu, albeit difficult, H45214a0 I want to work with afterburner now, but I can't find the u2 and u3 integration, is there an alternative solution about this, what can we do?