"Arduino"
"Arduino" 通过在开源的 Arduino Uno 微控制器面板上的数字和模拟引脚,提供了底层的、通用的输入和输出,这个面板串行连接到了 Wolfram 语言.
默认支持的面板是 Arduino Uno,它具有基本的 8 位微控制器芯片. 另外,也支持 Arduino Yun,它通过协处理器为芯片提供网络的功能,并允许与 Data Drop 交互.
Arduino Yun 允许通过 Wi-Fi 或以太网电缆连接互联网运行程序. 当使用面板的以太网连接,无需特别设置 Arduino,但是当使用无线 Wi-Fi 连接,面板需要设置到想连接的无线网络. 可以从 Arduino LLC 的网站找到此类信息.
所有 Wolfram 语言的 Arduino 功能在 Arduino Yun 和 Arduino Uno 面板上都可用;除非另有说明,否则所有功能都可用.
它可用于各种任务,着眼于与马达、传感器和其他设备等物理系统的交互.
它可用于在设备上的通用输入和输出 (GPIO) 以及执行 C/C++ 代码.
另外,该面板有 13 个数字输入和输出,带有 6 个可用于 脉宽调制 的引脚和 6 个可用于读取模拟电压和数字输入和输出的引脚.
在 Arduino 板上,以下引脚可用于读取和编写:2、3、4、5、6、7、8、9、10、11、12、13、"A0" (14)、"A1" (15)、"A2" (16)、"A3" (17)、"A4" (18)、"A5" (19).
Arduino 运行称作 sketch 的自定义程序,与 Wolfram 语言进行通讯. 该 sketch 必须在使用 DeviceRead、DeviceWrite 或 DeviceExecute 之前,用 DeviceConfigure 加载至 Arduino.
注意:默认情况下,"Arduino" 允许任何引脚交替使用读写模式. DeviceConfigure 可用于配置指定引脚的读或写.
打开设备
- 如果在机器上没有找到 Arduino IDE,会出现提示下载 1.6.7 版本并安装至 $UserBaseDirectory. 使用 Arduino 需要 Arduino IDE. 支持 Arduino IDE 的所有版本,可以使用设备属性 "ArduinoInstallLocation" 指定不同的位置.
- DeviceOpen 支持一个额外的选项 "BoardType",它允许指定所要连接的 Arduino 面板的类型. "BoardType" 的有效值为:
-
"Uno" 普通的 Arduino 面板,装有 ATMEGA328p 芯片(默认) "Yun" Arduino 面板具有附加的 Wi-Fi/连网功能 - Arduino Yun 可以通过面板上的协处理器连接因特网,当执行网络操作时,由于协处理器的初始化会导致延时. 一般需要 60 秒. 其他功能,例如引脚的读写,在设备开启后便可立即操作,但依赖网络的功能,例如,在 DeviceExecute 文档中的 DatabinAdd 函数在第一次连接时耗时会长一些.
- 使用选项 "InitialUpload",可以在 DeviceOpen 中把自定义的 Wolfram 语言程序自动上载到设备中. "InitialUpload" 默认为 True. 注意:如果 "InitialUpload"为 False,使用前,自定义的 Wolfram 语言程序需要使用 DeviceConfigure 上传.
DeviceOpen["Arduino",name]
用指定名称在串行口上打开 Arduino. 在基于 Unix 的系统上的典型名称是 "/dev/ttyXXX" 或 "/dev/tty.usbserialXXX",在 Windows 是 "COM1"、"COM2" 等.
配置设备
- 注意:任何程序修改都需要重新部署到 Arduino. 这可能会需要 5 到 30 秒,不过它是自动完成的.
- DeviceConfigure 也适用于规则列表.
- "PinConfigure" 不会修改 Arduino 运行的程序,因此不需要重新部署到 Arduino.
- 把一个引脚配置为一个方向,在未重新配置前会使该引脚无法被用于另一个方向. 在与敏感硬件一起使用前,建议设置每个引脚的方向.
- 有效的方向为:
-
"Input" 设置引脚为数字输入,或模拟输入,如果引脚支持的话 "Output" 设置引脚为数字输出引脚,可以输出 5 伏(1 或高),0 伏(0 或低),或一个模拟值,如果引脚支持的话 "AnalogOutput" 设置引脚为模拟 (PWM) 输出,它接受任何介于 0 和 1 间的实数,或格式为 的任何有理数,其中 是介于 0 到 255 间的一个 Integer "AnalogInput" 设置引脚为一个模拟输入,自动读取 0 到 5 伏的模拟电压 - 模拟输出 (PWM) 只有引脚 3、5、6、9、10 和 11 支持.
- 只有引脚 "A0" (14)、"A1" (15)、"A2" (16)、"A3" (17)、"A4" (18) 和 "A5" (19) 支持模拟输入.
- DeviceConfigure 配置运行 Arduino 的程序. 它可以增加功能,例如新函数、C++ 类和变量以及控制引脚的方向.
- 在 Arduino Yun 中启动 Data Drop 功能提供一个指定的 DatabinAdd 函数,它可以用 DeviceExecute 把 Arduino Yun 上引脚值上传到指定的数据仓. 指定的 "BootFunction" 也被启用;详情参见 "BootFunction" 的文档.
- 禁用 Arduino Yun 上的 Data Drop 功能为上传到设备的其他函数提供了更大的编程空间.
- Data Drop 功能还提供了三个 C 函数,可用于 DeviceConfigure 中的用 "Functions" 选项指定的任意自定义 C 函数. DatabinIntegerAdd、DatabinRealAdd 和 DatabinStringAdd 均上传 val 至由 binID 指定的 Databin,其中带有 keyName 的 Key. binID 或 keyName 都不会被释放,如果它们被动态分配,则应通过调用函数被适当释放. binID 和 keyName 都需要是以合适的空 (null) 字符结束的 C 样式字符串.
- DatabinIntegerAdd 上传 Integer 数值至 Databin.
- DatabinRealAdd 上传 Real 数值至 Databin.
- DatabinStringAdd 上传 String 至 Databin.
- "Functions" 会添加给定的 C/C++ 代码到 sketch 程序中并允许执行带有 DeviceExecute 的这套代码. "Functions" 被指定为一个关联,funcname 是一个 Association. 这个 Association 的键 "ArgumentTypes" 为参数类型的列表,"ReturnType" 为返回类型,"Code" 为 C/C++ 代码的实际 String.
- 以下是 Wolfram 语言和 C 语言之间类型转换的总结. 注意,double 和 float 在 Arduino 上是一样的,正如 short 和 int 是一样的那样. 关于 Arduino 架构的更多信息参见 http://arduino.cc/en/Reference/HomePage:
-
byte, char, short, int, long Integer float, double Real float [], double [] {Real} byte [], short [], int [], long [] {Integer} char [] String - 当 Arduino 中的 Integer 列表作为函数的自变量时,它们必须被指明为 long 指针 (long *) ,正如 Wolfram 语言中的整数在 Arduino 上被实现为 long 数据类型. 另外,作为自变量的单个整数列表,必须被指明为 {{Integer}},单个实数列表为 {{Real}}. Arduino 中的 Real 列表可被指明为 double 指针 (double *) 或 float 指针 (float *).
- 不支持 Arduino 中的 unsigned long 数据类型.
- Arduino 上函数支持的返回类型为 Integer、Real 和 String. 注意,对于 String 返回函数,函数返回的字符串必须是一个以空值结束的 C 字符串,否则会发生其他未定义的行为.
- 如果省略函数的 "ReturnType",但它的定义有一个非空的返回类型,则会导致返回的值被忽略,并不会通过串行口返回给 Wolfram 语言.
- "Functions" 的旧规范包括符号 Association 也被支持,其中,上面提到的 Association 如在 funcnameArduinoCode[<"Code"codestr, … >] 一样,是符号 ArduinoCode 的第一个和仅有的参数.
- 要使用 SymbolicC 函数,首先必须加载程序包:
- "BootFunction" 在启动时配置 Arduino 运行函数,甚至是没有连接 Wolfram 语言也会运行. 这样允许在 Arduino 上部署 "BootFunction", 然后从计算机上断开 Arduino,在其他地方启动并运行上传过的代码.
- 代码字符串 codestr 必须是无参数的有效 C/C++ 函数. 如果函数有返回值,则会被忽略.
- 可以在 Association 内部指定一个额外选项 "Scheduling",它控制调用 "BootFunction" 的时间安排. 获取安排设置函数的信息请参见以下的 DeviceExecute 部分.
- 当上传 "BootFunction" 至设备时,设备可能忙于运行 "BootFunction" 中的代码,因此在完成前可能不会回应其他请求. 在设置函数永不返回、无限运行的情况下,若要使用其他功能,必须用 DeviceConfigure 重新配置设备.
- DatabinAdd "BootFunction" 的其他选项为:
-
"Pin" Required 读取值的引脚,必须是一个有效的 Arduino 引脚. "Databin" Required 上传使用的 Databin,要么是作为字符串的数据仓的 "UUID" 或 "ShortID",或一个 Databin 对象. "Key" Optional 默认情况下,值是随着 "AnalogPinX" 或 "DigitalPinX" 的键上传的,但如果特别指定,也会伴随着 Key 的值上传. "ReadMode" Optional 模拟引脚可以读取为介于 0 伏到 5 伏间的连续电压,或读取为 1 或 0 的数字值. 这个选项控制读取模式,"Analog" 读取电压,"Digital" 读取数字状态 1 或 0. 默认为 Automatic,其中数字引脚作为 "Digital",模拟引脚作为 "Analog". "Scheduling" Optional 默认情况下,"BootFunction" 只在启动时间运行一次,但是可以配置 DatabinAdd 函数,运行由 "Scheduling" 指定的安排. 对于 "Scheduling" 的有效值请参见 DeviceExecute 部分. - 程序库主要是用于由 "Functions" 或 Initialization 选项指定的 codestr 中的任何自定义代码.
- 以下是 lib 的有效值:
-
"dir" 包含相关程序库的目录 "file" 包含相关程序库的存档文件 "LibraryName" 内置程序库的字面名称 {lib1,lib2,…} 上面任意组合的列表 - 由于大小的限制,某些程序库可能不能上传到 Arduino.
- 某些程序库,例如,"TFT" 和 "Ethernet" 程序库,对其他程序库有依赖性. 这些不会自动解决,必须由用户手动指定. 对于 "TFT" 和 "Ethernet" 程序库,"SPI" 程序库是由必要的,因此必须包含在程序库的列表中.
- 以下是 Arduino 软件支持的内置程序库列表:
-
"GSM" 与 Arduino GSM shield 接口的程序库 "LiquidCrystal" 与 LCD 显示接口的程序库 "Servo" 控制伺服电机的程序库 "Stepper" 控制步进电机的程序库 "TFT" 与 TFT 显示接口的程序库 "Ethernet" 与 Arduino 以太网 shield 接口的程序库 "Wire" 与 I2C 设备接口的程序库 "SPI" 启动使用 SPI 标准通讯的程序库 "EEPROM" 启动读写 Arduino EEPROM 的程序库 "SoftwareSerial" 启动在任何数字引脚上串行通讯的程序库 - Initialization 代码的典型用法是声明用在不同函数中的对象、变量或类. 注意,某些初始化代码实际上只是放在 "Functions" codestr 选项中. 大量的 Initialization 代码可以放在程序库中.
- 上传时,DeviceConfigure 的其他选项包括:
-
"FlashVerify" True "Debug" False "CleanIntermediate" True - "FlashVerify" 设置在上传到 Arduino 之后是否验证程序. 设置为 False 会减小所需的上传时间,但是有可能程序正确上传失败,你没有办法知道这些除非 Arduino 不能正常工作. 建议把它设为默认值除非你绝对需要速度. 可能的值为 True 或 False.
- "Debug" 设置是否让调试信息出现在屏幕上. 信息包括用于编译 sketch 程序和各种程序库的临时文件夹的位置,以及用于配置、编译和上传 sketch 程序至 Arduino 的原始命令. 可能的值为 True 或 False.
- "CleanIntermediate" 设置是否删除用于配置 Arduino 自定义 sketch 程序的 $TemporaryDirectory 目录中的中间文件. 可能值为 True 或 False.
DeviceConfigure[dev,"PinConfigure"<n1dir1,n2dir2,… >]
设置引脚 ni 的方向为 diri.
DeviceConfigure[dev,<n1dir1,n2dir2,… >]
设置引脚 ni 的方向为 diri.
DeviceConfigure[dev,"Upload"opts]
为 DeviceObject dev 配置 sketch 程序,由 opts 指定并上传到 Arduino.
DeviceConfigure[dev,"Upload""DataDrop"True]
在 Arduino Yun 中,配置 sketch 程序启动 Data Drop 功能. 这对于 Arduino Yun 是默认的,但是不适用于 Arduino Uno.
void DatabinIntegerAdd(char * binID,char * keyName, long val)
void DatabinRealAdd(char * binID, char * keyName, double val)
void DatabinStringAdd(char * binID, char * keyName, char * val)
DeviceConfigure[dev,"Upload""Functions"<funcname<"ArgumentTypes"{type1,type2,…},"ReturnType"return,"Code"codestr > >]
添加参数类型为 typei 的函数,返回类型 return,为 sketch 程序返回带有 C/C++ 定义的 codestr,使得函数可以被 DeviceExecute["Arduino",funcname] 调用.
DeviceConfigure[dev,"Upload""Functions"<funcnameCFunction[type,name,args,body] >]
添加带有名称 funcname 的函数至 Arduino sketch 程序,像定义 SymbolicC CFunction 一样.
DeviceConfigure[dev,"Upload""BootFunction"<"Code"codestr >]
配置 Arduino,在启动后立刻运行函数 codestr.
DeviceConfigure[dev,"Upload""BootFunction"<"Code"DatabinAdd,"Databin"bin,"Pin"pin >]
在 Arduino Yun 上配置 "BootFunction",它会上传至 Databin bin,以及读取 pin 的值.
DeviceConfigure[dev,"Upload""Libraries"lib]
在用户定义的函数中把程序库 lib 包含在 Arduino sketch 程序中.
DeviceConfigure[dev,"Upload""Libraries"{lib1,lib2,…}]
在用户定义的函数中把程序库 libi 包含在 Arduino sketch 程序中.
DeviceConfigure[dev,"Upload"Initializationcodestr]
配置 Arduino 的 sketch 程序,使 codestr 的 C/C++ 代码前置于文件.
设备属性
- 目前只支持属性 "PinConfigurations",它返回引脚最新值的 Dataset 以及各种引脚的状态, "SerialPort" 返回 Arduino 连接的串行口的名称,"ArduinoInstallLocation" 用于表示主机中 Arduino 软件的位置.
- "PinConfigurations" 是只读,而 "ArduinoInstallLocation" 可用于指定编译和上传函数的另一个位置.
- 以下为范例:
- "PinConfigurations" 与 "SerialPort" 是只读的,"ArduinoInstallLocation" 可以被写入,用于编译和上传函数中指定 Arduino 软件的位置.
- 指定的 "ArduinoInstallLocation" 属性会被验证,因此,被用户指定这是由编译器和上传的必须是 Arduino 软件的有效位置. 这是由编译器和上传实用程序以及其他必要的软件所决定. 支持所有已发行的 Arduino IDE 版本.
读取数据
- "ReadMode" 可能的值为 "Digital" 和 "Analog".
- 从模拟引脚读取默认执行模拟读取该引脚. 可以通过使用 "ReadMode""Digital" 读取数字值.
- 只有引脚"A0" (14)、"A1" (15)、"A2" (16)、"A3" (17)、"A4" (18) 和 "A5" (19) 支持模拟读取. 任何引脚均支持数字读取.
- 还支持 DeviceReadTimeSeries.
- "ReturnFunction" f 会返回 f[val]. 对于模拟输入引脚,val 是对应于该引脚模拟电压介于 0 到 1023 之间的数. 1023 对应于 5 伏,0 对应于 0 伏. 在 Arduino 上应用高于 5 伏的电压会损坏设备. 对于其他引脚,val 为 1 或 0,其取决于引脚的电压是高于还是低于 3 伏.
- 注意:默认情况下,"Arduino" 允许任何引脚可以交互使用读写模式. DeviceConfigure 可以用于配置指定的引脚为读或写.
DeviceRead[dev,n]
读取引脚 n 的值.
DeviceRead[dev,{{n1,n2,…}}]
读取每个引脚 ni 的值,返回 ni 与引脚值的关联.
DeviceRead[dev,{n,"ReturnFunction"(func)}]
读取引脚 n 的值,在返回前把 func 应用到值.
DeviceRead[dev,{n,"ReadMode"mode}]
读取引脚 n 的 mode 值.
写入数据
- val 值必须为 0 或 1,除非引脚 n 支持脉宽调制 (PWM).
- DeviceWrite 也支持规则列表.
- 引脚 3、5、6、9、10 和 11 支持 PWM. 在这些引脚中,val 可以是任何介于 0 和 1 之间的实数,或任何 形式的有理数(其中, 是介于 0 到 255 间的 Integer). 这对应于引脚的 PWM 定时器的占空比.
- PWM 引脚也支持写入介于 0 到 5 之间的电压 Quantity,它被调整为占空比.
- 注意:默认情况下,"Arduino" 允许任何引脚在读写模式下交互使用. DeviceConfigure 可用于配置指定引脚为读或写.
DeviceWrite[dev,nval]
把值 val 写入引脚 n.
DeviceWrite[dev,<n1val1,n2val2,… >]
把每个值 vali 写入引脚 ni.
执行命令
- "Scheduling" 会规划在 Arduino 上运行的函数. 这意味着关闭 Wolfram 语言后,此函数会继续运行,只要 Arduino 具有不间断电源. 如果 Arduino 被重置或失去电源,函数需要重新安排.
- Arduino 可以安排毫秒级的任务,因此由 timespec 指定的时间可以近似到千分位.
- 由 timespec 指定的任务时间支持以下格式:
-
dt 每 dt 秒执行函数 {wait} 在等待 wait 秒后,执行一次函数 {dt,count} 每 dt 秒执行函数 count 次 - 在 Arduino 安排任务后,它可能被 DeviceExecute[dev,"DeleteTask",funcname] 过早终止.
- 注意:在任何给定时间中只有一个函数可以在 Arduino 上运行或被安排.
- 当用 DeviceConfigure 上传至设备时,指定 "Databin"bin 会配置该函数使用 bin 作为 Databin 上传用的数据仓. 如果没用 DeviceConfigure 配置,必须指定选项 Databin,要么是作为 String 的数据仓的 "UUID" 或"ShortID",要么是 Databin 对象.
- "ReadMode""Digital" 指定 "ReadMode",在模拟引脚上读取 pin 的数字值,否则,会读取模拟引脚介于 0 到 5 伏的模拟电压. 当 pin 是数字引脚时,只有 "Digital" 或 Automatic 是有效值.
- 如果设备配置为 "DataDrop"False,则函数不适用.
- 注意:只适用于 Arduino Yun.
DeviceExecute[dev,funcname]
在 Arduino 上执行函数 funcname.
DeviceExecute[dev,funcname,args]
在 Arduino 上执行带有自变量 args 的函数 funcname.
DeviceExecute[dev,funcname,{args,"Scheduling"timespec}]
执行函数 funcname,其中自变量 args 在由 timespec 指定的任务上.
DeviceExecute[dev,DatabinAdd,pin]
在 Arduino Yun 上,把 pin 的当前值上传到 DeviceConfigure 中指定的默认 Databin.
DeviceExecute[dev,DatabinAdd,{pin,"Databin"bin,"Key"name,"ReadMode"mode}
在 Arduino Yun 上,当用 Key name 读取 mode 至 bin 时,上传 pin 的当前值.
关闭和释放资源
- 注意简单地从机器的 USB 或串行口中物理移除 Arduino,并不会关闭连接. 为了正确结束使用,建议在移除设备前调用 DeviceClose.
- 在 Arduino 上安排的任何函数任务会继续运行,甚至是在关闭设备的连接之后,只要 Arduino 具有不间断电源.
DeviceClose[dev]
关闭对 Arduino 设备 dev 的连接并释放串行口.
范例
基本范例 (1)
打开与 Arduino 的连接,并上传要求的 sketch 程序至设备:
把脉宽调制的占空比写入引脚 5,对某些设备其大致对应于2.5伏:
从引脚 4 读取,用 "ReturnFunction" 将读到的值与 1 比较:
上传 SymbolicC 函数至 Arduino,把两个数相加并加上 1000:
上传函数控制附加在 Arduino 引脚9的伺服电机,使用 Arduino 内置伺服程序库,把自变量作为伺服电机要旋转到的位置:
以下范例需要 LCD 附加在 Arduino 的引脚 12、11、5、4、3 和 2. 首先上传一个简单函数,把字符串写入 LCD 屏幕: