Okay, let me continue observations. I've captured full exchange sequence from the beginning. My tool is 40V snow thrower (2600607), batt is 5ah (2927207)
Battery starts transmitting when a tool is rising Ohm line up, initially it passes 5 different signals in 100ms interval, then starts transmitting one sequence until a tool release the line. Not sure how long it will cycle this, may be it will periodically retransmit whole greeting sequence (say, for older devices).
Initial sync pulse length: 397us (marked as S below)
Long pulse length: 198us (marked as 1 below)
Short pulse length: 94us (marked as 0 below)
Inter-pulse pause: 100ms.
Initial sequence
Q means query from battery side
R means tool response
1. Nearly +700ms from the moment when line is up
Q: S 0 x 24
R: 0 x 15
2. +800 ms
Q S 0 x 24
R 1 0 1 1 0 1 0 0 0 1 0 0 1 0 1 1
3. +900 ms
Q S 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1 0 0 0 0
R 1 0 1 1 0 1 0 0 0 1 0 0 1 0 1 1
4. +1000 ms
Q S 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0
R 1 0 1 1 0 1 0 0 0 1 0 0 1 0 1 1
5. +1100 ms
Q S 0 0 1 1 0 0 0 0 1 0 1 1 0 1 0 0 1 0 0 1 1 1 0 0
R 1 0 1 1 0 1 0 0 0 1 0 0 1 0 1 1
Note: Surprisingly, first response is really only 15 bits. All further are 16 bits length
Continuous mode
6. +1300ms
Q S 1 1 1 0 0 0 0 0 1 1 1 0 1 0 0 0 0 1 1 1 1 0 0 0
R 1 0 1 1 0 1 0 0 0 1 0 0 1 0 1 1
7. +1500ms
Q S 1 1 1 0 0 0 0 0 1 1 1 0 1 0 0 0 0 1 1 1 1 0 0 0
R 1 0 1 1 0 1 0 0 0 1 0 0 1 0 1 1
... etc
Here is a arduino code, which works for me (chineese nano works perfectly). Didn't check yet for long load time, but at least it successfully starts.
const int LINE_PIN = 2;
const int S_PREAMBLE = 412;
const int S_SHORT = 105;
const int S_LONG = 205;
const int S_PAUSE = 100;
const int MSG_PAUSE = 1000;
#define MESSAGE_LENGTH 25
const int INITIAL[4][MESSAGE_LENGTH] = {
{'S', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{'S', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{'S', 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
{'S', 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}
};
const int PERIODIC[MESSAGE_LENGTH] = {'S', 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0};
typedef enum {
LINE_LOW,
LINE_FLOAT
} line_state_t;
void set_line(line_state_t state) {
switch (state) {
case LINE_LOW:
pinMode(LINE_PIN, OUTPUT);
digitalWrite(LINE_PIN, LOW);
break;
case LINE_FLOAT:
pinMode(LINE_PIN, INPUT);
break;
}
}
void send_pulse(int pulse) {
set_line(LINE_LOW);
switch (pulse) {
case 'S':
delayMicroseconds(S_PREAMBLE);
break;
case 0:
delayMicroseconds(S_SHORT);
break;
case 1:
delayMicroseconds(S_LONG);
break;
}
set_line(LINE_FLOAT);
}
void send_message(const int m[MESSAGE_LENGTH]) {
for (int idx = 0; idx < MESSAGE_LENGTH; idx++) {
send_pulse(m[idx]);
delayMicroseconds(S_PAUSE);
}
}
void setup() {
set_line(LINE_FLOAT);
}
int state = 0;
void loop() {
int line = digitalRead(LINE_PIN);
if (line == 0) {
state = 0;
return;
}
if (line == 1 && state == 0) {
delay(700);
}
if (state < 4) {
send_message(INITIAL[state]);
state ++;
delay(100);
} else {
send_message(PERIODIC);
delay(200);
}
}