Skip to content

Commit

Permalink
Merge pull request #20 from EnviroDIY/develop
Browse files Browse the repository at this point in the history
Pull Y551 & Y560 from `develop` to `master`
  • Loading branch information
aufdenkampe authored Dec 15, 2021
2 parents 19b4f6a + 18bbcd2 commit 416fa28
Show file tree
Hide file tree
Showing 12 changed files with 114 additions and 96 deletions.
Binary file removed doc/Y550-COD-UV254-1.5_ModbusInstruction-en.pdf
Binary file not shown.
Binary file added doc/Y551-UV254-COD_Modbus_v2020-05-11.pdf
Binary file not shown.
Binary file added doc/Y551-UV254-COD_UserManual_v1.0.pdf
Binary file not shown.
Binary file added doc/Y560-NH4_Modbus_v2020-05-11.pdf
Binary file not shown.
Binary file added doc/Y560-NH4_UserManual_v1.0.pdf
Binary file not shown.
82 changes: 19 additions & 63 deletions examples/GetValues-TimingTest/GetValues-TimingTest.ino
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Modified from `GetValues.ino` to test optimal timing for the sensor timing setti
used by the ModularSensors library, similar to:
#define Y511_WARM_UP_TIME_MS 8000 //
#define Y511_STABILIZATION_TIME_MS 40000 //
#define Y511_MEASUREMENT_TIME_MS 4000 //
#define Y511_MEASUREMENT_TIME_MS 4000 //
*****************************************************************************/

// ---------------------------------------------------------------------------
Expand All @@ -29,10 +29,10 @@ used by the ModularSensors library, similar to:
// ---------------------------------------------------------------------------

// Define the sensor type
yosemitechModel model = Y511; // The sensor model number
yosemitechModel model = Y560; // The sensor model number

// Define the sensor's modbus address
byte modbusAddress = 0x03; // The sensor's modbus address, or SlaveID
byte modbusAddress = 0x01; // The sensor's modbus address, or SlaveID
// Yosemitech ships sensors with a default ID of 0x01.

// Define pin number variables
Expand Down Expand Up @@ -86,7 +86,9 @@ void setup()
// Turbidity and pH within 500ms
// Conductivity doesn't respond until 1.15-1.2s
Serial.println("Waiting for sensor and adapter to be ready.");
delay(1500);

// Warmup time for sensor to respond to modbus commands
delay(200);

// Get the sensor's hardware and software version
Serial.println("Getting sensor version.");
Expand Down Expand Up @@ -133,7 +135,7 @@ void setup()

