Skip to content

Commit

Permalink
Start moving to 6 significant bits only, for improved robustness
Browse files Browse the repository at this point in the history
  • Loading branch information
laneboysrc committed Mar 9, 2014
1 parent e2b8fdb commit 04c9b2d
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 111 deletions.
14 changes: 7 additions & 7 deletions firmware/pulse-measurement/servo-input.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ void Read_input(void) {

value = (TMR1H << 8) + TMR1L;

// Remove the offset we added in the transmitter to avoid tiny
// pulse durations
value -= 0x20;

/* If we receive a value > 0x880 then it can only be the special value
0xa04, which is used for syncing as well as calibrating the oscillator.
Expand All @@ -70,6 +67,9 @@ void Read_input(void) {
of how mis-tuned our local oscillator is.
*/
if (value <= 0x880) {
// Remove the offset we added in the transmitter to avoid tiny
// pulse durations
//value -= 0x20;
return;
}

Expand All @@ -95,18 +95,18 @@ void Read_input(void) {
// Convert 6-bit signed into 6-bit unsigned
i = i ^ 0x20;

if (value < 0x9f1) {
if (value < 0xa31) {
flags.locked = 0;
i += 10;
}
else if (value > 0xa17) {
else if (value > 0xa57) {
flags.locked = 0;
i -= 10;
}
else if (value < 0xa01) {
else if (value < 0xa3e) {
++i;
}
else if (value > 0xa07) {
else if (value > 0xa42) {
--i;
}
else {
Expand Down
44 changes: 29 additions & 15 deletions hk310-filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
import time

values = [
0xa0,
0x0f,
0x00,
0x02
0, # 1 bit
0x3f, # 6 bits
0x1f, # 5 bits
0x1f # 5 bits
]


Expand All @@ -34,35 +34,49 @@
def prepareValues():
# Sanitize values
for i, _ in enumerate(values):
if i == 1:
values[i] = values[i] & 0x7f
elif i>= 2:
if i == 0:
values[i] = values[i] & 0x01
elif i == 1:
values[i] = values[i] & 0x3f
elif i>= 2:
values[i] = values[i] & 0x1f
new = values[i]
old = values[i - 1]
# Maximize the difference between adjacent values
# This results in a minimum difference of 0x20
if abs(old - new) < abs(old - (new | 0x40)):
new = new | 0x40
# This results in a minimum difference of 0x200
if abs(old - new) < abs(old - (new | (0x400 >> 5))):
new = new | (0x400 >> 5)
values[i] = new

for i, _ in enumerate(values):
print nextValue(i)


c = 0

def nextValue(idx):
global values

rx_desired = values[idx] << 4
rx_desired += 0x20; # Add 0x20 to avoid tiny pulse durations
if rx_desired >= 0x700:
rx_desired += 2 # Above 0x700 add 2 for better stability!
global c

if idx == 0:
rx_desired = 0xa40
else:
rx_desired = values[idx] << 5
rx_desired = c << 5
c += 1
if c > 0x3f:
c = 0
#rx_desired += 8 # Add 0x08 as it is the desired value, so that we have -8 /+ 24 room for jitter
rx_desired += 0x20 # Add 0x20 to avoid tiny pulse durations
#if rx_desired >= 0x700:
rx_desired += (rx_desired >> 8) #
rx = 2720 - 1 - rx_desired
return rx * 16 / 17


prepareValues()


def crc16_ccitt(crc, byte):
""" Add a byte to the CRC16-CCITT checksum.
"""
Expand Down
156 changes: 67 additions & 89 deletions receiver-dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,39 @@
TIMING_OFFSET = 0x20

jitterString0x0f = [
# 0123456789abcdef
'|* . |',
'| * . |',
'| * . |',
'| * . |',
'| * . |',
'| * . |',
'| * . |',
'| *. |',
'| * |',
'| .* |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . *|'
# 0123456789abcdef0123456789abcdef
'|* . |',
'| * . |',
'| * . |',
'| * . |',
'| * . |',
'| * . |',
'| * . |',
'| *. |',
'| * |',
'| .* |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . * |'
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . * |',
'| . *|'
]


Expand All @@ -54,26 +70,26 @@ def processValue(value):
global receivedValues
global startTime

data = value >> 4
data = value >> 5

print " 0x%03x 0x%02x" % (value, data),
if oldData != data:
print " %s" % (int2bin(data, 8), ),
if data == 0xa0:
if value > 0x880:
now = time.time()
print "%3dms " % (int((now - startTime) * 1000), ),
startTime = now
if valueCount != 3:
print " VALUECOUNT not 3: %d" % valueCount,
else:
error = False
for i, _ in enumerate(receivedValues):
if i == 0:
if expectedValues[i] != (receivedValues[i] & 0x3f):
error = True
else:
if expectedValues[i] != (receivedValues[i] & 0x1f):
error = True
#for i, _ in enumerate(receivedValues):
# if i == 0:
# if expectedValues[i] != (receivedValues[i] & 0x3f):
# error = True
# else:
# if expectedValues[i] != (receivedValues[i] & 0x1f):
# error = True
if error:
print " DATA ERROR!",
sys.exit(1)
Expand All @@ -100,7 +116,7 @@ def dump(port):

diffs = []
for _ in range(4):
diffs.append(0xa04)
diffs.append(0xa40)

while True:
c = s.read(1)
Expand All @@ -113,73 +129,35 @@ def dump(port):
value = int(numString, 10)
except ValueError:
continue

if value < 0x880:
# Show the jitter diagram (lower 4 bits)
jitter = value & 0x1f
print jitterString0x0f[jitter],
else:
print '| . |',

# Remove the offset we added in the transmitter to ensure the minimum
# pulse does not go down to zero.
value -= TIMING_OFFSET

# Show the jitter diagram (lower 4 bits)
jitter = value & 0xf
print jitterString0x0f[jitter],
print "0x%03x" % (value, ),

if abs(oldValue - value) <= 4:
# Same value as previous reading (+/- jitter): treat it as "good"
largeChange = False
oldValue = value
print " ",

# Calculate a rolling average of the last n sync pulses
if value > 0x880:
diffs.pop(0)
diffs.append(value)
avg = 0
for d in diffs:
avg += d
avg = (avg) / len(diffs)
print "avg=%3x" % (avg, ),
else:
print " ",

processValue(value)

elif abs(oldValue - value) > 0x100:
# A change > 0x100 means we have gone from one payload value to the
# next. We have to wait for a second reading before we can
# process the new value, because we may deal with a glitch at the
# same time as data changes.

# If there are two consecutive large values it means we have only
# one reading of the previous value, which we can not rely on since
# it may have been a glitch. But at least we know exactly which
# payload value is affected.
if largeChange:
print "c*****",
else:
print "c ",
largeChange = True
oldValue = value

# If the value is a sync pulse we process always as we don't care
# about the absolute value of the sync pulse, so a potential glitch
# does not matter.
if value > 0x880:
print " ",
processValue(value)

# Remove the offset we added in the transmitter to ensure the minimum
# pulse does not go down to zero.
if value < 0x880:
value -= TIMING_OFFSET


# Calculate a rolling average of the last n sync pulses
if value > 0x880:
diffs.pop(0)
diffs.append(value)
avg = 0
for d in diffs:
avg += d
avg = (avg) / len(diffs)
print "avg=%3x" % (avg, ),
else:
# A change larger than the jitter range means we are dealing with
# a glitch. Since the glitch is always longer (because the glitch
# is caused by the program execution being interrupted by an
# interrupt routine), we use the smaller of the adjacent values.
largeChange = False
if (oldValue < value):
value = oldValue
print "G>>>>>",

print " ",
oldValue = value
processValue(value)
processValue(value)

print

Expand Down

0 comments on commit 04c9b2d

Please sign in to comment.