I'm working remotely right now, so I cant access the physical devices but am writing code and attempting to debug.
I believe my softserial may be disconnected between the arduino and the nodeMCU board I am using. when I send a message via MQTT to the NodeMCU there are two options - one it uses a softSerial to send a command to the arduino, or two it responds back on a different MQTT topic that the softSerial was unavailable.
So stupid question, and probably already know the answer but want to make sure.
IF the softSerial connection is physically broken between the two boards at this time - softSerial should always tell me the connection is not available correct? If this is not the case then I have an issue in code that I will have to figure out.
devilwacause:
IF the softSerial connection is physically broken between the two boards at this time - softSerial should always tell me the connection is not available correct?
I don't think so.
Arduino just talks to a pin. What happens afterwards is your problem.
Similarly, it just listens to a pin. If there is nothing, it doesn't care. It could be because nothing has been sent.
On another note - is the .isListening method no longer a part of SoftwareSerial? I can never get it to work, even tho it lights up as if it is still a method.
There can be multiple instances of SoftwareSerial. Only one instance at a time can be listening. The isListening() method tells whether the particular instance is the one listening. If you have only one instance of SoftwareSerial, that instance will always be listening.
Whether it hears anything, or not, is a different story. available() tells you how much it has heard but not passed on.
By "never get it to work" I mean the arduino IDE errors out when verifying/compiling and gives me the 'class SoftwareSerial' has no member named 'isListening' error.
devilwacause:
By "never get it to work" I mean the arduino IDE errors out when verifying/compiling and gives me the 'class SoftwareSerial' has no member named 'isListening' error.
I only have one instance of SoftwareSerial
Can you post the code, the Arduino you are using, and the verbose output (use File + Preferences to enable verbose mode during compiling)? The SoftwareSerial class DOES, in 1.0.5 and on, have an isListening() method.
Of course, if you only have one instance, that instance is guaranteed to be the instance that is listening, so it is pointless to be calling the isListening() method.
Code Is A Work in Progress, and this is my first use of SoftwareSerial, so any errors I may have please alert me to them.
#include <SoftwareSerial.h>
#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <stdlib.h>
// WiFi and MQTT variables
const char* ssid = "SSID";
const char* password = "SSID_PASS";
const char* mqtt_server = "Raspberry-MQTT";
// For Temperature
#define ONE_WIRE_BUS 5
char temperatureString[6];
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
//MQTT and ESP Setup
WiFiClient espClient;
PubSubClient client(espClient);
//For Communications with Arduino
const byte rxPin = 13;
const byte txPin = 15;
SoftwareSerial arduinoComs(rxPin, txPin); //rx/tx
// The following function handles all incoming messages from the MQTT server.
void callback(char* topic, byte* payload, unsigned int length) {
int topicSwitch;
String strTopic = String((char*)topic);
if (strTopic == "chickenCoop/Temperature/Command"){
topicSwitch = 1;
}else if (strTopic == "chickenCoop/Lights/Command") {
topicSwitch = 2;
}else if (strTopic == "chickenCoop/Lights/Status") {
topicSwitch = 3;
}else if (strTopic == "chickenCoop/Door/Command") {
topicSwitch = 4;
}else if (strTopic =="chickenCoop/Door/Status") {
topicSwitch = 5;
}else {
topicSwitch = 6;
}
switch (topicSwitch) {
case 1:
{
float temp = getTemperatureF();
String tempString = String(temp);
Serial.println("Temperature Requested");
Serial.print("Current Temperature ");
Serial.println(temp);
sendMsg("chickenCoop/Temperature", tempString);
break;
}
case 2:{// For Light Control
if (arduinoComs.available()>0) {
arduinoComs.print("LightState");
sendMsg("chickenCoop/Light", "Light Command Sent");
delay(5000);
char lightMsg = arduinoComs.read();
String lightMsg2 = String(lightMsg);
Serial.println(lightMsg);
sendMsg("chickenCoop/Light", lightMsg2);
arduinoComs.flush();
}else{
sendMsg("chickenCoop/Errors", "Serial Port Has Failed - Light State");
}
break;
}
case 3: {
//For Light Status
if (arduinoComs.available()>0) {
arduinoComs.print("LightStatus");
sendMsg("chickenCoop/Light", "Checking Light Status");
delay(5000);
char lightStatusMsg = arduinoComs.read();
String lightStatusMsg2 = String(lightStatusMsg);
Serial.println(lightStatusMsg2);
sendMsg("chickenCoop/Light", lightStatusMsg2);
arduinoComs.flush();
}else{
sendMsg("chickenCoop/Errors", "Serial Port Has Failed - Light Status");
}
break;
}
case 4:{ //Door Control and Status Messages
if (arduinoComs.available()>0) {
arduinoComs.print("DoorState");
sendMsg("chickenCoop/Door", "Door Command Sent");
delay(5000);
char doorMsg = arduinoComs.read();
String doorMsg2 = String(doorMsg);
Serial.println(doorMsg2);
sendMsg("chickenCoop/Door", doorMsg2);
arduinoComs.flush();
}else{
sendMsg("chickenCoop/Errors", "Serial Port Has Failed - Door State");
}
break;
}
case 5: {
// For Door Status
if (arduinoComs.available()>0) {
arduinoComs.print("DoorStatus");
sendMsg("chickenCoop/Door", "Checking Door Status");
delay(5000);
char doorStatusMsg = arduinoComs.read();
String doorStatusMsg2 = String(doorStatusMsg);
Serial.println(doorStatusMsg2);
sendMsg("chickenCoop/Door", doorStatusMsg2);
arduinoComs.flush();
}else{
sendMsg("chickenCoop/Errors", "Serial Port Has Failed - Door Status");
}
break;
}
case 6:
{
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
char receivedChar;
String receivedString;
for (int i=0;i<length;i++) {
receivedChar = (char)payload[i];
receivedString += receivedChar;
Serial.print(receivedChar);
}
Serial.println();
Serial.println(receivedString);
sendMsg("test/sendmsg", receivedString);
break;
}
}
}
// The following function handles all outgoing messages to the MQTT server.
void sendMsg(String loTopic, String loMsg){
String topicToSend = loTopic;
String msgToSend = loMsg;
if (client.publish((char*) topicToSend.c_str(), (char*) msgToSend.c_str()) )
{
Serial.println("Publish Succeeded!");
}
else
{
Serial.println("Publish Failed!");
}
return;
}
// The following function handles comnnecting and re-connecting to the MQTT server.
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266 Client")) {
Serial.println("connected");
// ... and subscribe to topic
client.subscribe("chickenCoop/Temperature/Command");
client.subscribe("chickenCoop/Lights/Command");
client.subscribe("chickenCoop/Door/Command");
client.subscribe("chickenCoop/Lights/Status");
client.subscribe("chickenCoop/Door/Status");
sendMsg("test/sendmsg", "Temp Connected");
//Force first temperature post, if Raspberry is running, Node-RED timer starts to continue them on schedule.
sendMsg("chickenCoop/Temperature/Command", "1");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
.
void setup_wifi() {
delay(20);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi Connected");
Serial.println("IP Address is: ");
Serial.println(WiFi.localIP());
Serial.println("");
}
// Calls for Temperature passing it back to the callback function to send to the mqtt server
float getTemperatureF(){
float tempC;
float tempF;
do {
DS18B20.requestTemperatures();
tempC = DS18B20.getTempCByIndex(0);
delay(300);
Serial.println(tempC);
}
while (tempC == 85.0 || tempC == (-127.0));
// Convert to Farhenheit
tempF = ((tempC * 1.8)+32);
return tempF;
}
void setup(){
Serial.begin(115200);
arduinoComs.begin(9600);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
DS18B20.begin();
if (arduinoComs.isListening()) {
Serial.println("arduinoComs SoftSerial ready");
}
}
void loop(){
// Check if client is connected to the MQTT server - if not call reconnect function.
if (!client.connected()) {
reconnect();
}
client.loop();
}
Using a NodeMCU ESP12-E Board - think I notice the problem. My SoftwareSerial is showing at V1.0, but curiously, if i go to the keywords file in the directory listed via verbose the Keyword is there
Went thru the verbose logs and found that instead of referencing the SoftwareSerial in AppData for Arduino, its referencing the SoftwareSerial under an ESP8266 folder in AppData, the keywords for it do not have the isListening option.