BoneScript Newbie Question

Hi,

I’m trying to understand variable scope in BoneScript. I have a global variable that I’d like to use to communicate between a web server response function and the loop function. Nothing that the server response function does to the global variables seems to show up in the loop function. So I’m guessing that they are not really the same variables. In the code below the web responder is setting an entry in the ring_states array. Loop is looking for that change of state in order to set some outputs. However, loop never sees the HIGH.

I there a way that I can define a variable such that both the web responder and the loop function refer to the same variable?

They run in different contexts, so the answer is essentially, no. You are better off using JavaScript timers within your setup function to put things within the same scope. I’ll try to come back later with some more hints looking at your code below.

I’ve modified the code below to something approximating what you’d want to do.

require(‘bonescript’);
fs = require(‘fs’);
child_process = require(‘child_process’);
http = require(‘http’);
url = require(‘url’);
path = require(‘path’);
events = require(‘events’);

server = false;
reset_pin = bone.P8_4;
or_pin = bone.P8_5;
pin_count = 4;
indicator_pins = new Array(bone.USR1, bone.USR2, bone.USR3, bone.P8_3);
ring_states = new Array(LOW, LOW, LOW, LOW);
ring_uris = new Array(’/1’, ‘/2’, ‘/3’, ‘/4’);

HIGH = 1;
LOW = 0;
INPUT = “in”;
OUTPUT = “out”;

setup = function() {
pinMode(reset_pin, INPUT);
pinMode(or_pin, OUTPUT);
var idx;
for(idx = 0; idx < pin_count; idx++)
{
pinMode(indicator_pins[idx], OUTPUT);
}

digitalWrite(indicator_pins[1], HIGH);
ring_states[1] = HIGH;

server = http.createServer(
function(req, res) {
var uri = url.parse(req.url).pathname;
console.log("Got URI: " + uri);
var idx;
for (idx = 0; idx < pin_count; idx++)
{
if (uri == ring_uris[idx])
{
ring_states[idx] = HIGH;
console.log("matched uri at index " + idx);
break;
}
}

res.writeHead(200, {“Content-Type”: “text/html”})
res.end();
}
);

server.listen(5400);

var myloop = function() {
var idx;
var or_pin_state = LOW;
for(idx = 0; idx < pin_count; idx++)
{
digitalWrite(indicator_pins[idx], ring_states[idx]);
if (ring_states[idx] == HIGH)
{
or_pin_state = HIGH;
console.log(“ring_states[” + idx + "] = " + ring_states[idx]);
}
}
digitalWrite(or_pin, or_pin_state);

if (digitalRead(reset_pin)) // Likely better to use attachInterrupt here
{
for(idx = 0; idx < pin_count; idx++)
{
ring_states[idx] = LOW;
}
}
};

setTimeout(myloop, 1000);
};

Thanks for the suggestion! I actually made it work using a different mechanism.

Once I saw your message about there being no way to connect the variables in loop with those in the web responder it broke me out of the mode of thinking I must be doing something really dumb and got me looking for another solution. I looked up the timer you mentioned but while doing my scratching about I discovered I at least got a copy of all the variables in the web responder and that it was possible to update the hardware. The hardware itself is certainly shared. So I split the hardware handling between the loop and the web responder and just skipped the ring_states array I had been trying to share. The web responder turns my outputs on in response to the urls and the loop turns them off in response to the reset input.

Since I am on a train and didn’t have a jumper handy, I found I was able to make a sort of cheat toggle that worked to send a binary message from the web responder to the loop using the hardware. I changed the pullup status of the reset_pin loop was watching to emulate a button push and got loop to reset the outputs in response to some debugging urls.

Seems to work OK.

Thanks again for your help, suggestion, and for your work on BoneScript!

This is what I wound up with: (I’ll be changing the LED outputs to normal outputs that will connect to a relay driver)

require(‘bonescript’);

fs = require(‘fs’);
child_process = require(‘child_process’);
http = require(‘http’);
url = require(‘url’);
path = require(‘path’);
events = require(‘events’);

server = false;
reset_pin = bone.P8_4;
or_pin = bone.P8_5;
pin_count = 4;
indicator_pins = new Array(bone.USR1, bone.USR2, bone.USR3, bone.P8_3);
ring_uris = new Array(’/1’, ‘/2’, ‘/3’, ‘/4’);

setup = function() {
pinMode(reset_pin, INPUT);
pinMode(or_pin, OUTPUT);
var idx;
for(idx = 0; idx < pin_count; idx++)
{
pinMode(indicator_pins[idx], OUTPUT);
}

server = http.createServer(
function(req, res) {
var uri = url.parse(req.url).pathname;
console.log("Got URI: " + uri);
var idx;
for (idx = 0; idx < pin_count; idx++)
{
if (uri == ring_uris[idx])
{
digitalWrite(indicator_pins[idx], HIGH);
digitalWrite(or_pin, HIGH);
console.log("matched uri at index " + idx);
break;
}
}

//up and down are for testing only. remove before deployment
if (uri == ‘/up’)
{
pinMode(reset_pin, INPUT_PULLUP);
}

if (uri == ‘/down’)
{
pinMode(reset_pin, INPUT);
}

res.writeHead(200, {“Content-Type”: “text/html”});
res.end();
}
);

server.listen(5400);
};

loop = function() {
var idx;
if (digitalRead(reset_pin))
{
for(idx = 0; idx < pin_count; idx++)
{
digitalWrite(indicator_pins[idx], LOW);
}
digitalWrite(or_pin, LOW);
}
};