Vancouver, Canada
Offline
Newbie
Karma: 0
Posts: 12
|
 |
« Reply #12 on: June 20, 2012, 01:30:48 am » |
Hello All;
I'm making a little progress in talking with my SDI-12 sensor. I'm using Rob Tillaart's code as a starting point with a few changes: First off I switched to SoftwareSerial.h and then set the UART to inverted logic. Before I had tried with Rob's code but that kept the Tx (pin 10) port high all the time which won't work with SDI-12. I added a 13ms HIGH pulse, followed by 9ms of LOW on the Tx pin before sending the command. You can see the SDI-12 answer but at slightly lower voltage. The voltage is lower for the reply because the Tx (pin 10) and Rx (pin 11) pins are tied together. At first they were simply tied together, but then the reply voltage was only about 1.8V because of the open Tx pin. Now the Tx pin talks through a 2.2kOhm resistor and far more signal is available for the Rx pin. If I could figure out how to pull the internal resistor on the Tx pin high I would give that a try.
I have attached two pics. One of the scope showing the 13ms High pulse, 9ms Low, the request from the Arduino, and finally the reply from the sensor.
The second pic is a screen grab of the terminal output. I send the configuration commands to the sensor, and then try to ask for the sensor to send back what it has for configuration. For some reason, the I can only read a small part of the settings back when requested. I can't figure out why.
And here is the code: // // FILE: SDI-12.001.pde // AUTHOR: Rob Tillaart // DATE: 2012-mar-18 // // PUPROSE: talk to SDI-12 anemometer //
#include <SoftwareSerial.h>
#define txPin 10 #define rxPin 11 #define INVERTED true //SDI-12 uses inverted logic
SoftwareSerial sdiAnem(rxPin, txPin, INVERTED);
void setup() { // communication with PC Serial.begin(115200); Serial.println("\nSDI-12 0.01");
// software serial for the sensor sdiAnem.begin(1200); delay(9); digitalWrite(txPin, HIGH); delay(13); digitalWrite(txPin, LOW); delay(9); sdiAnem.write("0XXU,A=0,M=R,C=1,B=1200,D=7,P=E,S=1!"); Serial.println("0XXU,A=0,M=R,C=1,B=1200,D7,P=E,S=1!");
delay(9); digitalWrite(txPin, HIGH); delay(13); digitalWrite(txPin, LOW); delay(9); sdiAnem.write("0XWU,R=01001100&01001100,I=10,A=60,G=3,U=N,D=0,N=W,F=4!"); Serial.println("0XWU,R=01001100&01001100,I=10,A=60,G=3,U=N,D=0,N=W,F=4!");
char incomingAnswer[80]; char a; int idy = 0; delay(9); digitalWrite(txPin, HIGH); delay(13); digitalWrite(txPin, LOW); delay(9); sdiAnem.write("0SU!"); if (sdiAnem.available() > 0) { a = sdiAnem.read(); incomingAnswer[idy] = a & 0x7F; // strip bit 8 idy++; } Serial.print("Reported settings are: "); Serial.println(incomingAnswer);
}
void loop() { char *answer;
answer = addressQuery(); // char, no string Serial.print("\n addressQuery: "); Serial.println(answer);
AcknowledgeActive('0'); // char, no string Serial.print("\n Address: "); Serial.println(answer);
sendIdentification('0'); // char, no string Serial.print("\n id: "); Serial.println(answer);
int t = 0; int n = 0;
/* startMeasurement('0', &t, &n); Serial.print("\n startMeasurement: "); Serial.println(answer); Serial.println(t, DEC); Serial.println(n, DEC);
delay(t*1000UL); // wait for the measurement to be ready */ sendData('0'); Serial.print("\n sendData: "); Serial.println(answer);
delay(20000UL); }
///////////////////////////////////////////////////////// // // Proto SDI-12 commands // // names of functions, Table 5, page 8, SDI-12 1.3 specification //
///////////////////////////////////////////////////////// // // Private members // char response[80]; // at least 35/75 according to 1.3 spec
///////////////////////////////////////////////////////// // // Public part I (admin commands) // char* AcknowledgeActive(char address) { char command[] = "a!"; command[0] = address; request(2, command, response); return response; }
char* addressQuery() { char command[] = "?!"; request(2, command, response); return response; }
char* addressChange(char oldAddress, char newAddress) { char command[] = "aAb!"; command[0] = oldAddress; command[2] = newAddress; request(4, command, response); return response; }
char* sendIdentification(char address) { char command[] = "aI!"; command[0] = address; request(3, command, response); return response; }
void printIdentification(char *idStr) { // TODO }
///////////////////////////////////////////////////////// // // Public part II (measurements) // char* startMeasurement(char address, int *t, int *n) { char command[] = "aI!"; command[0] = address; request(3, command, response);
int len = strlen(response); *n = (int) (response[len-1] - '\0'); *t = atoi(&response[1]) / 10;
return response; }
char* sendData(char address) { char command[] = "0R1!"; request(4, command, response); return response; }
///////////////////////////////////////////////////////// // // Private part I // void request(uint8_t length, char *command, char *response) { // send command delay(9); digitalWrite(txPin, HIGH); delay(13); digitalWrite(txPin, LOW); delay(9); for (int idx=0; idx<length; idx++) { sdiAnem.write(command[idx]); }
// blocking until answer comes in char c = ' '; int idx = 0; while (c != 10) // answer ends with LineFeed = char 10 { if (sdiAnem.available() > 0) { c = sdiAnem.read(); response[idx] = c & 0x7F; // strip bit 8 idx++; } } response[idx-2] = 0; // remove the CRLF and end string correctly }
// --- END OF FILE ---
|