mnsnoop / esp32Micronet

6 stars 3 forks source link

Handling Command / Parameter Packets #2

Open pionex opened 2 years ago

pionex commented 2 years ago

I am trying to handle the command to set / reset the race timer. Looking at another micronet project (https://github.com/Rodemfr/MicronetToNMEA/blob/master/Micronet.h) and my own received packets, I have determined that the 0xFD message that sets the timer is a 0x06 Command Packet rather than a 0x02 Data Packet.

I can now receive the messages from my racemaster, but I have not had luck yet sending a 0x06 message that will reset / start the timer.

The messages generated by the racemaster look like: 0130.731583:INF Got Timer Message0130.731638:DBG RX 022 bytes. +034181 μs: (p000000/d+34181) | 81 09 18 C1 | 87 09 2A 56 | 06 | 19 00 92 | 14 14 | FD 00 09 00 01 00 48 4F

0xFD - Timer Setup 0x00 - Unknown (Seems to always be 0x00) 0x09 - Time in Minutes 0x00 - Unknown (seconds? although can't set seconds using UI) 0x01 - Unknown - Changes 0x00 - Unknown - Changes 0x48 - Counts up with each command 0x4F - Simple checksum of the previous 7 bytes

pionex commented 2 years ago

I have added this code which appears to initially work. The actual protocol would send the message up to 5 times until it has responses from the other units. At some point I will work on a PR that fully implements the protocol.

void Micronet::SetTimer(uint8_t hours, uint8_t minutes, uint8_t seconds, bool start) { _uMNPacket pPacket; SetTimer(&pPacket, hours, minutes, seconds, start); Send(pPacket, GetNextPacketWindow(mnIdMyDevice, 0x06));
}

void Micronet::SetTimer(_uMNPacket *p, uint8_t hours, uint8_t minutes, uint8_t seconds, bool start) { static uint8_t counter = 0;

if (!p) return;

int iLength = 8;

p->sHeader.mnIdNetwork = mnIdMyNetwork; p->sHeader.mnIdDevice = mnIdMyDevice; p->sHeader.bPacketType = 0x06; p->sHeader.bUnk1 = 0x09; p->sHeader.bSignalQuality = 0xEF; //fixme. put rssi here p->sHeader.bChecksum = GetCRC(p->bRaw, 11); p->sHeader.bLengthChecksum = p->sHeader.bLength = iLength + 12;

p->sHeader.bData[0] = 0xFD; // Set Timer p->sHeader.bData[1] = hours;
p->sHeader.bData[2] = minutes;
p->sHeader.bData[3] = seconds; p->sHeader.bData[4] = 0x10; // Unknown p->sHeader.bData[5] = start ? 0x01 : 0x00; // Start / Stop p->sHeader.bData[6] = counter++;

p->sHeader.bData[7] = GetCRC(p->sHeader.bData, iLength - 1); }

mnsnoop commented 2 years ago

It's a good start. To handle command packets required a whole subsystem to keep track of all the network's settings, third round collision avoidance, command acknowledgement tracking, etc. If you're up for it god speed but if you want a quicker way using the data packet to control the timer as mentioned in issue 1 would be much easier.

There's little difference between data packets and command packets. I've sent data in command packets and commands in data packets. I believe the packets are misunderstood. 0x02 are like a UDP packet in that if they get dropped they get dropped while 0x06 are like a TCP packet being ack'd and counted.

edit: I saw in one of your replies that doesn't appear here that you said:

I am still not sure why index 4 of the data payload changes between 02, 08, 10, 20, 40, and 80. I also don't know how important the second to last byte is that increments with each press.

Index 4 is probably the status byte telling the other devices what the timer is doing and/or what you are doing to the timer via the buttons. You should see a pattern with starting/stopping/restarting/running the timer. The second to last byte is the 0x06 packet counter. Each 0x06 packet increments that by one. If another device's 0x06 counter is at 6 and it sees a 0x06 packet with an 8 it knows it missed something and can request a settings dump to resync with the network.