ruby/RoR 一直从串行端口和接口读取

逃跑

我正在尝试使用 RoR 设置一个 Web 应用程序,以便能够使用 Web 界面控制我的 Arduino。可能我的方法是这里出了什么问题,因为我很难在发送命令时阅读 arduino 在串口上所说的内容。我的主要和未来目标是将串行端口列出(流式传输)到我的 Web 界面,并在服务器端做出反应,如果在串行端口上给出了某些特定命令。

我已经尝试过什么?我虽然使用线程会是一个好主意,但我有一些问题。首先,我尝试了最简单的方法,即创建一个新的 Thred 并使用 .join。由于 serial.gets 有一段时间是正确的,无法摆脱它,我的服务器永远挂在那里。

即使最后不是我想要的东西,我也尝试通过运行 10 次来限制我的真正出路(如代码所示)。

我的 arduino 代码(有效):

char receivedChar;
boolean newData = false;

void setup() {
 Serial.begin(9600);
 pinMode(LED_BUILTIN, OUTPUT);
 Serial.println("<Arduino is ready>");
}

void loop() {
 recvOneChar();
}

void recvOneChar() {
 if (Serial.available() > 0) {
  receivedChar = Serial.read();
  if (receivedChar == '1') {
   digitalWrite(LED_BUILTIN, HIGH);
   Serial.println("LED IS ON");
  }else if (receivedChar == '2' ){
   digitalWrite(LED_BUILTIN, LOW);
   Serial.println("LED IS OFF");
  }
 }
}

RoR 上的控制器:

def blink_led
  puts "blink_led action called"
  t1 = Thread.new do
    Setting.blink_led
  end
  Setting.read_board
  t1.join
end

RoR 模型:

@port_str = "/dev/tty.usbmodem14201"
@baud_rate = 9600
@data_bits = 8
@stop_bits = 1
@parity = SerialPort::NONE


def self.read_board
    puts "INSIDE READ METHOD"
    sp = SerialPort.new(@port_str, @baud_rate, @data_bits, @stop_bits, @parity)

    i = 0
    while i < 10 do
      message = sp.gets
      if message
        message.chomp!

        puts message
      end
      i += 1
    end
end

def self.blink_led
    puts "INSIDE BLINK METHOD"
    sp = SerialPort.new(@port_str, @baud_rate, @data_bits, @stop_bits, @parity)

    #just read forever
    i = 0
    while i < 5
        sp.write('1');
        sleep(1)
        sp.write('2');
        sleep(1)
        i += 1
    end

    sp.close
end

凭借我的天真经验,我希望在我使用按钮调用控制器方法时完美获得,看到 LED 闪烁(它闪烁),同时在我的服务器上看到 PUTS 说 LED 亮起/熄灭。(期待一切运行完美)好吧,这并没有发生,我得到了一些奇怪的结果:

在我的服务器上添加 i 计数器之前,我的服务器运行了 1 次正常(我第一次按下按钮),之后就很奇怪了。首轮:

blink_led action called
INSIDE READ METHOD
INSIDE BLINK METHOD
Completed 200 OK in 6015ms (ActiveRecord: 0.0ms)

IS D ISIS OLS ONLED IS OFF
LED IS ON
LED IS OFF
LED IS ON
LED IS OFF

它只是挂在那里。

现在有了 while 循环上的 get 计数器,它真的没有做我想要的,我希望它一直运行(万一发生了什么)我还从另一个来源(一个小红宝石)向串行发送数据脚本)并希望我的服务器能够检查/响应它。

blink_led action called
INSIDE READ METHOD
INSIDE BLINK METHOD
LED IS LED IS OFF
Completed 200 OK in 6013ms (ActiveRecord: 0.0ms)

LED IS ON
LED IS OFF
LED IS ON
LED IS OFF
LED IS ON
LED IS OFF
LED IS ON
LED IS OFF

消息至少显示正确,但我的服务器仍然挂起。

我在这里的做法是错的吗?实现我想要实现的目标的最佳方法是什么?最后,我希望我的服务器能够一直运行串行读取命令,同时对从串行端口读取的内容做出反应并对接口上的输入做出反应,就像按下按钮一样。完成此操作后,我希望能够将我的串行端口“流式传输”(不知道这是否正确)到接口。

EDIT1:更正了一些拼写错误,并学会了如何在每次挂起时杀死服务器进程

Edit2:让我的问题清楚。我希望建立一种 2 路通信,1 路从接口/服务器到 arduino,从 arduino 到我的服务器。我正在寻找构建一些可以向 arduino 发送命令并从中读取答案的东西。到目前为止,我有一个动作/方法将命令发送到 arduino,发送“1”或“2”,arduino“LED 亮起”“LED 熄灭”相应地响应。但这(到目前为止)只有当我的服务器知道它会得到答案时才可行。

我有一个小的 ruby​​ 脚本,它发送相同的命令来打开和关闭 LED,我缺少的是我的服务器能够注意到串行端口上写了一些东西(在这种情况下,来自 arduino 的响应说“当此事件是从另一个源触发时,LED 亮起"/"LED 熄灭")。

最大取胜者

您可以将该read_board方法更改为永无止境的后台线程。它可以在收到消息时调用其他一些方法,并使用 websockets / action cable 更新前端。

  # app/models/setting.rb

  def self.read_board
    sp = SerialPort.new(@port_str, @baud_rate, @data_bits, @stop_bits, @parity)
    Thread.new do

      loop do
        message = sp.gets # This will probably wait for input
        if message
          message.chomp!
          message_received(message)
        end
      end

    end
  end

  def self.message_received(message)
    # Alert clients of message using websockets / actioncable.
  end

从某处调用此方法(只需调用一次)

# config/initializers/read_board.rb

Setting.read_board

你需要填写message_received方法。如果您不想弄乱动作电缆/ websockets,您可以创建一个存储新消息的数组,并从从列表中弹出的前端发送一个循环查询。但是,使用 websockets 是更好的选择。不幸的是,在这个答案中解释设置有点太复杂了,但是如果你四处搜索,你会发现很好的教程。

我会说尝试为 websockets / actioncable 制作一个演示项目(只是一个简单的聊天室,有大量的教程),然后尝试调整 arduino 项目的代码

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章