Open ernprivado opened 1 year ago
Heureka! :)
I managed to send the proper telegrams with hcitool on my raspi - without knowing what I was doing...
sudo su hciconfig hci0 up hciconfig hci0 leadv 3 // switch MK6.0 to BT-Mode hcitool -i hci0 cmd 08 0008 25 02 01 02 1b ff f0 ff 6D B6 43 CF 7E 8F 47 11 88 66 59 38 D1 7A AA 26 49 5E 13 14 15 16 17 18 // stop all channels hcitool -i hci0 cmd 08 0008 25 02 01 02 1b ff f0 ff 6D B6 43 CF 7E 8F 47 11 84 66 59 38 D1 7A AA 34 67 4A 55 BF 15 16 17 18 // channel 1 fullspeed hcitool -i hci0 cmd 08 0008 25 02 01 02 1b ff f0 ff 6d b6 43 cf 7e 8f 47 11 84 66 59 47 d1 7a aa 34 67 4a ed b7 15 16 17 18
hcitool -i hci0 cmd 08 0008 length: 25 (hex!) flags: 02 01 02 length: 1b type: ff (-> manufacturer specific) company id: ff f0 data: rest
Fantastic, you are a genius ! ;-) I confirm it work on my raspi zero w too !
when launching cmd for full speed, the motor run but make a stop at intervalls and go back to full speed. Do you believe it's related to advertisement speed ? all in all, this is a breakthrough, now a computer can drive any motor from a shell script or programming language !
when launching cmd for full speed, the motor run but make a stop at intervalls and go back to full speed. Do you believe it's related to advertisement speed?
Yes, we have to increase the advertisement frequency.
I haven't tested it but i think Here is a link how to increase BLE advertisement is the solution.
when launching cmd for full speed, the motor run but make a stop at intervalls and go back to full speed. Do you believe it's related to advertisement frequency?
Yes, we have to increase the advertisement speed.
I haven't tested IT but i think Here is a link how to increase BLE advertisement is the solution.
Yep, instead of
hciconfig hci0 leadv 3
I used this:
hcitool -i hci0 cmd 08 0008 25 02 01 02 1b ff f0 ff 6D B6 43 CF 7E 8F 47 11 88 66 59 38 D1 7A AA 26 49 5E 13 14 15 16 17 18
hcitool -i hci0 cmd 0x08 0x0006 A0 00 A0 00 03 00 00 00 00 00 00 00 00 07 00
hcitool -i hci0 cmd 0x08 0x000a 01
the motor now run without pause ;-) perfect
Now, I need to write a function to build the correct sequence of hex for each case (channel, motor direction, motor power...)
OK, that's fine :) Now you have to transfer the crypt-function from here to i.E. python (the function TryDecryptBruteForce) is not needed. All functions in this file are static - that's pretty easy to transfer - no OOP (object oriented programming). Then, to test, if you put the byte-arrays from MouldKing_6_0_Modul.cs in the crypt-function you have to get back the values in my comments. I think it would make sense to create a git repo for that so we can exchange code and knowhow ;) Could you create one?
OK, that's fine :) Now you have to transfer the crypt-function from here to i.E. python (the function TryDecryptBruteForce) is not needed. All functions in this file are static - that's pretty easy to transfer - no OOP (object oriented programming). Then, to test, if you put the byte-arrays from MouldKing_6_0_Modul.cs in the crypt-function you have to get back the values in my comments. I think it would make sense to create a git repo for that so we can exchange code and knowhow ;) Could you create one?
Please, excuse me, but I'm no programmer ;-(
However, I tried to convert code from C# to python with online tools, for now I came up with this, the code has no errors but the results arent what they should be :
import array
from pprint import pprint
# Define a byte array for Telegram Connect
telegram_connect = [0x6D, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x92]
telegram_base_device_a = [0x61, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9E]
telegram_base_device_b = [0x62, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9D]
telegram_base_device_c = [0x63, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9C]
Array_C1C2C3C4C5 = array.array('B', [0xC1, 0xC2, 0xC3, 0xC4, 0xC5])
MagicArray_37 = [0] * 37
MagicArray_63 = [0] * 63
def Crypt(rawDataArray):
targetArrayLength = len(Array_C1C2C3C4C5) + len(rawDataArray) + 20
targetArray = bytearray(targetArrayLength)
targetArray[15] = 113
targetArray[16] = 15
targetArray[17] = 85
for index in range(len(Array_C1C2C3C4C5)):
targetArray[index + 18] = Array_C1C2C3C4C5[(len(Array_C1C2C3C4C5) - index) - 1]
targetArray[18 + len(Array_C1C2C3C4C5):] = rawDataArray
for index in range(15, len(Array_C1C2C3C4C5) + 18):
targetArray[index] = revert_bits_byte(targetArray[index])
checksum = calc_checksum_from_arrays(Array_C1C2C3C4C5, rawDataArray)
targetArray[len(Array_C1C2C3C4C5) + 18 + len(rawDataArray):] = [(checksum & 255), ((checksum >> 8) & 255)]
magicNumberArray_63 = MagicArray_63.copy()
tempArrayLength = targetArrayLength - 18
tempArray = targetArray[18:].copy()
crypt_array(tempArray, magicNumberArray_63)
targetArray[18:] = tempArray
magicNumberArray_37 = MagicArray_37.copy()
crypt_array(targetArray, magicNumberArray_37)
telegramArray = bytearray(24)
lengthResultArray = len(Array_C1C2C3C4C5) + len(rawDataArray) + 5
telegramArray[:lengthResultArray] = targetArray[15:15 + lengthResultArray]
for index in range(lengthResultArray, len(telegramArray)):
telegramArray[index] = index + 1
return telegramArray
def create_magic_array(magic_number, size):
magic_array = [0] * size
magic_array[0] = 1
for index in range(1, 7):
magic_array[index] = (magic_number >> (6 - index)) & 1
return magic_array
def revert_bits_int(value):
result = 0
for index_bit in range(16):
if ((1 << index_bit) & value) != 0:
result |= 1 << (15 - index_bit)
return 65535 & result
def crypt_array(byte_array, magic_number_array):
# foreach byte of array
for index_byte in range(len(byte_array)):
current_byte = byte_array[index_byte]
current_result = 0
# foreach bit in byte
for index_bit in range(8):
current_result += (((current_byte >> index_bit) & 1) ^ shift_magic_array(magic_number_array)) << index_bit
byte_array[index_byte] = current_result & 255
return byte_array
def calc_checksum_from_arrays(first_array, second_array):
result = 65535
for first_array_index in range(len(first_array)):
result = (result ^ (first_array[(len(first_array) - 1) - first_array_index] << 8)) & 65535
for index_bit in range(8):
current_result = result & 32768
result <<= 1
if current_result != 0:
result ^= 4129
for current_byte in second_array:
result = ((revert_bits_byte(current_byte) << 8) ^ result) & 65535
for index_bit in range(8):
current_result = result & 32768
result <<= 1
if current_result != 0:
result ^= 4129
return revert_bits_int(result) ^ 65535
def shift_magic_array(i_arr):
# i_arr[3] = i_arr[2]
# i_arr[2] = i_arr[1]
# i_arr[1] = i_arr[0]
# i_arr[0] = i_arr[6]
# i_arr[6] = i_arr[5]
# i_arr[5] = i_arr[4]
# i_arr[4] = i_arr[3] ^ i_arr[6]
# return i_arr[0]
r0 = 3
r1 = i_arr[r0]
r2 = 6
r3 = i_arr[r2]
r1 = r1 ^ r3
r3 = 2
r4 = i_arr[r3]
i_arr[r0] = r4
r0 = 1
r4 = i_arr[r0]
i_arr[r3] = r4
r3 = 0
r4 = i_arr[r3]
i_arr[r0] = r4
r0 = i_arr[r2]
i_arr[r3] = r0
r0 = 5
r4 = i_arr[r0]
i_arr[r2] = r4
r2 = 4
r4 = i_arr[r2]
i_arr[r0] = r4
i_arr[r2] = r1
r6 = i_arr[r3]
return r6
def revert_bits_byte(value):
result = 0
for index_bit in range(8):
if ((1 << index_bit) & value) != 0:
result = result | (1 << (7 - index_bit))
return result
pprint(Crypt(telegram_connect))
the results returned :
>>> %Run MouldKingCrypt.py
bytearray(b'\x8e\xf0\xaa\xa3#\xc3C\x83m{\xa7\x80\x80\x80\x80\x92'
b'\xae\x8a\x13\x14\x15\x16\x17\x18')
...only a quick review - I don't have time till saturday: MagicArray_37 and MagicArray_63 aren't properly initialized
Insider the Crypt function you can replace
magicNumberArray_63 = MagicArray_63.copy()
magicNumberArray_37 = MagicArray_37.copy()
with
magicNumberArray_63 = create_magic_array(63, 7)
magicNumberArray_37 = create_magic_array(37, 7)
and delete
MagicArray_37 = [0] * 37
MagicArray_63 = [0] * 63
Here is a running version of your code
#!/usr/bin/python
import array
from pprint import pprint
# Define a byte array for Telegram Connect
telegram_connect = [0x6D, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x92]
telegram_base_device_a = [0x61, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9E]
telegram_base_device_b = [0x62, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9D]
telegram_base_device_c = [0x63, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9C]
Array_C1C2C3C4C5 = [0xC1, 0xC2, 0xC3, 0xC4, 0xC5]
def Crypt(rawDataArray):
targetArrayLength = len(Array_C1C2C3C4C5) + len(rawDataArray) + 20
targetArray = bytearray(targetArrayLength)
targetArray[15] = 113
targetArray[16] = 15
targetArray[17] = 85
for index in range(len(Array_C1C2C3C4C5)):
targetArray[index + 18] = Array_C1C2C3C4C5[(len(Array_C1C2C3C4C5) - index) - 1]
targetArray[18 + len(Array_C1C2C3C4C5):] = rawDataArray
for index in range(15, len(Array_C1C2C3C4C5) + 18):
targetArray[index] = revert_bits_byte(targetArray[index])
checksum = calc_checksum_from_arrays(Array_C1C2C3C4C5, rawDataArray)
targetArray[len(Array_C1C2C3C4C5) + 18 + len(rawDataArray):] = [(checksum & 255), ((checksum >> 8) & 255)]
magicNumberArray_63 = create_magic_array(63, 7)
tempArrayLength = targetArrayLength - 18
tempArray = targetArray[18:].copy()
crypt_array(tempArray, magicNumberArray_63)
targetArray[18:] = tempArray
magicNumberArray_37 = create_magic_array(37, 7)
crypt_array(targetArray, magicNumberArray_37)
telegramArray = bytearray(24)
lengthResultArray = len(Array_C1C2C3C4C5) + len(rawDataArray) + 5
telegramArray[:lengthResultArray] = targetArray[15:15 + lengthResultArray]
for index in range(lengthResultArray, len(telegramArray)):
telegramArray[index] = index + 1
return telegramArray
def create_magic_array(magic_number, size):
magic_array = [0] * size
magic_array[0] = 1
for index in range(1, 7):
magic_array[index] = (magic_number >> (6 - index)) & 1
return magic_array
def revert_bits_int(value):
result = 0
for index_bit in range(16):
if ((1 << index_bit) & value) != 0:
result |= 1 << (15 - index_bit)
return 65535 & result
def crypt_array(byte_array, magic_number_array):
# foreach byte of array
for index_byte in range(len(byte_array)):
current_byte = byte_array[index_byte]
current_result = 0
# foreach bit in byte
for index_bit in range(8):
current_result += (((current_byte >> index_bit) & 1) ^ shift_magic_array(magic_number_array)) << index_bit
byte_array[index_byte] = current_result & 255
return byte_array
def calc_checksum_from_arrays(first_array, second_array):
result = 65535
for first_array_index in range(len(first_array)):
result = (result ^ (first_array[(len(first_array) - 1) - first_array_index] << 8)) & 65535
for index_bit in range(8):
current_result = result & 32768
result <<= 1
if current_result != 0:
result ^= 4129
for current_byte in second_array:
result = ((revert_bits_byte(current_byte) << 8) ^ result) & 65535
for index_bit in range(8):
current_result = result & 32768
result <<= 1
if current_result != 0:
result ^= 4129
return revert_bits_int(result) ^ 65535
def shift_magic_array(i_arr):
# i_arr[3] = i_arr[2]
# i_arr[2] = i_arr[1]
# i_arr[1] = i_arr[0]
# i_arr[0] = i_arr[6]
# i_arr[6] = i_arr[5]
# i_arr[5] = i_arr[4]
# i_arr[4] = i_arr[3] ^ i_arr[6]
# return i_arr[0]
r0 = 3
r1 = i_arr[r0]
r2 = 6
r3 = i_arr[r2]
r1 = r1 ^ r3
r3 = 2
r4 = i_arr[r3]
i_arr[r0] = r4
r0 = 1
r4 = i_arr[r0]
i_arr[r3] = r4
r3 = 0
r4 = i_arr[r3]
i_arr[r0] = r4
r0 = i_arr[r2]
i_arr[r3] = r0
r0 = 5
r4 = i_arr[r0]
i_arr[r2] = r4
r2 = 4
r4 = i_arr[r2]
i_arr[r0] = r4
i_arr[r2] = r1
r6 = i_arr[r3]
return r6
def revert_bits_byte(value):
result = 0
for index_bit in range(8):
if ((1 << index_bit) & value) != 0:
result = result | (1 << (7 - index_bit))
return result
# pprint(Crypt(telegram_connect))
result = Crypt(telegram_connect)
print(' '.join(f'{x:02x}' for x in result))
Output:
/home/pi/dev/mkconnect/test.py
6d b6 43 cf 7e 8f 47 11 88 66 59 38 d1 7a aa 26 49 5e 13 14 15 16 17 18
I've corrected the code, now it work
import array
#from pprint import pprint
#import numpy as np
#np.set_printoptions(formatter={'int':hex})
# Define a byte array for Telegram Connect
telegram_connect = [0x6D, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x92]
telegram_base_device_a = [0x61, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9E]
telegram_base_device_b = [0x62, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9D]
telegram_base_device_c = [0x63, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9C]
Array_C1C2C3C4C5 = array.array('B', [0xC1, 0xC2, 0xC3, 0xC4, 0xC5])
def Crypt(rawDataArray):
targetArrayLength = len(Array_C1C2C3C4C5) + len(rawDataArray) + 20
targetArray = [0] * targetArrayLength
targetArray[15] = 113 #0x71
targetArray[16] = 15 #0x0F
targetArray[17] = 85 #0x55
for index in range(len(Array_C1C2C3C4C5)):
targetArray[index + 18] = Array_C1C2C3C4C5[(len(Array_C1C2C3C4C5) - index) - 1]
targetArray[18 + len(Array_C1C2C3C4C5):] = rawDataArray
for index in range(15, len(Array_C1C2C3C4C5) + 18):
targetArray[index] = revert_bits_byte(targetArray[index])
checksum = calc_checksum_from_arrays(Array_C1C2C3C4C5, rawDataArray)
targetArray[len(Array_C1C2C3C4C5) + 18 + len(rawDataArray):] = [(checksum & 255), ((checksum >> 8) & 255)]
magicNumberArray_63 = create_magic_array(63, 7)
tempArrayLength = targetArrayLength - 18
tempArray = targetArray[18:].copy()
crypt_array(tempArray, magicNumberArray_63)
targetArray[18:] = tempArray
magicNumberArray_37 = create_magic_array(37, 7)
crypt_array(targetArray, magicNumberArray_37)
telegramArray = [0] * 24
lengthResultArray = len(Array_C1C2C3C4C5) + len(rawDataArray) + 5
telegramArray[:lengthResultArray] = targetArray[15:15 + lengthResultArray]
for index in range(lengthResultArray, len(telegramArray)):
telegramArray[index] = index + 1
return telegramArray
def create_magic_array(magic_number, size):
magic_array = [0] * size
magic_array[0] = 1
for index in range(1, 7):
magic_array[index] = (magic_number >> (6 - index)) & 1
return magic_array
def revert_bits_int(value):
result = 0
for index_bit in range(16):
if ((1 << index_bit) & value) != 0:
result |= 1 << (15 - index_bit)
return 65535 & result
def crypt_array(byte_array, magic_number_array):
# foreach byte of array
for index_byte in range(len(byte_array)):
current_byte = byte_array[index_byte]
current_result = 0
# foreach bit in byte
for index_bit in range(8):
current_result += (((current_byte >> index_bit) & 1) ^ shift_magic_array(magic_number_array)) << index_bit
byte_array[index_byte] = current_result & 255
return byte_array
def calc_checksum_from_arrays(first_array, second_array):
result = 65535
for first_array_index in range(len(first_array)):
result = (result ^ (first_array[(len(first_array) - 1) - first_array_index] << 8)) & 65535
for index_bit in range(8):
current_result = result & 32768
result <<= 1
if current_result != 0:
result ^= 4129
for current_byte in second_array:
result = ((revert_bits_byte(current_byte) << 8) ^ result) & 65535
for index_bit in range(8):
current_result = result & 32768
result <<= 1
if current_result != 0:
result ^= 4129
return revert_bits_int(result) ^ 65535
def shift_magic_array(i_arr):
# i_arr[3] = i_arr[2]
# i_arr[2] = i_arr[1]
# i_arr[1] = i_arr[0]
# i_arr[0] = i_arr[6]
# i_arr[6] = i_arr[5]
# i_arr[5] = i_arr[4]
# i_arr[4] = i_arr[3] ^ i_arr[6]
# return i_arr[0]
r0 = 3
r1 = i_arr[r0]
r2 = 6
r3 = i_arr[r2]
r1 = r1 ^ r3
r3 = 2
r4 = i_arr[r3]
i_arr[r0] = r4
r0 = 1
r4 = i_arr[r0]
i_arr[r3] = r4
r3 = 0
r4 = i_arr[r3]
i_arr[r0] = r4
r0 = i_arr[r2]
i_arr[r3] = r0
r0 = 5
r4 = i_arr[r0]
i_arr[r2] = r4
r2 = 4
r4 = i_arr[r2]
i_arr[r0] = r4
i_arr[r2] = r1
r6 = i_arr[r3]
return r6
def revert_bits_byte(value):
result = 0
for index_bit in range(8):
if ((1 << index_bit) & value) != 0:
result = result | (1 << (7 - index_bit))
return result
print(Crypt(telegram_connect))
print(Crypt(telegram_base_device_a))
Here is a running version of your code
#!/usr/bin/python import array from pprint import pprint # Define a byte array for Telegram Connect telegram_connect = [0x6D, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x92] telegram_base_device_a = [0x61, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9E] telegram_base_device_b = [0x62, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9D] telegram_base_device_c = [0x63, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9C] Array_C1C2C3C4C5 = [0xC1, 0xC2, 0xC3, 0xC4, 0xC5] def Crypt(rawDataArray): targetArrayLength = len(Array_C1C2C3C4C5) + len(rawDataArray) + 20 targetArray = bytearray(targetArrayLength) targetArray[15] = 113 targetArray[16] = 15 targetArray[17] = 85 for index in range(len(Array_C1C2C3C4C5)): targetArray[index + 18] = Array_C1C2C3C4C5[(len(Array_C1C2C3C4C5) - index) - 1] targetArray[18 + len(Array_C1C2C3C4C5):] = rawDataArray for index in range(15, len(Array_C1C2C3C4C5) + 18): targetArray[index] = revert_bits_byte(targetArray[index]) checksum = calc_checksum_from_arrays(Array_C1C2C3C4C5, rawDataArray) targetArray[len(Array_C1C2C3C4C5) + 18 + len(rawDataArray):] = [(checksum & 255), ((checksum >> 8) & 255)] magicNumberArray_63 = create_magic_array(63, 7) tempArrayLength = targetArrayLength - 18 tempArray = targetArray[18:].copy() crypt_array(tempArray, magicNumberArray_63) targetArray[18:] = tempArray magicNumberArray_37 = create_magic_array(37, 7) crypt_array(targetArray, magicNumberArray_37) telegramArray = bytearray(24) lengthResultArray = len(Array_C1C2C3C4C5) + len(rawDataArray) + 5 telegramArray[:lengthResultArray] = targetArray[15:15 + lengthResultArray] for index in range(lengthResultArray, len(telegramArray)): telegramArray[index] = index + 1 return telegramArray def create_magic_array(magic_number, size): magic_array = [0] * size magic_array[0] = 1 for index in range(1, 7): magic_array[index] = (magic_number >> (6 - index)) & 1 return magic_array def revert_bits_int(value): result = 0 for index_bit in range(16): if ((1 << index_bit) & value) != 0: result |= 1 << (15 - index_bit) return 65535 & result def crypt_array(byte_array, magic_number_array): # foreach byte of array for index_byte in range(len(byte_array)): current_byte = byte_array[index_byte] current_result = 0 # foreach bit in byte for index_bit in range(8): current_result += (((current_byte >> index_bit) & 1) ^ shift_magic_array(magic_number_array)) << index_bit byte_array[index_byte] = current_result & 255 return byte_array def calc_checksum_from_arrays(first_array, second_array): result = 65535 for first_array_index in range(len(first_array)): result = (result ^ (first_array[(len(first_array) - 1) - first_array_index] << 8)) & 65535 for index_bit in range(8): current_result = result & 32768 result <<= 1 if current_result != 0: result ^= 4129 for current_byte in second_array: result = ((revert_bits_byte(current_byte) << 8) ^ result) & 65535 for index_bit in range(8): current_result = result & 32768 result <<= 1 if current_result != 0: result ^= 4129 return revert_bits_int(result) ^ 65535 def shift_magic_array(i_arr): # i_arr[3] = i_arr[2] # i_arr[2] = i_arr[1] # i_arr[1] = i_arr[0] # i_arr[0] = i_arr[6] # i_arr[6] = i_arr[5] # i_arr[5] = i_arr[4] # i_arr[4] = i_arr[3] ^ i_arr[6] # return i_arr[0] r0 = 3 r1 = i_arr[r0] r2 = 6 r3 = i_arr[r2] r1 = r1 ^ r3 r3 = 2 r4 = i_arr[r3] i_arr[r0] = r4 r0 = 1 r4 = i_arr[r0] i_arr[r3] = r4 r3 = 0 r4 = i_arr[r3] i_arr[r0] = r4 r0 = i_arr[r2] i_arr[r3] = r0 r0 = 5 r4 = i_arr[r0] i_arr[r2] = r4 r2 = 4 r4 = i_arr[r2] i_arr[r0] = r4 i_arr[r2] = r1 r6 = i_arr[r3] return r6 def revert_bits_byte(value): result = 0 for index_bit in range(8): if ((1 << index_bit) & value) != 0: result = result | (1 << (7 - index_bit)) return result # pprint(Crypt(telegram_connect)) result = Crypt(telegram_connect) print(' '.join(f'{x:02x}' for x in result))
Output:
/home/pi/dev/mkconnect/test.py 6d b6 43 cf 7e 8f 47 11 88 66 59 38 d1 7a aa 26 49 5e 13 14 15 16 17 18
Oh thanks, sorry, I was looking at it in beetwen, I didn't see your post !
telegram_base_device_a seem to be the code for stopping the motors but how do you manage the choice of channel, rotation direction and motor's power ?
https://github.com/imurvai/brickcontroller2/assets/6136831/78c71be0-c5bd-4b8c-baab-36d14fdf9dc9
Many things to do yet, but very promising ! I will order a raspberry pi pico W (with embedded python interpreter and bluetooth) to test if that works too... but I have to find a way to bypass hcitool and send the commands directly to the integrated BT controller I hope it's possible on this device, if not I'll keep the raspi zero w.
Next step is to control channel selection, motor direction and motor power. After that, comes the nice part of using proximity sensor, color sensors and switchs via i2c which should be easy to do. In the end, why not make a pcb board with sensors connectors (i2c bus allow many peripherals on short distances with minimal cabling) and digital inputs (I think about magnetics dil relays, very cheap, and others simple mecanicals switchs, all those can act as limit switch)
I have another mould king 6.0 hub on order plus a bunch of motors to make tests
edit: it seems that there is issues for running on raspi pico : micropython instead of python
there is a simulator here (same error on real device) : https://wokwi.com/projects/new/micropython-pi-pico pasting the very same code is not working, I didn't had time to look at it more precisely
Traceback (most recent call last):
File "main.py", line 143, in <module>
File "main.py", line 23, in Crypt
NotImplementedError: array/bytes required on right side
Oh, i found something interesting: hcitool has been deprecated
edit: it seems that there is issues for running on raspi pico : micropython instead of python
there is a simulator here (same error on real device) : https://wokwi.com/projects/new/micropython-pi-pico pasting the very same code is not working, I didn't had time to look at it more precisely
Traceback (most recent call last): File "main.py", line 143, in <module> File "main.py", line 23, in Crypt NotImplementedError: array/bytes required on right side
I've corrected the code for the pico, now it appear to run correctly 👍
ps : just for reference, I found this code exemple for BT advertising on the pico controller: https://github.com/raspberrypi/pico-micropython-examples/blob/master/bluetooth/ble_advertising.py
#import array
import sys
import time
try:
from ulab import numpy as np
except ImportError:
import numpy as np
np.set_printoptions(threshold=1000)
#telegram_connect = np.array([0x6D, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x92])
#telegram_base_device_a = np.array([0x61, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9E])
#telegram_base_device_b = np.array([0x62, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9D], dtype=np.uint8)
#telegram_base_device_c = np.array([0x63, 0x7B, 0xA7, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x9C], dtype=np.uint8)
#Array_C1C2C3C4C5 = np.array([0xC1, 0xC2, 0xC3, 0xC4, 0xC5])
# Define a byte array for Telegram Connect
telegram_connect = np.array([109, 123, 167, 128, 128, 128, 128, 146], dtype=np.uint8)
telegram_base_device_a = np.array([97, 123, 167, 128, 128, 128, 128, 128, 128, 158], dtype=np.uint8)
telegram_base_device_b = np.array([98, 123, 167, 128, 128, 128, 128, 128, 128, 157], dtype=np.uint8)
telegram_base_device_c = np.array([99, 123, 167, 128, 128, 128, 128, 128, 128, 156], dtype=np.uint8)
Array_C1C2C3C4C5 = np.array([193, 194, 195, 196, 197], dtype=np.uint8)
def Crypt(rawDataArray):
# targetArrayLength should be 5+8+20 = 33 for connect
targetArrayLength = len(Array_C1C2C3C4C5) + len(rawDataArray) + 20
#targetArray = bytearray(targetArrayLength)
targetArray = np.zeros(targetArrayLength, dtype=np.uint8)
targetArray[15] = 113
targetArray[16] = 15
targetArray[17] = 85
for index in range(len(Array_C1C2C3C4C5)):
targetArray[index + 18] = Array_C1C2C3C4C5[(len(Array_C1C2C3C4C5) - index) - 1]
for index in range(len(rawDataArray)):
targetArray[18 + len(Array_C1C2C3C4C5) + index] = rawDataArray[index]
for index in range(15, len(Array_C1C2C3C4C5) + 18):
targetArray[index] = revert_bits_byte(targetArray[index])
checksum = calc_checksum_from_arrays(Array_C1C2C3C4C5, rawDataArray)
targetArray[len(Array_C1C2C3C4C5) + 18 + len(rawDataArray):] = [(checksum & 255), ((checksum >> 8) & 255)]
magicNumberArray_63 = create_magic_array(63, 7)
tempArrayLength = targetArrayLength - 18
tempArray = targetArray[18:].copy()
crypt_array(tempArray, magicNumberArray_63)
targetArray[18:] = tempArray
magicNumberArray_37 = create_magic_array(37, 7)
crypt_array(targetArray, magicNumberArray_37)
telegramArray = np.zeros(24, dtype=np.uint8)
lengthResultArray = len(Array_C1C2C3C4C5) + len(rawDataArray) + 5
telegramArray[:lengthResultArray] = targetArray[15:15 + lengthResultArray]
for index in range(lengthResultArray, len(telegramArray)):
telegramArray[index] = index + 1
return telegramArray
def create_magic_array(magic_number, size):
magic_array = [0] * size
magic_array[0] = 1
for index in range(1, 7):
magic_array[index] = (magic_number >> (6 - index)) & 1
return magic_array
def revert_bits_int(value):
result = 0
for index_bit in range(16):
if ((1 << index_bit) & value) != 0:
result |= 1 << (15 - index_bit)
return 65535 & result
def crypt_array(byte_array, magic_number_array):
# foreach byte of array
for index_byte in range(len(byte_array)):
current_byte = byte_array[index_byte]
current_result = 0
# foreach bit in byte
for index_bit in range(8):
current_result += (((current_byte >> index_bit) & 1) ^ shift_magic_array(magic_number_array)) << index_bit
byte_array[index_byte] = current_result & 255
return byte_array
def calc_checksum_from_arrays(first_array, second_array):
result = 65535
for first_array_index in range(len(first_array)):
result = (result ^ (first_array[(len(first_array) - 1) - first_array_index] << 8)) & 65535
for index_bit in range(8):
current_result = result & 32768
result <<= 1
if current_result != 0:
result ^= 4129
for current_byte in second_array:
result = ((revert_bits_byte(current_byte) << 8) ^ result) & 65535
for index_bit in range(8):
current_result = result & 32768
result <<= 1
if current_result != 0:
result ^= 4129
return revert_bits_int(result) ^ 65535
def shift_magic_array(i_arr):
# i_arr[3] = i_arr[2]
# i_arr[2] = i_arr[1]
# i_arr[1] = i_arr[0]
# i_arr[0] = i_arr[6]
# i_arr[6] = i_arr[5]
# i_arr[5] = i_arr[4]
# i_arr[4] = i_arr[3] ^ i_arr[6]
# return i_arr[0]
r0 = 3
r1 = i_arr[r0]
r2 = 6
r3 = i_arr[r2]
r1 = r1 ^ r3
r3 = 2
r4 = i_arr[r3]
i_arr[r0] = r4
r0 = 1
r4 = i_arr[r0]
i_arr[r3] = r4
r3 = 0
r4 = i_arr[r3]
i_arr[r0] = r4
r0 = i_arr[r2]
i_arr[r3] = r0
r0 = 5
r4 = i_arr[r0]
i_arr[r2] = r4
r2 = 4
r4 = i_arr[r2]
i_arr[r0] = r4
i_arr[r2] = r1
r6 = i_arr[r3]
return r6
def revert_bits_byte(value):
result = 0
for index_bit in range(8):
if ((1 << index_bit) & value) != 0:
result = result | (1 << (7 - index_bit))
return result
result = Crypt(telegram_connect)
result2 = Crypt(telegram_base_device_a)
print(' '.join(f'{x:02X}' for x in result))
print(' '.join(f'{x:02X}' for x in result2))
@elclaudio I have created the repo mkconnect-python. I suggest to continue the discussion there... :)
Hi I notice that there is no support for mould king hub. I was just wondering if there is a plan for it