Somewhere in the hash of his original posting he mentions that the data is changing slowly.
If you used one bit for a flag, you could send 128 different values of absolute data to initialize, then send a delta in the range -64 +63 (if you used two's compliment) at every sample that doesn't happen to fall on a legal "absolute" value.
If your "absolute" data ranged from 0.00 to 5.08 in steps of 0.04, then as long as the data really did move slowly, you'd never be off by more than
0.02, and then only for one transmission time.
--
Tim Wescott
Wescott Design Services
http://www.wescottdesign.com
That would be akin to an ADPCM (adaptive delta PCM) encoding, and yes, it could work reasonably well. If you're strictly limited to sending only one byte per sample time, it would be "lossy compression" due to the slight inaccuracies it would develop from time to time, but it might well be "good enough for folk music".
I think it'd be much smarter to just send the reading, in ASCII, with a linefeed at the end to boot -- that way you plug the module into a serial port and look at the result on a terminal when you're debugging problems.
But the OP's prose is somewhat impenetrable.
--
Tim Wescott
Wescott Design Services
http://www.wescottdesign.com
(sigh) Complete sentences and *thoughts* would make this *much* easier to understand...
"Send as packed BCD of the tenths and hundredths"
OK, so there goes your first byte (packed BCD=2*4b)
Now, you've got two more bits to encode, somewhere.
Presumably, you don't want to spend (transfer) another byte. So, all you can do is encode the bit in "time". I.e., build some sense of state into your algorithm (neglecting, for the moment, the startup issues of such an algorithm -- maybe your signal ALWAYS starts from some known value, etc).
So, if you've seen something approaching the high end of your encoding range (8x, 9x, etc.), you can send subsequent values that EXCEED that as 2r101xxxxx - 2r11111111 (or, 2r11111001, etc.).
I.e., 16rA0-16rA9 could represent 1.00-1.09, 16rB0-16rB9 as 1.10-1.19, etc. And, as you reach another "threshold", the encoding once again changes -- until you have extended your range to include 3.90-3.99.
This really seems kludgey. All to save 1 bit in a transmission? (0-3.99 can be encoded in 9 bits IF you want 0.01 precision in your values; less if you are willing to settle for less precision!)
A more worthwhile approach (if you are wed to BCD and can't cope with binary) might be to Chen-Ho encode your 2.25 digits into 8b.
No. If you use one of these datapoints, the other 100 go away because you are NOT using one of the 100 datapoints that represents them!
Pick one of the letters in the following string and insert it between these two X's: X X
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Now, pick one of the digits in the following string and insert it between those same two X's!
0123456789
Gee, where did your letter choice go??
You have more data available than space to fit (store) it. You have to encode the data in some "out of band" manner -- e.g., time/state.
But, that will only work if you can cleanly and deterministically *get* to the "correct" state in some fixed amount of time.
E.g., what do you do if you turn on your device (or, the PC) and the value to be sent is 3.49? As you can only represent 0.00-0.99 (or
0.00-2.55 or !), the first value that you ship to the PC will be "wrong". E.g., you may send (the code for) 0.99 -- but, clearly the value is NOT 0.99! You may then quickly follow up with some special code knowing the PC now has "memory of" 0.99 and, effectively, slew to a higher value (e.g., perhaps 0xFF tells the PC "add 1.00 to the previous value that you saw" while anything between 0xA0 and 0xE9 says "add the value LESS 0xA0 to the most recent value that you have").
So, send 0x99. Then, 0xFF (PC now is thinking 0.99+1=1.99). Then, another 0xFF (1.99+1=2.99) then 0xE9 (2.99+0xE9-0xA0=3.48 -- if I've done my hex math correctly) then 0xA1 to arrive at 3.48+0.01=3.49. But, each of these incremental values was "wrong" -- the input was
3.49 for ALL of them (and, presumably, hasnt changed in the interim)!
[Of course this encoding won't work. It's just something trivial to show you what the problem is. You are relying on time/state to convey additional information. So, there is always a risk that you will not be in-sync with the data unless you can guarantee that it never slews faster than your code can accommodate. Startup is obviously a bad time for such protocols!]
Actually I think I cracked the code. He is thinking that he can utilize some of the "don't care" bits that occur in the two digits, '8' and '9'. Not fully realizing that these can indeed be used... if these digits are transmitted. But when the two lsds are characters other than an 8 or 9 there are no don't care bits so you lose that capacity.
It is curious marketeering calling it 2-1/2 or 2-3/4 digits when they are in reality a shade under 2-1/3 and 2-2/3 respectively. Lg10(2) ~= 0.301 < 1/3
Fx yz first byte ix 1111xxxx where xxxx encodes the first digit in BCD second byte is yyyyzzzz where yyyy is the second digit and zzzz is the third,
If the reading is negative send 1110xxxx for the first byte instead. its reasonably compact and includes synchronisation information to recover from communicatons errors.
Alternatively maybe go full ascii as has been suggested.
yes, perhaps I should have termed them don't-care rather than illegal. In hardware terms , for the send end, AND D4,D7 (active H for tenths digit 9) and output goes to feed the control of 2 analogue gates that pass the 2 bits of the 0,1,2,or3 units data onto lines D5,D6. Convert to serial, and pass to pc where look-up or whatever will decript back to 9 and the units figure
It is well behaved data. I'd only be passing the units,u value, data superimposed on (.)9x when it is sent , so the receiver has the previous units value u' for logging and only has to monitor whether the next ,non-9 , data is 8x or 0x to know whether to log u' as u or u +1 eg for amended BCD of 1001xxxx and units value of 2 , transmit 1101xxxx then if the next non-9 data is 1000xxxx then units value is still the 2 if the next data is 0000xxxx then units value is 3 The transmitted data is full 8 bit data, not packed double BCD subset.
If the data changes that slowly there are a bazillion ways to compress and send the data. Are you sure the data will always have an x.9y to send in between x.8y and x+1.0y?
BTW, your earlier post seemed to be describing hardware to do the encode and decode. Is that really necessary? Can't software do this?
The only way the decoded data could jump 1 unit between samplings , is if there is an error in the sensing,coding or decoding, not the original input, so it can be ignored in software if a random glitch and flag as
-9999 ,or whatever, or the whole system is broken anyway. Decoding would by VB on a pc, so no limitations there.
I've no means of programming pics or controllers ,without kitting-up for all that plus learning to use it all, too long in the tooth for that now, and this is just a one off. Bits of paper and soldering iron only for me
ISTR a Nixie voltmeter that used an NE-2 positioned with the electrodes edgewise to make a '1'.
Cheers
Phil Hobbs
--
Dr Philip C D Hobbs
Principal Consultant
ElectroOptical Innovations LLC
Optics, Electro-optics, Photonics, Analog Electronics
160 North State Road #203
Briarcliff Manor NY 10510
hobbs at electrooptical dot net
http://electrooptical.net
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.