Code Monkey home page Code Monkey logo

legoino's Introduction

Gitter GitHub release (latest SemVer) arduino-library-badge BuildExampleSketches

Legoino

Disclaimer: LEGO® is a trademark of the LEGO Group of companies which does not sponsor, authorize or endorse this project.

Legoino is an Arduino Library for controlling all kinds of LEGO Powered UP devices. From the two port hub, Move Hub (e.g. Boost), DUPLO train hub, Technic Hub to several devices like distance and color sensor, tilt sensor, train motor, remote control, speedometer, etc. you can control almost everything with that library and your Arduino sketch.

It is also possible to use the "old" Power Function IR Modules and control them via an IR LED connected to a PIN of your ESP32 device. With the Hub emulation function you can even control an "old" Power Function Light or Motor with the Powered Up app.

Arduino Hardware and dependent libraries

The library is implemented for ESP32 boards and uses the ESP32 NimBLE-Arduino library as dependency. This should be installed via the Arduino library manager before using Legoino.

Quickstart

You can find a step by step instruction to your first Legoino project on the following link: Quickstart Tutorial

Breaking Changes

Starting from version 1.0.0 many functions have been renamed and the global variables have been replaced by callback functions. In former versions the reading of sensor values of single or multiple sensors and even reading sensors from different hubs, was not working properly. Due to the changes to the NimBLE-Arduino library the callbacks can now be part of member functions and don't have to be defined globally.

So have a look at the changes and adapt your sketches to the new callbacks. You can find a migration guide here: Migration Guide

If you have questions regarding the migration of your sketches, don't hesitate to use the Gitter chat.

Usage Videos

In the following videos you can see with short examples what you can do with the library.

Remote control your Boost model example (just click the image to see the video)

Legoino Boost control example

Simple Train example (just click the image to see the video)

Legoino TrainHub color control example

Simple Boost movement example (just click the image to see the video)

Legoino BoostHub simple movements example

Simple Hub Emulation example as Bridge from PoweredUp to PowerFunction. With this you have an upgrade of your PowerFunction system and it works like a two Port PoweredUp hub. Legoino Hub Emulation example

Examples

All the included examples are a great source to find a solution or pattern for your problem you want to solve with your Arduino sketch.

You can find different examples in the "examples" folder. You can select the examples in your Arduino IDE via the Menu "File->Examples". Just have a look on the videos to see the examples running 😃

  • Boost.ino: Example which uses the basic Boost movements (usable with M.T.R. 4 or Vernie model). http://www.youtube.com/watch?v=VgWObhyUmi0
  • ColorSensor.ino: Example which reads in the color sensor value (attached to an arbitrary port) and uses the detected color to set the Hub LED accordingly. https://youtu.be/_xCd9Owy1nk
  • MoveHubDeviceInfo.ino: Example which displays the various device infos (firmware version, battery level, RSSI, hardware version, tilt) in the serial monitor.
  • DistanceSensor.ino: Example which reads in the input of the distance sensor and sets the Hub LED color dependent on the distance. https://youtu.be/TOAQtGGjZ6c
  • RotationSensor.ino: Example which reads in the input of the Tacho motor angle to set the Hub LED dependent on the angle to the scale of rainbow colors. https://youtu.be/c3DHpX55uN0
  • TrainHub.ino: Example for a PowererdUp Hub to set the speed of a train model. http://www.youtube.com/watch?v=o1hgZQz3go4
  • TrainColor.ino: Example of PoweredUp Hub combined with color sensor to control the speed of the train dependent on the detected color. https://youtu.be/GZ0fqe3-Bhw
  • HubEmulation.ino: Example of an emulated PoweredUp Hub two port hub (train hub) which could receive signals from the PoweredUp app and will send out the signals as IR commands to a Powerfunction remote receiver. https://www.youtube.com/watch?v=RTNexxT4-yQ
  • PoweredUpRemoteAutoDetection.ino: Example of connection of PoweredUp and PoweredUpRemote where the device type is fetched automatically and the order in which you switched on the hubs is no longer relevant.
  • ControlPlusHub.ino: Example with connection of ControlPlusHub (TechnicHub) where a Tacho Motor on Port D is controlled.
  • Mario.ino Example of connection to a Mario Hub to read in sensor notifications about the Barcode/Tag sensor, Color sensor, Pants sensor and Gesture sensor.

Setup and Usage

Just install the library via the Arduino Library Manager.

First example

Just have a look on the Quickstart Tutorial.

Connection procedure

To setup a connection to your hub, the Hub instance has to be initialized. This will trigger a scan procedure to look if a LEGO Hub is active. If the library found an active hub, it will read out its data (Hub Address, Hub Name, etc.) and changes the state to myHub.isConnecting() == true

Now you are ready to connect to the hub with the command myHub.connectHub();

If the library changes the state to myHub.isConnected() == true you are ready to go and do some cool stuff 😁

In the setup part of your Arduino sketch, just initialize your Hub:

myHub.init();

In the main loop just add the following connection flow:

  if (myHub.isConnecting()) {
    myHub.connectHub();
    if (myHub.isConnected()) {
      Serial.println("We are now connected to the HUB");
    } else {
      Serial.println("We have failed to connect to the HUB");
    }
  }

Motor Commands

There are different types of motors in the LEGO ecosystem. The Basic Motor (e.g. Train Hub), The Tacho motor and the absolute motor. The prefixes Basic, Tacho and Absolute tell you which command fits for what type of motor. The Tacho Motor commands can also be used with the Absolute motor.

  void stopBasicMotor(byte port);
  void setBasicMotorSpeed(byte port, int speed);
  void setAccelerationProfile(byte port, int16_t time);
  void setDecelerationProfile(byte port, int16_t time);
  void stopTachoMotor(byte port);
  void setTachoMotorSpeed(byte port, int speed, byte maxPower = 100, BrakingStyle brakingStyle = BrakingStyle::BRAKE);
  void setTachoMotorSpeedForTime(byte port, int speed, int16_t time, byte maxPower = 100, BrakingStyle brakingStyle = BrakingStyle::BRAKE);
  void setTachoMotorSpeedForDegrees(byte port, int speed, int32_t degrees, byte maxPower = 100, BrakingStyle brakingStyle = BrakingStyle::BRAKE);
  void setTachoMotorSpeedsForDegrees(int speedLeft, int speedRight, int32_t degrees, byte maxPower = 100, BrakingStyle brakingStyle = BrakingStyle::BRAKE);
  void setAbsoluteMotorPosition(byte port, int speed, int32_t position, byte maxPower = 100, BrakingStyle brakingStyle = BrakingStyle::BRAKE);
  void setAbsoluteMotorEncoderPosition(byte port, int32_t position);

