我想为arduino创建一个程序,以便能够添加和删除控制某些引脚的规则,无论何时我想要而不是硬编码。 例如,像这样的规则:
如果pin1 = HIGH且pin2 = LOW,则pin3 = HIGH
我想谈谈这个:
if(pin1 == HIGH && pin2 == LOW){
digitalWrite(pin3, HIGH);
}
假设我们通过命令行将规则作为字符串传递。 我怎么能把这个字符串转换成规则?这样的事情可能吗?
答案 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(复杂可编程逻辑器件)如何工作等效的软件实现。如果您阅读本文,您将了解如何在硬件中完成此操作:
PAL可以在一组输入和输出之间创建任意组合逻辑规则,即任何可以表达为AND的逻辑方程,OR和NOT的逻辑方程都可以编程。它通过“烧”一组保险丝来编程,这些保险丝将输入连接到逻辑门然后连接到输出。上传到这些设备的只是一组0和1。
您可以在软件中使用0和1的数组来实现这样的事情来表示保险丝。硬代码将在阵列上运行并计算输出。您需要开发使用正确的保险丝加载阵列的方法。
编程PAL的常用方法是使用VHDL语言。这种语言的编译器采用与您类似的表达式,并将其转换为PAL可以使用的AND,OR和NOT的集合。搜索将对这种语言进行无休止的讨论,例如:
您必须创建采用文本输入并确定保险丝的编译器。你将承担一些重要的任务:
特定于域的语言解析器(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];
}
然后,您可以添加要从序列中读取的内容,并在运行中将新值加载到表中。