// Get/set the sensor brush status (for sensors with brushes).
// NOTE: Not implemented for Y4000
if (model == Y511 || model == Y513 || model == Y514)
if (model == Y511 || model == Y513 || model == Y514 || model == Y551 || model == Y560)
{
// Check the wiper timing
Serial.println("Getting sensor cleaning interval.");
Expand All @@ -155,61 +157,10 @@ void setup()
if (success) Serial.println(" Measurements started.");
else Serial.println(" Failed to start measuring!");

// The modbus manuals recommend the following warm-up times between starting
// measurements and requesting values :
// 2 s for whipered chlorophyll
// 20 s for turbidity
// 10 s for conductivity

// On wipered (self-cleaning) models, the brush immediately activates after
// getting power and takes approximately 10-11 seconds to finish. No
// readings should be taken during this time.

// pH returns values after ~4.5 seconds
// Conductivity returns values after about 2.4 seconds, but is not stable
// until ~10 seconds.
// DO does not return values until ~8 seconds
// Turbidity takes ~22 seconds to get stable values.
Serial.println("Allowing sensor to stabilize..");
for (int i = 10; i > 0; i--)
{
Serial.print(i);
delay (250);
Serial.print(".");
delay (250);
Serial.print(".");
delay (250);
Serial.print(".");
delay (250);
}
Serial.println("\n");
// Skip stabilization and brush cycle to test for timing

if (model == Y511 || model == Y513 || model == Y514 || model == Y4000) // Y4000 activates brush when powered on
{
// We'll run the brush once in the middle of this
Serial.println("Activating brush.");
success = sensor.activateBrush();
if (success) Serial.println(" Brush activated.");
else Serial.println(" Failed to activate brush!");
}

if (model == Y511 || model == Y513 || model == Y514 || model == Y510 || model == Y4000)
{
Serial.println("Continuing to stabilize..");
for (int i = 12; i > 0; i--)
{
Serial.print(i);
delay (250);
Serial.print(".");
delay (250);
Serial.print(".");
delay (250);
Serial.print(".");
delay (250);
}
Serial.println("\n");
}

// Print table headers
switch (model)
{
case Y4000:
Expand All @@ -224,13 +175,15 @@ void setup()
}
default:
{
Serial.print("Time(ms) ");
Serial.print("Temp(°C) ");
Serial.print(sensor.getParameter());
Serial.print("(");
Serial.print(sensor.getUnits());
Serial.print(")");
if (model == Y532 || model == Y504) Serial.print(" Value");
//Serial.print(" Millis");
if (model == Y551) Serial.print(" Turbidity (NTU)");
if (model == Y560) Serial.print(" pH");
Serial.println();
}
}
Expand Down Expand Up @@ -276,16 +229,17 @@ void loop()
{
float parmValue, tempValue, thirdValue = -9999;
sensor.getValues(parmValue, tempValue, thirdValue);

Serial.print(millis());
Serial.print(" ");
Serial.print(tempValue);
Serial.print(" ");
Serial.print(parmValue);
if (model == Y532 || model == Y504)
if (model == Y532 || model == Y504 || model == Y551 || model == Y560)
{
Serial.print(" ");
Serial.print(thirdValue);
}
// Serial.print(" ");
// Serial.print(millis());
Serial.println();
}
}
Expand All @@ -298,12 +252,14 @@ void loop()
// 2 s for turbidity
// 3 s for conductivity
// 1 s for DO
// 2 s for COD
// 2 s for Ammonium

// The turbidity and DO sensors appear return new readings about every 1.6 seconds.
// The pH sensor returns new readings about every 1.8 seconds.
// The conductivity sensor only returns new readings about every 2.7 seconds.

// The temperature sensors can take readings much more quickly. The same results
// can be read many times from the registers between the new sensor readings.
delay(5000);
delay(500);
}
24 changes: 15 additions & 9 deletions examples/GetValues/GetValues.ino
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ Yosemitech modbus sensor.
// ---------------------------------------------------------------------------

// Define the sensor type
yosemitechModel model = Y511; // The sensor model number
yosemitechModel model = Y560; // The sensor model number

// Define the sensor's modbus address
byte modbusAddress = 0x03; // The sensor's modbus address, or SlaveID
byte modbusAddress = 0x01; // The sensor's modbus address, or SlaveID
// Yosemitech ships sensors with a default ID of 0x01.

// Define pin number variables
Expand Down Expand Up @@ -127,7 +127,7 @@ void setup()

// Get/set the sensor brush status (for sensors with brushes).
// NOTE: Not implemented for Y4000
if (model == Y511 || model == Y513 || model == Y514)
if (model == Y511 || model == Y513 || model == Y514 || model == Y551 || model == Y560)
{
// Check the wiper timing
Serial.println("Getting sensor cleaning interval.");
Expand All @@ -154,6 +154,9 @@ void setup()
// 2 s for whipered chlorophyll
// 20 s for turbidity
// 10 s for conductivity
// 2 s for COD
// 20 s for Ammonium, due to 15 s to complete a brush cycle


// On wipered (self-cleaning) models, the brush immediately activates after
// getting power and takes approximately 10-11 seconds to finish. No
Expand All @@ -178,7 +181,8 @@ void setup()
}
Serial.println("\n");

if (model == Y511 || model == Y513 || model == Y514 || model == Y4000) // Y4000 activates brush when powered on
if (model == Y511 || model == Y513 || model == Y514 || model == Y551 || model == Y560 || model == Y4000)
// Y4000 activates brush when powered on
{
// We'll run the brush once in the middle of this
Serial.println("Activating brush.");
Expand All @@ -187,7 +191,7 @@ void setup()
else Serial.println(" Failed to activate brush!");
}

