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
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().
-
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-adminMaarten Hartman– Maarten Hartman2015年12月04日 22:55:51 +00:00Commented Dec 4, 2015 at 22:55
I have gotten it to work myself. There were two problems in my case.
- 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.
- 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;
});
}
-
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!Davie Brown– Davie Brown2016年03月11日 23:08:56 +00:00Commented Mar 11, 2016 at 23:08