Table of Contents
My son got the LEGO Boost set for his birthday and is really loving it. In the past we used an ESP8266 microcontroller to hack the LEGO train remote controls (LEGO PowerFunctions) using MQTT to communicate with the ESP8266 which was build into the train which in turn used an IR led to control the train speed.
Now with LEGO Boost we got our first experience with the newer LEGO Powered Up and our search for ways to hack this began…
Legoino
We found a very interesting Arduino library which makes it possible to use the ESP32 buildin BLE to control LEGO Powered Up and thus the LEGO Boost movehub.
https://github.com/corneliusmunz/legoino
I have tested this library and it works like a charm:
By the way, thanks JKBrickworks for the instructions for the Candy Catapult!
Power Functions
Our first goal was to try to read out the LEGO Power Functions IR remote control and use that to drive the LEGO Boost movehub.
As said, we have experience with emulating the IR remote but never attempted to receive its signals. Fortunately I fount this little gem:
Arduino-LPF: Lego Power Functions IR receiver with LCD
This also proved to be fairly simple:
Combining Arduino-LPF and Legoino
Now nothing stands in the way of combining both and use the “old” LEGO Power Functions remote controls in conjunction with the “new” LEGO Powered Up hubs:
//Lego Power Functions receiver: https://github.com/thordreier/Arduino-LPF #include "Arduino-LPF-receiver.h" #include "Arduino-LPF-driver.h" const byte IRreceiverPin = 2; // datapin of the IR receiver (TSOP38238) byte address = 0; // is always 0 in normal Power Functions byte channel = 0; // between 0 and 3 (for channel 1-4) LPFDriver driver( address, channel ); // Lego Boost library: https://github.com/corneliusmunz/legoino #include "BoostHub.h" // create a hub instance BoostHub myBoostHub; // declare the ports BoostHub::Port _portA = BoostHub::Port::A; BoostHub::Port _portB = BoostHub::Port::B; BoostHub::Port _portC = BoostHub::Port::C; BoostHub::Port _portD = BoostHub::Port::D; // Variables to hold the PF values int8_t iRED; int8_t iBLUE; byte bRED_BRAKE; byte bBLUE_BRAKE; // Interrupt service routine called whenever IR signal is received and decoded void control_motor( int8_t speed0, byte brake0, int8_t speed1, byte brake1 ) { iRED = speed0; iBLUE = speed1; bRED_BRAKE = brake0; bBLUE_BRAKE = brake1; Serial.print("RED = ");Serial.print(iRED);Serial.print(" RED brake = ");Serial.print(bRED_BRAKE); Serial.print(" | BLUE = ");Serial.print(iBLUE);Serial.print(" BLUE brake = ");Serial.println(bBLUE_BRAKE); } void setup() { Serial.begin(115200); Serial.println("Lego Power Functions 2 Powered Up"); // Initialize the Lego Power Functions pinMode(IRreceiverPin, INPUT); lpf_receiver_set_pin(IRreceiverPin); attachInterrupt(digitalPinToInterrupt(IRreceiverPin), lpf_receiver_interrupt, CHANGE); driver.set_driverfunction( control_motor ); // initalize the BoostHub instance myBoostHub.init(); } void loop() { // Receive the Lego Power Functions IR messages while( lpf_msg msg = lpf_receiver_get_next_msg() ) { driver.parse_msg(msg); //Serial.println( msg, BIN ); } // connect flow. Search for BLE services and try to connect if the uuid of the hub is found if (myBoostHub.isConnecting()) { myBoostHub.connectHub(); if (myBoostHub.isConnected()) { Serial.println("Connected to HUB"); } else { Serial.println("Failed to connect to HUB"); } } if (myBoostHub.isConnected()) { char hubName[] = "myBoostHub"; myBoostHub.setHubName(hubName); if (bRED_BRAKE){ myBoostHub.setLedColor(RED); myBoostHub.stopMotor(_portA); } else { if (iRED != 0){ myBoostHub.setLedRGBColor(255, 50, 30); } myBoostHub.setMotorSpeed(_portA, map(iRED,-7,7,-100,100)); } if (bBLUE_BRAKE){ myBoostHub.setLedColor(BLUE); myBoostHub.stopMotor(_portB); } else { if (iBLUE != 0){ myBoostHub.setLedRGBColor(255, 50, 30); } myBoostHub.setMotorSpeed(_portB, map(iBLUE,-7,7,-100,100)); } } }