-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathibus.py
85 lines (70 loc) · 2.86 KB
/
ibus.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
from machine import UART
# Works by connecting to uart, transferring data and then disconnecting
# Allows ibus to be polled regularly without creating a block
# returns raw values
# To make meaningful there is a normalize static method
# approx (-100 to +100) for default (standard) controls
# 0 is centre. The zero point can be adjusted on the controller
# actual value of min and maximum may differ
# approx (0 to 100) for dials
# Select appropriate uart pin (following are defaults)
# For ibus receive then only RX pin needs to be connected
# UART 0: TX pin 0 GP0 RX pin 1 GP1
# UART 1: TX pin 6 GP4 RX pin 7 GP5
# Connect appropriate RX pin to rightmost pin on FS-iA6B
# returns list of channel values. First value (pseudo channel 0) is status
# 0 = initial values
# 1 = new values
# -1 = failed to receive data old values sent
# -2 = checksum error
class IBus ():
# Number of channels (FS-iA6B has 6)
def __init__ (self, uart_num, baud=115200, num_channels=6):
self.uart_num = uart_num
self.baud = baud
self.uart = UART(self.uart_num, self.baud)
self.num_channels = num_channels
# ch is channel value
self.ch = []
# Set channel values to 0
for i in range (self.num_channels+1):
self.ch.append(0)
# Returns list with raw data
def read(self):
# Max 10 attempts to read
for z in range(10):
buffer = bytearray (31)
char = self.uart.read(1)
# check for 0x20
if char == b'\x20':
# read reset of string into buffer
self.uart.readinto(buffer)
checksum = 0xffdf # 0xffff - 0x20
# check checksum
for i in range(29):
checksum -= buffer[i]
if checksum == (buffer[30] << 8) | buffer[29]:
# buffer[0] = 0x40
self.ch[0] = 1 # status 1 = success
for i in range (1, self.num_channels + 1):
self.ch[i] = (buffer[(i*2)-1] + (buffer[i*2] << 8))
return self.ch
else:
# Checksum error
self.ch[0] = -2
else:
self.ch[0] = -1
# Reach here then timed out
self.ch[0] = -1
return self.ch
# Convert to meaningful values - eg. -100 to 100
# Typical use for FS-iA6B
# channel 1 to 4 use type="default" provides result from -100 to +100 (0 in centre)
# channel 5 & 6 are dials type="dial" provides result from 0 to 100
# Note approx depends upon calibration etc.
@staticmethod
def normalize (value, type="default"):
if (type == "dial"):
return ((value - 1000) / 10)
else:
return ((value - 1500) / 5)