Skip to content

Commit

Permalink
Mould King: control up to 4 bricks at the same time
Browse files Browse the repository at this point in the history
  • Loading branch information
pascallanger committed Jun 20, 2021
1 parent c36b112 commit 6e9ebfd
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 44 deletions.
123 changes: 87 additions & 36 deletions Multiprotocol/MouldKg_nrf24l01.ino
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,15 @@ Multiprotocol is distributed in the hope that it will be useful,
#define MOULDKG_RF_NUM_CHANNELS 4

enum {
MOULDKG_BINDTX=0,
MOULDKG_BINDRX,
MOULDKG_DATA,
MOULDKG_BINDTX=0,
MOULDKG_BINDRX,
MOULDKG_PREP_DATA,
MOULDKG_PREP_DATA1,
MOULDKG_DATA,
};

uint8_t MOULDKG_RX_id[4*3];

static void __attribute__((unused)) MOULDKG_send_packet()
{
uint8_t len = MOULDKG_BIND_PAYLOAD_SIZE;
Expand All @@ -45,14 +49,13 @@ static void __attribute__((unused)) MOULDKG_send_packet()
}
else
{
XN297_RFChannel(hopping_frequency[(packet_count>>1)&0x03]);

uint8_t n = num_ch<<2;
if(sub_protocol == MOULDKG_ANALOG)
{
packet[0] = 0x36;
uint8_t ch[]={ 1,0,2,3 };
for(uint8_t i=0;i<4;i++)
packet[i+4] = convert_channel_8b(ch[i]);
packet[i+4] = convert_channel_8b(ch[i]+n);
len = MOULDKG_PAYLOAD_SIZE_ANALOG;
}
else
Expand All @@ -63,28 +66,26 @@ static void __attribute__((unused)) MOULDKG_send_packet()
{
packet[0] = 0x31;
//Button B
if(Channel_data[CH2]>CHANNEL_MAX_COMMAND) val |= 0x40;
else if(Channel_data[CH2]<CHANNEL_MIN_COMMAND) val |= 0x80;
if(Channel_data[CH2+n]>CHANNEL_MAX_COMMAND) val |= 0x40;
else if(Channel_data[CH2+n]<CHANNEL_MIN_COMMAND) val |= 0x80;
//Button C
if(Channel_data[CH3]>CHANNEL_MAX_COMMAND) val |= 0x10;
else if(Channel_data[CH3]<CHANNEL_MIN_COMMAND) val |= 0x20;
if(Channel_data[CH3+n]>CHANNEL_MAX_COMMAND) val |= 0x10;
else if(Channel_data[CH3+n]<CHANNEL_MIN_COMMAND) val |= 0x20;
}
else
{
packet[0] = 0x30;
val = 0x60
| GET_FLAG(CH5_SW, 0x80) // Button E
| GET_FLAG(CH6_SW, 0x10); // Button F
val = 0x60;
// | GET_FLAG(CH5_SW, 0x80) // Button E
// | GET_FLAG(CH6_SW, 0x10); // Button F
}
//Button A
if(Channel_data[CH1]>CHANNEL_MAX_COMMAND) val |= 0x01;
else if(Channel_data[CH1]<CHANNEL_MIN_COMMAND) val |= 0x02;
if(Channel_data[CH1+n]>CHANNEL_MAX_COMMAND) val |= 0x01;
else if(Channel_data[CH1+n]<CHANNEL_MIN_COMMAND) val |= 0x02;
//Button D
if(Channel_data[CH4]>CHANNEL_MAX_COMMAND) val |= 0x04;
else if(Channel_data[CH4]<CHANNEL_MIN_COMMAND) val |= 0x08;
if(Channel_data[CH4+n]>CHANNEL_MAX_COMMAND) val |= 0x04;
else if(Channel_data[CH4+n]<CHANNEL_MIN_COMMAND) val |= 0x08;
packet[4]= val;

packet_count++;
}
}

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

