"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 必须在使用 DeviceReadDeviceWriteDeviceExecute 之前,用 DeviceConfigure 加载至 Arduino.

注意:默认情况下,"Arduino" 允许任何引脚交替使用读写模式. DeviceConfigure 可用于配置指定引脚的读或写.

Arduino Uno

设备发现

  • 发现 Arduino 基本上与发现串行口是一样的,因为这是与 Arduino 的通信方法. 因此,Arduino 的自动发现具有挑战性且当前并未实现.
  • 在基于 Unix 的系统上,串行连接的名称有时可通过比较特定连接插入前后的 /dev/tty* 设备识别.
  • 在基于 Windows 的系统上,串行连接的名称有时可通过打开设备管理器,检查虚拟 COM 端口列表或只是端口 (COM & LPT)识别,这取决于你的 Windows 版本.

打开设备

    DeviceOpen["Arduino",name]

    用指定名称在串行口上打开 Arduino. 在基于 Unix 的系统上的典型名称是 "/dev/ttyXXX""/dev/tty.usbserialXXX",在 Windows 是 "COM1""COM2" 等.

  • 如果在机器上没有找到 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 上传.

配置设备

  • 注意:任何程序修改都需要重新部署到 Arduino. 这可能会需要 5 到 30 秒,不过它是自动完成的.
  • DeviceConfigure[dev,"PinConfigure"<|n1dir1,n2dir2,|>]

    设置引脚 ni 的方向为 diri.

    DeviceConfigure[dev,<|n1dir1,n2dir2,|>]

    设置引脚 ni 的方向为 diri.

  • 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[dev,"Upload"opts]

    DeviceObject dev 配置 sketch 程序,由 opts 指定并上传到 Arduino.

  • DeviceConfigure 配置运行 Arduino 的程序. 它可以增加功能,例如新函数、C++ 类和变量以及控制引脚的方向.
  • DeviceConfigure[dev,"Upload""DataDrop"True]

    在 Arduino Yun 中,配置 sketch 程序启动 Data Drop 功能. 这对于 Arduino Yun 是默认的,但是不适用于 Arduino Uno.

  • 在 Arduino Yun 中启动 Data Drop 功能提供一个指定的 DatabinAdd 函数,它可以用 DeviceExecute 把 Arduino Yun 上引脚值上传到指定的数据仓. 指定的 "BootFunction" 也被启用;详情参见 "BootFunction" 的文档.
  • 禁用 Arduino Yun 上的 Data Drop 功能为上传到设备的其他函数提供了更大的编程空间.
  • Data Drop 功能还提供了三个 C 函数,可用于 DeviceConfigure 中的用 "Functions" 选项指定的任意自定义 C 函数. DatabinIntegerAddDatabinRealAddDatabinStringAdd 均上传 val 至由 binID 指定的 Databin,其中带有 keyNameKey. binIDkeyName 都不会被释放,如果它们被动态分配,则应通过调用函数被适当释放. binIDkeyName 都需要是以合适的空 (null) 字符结束的 C 样式字符串.
  • void DatabinIntegerAdd(char * binID,char * keyName, long val)
  • DatabinIntegerAdd 上传 Integer 数值至 Databin.
  • void DatabinRealAdd(char * binID, char * keyName, double val)
  • DatabinRealAdd 上传 Real 数值至 Databin.
  • void DatabinStringAdd(char * binID, char * keyName, char * val)
  • DatabinStringAdd 上传 StringDatabin.
  • DeviceConfigure[dev,"Upload""Functions"<|funcname<|"ArgumentTypes"{type1,type2,},"ReturnType"return,"Code"codestr|>|>]

    添加参数类型为 typei 的函数,返回类型 return,为 sketch 程序返回带有 C/C++ 定义的 codestr,使得函数可以被 DeviceExecute["Arduino",funcname] 调用.

  • "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, longInteger
    float, doubleReal
    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 上函数支持的返回类型为 IntegerRealString. 注意,对于 String 返回函数,函数返回的字符串必须是一个以空值结束的 C 字符串,否则会发生其他未定义的行为.
  • 如果省略函数的 "ReturnType",但它的定义有一个非空的返回类型,则会导致返回的值被忽略,并不会通过串行口返回给 Wolfram 语言.
  • "Functions" 的旧规范包括符号 Association 也被支持,其中,上面提到的 Association 如在 funcnameArduinoCode[<|"Code"codestr, |>] 一样,是符号 ArduinoCode 的第一个和仅有的参数.
  • DeviceConfigure[dev,"Upload""Functions"<|funcnameCFunction[type,name,args,body]|>]

    添加带有名称 funcname 的函数至 Arduino sketch 程序,像定义 SymbolicC CFunction 一样.

  • 要使用 SymbolicC 函数,首先必须加载程序包:
  • DeviceConfigure[dev,"Upload""BootFunction"<|"Code"codestr|>]

    配置 Arduino,在启动后立刻运行函数 codestr.

  • "BootFunction" 在启动时配置 Arduino 运行函数,甚至是没有连接 Wolfram 语言也会运行. 这样允许在 Arduino 上部署 "BootFunction", 然后从计算机上断开 Arduino,在其他地方启动并运行上传过的代码.
  • 代码字符串 codestr 必须是无参数的有效 C/C++ 函数. 如果函数有返回值,则会被忽略.
  • 可以在 Association 内部指定一个额外选项 "Scheduling",它控制调用 "BootFunction" 的时间安排. 获取安排设置函数的信息请参见以下的 DeviceExecute 部分.
  • 当上传 "BootFunction" 至设备时,设备可能忙于运行 "BootFunction" 中的代码,因此在完成前可能不会回应其他请求. 在设置函数永不返回、无限运行的情况下,若要使用其他功能,必须用 DeviceConfigure 重新配置设备.
  • DeviceConfigure[dev,"Upload""BootFunction"<|"Code"DatabinAdd,"Databin"bin,"Pin"pin|>]

    在 Arduino Yun 上配置 "BootFunction",它会上传至 Databin bin,以及读取 pin 的值.

  • 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 部分.
  • DeviceConfigure[dev,"Upload""Libraries"lib]

    在用户定义的函数中把程序库 lib 包含在 Arduino sketch 程序中.

    DeviceConfigure[dev,"Upload""Libraries"{lib1,lib2,}]

    在用户定义的函数中把程序库 libi 包含在 Arduino sketch 程序中.

  • 程序库主要是用于由 "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"启动在任何数字引脚上串行通讯的程序库
  • DeviceConfigure[dev,"Upload"Initializationcodestr]

    配置 Arduino 的 sketch 程序,使 codestr 的 C/C++ 代码前置于文件.

  • Initialization 代码的典型用法是声明用在不同函数中的对象、变量或类. 注意,某些初始化代码实际上只是放在 "Functions" codestr 选项中. 大量的 Initialization 代码可以放在程序库中.
  • 上传时,DeviceConfigure 的其他选项包括:
  • "FlashVerify"True
    "Debug"False
    "CleanIntermediate"True
  • "FlashVerify" 设置在上传到 Arduino 之后是否验证程序. 设置为 False 会减小所需的上传时间,但是有可能程序正确上传失败,你没有办法知道这些除非 Arduino 不能正常工作. 建议把它设为默认值除非你绝对需要速度. 可能的值为 TrueFalse.
  • "Debug" 设置是否让调试信息出现在屏幕上. 信息包括用于编译 sketch 程序和各种程序库的临时文件夹的位置,以及用于配置、编译和上传 sketch 程序至 Arduino 的原始命令. 可能的值为 TrueFalse.
  • "CleanIntermediate" 设置是否删除用于配置 Arduino 自定义 sketch 程序的 $TemporaryDirectory 目录中的中间文件. 可能值为 TrueFalse.

