3

我正在尝试与SDI-12设备进行串行通信,它需要以 1200 波特反转的七个数据位、偶校验和一个停止位(7E1) 串行。

从数据表:

SDI-12通信以每秒 1200 位的速度发送字符。每个字符有 1 个起始位、7 个数据位(LSB 在前)、1 个偶校验位和 1 个停止位(低电平有效或反转逻辑电平):

All SDI-12命令和响应在数据线上必须遵循以下格式。命令和响应都以地址开头,并以回车换行组合终止。

Serial 或 SoftwareSerial 库可以做到这一点吗?我试图避免使用额外的硬件(除了到 3.3 V 的电平转换器),但如果这是唯一的方法,我会这样做。

我已经看到 SoftwareSerial 可以做反转,而 Serial 可以做 7E1,但我找不到两者是否都可以。

我可以使用Arduino Mega (R2) 和Arduino Uno (R3)。

这是我要与之通信的设备:http: //www.decagon.com/products/sensors/soil-moisture-sensors/gs3-soil-moisture-temperature-and-ec/在这里,http://www .decagon.com/assets/Uploads/GS3-Integrators-Guide.pdf是解释协议的文件。第 6 页讨论了它对 SDI 的实施。

4

2 回答 2

1

我对 Arduino 不熟悉,但是 SDI-12 物理层与标准 TTL 电平相反——可能有两个原因:

  1. 由于空闲电压为 0V,这会导致较低的待机功耗(由于典型 SDI-12 传感器中的标称下拉电阻。
  2. 它有助于使用标准 RS-232 串行端口进行简单的总线“嗅探”。

没有对 5V IO 引脚进行位敲击 - 是的,如果使用标准微控制器 UART,您将需要一个外部逆变器(或 2 个)和一个三态缓冲器。可能需要电平转换,具体取决于您的硬件。

点赞维基百科条目——SDI-12 使用完全标准的 UART 位时序(非常像 RS-232),只是不同的信号电平(0 - 5V);见第 2 点。但是,有特定的中断序列和严格的时序要求,这使得固件开发更加困难。

如果您认真对待 SDI-12 固件开发,您可能需要购买 SDI-12 验证器对规范进行彻底的研究是必不可少的。

于 2012-11-28T07:03:27.740 回答
1

有点晚了……但迟到总比没有好

实际上,我刚刚为此编写了一个库(实际上包括传感器……所以它应该与包含的示例完全一致)

https://github.com/joranbeasley/SDISerial(Arduino库)

#include <SDISerial.h> //https://github.com/joranbeasley/SDISerial (Arduino Library)
#include <string.h>
#define DATA_PIN 2
SDISerial connection(DATA_PIN);
char output_buffer[125]; // just for uart prints
char tmp_buffer[4];
char sensor_info[]
//initialize variables
void setup(){
      connection.begin();
      Serial.begin(9600);//so we can print to standard uart
      //small delay to let the sensor do its startup stuff
      delay(3000);//3 seconds should be more than enough
      char* sensor_info = connection.sdi_query("0I!",1000); // get sensor info for address 0
}

//main loop
void loop(){
    //print to uart
    Serial.println("Begin Command: ?M!");

    //send measurement query (M) to the first device on our bus
    char* resp = connection.service_request("0M!","0D0!");//Get Measurement from address 0


    sprintf(output_buffer,"RECV: %s",resp?resp:"No Response Recieved!!");
    Serial.println(output_buffer);
    delay(10000);//sleep for 10 seconds before the next read
}
于 2014-03-05T19:47:49.313 回答