Hub Commands

For some use cases it is required to get the hub address (check a specific hub), the hub type (check a hub type) or the hub name. It is also possible to change the hub name and shutdown the hub.

  NimBLEAddress getHubAddress();
  HubType getHubType();
  std::string getHubName();
  void setHubName(char name[]);
  void shutDownHub();

LED Commands

To control the Hub LEDs, you can use predefined color Variables in the Color enum, RGB values or HSV values with the following commands:

  void setLedColor(Color color);
  void setLedRGBColor(char red, char green, char blue);
  void setLedHSVColor(int hue, double saturation, double value);

Sensor and hub property handling

To get notified about sensor value updates (Button, Hub properties like voltage, RSSI, Tacho motor encoder, Speedometer, color sensor, distance sensor, ...), callback functions are used. After you read the following section you can also have a look into the examples which are included in the library. They are always a good source to find solutions/patterns for problems you want to solve.

Callbacks

To use the callbacks you have to do the following steps. Part of the callback ist the reference of the hub instance. So you can use the hub instance which has triggered the callback function to control attached motors or devices.

Write callback function for port devices

To read in changes of devices which are attached to a port (built-in or external), you have to write a function with the following signature:

typedef void (*PortValueChangeCallback)(void *hub, byte portNumber, DeviceType deviceType, uint8_t *pData);

Example:

// callback function to handle updates of sensor values
void tachoMotorCallback(void *hub, byte portNumber, DeviceType deviceType, uint8_t *pData)
{
  Lpf2Hub *myHub = (Lpf2Hub *)hub;

  Serial.print("sensorMessage callback for port: ");
  Serial.println(portNumber, DEC);
  if (deviceType == DeviceType::MEDIUM_LINEAR_MOTOR)
  {
    int rotation = myHub->parseTachoMotor(pData);
    Serial.print("Rotation: ");
    Serial.print(rotation, DEC);
    Serial.println(" [degrees]");
    myHub->setLedHSVColor(abs(rotation), 1.0, 1.0);
  }
}

This function will be called when a value update appears and you can react on the new value. In this case the LED color changes dependent on the motor rotation.

Write callback function for hub properties

To read in changes of hub properties (button, RSSI, battery level, ...), you have to write a function with the following signature:

typedef void (*HubPropertyChangeCallback)(void *hub, HubPropertyReference hubProperty, uint8_t *pData);

Example:

// callback function to handle updates of hub properties
void hubPropertyChangeCallback(void *hub, HubPropertyReference hubProperty, uint8_t *pData)
{
  Lpf2Hub *myHub = (Lpf2Hub *)hub;
  Serial.print("HubAddress: ");
  Serial.println(myHub->getHubAddress().toString().c_str());

  Serial.print("HubProperty: ");
  Serial.println((byte)hubProperty, HEX);

  if (hubProperty == HubPropertyReference::RSSI)
  {
    Serial.print("RSSI: ");
    Serial.println(myHub->parseRssi(pData), DEC);
    return;
  }

  if (hubProperty == HubPropertyReference::BATTERY_VOLTAGE)
  {
    Serial.print("BatteryLevel: ");
    Serial.println(myHub->parseBatteryLevel(pData), DEC);
    return;
  }

  if (hubProperty == HubPropertyReference::BUTTON)
  {
    Serial.print("Button: ");
    Serial.println((byte)myHub->parseHubButton(pData), HEX);
    return;
  }
}

This function will be called when a value update appears and you can react on the new value. In this case it will check the hub button state (pressed, released) or the RSSI value has changed or the battery level has changed.

Activate notifications

To get calls to your callback functions you have to register or activate it for the properties you want to get informed about updates. This has to be done after the hub is connected (not before). If you want to register updates for several properties/sensors, just add a short delay (50-100ms) after each register/activate call.

For Port related updates you have to use the function

  void activatePortDevice(byte portNumber, byte deviceType, PortValueChangeCallback portValueChangeCallback = nullptr);

Example:

// get notified for value updates of the device which is connected on port D
myMoveHub.activatePortDevice(portD, tachoMotorCallback);
delay(50);
myMoveHub.activateHubPropertyUpdate(HubPropertyReference::BUTTON, buttonCallback);

For Hub property related updates you have to use the function

  void activateHubPropertyUpdate(HubPropertyReference hubProperty, HubPropertyChangeCallback hubPropertyChangeCallback = nullptr);

Example:

// get notified for value updates of the build in Button of the hub
myMoveHub.activateHubPropertyUpdate(HubPropertyReference::BUTTON, buttonCallback);

You can also check if an expected device is really connected to a port by using the newly introduced function checkPortForDevice like in the following example:

Serial.print("check ports... if needed sensor is already connected: ");
byte portForDevice = myHub.getPortForDeviceType((byte)DeviceType::COLOR_DISTANCE_SENSOR);
Serial.println(portForDevice, DEC);
// check for expected port number where the device should be connected
if (portForDevice == 1)  
{
	Serial.println("activatePortDevice");
	myHub.activatePortDevice(portB, colorDistanceSensorCallback);
}

Hub emulation

The Hub emulation feature is in BETA mode. You can test it and if you find any issues or needed new requirements, just open an issue in github project

The basic idea is that the ESP32 controller acts as a hub and could be controlled via the PoweredUp App.

First you have to create an instance of a hub where you can define the name of the Hub which will be advertised and the type of the hub. In the current implementation only the POWERED_UP_HUB type is supported and only a connected TRAIN_MOTOR and HUB_LED will work.

#include "Lpf2HubEmulation.h"
#include "LegoinoCommon.h"

// create a hub instance
Lpf2HubEmulation myEmulatedHub("TrainHub", HubType::POWERED_UP_HUB);

To get notified if a command is sent to the app, a callback has to be defined and registered with the setWritePortCallback. If the app is connected and send out a command, you can define what you want to do if you receive that command. For example you can send out a power function command to act as a hub relay.

  // define the callback function if a write message event on the characteristic occurs
  myEmulatedHub.setWritePortCallback(&writeValueCallback);
  myEmulatedHub.start();
void writeValueCallback(byte port, byte value)
{
  Serial.println("writeValueCallback: ");
  Serial.println(port, HEX);
  Serial.println(value, HEX);

  if (port == 0x00)
  {
    //do something when port 0x00 (A) has received a value
  }

  if (port == 0x01)
  {
    //do something when port 0x01 (B) has received a value
  }

  if (port == 0x32)
  {
    //do something when port 0x32 (LED) has received a value
  }
}

