• Recent
  • Tags
  • Unsolved
  • Solved
  • MagicMirror² Repository
  • Documentation
  • 3rd-Party-Modules
  • Donate
  • Discord
  • Register
  • Login
MagicMirror Forum
  • Recent
  • Tags
  • Unsolved
  • Solved
  • MagicMirror² Repository
  • Documentation
  • 3rd-Party-Modules
  • Donate
  • Discord
  • Register
  • Login
A New Chapter for MagicMirror: The Community Takes the Lead
Read the statement by Michael Teeuw here.

MMM-PiLights - Control a LPD8806 Led Strip on a Raspberry Pi

Scheduled Pinned Locked Moved Utilities
17 Posts 7 Posters 14.8k Views 9 Watching
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    jc21
    last edited by Sep 21, 2016, 3:27 AM

    This guide should cover it. Although that is for older raspberry pi models but still worth a read.

    For raspberry pi 3 I’ve connected the pins [DI to 20] and [CI to 24] as labelled in this image.

    1 Reply Last reply Reply Quote 1
    • K Offline
      KirAsh4 Moderator
      last edited by Sep 21, 2016, 4:44 AM

      I’m referring to adding it to the repository README.md file.

      A Life? Cool! Where can I download one of those from?

      1 Reply Last reply Reply Quote 0
      • K Offline
        KirAsh4 Moderator
        last edited by Sep 21, 2016, 4:54 AM

        And technically speaking, the LPD8806 chipset requires 4 wires for input: VCC, GND, DATA_IN (DI), and CLOCK_IN (CI). On a Raspberry Pi 3, the SPI port is on pins:

        MOSI    P1-19  (Master Out Slave In)
        MISO    P1-21  (Master In Slave Out)
        SCLK    P1-23
        GND     P1-25
        CE0     P1-24
        CE1     P1-26
        

        For DATA_IN, you should use the MOSI (19) pin, and for CLOCK_IN, the SCLK (23) pin. Pins 24 and 26 are chip select pins if you happen to have several SPI slave devices and needed to select which one you’re addressing.

        A Life? Cool! Where can I download one of those from?

        1 Reply Last reply Reply Quote 0
        • J Offline
          jc21
          last edited by Sep 22, 2016, 4:14 AM

          Ahh you are correct that is how I have it connected, I just had a dyslexic moment and named the opposing pins by accident :/

          1 Reply Last reply Reply Quote 0
          • S Offline
            schmo90
            last edited by Jan 19, 2017, 7:45 AM

            Hy

            i changed your module to work with the common W2801 Led Strips.

            Now i wanted to add some new sequences.
            I modified the switch case but everytime i will go to this sequence with the http request i get the answer, squence not found.

            this.expressApp.use(bodyParser.urlencoded({extended: true}));

                this.expressApp.get('/PiLights', (req, res) => {
                    console.error('[PiLights] Incoming:', req.query);
            
                    if (typeof req.query.sequence !== 'undefined') {
                        // Sequence
            
                        this.runSequence(req.query.sequence)
                            .then(function () {
                                res.status(200)
                                    .send({
                                        status: 200
                                    });
                            })
                            .catch(function (err) {
                                res.status(400)
                                    .send({
                                        status: 400,
                                        error: err.message
                                    });
                            });
            
                    } else {
                        res.status(400)
                            .send({
                                status: 400,
                                error: 'Sequence not specified'
                             });
                    }
            

            So if i send a new sequence then i will get the answer 400 sequence not specified.
            Where do you specify the available sequences?

            With Best regards
            Schmo

            A 1 Reply Last reply Jan 22, 2017, 10:04 AM Reply Quote 0
            • J Offline
              jc21
              last edited by Jan 19, 2017, 10:28 PM

              Hi schmo90, good to see you’re contributing :)

              Assuming your tests with curl -X GET "http://yourmagicmirror/PiLights?sequence=blue_pulse" still don’t work, I think I’d need to see all of your changes. If you’ve forked my repo on github can you please link it?

              1 Reply Last reply Reply Quote 0
              • S Offline
                schmo90
                last edited by Jan 20, 2017, 9:22 AM

                Hy

                yeah i made a infinite mirror behind the magic mirror :-)

                your animations are working fine with my change of your led strip class to my w2801 class.
                But if i add some squences in the switch case, for example ‘off’ then i get the request error.

                is there some hidn node.js thing where you define the possible sequences?

                I have to say i am a C# developer and it is the first time with node.js…
                No debugging and intellisense with nano is realy painfull^^

                J 1 Reply Last reply Jan 22, 2017, 9:11 AM Reply Quote 0
                • J Offline
                  jc21 @schmo90
                  last edited by Jan 22, 2017, 9:11 AM

                  @schmo90 It should work fine, there is no logic prior to that switch that filters possible values.

                  What does the server console log report after the text [PiLights] Incoming: ?

                  req.query.sequence should contain the string name of the sequence you’re requesting.

                  1 Reply Last reply Reply Quote 0
                  • A Offline
                    Ashidian @schmo90
                    last edited by Jan 22, 2017, 10:04 AM

                    @schmo90 I bought a WS2801 LED strip as well. What did you changed to use this module with your strip?

                    I think it would be great for this module to implement both possibilities of LED strips so one can set the type in the properties, wouldn’t it?

                    1 Reply Last reply Reply Quote 0
                    • S Offline
                      schmo90
                      last edited by schmo90 Jan 22, 2017, 11:40 AM Jan 22, 2017, 11:38 AM

                      hy i found out that node.js will not allow to call some functions.

                      it jumped everytime into the try catch.

                      but now it is working fine…
                      and you need to install the ws2801 npm packages from
                      https://www.npmjs.com/package/rpi-ws2801

                      here is the file:
                      (but i dont know if the uplaod worked…)
                      [0_1485084948629_node_helper.js](Uploading 100%)

                      /* global require */
                      
                      const _ = require('lodash');
                      const Color = require('color');
                      const NodeHelper = require('node_helper');
                      const bodyParser = require('body-parser');
                      const LPD8806 = require('lpd8806-async');
                      //const WS2801	 = require('rpi-ws2801');
                      const async = require('async');
                      
                      var ajv = require('ajv')({
                          allErrors: true,
                          format: 'full',
                          coerceTypes: true
                      });
                      
                      module.exports = NodeHelper.create({
                      
                          config: {},
                          animationRunning: false,
                          stopAnimationRequest: false,
                          defaultSpeed: 100,
                      
                          /**
                           * node_helper start method
                           */
                          start: function () {
                              console.log('[PiLights] Starting node_helper');
                      
                              this.expressApp.use(bodyParser.json());
                              this.expressApp.use(bodyParser.urlencoded({ extended: true }));
                      
                              this.expressApp.get('/PiLights', (req, res) => {
                                  console.error('[PiLights] Incoming:', req.query);
                      
                                  if (typeof req.query.sequence !== 'undefined') {
                                      // Sequence
                      
                                      this.runSequence(req.query.sequence)
                                          .then(function () {
                                              res.status(200)
                                                  .send({
                                                      status: 200
                                                  });
                                          })
                                          .catch(function (err) {
                                              res.status(400)
                                                  .send({
                                                      status: 400,
                                                      error: err.message
                                                  });
                                          });
                      
                                  } else {
                                      res.status(400)
                                          .send({
                                              status: 400,
                                              error: 'Sequence not specified'
                                          });
                                  }
                              });
                          },
                      
                          /**
                           *
                           * @param {String} notification
                           * @param {*}      payload
                           */
                          socketNotificationReceived: function (notification, payload) {
                              if (notification === 'START') {
                                  this.config = payload;
                      
                                  try {
                                      console.info('Trying to load leds');
                      
                                      // Internal reference to rpi-ws2801
                                      this.leds = require("rpi-ws2801");
                                      this.leds.connect(this.config.ledCount, this.config.device);
                                      // Initialize off
                                      this.leds.fill(0x00, 0x00, 0x00);
                                      //this.leds.setMasterBrightness(this.config.brightness);
                      
                                      console.log('[PiLights] Leds connected ok');
                      
                                  } catch (err) {
                                      console.error('[PiLights] Unable to open SPI (' + this.config.device + '), not supported?', err.message);
                                      this.leds = null;
                                  }
                      
                              } else if (notification === 'SEQUENCE') {
                                  Promise.resolve(this.runSequence(payload)
                                      .catch(function (err) {
                                          console.log('[PiLights] Sequence error: ' + err.message);
                                      }));
                              }
                          },
                      
                          /**
                           * Runs a light sequence
                           *
                           * @param   {String}  sequence
                           * @param   {Integer} [iterations]
                           * @returns {Promise}
                           */
                          runSequence: function (sequence, iterations) {
                              var self = this;
                              iterations = iterations || 20;
                      
                              return new Promise(function (resolve, reject) {
                                  var colors = [0, 0, 0];
                      
                                  switch (sequence) {
                                      case 'blue_pulse':
                                          colors = [0, 0, 255];
                                          break;
                                      case 'white_pulse':
                                          colors = [255, 255, 255];
                                          break;
                                      case 'lightblue_pulse':
                                          colors = [0, 255, 255];
                                          break;
                                      case 'red_pulse':
                                          colors = [255, 0, 0];
                                          break;
                                      case 'green_pulse':
                                          colors = [0, 255, 0];
                                          break;
                                      case 'orange_pulse':
                                          colors = [255, 170, 0];
                                          break;
                                      case 'pink_pulse':
                                          colors = [255, 0, 255];
                                          break;
                                      case 'off':
                                          colors = [0, 0, 0];
                                          iterations = 1;
                                          break;
                                      default:
                                          reject(new Error('Unknown sequence: ' + sequence));
                                          return;
                                          break;
                                  }
                                  resolve(self.pulse(colors[0], colors[1], colors[2], iterations, 20));
                      
                              });
                          },
                      
                          /**
                           * @param {Function} cb
                           * @returns {*}
                           */
                          switchAnimation: function (cb) {
                              if (!this.animationRunning) {
                                  return this.startAnimation(cb);
                              }
                      
                              this.stopAnimationRequest = true;
                      
                              if (this.animationRunning) {
                                  //console.log('animation was running, delaying new animation');
                      
                                  var self = this;
                                  setTimeout(function () {
                                      self.switchAnimation(cb);
                                  }, 100);
                              } else {
                                  this.startAnimation(cb);
                              }
                          },
                      
                          /**
                           *
                           * @param {Function} cb
                           * @returns {Function}
                           */
                          startAnimation: function (cb) {
                              //console.log('[PiLights] Starting animation..');
                              this.stopAnimationRequest = false;
                              this.animationRunning = true;
                              return cb();
                          },
                      
                          /**
                           *
                           */
                          stopAnimation: function () {
                              //console.log('[PiLights] Animation stopped.');
                              this.animationRunning = false;
                          },
                      
                          /**
                           *
                           */
                          update: function () {
                              //        if (this.leds) {
                              //            this.leds.update();
                              //        }
                          },
                      
                          /**
                           *
                           * @param {Integer} red
                           * @param {Integer} green
                           * @param {Integer} blue
                           * @param {Integer} [iterations]
                           * @param {Integer} [speed]
                           */
                          pulse: function (red, green, blue, iterations, speed) {
                              if (this.leds) {
                                  this.switchAnimation(() => {
                                      console.log('[PiLights] Pulse (' + red + ',' + green + ', ' + blue + ') Iterations: ' + iterations + ', Speed: ' + speed);
                                      this.flashEffect(red, green, blue, iterations, speed);
                                  });
                              }
                          },
                      
                          /**
                           *
                           * @param r
                           * @param g
                           * @param b
                           */
                          fillRGB: function (r, g, b) {
                              if (this.leds) {
                                  this.switchAnimation(() => {
                                      //console.log('[PiLights] Filling leds with', r, g, b);
                                      this.leds.fill(r, g, b);
                                      this.stopAnimation();
                                  });
                              }
                          },
                      
                          /**
                           *
                           */
                          off: function () {
                              if (this.leds) {
                                  //console.log('[PiLights] Setting Leds Off');
                                  this.leds.fill(0x00, 0x00, 0x00);
                                  this.stopAnimation();
                              }
                          },
                      
                          /**
                           *
                           * @param {Integer} r
                           * @param {Integer} g
                           * @param {Integer} b
                           * @param {Integer} [iterations]
                           * @param {Integer} [speed]
                           */
                          flashEffect: function (r, g, b, iterations, speed) {
                              var self = this;
                              var step = 0.05;
                              var total_iterations = 0;
                      
                              speed = speed || 10; // ms
                              iterations = iterations || 99999;
                      
                              var level = 0.00;
                              var dir = step;
                      
                              function performStep() {
                                  if (level <= 0.0) {
                                      level = 0.0;
                                      dir = step;
                                      total_iterations++;
                                  } else if (level >= 1.0) {
                                      level = 1.0;
                                      dir = -step;
                                  }
                      
                                  level += dir;
                      
                                  if (level < 0.0) {
                                      level = 0.0;
                                  } else if (level > 1.0) {
                                      level = 1.0;
                                  }
                      
                                  if (self.stopAnimationRequest || total_iterations > iterations) {
                                      self.stopAnimation();
                                      return;
                                  }
                      
                                  self.leds.fill(r * level, b * level, g * level);
                      
                      
                                  setTimeout(performStep, speed);
                              }
                      
                              if (this.leds) {
                                  performStep();
                              }
                          }
                      
                      });
                      
                      
                      1 Reply Last reply Reply Quote 1
                      • 1
                      • 2
                      • 1 / 2
                      • First post
                        Last post
                      Enjoying MagicMirror? Please consider a donation!
                      MagicMirror created by Michael Teeuw.
                      Forum managed by Sam, technical setup by Karsten.
                      This forum is using NodeBB as its core | Contributors
                      Contact | Privacy Policy