Skip to content

Commit 6e9ebfd

Browse files
committed
Mould King: control up to 4 bricks at the same time
1 parent c36b112 commit 6e9ebfd

File tree

4 files changed

+109
-44
lines changed

4 files changed

+109
-44
lines changed

Multiprotocol/MouldKg_nrf24l01.ino

Lines changed: 87 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,15 @@ Multiprotocol is distributed in the hope that it will be useful,
2929
#define MOULDKG_RF_NUM_CHANNELS 4
3030

3131
enum {
32-
MOULDKG_BINDTX=0,
33-
MOULDKG_BINDRX,
34-
MOULDKG_DATA,
32+
MOULDKG_BINDTX=0,
33+
MOULDKG_BINDRX,
34+
MOULDKG_PREP_DATA,
35+
MOULDKG_PREP_DATA1,
36+
MOULDKG_DATA,
3537
};
3638

39+
uint8_t MOULDKG_RX_id[4*3];
40+
3741
static void __attribute__((unused)) MOULDKG_send_packet()
3842
{
3943
uint8_t len = MOULDKG_BIND_PAYLOAD_SIZE;
@@ -45,14 +49,13 @@ static void __attribute__((unused)) MOULDKG_send_packet()
4549
}
4650
else
4751
{
48-
XN297_RFChannel(hopping_frequency[(packet_count>>1)&0x03]);
49-
52+
uint8_t n = num_ch<<2;
5053
if(sub_protocol == MOULDKG_ANALOG)
5154
{
5255
packet[0] = 0x36;
5356
uint8_t ch[]={ 1,0,2,3 };
5457
for(uint8_t i=0;i<4;i++)
55-
packet[i+4] = convert_channel_8b(ch[i]);
58+
packet[i+4] = convert_channel_8b(ch[i]+n);
5659
len = MOULDKG_PAYLOAD_SIZE_ANALOG;
5760
}
5861
else
@@ -63,28 +66,26 @@ static void __attribute__((unused)) MOULDKG_send_packet()
6366
{
6467
packet[0] = 0x31;
6568
//Button B
66-
if(Channel_data[CH2]>CHANNEL_MAX_COMMAND) val |= 0x40;
67-
else if(Channel_data[CH2]<CHANNEL_MIN_COMMAND) val |= 0x80;
69+
if(Channel_data[CH2+n]>CHANNEL_MAX_COMMAND) val |= 0x40;
70+
else if(Channel_data[CH2+n]<CHANNEL_MIN_COMMAND) val |= 0x80;
6871
//Button C
69-
if(Channel_data[CH3]>CHANNEL_MAX_COMMAND) val |= 0x10;
70-
else if(Channel_data[CH3]<CHANNEL_MIN_COMMAND) val |= 0x20;
72+
if(Channel_data[CH3+n]>CHANNEL_MAX_COMMAND) val |= 0x10;
73+
else if(Channel_data[CH3+n]<CHANNEL_MIN_COMMAND) val |= 0x20;
7174
}
7275
else
7376
{
7477
packet[0] = 0x30;
75-
val = 0x60
76-
| GET_FLAG(CH5_SW, 0x80) // Button E
77-
| GET_FLAG(CH6_SW, 0x10); // Button F
78+
val = 0x60;
79+
// | GET_FLAG(CH5_SW, 0x80) // Button E
80+
// | GET_FLAG(CH6_SW, 0x10); // Button F
7881
}
7982
//Button A
80-
if(Channel_data[CH1]>CHANNEL_MAX_COMMAND) val |= 0x01;
81-
else if(Channel_data[CH1]<CHANNEL_MIN_COMMAND) val |= 0x02;
83+
if(Channel_data[CH1+n]>CHANNEL_MAX_COMMAND) val |= 0x01;
84+
else if(Channel_data[CH1+n]<CHANNEL_MIN_COMMAND) val |= 0x02;
8285
//Button D
83-
if(Channel_data[CH4]>CHANNEL_MAX_COMMAND) val |= 0x04;
84-
else if(Channel_data[CH4]<CHANNEL_MIN_COMMAND) val |= 0x08;
86+
if(Channel_data[CH4+n]>CHANNEL_MAX_COMMAND) val |= 0x04;
87+
else if(Channel_data[CH4+n]<CHANNEL_MIN_COMMAND) val |= 0x08;
8588
packet[4]= val;
86-
87-
packet_count++;
8889
}
8990
}
9091

@@ -101,7 +102,7 @@ static void __attribute__((unused)) MOULDKG_send_packet()
101102

