Arduino - 创建动态规则

时间:2013-06-07 19:03:58

标签: arduino

我想为arduino创建一个程序,以便能够添加和删除控制某些引脚的规则,无论何时我想要而不是硬编码。 例如,像这样的规则:

  

如果pin1 = HIGH且pin2 = LOW,则pin3 = HIGH

我想谈谈这个:

if(pin1 == HIGH && pin2 == LOW){
   digitalWrite(pin3, HIGH);
}

假设我们通过命令行将规则作为字符串传递。 我怎么能把这个字符串转换成规则?这样的事情可能吗?

3 个答案:

答案 0 :(得分:1)

你的第二段代码:

if(pin1 == HIGH && pin2 == LOW){
   digitalWrite(pin3, HIGH);
}

由IDE编译为机器代码。然后将该机器代码上传到Arduino然后执行。

因此你不能像这样发送一些字符串

if pin1=HIGH and pin2=LOW then pin3=HIGH

到Arduino因为在你的程序转换成所需的形式后,Arduino方面缺少完整的IDE和编译器。一个C ++编译器工具链很大 - 几十兆字节! Arduino上没有这个地方。

可以做什么:为您的规则创建一个简单语言,并为那些在Arduino上运行的语言开发一个解释器。

也许你也不需要重新发明轮子 - 谷歌用于在AVR CPU上运行的简单BASIC解释器并适应其中一个。

答案 1 :(得分:1)

您要求的是可能,但您需要做很多工作。


方法1(想大):

您正在寻找的是与PAL(可编程阵列逻辑)和CPLD(复杂可编程逻辑器件)如何工作等效的软件实现。如果您阅读本文,您将了解如何在硬件中完成此操作:

Wikipedia article on PLD's

PAL可以在一组输入和输出之间创建任意组合逻辑规则,即任何可以表达为AND的逻辑方程,OR和NOT的逻辑方程都可以编程。它通过“烧”一组保险丝来编程,这些保险丝将输入连接到逻辑门然后连接到输出。上传到这些设备的只是一组0和1。

您可以在软件中使用0和1的数组来实现这样的事情来表示保险丝。硬代码将在阵列上运行并计算输出。您需要开发使用正确的保险丝加载阵列的方法。

编程PAL的常用方法是使用VHDL语言。这种语言的编译器采用与您类似的表达式,并将其转换为PAL可以使用的AND,OR和NOT的集合。搜索将对这种语言进行无休止的讨论,例如:

A VHDL tutorial

您必须创建采用文本输入并确定保险丝的编译器。你将承担一些重要的任务:

  • 特定于域的语言解析器(I can recommend ANTLR),

  • PAL编译器(我不建议任何人自己这样做)和

  • 用于模拟PAL的Arduino代码。

当你创建自己的等效VHDL和PAL时,你可能会认为你可以把PAL芯片放在原型板上并完成。


方法2(更实用):

实现相同结果的更简单方法是真值表。真值表相当于某些逻辑表达式。要实现真值表,请将逻辑表达式转换为每个输入大小写一行的表。以下是驱动输出的两个输入的真值表的示例:

IN1  IN2  OUT
0    0    1
0    1    0
1    0    1
1    1    1

这种真值表实现的代码如下所示:

const int IN1 = 6;
const int IN2 = 7;
const int OUTA = 13;

byte table[4] = {1, 0, 1, 1};

void loop() {
  int in1;
  int in2;
  byte outbit;
  size_t ix;
  //
 in1 = digitalRead(IN1);
 in2 = digitalRead(IN2);
 ix = in2 * 2 + in1;
 outbit = table[ix];
 digitalWrite(OUTA, outbit);
}

逻辑规则的完整表达式是4个字节的数组。要“编程”一个新的输出方程式,您只需发送一组新的4个值,对于您发送“0 0 1 0”的特定方程式。您的程序将收到值列表并将它们存储在表数组中。一旦存储了新的值/规则,输出的功能就会改变。

只要您有足够的RAM来存储表,这种类型的可编程逻辑就是可行的。对于4个输入,您只需要16个值,对于5个,您只需要32个。


您的问题在电子设计中引起了强烈关注:您需要为正确的问题选择合适的设备。代码并不总是更好或更容易。避免锤钉式陷阱(当你的唯一工具是锤子时,每个问题看起来像钉子)。 PAL / CPLD和微控制器是一个强大的组合。

答案 2 :(得分:0)

要添加@ jdr5ca提到的真值表方法,理解arduino中使用的控制器以及使用ardiuno库是个好主意。

引脚0到7是端口D,引脚8到15端口B.每个端口表示为三个单字节寄存器 - PORT_是输出/偏置电阻,PIN_是输入状态,DDR_是方向。当您调用digitalRead(pin)时,代码会看到引脚位于哪个范围内,为该端口读取PIN_,然后进行位移并屏蔽该值以仅提供该引脚的状态。这对于一次读取一个引脚很方便,但是比你读几个引脚更方便。

因此,如果您创建一个包含256个条目的真值表,您可以使用一条线从输入0到7的值写入引脚8到15的输出,而不是将寄存器解码为引脚,然后再次对它们进行编码: / p>

byte table[256] = {0};

void loop() {
   PORTB = table[PIND];
}

然后,您可以添加要从序列中读取的内容,并在运行中将新值加载到表中。