I am new to Node-Red and am trying out a project with the EmotivBCI toolbox. I am trying to get a servo running using the Arduino nodes (running Firmata). The EmotivBCI node that I am using basically returns a value between 0-100. Basically, I want the servo position stored in a variable that is initialized when I deploy the flow as 'pos=0'. I then use an if condition to increase the value of 'pos' by 1 as long as the BCI node returns a value greater than 50.
My problem is, I don't know how to initialize and store the value of the variable (for the duration of the deployment) and call it inside a function node. I noticed that the context variable does something similar, but I was not able to figure it out.
Thanks, Steve. I tried this, but as you said, it crashed because of the while loop. Also, I'm not sure if I'm using the context variables right. Could you take a look?
And do you have any suggestions on how I might go about getting my function to work?
The important one is the third one that says 'push'. I have a slider on another app called EmotivBCI where I control the output of the Mental Commands: push node and it returns a value between 0-100.
What I want to do is control a servo motor's motion based on the slider. Basically, if the push node returns anything between 50 and 100, the pos should increment by 1 every time the node returns a value greater than 50. If I keep the slider below 50, then the function should do nothing. The pos needs to be returned to the Arduino pin which is connected to NodeRed via Firmata (I've used the debug here to see my output rather than the Arduino pin for now).
Also, I see what you mean about the while loop, and I get why it's not advisable to use it, but in this case, I can't think of an alternative. Do you think I could call msg.payload inside the while loop to check 'a' has dipped below 50 so it can safely exit the loop ?
Does the Push node send you regular updates? If so then why do you need a loop? Can't you just look at the value sent by the push node and send on the appropriate value each time?
var pos = context.get("pos") || 0; //get pos from context
var sendIt = false; //default to NOT sending msg on to next node
var pushValue = msg.payload;
if(pushValue > 50 && pushValue < 100) {
pos++;
sendIt = true;
}
context.set("pos", pos);//store pos
//check and send to next node (or not)
if(sendIt) {
msg.payload = pos;
return msg;
}
Many thanks! It worked out. And I also understood how to set up the context variables now.
One question, am I correct in saying that the context variable will only save state inside a function, while a flow variable will save state inside the entire flow?
the (node) context is just within the node.... the flow context is available across any nodes in that editor tab, and global context is available across all tabs (the overall flow file)
It works both ways since I'm running a simulation at the moment, but the value never really goes up to 100 in real-time. But yes, to be accurate, the = sign should be there. However, my struggle was with initializing and using the context variables, which has thankfully been resolved.
I basically duplicated the first set of nodes and changed the script inside to count down rather than up and of course there's another input signal to trigger this. Changed the context variable to a flow variable to communicate the same value of pos between the nodes.
Here's my set-up and the code for the reverse POS.
My final goal is to be running a 6 jointed robotic arm using NodeRed as the go-between(EmotivBCI to Arduino). So right now, I'm basically thinking of duplicating this flow 6 times for the 6 different servos on the motor. I'm not sure if that's the most efficient way to do it.
I'm a total newbie to this, so any comments for improvements, or suggestions would be most helpful.