102103
static void __attribute__((unused)) MOULDKG_initialize_txid()
103104
{
104-
rx_tx_addr[0] = rx_tx_addr[3]; // Use RX_num;
105+
//rx_tx_addr[0] = rx_tx_addr[3]; // Use RX_num;
105106

106107
#ifdef FORCE_MOULDKG_ORIGINAL_ID
107108
rx_tx_addr[0]=0x57;
@@ -119,6 +120,8 @@ static void __attribute__((unused)) MOULDKG_RF_init()
119120

120121
uint16_t MOULDKG_callback()
121122
{
123+
uint8_t rf,n;
124+
uint16_t addr;
122125
switch(phase)
123126
{
124127
case MOULDKG_BINDTX:
@@ -134,17 +137,18 @@ uint16_t MOULDKG_callback()
134137
//Not sure if I should test packet_in[0]
135138
if(memcmp(&packet_in[1],&packet[1],3)==0)
136139
{//TX ID match
137-
//Use RX ID as address
138-
XN297_SetTXAddr(&packet_in[4], 3);
139-
//Calculate frequencies based on RX ID
140-
hopping_frequency[0] = 0x0C + (packet_in[4] & 0x0F);
141-
hopping_frequency[1] = 0x1C + (packet_in[4] >> 4);
142-
hopping_frequency[2] = 0x2C + (packet_in[5] & 0x0F);
143-
hopping_frequency[3] = 0x3C + (packet_in[5] >> 4);
144-
//Switch to normal mode
145-
BIND_DONE;
146-
XN297_SetTxRxMode(TXRX_OFF);
147-
phase = MOULDKG_DATA;
140+
if(option == 0)
141+
{
142+
memcpy(MOULDKG_RX_id,&packet_in[4],3);
143+
phase = MOULDKG_PREP_DATA1;
144+
}
145+
else
146+
{// Store RX ID
147+
addr=MOULDKG_EEPROM_OFFSET+RX_num*3;
148+
for(uint8_t i=0;i<3;i++)
149+
eeprom_write_byte((EE_ADDR)(addr+i),packet_in[4+i]);
150+
phase = MOULDKG_PREP_DATA;
151+
}
148152
break;
149153
}
150154
}
@@ -162,24 +166,71 @@ uint16_t MOULDKG_callback()
162166
XN297_SetTxRxMode(RX_EN);
163167
phase = MOULDKG_BINDTX;
164168
return MOULDKG_BIND_PACKET_PERIOD-600;
169+
case MOULDKG_PREP_DATA:
170+
addr=MOULDKG_EEPROM_OFFSET+RX_num*3;
171+
debug("RXID: ");
172+
for(uint8_t i=0;i<3*4;i++)
173+
{ // load 4 consecutive RX IDs
174+
MOULDKG_RX_id[i]=eeprom_read_byte((EE_ADDR)(addr+i));
175+
debug(" %02X",MOULDKG_RX_id[i]);
176+
}
177+
debugln("");
178+
case MOULDKG_PREP_DATA1:
179+
//Switch to normal mode
180+
BIND_DONE;
181+
XN297_SetTxRxMode(TXRX_OFF);
182+
phase = MOULDKG_DATA;
183+
break;
165184
case MOULDKG_DATA:
166185
#ifdef MULTI_SYNC
167-
telemetry_set_input_sync(MOULDKG_PACKET_PERIOD);
186+
if(num_ch==0)
187+
telemetry_set_input_sync(MOULDKG_PACKET_PERIOD);
168188
#endif
169-
MOULDKG_send_packet();
189+
if(option == 0) option++;
190+
if(num_ch<option)
191+
{
192+
//Set RX ID address
193+
n = num_ch*3;
194+
XN297_SetTXAddr(&MOULDKG_RX_id[n], 3);
195+
//Set frequency based on current RX ID and packet number
196+
rf = 0x0C;
197+
if(packet_count & 0x04)
198+
{
199+
n++;
200+
rf += 0x20;
201+
}
202+
if(packet_count & 0x02)
203+
rf += 0x10 + (MOULDKG_RX_id[n] >> 4);
204+
else
205+
rf += MOULDKG_RX_id[n] & 0x0F;
206+
XN297_RFChannel(rf);
207+
#if 1
208+
debugln("num_ch=%d,packet_count=%d,rf=%02X,ID=%02X %02X %02X",num_ch,packet_count,rf,MOULDKG_RX_id[num_ch*3],MOULDKG_RX_id[num_ch*3+1],MOULDKG_RX_id[num_ch*3+2]);
209+
#endif
210+
MOULDKG_send_packet();
211+
if(num_ch==0)
212+
packet_count++;
213+
}
214+
num_ch++;
215+
num_ch &= 0x03;
170216
break;
171217
}
172-
return MOULDKG_PACKET_PERIOD;
218+
return MOULDKG_PACKET_PERIOD/4;
173219
}
174220

