Electronza
  • Homepage
  • Privacy
    • Privacy Policy
  • Contact
Electronza
  • Homepage
  • Privacy
    • Privacy Policy
  • Contact
Electronza
You are at:Home»Tutorials»SPEC DGS sensors: new firmware, new behaviour
SPEC Digital H2S sensor
SPEC Digital H2S sensor

SPEC DGS sensors: new firmware, new behaviour

4
By Electronza on April 18, 2019 Tutorials

Yesterday I managed to damage the DGS-H2S sensor I used in my projects. No big deal, I dropped in on the floor, and the sensor broke. While I wait for a replacement sensor to arrive, I tried to work with a spare one, a new sensor that I plan to put into a permanent location.

SURPRISE!!! The new sensor didn’t work!

I expected that SPEC DGS sensors are drop-in replacements, but I was proven wrong. After a day of investigating this issue, I realized that there are two firmware versions of the same sensor, and each firmware comes with its features. To make matters more complicated, there is no marking on the sensor itself to tell the firmware version. Furthermore, all documentation on https://www.spec-sensors.com/ is for the old firmware.

But, here is what I have found about the new version:

Checking the firmware version of the sensor

To check the firmware version of the sensor one has to connect it to an Arduino Due or an Arduino Uno board, as described in my previous projects, and then run the SerialPassthrough Arduino sketch.

Open serial monitor, then configure it to send only the carriage return.

DGS-H2S - checking firmware version
DGS-H2S – checking firmware version

Reset the sensor by sending ‘r‘ or ‘R‘. Then try to rapidly send several times the character ‘f’ (lower-case f, without quotation marks), until the sensor responds. If the sensor has the new firmware, it will respond with ‘15SEP17′.  If you have the old version, you will trigger a measurement, and then it will respond with ‘14FEB17′.

Oh, and the SPEC-DGS library is for the firmware version 25SEP17.

New firmware, new behavior

Some issues and features I have found so far in the new firmware:

  • When started, the first thing to do is reset the sensor by sending ‘r’ or ‘R’
    • The reset works by executing a while(1); loop and waits for the watchdog to reset the sensor. After issuing the reset command one needs to wait for about one second.
  • The sensor no longer expects the unlock code 12345/r
    • Setting the zero value is simply performed by sending ‘Z’. The sensor will respond with “Setting zero…done”
  • Triggering a single measurement works by sending ‘\r’ only
  • One can instead put the sensor in continuous mode by sending ‘c’.
  • continuous mode is stopped with ‘c’.
  • Continous mode is one second only
  • The sensor is much faster!!!
  • There is a new command ‘A‘ which configures the sensor to perform the average of a given number of measurements. To use this feature, send ‘A‘ , without ‘/r’. The sensor will respond with “Enter Average Total:”. Insert the average value (between 1 and 300), followed by ‘/r’. If successful, the sensor will respond with ‘/r/n’
    • The response time of the sensor changes according to the average value. While triggering a single measurement by sending ‘/r’, the sensor responds in 287ms if A=1, and in 375ms if A=300.
    • You can check the Average_Total value in the EEPROM dump, by sending ‘e‘
    • Recommended values are least 60 for O3/NO2/H2S and 300 for SO.
  • There is a sleep command, ‘s‘. Wake up the sensor by sending anything on the serial port. Wait for about one second, then you can issue commands.
    • The sensor draws 4.2mA in normal mode. In sleep mode it needs only 26μA.

New Arduino code

Below is a code version that I have tested with Arduino Due.\


// SPEC H2S Sensor demo code
// This code works with sensor firmware 15SEP17
// #define SERIAL1_RX_BUFFER_SIZE 256
// #define SERIAL1_TX_BUFFER_SIZE 256
// Sensor values
// The format of the output is: SN[XXXXXXXXXXXX], PPB [0 : 999999], TEMP [-99:99],
// RH[0:99], RawSensor[ADCCount], TempDigital, RHDigital, Day[0:99], Hour [0:23]
// Note that on Arduino Due integer variable (int) stores a 32-bit (4-byte) value.
// This yields a range of -2,147,483,648 to 2,147,483,647
// (minimum value of -2^31 and a maximum value of (2^31) – 1).
// On 8 bit boards some readings have to be recorded as floats
String SensorSerialNo;
int H2S;
int Temperature;
int RH;
int RawSensor;
int TempDigital;
int RHDigital;
int Days;
int Hours;
int Minutes;
int Seconds;
#define command_delay 500
#define start_delay 2500
String dataString = "";
String responseString = "";
boolean dataStringComplete = 0;
char inChar;
void setup() {
Serial.begin(9600);
// Wait for serial port
while(!Serial);
Serial.println("SPEC DGS-H2S sensor demo code!");
Serial.println("");
Serial1.begin(9600);
// Normally, data is returned within one second
Serial1.setTimeout(1500);
// reserve 80 bytes for the dataString
dataString.reserve(80);
responseString.reserve(150);
// Wait for sensor
delay(500);
flush_serial1();
Serial.println("Resetting sensor");
SPEC_reset();
// Print firmware version
SPEC_show_firmware();
// EEPROM dump
SPEC_dump_EEPROM();
Serial.println(" ");
Serial.println("STARTING MEASUREMENTS");
Serial.println(" ");
}
void loop() {
// Do a readout every 10 seconds
SPEC_Data_read();
SPEC_parse_data();
SPEC_print_data();
delay(10000);
}
/* ********************************************************************************
* This function triggers one measurement and receives the data from the sensor
**********************************************************************************/
void SPEC_Data_read(){
// First, we do some initialization
// dataStringComplete is set as "false", as we don't have any valid data received
dataStringComplete = 0;
// Clear the data string
dataString = "";
// Now we trigger a measurement
//Serial1.print(" ");
Serial1.print("\r");
// We wait for the sensor to respond
dataString = Serial1.readStringUntil('\n');
//Serial.println(dataString);
}
/* ********************************************************************************
* This function takes the received string and upodates sensor data
**********************************************************************************/
void SPEC_parse_data(){
// Parses the received dataString
// Data string is comma separated
// The format of the output is: SN[XXXXXXXXXXXX], PPB [0 : 999999], TEMP [-99:99],
// RH[0:99], RawSensor[ADCCount], TempDigital, RHDigital, Day[0:99], Hour [0:23],
// Minute[0:59], Second[0 : 59]\r\n
// Take a look also at
// https://stackoverflow.com/questions/11068450/arduino-c-language-parsing-string-with-delimiter-input-through-serial-interfa
// We look first for the SN
int idx1 = dataString.indexOf(',');
SensorSerialNo = dataString.substring(0, idx1);
int idx2 = dataString.indexOf(',', idx1 + 1);
// Hint: after comma there's a space – it should be ignored
String S_gas = dataString.substring(idx1 + 2, idx2);
H2S = S_gas.toInt();
int idx3 = dataString.indexOf(',', idx2 + 1);
String S_temp = dataString.substring(idx2 + 2, idx3);
Temperature = S_temp.toInt();
int idx4 = dataString.indexOf(',', idx3 + 1);
String S_humi = dataString.substring(idx3 + 2, idx4);
RH = S_humi.toInt();
int idx5 = dataString.indexOf(',', idx4 + 1);
String S_raw_gas = dataString.substring(idx4 + 2, idx5);
RawSensor = S_raw_gas.toInt();
int idx6 = dataString.indexOf(',', idx5 + 1);
String S_Tdigital = dataString.substring(idx5 + 2, idx6);
TempDigital = S_Tdigital.toInt();
int idx7 = dataString.indexOf(',', idx6 + 1);
String S_RHdigital = dataString.substring(idx6 + 2, idx7);
RHDigital = S_RHdigital.toInt();
int idx8 = dataString.indexOf(',', idx7 + 1);
String S_Days = dataString.substring(idx7 + 2, idx8);
Days = S_Days.toInt();
int idx9 = dataString.indexOf(',', idx8 + 1);
String S_Hours = dataString.substring(idx8 + 2, idx9);
Hours = S_Hours.toInt();
int idx10 = dataString.indexOf(',', idx9 + 1);
String S_Minutes = dataString.substring(idx9 + 2, idx10);
Minutes = S_Minutes.toInt();
int idx11 = dataString.indexOf('\r');
String S_Seconds = dataString.substring(idx10 + 2, idx11);
Seconds = S_Seconds.toInt();
}
/* ********************************************************************************
* This function prints the sensor data
**********************************************************************************/
void SPEC_print_data(){
Serial.println("********************************************************************");
Serial.print ("Sensor Serial No. is ");
Serial.println (SensorSerialNo);
Serial.print ("H2S level is ");
Serial.print (H2S);
Serial.println (" ppb");
Serial.print ("Temperature is ");
Serial.print (Temperature, DEC);
Serial.println (" deg C");
Serial.print ("Humidity is ");
Serial.print (RH, DEC);
Serial.println ("% RH");
Serial.print ("Sensor is online since: ");
Serial.print (Days, DEC);
Serial.print (" days, ");
Serial.print (Hours, DEC);
Serial.print (" hours, ");
Serial.print (Minutes, DEC);
Serial.print (" minutes, ");
Serial.print (Seconds, DEC);
Serial.println (" seconds");
Serial.println ("Raw Sensor Data");
Serial.print ("Raw gas level: ");
Serial.println (RawSensor);
Serial.print ("Temperature digital: ");
Serial.println (TempDigital);
Serial.print ("Humidity digital: ");
Serial.println (RHDigital);
Serial.println ("");
}
/* ********************************************************************************
* EEPROM dump
**********************************************************************************/
void SPEC_dump_EEPROM(){
Serial1.print("e");
dataString = Serial1.readStringUntil('\n');
// You can uncomment this line if you wish
//Serial.println(dataString);
for (int i=0; i<20; i++){
responseString = Serial1.readStringUntil('\n');
Serial.println(responseString);
}
}
void SPEC_reset(){
Serial1.print("r");
delay(1000);
}
void SPEC_show_firmware(){
Serial1.print("f");
responseString = Serial1.readStringUntil('\n');
Serial.print("Sensor firmware version is ");
Serial.println(responseString);
Serial.println("");
delay(400);
}
void flush_serial1(){
// Do we have data in the serial buffer?
// If so, flush it
if (Serial1.available() > 0){
Serial.println ("Flushing serial buffer…");
while(1){
inChar = (char)Serial1.read();
delay(10);
Serial.print(inChar);
if (inChar == '\n') break;
}
Serial.println (" ");
Serial.println ("Buffer flushed!");
}
}

