Belle-Ve Bricks

Your Imagination

power function

LEGO Powered Up vs Power Functions

Create Your

We help you from start to finish to create and deliver your tailor-made custom model.
Custom model
Continue

LEGO Powered Up is the current line of electric components that allows you to motorize LEGO® Technic sets (or MOCs for that effect too). LEGO® Powered Up was released in 2018 and has evolved quite a bit since then with LEGO® Power Functions being officially discontinued in 2020.

Key Takeaway

LEGO Powered Up vs Power Functions Video

YouTube video

LEGO Powered Up & Power Functions Pros and Cons

Let’s do a quick comparison between the two without diving too deep into the technical details.

The LEGO® Powered UP line of products brought with it several innovations and improvements over its predecessor as you would expect from a new product.

What LEGO Motor Upgrades Are There?

The main upgrade was the use of Bluetooth to communicate with the electric components remotely, which allowed for control at longer distances and outdoor play, something Power Functions fell short of which used infrared light instead that was prone to issues as sunlight easily interfered with it.

A noteworthy upgrade was also the inclusion of sensors inside the motors, which can detect the axle position and make it turn the right amount instead of rotating constantly, basically turning a regular motor into a servo motor; the LEGO® Power Functions line couldn’t do this, a dedicated servo motor was needed for such functions, and still, it could only turn 90º to each side with the standard controller, or had 15 predefined positions if using it with the less known “speed controller” (which wasn’t usable for steering purposes due to its very slow update time).

Another major change was the fact that LEGO® Powered UP now needs a compatible android or iOS device with the Control+ app installed which works as a remote control. This allows for custom controls and virtual buttons for each LEGO® set.

In contrast, LEGO® Power Functions had its infrared emitting control with just two buttons and that was it, the same controller was used for all LEGO® Power Function sets without customizable controls.

At this point, it seems like LEGO® Powered Up is amazing, and it is, but there are some aspects limiting its success and adoption rate.  Innovation and new features came at a cost… complexity!

LEGO Powered Up

One of the main reasons for controversy is the requirement of a compatible android or iOS device to control all of the LEGO® Powered Up functions, it’s third-party hardware that may at some point in the future cease to exist and is also another expense to factor in if you are let’s say, an Apple fan.

I understand LEGO® probably went this way because smartphones are everywhere now, iOS and android operating systems are incredibly popular and it was probably cheaper to develop an app rather than to design and produce hundreds of thousands of remote controls. Nonetheless, this introduced a lot more steps and complexity to make the system work.

LEGO Powered Up Control + App

The control+ app needs to be downloaded and installed, Bluetooth needs to be synced between the device and the LEGO® Powered Up hub, and then controls need to be configured for each particular set, although recent updates made things easier on this front. It may take 10+ minutes to actually get stuck in and start playing with your motorized Technic set.

The Power Functions system didn’t need any of that, you just turned the battery box on, placed the control in the same channel as the receiver and you’re good to go, it took just seconds.

There are other things that LEGO® fans don’t like about the LEGO® Powered Up system, like the fact it is directly incompatible with LEGO® Power Functions elements since the connectors are different; you are also limited to just four elements per hub, while you could stack and connect as many elements as you wanted on the Power Functions IR receiver; not to mention the price, Powered Up parts are overall more expensive, and it is slowing down adoption in general.

LEGO Powered-Up Features

The extra features LEGO® Powered Up offers surely allow for more creative freedom, but its added complexity took some of the fun away and created a steeper learning curve for newcomers, while LEGO® Power Functions remained simple to use and intuitive. This is why many LEGO® Technic fans still haven’t made the move into LEGO® Powered Up and prefer its predecessor, LEGO® Power Functions, which can be enhanced with third-party hardware, but that’s for another topic.

LEGO Power Functions

Despite LEGO® Power Functions being officially discontinued, if you like the system and want to get your hands on some parts, there is still one official way to get them, and that is through the 42095 set, the “Stunt Racer”, which is still supported and includes 5 Power Functions elements: 2 l-motors, 1 remote-controller, 1 IR receiver, and 1 battery box.

