Open frezik opened 8 years ago
OK, I get the point. I made some thoughts about this in the past too.
The only solution I can up was, add a crystal (or use another IC) to the transponder for more correct pulses (timings) and do the parsing of the codes via interrupts in the ir_daemon.
Regarding your solution, don't know if this will fix the problem (neither do I know if my suggestion will fix it) but let's try yours.
I think it will be a combination of the two--longer header length, and an external crystal.
I've been playing with some transmitters on a custom PCB, and using LIRC to get the raw pulse/space data. With an attiny85 on its internal 8MHz clock, the data is all over the place.
I then pulled the attiny out of its socket and used jumpers from an Arduino (atmega328, 16MHz external crystal) to hit the right pins in the socket to drive the circuit. I used a sketch based on the sendRaw example from the Arduino-IRremote library, which you can see here:
Using the same circuit board, those numbers came out as clean as can be expected for IR pulses. I doubt the switch to the atmega matters. It's the clock that's doing it.
As another experiment, I set the attiny85 for a 1 MHz internal clock. Those numbers came out almost as clean as the Arduino. The only problem was that it wasn't quite fast enough to switch at 300us. The data bits almost always came out at 600us.
The one thing is that from these tests, I would have expected this to be all but unusable. Seems like there's enough people using the system "in the wild" that somebody would have noticed that by now.
After testing again, I think it's actually working fine with the 300us timing on the 1MHz clock. See:
This also removes the delay at the end of the loop. I believe this is what may have been helping the previous system to recover. With a longer header length, it shouldn't be necessary. In practice, removing that delay is likely to shorten the effective distance needed for a clean read, since the transmitter can send more duplicate codes.
It also does an infinite loop with while(1){...}
. This is faster than waiting for loop()
to be continuously called.
The docs were also cleaned up, with issue #43 cleaned up, and the protocol header redefined. The math at the end for the length of the transmission was also corrected for the new header. I figured it was worth keeping the previous doc around while transmitters are still out there, so I moved it into ir_pulses_old.md
.
This branch also has some of my work for the v2 ir_daemon, which runs off LIRC.
If you are changing protocol anyway (requires transponder reflashing, etc) - maybe add single-bit checksum too? One bit checksum for 6 bits of data (for example, XOR'ed) - does not add much payload, but would filter random ID's appearing in list (this happens sometimes). Usually ID can be read several times when going trough gate, so ID with mistake is not big issue.
I'm not sure how this plays with new ir_daemon - maybe requires many changes?
Pass the id number through an xmodem crc and then tack the resulting checksum at the end of the signal. If on the rx side the checksum doesnt add up to the id sent, discard as its an invalid (1/2 received) signal. This should work regardless of timing.
frezik, how do i run ir daemon v2, i.ve already install lirc dan cpan
Looking over the existing IR protocol design:
https://github.com/polyvision/EasyRaceLapTimer/blob/master/docs/ir_pulses.md
I thought of a situation that doesn't seem to have a solution in the current system (though I may have missed something). The data stream starts with a 300us pulse and 300us space as a header. It then alternates between pulses and spaces, with a 1-bit sent as 600us and 0-bit as 300us.
Here's the issue: let's say the quadcopter flies in range of the sensor just as it sends the second bit after the header (which will be a space). The sensor will see this as a single long space after the last quadcopter left the sensor range. Let's say the next pulse and space (third and fourth bits after the header) both happen to be 0. This will be detected as the start of a new header, and bits will be parsed from there as if the code had just started--obviously not the correct situation!
Since the quadcopter's transponder will keep cycling the same code, the next header will be parsed as a pair of zeros in the middle of a code. The software doesn't have a chance to recover.
This can be corrected by dealing with a longer code. The current equation on the page suggests that in the worst-case of a quad travelling at 120km/s, the complete code would be transmitted over the course of 15cm of movement. I suggest designing for 3 or more sensors wired in parallel to allow a budget of at least 30cm. This would be a marginal additional cost with slightly more complicated wiring.
With that change, the header can be changed to a 1200us pulse/1200us space. This allows the sensor code to easily throw away the initial partial code, then pick up the next good code. Duplicates sent in a short time period need to be thrown out, but that's true, anyway.
I'd also recommend sensor designers wire multiple receivers for at least 60cm. That gives the system the best chance of correctly picking up the code.