view raw

dgs-h2s.ino

hosted with ❤ by GitHub

  
  
firmware H2S hydrogen sulfide SPEC Sensors DGS-H2S
Share. Facebook Twitter Pinterest LinkedIn Tumblr Email

Related Posts

Some software services that make my life easier

H2S IoT node with ESP8266 Thing Dev

H2S IoT node with ESP8266 and openSenseMap

Arduino: MCP23S17 LCD

Arduino: a code library for MCP23S17 LCD

4 Comments

  1. SorinN on June 22, 2019 11:31 pm

    Hello,
    I am trying since several days to use the sensor (968-036 Hydrogen Sulfide (H2S) Sensor USB) with firmware 15SEP17 with Arduino Due – as per your example but using the NativeUSB port. It simply does not return any data from sensor. I checked and the sensor is powered. On the USB connection directly to Teraterm, the sensor is working fine. The sensor has direct USB output. I tried Serial Passthrough using SerialUSB and still nothing.
    What else should I try?

    Reply
    • Teodor Costachioiu on June 23, 2019 8:36 pm

      Hello Sorin,

      The USB-to-serial converter of the Programming port is connected to the first UART of the SAM3X. It’s possible to communicate over this port using the “Serial” object in the Arduino programming language. – see https://www.arduino.cc/en/Guide/ArduinoDue#toc13

      See also https://forum.arduino.cc/index.php?topic=180928.0
      and
      https://copperhilltech.com/blog/how-to-use-the-native-usb-of-the-arduino-due-for-highspeed-communication/

      I simply prefer to use the programming port to get the output from Serial.

      Reply
  2. SorinN on June 25, 2019 9:27 pm

    Hello, Teodor! I got it finally working tonight, by not using SerialUSB or Serial ports (the USB ports on the Due board) but using the Serial1 and direct connection of the sensor to pins 18/19. Although I changed several cables and adapters it seems that the UART to USB adapter the sensor was delivere with only works with the laptop (?) and not the Arduino Due board.

    I tried to use your suggestion – but “Serial” was already the programming port connected to my computer, the “SerialUSB” did not work and so on.

    I will look into opensensebox in the next days to pin it on the dynamic map, but I’ll have to add some wifi module to publish the H2S level.

    Reply
    • Teodor Costachioiu on June 25, 2019 9:42 pm

      Hi Sorin,

      You mention opensensebox. Shall I understand you plan to send data to https://opensensemap.org/? If so, it’s easier to do it with ESP8266 Thing from Sparkfun.

      Reply

Leave A Reply Cancel Reply

Latest posts
January 15, 2023

A pretty text box for Blogger posts

January 15, 2023

New blog section: beginners’ corner

January 15, 2023

Cleaning unused images from blogs hosted on Blogger

Categories
  • Beginners' corner
  • Electronics projects
    • ESP8266
    • Arduino projects
    • IoT
    • 8-bit PIC projects
    • Raspberry PI
    • PIC32 projects
    • Robots
  • Arduino libraries
  • Reviews
    • Tools & equipment
    • Development boards
    • IoT
    • Industrial Arduino
  • Blogger / Blogspot
  • Tutorials
  • Casual stuff
Popular posts
Arduino Uno 4-20mA communication using 4-20mA R click and 4-20mA T click boards from MikroElektronika: MIKROE-1296, MIKROE-1387, Uno Click Shield
August 17, 2016

4-20mA current loop Arduino tutorial Part I: hardware

ESP8266 Thing Dev from Sparkfun
May 15, 2019

ESP8266 – running on battery power

ECG click on Arduino Uno
December 5, 2016

ECG click: Arduino IDE code examples

WiFi3 Click - esp8266 in click board format
March 15, 2017

ESP8266: AT mode webserver tutorial

Honeywell HPMA115S0-XXX particle sensor
November 23, 2017

Arduino: measuring PM2.5 and PM10 with Honeywell HPMA115S0

Copyright © 2023 Teodor Costachioiu

Type above and press Enter to search. Press Esc to cancel.