> pointers Use a shift register (byte vector) containing pulse widths. In the beginning you are training so there will be some known data which you shift in. If you have a longer vector you can shift in pulse widths for the whole sync block (I did this with a vector of length 16 for two bytes of preamble). The average of the sync block is the slice level used to discriminate it (assuming the number of 1's and 0's in the preamble is equal - which it is because I made it so). When the speed changes then the slice level needs to shift. I assume that the speed change over a few bits (16) is small and that the average data is noise. Else you will need to fix the slice level using the delta (delta = pulse_width - slice level), which is signed, and needs to be filtered. As the speed changes (f.ex. increases) the long period will become shorter, and closer to the slice level, and the short period will become shorter and farther from the slice level. Knowing the normal delta you had at start, each delta can be used to correct the slice level. You choose how to process the slice level and how to filter. Then starting with this slice level, you slice data (pulse widths) and then adjust the slice level so it represents the the running average of recevied data, for each bit. This is really simple (hmm). There are more elaborate schemes but I used a simple one. My data was not varying 30:1. What is the data source ? 30:1 is too much even for swipe card readers. I did this about 11 years ago for a Z80 ;-) Peter -- http://www.piclist.com hint: The list server can filter out subtopics (like ads or off topics) for you. See http://www.piclist.com/#topics