设备属性

  • 目前只支持属性 "PinConfigurations",它返回引脚最新值的 Dataset 以及各种引脚的状态, "SerialPort" 返回 Arduino 连接的串行口的名称,"ArduinoInstallLocation" 用于表示主机中 Arduino 软件的位置.
  • "PinConfigurations" 是只读,而 "ArduinoInstallLocation" 可用于指定编译和上传函数的另一个位置.
  • 以下为范例:
  • "PinConfigurations""SerialPort" 是只读的,"ArduinoInstallLocation" 可以被写入,用于编译和上传函数中指定 Arduino 软件的位置.
  • 指定的 "ArduinoInstallLocation" 属性会被验证,因此,被用户指定这是由编译器和上传的必须是 Arduino 软件的有效位置. 这是由编译器和上传实用程序以及其他必要的软件所决定. 支持所有已发行的 Arduino IDE 版本.

读取数据

    DeviceRead[dev,n]

    读取引脚 n 的值.

    DeviceRead[dev,{{n1,n2,}}]

    读取每个引脚 ni 的值,返回 ni 与引脚值的关联.

    DeviceRead[dev,{n,"ReturnFunction"(func)}]

    读取引脚 n 的值,在返回前把 func 应用到值.

    DeviceRead[dev,{n,"ReadMode"mode}]

    读取引脚 nmode 值.

  • "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 可以用于配置指定的引脚为读或写.