It’s a tracked vehicle that can do wheelies, but even if you don’t like the model in this set, there are amazing MOCs and alternative models you can build with it, a lot of remote-controlled racers with steering capabilities that’s for sure, visit my store to check them out!

Conclusion

<div class="badge-base LI-profile-badge" data-locale="en_US" data-size="large" data-theme="dark" data-type="HORIZONTAL" data-vanity="ferdi-vol" data-version="v1"><a class="badge-base__link LI-simple-link" href="https://www.linkedin.com/in/%E2%9C%85-ferdi-vol-corporate-gifts/?trk=profile-badge"></a></div>
/* Auto generated, hash = 5dceu9kevqjdyuy2uw1atqrsu */
//TODO: Break this file down so that we can actually unit test it.
(function(window) {
  /**
  * Renders all unrendred LinkedIn Badges on the page
  */
  window.LIRenderAll = function () {
    var CALLBACK_NAME     = 'LIBadgeCallback', //Must match callback on helpers.js
        BADGE_NAMES       = '.LI-profile-badge, .LI-entity-badge',
        // TODO -- tracking param for other badge types
        TRACKING_PARAM    = 'profile-badge',
        responsesReceived = 0, //Keeps track of number of responses recieved for proper cleanup when finished
        expectedResponses = 0, //Keeps track of number of responses to expect
        scripts           = [ ], //Keeps track of scripts added for proper cleanup when finished
        childScripts      = {}, //Keeps track of child scripts to render
        badges            = Array.prototype.slice.call(document.querySelectorAll(BADGE_NAMES));

    var i, len, badge, rendered;
    for (i = 0, len = badges.length;  i < len; i++) {
      badge    = badges[i];
      rendered =  badge.getAttribute('data-rendered');
      if (!rendered) {
        expectedResponses++;
        badge.setAttribute('data-rendered', true);
        renderBadge(badge);
      }
    }

    function isCNDomain() {
      if (typeof window !== "undefined") {
        var hostName = window.location && window.location.hostname ||  '';
        return (/linkedin(-ei)?.cn$/).test(hostName);
      }

      return false;
    }

    function generateUrl(isEI) {
      var domainPrefix = isEI ? 'https://badges.linkedin-ei' : 'https://badges.linkedin';
      if (isCNDomain()) {
        return domainPrefix + ".cn/";
      }

      return domainPrefix + ".com/";
    }

    function getBadgeKeyQueryParams(badge) {
      return Array.prototype.slice.call(badge.attributes).filter(function (attr) {
        return attr.name.lastIndexOf('data-key-', 0) !== -1;
      }).map(function (attr) {
        // Most browsers automatically lowercase the attribute name when its being read
        // We are calling lowercase on it again to ensure consistency for any browsers that are lagging behind.
        return encodeURIComponent(attr.name.replace('data-', '').toLowerCase()) + '=' + encodeURIComponent(attr.value);
      });
    }

    /*
    * Renders a single badge on the page
    * @param badge: div element of badge to render
    */
    function renderBadge(badge) {
      var size       = badge.getAttribute('data-size'),
          locale     = badge.getAttribute('data-locale'),
          type       = badge.getAttribute('data-type'),
          theme      = badge.getAttribute('data-theme'),
          vanity     = badge.getAttribute('data-vanity'),
          version    = badge.getAttribute('data-version'),
          isEI       = badge.hasAttribute('data-ei'),
          entity     = badge.getAttribute('data-entity'),
          isCreatePage = badge.hasAttribute('data-iscreate'),
          uid        = Math.round(1000000 * Math.random()),
          baseUrl = generateUrl(isEI),
          queryParams = [
            'locale=' + encodeURIComponent(locale),
            'badgetype=' + encodeURIComponent(type),
            'badgetheme=' + encodeURIComponent(theme),
            'uid=' + encodeURIComponent(uid),
            'version=' + encodeURIComponent(version)
          ],
          url;

      if (version === 'v2') {
        baseUrl += 'view';
        queryParams.push('badgesize=' + encodeURIComponent(size));
        queryParams.push('entity=' + encodeURIComponent(entity));
        queryParams = queryParams.concat(getBadgeKeyQueryParams(badge));
      } else {
        baseUrl += 'profile';
        queryParams.push('maxsize=' + encodeURIComponent(size));
        queryParams.push('trk=' + encodeURIComponent(TRACKING_PARAM));
        queryParams.push('vanityname=' + encodeURIComponent(vanity));
      }

      if (isCreatePage) {
        queryParams.push('fromCreate=true');
      }

      url = baseUrl + '?' + queryParams.join('&');
      badge.setAttribute('data-uid' , uid);
      jsonp(url); //Calls responseHandler when done
    }

    /**
    * Handles a response from the server. Finds badge matching badgeUid and inserts badgeHtml there
    * @param badgeHtml: String representing contents of the badge
    * @param badgeUid: UID of the badge to target
    **/
    function responseHandler(badgeHtml, badgeUid) {
      responsesReceived ++;

      var i, badge, uid, isCreate;
      var defaultWidth = 330 // max possible width
      var defaultHeight = 300 // max possible height

      for (i = 0, len = badges.length; i < len; i++) {
        badge = badges[i];
        // isCreate needed to prevent reloading artdeco script tag
        isCreate = badge.getAttribute('data-iscreate');
        uid   = parseInt(badge.getAttribute('data-uid'), 10);
        if (uid === badgeUid) {
          var badgeMarkup = `<body>${badgeHtml}</body>`
          var iframe = document.createElement('iframe');
          iframe.onload = function() {
            var iframeBody = iframe.contentWindow.document.body;
            // 5 px buffer to avoid the badge border being cut off.
            iframe.setAttribute('height', (iframeBody.scrollHeight || defaultHeight) + 5);
            iframe.setAttribute('width', (iframeBody.scrollWidth || defaultWidth) + 5);
          };
          iframe.setAttribute('frameBorder', '0');
          iframe.style.display = 'block';
          badge.appendChild(iframe);
          iframe.contentWindow.document.open();
          iframe.contentWindow.document.write(badgeMarkup);
          iframe.contentWindow.document.close();
          replaceScriptTags(badge, isCreate);
        }
      }
      tryClean();
    }

  // These functions are needed because badge markup is added via innerHtml property which does not run script tags
  function replaceScriptTags(node, isCreate) {
    if (shouldReplaceNode(node, isCreate)) {
      node.parentNode.replaceChild(cloneScriptNode(node), node);
      childScripts[node.src] = true;
    } else {
      var i = 0,
          children = node.childNodes;
      while (i < children.length) {
        replaceScriptTags(children[i++], isCreate);
      }
    }
    return node;
  }

  function shouldReplaceNode(node, isCreate) {
    return isScriptNode(node) && !childScripts[node.src] && (!isCreate || (isCreate && !node.getAttribute('data-isartdeco')));
  }

  function isScriptNode(node) {
    return node.tagName === 'SCRIPT';
  }

  function cloneScriptNode(node){
    var script  = document.createElement("script");
    for( var i = node.attributes.length-1; i >= 0; i-- ) {
      script.setAttribute( node.attributes[i].name, node.attributes[i].value );
    }
    return script;
  }

    // Gets all incoming responses
    window[CALLBACK_NAME] = responseHandler;

    /**
    * Tries to clean added tags
    **/
    function tryClean() {
      //Clean up after all requests are done..
      //Accounts for people including script more than once
      var done = (responsesReceived >= expectedResponses && expectedResponses > 0) || responsesReceived >= badges.length;
      if (done) {
        delete window[CALLBACK_NAME];

        // remove all script tags
        scripts.map(function(script){
          document.body.removeChild(script);
        });

      }
    }

    /*
    * Makes Jsonp request, responses handles by CALLBACK_NAME
    * @param url String: url of server to make request to
    */
    function jsonp(url) {
      var script = document.createElement('script');
      script.src = url;
      scripts.push(script);
      document.body.appendChild(script);
    }
  };

  if (document.readyState === 'complete') {
    window.LIRenderAll();
  } else {
    window.addEventListener('load', window.LIRenderAll, false);
  }

})(window);
Popular Posts