To signalize the app which devices are connected you have to send some commands with the attachDevice method. You can define on which port, which device type is connected.

  // if an app is connected, attach some devices on the ports to signalize
  // the app that values could be received/written to that ports
  if (myEmulatedHub.isConnected && !myEmulatedHub.isPortInitialized)
  {
    delay(1000);
    myEmulatedHub.isPortInitialized = true;
    myEmulatedHub.attachDevice(0x00, DeviceType::TRAIN_MOTOR);
    delay(1000);
    myEmulatedHub.attachDevice(0x32, DeviceType::HUB_LED);
    delay(1000);
    myEmulatedHub.attachDevice(0x01, DeviceType::TRAIN_MOTOR);
    delay(1000);
  }

PowerFunction IR

To use the PowerFunction Infrared library you have to connect a IR-LED to your controller. The PowerFunction part of the Legoino library will work on different hardware architectures (AVR, ESP8266, ESP32). To instantiate a new object, you have to define on which pin the IR LED is connected. Additionally you can define the Power function channel which should be used. Pay attention, that the channel in the library starts with 0 and on the physical IR Lego controller it starts with 1. So if you want to control channel 1 of your physical device, you have to use channel 0 in the PowerFunction part of the library.

#include "PowerFunctions.h"
// create a power functions instance (IR LED on Pin 12, IR Channel 0)
PowerFunctions pf(12, 0);

Then you can control the output ports (Red, Blue) with the following possible commands. The ports could be defined with the PowerFunctionsPort enum. For the PWM values the PowerFunctionsPwm enum is used.

  void single_pwm(PowerFunctionsPort port, PowerFunctionsPwm pwm);
  void single_pwm(PowerFunctionsPort port, PowerFunctionsPwm pwm, uint8_t channel);
  void single_increment(PowerFunctionsPort port);
  void single_increment(PowerFunctionsPort port, uint8_t channel);
  void single_decrement(PowerFunctionsPort port);
  void single_decrement(PowerFunctionsPort port, uint8_t channel);
  void combo_pwm(PowerFunctionsPwm redPwm, PowerFunctionsPwm bluePwm);
  void combo_pwm(PowerFunctionsPwm redPwm, PowerFunctionsPwm bluePwm, uint8_t channel);

There is a helper function to convert speed values from -100...100 to the discrete PWM values:

PowerFunctionsPwm speedToPwm(byte speed);

Boost

The Boost functions are a higher level of abstraction for moving the Vernie or M.T.R. 4 model one step forward/back and rotate the model or move with an arc.

Add the following include in your *.ino sketch:

#include "Boost.h"
Boost myBoostHub;

Basic movements (Vernie, M.T.R. 4)

If you want to move Vernie or M.T.R. 4 you can use the following commands. These commands are using the underlying basic motor commands and are adjusted to the Boost grid map.

If you want to move forward for a specific number of steps, just use the following command:

myBoostHub.moveForward(1) // move one step forward
myBoostHub.moveForward(3) // move three steps forward

If you want to move back for a specific number of steps, just use the following command:

myBoostHub.moveBack(1) // move one step back
myBoostHub.moveBack(3) // move three steps back

If you want to rotate for a specific angle, just use the following commands:

myBoostHub.rotateLeft(90) // rotate 90 degrees left
myBoostHub.rotateRight(180) // rotate 180 degrees right
myBoostHub.rotate(360) // rotate 360 degrees right (positive angles means right, negative means left)
myBoostHub.rotate(-180) // rotate 180 degrees left (positive angles means right, negative means left)

If you want to move with an arc for a specific angle, just use the following commands:

myBoostHub.moveArcLeft(180) // move with an arc for 180 degrees to the left
myBoostHub.moveArcRight(90) // move with an arc for 90 degrees to the right
myBoostHub.moveArc(270) // move with an arc for 270 degrees to the right (positive angles means right, negative means left)
myBoostHub.moveArc(-90) // move with an arc for 90 degrees to the left (positive angles means right, negative means left)