if (model == Y511 || model == Y513 || model == Y514 || model == Y510 || model == Y4000)
if (model == Y511 || model == Y513 || model == Y514 || model == Y551 || model == Y560 || model == Y4000 || model == Y510)
{
Serial.println("Continuing to stabilize..");
for (int i = 12; i > 0; i--)
Expand All @@ -204,6 +208,7 @@ void setup()
Serial.println("\n");
}

// Print table headers
switch (model)
{
case Y4000:
Expand All @@ -224,7 +229,8 @@ void setup()
Serial.print(sensor.getUnits());
Serial.print(")");
if (model == Y532 || model == Y504) Serial.print(" Value");
//Serial.print(" Millis");
if (model == Y551) Serial.print(" Turbidity (NTU)");
if (model == Y560) Serial.print(" pH");
Serial.println();
}
}
Expand Down Expand Up @@ -273,13 +279,11 @@ void loop()
Serial.print(tempValue);
Serial.print(" ");
Serial.print(parmValue);
if (model == Y532 || model == Y504)
if (model == Y532 || model == Y504 || model == Y551 || model == Y560)
{
Serial.print(" ");
Serial.print(thirdValue);
}
// Serial.print(" ");
// Serial.print(millis());
Serial.println();
}
}
Expand All @@ -292,6 +296,8 @@ void loop()
// 2 s for turbidity
// 3 s for conductivity
// 1 s for DO
// 2 s for COD
// 2 s for Ammonium

// The turbidity and DO sensors appear return new readings about every 1.6 seconds.
// The pH sensor returns new readings about every 1.8 seconds.
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "YosemitechModbus",
"version": "0.2.5",
"version": "0.3.0",
"keywords": "Yosemitech, Modbus, communication, bus, sensor",
"description": "Arduino library for communication with Yosemitech sensors via Modbus.",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=YosemitechModbus
version=0.2.5
version=0.3.0
author=Sara Damiano <[email protected]>
maintainer=Sara Damiano <[email protected]>
sentence=Arduino library for communication with Yosemitech sensors via Modbus.
Expand Down
50 changes: 39 additions & 11 deletions src/YosemitechModbus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ String yosemitech::getModel(void)
case Y520: {return "Y520";}
case Y532: {return "Y532";}
case Y533: {return "Y533";}
case Y550: {return "Y550";}
case Y551: {return "Y551";}
case Y560: {return "Y560";}
case Y4000: {return "Y4000";}
default: {return "Unknown";}
}
Expand All @@ -66,7 +67,8 @@ String yosemitech::getParameter(void)
case Y520: {return "Conductivity";}
case Y532: {return "pH";}
case Y533: {return "ORP";}
case Y550: {return "COD";}
case Y551: {return "COD";}
case Y560: {return "Ammonium";}
case Y4000: {return "DO, Turb, Cond, pH, Temp, ORP, Chl, BGA";}
default: {return "Unknown";}
}
Expand All @@ -86,9 +88,10 @@ String yosemitech::getUnits(void)
case Y514: {return "µg/L";}
case Y516: {return "ppb";}
case Y520: {return "mS/cm";}
case Y532: {return "pH";}
case Y532: {return "pH, mV";}
case Y533: {return "mV";}
case Y550: {return "mg/L";}
case Y551: {return "mg/L, NTU";}
case Y560: {return "mg/L";}
case Y4000: {return "mg/L, NTU, mS/cm, pH, °C, mV, µg/L, µg/L";}
default: {return "Unknown";}
}
Expand Down Expand Up @@ -150,6 +153,8 @@ String yosemitech::getSerialNumber(void)
if (modelSS == 29) _model = Y511; // 29 means self-cleaning turbidity sensor
if (modelSS == 48) _model = Y514; // 48 means chlorophyll
if (modelSS == 43) _model = Y532; // 43 must mean pH
if (modelSS == 47) _model = Y551; // 47 must mean COD
if (modelSS == 68) _model = Y560; // 68 must mean Ammonium
if (modelSS == 38) _model = Y4000; // 38 must mean MultiParameter Sonde
}

