1

Using the python script below I can make my motor run:

import RPi.GPIO as GPIO
from time import sleep

GPIO.setmode(GPIO.BOARD)

Motor1A = 16
Motor1B = 18
Motor1E = 22

GPIO.setup(Motor1A,GPIO.OUT)
GPIO.setup(Motor1B,GPIO.OUT)
GPIO.setup(Motor1E,GPIO.OUT)

print "Turning motor on"
GPIO.output(Motor1A,GPIO.HIGH)
GPIO.output(Motor1B,GPIO.LOW)
GPIO.output(Motor1E,GPIO.HIGH)

sleep(2)

print "Stopping motor"
GPIO.output(Motor1E,GPIO.LOW)

GPIO.cleanup()

I would like to start and stop the engine from my nodejs server. I have already tried to run python scripts from nodejs, but this gave permission problems and it is not ideal to use multiple languages for just a few commands.

For these reasons I want to use https://www.npmjs.com/package/rpi-gpio

This is my first attempt to convert the code to nodejs. I get the error "Error: Pin has not been exported for write"

var gpio = require('rpi-gpio');

var Motor1A = 16;
var Motor1B = 18;
var Motor1E = 22;

gpio.setup(Motor1A, gpio.DIR_OUT);
gpio.setup(Motor1B, gpio.DIR_OUT);
gpio.setup(Motor1E, gpio.DIR_OUT);

gpio.write(Motor1A, gpio.HIGH, function(err) {
    if (err) throw err;
    console.log('Written to pin Motor1A');
});

gpio.write(Motor1B, gpio.LOW, function(err) {
    if (err) throw err;
    console.log('Written to pin Motor1B');
});

gpio.write(Motor1E, gpio.HIGH, function(err) {
    if (err) throw err;
    console.log('Written to pin Motor1E');
});

setTimeout(stopMotor_1, 2000);

function stopMotor_1() {
    gpio.write(Motor1E, gpio.LOW, function(err) {
        if (err) throw err;
        console.log('Stopped');
    });
}

second attempt:

gpio.setup(Motor1A, gpio.DIR_OUT, writeMotor1A);
gpio.setup(Motor1B, gpio.DIR_OUT, writeMotor1B);
gpio.setup(Motor1E, gpio.DIR_OUT, writeMotor1E);

function writeMotor1A(){
  gpio.write(Motor1A, gpio.HIGH, function(err) {
  if (err) throw err;
    console.log('Written to pin Motor1A');
  });
}
function writeMotor1B(){
  gpio.write(Motor1B, gpio.LOW, function(err) {
  if (err) throw err;
    console.log('Written to pin Motor1B');
  });
}
function writeMotor1E(){
  gpio.write(Motor1E, gpio.HIGH, function(err) {
  if (err) throw err;
    console.log('Written to pin Motor1C');
  });
}

results in the same error 'Error: Pin has not been exported for write'

Interestingly, when I do 'gpio-admin export 16' I get the following error:

gpio-admin: could not flush data to /sys/class/gpio/export: Device or resource busy

The same command for pin 18 and 22 does not return any messages.

Can anyone help me convert the above script to a nodejs / rpi-gpio script? I have no experience doing this in nodejs and I can't find any good examples.

2 Answers 2

1

Due to the asynch nature of nodejs, you will want to do your writes from a callback of the setup functions. I think it is trying to write before the setup is completed. A nice example can be found in the module's documentation here.

Change:

gpio.setup(Motor1A, gpio.DIR_OUT);
gpio.write(Motor1A, gpio.HIGH, function(err) {
if (err) throw err;
  console.log('Written to pin Motor1A');
});

To:

gpio.setup(Motor1A, gpio.DIR_OUT, writeMotor1A);
function writeMotor1A(){
  gpio.write(Motor1A, gpio.HIGH, function(err) {
  if (err) throw err;
    console.log('Written to pin Motor1A');
  });
}

This will ensure that the write does not happen until setup completes and executes the callback function.

Also note that the asynchronous behavior will cause all 3 gpio to go high at "essentially the same time". If you need them to be one-after-the-other, you will need to chain them together such that completion of writeMotor1A() executes a call that runs setup for Motor1B which has a callback to writeMotor1B().

1
  • thanks pierce. I still get the same error. The python script works instantly, so there must be something missing here.. anything else I could have done wrong? Note the python line 'GPIO.setmode(GPIO.BOARD)' - could it be it is looking at a non-existing gpio set? btw I am not running nodejs as root, I do however use github.com/quick2wire/quick2wire-gpio-admin Dec 4, 2015 at 22:55
1

I have gotten it to work myself. There were two problems in my case.

  1. Permission problem: my gpio-admin setup didn't work properly, so nodejs did not have the required permissions to open up the pins. Running node as sudo solved this problem.
  2. Incorrect code. I was using the values gpio.HIGH and gpio.LOW, these are incorrect. The correct values are simply 'true' or 'false'.

The code below works, which turns on the motor:

var gpio = require('rpi-gpio');

var Motor1A = 16;
var Motor1B = 18;
var Motor1E = 22;

gpio.setup(Motor1A, gpio.DIR_OUT);
gpio.setup(Motor1B, gpio.DIR_OUT);
gpio.setup(Motor1E, gpio.DIR_OUT);

function forward_engine_1() {
    gpio.write(Motor1A, true, function(err) {
        if (err) throw err;
    });

    gpio.write(Motor1B, false, function(err) {
        if (err) throw err;
    });

    gpio.write(Motor1E, true, function(err) {
        if (err) throw err;
    });
}
1
  • I had a similar problem to 1. Running node as sudo fixed my issue (for now, till I can work out what's went wrong with gpio-admin.) Thanks a bunch! Mar 11, 2016 at 23:08

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.