Home › Forums › Mayfly Data Logger › RS485 without auto direction control
- This topic has 16 replies, 3 voices, and was last updated 2020-01-03 at 1:32 PM by neilh20.
-
AuthorPosts
-
-
2019-12-10 at 8:48 AM #13456
I trying to set up a Mayfly logger with two Y504 oxygen sensors but are running into some problems.
I could not get my hands on any of the RS485 modules you are using in the examples and had to try one I had on the shelf.
This is is the module I’ve been using with 3.3V Arduinos before:
Mikroe rs485 3.3v clickThe module work with the examples supplied in the YosemitechModbus\examples\GetValues
(using “const int DEREPin = 4;”)I know you recommend a modules with automatic direction control but I just want to check if anyone made any progress with this.
If I set max485EnablePin to anything else than -1 the logger program restarts after/during sensor test:
“Logger portion of setup finished.
Attempting to connect to the internet and synchronize RTC with NISTSetting up sensors…
Now running OxygenScout on Logger 00001
Using ModularSensors Library version 0.23.15”
I’m using the version 0.4 of the Mayfly logger and EnviroDIY_ModularSensors 0.23.15.
-
2019-12-10 at 9:34 AM #13460
I have never gotten the communication to work correctly using manual flow control, but it should not be causing your board to restart. I’ll look into it.
When using manual flow control, you have to set the direction pin high or low to change directions. The library does this, but I think there is a timing issue or something because my attempts at using it with a max485 and level shifters compeletely failed.
-
2019-12-10 at 1:09 PM #13461
Also, I’m really surprised you couldn’t find an adapter with automatic flow control. Where were you looking? There are a bunch on Amazon. This is one brand I’ve bought: https://www.amazon.com/SMAKN%C2%AE-Adapter-Serial-Converter-Module/dp/B010723BCE
-
2019-12-10 at 6:00 PM #13462
Ok, I broke out the 3.3V RS485 chip I have (an LTC1480) from the “someday I’ll test this” box. I’d bought the chip ages ago to try out in place of the (5V) MAX485 that I couldn’t ever get to work. But since the automatic flow control always worked nicely, I threw the LT1480 onto a shelf unopened.
Anyway, it worked for me. I made some very small tweaks to the SensorModbusMaster library to see if I could get the timing better, which helped a little, but it worked even without. I didn’t have any issues with the board restarting or anything.
Hm.. In my test I used AltSoftSerial (pins 5&6) as my serial and tried the RE_/DE on both pins 4 and A2. What exactly are your connections and what code exactly are you running?
-
2019-12-10 at 6:51 PM #13463
I was feeling cocky after the LTC1480 worked and pulled out the Max485 and level shifters. Zero success with communication, but I didn’t have any problems with the program crashing.
-
2019-12-11 at 2:20 AM #13465
Wow, I just realized I didn’t really post any real question and still you are helping=)I’m really thankful and impressed by all your effort.
I have ordered a module with automatic flow control from Amazon but I didn’t want to wait for it to arrive so I started with what I had.
The module I have has been working nicely before but this time I can’t get it to work. In the past the timing turning the Enable pin low has been tricky for me. For simple programs I’ve used delays but I tried something like Nick Gammon’s solution under “Flushing the output” RS485 communications. But not in this case.I using the “logging_to_ThingSpeak”-example with one Yosemitech Y504, AltSoftSerial (pins 5&6) and RE/DE on pin 4.
On my module the RE/DE are coupled together so you only need one pin. The restart happens even if I disconnect everything from the Mayfly logger. And the only way to stop it from happen is to set the “max485EnablePin” to -1. I will try some more examples to see if I can get it right with my coding.123456789101112131415161718192021222324252627282930313233343536// ==========================================================================// Settings for Additional Serial Ports// ==========================================================================// AltSoftSerial by Paul Stoffregen (https://github.com/PaulStoffregen/AltSoftSerial)// is the most accurate software serial port for AVR boards.// AltSoftSerial can only be used on one set of pins on each board so only one// AltSoftSerial port can be used.// Not all AVR boards are supported by AltSoftSerial.#include <AltSoftSerial.h>AltSoftSerial altSoftSerial;// ==========================================================================// Yosemitech Y504 Dissolved Oxygen Sensor// ==========================================================================#include <sensors/YosemitechY504.h>// Create a reference to the serial port for modbus// Extra hardware and software serial ports are created in the "Settings for Additional Serial Ports" section#if defined ARDUINO_ARCH_SAMD || defined ATMEGA2560HardwareSerial &modbusSerial = Serial2; // Use hardware serial if possible#elseAltSoftSerial &modbusSerial = altSoftSerial; // For software serial if needed// // NeoSWSerial &modbusSerial = neoSSerial1; // For software serial if needed#endifbyte y504ModbusAddress1 = 0x01; // The modbus address of the Y504//byte y504ModbusAddress2 = 0x05; // The modbus address of the Y504const int8_t rs485AdapterPower = sensorPowerPin; // Pin to switch RS485 adapter power on and off (-1 if unconnected)const int8_t modbusSensorPower = -1; // Pin to switch sensor power on and off (-1 if unconnected) TODO Change pinconst int8_t max485EnablePin = -1; // Pin connected to the RE/DE on the 485 chip (-1 if unconnected)const uint8_t y504NumberReadings = 10; // The manufacturer recommends averaging 10 readings, but we take 5 to minimize power consumption// Create a Yosemitech Y504 dissolved oxygen sensor objectYosemitechY504 y504_1(y504ModbusAddress1, modbusSerial, rs485AdapterPower, modbusSensorPower, max485EnablePin, y504NumberReadings);//YosemitechY504 y504_2(y504ModbusAddress2, modbusSerial, rs485AdapterPower, modbusSensorPower, max485EnablePin, y504NumberReadings); -
2019-12-13 at 12:34 PM #13471
I’m totally lost. Tried the “data_saving”-example as is and the logger restarts even if I keep the enable pin at -1. Doesn’t make a difference if I detach everything from the Mayfly and I tried both different usb-cables and FTDI-cable.
The “thingspeak” example works if I don’t add any Yosemitech libraries/sensors in the code. I wonder if I’m doing anything wrong with PlatformIO? I have to add https://github.com/SRGDamia1/NeoSWSerial.git and https://github.com/EnviroDIY/SoftwareSerial_ExternalInts.git
to the “platformio.ini” of the “data_saving”-example even if the .ini-file on github don’t use it.Tried the same code with a Sodaq Mbili and it behaves exactly the same.
Anyone who can help me where I should start with the debug?
-
2019-12-16 at 11:54 AM #13475
Oops. I’d meant to cut the code using NeoSWSerial and SoftwareSerial from that particular example but apparently cut it only from the example platformio.ini file.
Can you post your platformio.ini file? Are you using Atom or VSCode? It shouldn’t make a difference for the code; I’m just asking so I can help you better. What versions of all libraries do you have installed? Did you install any manually or let PlatformIO do the install? Are you sure you haven’t installed any twice? In your project’s folder, navigate to the .pio/libdeps/mayfly subfolder and look at all the folders within it. Do you see any library names in there twice (with a different suffix tagged onto the end of the folder name). If you see any repeats, the easiest solution is to delete everything and let PlatformIO reinstall just one version of each. Then update all your libraries and your platforms if you haven’t already. To do this, open a new terminal in PlatformIO with either the button or the menu. On Atom you can use the + icon on the bottom; on VSCode there should be a button on the very bottom left that looks like this: [> ]. In the terminal first update the platforms with the command “pio update”. Then update your project specific libraries with the command “pio lib update.” PlatformIO itself hasn’t been updated in a while, but you can verify that you’re running the lastest version with the command “pio upgrade.” After updating everything, make sure you clean out any older pre-compiled files by hitting the trashcan icon.
When you say the board restarts, does it restart instantly or does it hang for 15 minutes and then restart? Please add these defines to your platformio.ini file and then post the output when the board is running. It might be very long; you can post it or attach it as a text file.
INI1234567891011121314151617181920212223242526272829303132333435363738; PlatformIO Project Configuration File;; Build options: build flags, source filter; Upload options: custom upload port, speed and extra flags; Library options: dependencies, extra library storages; Advanced options: extra scripting;; Please visit documentation for the other options and examples; http://docs.platformio.org/page/projectconf.html[platformio]description = ModularSensors example using two "loggers" to save cellular data[env:mayfly]monitor_speed = 115200board = mayflyplatform = atmelavrframework = arduinolib_ldf_mode = deep+lib_ignore = RTCZerobuild_flags =-DSDI12_EXTERNAL_PCINT-DNEOSWSERIAL_EXTERNAL_PCINT-DMQTT_MAX_PACKET_SIZE=240-DTINY_GSM_RX_BUFFER=64-DTINY_GSM_YIELD_MS=2-DMS_YOSEMITECHPARENT_DEBUG-DMS_YOSEMITECHPARENT_DEBUG_DEEP-DMS_LOGGERBASE_DEBUG-DMS_VARIABLEBASE_DEBUG-DMS_SENSORBASE_DEBUG-DMS_VARIABLEARRAY_DEBUG-DMS_VARIABLEARRAY_DEBUG_DEEPlib_deps =EnviroDIY_ModularSensors@0.23.16https://github.com/PaulStoffregen/AltSoftSerial.githttps://github.com/EnviroDIY/SoftwareSerial_ExternalInts.githttps://github.com/SRGDamia1/NeoSWSerial.git -
2019-12-17 at 5:47 AM #13476
To answer your questions:
-I’m using platformio on VSCode. (I’m really not comfortable using it but these kind of problems is good for actually learning hands on. There is a lot of strange things in there that I don’t understand and I wish I could find a really good tutorial how to work with it.)
-Attached my “platformio.ini”
-I’ve tried both manual install and to let platformio do it.
-Now updated/upgraded/cleaned
– This is how the lib_dep folder looks like:
v libdeps\mayfly
>tmp_installing-kgja50_package
>AltSoftSerial
>NeoSWSerial
>SoftwareSerial_ExtInts
-I was pretty sure AltSoftSerial was the problem since I got some errors when including it when using the mayfly board both in Arduino
IDE and platformio but that seems to work now.
-If I now focus on the “data_saving”-example which I know I didn’t corrupt with my own programming I might be misinterpreting the output
based on my past problems with my own code (modified version of the Thingspeak example). When using your platformio.ini without the debugflags I get the output as attached in file “output1.txt”. Every 15 sec I get a new line of “Now running data_saving.ino on Logger XXXXX”
When using the debug flags I get whats in output2.txt
Then the Y504 seems to update. Maybe I was waiting for a output similar to the thingspeak-example? The testbutton didn’t work which made me assume something was wrong.The debug flags are very helpful. I totally missed to try them. The buffer setting in my terminal is probably to low to catch enough but i learned i can save the log to a text file with “pio device monitor > Filename.txt” in the terminal. Also very helpful.
Oh I forgot to replace the gprsbee which I removed the
Attachments:
-
2019-12-17 at 5:50 AM #13479
My reply is very hard to read especially when all my spacing got removed. Sorry for that:)
Attaching a .ini didn’t work so here it is:
1234567891011121314151617181920212223242526272829303132333435363738394041424344; PlatformIO Project Configuration File;; Build options: build flags, source filter; Upload options: custom upload port, speed and extra flags; Library options: dependencies, extra library storages; Advanced options: extra scripting;; Please visit documentation for the other options and examples; http://docs.platformio.org/page/projectconf.html[platformio]description = ModularSensors example using two "loggers" to save cellular data;[env:sodaq_mbili];board = sodaq_mbili[env:mayfly]board = mayflymonitor_speed = 115200; change microcontroller;board_build.mcu = atmega1284pplatform = atmelavrframework = arduinolib_ldf_mode = deep+lib_ignore = RTCZerobuild_flags =-DSDI12_EXTERNAL_PCINT-DNEOSWSERIAL_EXTERNAL_PCINT-DMQTT_MAX_PACKET_SIZE=240-DTINY_GSM_RX_BUFFER=64-DTINY_GSM_YIELD_MS=2;-D __AVR_ATmega1280__lib_deps =EnviroDIY_ModularSensors@0.23.16; ^^ Use this when working from an official release of the library; https://github.com/EnviroDIY/ModularSensors.git#develop; ^^ Use this when if you want to pull from the develop branchhttps://github.com/PaulStoffregen/AltSoftSerial.githttps://github.com/SRGDamia1/NeoSWSerial.githttps://github.com/EnviroDIY/SoftwareSerial_ExtInts.git -
2019-12-18 at 4:42 AM #13480
It feels like a memory leak but I can’t see why. I tried to modify the thingspeak example but then everything got messed up and the pins scramled. I’ll try with another computer and see if I can find the bugs in my code. Probably something very simple.
Attachments:
-
2019-12-18 at 4:43 AM #13483123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392/*****************************************************************************logging_to_thingSpeak.inoWritten By: Sara Damiano (sdamiano@stroudcenter.org)Development Environment: PlatformIOHardware Platform: EnviroDIY Mayfly Arduino DataloggerSoftware License: BSD-3.Copyright (c) 2017, Stroud Water Research Center (SWRC)and the EnviroDIY Development TeamThis example sketch is written for ModularSensors library version 0.23.16This sketch is an example of logging data to an SD card and sending the data toThingSpeak.DISCLAIMER:THIS CODE IS PROVIDED "AS IS" - NO WARRANTY IS GIVEN.*****************************************************************************//*// ==========================================================================// Defines for the Arduino IDE// In PlatformIO, set these build flags in your platformio.ini// ==========================================================================#ifndef TINY_GSM_RX_BUFFER#define TINY_GSM_RX_BUFFER 64#endif#ifndef TINY_GSM_YIELD_MS#define TINY_GSM_YIELD_MS 2#endif#ifndef MQTT_MAX_PACKET_SIZE#define MQTT_MAX_PACKET_SIZE 240#endif*/// ==========================================================================// Include the base required libraries// ==========================================================================#include <Arduino.h> // The base Arduino library#include <EnableInterrupt.h> // for external and pin change interrupts#include <LoggerBase.h> // The modular sensors library// ==========================================================================// Data Logger Settings// ==========================================================================// The library version this example was written forconst char *libraryVersion = "0.23.16";// The name of this fileconst char *sketchName = "Thingspeak";// Logger ID, also becomes the prefix for the name of the data file on SD cardconst char *LoggerID = "00002";// How frequently (in minutes) to log dataconst uint8_t loggingInterval = 1;// Your logger's timezone.const int8_t timeZone = 1; // CET// NOTE: Daylight savings time will not be applied! Please use standard time!// ==========================================================================// Primary Arduino-Based Board and Processor// ==========================================================================#include <sensors/ProcessorStats.h>const long serialBaud = 115200; // Baud rate for the primary serial port for debugging//int BEE_CTS_PIN = 19; // Bee CTS Pin (Clear to Send)const int8_t greenLED = 8; // MCU pin for the green LED (-1 if not applicable)const int8_t redLED = 9; // MCU pin for the red LED (-1 if not applicable)const int8_t buttonPin = 21; // MCU pin for a button to use to enter debugging mode (-1 if not applicable)const int8_t wakePin = A7; // MCU interrupt/alarm pin to wake from sleep// 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 pin (-1 if not applicable)const int8_t sdCardSSPin = 12; // MCU SD card chip select/slave select pin (must be given!) 12 for Mayflyconst int8_t sensorPowerPin = 22; // MCU pin controlling main sensor power (-1 if not applicable)// Create the main processor chip "sensor" - for general metadataconst char *mcuBoardVersion = "v0.4";ProcessorStats mcuBoard(mcuBoardVersion);// ==========================================================================// Settings for Additional Serial Ports// ==========================================================================/// The modem and a number of sensors communicate over UART/TTL - often called "serial".// "Hardware" serial ports (automatically controlled by the MCU) are generally// the most accurate and should be configured and used for as many peripherals// as possible. In some cases (ie, modbus communication) many sensors can share// the same serial port.#if not defined ARDUINO_ARCH_SAMD && not defined ATMEGA2560 // For AVR boards// Unfortunately, most AVR boards have only one or two hardware serial ports,// so we'll set up three types of extra software serial ports to use// AltSoftSerial by Paul Stoffregen (https://github.com/PaulStoffregen/AltSoftSerial)// is the most accurate software serial port for AVR boards.// AltSoftSerial can only be used on one set of pins on each board so only one// AltSoftSerial port can be used.// Not all AVR boards are supported by AltSoftSerial.#include <AltSoftSerial.h>AltSoftSerial altSoftSerial;// NeoSWSerial (https://github.com/SRGDamia1/NeoSWSerial) is the best software// serial that can be used on any pin supporting interrupts.// You can use as many instances of NeoSWSerial as you want.// Not all AVR boards are supported by NeoSWSerial.#include <NeoSWSerial.h> // for the stream communicationconst int8_t neoSSerial1Rx = 11; // data in pinconst int8_t neoSSerial1Tx = -1; // data out pinNeoSWSerial neoSSerial1(neoSSerial1Rx, neoSSerial1Tx);// To use NeoSWSerial in this library, we define a function to receive data// This is just a short-cut for latervoid neoSSerial1ISR(){NeoSWSerial::rxISR(*portInputRegister(digitalPinToPort(neoSSerial1Rx)));}const int8_t softSerialRx = A3; // data in pinconst int8_t softSerialTx = A4; // data out pin#include <SoftwareSerial_ExtInts.h> // for the stream communicationSoftwareSerial_ExtInts softSerial1(softSerialRx, softSerialTx);#endif // End software serial for avr boards// ==========================================================================// Wifi/Cellular Modem Settings// ==========================================================================// Create a reference to the serial port for the modemHardwareSerial &modemSerial = Serial1; // Use hardware serial if possible// Modem Pins - Describe the physical pin connection of your modem to your boardconst int8_t modemVccPin = 23; // MCU pin controlling modem power (-1 if not applicable)const int8_t modemStatusPin = 19; // MCU pin used to read modem status (-1 if not applicable)//const int8_t modemResetPin = 20; // MCU pin connected to modem reset pin (-1 if unconnected)const int8_t modemSleepRqPin = -1; // MCU pin used for modem sleep/wake request (-1 if not applicable)const int8_t modemLEDPin = redLED; // MCU pin connected an LED to show modem status (-1 if unconnected)// Network connection informationconst char *apn = "xxxxx"; // The APN for the gprs connection#include <modems/Sodaq2GBeeR6.h>const long modemBaud = 9600; // SIM800 does auto-bauding by defaultSodaq2GBeeR6 modem2GB(&modemSerial,modemVccPin, modemStatusPin, apn);// Create an extra reference to the modem by a generic name (not necessary)Sodaq2GBeeR6 modem = modem2GB;//const char *BEE_TYPE = "GPRS"; // The type of XBee, either "GPRS" or "WIFI"//const char* APN = "online.telia.se"; // The APN for the GPRSBee// ==========================================================================// Maxim DS3231 RTC (Real Time Clock)// ==========================================================================#include <sensors/MaximDS3231.h>// Create a DS3231 sensor objectMaximDS3231 ds3231(1);// ==========================================================================// Yosemitech Y504 Dissolved Oxygen Sensor// ==========================================================================#include <sensors/YosemitechY504.h>// Create a reference to the serial port for modbus// Extra hardware and software serial ports are created in the "Settings for Additional Serial Ports" section#if defined ARDUINO_ARCH_SAMD || defined ATMEGA2560HardwareSerial &modbusSerial = Serial2; // Use hardware serial if possible#elseAltSoftSerial &modbusSerial = altSoftSerial; // For software serial if needed//NeoSWSerial &modbusSerial = neoSSerial1; // For software serial if needed//SoftwareSerial_ExtInts &modbusSerial =softSerial1; // For software serial if needed#endifbyte y504ModbusAddress1 = 0x01; // The modbus address of the Y504byte y504ModbusAddress2 = 0x05; // The modbus address of the Y504 TODO->Set adressconst int8_t rs485AdapterPower = sensorPowerPin; // Pin to switch RS485 adapter power on and off (-1 if unconnected)const int8_t modbusSensorPower = -1; // Pin to switch sensor power on and off (-1 if unconnected)const int8_t max485EnablePin = 4; // Pin connected to the RE/DE on the 485 chip (-1 if unconnected)const uint8_t y504NumberReadings = 5; // The manufacturer recommends averaging 10 readings, but we take 5 to minimize power consumption// Create a Yosemitech Y504 dissolved oxygen sensor objectYosemitechY504 y504_1(y504ModbusAddress1, modbusSerial, modbusSensorPower, max485EnablePin, y504NumberReadings);YosemitechY504 y504_2(y504ModbusAddress2, modbusSerial, modbusSensorPower, max485EnablePin, y504NumberReadings);// Create the dissolved oxygen percent, dissolved oxygen concentration, and// temperature variable pointers for the Y504//Variable *y504DOpct = new YosemitechY504_DOpct(&y504, "12345678-abcd-1234-ef00-1234567890ab");//Variable *y504DOmgL = new YosemitechY504_DOmgL(&y504, "12345678-abcd-1234-ef00-1234567890ab");//Variable *y504Temp = new YosemitechY504_Temp(&y504, "12345678-abcd-1234-ef00-1234567890ab");// ==========================================================================// Creating the Variable Array[s] and Filling with Variable Objects// ==========================================================================Variable *variableList[] = {new YosemitechY504_DOpct(&y504_1, "4d202b9c-1b23-11ea-978f-2e728ce88125"),new YosemitechY504_Temp(&y504_1, "4d202cdc-1b23-11ea-978f-2e728ce88125"),new YosemitechY504_DOmgL(&y504_1, "4d202e1c-1b23-11ea-978f-2e728ce88125"),new YosemitechY504_DOpct(&y504_2, "4d202f5c-1b23-11ea-978f-2e728ce88125"),new YosemitechY504_Temp(&y504_2, "4d203290-1b23-11ea-978f-2e728ce88125"),new YosemitechY504_DOmgL(&y504_2, "4d203128-1b23-11ea-978f-2e728ce88125"),new Modem_SignalPercent(&modem, "cc731ad3-a201-4160-bc15-4aa80f530fba"),new ProcessorStats_Battery(&mcuBoard, "f4fcc3cb-5a89-4436-984f-6b48612eb7fa"),new MaximDS3231_Temp(&ds3231, "61a93cdb-6c9f-46b3-a3ed-892ccd97a08f"),new Modem_RSSI(&modem, "6486cb74-ed40-4340-805e-f9a8fd1af77e")};// Count up the number of pointers in the arrayint variableCount = sizeof(variableList) / sizeof(variableList[0]);// Create the VariableArray objectVariableArray varArray;// ==========================================================================// The Logger Object[s]// ==========================================================================// Create a logger instanceLogger dataLogger;// ==========================================================================// ThingSpeak Data Publisher// ==========================================================================// Create a channel with fields on ThingSpeak in advance// The fields will be sent in exactly the order they are in the variable array.// Any custom name or identifier given to the field on ThingSpeak is irrelevant.// No more than 8 fields of data can go to any one channel. Any fields beyond the// eighth in the array will be ignored.const char *thingSpeakMQTTKey = "XXXXXXXXXXXXXXXX"; // Your MQTT API Key from Account > MyProfile.const char *thingSpeakChannelID = "######"; // The numeric channel id for your channelconst char *thingSpeakChannelKey = "XXXXXXXXXXXXXXXX"; // The Write API Key for your channel// Create a data publisher for ThingSpeak#include <publishers/ThingSpeakPublisher.h>ThingSpeakPublisher TsMqtt;// ==========================================================================// 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);}// Read's 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];}// ==========================================================================// Main setup function// ==========================================================================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);if (String(MODULAR_SENSORS_VERSION) != String(libraryVersion))Serial.println(F("WARNING: THIS EXAMPLE WAS WRITTEN FOR A DIFFERENT VERSION OF MODULAR SENSORS!!"));// Start the serial connection with the modemmodemSerial.begin(modemBaud);// Start the stream for the modbus sensors; all currently supported modbus sensors use 9600 baudmodbusSerial.begin(9600);// 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();// 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 variable array[s], logger[s], and publisher[s]varArray.begin(variableCount, variableList);dataLogger.begin(LoggerID, loggingInterval, &varArray);TsMqtt.begin(dataLogger, &modem.gsmClient, thingSpeakMQTTKey, thingSpeakChannelID, thingSpeakChannelKey);// Note: Please change these battery voltages to match your battery// Check that the battery is OK before powering the modemif (getBatteryVoltage() > 3.55 || !dataLogger.isRTCSane()){modem.modemPowerUp();modem.wake();// Synchronize the RTC with NISTSerial.println(F("Attempting to connect to the internet and synchronize RTC with NIST"));if (modem.connectInternet(120000L)){dataLogger.setRTClock(modem.getNISTTime());}else{Serial.println(F("Could not connect to internet for clock sync."));}}// Set up the sensors, except at lowest battery levelif (getBatteryVoltage() > 3.4){Serial.println(F("Setting up sensors..."));varArray.setupSensors();}// Power down the modemmodem.disconnectInternet();modem.modemSleepPowerDown();// 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){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 sleepdataLogger.systemSleep();}// ==========================================================================// Main loop function// ==========================================================================// 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();}}
-
2019-12-19 at 9:57 AM #13485
Finally some progress when I got some help.
In the modified ThingsSpeak sketch the constructor was the problem.
YosemitechY504 y504_1(y504ModbusAddress1, modbusSerial, modbusSensorPower, max485EnablePin, y504NumberReadings);-> did not work
YosemitechY504 y504_2(y504ModbusAddress2, modbusSerial, rs485AdapterPower, modbusSensorPower, max485EnablePin, y504NumberReadings);->Works. I don’t know how I lost one of the power pins but that explains why it worked better from the beginning.Back to the original problem…
The logger crashes if I set the EnablePin to >0 and don’t set the -D MS_YOSEMITECHPARENT_DEBUG flag
In setup the program enters and don’t return from varArray.setupSensors();In YosemitechParent.ccp (line 67-69) the debugStream is null if not in debug.
123#ifdef MS_YOSEMITECHPARENT_DEBUG_DEEPsensor.setDebugStream(&DEEP_DEBUGGING_SERIAL_OUTPUT);#endifIn SensorModbusMaster (line 683-690) it ends up with the null pointer
12345678910// This flips the device/receive enable to RECIEVER so the sensor can send textvoid modbusMaster::recieverEnable(void){if (_enablePin >= 0){digitalWrite(_enablePin, LOW);_debugStream->println("RS485 Receiver/Slave Tx Enabled");// delay(8);}} -
2019-12-23 at 4:12 PM #13487
I’m sorry I haven’t responded. My family is finally finished with a fun round of stomach bugs.
Were you by chance talking with @neilh or did you just happen to get to the same place at almost the same time coincidentally? Neil wrote up a fix for this in the SensorModbusMaster library, which I just accepted. If you update that library, you should be getting the fix. It might take 24 hours or so for the PlatformIO registry to catch the update on the library; if you’re ready to get the fix NOW you can uninstall and reinstall SensorModbusMaster using the github link instead of the library name.
With the fix in SensorModbusMaster, is it finally working for you?
I”m sorry for not being more helpful sooner!
-
2019-12-23 at 9:43 PM #13492
Sara sorry about the stomach bug. Life is challenging when the rulers of the internal ecology get distracted with nasty bug invasions.
thanks for the fix ~ I just noticed this conversation today.
I think it was working with the AVR compiler as I had it all working for many months on a Mayfly (except that specific riparian monitoring Mayfly got stolen a couple of months ago). I’ve seen this problem before, that the AVR compiler has some defensive won’t execute a NULL pointer. Which is great. The NULL pointer came up in the ARM context, but I hadn’t regression tested it with the AVR.
I haven’t looked at this AVR Mayfly RS485 DIR management as its a streams based environment. That is where the Auto Direction SOM works very nicely. I had no problems with it.
Apologies if this is repeating something that everyone knows;
Modbus is a packet of information. At the begin of the packet the RS485 driver half duplex goes to transmit, and then only when the complete Modbus msg is sent does the RS485 driver revert to receive.
The reverting to receive is critical hard real time, as the modbus slave starts to respond shortly afterwards and I believe its specified at 3.5Character timings or about 3.5mS. Modbus also specifies for a packet that there should never be a gap between characters of more than 1.5Character timings or about 1.5mS.
The RS485 SOM does this with a simple hardware timing. Resistor, Cap, Diode and buffer(schmitt trigger) I believe.
For a streams based environment I believe its challenging.
I did investigate this for an Ubuntu Linux build and compiled in a different set of drivers for an RS485 mode.
For the streams based environment, turning the driver to transmit is easy and can be done before starting writing to the stream.
However it requires an accurate time to detect, not just when the last byte in the packet is written to the hardware (and how does a stream know its the last byte especially if there is a multibyte FIFO for the Tx UART) but when that byte has completed transmission through the UART. So for a stream based environment, the driver needs to start a timer whenever the UART end of character interrupt is received, and if another character isn’t written into the UART in 1.5character timings (a 1.5mS) then it needs to switch the direction to receive.
In the world of industrial designed systems for Modbus there are a number of potential solutions a) design a packet based interface for the Mega1280 UART- the UART supports end-of-byte transmission, but the driver guarenttees the Rx switch. b) use a MAX1348 driver which also has auto direction, but it requires +5V c) using a processor with UART that supports RS485 like the SAM51Well Solstice Salutations to everyone, I hope you have a good holiday – and that there is harmony with the anthropogenic masters, the gastric microbial ecology!.
-
2020-01-03 at 3:18 AM #13527
I’m not expecting you to fix all my problems, but I’m very grateful for any help I can get. I prefer this kind of bug though…
It was actually very instructive to go through the libraries and trying to learn how they work. It was driving me nuts when it was working with the deep debug flag but it finally made sense.
I totally missed @neilh’s fix before doing the debug. I got some help and was doing some serial debug through the libraries before reaching the conclusion. I have now learned I can check out github for known issues before trying to find them myself=)
I was trying to add a Null stream object (since someone pointed me in that direction) but didn’t finish in time so I deployed with the debug flag. Will try the fix later.
-
2020-01-03 at 1:32 PM #13531
Hi Erik, Sounds like we ended up working on the same issue at about the same time.
Great to hear you have a basic path forwards. I am very much a fan of the open source ModularSensors and EnviroDIY which covers a lot of functionality.However, it is a matrix of south bound (away from internet) instrument sensor interfaces ~~which are fantastic~~ and north bound (towards internet) communication interfaces.
I personally have just a few configurations that I’m trying to build for the future, very much with RS485/12V (and SDI12/5V as instruments support it).
From the software engineering aspect of the open source, there is no regression defined. So I’m attempting a definition of that.
SO interested how it works for you.
-
-
AuthorPosts
- You must be logged in to reply to this topic.