2017-01-08 47 views
5

我是nodejs的新手,我所做的是将LCD面板和4x4薄膜矩阵键盘连接到Raspberry Pi,并使用Node.js对它们进行编程。我想要实现的是每按一次按键,它应该立即显示在液晶显示屏上,当我按#时,它应该停止输入。异步功能在循环内不产生直接结果

为此,我已经使用的包LCD https://www.npmjs.com/package/lcd和RPIO https://github.com/jperkin/node-rpio,因为我必须为用户输入的连续检查我已经把代码同时输入,同时循环&里面我写了打印语句,这是在问题即将到来。当按下键盘上的按键时,LCD面板不显示任何字符,但当按#时,程序退出并且所有字符都显示在LCD面板上。

我写的代码如下。

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(); 
}); 

任何帮助将不胜感激。谢谢。

+0

我会建议打破你的代码小块,并专注于问题。 – niry

+0

你不能在JS中使用'while(true)'循环。这就是为什么你有事件得到关注按键为例。看看'rpio.poll()'。由于我不完全理解你的两个for循环是如何工作的,以及你在那里使用的'rpio.write()'和'rpio.read()',所以我不能重写你的代码 – Thomas

+0

我猜' col'和'row'包含某种位掩码!? – Thomas

回答

0

根据上面关于@Thomas的讨论,我建议你模拟while(true)循环与setImediate调用,其中您请求矩阵并执行LCD.print。这是因为LCD.print将操作添加到javascripts事件队列中。但事件队列的操作将被阻止,直到实际操作完成。只要您在while(true)循环中,它就永远不会完成。

因此,您必须结束活动操作并给予事件循环控制,然后执行打印命令。但同时,只要不按下“#”键,您就必须确保您再次扫描关键矩阵。

下面是一个例子:

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); 
    } 
    }); 
}); 

的代码没有进行测试,因为我这儿没raspi。它应该给你一个如何解决问题的想法。

一个非常酷的解决方案是将一个微控制器(MSP430,...)添加到关键矩阵中。 MC扫描矩阵并通过SPI或I2C将按键传输到raspi。 ....好吧,好的,不要打我;-)