Mario Hub (#71360)

With Legoino it is possible to connect to the Mario Hub and read out sensor values from the

  • Pant Sensor
  • Color and Tag/Barcode Sensor
  • Gesture Sensor
  • Voltage Sensor

You can do this via the standard "sensor notification" procedure. Just have a look into the Mario.ino example sketch.

There is an undocumented hub property 0x12 to control the volume of the hub. This feature can be used with the Legoino function setMarioVolume(volume) with a volume value from 0..100 in %.

Connection to more than 3 hubs

It is possible to connect to up to 9 hubs in parallel with a common ESP32 board. To enable the connection to more than 3 hubs, you have to change a single configuration of the NimBLE library. Just open the nimconfig.h file located in your Arduino library folder in the directory NimBLE-Arduino/src. Open the file with an editor and change the following settings to your demands:

/** @brief Sets the number of simultaneous connections (esp controller max is 9) */
#define CONFIG_BT_NIMBLE_MAX_CONNECTIONS 3

Then close the Arduino environment and open it again to force the rebuild of the library. Open your sketch build and upload it and be happy with multiple connections.

Debug Messages

The standard log_d, log_w, log_xx messages are used. The log levels could be set via the Arduino environment and the messages are sent to the serial monitor.

Credits

Hands up to Lego, that they have recently open-sourced the Specification https://github.com/LEGO/lego-ble-wireless-protocol-docs

Thanks to @JorgePe and all contributors for the reverse engineering part https://github.com/JorgePe/BOOSTreveng

Thanks to @jakorten for his SWIFT iOS App https://github.com/jakorten/UpControl

Thanks @nathankellenicki for his brilliant structured node module https://github.com/nathankellenicki/node-poweredup

Thanks to @h2zero for developing a new BLE library based on the NimBLE project and supporting Legoino with the possibility in changing the callback functions that it works also for member functions.

Thanks to @giancann, @marcrupprath and @albant for the hub emulation idea and first implementation.

Thanks to @fvanroie for his contribution about callbacks.

Thanks for the original PowerFunctions Library by @jurriaan

Thanks to @wmarkow for his detailed input about hub emulation issues on Android devices and his proposals.

Remarks

Prerequisite of that library is the NimBLE-Arduino library (https://github.com/h2zero/NimBLE-Arduino) with at least version 1.0.1. Otherwise the notifications of changed characteristic values will not work. So just install the version 1.0.1 of that library via the Arduino Library manager or the platform.io library manager (https://www.arduinolibraries.info/libraries/nim-ble-arduino) as a prerequisite.

Up to now the library is only tested for a Powered Up Train controllers, Boost controllers, Control+ Hubs, PoweredUp Remote, Duplo Train Hub and Mario Hub. You can connect to your Hub, set the LED color, set the Hub name, control the motors (speed, port, movements) and shut down the Hub via a Arduino command. You also are able to read in hub device infos (RSSI, battery level, tilt) and sensor values (color, distance, rotation angle).

ToDo

  • Virtual Ports
  • HW Families

legoino's People

Contributors

corneliusmunz avatar docteurzoidberg avatar fredlcore avatar jeluf avatar lgm42 avatar maehw avatar per1234 avatar wmarkow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

legoino's Issues

Lego Boost issues/feedback found on migrating to legoino V1.01

Hi Cornelius,
first of all thank you for this cool and active library. Congratulations for reaching a version 1, quite a milestone!

I was not aware that the API is that much under development, so I had to completely rework my Lego Boost example (AtomMatrixVernie in https://github.com/hrgraf/M5), which I only have started 1 month ago...

But organizing the library for more callbacks makes sense to me and seems to be more adapted to the BLE world.
Plus: new features such as Hub emulation sound very interesting.

Now about the issues that I have found during migration:
(tested with Lego Boost, my only powered up device)

  1. a lot of data type casting in the new API, e.g. enum to byte, even in code that is not time critical
    e.g. for port in activatePortDevice()

  2. don't understand the issue with delay() required for activatePortDevice()
    but even doing so, I get no HW/FW versions reported

  3. distance sensor unit does not seem to be cm, rather mm

  4. color sensor is reporting undefined color
    For me, reporting an undefined color is not an error, but a normal situation, that should be handled in the application, and not lead to error messages:
    [E][Lpf2Hub.cpp:424] parseColor(): undefined color (255)
    E.g. the example MoveHubColorSensor.ino crashes on line 34, because it does not check the color range
    For color range checking, there is no constant defined in your API
    I suggest the following (which I did in my fork of legoino). If you want, I can raise a pull request, but it is that simple:

--- a/src/Lpf2HubConst.h
+++ b/src/Lpf2HubConst.h
@@ -208,10 +208,11 @@ typedef enum Color
   ORANGE = 8,
   RED = 9,
   WHITE = 10,
+  NUM_COLOR,
   NONE = 255
 };
  1. few and late callbacks e.g. on distance or tilt sensor
    (This might be an issue of the Lego boost hub itself)
    I found that I get max. 15 updates (callback) in total per second, while I tilt the hub etc.
    The distance sensor has some lag, sometimes reports distance updates only after 1s.

  2. As you are using an AtomMatrix ESP32 device yourself, you could try out my AtomMatrixVernie example in https://github.com/hrgraf/M5). It is a nice demonstration of your legoino library and you could add it to your examples.

Cheers,
Hans-Rudolf

New HubEmulation only works on my iPhone

Hi,

I managed to upload the hub emulation example to my ESP32 (Lolin32 V1.0.0) and the Lego PoweredUp app (V3.5.0) on my iPhone connected without any issues.
When my son tried to connect with the Lego PoweredUp app (V3.5.0) on his Android phone or the Galaxy Tab the connecting fails.
Is this an isolated issue or can anyone reproduce this?
I havn't tried an earlier version of the Lego PU app yet.

Is it possible to auto-detect connected devices?

Hi!
Is it possible to detect what is connected to a specific port?
I'm playing with Technic Hub and the official Lego app is able to perform a connection-check when selecting the model to control.
I thought I could use the getDeviceTypeForPortNumber() method but it always return "0" even if a motor is connected to the specified port and I can control it with setMotorSpeed commands.

Thanks

Example to directly control Duplo train?

First of all: Thanks for this great library! I'm relatively new to these "new" Lego Duplo trains and was looking a way to control them via my ESP32 instead of the Lego App.
I'm just a bit confused about the concepts of "(Train)Hubs" and therefore not sure which example I could use as a starter to control our son's Duplo train to make it drive forward/backwards/stop/fill up etc.
Also how to figure out how to specify which of the trains should be the target of communication (we have two trains) would be important I guess.

If there are any examples that already exist that do (part of) what I'm looking for, I'd be happy if someone could point me towards it. Otherwise, if someone has already used it in this conjunction and could provide an example, that would also be great.

Thanks a lot!

Would it be feasable to have an ESP32 behave like an hub?

First of all, thanks a lot for this project!!! I have some issue s starting the hub but I'll try to debug that a little further before submitting it as an issue.
In the meantime I had this brainwave:
Maybe not completely in the scope of this project but I would like to be able to have the Powered Up /Boost App to reconize and connect to an Arduino kind of devices as an hub.... This way it would be possible to use the old power functions and even older motors in conjunction with the app and legoino.
So have legoino or the app sent out the command and an microcontroller receives it, just like the hub does, and processes it to whatever it is programmed to do with it...

Why use "enum struct" instead of "enum" for DuploTrainBaseSound?

enum struct DuploTrainBaseSound

For Color you use an enum which makes code much easier to read as you can just use RED or CYAN to refer to the respective colors. For the sounds, we have to write DuploTrainBaseSound::BRAKE which makes reading a bit more clumsy. It's of course nothing major and maybe I just overlook an important aspect, but if it is exchangeable, why not use a simple enum here as well?

NodeMCU ESP8266

Hello,

I'm using a NodeMCU ESP8266 and i'm attempting to use legoino but it fails. So my question is, is it possible to use legoino on a NodeMCU 8266?

Greetings,

Niek

Status --> is connected for train hub

Hello Cornelius,

first thanks lot lot for your fantastic work on the legion library. It works super for my train hubs.

I have one question. I want to implement a LED on the ESP32 to show if and which train is connected. Unfortunately the command "isConnected" shows me just the lastet status. So if I turn off the train hub the "isConnected" still is "1 or true". Is there any way to check if the connection ist available anymore.

Thank a lot and regards
Hölle

Make connection flow easier

With more devices handled in an Arduino sketch the connection flow and the boilerplate code becomes more and more complicated. In this issue i want to discuss the requirements of a more easy way of the connection procedure. Initial thoughts came from @falk12 written in the following thread of another issue:
#34 (comment)

Main Goals:

  • Single Setup command where the hub with attached devices, callbacks could be defined
  • If defined in the setup, the ports will be activated for updates automatically if a device is connected
  • Support of use and array multiple hub instances
  • Get rid of the isConnecting / connectHub methods and do this internally in the library

Duplo train - Invalid color name for no-color

Hello once again.

I try the DuploTrainBase example and work properly with my board.

But I noticed that if I lift the train base the callback function report a color of (int) 255 so in the serial display appear an invalid name (something that is readed like "???").

Could be useful add another color named "nocolor" (for example) in the COLOR_STRING array or map the color id > 10 as "black" in the parseColor() function.

Thank you,

GC84

Typo in README.md

According to the README the LED colours are:

Available colors are: BLACK, PINK, PURPLE, BLUE, LIGHT_BLUE, CYAN, GREEN, YELLOW, ORANGE, RED, WHITE

But LIGHT_BLUE should have been LIGHTBLUE

Please use scoped enums throughout Lpf2HubConst.h

Perhaps you could use scoped enums throughout Lpf2HubConst.h. Especially the Color enum (values) colides with other similar definitions and scoped enums would help to keep the code interoperable with other libraries.

Multiple Hub?

Hi,
it's possible to connecr/control more than one hub with ESP32?

Continuos reboot

Hi all,
after a white i came back to work on my project (last time i used ver 1.0.1 and everything works fine).
If i update the library (any verson > 1.0.1) the system reboot continuously.

abort() was called at PC 0x4011ec63 on core 1

ELF file SHA256: 0000000000000000

Backtrace: 0x4008ebdc:0x3ffc6ba0 0x4008ee59:0x3ffc6bc0 0x4011ec63:0x3ffc6be0 0x4011ecaa:0x3ffc6c00 0x4011f689:0x3ffc6c20 0x4011e6b8:0x3ffc6c40 0x4011f039:0x3ffc6c60 0x400d2edf:0x3ffc6c80 0x400d2f35:0x3ffc6cb0 0x400d31a5:0x3ffc6cd0 0x400d32ae:0x3ffc6d30 0x400d1abd:0x3ffc6d50 0x400d2c47:0x3ffc6da0 0x400e78e5:0x3ffc6dc0 0x4008fe5a:0x3ffc6de0

Rebooting...
ets Jun 8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 188777542, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5856
entry 0x400806a8

Maybe it depends to my code.
Tested with espe32 Dev and esp32 Pico..same result.

Thx for any help!

playSound and setLedColor very unreliable

Libraries: Legoino 1.0.2, NimBLE-Arduino 1.0.2
ESP32 board: AZ-Delivery ESP32 NodeMCU V2
Lego model: Duplo Loco from the 10874 set

Cornelius, big thanks for your Legoino library!

When I use Legoino, the methods setBasicMotorSpeed and stopBasicMotor both work perfectly every time. On the other hand, playSound and setLedColor are very unreliable and only do their job in about one out of three times called. Any ideas what I do wrong? Is there a known bug? Maybe in conjunction with certain ESP32 boards?

Attaching an .ino file renamed to .txt: Simplified.ino

Read reply from HUB

Hi @corneliusmunz,

thank you for your support, is a great thing that this project is alive!

Another question: I am digging into BLE protocol and I there are some command where HUB send reply to the Arduino.
For example command "Port Information Request" or "Port Input Format Setup"

So, if I understend correctly, I can send message from arduino to the HUB with the "WriteValue()" command. But how can I get access of this reply? There is a callback to register?

Or, there is already a function that handle reply for theese commands?

Thank you

Can you please add SBrick and BuWizz support?

Lego world has two main competitors to a standard PF controls, and those are SBrick and BuWizz.
They work through Bluetooth interface, and support controlling with phones or tablets.
They were a great substitution for PF receivers for many years, and a lot of Lego funs has at least one of them.
It would be nice if your library could also support those two - in that case you would probably cover 90% of all LEGO receivers (except various Chinese copies).
The only solution, that reverse engineers their protocols I found is here:
https://github.com/imurvai/brickcontroller2
But I cannot even compile and run it.

Feature Request: Non-blocking init

Thank you for writing a great library, I’m really enjoying exploring its potential.

One thing that seems out of place however is the blocking init call. When you are connecting to multiple hubs, and trying to control a complex environment, even one second can be too long for comms and the program to pause.

I notice the NimBLE library now supports a non-blocking scan function, is there any chance this can be brought across to Legoino?

TrainHub Does not seem to work

Hi There,

when I flash the train_esp example to my esp32, it is able to connect to the hub and also change the LED color. But it seems like it is not sending the right command for controlling the motor speed.

I tried both of the ports. Maybe this does not work for me, since lego installed an update to my hub when I used the PoweredUP App on iOS?

Thanks for helping me out :)

Rotation feedback of motors on all hubs

Hi,

I don't get anything working except the boost.
below the results for all hubs and motors with the columns motor/result when connected/feedback if turned manually
MoveHub
Boost Rotation: 0 [degrees] Ok
L Rotation: 10240 [degrees] none
XL Rotation: 33559552 [degrees] none
intern Rotation: 0 [degrees] Ok

ControlPlusHub
Boost Sometimes working
L Rotation: 16792320 [degrees] none
XL Rotation: 16792320 [degrees] none

PoweredUpHub
Boost Rotation: -12032 [degrees] none
L Rotation: -12032 [degrees] none
XL Rotation: -12032 [degrees] none

Here is the code based on your exmaple:
Only type of ports is changed, checking of DeviceType removed.
Please note: the delay(100) after init() makes connection much easier and faster

#include   "Lpf2Hub.h"

// create a hub instance
Lpf2Hub testHub;
//byte port = (byte)MoveHubPort::A; ///   #############################################
//byte port = (byte)PoweredUpHubPort::A;   /// #############################################
byte port = (byte)ControlPlusHubPort::A;   /// #############################################
 
void tachoMotorCallback(void *hub, byte   portNumber, DeviceType deviceType, uint8_t *pData)
{
Lpf2Hub *myHub = (Lpf2Hub *)hub;
 
Serial.print("sensorMessage callback for port: ");
Serial.println(portNumber, DEC);
int rotation = myHub->parseTachoMotor(pData);
Serial.print("Rotation: ");
Serial.print(rotation, DEC);
Serial.println(" [degrees]");
myHub->setLedHSVColor(abs(rotation), 1.0, 1.0);
}
 
void setup()
{
Serial.begin(115200);
testHub.init(); // initalize the MoveHub instance
delay(100);
}
 
// main loop
void loop()
{
 
// connect flow. Search for BLE services and try to connect if the   uuid of the hub is found
if (testHub.isConnecting())
{
testHub.connectHub();
if (testHub.isConnected())
{
Serial.println("Connected to HUB");
delay(200); //needed because otherwise the message is to fast after   the connection procedure and the message will get lost
// connect boost tacho motor  to   port d, activate sensor for updates, set callback function for rotation   changes
testHub.activatePortDevice(port, tachoMotorCallback);
delay(50);
 
testHub.setLedColor(GREEN);
}
else
{
Serial.println("Failed to connect to HUB");
}
}
}

 

Power Functions Sample Connection

Hello,

Very nice library, i like, it's really funny and usefull.

But, it's possible to have a full connetion scheme with IR for Power Functions ?

I try with IR led on Pin12, but for me, Power Functions doesn't work, probably my fault, in electronic part ?

Kind regards,

Color Sensor value for GREEN shows CYAN

@M9lab figured out in the gitter chat (https://gitter.im/legoinochat/community?at=5f96b2fcc7ef520fffc61333) that the library detects the color CYAN (value = 5) for a GREEN brick. After a short evaluation i can confirm this issue.

But some strange things appear here while checking the issue:

If you setup a PoweredUp program on the iOS or Android app, the sensor detects GREEN with the color detection block. But if you feed in the block to the Hub LED, the Hub LED will be set to CYAN. So i think the color sensor firmware does a wrong mapping of the GREEN color to the value 5 which means in Lego colors CYAN. In the visualisation of the App it seems that a remapping occurs here on the App SW side but if you feed in the value directly to the RGB light of the HUB the remapping is not applied and you see CYAN if your sensor faces a GREEN block.

Maybe some users can try out a similar program as the following and can check if this behaviour could be reproduced. If so, i could do the remapping in the legoino library that the sensor value 5 is mapped to 6.

IMG_7061

Using legoino together with esp32-ps3 not possible?

I would like to use my old PS3 controller together with legoino and found this library here: https://github.com/jvpernis/esp32-ps3
However, if I use their "Ps3Demo" from the example folder and simply add

#include "Lpf2Hub.h"
// create a hub instance
Lpf2Hub myHub;

at the top of the file and
myHub.init()
in the setup() function, the script either crashes with this message if I add the init() function after the PS3-related calls:

ESP_ERROR_CHECK failed: esp_err_t 0x103 (ESP_ERR_INVALID_STATE) at 0x40091b64
file: "/Users/frederik/Documents/Arduino/libraries/NimBLE-Arduino/src/NimBLEDevice.cpp" line 559
func: static void NimBLEDevice::init(const string&)
expression: esp_bt_controller_init(&bt_cfg)

Or throws this error (if myHub.init() goes before the PS3 attach functions) without crashing, but also without connecting to the PS3 controller anymore:

CRIT NimBLEDevice: "Resetting state; reason=19, "

Is it technically not possible to use legoino's BLE connection together with Esp32-Ps3's "classic" serial connection to the PS3 controller? Or is this something that could be resolved in code?
I'm referencing @jvpernis here as well just in case.

Impossible to connect more than 3 hubs

I have 10 PUP Smart Hubs, but i don't have success to connect more than 3 hubs simultaneously.
When i try to connect the fourth hub, the program stop execution...

Color detection very "sensitive"

I have not been able to emulate satisfactingly the behavior of my Duplo train when it comes to playing sounds based on the color tiles. The color scanner not only sends the color when driving over a tile, but now also reacts to any changes in the floor texture where the tracks are being laid out. For example, we have a wooden floor and this is often detected as "yellow" and therefore activates the "horn" sound. This does not happen when the train is running on its own.

I assume that there must be some kind of delay of some sort that needs to be addressed programmatically. Maybe this is not something that could/should be done directly in your library, but since this is the first go-to point and others might have this issue as well, it would be a good place to present a solution, I think.

Hub emulation dependency on NimBLE???

I installed the new 1.0.0 version of Legoino and while testing the HubEmulation example I got a compilation error on NimBLEDevice.h.
Maybe I missed a warning about dependencies but after I installed NimBLE-Arduino library it worked fine.
If it isn't in the documentation (I'm dyslexic so maybe I just missed it) I think it should be added :)

