Open Kevin-M-Smith opened 10 years ago
Some thoughts:
Could the communication be done with a timer, like AltSoftSerial? Or, perhaps, given the low baud rate, with delays like OneWire?
I quick look at the AltSoftSerial library looks promising. I hope to get a chance to take a more in-depth look in the next few days.
I'm playing with an Adafruit Feather 32u4 (same processor as the Leonardo) and the shortcut of using specific interrupt vectors doesn't seem to be working for me.
Right now I have a version of the SDI-12 library, a version of Software Serial, and a version of a PCInt library all integrated into the ModularSensors library. It works fine on the Mayfly (AtMega 1284P with TQFN) and would probably be ok on an Uno, but I'm trying to see what it would take to make it work with other boards. (32u4, SAMD21, ESP8266, maybe Teensy or STM32... ) The SoftwareSerial/SDI12 conflict is an ugly hold-up and I'm just not sure how to get around it.
I've thought about forcing users to create sensor objects with the SS or SDI12 instance as part of the constructor, but that just doesn't seem as clean as creating it within the sensor. And it doesn't really solve anything because the user would be stuck in the same position I'm in, digging around for a way of making the libraries compatible when they want to combine SDI12 and serial sensors.
In combining them, I think I would prefer to have a version of SS that allows as many pins as possible, but don't see the need the SDI12 to support more than one pin. With SDI12, 62 can be added to the same Arduino pin, but each serial sensor needs one two completely independent pins. So, in that way, I guess making SDI12 more like AltSS and monopolizing the single input capture pin would be better, although that still knocks out the one or two output compare pins.
I'm also integrating the OneWire library for the Dallas temperature probes, which is why I've looked at its method of using delays for the timing and was wondering if it could work at the 1200 baud rate. I know using delays isn't great either because it's wasting time doing nothing and could miss other interrupts, but at least it would solve the compatibility problem.
Another SS library I came across: https://github.com/SlashDevin/NeoSWSerial. This one still uses interrupts, but does have the "clever set of #define statements" to allow it to play more nicely with other libraries. It also allows you to use it to define other pin change interrupts, so although it clashes with them, it might not require the use of a separate library for other interrupts.
Actually.. thinking about it even more.. using only delays clearly won't work because, while we can always depend on a device responding within 15ms of a request and shutting up within 7.5ms of finishing, devices can also send out service requests if they finish up early. We'd never be able to catch the service request if we're depending on the 15ms/7.5ms timing.
I've added the "clever defines" so an pin change interrupt can set up the interrupts for this library and tested it with Grey Gnomes EnableInterrupt on the Mayfly, 32u4, and M0. This requires the user to uncomment the line #define SDI12_EXTERNAL_PCINT and recompile the library and then call SDI12::handleInterrupt() on the receive pin from their other pin change library.
I'm debating about merging the cpp and h files into a single header file so that the library is not pre-compiled the statement #define SDI12_EXTERNAL_PCINT can just be added to any other sketch or library to stop SDI12 from hogging the interrupts. @Kevin-M-Smith , what do you think?
I have this issue with Arduino pro mini 3.3V and proposed solution in post#1 regarding commenting PCINT Request Vector lines is not working. Has anyone solved this issue or found a solution for this? I would be thankful if you share your solutions with me.
This is the error I get after compiling samples code on Arduino IDE 1.8.9:
By the way, where/how can I find PCINT structure (pin to port mapping) for Arduino pro mini to know which pin in associated with which PCINT Request Vector (PCINT0, PCINT1, PCINT2)?
Look at example J. It's working code of calling the SDI-12 interrupt from another interrupt library. The "bestiary" of the EnableInterrupt library is helpful for interrupt mapping.
Sometime ago, this issue seems to have been addressed through the release of the SDI12_PCINT3 branch. now renamed mayfly branch. Currently, SDI12_PCINT3.cpp in that branch seems NOT to have the other interrupts cropped, as advertised. I had to comment them out myself to make code compile correctly. If I can figure out how to submit a pull request in the next few hours, I will do so.
@Kalirren I am trying to replicate what you did. On that branch, the only function that gives trouble is the receiveISR()
. What exactly did you comment out to make that work?
Hi @hexad, It has been several years, but thankfully I left a trail for myself to follow. I opened a pull request to fix this bug, which I consider a regression, almost 1.5 years ago. No one has merged it?
https://github.com/EnviroDIY/Arduino-SDI-12/pull/84
You can see the code I commented out in that section. Note that that code is actually the code that concerns the interrupts that the mayfly branch documentation CLAIMS are disabled, but apparently aren't actually disabled...?
@Kalirren Thank you very much for your quick reply! I tried to comment out your code but it didn't work... I have this to note:
SoftwareSerial
). However, I kept receiving bad values of data (The Volumetric Water Content for Mineral Soils is: -0.70 m^3/m^3
).SoftwareSerial
library, then I received junk data. (Opening SDI-12 bus... ⸮\⸮y==⸮⸮⸮⸮⸮⸮⸮⸮%⸮⸮⸮⸮rrj⸮⸮
)Please note that I know my code works fine. Because when I don't include the SoftwareSerial
library and keep the code without your modifications, the values I get are correct...
In other words, while the library may compile, it does not work without those timer interrupts that you removed.
Ahh, this is enlightening. I recall that I had written a different section of code explicitly enabling some interrupts on registers 0 and 2 on assumption that the Mayfly branch documentation was correct. Because the interrupts were being enabled twice, once in my code and once in the library, there was a compile error, which I fixed by commenting out the version in the library to make it consistent with branch documentation.
I don't believe I ever used the receiveISR() function. If I recall correctly, I simply couldn't get it to work...
Problem Overview
Refresher on Interrupts
Library Conflicts
If you look at the SoftwareSerial library: https://github.com/arduino/Arduino/blob/master/libraries/SoftwareSerial/SoftwareSerial.cpp
In SoftwareSerial.cpp:
Code Interpretation
Stopgap Fix
As an example:
Pins 2 and 3 map to the PCINT Request Vector PCINT2. As a simple fix we can comment out the sections of code we are not using. (You may want to include a note as to why you changed it.)
In SoftwareSerial.cpp:
Next, we are going to do the complementary action in the SDI-12 Library. Since we are using pin 9 for SDI-12, we only need to assign our ISR to PCINT Request Vector PCINT0.
In SDI12.cpp:
Restart the Arduino IDE, and it should recognize the changes to the libraries and your code should compile without issue.
Towards A Better Fix?
Limitations
Desires
Potential Options?
Looking forward to your thoughts.