Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous function not producing immediate result inside while loop

I am new to nodejs and what I have done is I have connected LCD Panel and 4x4 Membrane matrix keypad to Raspberry Pi and I have programmed them using Node.js. What I want to achieve is whenever a key is pressed it should be displayed immediately on the LCD panel and when I press # it should stop taking input.

For this I have used packages LCD https://www.npmjs.com/package/lcd and RPIO https://github.com/jperkin/node-rpio and since I have to continuously check for user input I have put the code for taking input in while loop & inside that I have written the print statement and that is where the problem is coming. LCD panel doesn't display any character when I press a key on keypad but when I press #, the program exits and all the characters are displayed on the LCD panel.

The code that I have written is as follows.

var rpio = require('rpio');
var Lcd = require('lcd'),//This is asynchronous function
    lcd = new Lcd({
        rs: 18,
        e: 23,
        data: [24, 17, 27, 22],
        cols: 8,
        rows: 2
    });
var matrix=[[1,2,3,'A'],
            [4,5,6,'B'],
            [7,8,9,'C'],
            ['*',0,'#','D']]
var row=[37,35,33,31];
var col=[29,23,40,38];
for (var i = 0; i < 4; i++) {
    rpio.open(col[i], rpio.OUTPUT, rpio.HIGH);
}
for (var i = 0; i < 4; i++) {
    rpio.open(row[i], rpio.INPUT, rpio.PULL_UP);
}
var code="";
var comeout=0;
lcd.on('ready', function() {
    lcd.setCursor(0, 0);
    //start of keypad code
    while(true){
        for (var j = 0; j < 4; j++) {
            rpio.write(col[j],rpio.LOW);
            for (var i = 0; i < 4; i++) {
                if(rpio.read(row[i])==0){
                    console.log(matrix[i][j]);
                    lcd.print(matrix[i][j]);
                    if(matrix[i][j]=='#'){
                        comeout=1;
                        break;
                    }
                    while(rpio.read(row[i])==0);
                }
            }
            if(comeout==1)
                break;
            else
                rpio.write(col[j],rpio.HIGH);
        }
        if(comeout==1)
            break;
    }
    //end of keypad code
});

// If ctrl+c is hit, free resources and exit.
process.on('SIGINT', function() {
    lcd.clear();
    lcd.close();
    process.exit();
});

Any help would be much appreciated. Thank you.

like image 922
Vikas Yadav Avatar asked Jan 08 '17 05:01

Vikas Yadav


1 Answers

According to the discussion with @Thomas above, I would suggest you simulate the while(true) loop with setImediate calls in which you request the matrix and perform the LCD.print. This is because the LCD.print adds operations to javascripts event queue. But the operations of the event queue are blocked until the actual operation is completed. It would never complete as long as you are in the while(true) loop.

So you must end the active operation and give the event loop control, which in turn executes the print commands. But at the same time you must assure that you scan the key matrix again as long as you do not press the "#" key.

Here is an example:

lcd.on('ready', function() 
{
  lcd.setCursor(0, 0);
  setImediate(
  function scanMatrix()
  {
    for (var j = 0; j < 4; j++) 
    {
      rpio.write(col[j],rpio.LOW);
      for (var i = 0; i < 4; i++) 
      {
        if(rpio.read(row[i])==0)
        {
          console.log(matrix[i][j]);
          lcd.print(matrix[i][j]);
          if(matrix[i][j]!='#')
          {
            setImmediate(scanMatrix);
          }
          while(rpio.read(row[i])==0);
        }
      }
      rpio.write(col[j],rpio.HIGH);
    }
  });
});

The code is not tested because I have no raspi here. It should give you an Idea of how to solve the problem.

A really cool ;-) solution would be to add a microcontroller (MSP430, ...) to the key matrix. The MC scans the matrix and transfers keypresses to the raspi via SPI or I2C. .... OK, ok, ok don't beat me ;-)

like image 89
Peter Paul Kiefer Avatar answered Oct 01 '22 05:10

Peter Paul Kiefer