The motor does not rotate

Hi !,
I'm trying to move the sample, but the motor doesn't move.

The LED seems to work.

Please tell us the Firmware version of Boost that you are testing.

This uses the latest version 1.0.00.022.

Thank you for your answer.

HubEmulation support for more devices

Hi @corneliusmunz,

the HubEmulation is a great feature for the legoino library and will open tons of new applications, e.g. to control ESP32 projects with the Lego PoweredUp app.

While basic motor drive commands arrive, drive for angle etc. seems not be supported (yet)?
And what about other sensor data? Having bidirectional communication would increase possibilities.

I have started a HubEmulation example to emulate a Boost Move Hub using
an ESP32 Atom Matrix and try reporting its accelerometer as tilt to the PoweredUp app.

In legoino V1.0.2, Lpf2HubEmulation::start() does only support HubType::POWERED_UP_HUB resp. CONTROL_PLUS_HUB.
So in my fork, I have added manufacturerData for the BOOST_MOVE_HUB.

Next, getPortInformationPayload() and getPortModeInformationRequestPayload() support only DeviceType::TRAIN_MOTOR and HUB_LED. How to add more devices, e.g. MOVE_HUB_TILT_SENSOR?

Where/how did you get the payload values in those functions?

My approach is very tedious and takes many iterations: I use another sketch with a legoino Boost hub, where I request the same from the real Lego Boost Hub and log the answers. Then, I can enter them in the HubEmulation and have another try.

