I'm building an observatory. There's going to be a rain sensor that will notify me if rain is detected. The sensor connects to an Arduino which triggers a safety monitor in the Astrophotography capture and control software which then parks the telescope and closes the observatory roof. The interface between the Arduino and the astronomy software is an ASCOM Safety Monitor driver. The Arduino sketch would be simple because all it has to do is detect a switch closing which is connected to a pull up resistor. An example of an Arduino sketch I have seen is as follows:
bool pinState = LOW;
bool safeState = HIGH; //set desired safeState of the monitor HIGH or LOW
void setup() {
pinMode(2, INPUT);
Serial.begin(9600); // initialize serial
Serial.flush(); // flush the port
Serial.print("notsafe#"); // send notsafe# as first state while monitor and client initialize
}
void loop() {
String cmd;
if (Serial.available() > 0) {
cmd = Serial.readStringUntil('#');
if (cmd == "S") {
pinState = digitalRead(2);
if (pinState == safeState) {
Serial.print("safe#");
}
if (pinState != safeState) {
Serial.print("notsafe#");
}
}
}
It's fairly straightforward but the bit I'm uncertain on is " cmd = Serial.readStringUntil('#');"
Is the # sent to the Serial Monitor by the ASCOM driver? or does Serial.readStringUntil always end with a #?
I need to add to the the Arduino code but I would like to use the ASCOM driver as is so a greater understanding of what's going on would help me greatly.
have a read of Serial.readStringUntil() - it will read characters into a string until the termination characater is found or until it times out (default 1 second)
I did read that, I'll go and read it again to make sure it goes in! So do you think the string characters are output from the ASCOM driver? Is the # the termination character?
That code looks like it makes you type S# before it will check pin 2 and send along to some listener a safe/nosafe status.
Or is waiting to be "asked" by some entity, at which time it will check pin 2 and report. More likely.
So, if the thing is asking, you can just decide which message to send depends on your rain sensor.
If the thing isn't asking, it is not clear when it would be willing to receive a message…
For example, it might always be willing to hear you, so in that case any time your conditions change, like it goes from it is raining to it is not raining, you could send unsolicited the safe/nosafe packet.
Which is a long winded way of saying we need to know more about all the actors in this little play you are staging.
And how (abject curiosity) are you detecting this alleged rain?
I believe the ASCOM driver continuously asks if pin 2 is high or low. Then reports to the astronomy software safe or not safe. So, when using Serial.readStringUntil('#') would the # character normally be expected at some point in the string?
The actors are the astrophotography software (NINA (it could be any astrophotography package)), the NINA safety monitor (Boolean yes/no), the ASCOM driver (a means of communicating between software packages and peripherals), the Arduino and the rain sensor.
There are a number of different rain sensors falling mainly into two groups. Resistive and optical. The optical ones detect a drop of rain in a glass dome and close a switch. The resistive ones detect the change in resistance between closely separated conducting lines and close a switch. I'll probably use the latter.
Sorry, no documentation. Just the Arduino sketch, a schematic and the ASCOM driver which is an exe file.
They are from here:
I believe the driver is really as simple as a range of switches open/closed on the input and a single Boolean high/low on the output to report safe/not safe.
So the S# is a question from the ASCOM driver inquiring the status of the sensor switch and high or low are the possible answers resulting in safe# or notSafe#
The code doesn't work. I'm wondering if it's because I put in a 2000 delay so I could read all the variables on the serial monitor and it's timing out as @horace pointed out.
Thanks all, I'll take my mods out of the code and try it again.
The ASCOM driver is installed from an exe file and is activated when NINA is fired up. When NINA is run the first thing is to connect the equipment, the telescope mount, the focuser, the camera etc. This includes connecting the Safety Monitor. The driver confirms correct installation because it appears in a drop down list of safety monitors. NINA reports that it has successfully connected and the not safe symbol is displayed. The Arduino is connected to the pc through a USB in the usual way. So the ASCOM driver connects to the Arduino by outputting the S# string I guess, which is received by the Arduino. Then the Arduino sends back safe# or notsafe# as a function of the status of the rain sensor switch which the ASCOM driver sends to the NINA Safety Monitor.
If the program is not working correctly you can do some trouble shooting as to whether the S# message is received by the Arduino, or if the reply is not received by the ASCOM driver. The program certainly works as written for communication with the Serial monitor.
Can you see in the PC is the ASCOM driver is receiving the correct "safe" or "not safe" message? Can you see the Tx led on the Arduino flash briefly when the message is sent?
You can test for the Arduino receiving the "S#" message by using an LED indicator.
bool pinState = LOW;
bool safeState = HIGH; //set desired safeState of the monitor HIGH or LOW
void setup()
{
pinMode(2, INPUT);
pinMode(13, OUTPUT);
Serial.begin(9600); // initialize serial
Serial.flush(); // flush the port
Serial.print("notsafe#"); // send notsafe# as first state while monitor and client initialize
}
void loop()
{
String cmd;
if (Serial.available() > 0)
{
cmd = Serial.readStringUntil('#');
if (cmd == "S")
{
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
pinState = digitalRead(2);
if (pinState == safeState)
{
Serial.print("safe#");
}
if (pinState != safeState)
{
Serial.print("notsafe#");
}
}
}
}
@Graeme1858 I haven't figured out your hardware setup, don't worry about that, I will.
But I wonder prematurely perhaps if you could,d use a terminal emulator program such as PuTTY or CoolTerm and talk/listen directly to the other side using serial comms and leaving the Arduino and any excitement or trouble programming that might be out of the picture.
Just to see what is said, and to see if you can make sense of what to say back, and what happens.
Then it should be easier to make the Arduino do what you've confirmed "manually".
I could have phrased that better! The Safety Monitor is able to show the safe/not safe status but a not safe condition is shown at all times. I have a button switch simulating the rain sensor, operating the switch connects D2 to grd but the Safety Monitor does not change status.
I tried your D13 code, S is being received.
You highlighted part of the problem asking if the IDE was running. It doesn't need to be running but I didn't terminate it so there was a clash with both the IDE and NINA trying to connect to Com 4.
If I upload the sketch and shut down the IDE, then fire up NINA, then connect the Safety Monitor with the switch closed, notsafe is returned. If I then open the switch, after 2 seconds safe is returned but after another 2 seconds the status returns to notsafe! The Tx LED flashes until I close the switch again.
At least I get a safe tick for a couple of seconds now. But most importantly, I understand the code now! Unless you recognise this symptom, perhaps I should take it up with ASCOM.
With the conflict between the monitor and NINA program on the PC resolved, the issue does not appear to be a fundamental communication problem.
The Nano sees "S#" and a reply is going out to NINA.
That reply should depend on the state of the switch on Pin2.
If I then open the switch, after 2 seconds safe is returned but after another 2 seconds the status returns to notsafe!
Can you please post the circuit diagram with the switch in place of the rain gage relay. It's not clear to me that the input to pin2 is not floating when the switch is open. You may want to change the pin mode to INPUT_PULLUP to use the internal pullup, and have the switch(when pressed) connect pin 2 to ground.
The wiring looks correct. Is the program on the PC still acting like this?
If I then open the switch, after 2 seconds safe is returned but after another 2 seconds the status returns to notsafe!
If so, you may want to modifiy the program so the led indicates the state of D2 (and not the Serial receive) to confirm that D2 is staying where it is supposed to be.
However, I have never seen this unstable behavior with a pin pulled HIGH with 10K like you have, and you may want to do the deeper investigation into the ASCOM.
bool pinState = LOW;
bool safeState = HIGH; //set desired safeState of the monitor HIGH or LOW
void setup()
{
pinMode(2, INPUT_PULLUP); //pulled HIGH
pinMode(13, OUTPUT);
Serial.begin(9600); // initialize serial
Serial.flush(); // flush the port
Serial.print("notsafe#"); // send notsafe# as first state while monitor and client initialize
}
void loop()
{
String cmd;
if (Serial.available() > 0)
{
cmd = Serial.readStringUntil('#');
if (cmd == "S")
{
pinState = digitalRead(2);
if (pinState == safeState) //pinState == HIGH switch open
{
Serial.print("safe#");
digitalWrite(13, HIGH);
}
if (pinState != safeState) // switch to gnd
{
Serial.print("notsafe#");
digitalWrite(13,LOW);
}
}
}
}