5
\$\begingroup\$

The following code is used to access a shield which converts settings written over I2C to Servo output.

I make use of the MRAA library since that's the default supported by my hardware.

To prevent my I2C commands from being written all at the same time, I use setTimeout to wait a given amount of time before executing the next.

For those unfamiliar with MRAA and I2C:

writeReg accepts two arguments. The first is the target register, the second is the data. As long as two different registers are being written, it's no problem if one is written earlier than the other. However, I want to make this code more generic so it can be used with something different than Servos as well. A generic solution should give me the possibility to burst multiple parts of data to the same address and keep the order intact.

Save to say my current structure is not easily expandable. How should I make it more expandable the Node.JS way? Expandability is more important than performance, but since I'm looking for an idiomatic solution this shouldn't be relevant.

Also note the data written seems redundant, but there are out-of-scope reasons for this.

var m = require('mraa'); // I/O library

Servo = new m.I2c(0)
Servo.address(0x74)

timer();

function timer() {
  firstI2C();
  setTimeout(timer, 5000)
}

function firstI2C() {
  Servo.writeReg(1, 250);
  Servo.writeReg(2, 128+16+0x0);
  Servo.writeReg(37, 0);
  console.log("1");
  setTimeout(secondI2C, 1000)
}

function secondI2C() {
  Servo.writeReg(1, 5);
  Servo.writeReg(2, 128+16+0x0);
  Servo.writeReg(37, 0);
  console.log("2");
  setTimeout(thirdI2C, 1000)
}

function thirdI2C() {
  Servo.writeReg(1, 250);
  Servo.writeReg(2, 128+16+2);
  Servo.writeReg(37, 0);
  console.log("3");
  setTimeout(fourthI2C, 1000)
}

function fourthI2C() {
  Servo.writeReg(1, 5);
  Servo.writeReg(2, 128+16+2);
  Servo.writeReg(37, 0);
  console.log("4");
}

I've been thinking about a function which would accept data in JSON and maps it to such functions and which keeps execution order by the position in the JSON (list). However, such a function is way beyond my current skill level.

\$\endgroup\$
4
\$\begingroup\$

A very simple solution is to use a Map that (as its name implies) maps a string to a function so that you can pass an array of sorted strings and ask for the application to get each function and run it in the specified order.

Something like this:

var myFuncs={ 'firstI2C':firstI2C,
              'secondI2C':secondI2C,
              //so on
}

Then you can have a function that tells the program to run next function. For example:

var nextMethodIndex=0;

var methodOrder=['firstI2C','secondI2C','thirdI2C',....] // this array can be fed as JSON.

function runNextMethod()
{
    if(nextMethodIndex<methodOrder.length)
    {
         var func= myFuncs[methodOrder[nextMethodIndex]];
         nextMethodIndex++;
         setTimeout(func, 1000)
    }

}

Finally you should modify your functions to call runNextMethod when they finish their job.

function timer() {
  runNextMethod();
  setTimeout(timer, 5000)
}

function firstI2C() {
  Servo.writeReg(1, 250);
  Servo.writeReg(2, 128+16+0x0);
  Servo.writeReg(37, 0);
  console.log("1");
  runNextMethod();
}
|improve this answer|||||
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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