static void __attribute__((unused)) MOULDKG_initialize_txid()
{
rx_tx_addr[0] = rx_tx_addr[3]; // Use RX_num;
//rx_tx_addr[0] = rx_tx_addr[3]; // Use RX_num;

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

uint16_t MOULDKG_callback()
{
uint8_t rf,n;
uint16_t addr;
switch(phase)
{
case MOULDKG_BINDTX:
Expand All @@ -134,17 +137,18 @@ uint16_t MOULDKG_callback()
//Not sure if I should test packet_in[0]
if(memcmp(&packet_in[1],&packet[1],3)==0)
{//TX ID match
//Use RX ID as address
XN297_SetTXAddr(&packet_in[4], 3);
//Calculate frequencies based on RX ID
hopping_frequency[0] = 0x0C + (packet_in[4] & 0x0F);
hopping_frequency[1] = 0x1C + (packet_in[4] >> 4);
hopping_frequency[2] = 0x2C + (packet_in[5] & 0x0F);
hopping_frequency[3] = 0x3C + (packet_in[5] >> 4);
//Switch to normal mode
BIND_DONE;
XN297_SetTxRxMode(TXRX_OFF);
phase = MOULDKG_DATA;
if(option == 0)
{
memcpy(MOULDKG_RX_id,&packet_in[4],3);
phase = MOULDKG_PREP_DATA1;
}
else
{// Store RX ID
addr=MOULDKG_EEPROM_OFFSET+RX_num*3;
for(uint8_t i=0;i<3;i++)
eeprom_write_byte((EE_ADDR)(addr+i),packet_in[4+i]);
phase = MOULDKG_PREP_DATA;
}
break;
}
}
Expand All @@ -162,24 +166,71 @@ uint16_t MOULDKG_callback()
XN297_SetTxRxMode(RX_EN);
phase = MOULDKG_BINDTX;
return MOULDKG_BIND_PACKET_PERIOD-600;
case MOULDKG_PREP_DATA:
addr=MOULDKG_EEPROM_OFFSET+RX_num*3;
debug("RXID: ");
for(uint8_t i=0;i<3*4;i++)
{ // load 4 consecutive RX IDs
MOULDKG_RX_id[i]=eeprom_read_byte((EE_ADDR)(addr+i));
debug(" %02X",MOULDKG_RX_id[i]);
}
debugln("");
case MOULDKG_PREP_DATA1:
//Switch to normal mode
BIND_DONE;
XN297_SetTxRxMode(TXRX_OFF);
phase = MOULDKG_DATA;
break;
case MOULDKG_DATA:
#ifdef MULTI_SYNC
telemetry_set_input_sync(MOULDKG_PACKET_PERIOD);
if(num_ch==0)
telemetry_set_input_sync(MOULDKG_PACKET_PERIOD);
#endif
MOULDKG_send_packet();
if(option == 0) option++;
if(num_ch<option)
{
//Set RX ID address
n = num_ch*3;
XN297_SetTXAddr(&MOULDKG_RX_id[n], 3);
//Set frequency based on current RX ID and packet number
rf = 0x0C;
if(packet_count & 0x04)
{
n++;
rf += 0x20;
}
if(packet_count & 0x02)
rf += 0x10 + (MOULDKG_RX_id[n] >> 4);
else
rf += MOULDKG_RX_id[n] & 0x0F;
XN297_RFChannel(rf);
#if 1
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]);
#endif
MOULDKG_send_packet();
if(num_ch==0)
packet_count++;
}
num_ch++;
num_ch &= 0x03;
break;
}
return MOULDKG_PACKET_PERIOD;
return MOULDKG_PACKET_PERIOD/4;
}

void MOULDKG_init()
{
BIND_IN_PROGRESS; // autobind protocol
if(option == 0)
BIND_IN_PROGRESS;
MOULDKG_initialize_txid();
MOULDKG_RF_init();
bind_counter = MOULDKG_BIND_COUNT;
phase = MOULDKG_BINDTX;
if(IS_BIND_IN_PROGRESS)
phase = MOULDKG_BINDTX;
else
phase = MOULDKG_PREP_DATA;
packet_count = 0;
num_ch = 0;
}

#endif
Expand Down
2 changes: 1 addition & 1 deletion Multiprotocol/Multi_Protos.ino
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_MLINK, STR_MLINK, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_CYRF, MLINK_init, MLINK_callback },
#endif
#if defined(MOULDKG_NRF24L01_INO)
{PROTO_MOULDKG, STR_MOULDKG, STR_SUBTYPE_MOULKG, 2, OPTION_NONE, 0, 0, SW_NRF, MOULDKG_init, MOULDKG_callback },
{PROTO_MOULDKG, STR_MOULDKG, STR_SUBTYPE_MOULKG, 2, OPTION_OPTION, 0, 0, SW_NRF, MOULDKG_init, MOULDKG_callback },
#endif
#if defined(MT99XX_CCNRF_INO)
{PROTO_MT99XX, STR_MT99XX, STR_SUBTYPE_MT99, 7, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback },
Expand Down
2 changes: 1 addition & 1 deletion Multiprotocol/Multiprotocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_REVISION 2
#define VERSION_PATCH_LEVEL 85
#define VERSION_PATCH_LEVEL 86

#define MODE_SERIAL 0

Expand Down
26 changes: 20 additions & 6 deletions Protocols_Details.md
Original file line number Diff line number Diff line change
Expand Up @@ -1707,17 +1707,31 @@ CH16| CH8 | -100% | 0% | - | - | -
## MouldKg - *90*
Mould King 2.4GHz TX: Technic Brick models

Up to 4 bricks can be controlled at the same time.

Option field | Value
-------------|------
0|The module will act like the original radio which will bind every time and attach to the first brick in bind mode
1|The module will control the brick number RX_num
2|The module will control the brick number RX_num and RX_num+1
3|The module will control the brick number RX_num, RX_num+1 and RX_num+2
4|The module will control the brick number RX_num, RX_num+1, RX_num+2 and RX_num+3

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.

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.

### Sub_protocol Analog - *0*

CH1|CH2|CH3|CH4
---|---|---|---
A|B|C|D
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---
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

### Sub_protocol Digit - *1*

CH1|CH2|CH3|CH4|CH5|CH6
---|---|---|---|---|---
A|B|C|D|E|F
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---
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

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

0 comments on commit 6e9ebfd

Please sign in to comment.