Home › Forums › Environmental Sensors › Please Help! Meter CTD Gen2 being blocked by Yosemitech 511-a
Tagged: -9999, CTD, Gen2, interference, Meter, yosemitech
- This topic has 9 replies, 4 voices, and was last updated 2023-12-15 at 1:48 PM by mbullard.
-
AuthorPosts
-
-
2023-01-26 at 9:39 PM #17563
Hi everyone,
This problem has been causing me trouble for nearly a year, but it has become unworkable with installation of Gen2 Meter CTD sensors.
My problem: Meter CTD (SDI12) and Yosemitech 511-a Turbidity (MODBUS) sensors seem to interfere with each other causing the CTD to sporadically drop out return -9999 values. This only occurred at some sites (around 4 out of 10) and all coding and sensors was identical.
This was workable with the Gen1 sensor as the dropouts were less frequent. However, the Gen2 sensor has interference with every single reading making it impossible to run these two sensors off the same Mayfly board. If I remove the MODBUS wing, the CTD reads perfectly. If I replace the MODBUS wing, the CTD reads -9999 values while the 511-a returns perfect turbidity and temperature measurements.
What I think is Going On: I think the return of information from the CTD is being over-ridden by Turbidity information. The Gen1 CTD seemed to have a faster response time (https://www.envirodiy.org/topic/hydros-21-decagon-ctd-reading-error/#post-17066) which meant that the modularsensors package was amended from a wait time of 500 milliseconds to 1000 milliseconds to accommodate the Gen 2. I wonder if this longer wait time may leave the line open a bit longer which allows information from the Turbidity sensor to creep in. Perhaps my previous problems with Gen 1 sensors were due to variance in the response times of each sensor?
In very non-technical terms, I envision it like this:
The Mayfly says ‘time for a sample, information please’. The Gen 1 CTD would typically reply first ‘here’s some numbers’, followed by the same answer from the turbidity sensor. Sometimes these messages would overlap (only at some sites – perhaps due to imperfections in the sensors?) making the message garbled and only the turbidity numbers clear.
Now, with the update of modularsensors to 0.33.3, I think the Gen 2 CTD and the Yosemitech 511-a respond at the same time (i.e., the CTD responds slightly later) making every message garbled. The turbidity sensor obviously has a louder voice so only those numbers come back.
<b>Towards a Solution: </b>I am pulling my hair out trying to solve this, but I think I need help from our experts @shicks and @srgdamiano.
Is there a way to get modular sensors to ask the CTD for data and wait until the CTD responds before asking the 511-a for data? I’m wondering if splitting these calls up may solve my issue.
I’m open to anyone else’s opinion as well.
Thanks in advance for your help.
James
Previous posts about this problem can be read here:
https://www.envirodiy.org/topic/linking-two-mayfly-boards-together/
https://www.envirodiy.org/topic/hydros-ctd-10-regularly-dropping-out-9999/
-
2023-01-27 at 11:11 AM #17564
The ModularSensors library is running the SDI-12 sensors in “concurrent” mode and the modbus communication only happens when initiated by the logger. So the two sensors really should not be trying to talk to the logger at the same time. ModularSensors first asks each sensor to start taking a reading, then goes back and asks each one for its results in the order that they’re expected to be ready. You can try using the build flag
-D MS_SDI12_NON_CONCURRENT
in your PlatformIO.ini. That will tell it to start a reading and then wait the full time for a reading to finish before the starting the next sensor. Note that the flag only affects SDI-12 sensors.If the same code is working in some places but not in others, I would suspect the problem is electrical, not code. That is, some combination of instantaneous voltage instabilities when both sensors are working is garbling the communication. The SDI-12 library is “bit-banged” so it’s very weak to interference. Shannon or Neil may have better ideas on ways you could try to electrically isolate the sensors from each other.
-
2023-01-27 at 5:31 PM #17566
We’ve been using Y-511a sensors together with Gen 2 Hydros21 CTD sensors and have had no problems with communication, however we’re using our own modbus adapter (based on a MAX13412 chip) instead of the Neil’s modbus wing. As Sara said, the sensors shouldn’t be talking the the Mayfly at the same time since the Y-511 has a 40-second warmup time, followed by a 8-second sampling time, so the Mayfly doesn’t hear anything from the Y-511a for almost a minute after it is powered up. I’m not sure if the modbus wing you’re using has a level-shifter on the SDI-12 data line, but we found that most level-shifting circuits cause inconsistent communication with the Meter Group sensors, probably because the logic high level of their sensors is only 3.6v, which in our experience is safe enough to connect directly to the Mayfly’s digital input.
-
2023-01-29 at 11:06 PM #17569
Thank you both for your reply. Okay, so it seems that I may be barking up the wrong tree with that one. I will try Sara’s build flag to see if that works, but I’m not holding my breath.
I have my SDI12 jumper pins for the CTS set on 5v. Could this be the problem? For some reason I couldn’t get the Gen1 CTD’s to work at 3.3v, but they worked at 5v so I set them all as that.
FYI, I am using the modbus wing-shield here:
https://github.com/EnviroDIY/Mayfly-Modbus-Wing/tree/master/Modbus-Mayfly_WingShield
Thanks again for your help.
James
-
2023-01-30 at 2:58 PM #17573
-
2023-01-30 at 4:20 PM #17574
Here’s my code that has been successfully working on a Mayfly v1.1 RevB board, with a Hydros21 connected to the D4-7 Grove jack (with jumper set to the switched 3v setting) and a Y-511a and our custom RS485 adapter connected to the D5-6 jack and an external (non-Mayfly) 12v source supplying power for the Y-511a.
Arduino123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406// ==========================================================================// Defines for the Arduino IDE// NOTE: These are ONLY needed to compile with the Arduino IDE.// If you use PlatformIO, you should set these build flags in your// platformio.ini// ==========================================================================/** Start [defines] */#ifndef TINY_GSM_RX_BUFFER#define TINY_GSM_RX_BUFFER 64#endif#ifndef TINY_GSM_YIELD_MS#define TINY_GSM_YIELD_MS 2#endif/** End [defines] */// ==========================================================================// Include the libraries required for any data logger// ==========================================================================/** Start [includes] */// The Arduino library is needed for every Arduino program.#include <Arduino.h>// EnableInterrupt is used by ModularSensors for external and pin change// interrupts and must be explicitly included in the main program.#include <EnableInterrupt.h>// Include the main header for ModularSensors#include <ModularSensors.h>/** End [includes] */#include <AltSoftSerial.h>AltSoftSerial altSoftSerial(6,5);#define modbusSerial altSoftSerial // For AltSoftSerial// ==========================================================================// Data Logging Options// ==========================================================================/** Start [logging_options] */// The name of this program fileconst char* sketchName = "DRWI_SIM7080LTE.ino";// Logger ID, also becomes the prefix for the name of the data file on SD cardconst char* LoggerID = "Logger_XXXXXX";// How frequently (in minutes) to log dataconst uint8_t loggingInterval = 10;// Your logger's timezone.const int8_t timeZone = -5; // Eastern Standard Time// NOTE: Daylight savings time will not be applied! Please use standard time!// Set the input and output pins for the logger// NOTE: Use -1 for pins that do not applyconst int32_t serialBaud = 57600; // Baud rate for debuggingconst int8_t greenLED = 8; // Pin for the green LEDconst int8_t redLED = 9; // Pin for the red LEDconst int8_t buttonPin = 21; // Pin for debugging mode (ie, button pin)const int8_t wakePin = 31; // MCU interrupt/alarm pin to wake from sleep// Mayfly 0.x D31 = A7// Set the wake pin to -1 if you do not want the main processor to sleep.// In a SAMD system where you are using the built-in rtc, set wakePin to 1const int8_t sdCardPwrPin = -1; // MCU SD card power pinconst int8_t sdCardSSPin = 12; // SD card chip select/slave select pinconst int8_t sensorPowerPin = 22; // MCU pin controlling main sensor power/** End [logging_options] */// ==========================================================================// ==========================================================================// Wifi/Cellular Modem Options// ==========================================================================/** Start [sim_com_sim7080] */// For almost anything based on the SIMCom SIM7080G#include <modems/SIMComSIM7080.h>// Create a reference to the serial port for the modemHardwareSerial& modemSerial = Serial1; // Use hardware serial if possibleconst int32_t modemBaud = 9600; // SIM7080 does auto-bauding by default, but// for simplicity we set to 9600// Modem Pins - Describe the physical pin connection of your modem to your board// NOTE: Use -1 for pins that do not applyconst int8_t modemVccPin = 18;// MCU pin controlling modem power --- Pin 18 is the power enable pin for the// bee socket on Mayfly v1.0, use -1 if using Mayfly 0.5b or if the bee socket// is constantly powered (ie you changed SJ18 on Mayfly 1.x to 3.3v)const int8_t modemStatusPin = 19; // MCU pin used to read modem statusconst int8_t modemSleepRqPin = 23; // MCU pin for modem sleep/wake requestconst int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem// status// Network connection informationconst char* apn ="hologram"; // APN connection name, typically Hologram unless you have a// different provider's SIM card. Change as needed// Create the modem objectSIMComSIM7080 modem7080(&modemSerial, modemVccPin, modemStatusPin,modemSleepRqPin, apn);// Create an extra reference to the modem by a generic nameSIMComSIM7080 modem = modem7080;/** End [sim_com_sim7080] */// ==========================================================================// Using the Processor as a Sensor// ==========================================================================/** Start [processor_sensor] */#include <sensors/ProcessorStats.h>// Create the main processor chip "sensor" - for general metadataconst char* mcuBoardVersion = "v1.1";ProcessorStats mcuBoard(mcuBoardVersion);/** End [processor_sensor] */// ==========================================================================// Maxim DS3231 RTC (Real Time Clock)// ==========================================================================/** Start [ds3231] */#include <sensors/MaximDS3231.h>// Create a DS3231 sensor objectMaximDS3231 ds3231(1);/** End [ds3231] */// ==========================================================================// Sensirion SHT4X Digital Humidity and Temperature Sensor// Built in on Mayfly 1.x// ==========================================================================/** Start [sensirion_sht4x] */#include <sensors/SensirionSHT4x.h>// NOTE: Use -1 for any pins that don't apply or aren't being used.const int8_t SHT4xPower = sensorPowerPin; // Power pinconst bool SHT4xUseHeater = true;// Create an Sensirion SHT4X sensor objectSensirionSHT4x sht4x(SHT4xPower, SHT4xUseHeater);/** End [sensirion_sht4x] */// ==========================================================================// Meter Hydros 21 Conductivity, Temperature, and Depth Sensor// ==========================================================================/** Start [hydros21] */#include <sensors/MeterHydros21.h>const char* hydrosSDI12address = "1"; // The SDI-12 Address of the Hydros 21const uint8_t hydrosNumberReadings = 6; // The number of readings to averageconst int8_t SDI12Power = sensorPowerPin; // Power pin (-1 if unconnected)const int8_t SDI12Data = 7; // The SDI12 data pin// Create a Meter Hydros 21 sensor objectMeterHydros21 hydros(*hydrosSDI12address, SDI12Power, SDI12Data,hydrosNumberReadings);/** End [hydros21] *///----------------------------------------------------------------------------#include <sensors/YosemitechY511.h>// NOTE: Extra hardware and software serial ports are created in the "Settings// for Additional Serial Ports" sectionbyte y511ModbusAddress = 0x01; // The modbus address of the Y511const int8_t y511AdapterPower = sensorPowerPin; // RS485 adapter power pin (-1 if unconnected)const int8_t y511SensorPower = 22; // Sensor power pinconst int8_t y511EnablePin = -1; // Adapter RE/DE pin (-1 if not applicable)const uint8_t y511NumberReadings = 5;// The manufacturer recommends averaging 10 readings, but we take 5 to minimize// power consumption// Create a Y511-A Turbidity sensor objectYosemitechY511 y511(y511ModbusAddress, modbusSerial, y511AdapterPower,y511SensorPower, y511EnablePin, y511NumberReadings);//---------------------------------------------------------// ==========================================================================// Creating the Variable Array[s] and Filling with Variable Objects// ==========================================================================/** Start [variable_arrays] */Variable* variableList[] = {new MeterHydros21_Cond(&hydros),new MeterHydros21_Depth(&hydros),new MeterHydros21_Temp(&hydros),new YosemitechY511_Turbidity(&y511),new YosemitechY511_Temp(&y511),new ProcessorStats_Battery(&mcuBoard), // Battery voltage (EnviroDIY_Mayfly_Batt)new SensirionSHT4x_Humidity(&sht4x), // Relative humidity (Sensirion_SHT40_Humidity)new SensirionSHT4x_Temp(&sht4x), // Temperature (Sensirion_SHT40_Temperature)new Modem_SignalPercent(&modem), // Percent full scale (EnviroDIY_LTEB_SignalPercent)};// All UUID's, device registration, and sampling feature information can be// pasted directly from Monitor My Watershed.// To get the list, click the "View token UUID list" button on the upper right// of the site page.// *** CAUTION --- CAUTION --- CAUTION --- CAUTION --- CAUTION ***// Check the order of your variables in the variable list!!!// Be VERY certain that they match the order of your UUID's!// Rearrange the variables in the variable list ABOVE if necessary to match!// Do not change the order of the variables in the section below.// *** CAUTION --- CAUTION --- CAUTION --- CAUTION --- CAUTION ***// Replace all of the text in the following section with the UUID array from// MonitorMyWatershed// --------------------- Beginning of Token UUID List ---------------------const char* UUIDs[] = // UUID array for device sensors{"12345678-abcd-1234-ef00-1234567890ab", // Specific conductance (Meter_Hydros21_Cond)"12345678-abcd-1234-ef00-1234567890ab", // Water depth (Meter_Hydros21_Depth)"12345678-abcd-1234-ef00-1234567890ab", // Temperature (Meter_Hydros21_Temp)"12345678-abcd-1234-ef00-1234567890ab", // Turbidity (YosemiTech_Y511-A_Turbidity)"12345678-abcd-1234-ef00-1234567890ab", // Temperature (YosemiTech_Y511-A_Temp)"12345678-abcd-1234-ef00-1234567890ab", // Battery voltage (EnviroDIY_Mayfly_Batt)"12345678-abcd-1234-ef00-1234567890ab", // Relative humidity (Sensirion_SHT40_Humidity)"12345678-abcd-1234-ef00-1234567890ab", // Temperature (Sensirion_SHT40_Temperature)"12345678-abcd-1234-ef00-1234567890ab", // Percent full scale (EnviroDIY_LTEB_SignalPercent)};const char* registrationToken = "12345678-abcd-1234-ef00-1234567890ab"; // Device registration tokenconst char* samplingFeature = "12345678-abcd-1234-ef00-1234567890ab"; // Sampling feature UUID// ----------------------- End of Token UUID List -----------------------// Count up the number of pointers in the arrayint variableCount = sizeof(variableList) / sizeof(variableList[0]);// Create the VariableArray objectVariableArray varArray(variableCount, variableList, UUIDs);/** End [variable_arrays] */// ==========================================================================// The Logger Object[s]// ==========================================================================/** Start [loggers] */// Create a new logger instanceLogger dataLogger(LoggerID, loggingInterval, &varArray);/** End [loggers] */// ==========================================================================// Creating Data Publisher[s]// ==========================================================================/** Start [publishers] */// Create a data publisher for the Monitor My Watershed/EnviroDIY POST endpoint#include <publishers/EnviroDIYPublisher.h>EnviroDIYPublisher EnviroDIYPOST(dataLogger, &modem.gsmClient,registrationToken, samplingFeature);/** End [publishers] */// ==========================================================================// Working Functions// ==========================================================================/** Start [working_functions] */// Flashes the LED's on the primary boardvoid greenredflash(uint8_t numFlash = 4, uint8_t rate = 75) {for (uint8_t i = 0; i < numFlash; i++) {digitalWrite(greenLED, HIGH);digitalWrite(redLED, LOW);delay(rate);digitalWrite(greenLED, LOW);digitalWrite(redLED, HIGH);delay(rate);}digitalWrite(redLED, LOW);}// Reads the battery voltage// NOTE: This will actually return the battery level from the previous update!float getBatteryVoltage() {if (mcuBoard.sensorValues[0] == -9999) mcuBoard.update();return mcuBoard.sensorValues[0];}// ==========================================================================// Arduino Setup Function// ==========================================================================/** Start [setup] */void setup() {// Start the primary serial connectionSerial.begin(serialBaud);// Print a start-up note to the first serial portSerial.print(F("Now running "));Serial.print(sketchName);Serial.print(F(" on Logger "));Serial.println(LoggerID);Serial.println();Serial.print(F("Using ModularSensors Library version "));Serial.println(MODULAR_SENSORS_VERSION);Serial.print(F("TinyGSM Library version "));Serial.println(TINYGSM_VERSION);Serial.println();// Start the serial connection with the modemmodemSerial.begin(modemBaud);// Set up pins for the LED'spinMode(greenLED, OUTPUT);digitalWrite(greenLED, LOW);pinMode(redLED, OUTPUT);digitalWrite(redLED, LOW);// Blink the LEDs to show the board is on and starting upgreenredflash();pinMode(20, OUTPUT); // for proper operation of the onboard flash memory// chip's ChipSelect (Mayfly v1.0 and later)altSoftSerial.begin(9600);modbusSerial.begin(9600);// Set the timezones for the logger/data and the RTC// Logging in the given time zoneLogger::setLoggerTimeZone(timeZone);// It is STRONGLY RECOMMENDED that you set the RTC to be in UTC (UTC+0)Logger::setRTCTimeZone(0);// Attach the modem and information pins to the loggerdataLogger.attachModem(modem);modem.setModemLED(modemLEDPin);dataLogger.setLoggerPins(wakePin, sdCardSSPin, sdCardPwrPin, buttonPin,greenLED);// Begin the loggerdataLogger.begin();// Note: Please change these battery voltages to match your battery// Set up the sensors, except at lowest battery levelif (getBatteryVoltage() > 3.4) {Serial.println(F("Setting up sensors..."));varArray.setupSensors();}/** Start [setup_esp] */for (int8_t ntries = 5; ntries; ntries--) {// This will also verify communication and set up the modemif (modem.modemWake()) break;// if that didn't work, try changing baud ratemodemSerial.begin(115200);modem.gsmModem.sendAT(GF("+UART_DEF=9600,8,1,0,0"));modem.gsmModem.waitResponse();modemSerial.end();modemSerial.begin(9600);}/** End [setup_esp] */// Sync the clock if it isn't valid or we have battery to spareif (getBatteryVoltage() > 3.55 || !dataLogger.isRTCSane()) {// Synchronize the RTC with NIST// This will also set up the modemdataLogger.syncRTC();}// Create the log file, adding the default header to it// Do this last so we have the best chance of getting the time correct and// all sensor names correct// Writing to the SD card can be power intensive, so if we're skipping// the sensor setup we'll skip this too.if (getBatteryVoltage() > 3.4) {Serial.println(F("Setting up file on SD card"));dataLogger.turnOnSDcard(true); // true = wait for card to settle after power updataLogger.createLogFile(true); // true = write a new headerdataLogger.turnOffSDcard(true); // true = wait for internal housekeeping after write}// Call the processor sleepSerial.println(F("Putting processor to sleep\n"));dataLogger.systemSleep();}/** End [setup] */// ==========================================================================// Arduino Loop Function// ==========================================================================/** Start [loop] */// Use this short loop for simple data logging and sendingvoid loop() {// Note: Please change these battery voltages to match your battery// At very low battery, just go back to sleepif (getBatteryVoltage() < 3.4) {dataLogger.systemSleep();}// At moderate voltage, log data but don't send it over the modemelse if (getBatteryVoltage() < 3.55) {dataLogger.logData();}// If the battery is good, send the data to the worldelse {dataLogger.logDataAndPublish();}}/** End [loop] */ -
2023-02-01 at 10:40 PM #17581
Hi @shicks and @srgdamiano. You’re not going to believe it but the addition of the build flag below has fixed my problem, at least for the Gen2 sensors.
1-D MS_SDI12_NON_CONCURRENTI am certain it is this build flag and not the voltage pin (previously set to 5v) because I uploaded my script prior to switching the voltage pin over and it suddenly sprang into life. I have subsequently changed the pin over to 3.3v for good measure.
I will keep you updated.
James
-
2023-12-14 at 10:39 AM #18239
(I am placing this comment here rather than start a new topic because of similarities)
We have two stations that developed the same problem in August of 2023. One station is here: https://monitormywatershed.org/sites/GVWA%20107/
Both were V1.0 Mayfly with the LTE Bee, Hydros21 CTD and Yosemitech 511-a Turbidity sensors with the Modbus-Mafly-Wingshield . The Hydros21 is using the new 500 and 1000 ms timings and the voltage jumper is set to 3.3 volts. The wingshield is getting 5 volts switched from the header (pin 11) and using the U3V12F9 boost regulator.
First symptoms in August were the CTD returning -9999 and -9991, which are bad measurement and low voltage error codes.
We replaced the V1.0 boards with V1.1 rev B boards this week but the problems persists. However, disconnecting one or the other of the sensors results in normal operation for the connected sensor. Is it likely that there is insufficient power getting to the sensors during sensor operation? If so, could I try:
- getting 12 volt for the 511-a from pin 9 on the header (now that the 12 volt boost has been upgraded) and removing the U3V12F9?
- the above, but also altering SJ25 to get 9 volts?
- change SJ27 and monitor for voltage sag?
It is always possible to run a jumper from the LIPO header to a second board as a workaround.
Thanks for any insights,
Mike
-
2023-12-14 at 6:46 PM #18243
The Yosemitech Y-511A needs 12v to operate, so it won’t be happy if you modify the Mayfly jumper to set the 12v output to 9v. I’m not familiar with the operation of the modbus wing you’re using so I can’t comment on its operation, but we have a new modbus adapter board with it’s own beefy 12v-boost Grove adapter board that will be available in the shop in a few weeks, so I think that might be something for you to try. I can send you an email about it, and we’ll be posting examples here once they’re ready for release.
-
2023-12-15 at 1:48 PM #18253
Thank you for the quick response, we are looking forward to the new modbus adater. Meanwhile, we made some quick changes to existing wingboards to power the Y-511A from the 12v available on the V1.1 rev B, with good results. One station is back to normal and the other should be as soon as the updated wingboard is installed. Thanks!
Edit 12/22/23: The change to the wingboards did not resolve the issue, but did change the data the Y511-a was sending from -9999 to 0.0
Edit 2/9/24: Turns out the wiper on the Y-511A was rotating outside of its normal operation and got stuck on an adjacent PVC fixture. If the wiper rotates 360 degrees instead of just wiping back and forth, the rubber wiper will overhang the stainless steel body of the Y-511A, and collide with other things. The stuck wiper was pulling a lot of current, and possibly causing voltage sag on the Mayfly. Unstuck now, and appears to be operating normally.
-
-
AuthorPosts
- You must be logged in to reply to this topic.