Expand Down Expand Up @@ -205,10 +210,12 @@ bool yosemitech::startMeasurement(void)
if (respSize == 8 && modbus.responseBuffer[0] == _slaveID) return true;
else return false;
}
// Y532 (pH) or Y533 (ORP) do not require Start/Stop functions. They are not listed in the Y532/Y533 Modbus Manual.
// Y532 (pH), Y533 (ORP), Y560 (Ammonium) ion selective elctrodes do not
// require Start/Stop functions, which are not listed in their Modbus Manuals.
// However, Start/Stop functions are required to get these to work in ModularSensors.
case Y532:
case Y533:
case Y560:
{
return true;
}
Expand All @@ -233,10 +240,12 @@ bool yosemitech::stopMeasurement(void)
{
switch (_model)
{
// Y532 (pH) or Y533 (ORP) do not require Start/Stop functions. They are not listed in the Y532/Y533 Modbus Manual.
// Y532 (pH), Y533 (ORP), Y560 (Ammonium) ion selective elctrodes do not
// require Start/Stop functions, which are not listed in their Modbus Manuals.
// However, Start/Stop functions are required to get these to work in ModularSensors.
case Y532:
case Y533:
case Y560:
{
return true;
}
Expand All @@ -260,10 +269,11 @@ bool yosemitech::stopMeasurement(void)


// This gets values back from the sensor
// All sensors but pH, return two 32-bit float values beginning in holding register
// 0x2600 (9728), where the parameter value is in the first two register and the
// Most sensors (other than Y4000 Sonde; Y551 COD; Y532 pH; or Y533 ORP),
// return two 32-bit float values beginning in holding register 0x2600 (9728),
// where the parameter value is in the first two register and the
// temperature in celsius is in the next two registers. For some sensors
// (Y520/Conductivity and Y514/Chlorophyll) this followed by an error code.
// (Y520 Conductivity and Y514 Chlorophyll) this followed by an error code.
// The pH sensor returns the pH as a 32-bit float beginning in holding register
// 0x2800 (10240) and the temperature in celsuis as a separate 32-bit float
// beginning in holding register 0x2400 (9216). The pH sensor can also return
Expand All @@ -288,7 +298,25 @@ bool yosemitech::getValues(float &parmValue, float &tempValue, float &thirdValue
// wants the sonde results, they should give 8 values to put them in.
return false;
}
case Y550: // Y550 COD, with turbidity
// Y560 Ammonium
case Y560:
{
// Y560 Ammonium has many parameters, but this will return the
// three most important (NH4_N, Temp, pH). Other options are below.
if (modbus.getRegisters(0x03, 0x2600, 4)) // default register gives potential & pH
{
// pH in registers 3-4 of 4 (starting in byte 7 of total response frame)
thirdValue = modbus.float32FromFrame(littleEndian, 7);
// Get temperature at register 0x2400. 32 bits = 4 bytes = 2 registers
tempValue = modbus.float32FromRegister(0x03, 0x2400, littleEndian);
// Get NH3_N (mg/L) at register 0x2800
parmValue = modbus.float32FromRegister(0x03, 0x2800, littleEndian);
errorCode = 0x00; // No errors
return true;
}
break;
}
case Y551: // Y551 COD, with turbidity
{
if (modbus.getRegisters(0x03, 0x2600, 5))
{
Expand Down Expand Up @@ -406,7 +434,7 @@ bool yosemitech::getValues(float &parmValue, float &tempValue, float &thirdValue
}
break;
}
// Everybody else other than Y550 COD; Y532 (pH) or Y533 (ORP); Y502 & Y504 (DO)
// Everybody else other than Y4000 Sonde; Y551 COD; Y532 (pH); Y533 (ORP); Y502 & Y504 (DO)
default:
{
if (modbus.getRegisters(0x03, 0x2600, 5))
Expand Down
Loading

2 comments on commit 416fa28

@neilh10
Copy link

@neilh10 neilh10 commented on 416fa28 Feb 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An FYI observation - for an .h its often useful to mark something as superseded than remove it.
I've just spent 2hrs chasing down a compile issue for src/YosemitechModbus.h where the Y550 was removed and causing the tip version of src/YosemitechModbus.cpp to fail.
The solution is to reference for it to work https://github.com/EnviroDIY/YosemitechModbus#v0.2.5

@aufdenkampe
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@neilh10, OK. It's clear that I messed that up. I'm really sorry about that. I really didn't think anyone had ever used the Y550, but I see that my shortcut was a mistake.

I'll work on a bug fix.

Please sign in to comment.