2

Using Node.js, express and cylon.js, I'm getting a post request and blinking an LED using a raspberry Pi. I receive the first post request fine, the code runs and the LED blinks. However on the second post request I receive an error:

events.js:146
      throw err;
      ^

Error: Uncaught, unspecified "error" event. (Error occurred while writing value 1 to pin 23)
    at DigitalPin.emit (events.js:144:17)
    at DigitalPin.<anonymous> (/home/pi/tech-corner/devTracker/node_modules/cylon/lib/io/digital-pin.js:70:12)
    at fs.js:1134:21
    at FSReqWrap.oncomplete (fs.js:82:15)

Note that in the code below I'm using pin: 16. So I'm confused as to why it's trying to write to pin 23.

var express = require('express')
var bodyParser = require('body-parser')
var app = express()
var Cylon = require('cylon')

var pi = Cylon.robot({
  connections: {
    raspi: { adaptor: 'raspi' }
  },

  devices: {
    led: { driver: 'led', pin: 16 }
  },

  work: function (my) {
    after((1).second(), function () {
      console.log('Post request recieved! Toggle the LED')
      my.led.toggle()
    })

    after((2).second(), function () {
      my.led.toggle()
    })

    after((5).seconds(), function () {
      console.log('I\'m shutting down now.')
      pi.halt()
    })
  }
})

app.set('port', process.env.PORT || 1337 - 1)

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

app.post('/', function (req, res) {
  console.log(req.body.user_name)

  pi.start()

  res.end('Hello')
})

app.listen(app.get('port'), function () {
  console.log('Node app is running at http://localhost:' + app.get('port'))
})

Any help greatly appreciated. I assume my raspberryPi set-up is fine since it works on the first hook.

EDIT: Incase anyone comes across this and has a similar problem. I decided to go with pigpio which was a lot easier.

4
  • Pin 16 on the expansion header is GPIO23. Perhaps your software isn't using the GPIO numbering scheme you thought you were using?
    – joan
    Jun 10, 2016 at 15:17
  • Ah so that explains the Pin 23, however it works the "first" time round. Although I did notice I was getting an error on when I run npm start for the first time - Setting up pin direction failed. However once I try the second time it seems to work fine.
    – kot
    Jun 10, 2016 at 15:35
  • Is "npm start" the proper call to start a javascript project? Shouldn't it be "node filename.js" (with filename replaced by the actual name of the file)? I'm familar with gobot (a sister project).
    – NomadMaker
    Jul 31, 2018 at 20:25
  • npm start reads the package.json and runs the start command which would be node index.js
    – kot
    Aug 2, 2018 at 13:23

1 Answer 1

0

I heard of Cylon for the first time here by your Question. So you can estimate the quality of my answer. ;-)

It could be that, after the call of the .halt() method the system will be reinitialized and is not ready to start again without reconfiguration as you try in the POST request. The following Code might work if I'm right ;-).

var express = require('express')
var bodyParser = require('body-parser')
var app = express()
var Cylon = require('cylon')

var piCnf = {
  connections: {
    raspi: { adaptor: 'raspi' }
  },

  devices: {
    led: { driver: 'led', pin: 16 }
  },

  work: function (my) {
    after((1).second(), function () {
      console.log('Post request recieved! Toggle the LED')
      my.led.toggle()
    })

    after((2).second(), function () {
      my.led.toggle()
    })

    after((5).seconds(), function () {
      console.log('I\'m shutting down now.')
      my.halt()
    })
  }
};

app.set('port', process.env.PORT || 1337 - 1)

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

app.post('/', function (req, res) {
  console.log(req.body.user_name)

  var pi = Cylon.robot(piCnf);
  pi.start()

  res.end('Hello')
})

app.listen(app.get('port'), function () {
  console.log('Node app is running at http://localhost:' + app.get('port'))
})

I have read some examples now (it's an interesting framework) and a few documentation pages and as far as I can see Cylon is a standalone system with its own connection adapters for rest calls (APIs) and so on. So I see no need for using express in parallel.

But it is easy to use Cylon without express in a similar fashion like this. I've modified the code of an example from the original Cylon page. (https://cylonjs.com/documentation/guides/working-with-robots/)

var flagBlinkOn = false;

Cylon.robot({
  name: "testbot",
  connections: {
    "loopback": { adaptor: "loopback" }
  },


  devices: {
   led: { driver: 'led', pin: 16 }
  },

  work: function() {
     every((1).seconds(), function() {
      my.led.toggle()
     });
  },

  switchOn: function(my) {
    flagBlinkOn = true;
  },

  switchOff: function(my) {
    flagBlinkOn = false;
  }
});

// GET /api/robots/testbot/commands
// => ['switchOff', 'switchOn']
// GET /api/robots/testbot/switchOff 
// -> switch off blinking
// GET /api/robots/testbot/switchOn
// -> switch on blinking

Of cause: this configures a GET request and I do not know if POST is possible. I'm also not sure how to change the ip adress and the port. But there is a configuration object and surely some more connection types and devices. And sorry, I did not tested this Code.

Perhaps there is someone who could give you a complete answer. But until then I'll hope I could help you a little bit.

5
  • Thanks for this Peter! I seem to be getting the same error I get on the first run of npm start - Error: Uncaught, unspecified "error" event. (Setting up pin direction failed). Maybe this is the raspberry pi trying to initialize the set-up with the pins and failing because I've already used them previously? I'm not sure. Maybe a dumb question but maybe I can do the get request functions from within the post function?
    – kot
    Jun 10, 2016 at 16:22
  • @kot Aaah! Sorry, I have made a terrible mistake. I use the pi variable in a function where it is not defined at all. I've edited my answer. Jun 10, 2016 at 16:28
  • I noticed this and tried a few different things! even halting Cylon - Cylon.halt, my.halt(), my.led.halt(). It must be something with running the same pin after stopping the service! Thanks very much though Peter! This might be a tough one! (although it seems super simple haha)
    – kot
    Jun 10, 2016 at 16:38
  • @kot my solution spawns new Cylon objects on each post call. There might be some issues with that. If the old Object still uses the "led" driver the new object can probably not access it. I don't know anything about the halt method. Perhaps it destroys connection or low level hardware access. And so on. How about using Cylon without express and the need for restarting the Cylon instances? Jun 10, 2016 at 16:39
  • As soon as I'll arrive at home this evening I unpack my old raspi and start trying it. I can't help. ;-) Perhaps I find a way. Then I promise to report it here ;-) Jun 10, 2016 at 16:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.