Any better idea or more documentation on this?
Any plans on such features on your side?

Callback functions for connection status

Hi @corneliusmunz,
would it be able to introduce some handy callbacks for the following events?

connecting(): hub is connecting

connected(): hub has been connected. Might only be useful if .connect() is converted into a non-blocking function as well.

disconnected(): hub has disconnected

Keep up to good work!

Unable to connect multiple hubs since release 1.0.4

Hi @corneliusmunz,
we appreciate the non-blocking connection procedure introduced with release 1.0.4. This is a great improvement, thank you very much for that.

We have experienced the following problem:

  • We want to connect to multiple hubs.
  • You call init() for multiple hubs BEFORE the hubs actually connect to the PC.
  • Only the last hub that was initialised will be connected, not the other ones.

We had to create a relatively complitcated work around to overcome this problem.

Maybe you could have a look into this?

Thanks!

Some issue sconnecting for the first time

Not sure why but my ESP32 won't connect if the Movehub has been turned of for a longer period of time.
When I connect it first to the Powered Up app on my phone and then close the app again the ESP connects without any problems. But when I try to do it without "waking" the hub (Boost Movehub) with the app the ESP won't connect.
Does this sound familiar?

Best approach to test if connection is still active?

I would like to detect whether and established connection is still active or whether the device (here: Duplo train) has been turned off. So far, if I turn off the device, myHub.isConnected() continues to evaluate as true.