175221
void MOULDKG_init()
176222
{
177-
BIND_IN_PROGRESS; // autobind protocol
223+
if(option == 0)
224+
BIND_IN_PROGRESS;
178225
MOULDKG_initialize_txid();
179226
MOULDKG_RF_init();
180227
bind_counter = MOULDKG_BIND_COUNT;
181-
phase = MOULDKG_BINDTX;
228+
if(IS_BIND_IN_PROGRESS)
229+
phase = MOULDKG_BINDTX;
230+
else
231+
phase = MOULDKG_PREP_DATA;
182232
packet_count = 0;
233+
num_ch = 0;
183234
}
184235

185236
#endif

Multiprotocol/Multi_Protos.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ const mm_protocol_definition multi_protocols[] = {
367367
{PROTO_MLINK, STR_MLINK, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_CYRF, MLINK_init, MLINK_callback },
368368
#endif
369369
#if defined(MOULDKG_NRF24L01_INO)
370-
{PROTO_MOULDKG, STR_MOULDKG, STR_SUBTYPE_MOULKG, 2, OPTION_NONE, 0, 0, SW_NRF, MOULDKG_init, MOULDKG_callback },
370+
{PROTO_MOULDKG, STR_MOULDKG, STR_SUBTYPE_MOULKG, 2, OPTION_OPTION, 0, 0, SW_NRF, MOULDKG_init, MOULDKG_callback },
371371
#endif
372372
#if defined(MT99XX_CCNRF_INO)
373373
{PROTO_MT99XX, STR_MT99XX, STR_SUBTYPE_MT99, 7, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback },

Multiprotocol/Multiprotocol.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#define VERSION_MAJOR 1
2020
#define VERSION_MINOR 3
2121
#define VERSION_REVISION 2
22-
#define VERSION_PATCH_LEVEL 85
22+
#define VERSION_PATCH_LEVEL 86
2323

2424
#define MODE_SERIAL 0
2525

Protocols_Details.md

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,17 +1707,31 @@ CH16| CH8 | -100% | 0% | - | - | -
17071707
## MouldKg - *90*
17081708
Mould King 2.4GHz TX: Technic Brick models
17091709

1710+
Up to 4 bricks can be controlled at the same time.
1711+
1712+
Option field | Value
1713+
-------------|------
1714+
0|The module will act like the original radio which will bind every time and attach to the first brick in bind mode
1715+
1|The module will control the brick number RX_num
1716+
2|The module will control the brick number RX_num and RX_num+1
1717+
3|The module will control the brick number RX_num, RX_num+1 and RX_num+2
1718+
4|The module will control the brick number RX_num, RX_num+1, RX_num+2 and RX_num+3
1719+
1720+
To associate a brick to a RX number (RX_num above), set this RX number under the protocol, set option to 1, launch a bind and power on the brick you want to control. Repeat this for every brick using a different RX number each time and then indicate the number of bricks to be comtrolled using the Option field.
1721+
1722+
Example: I want to control 2 bricks. I select RX number 1, set option to 1 and launch a bind on the first brick. I select RX number 2, set option to 1 and launch a bind on the second brick. Now to control both bricks I set RX number to 1, option to 2. Therefore brick1 will react to channels CH1 to CH4 and brick2 to channel CH5 to CH8.
1723+
17101724
### Sub_protocol Analog - *0*
17111725

1712-
CH1|CH2|CH3|CH4
1713-
---|---|---|---
1714-
A|B|C|D
1726+
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
1727+
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---
1728+
Brick1_A|Brick1_B|Brick1_C|Brick1_D|Brick2_A|Brick2_B|Brick2_C|Brick2_D|Brick3_A|Brick3_B|Brick3_C|Brick3_D|Brick4_A|Brick4_B|Brick4_C|Brick4_D
17151729

17161730
### Sub_protocol Digit - *1*
17171731

1718-
CH1|CH2|CH3|CH4|CH5|CH6
1719-
---|---|---|---|---|---
1720-
A|B|C|D|E|F
1732+
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
1733+
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---
1734+
Brick1_A|Brick1_B|Brick1_C|Brick1_D|Brick2_A|Brick2_B|Brick2_C|Brick2_D|Brick3_A|Brick3_B|Brick3_C|Brick3_D|Brick4_A|Brick4_B|Brick4_C|Brick4_D
17211735

17221736
## NCC1701 - *44*
17231737
Model: Air Hogs Star Trek USS Enterprise NCC-1701-A

0 commit comments

Comments
 (0)