PDA

View Full Version : Decoding serial data bytes and nibbles.



retepsnikrep
- 17th January 2018, 17:04
I have a hex serial 15 byte data stream in a byte array.

ED,1E,D2,EF,2E,D3,ED,2E,D2,EF,2E,D3,ED,1E,D2,

It needs to be chopped up into 10 x 12 bit data blocks as below.

ED1,ED2,EF2,ED3,ED1,ED2,EF2,ED3,ED1,ED2

How can i do that efficiently so I end up with each 12 bit block in a word array variable. eg

DataWord[0] = ED1
DataWord[1] = ED2

etc etc

Shifting came to mind but the logic scrambled my brain. Thanks for ideas

Dave
- 17th January 2018, 22:06
'************************************************* ***************
'* Name : UNTITLED.BAS *
'* Author : David Purola *
'* Notice : Copyright (c) 2018 Tronex Products *
'* : All Rights Reserved *
'* Date : 1/17/2018 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
indata var byte[15] 'assuming byte 14 is most significant
dataword var word[10] 'assuming word 9 is most significant
outpointer var byte

outpointer = 0
while outpointer < 10
select case outpointer
case 9
dataword(outpointer) = (indata(14) << 4) + (indata(13) & $f0)
case 8
dataword(outpointer) = ((indata(13) & $0f) << 8) + indata(12)
case 7
dataword(outpointer) = (indata(11) << 4) + (indata(10) & $f0)
case 6
dataword(outpointer) = ((indata(10) & $0f) << 8) + indata(9)
case 5
dataword(outpointer) = (indata(8) << 4) + (indata(7) & $f0)
case 4
dataword(outpointer) = ((indata(7) & $0f) << 8) + indata(6)
case 3
dataword(outpointer) = (indata(5) << 4) + (indata(4) & $f0)
case 2
dataword(outpointer) = ((indata(4) & $0f) << 8) + indata(3)
case 1
dataword(outpointer) = (indata(2) << 4) + (indata(1) & $f0)
case 0
dataword(outpointer) = ((indata(1) & $0f) << 8) + indata(0)
end select
outpointer = outpointer + 1
wend

Dave
- 17th January 2018, 22:21
'another way....
indata var byte[15] 'assuming byte 14 is most significant
dataword var word[10] 'assuming word 9 is most significant
outpointer var byte
inpointer var byte

outpointer = 0
while outpointer < 10
inpointer = 0
while inpointer < 12
dataword.0((outpointer * 12) + inpointer) = indata.0((outpointer * 12) + inpointer)
inpointer = inpointer + 1
wend
outpointer = outpointer + 1
wend

richard
- 18th January 2018, 00:08
neither of daves options works for me, I might be imagining the input differently

I have a hex serial 15 byte data stream in a byte array.
would need 30 bytes and could be parsed using serin2 ...[hex3 dw[0],hex3 dw[1] .......

I assume a input constructed like this,

ie 15 binary values in this order ,
arraywrite inbuff ,[$ED,$1E,$D2,$EF,$2E,$D3,$ED,$2E,$D2,$EF,$2E,$D3,$E D,$1E,$D2]




this does work





Pause 500 ' LCD initialize time
lcdout $FE,1
inbuff var byte[15]

dataword var word[10]
d var byte
INPOINTER VAR BYTE
outpointer var byte
arraywrite inbuff ,[$ED,$1E,$D2,$EF,$2E,$D3,$ED,$2E,$D2,$EF,$2E,$D3,$E D,$1E,$D2]


for d=0 to 4
dataword[d*2]=inbuff[d*3]*16+inbuff[d*3+1]>>4
dataword[d*2+1]=inbuff[d*3+2]+(inbuff[d*3+1]&$f)*256
next

for d=0 to 4
IF D=4 THEN
lcdout $FE,$80+d*4,hex3 dataword[d*2]
lcdout $FE,$c0+d*4,hex3 dataword[d*2+1]
ELSE
lcdout $FE,$80+d*4,hex3 dataword[d*2],","
lcdout $FE,$c0+d*4,hex3 dataword[d*2+1],","
ENDIF
next

richard
- 18th January 2018, 00:41
daves idea compiles to be 200 words shorter . I like that
but I still can't get it going

richard
- 18th January 2018, 01:49
to make I work
the input array needs its bit order endianness reversed then the result needs the same treatment
which defeats any gain



for d=0 to 14
inbuff[d]= inbuff[d] rev 8
next



outpointer = 0
while outpointer < 10
inpointer = outpointer*12
d=0
while d<12
dataword.0((outpointer * 16) + d) = inbuff.0(d + inpointer)
d=d+1
wend
dataword[outpointer]=dataword[outpointer] rev 12
outpointer= outpointer + 1
wend

retepsnikrep
- 18th January 2018, 08:22
Thanks to all your help.

I ended up using this bit but it's still boggling my mind a bit as to how it actually works.



for d=0 to 4
dataword[d*2]=inbuff[d*3]*16+inbuff[d*3+1]>>4
dataword[d*2+1]=inbuff[d*3+2]+(inbuff[d*3+1]&$f)*256
next