Is there some kind of variable or characteristic I can read that is continuously updated and from which I can detect whether the connection is still active? Or can I send a command to the device that will generate a response?

And once I have figured out that the device has been turned off, what actions do I need to take to get my code back into listening mode? Do I have to do a myhub.init() again? Or can I somehow "close" the connection and then myHub will be in scanning mode again?

Thanks!

Add configurable option to set BLE Power level

It would be good to enable the user to set the BLE Power level without calling NimBLE-Arduino functions. Maybe the default levels could be changed from -3dB to +9dB

The power levels for scan, advertisment and default could be changed with the static NimBLE-Arduino function
void NimBLEDevice::setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType)

With esp_power_level_t

/*
ESP_PWR_LVL_N12 = 0, Corresponding to -12dbm
ESP_PWR_LVL_N9  = 1, Corresponding to  -9dbm
ESP_PWR_LVL_N6  = 2, Corresponding to  -6dbm
ESP_PWR_LVL_N3  = 3, Corresponding to  -3dbm
ESP_PWR_LVL_N0  = 4, Corresponding to   0dbm
ESP_PWR_LVL_P3  = 5, Corresponding to  +3dbm
ESP_PWR_LVL_P6  = 6, Corresponding to  +6dbm
ESP_PWR_LVL_P9  = 7, Corresponding to  +9dbm
*/

and esp_ble_power_type_t

/*
ESP_BLE_PWR_TYPE_ADV        = 9,  For advertising
ESP_BLE_PWR_TYPE_SCAN       = 10, For scan
ESP_BLE_PWR_TYPE_DEFAULT    = 11, For default, if not set other, it will use default value
 */

@fvanroie : I've seen this in your code and thought that this would be a good way to increase the usable distance of the BLE connections to the hubs. Do you have faced any issues about remarkable lower battery lifetimes?

Legoino 1.0.1 do not compile on arduino IDE 1.8.3

Hello,

I just installed Legoino library for arduino 1.8.3 but the "DuploTrainExample" do not compile (here the error log file). I edit the "Lpf2Hub.cpp" file (where the error were reported) and modified line 106 (error in implicit cast), line 784 (return is missing, I put -1 but unsure of the result) and line 466 (in for loop index i is not initialized).

With new file the example compile, but I am not sure about results.

Thanks,

GB

Core 1 panic'ed

I am using an M5Stack 2020 Atom Matrix ESP32 PICO
This is my first project. I built a remote control for the hub. This is already running.
I noticed 2 problems in the function init ().
Problem 1:
Sketch 1:

void setup() {
Serial.begin(9600);

IrReceiver.begin(22, true);
myHub.init();
}

void loop() {

}

This leads to the following crash:

V⸮⸮1
l+⸮⸮0⸮f⸮�⸮⸮⸮,lYK⸮j
녑:0x&⸮⸮�⸮⸮�⸮leK⸮044C!⸮+⸮⸮0x�⸮78⸮⸮,⸮⸮⸮�h<NJ"ҋ�⸮"� ⸮⸮95� ⸮⸮⸮�)�⸮Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed)
Core 1 register dump:
PC : 0x400d17c8 PS : 0x00060034 A0 : 0x80081458 A1 : 0x3ffbe7b0
A2 : 0x00000064 A3 : 0x20000000 A4 : 0x00000400 A5 : 0x3ffc5d10
A6 : 0x00000000 A7 : 0x3ffc5d4c A8 : 0x80081017 A9 : 0x00000000
A10 : 0x00000001 A11 : 0x00000000 A12 : 0x00000000 A13 : 0x00000000
A14 : 0x00000000 A15 : 0x00000005 SAR : 0x00000016 EXCCAUSE: 0x00000007
EXCVADDR: 0x00000000 LBEG : 0x4000164d LEND : 0x40001667 LCOUNT : 0xfffffffc
Core 1 was running in ISR context:
EPC1 : 0x400931c6 EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x400d17c8

Backtrace: 0x400d17c8:0x3ffbe7b0 0x40081455:0x3ffbe7d0 0x400848dd:0x3ffbe7f0 0x400931c3:0x3ffc5d70 0x400939c1:0x3ffc5d90 0x40087504:0x3ffc5db0 0x400f1d0d:0x3ffc5e20 0x400f05dd:0x⸮
*
*
The following sketch works:
void setup() {
Serial.begin(9600);
myHub.init();
IrReceiver.begin(22, true);

}

Problem 2:
The following sketch leads to a crash after about 9300 runs:

#include <Lpf2Hub.h>

Lpf2Hub myHub;
int i;

void setup() {
Serial.begin(9600);
myHub.init();
i = 0;
}

void loop() {

if (!myHub.isConnected() && !myHub.isConnecting())
{
myHub.init();
}

Serial.println (i++);

} // End of loop

9321
9322
abort() was called at PC 0x40108b5f on core 1

Backtrace: 0x40090a94:0x3ffc5e40 0x40090cc5:0x3ffc5e60 0x40108b5f:0x3ffc5e80 0x40108ba6:0x3ffc5ea0 0x401086ed:0x3ffc5ec0 0x40108440:0x3ffc5ee0 0x401088a5:0x3ffc5f00 0x400d1983:0x3ffc5f20 0x400d19d9:0x3ffc5f50 0x400d1a31:0x3ffc5f70 0x400d1758:0x3ffc5fd0 0x400e395d:0x3ffc5ff0 0x4008d4e5:0x3ffc6010

Rebooting...
�B⸮⸮8�⸮"⸮⸮⸮JQ⸮⸮Z⸮⸮Sa⸮@⸮S!⸮⸮0
1
2
3

Support for "StartSpeed" sub command 0x07/0x08