写入数据

    DeviceWrite[dev,nval]

    把值 val 写入引脚 n.

    DeviceWrite[dev,<|n1val1,n2val2,|>]

    把每个值 vali 写入引脚 ni.

  • 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 可用于配置指定引脚为读或写.

执行命令

    DeviceExecute[dev,funcname]

    在 Arduino 上执行函数 funcname.

    DeviceExecute[dev,funcname,args]

    在 Arduino 上执行带有自变量 args 的函数 funcname.

    DeviceExecute[dev,funcname,{args,"Scheduling"timespec}]

    执行函数 funcname,其中自变量 args 在由 timespec 指定的任务上.

  • "Scheduling" 会规划在 Arduino 上运行的函数. 这意味着关闭 Wolfram 语言后,此函数会继续运行,只要 Arduino 具有不间断电源. 如果 Arduino 被重置或失去电源,函数需要重新安排.
  • Arduino 可以安排毫秒级的任务,因此由 timespec 指定的时间可以近似到千分位.
  • timespec 指定的任务时间支持以下格式:
  • dtdt 秒执行函数
    {wait}在等待 wait 秒后,执行一次函数
    {dt,count}dt 秒执行函数 count
  • 在 Arduino 安排任务后,它可能被 DeviceExecute[dev,"DeleteTask",funcname] 过早终止.
  • 注意:在任何给定时间中只有一个函数可以在 Arduino 上运行或被安排.
  • DeviceExecute[dev,DatabinAdd,pin]

    在 Arduino Yun 上,把 pin 的当前值上传到 DeviceConfigure 中指定的默认 Databin.

    DeviceExecute[dev,DatabinAdd,{pin,"Databin"bin,"Key"name,"ReadMode"mode}

    在 Arduino Yun 上,当用 Key name 读取 modebin 时,上传 pin 的当前值.

  • 当用 DeviceConfigure 上传至设备时,指定 "Databin"bin 会配置该函数使用 bin 作为 Databin 上传用的数据仓. 如果没用 DeviceConfigure 配置,必须指定选项 Databin,要么是作为 String 的数据仓的 "UUID""ShortID",要么是 Databin 对象.
  • "ReadMode""Digital" 指定 "ReadMode",在模拟引脚上读取 pin 的数字值,否则,会读取模拟引脚介于 0 到 5 伏的模拟电压. 当 pin 是数字引脚时,只有 "Digital"Automatic 是有效值.
  • 如果设备配置为 "DataDrop"False,则函数不适用.
  • 注意:只适用于 Arduino Yun.

关闭和释放资源

    DeviceClose[dev]

    关闭对 Arduino 设备 dev 的连接并释放串行口.

  • 注意简单地从机器的 USB 或串行口中物理移除 Arduino,并不会关闭连接. 为了正确结束使用,建议在移除设备前调用 DeviceClose.
  • 在 Arduino 上安排的任何函数任务会继续运行,甚至是在关闭设备的连接之后,只要 Arduino 具有不间断电源.

范例

基本范例  (1)

打开与 Arduino 的连接,并上传要求的 sketch 程序至设备:

设置引脚 3 的脉宽调制的占空比为 50%:

把 0 写入数字引脚 10:

把脉宽调制的占空比写入引脚 5,对某些设备其大致对应于2.5伏:

从多个模拟输入引脚读取:

从引脚 4 读取,用 "ReturnFunction" 将读到的值与 1 比较:

从模拟引脚 A3 读取值,应用转换函数把值变成英寸:

获取特定引脚最新读取的值:

上传 SymbolicC 函数至 Arduino,把两个数相加并加上 1000:

现在运行带有参数 1 和 20 的函数:

上传函数控制附加在 Arduino 引脚9的伺服电机,使用 Arduino 内置伺服程序库,把自变量作为伺服电机要旋转到的位置:

现在旋转伺服机到 90 度的位置:

以下范例需要 LCD 附加在 Arduino 的引脚 12、11、5、4、3 和 2. 首先上传一个简单函数,把字符串写入 LCD 屏幕:

现在,把字符串写入 LCD 屏幕:

连接 Arduino Yun:

创造一个新的上传数据仓:

配置 Arduino 使用默认的数据仓:

上传引脚 "A0" 的当前值至数据仓:

在下个 10 秒中每秒一次把数字引脚 4 的值上传至数据仓中:

配置 Yun 在启动后每 60 秒一次,无限上传引脚 "A5" 的值,其中键为 "SensorValue":