Der Cornelius,
first of all, thank you very much for all your efforts and the really nice software your have created. Because I became aware of legoino, I got myself an ESP32 dev board - installed all the things required and it just was going like a charm: Can control the PoweredUp hub (2I/O) using your software.
I also got myself the LEGO crocodile, and a Pup L Motor. I am programming my own pieces of software using VB6 (no joke) with the nsoftware BLE stack (I got that for free from them, when I told them what I was planning to do ... nice move!)
So far I can control 10+ hubs (Technic hubs (4I/O) and Hubs (2I/O). All on a very basci level, as I am no programmer at all - I'm a chemist :-)
My question is, whether you are planning on implementing the StartSpeed sub command (0x07/0x08) of the output command 0x81? I believe you have done that for the Boost controller already. The rather new Pup L motor (in contrast to the train motor) has a built-in rotation sensor. I used that feature to run my Crocodile - an it goes really smoothly. Nice to see it moving slowly but at constant speed. I simply used the LWP StartSpeed (Speed, MaxPower, UseProfile) command with MaxPower 100(%) and UserProfile = 0 (no profile).
My current project is to equip the piece of track on the wall with some sensors, and then sue the ESP32 along with your software to let it go back and forth; here is the idea: https://www.eurobricks.com/forum/index.php?/forums/topic/179240-mod-10277-and-on-and-on-another-crocodile-mod-%E2%80%A6/
All the best
Thorsten

Add a status variable/function to determine whether a non-blocking scan is still active

The default duration for a scan is 10 seconds. If you start the ESP32, it will scan for that duration for any kind of device, but not after these 10 seconds. So if you turn on your device after that period, it won't connect unless you restart the ESP32.
If one could test whether the non-blocking scan is over, one could restart the scan by calling myHub.init() again afterwards.

I tried to add the variable _isScanning and set it to true in the start() function and set it again to false in the scanEndedCallback() function, but somehow these are in different namespaces and I can't pass a pointer to _isScanning, so it didn't work out with my limited C++ knowledge. Do you have any idea wheter this could be achieved properly? Thanks!

Include 'Lpf2Hub* hub' parameter in HubPropertyChangeCallback ?

I'm updating my code to test the new capabilities in the feature/add_hub_emulation branch. In my code I have multiple tasks connecting to multiple PU hubs. I'm a bit stuck with the new callback functions.

It seems each callback can only be used with one specific hub e.g. global myMoveHub, since the callback has no way of knowing for which hub it is receiving the update. Would it make sense to include a Lpf2Hub* this property, or something to distinguish the affected Hub?

The callback might be;

// callback function to handle updates of hub properties
void hubPropertyChangeCallback(Lpf2Hub* hub, HubPropertyReference hubProperty, uint8_t *pData)
{
  Serial.print("HubProperty: ");
  Serial.println((byte)hubProperty, HEX);

  if (hubProperty == HubPropertyReference::RSSI)
  {
    Serial.print("RSSI: ");
    Serial.println(hub->parseRssi(pData), DEC);  // use this-> instead of a global myMoveHub
    return;
  }
}

I want to avoid having to write several callbacks, one for each of hub in the network. What do you think?

HUB emulation PORT A

Hi,
legoino is a perfect project, thank you.
I have a problem with HUB emulation.
HW I use NodeMcu WROOM-32
I monitor the data on a serial monitor.
Everything is OK for PORT B.
For HUB LED it is OK.
But I don't get any data for PORT A.
Who could be the problem?
Will emulation also be available for TechnicHUB?
Thank you

Feature Request HubEmulation: Support for regulated Motors

Thank you for your project, its really great and fun to work with!

Currently I am working on a ESP32-based legoino hub to connect old NXT / EV3 motors (and eventually NXT / EVE3 sensor) to the new PoweredUp app (and other devices using the new protocol). Hardware is rather simple, but unfortunately it seems like its currently not possible to register anything but train motors, or is it?

Also the callback only seems to support one byte channel and one byte payload. No subcommands nor multibyte payloads seem to be supported, which are necessary for more advanced control for regulated motors.

So can you give me a hint whether you are working on these problems or where to look myself to provide a patch?

Make PowerFunctions library useable for ESP8266

First of all congratulations to your wonderful library. As discussed, we are using it in our Mattzobricks project of automated LEGO trains (www.mattzobricks.com).

When having the Legoino library installed, it is impossible to compile a firmware for an ESP8266 that uses the PowerFunctions library.

If you include the PowerFunctions library, the compile will fail, because all other parts of the Legoino will also be compiled - this will fail on ESP8266 because it does not support Bluetooth.

If you install the PowerFunctions library in an extra folder, this will lead to a conflict between the PowerFunctions library that is included in the Legoino library.

It would be great if you had a solution for this.

Thanks a lot!

Using several Lpf2Hub instances possible?

First of all, I'm not sure if this is a doublette of #46 - if so, feel free to close this right now.
I'm trying to connect my ESP32 to three Lego Duplo trains. The way I'm doing this is that I setup an array of Lfp2Hub objects like this:

#define HUBS 3
Lpf2Hub* myHubs[HUBS];
Lpf2Hub* myHub;

and then send all of them into init mode in setup():

  for (int x=0; x<HUBS; x++) {
    myHubs[x] = new Lpf2Hub;
    myHubs[x]->init();
  }

Subsequently, I can cycle through them in a for-loop:

  for (int hub=0; hub<HUBS; hub++) {
    myHub = myHubs[hub];
    if (myHub->isConnecting()) {
      ...
    }
  }

However, this only works for the first train to be connected, and this will always be the last element of the myHubs array (2 in this case). Also, once the first connection is made, any subsequent train that is turned on won't connect.

After reading #46, I was wondering if this also has to do with the blocking-/non-blocking approach. But if changing to a blocking model would be necessary to connect multiple hubs, wouldn't that mean that I'd have to a) define how many hubs I want to use and b) make sure that all of these hubs are connected before the code will continue to execute? Because that's what blocking means, isn't it?
My goal would be that my kids can decide whether they put 1, 2 or 3 trains on the track and all active ones could be controlled (I would use the PS3 controller's "SELECT" button to switch between them). However, it seems that with blocking mode, they would have to always use the same number of trains, wouldn't it?

Library compatibility problem

Hi,

The Legoino library is not compatible with the M5Stack / M5StickC Library due to re-declaration of colors.
I propose to rename the color in the library like that (file Lpf2Hub.h) :

typedef enum Color
{
  LEGO_BLACK = 0,
  LEGO_PINK = 1,
  LEGO_PURPLE = 2,
  LEGO_BLUE = 3,
  LEGO_LIGHTBLUE = 4,
  LEGO_CYAN = 5,
  LEGO_GREEN = 6,
  LEGO_YELLOW = 7,
  LEGO_ORANGE = 8,
  LEGO_RED = 9,
  LEGO_WHITE = 10,
  LEGO_NONE = 255
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.