Sorry I should have explained I meant my #define s at the beginning which define the message "keys" that the safestring then gets compared to? From what I can tell these are still strings (double quote) and when I change them to single quote for char array I am getting a warning I am having trouble making sense of on the last parameter of the setRelay function
argument of type "int" is incompatible with parameter of type "const char *
very confused why it thinks it is an integer now??
anyhow, I have made a sketch with stream which seems to be producing some kind of failure. It was a little challenging because the spacing between the messages did a decent job at mitigating but some loss is definitely occurring. I still need to attach a secondary serial connection but was curious what your thoughts were.
the message set looks like this
"mi1s:1\n"
"cainv:1\n"
"caexv:1\n"
"pump:1\n"
"rtinv:1\n"
"rtexv:1\n"
"rtexv:0\n"
"pump:0\n"
"mi1s:0\n"
"rtinv:0\n"
"pump:0\n"
"caexv:0\n"
"cainv:0\n"
it powers 6 relays and then turns them off, however when I run this I only get replies to the last 7 messages rather than the whole 12. Additionally, there is no issue just turning on the 6 relays simultaneously which should rule out the possibility of a power issue, as well as the fact the relays use low level logic so they are actually using the most of the Arduinos power when all off at the beginning. When I run this sketch with echo on it pulses only the "rtexv" relay very quickly and the messages for all other relays are only 0s.
With this info you think the best next step is to monitor the safestring debug through serial1, try buffering input, or anything else? when I SafeString::setOutput(Serial); on serial0 just to see if there is anything I am not getting any errors etc... just my own SafeString::Output.print
// https://forum.arduino.cc/t/100-paid-request-serial-safestring-digital-read-write-bug-is-ruining-my-life/903396
#include "SafeStringReader.h"
#include "BufferedOutput.h"
#include "SafeStringStream.h"
// serial messages / keys and pin definitions
// air valves
#define CANOPY_IN_AV "cainv"
#define CANOPY_IN_PIN 44 // NC
#define CANOPY_EX_AV "caexv"
#define CANOPY_EX_PIN 47 // OC
#define ROOT_IN_AV "rtinv"
#define ROOT_IN_PIN 43 // NR
#define ROOT_EX_AV "rtexv"
#define ROOT_EX_PIN 46 // OR
#define AMBIENT_IN_AV "aminv"
#define AMBIENT_IN_PIN 45 // NA
#define AMBIENT_EX_AV "amexv"
#define AMBIENT_EX_PIN 48 // OA
// water solenoids
#define PASS_RADIATOR_SOL "pards" // R1
#define PASS_RAD_PIN 39
#define ROOT_RADIATOR_SOL "rtrds" // R2
#define ROOT_RAD_PIN 40
#define CANOPY_SPRAY_SOL "casps" // IC
#define CANOPY_SPRAY_PIN 41
#define CORE_IN_SOL "coins" // IR
#define CORE_IN_PIN 38
#define RETURN_IN_SOL "reins" // RE
#define RETURN_IN_PIN 37
#define ROOT_DRAIN_IN_SOL "rtdrins" // RZ
#define ROOT_DRAIN_IN_PIN 36
#define MIST_1_SOL "mi1s" // M1
#define MIST_1_PIN 35
#define MIST_2_SOL "mi2s" // M2
#define MIST_2_PIN 34
#define DRAIN_SOL "drains" // DR
#define DRAIN_PIN 33
// water pump
#define PUMP "pump"
#define PUMP_PIN 42
// lock
#define LOCK "lock"
#define LOCK_PIN 27
#define EMPTY 26
bool locked = false;
// fan
#define FAN "fan"
#define IN1 5
#define IN2 4
#define PWM 6
// SENSORS
#define HUMIDITY "humid"
#define IN_TEMP "intemp"
#define ROOT_TEMP "rttemp"
#define EX_TEMP "extemp"
#define EX_TEMP_PIN A6
#define PRESSURE "press"
#define PRESSURE_PIN A14
const int pressure_offset = 0.469;
#define RETURN_SOLUTION "resol"
#define RETURN_SOLUTION_PIN 29
#define DOOR_CLOSED "door"
#define LEFT_DOOR_CLOSE_PIN 16
#define RIGHT_DOOR_CLOSE_PIN 15
#define TOUCH "touch"
// SafeStringStream
cSF(sfTestData, 180); // the test data SafeString, will be filled in setup()
cSF(rxBuf, 64); // the extra rxbuffer for the SafeStringStream to mimic the Uno hardware serial rx buffer
SafeStringStream sfStream(sfTestData,rxBuf); // set the SafeString to be read from and the SafeString providing the rx buffer
// create an safeReader instance of SafeStringReader class
// delimited by comma, CarrageReturn or NewLine
// the createSafeStringReader( ) macro creates both the SafeStringReader (safeReader) and the necessary SafeString that holds input chars until a delimiter is found
// args are (ReaderInstanceName, expectedMaxCmdLength, delimiters)
createSafeStringReader(safeReader, 63, ",\r\n");
// Buffered output instance
createBufferedOutput(output, 63, BLOCK_IF_FULL);
bool running = true;
float pressure = 300;
void setup() {
Serial.begin(115200);
safeReader.connect(sfStream); // read the test data from the SafeStringStream
safeReader.echoOn(); // echos the read data back to be re-read again
sfTestData = F(
"mi1s:1\n"
"cainv:1\n"
"caexv:1\n"
"pump:1\n"
"rtinv:1\n"
"rtexv:1\n"
"rtexv:0\n"
"pump:0\n"
"mi1s:0\n"
"rtinv:0\n"
"pump:0\n"
"caexv:0\n"
"cainv:0\n"
); // initialized the test data
Serial.println("Test Data:-");
Serial.println(sfTestData);
Serial.println("----------");
sfStream.begin(sfTestData, 115200); // start releasing sfTestData at 9600 baud
pinMode(CANOPY_IN_PIN, OUTPUT);
pinMode(CANOPY_EX_PIN, OUTPUT);
pinMode(ROOT_IN_PIN, OUTPUT);
pinMode(ROOT_EX_PIN, OUTPUT);
pinMode(AMBIENT_IN_PIN, OUTPUT);
pinMode(AMBIENT_EX_PIN, OUTPUT);
pinMode(PASS_RAD_PIN, OUTPUT);
pinMode(ROOT_RAD_PIN, OUTPUT);
pinMode(CANOPY_SPRAY_PIN, OUTPUT);
pinMode(CORE_IN_PIN, OUTPUT);
pinMode(RETURN_IN_PIN, OUTPUT);
pinMode(ROOT_DRAIN_IN_PIN, OUTPUT);
pinMode(MIST_1_PIN, OUTPUT);
pinMode(MIST_2_PIN, OUTPUT);
pinMode(DRAIN_PIN, OUTPUT);
pinMode(PUMP_PIN, OUTPUT);
pinMode(LOCK_PIN, OUTPUT);
pinMode(EMPTY, OUTPUT);
allRelaysOff();
// enable error messages and SafeString.debug() output to be sent to Serial
// SafeString::setOutput(Serial);
// safeReader.connect(Serial); // where SafeStringReader will read from
// safeReader.echoOn(); // echo back all input, by default echo is off
output.connect(Serial); // Connect output buffer to serial
}
void loop() {
output.nextByteOut(); // Send next byte from serial buffer
processSerial();
}
void processSerial(){
if(safeReader.read()){
SafeString::Output.println(safeReader);
size_t colonIdx = 0;
colonIdx = safeReader.indexOf(':');
if (colonIdx < safeReader.length()){ // Command needs data parsing
// safeString parsing variables
createSafeString(command, 9);
createSafeString(data, 11);
long dataLong;
float dataFloat;
// Parse
safeReader.substring(command, 0, colonIdx); // extract command before colon
safeReader.substring(data, colonIdx+1); // extract data after colon
if (data.toLong(dataLong)){ // type long parse (fails with decimal)
SafeString::Output.print(F("Long data detected: "));
SafeString::Output.println(dataLong);
// output.println(safeReader);
if (command == CANOPY_IN_AV){ // canopy in air valve
setRelay(CANOPY_IN_PIN, bool(dataLong), CANOPY_IN_AV);
} else if (command == CANOPY_EX_AV){ // canopy exhaust air valve
setRelay(CANOPY_EX_PIN, bool(dataLong), CANOPY_EX_AV);
} else if (command == ROOT_IN_AV){ // root in air valve
setRelay(ROOT_IN_PIN, bool(dataLong), ROOT_IN_AV);
} else if (command == ROOT_EX_AV){ // root exhaust air valve
setRelay(ROOT_EX_PIN, bool(dataLong), ROOT_EX_AV);
} else if (command == AMBIENT_IN_AV){ // ambient in air valve
setRelay(AMBIENT_IN_PIN, bool(dataLong), AMBIENT_IN_AV);
} else if (command == AMBIENT_EX_AV){ // ambient ehaust air valve
setRelay(AMBIENT_EX_PIN, bool(dataLong), AMBIENT_EX_AV);
} else if (command == PASS_RADIATOR_SOL){ // pass through radiator solenoid
setRelay(PASS_RAD_PIN, bool(dataLong), PASS_RADIATOR_SOL);
} else if (command == ROOT_RADIATOR_SOL){ // root radiator solenoid
setRelay(ROOT_RAD_PIN, bool(dataLong), ROOT_RADIATOR_SOL);
} else if (command == CANOPY_SPRAY_SOL){ // canopy spray solenoid
setRelay(CANOPY_SPRAY_PIN, bool(dataLong), CANOPY_SPRAY_SOL);
} else if (command == CORE_IN_SOL){ // core intake solution solenod
setRelay(CORE_IN_PIN, bool(dataLong), CORE_IN_SOL);
} else if (command == RETURN_IN_SOL){ // return intake solenoid
setRelay(RETURN_IN_PIN, bool(dataLong), RETURN_IN_SOL);
} else if (command == ROOT_DRAIN_IN_SOL){ // root drain intake solenoid
setRelay(ROOT_DRAIN_IN_PIN, bool(dataLong), ROOT_DRAIN_IN_SOL);
} else if (command == MIST_1_SOL){ // mist 1 solenoid
setRelay(MIST_1_PIN, bool(dataLong), MIST_1_SOL);
} else if (command == MIST_2_SOL){ // mist 2 solenoid
setRelay(MIST_2_PIN, bool(dataLong), MIST_2_SOL);
} else if (command == DRAIN_SOL){ // drain solenoid
setRelay(DRAIN_PIN, bool(dataLong), DRAIN_SOL);
} else if (command == PUMP){ // water pump
setRelay(PUMP_PIN, bool(dataLong), PUMP);
}
}
} else { // else no data command
readPressure();
}
}
}
// Send outgoing message with colon
// could pass SafeString & here but seems an overkill
void transmitSerial(const char*key, const char*data) {
output.print(key); output.print(F(":"));
output.println(data);
}
// set relay true = on false = off
void setRelay(int pin, bool setting, const char*reply_key){
digitalWrite(pin, !setting);
cSF(sfData, 10);
sfData = !digitalRead(pin);
transmitSerial(reply_key, sfData.c_str()); //String(!digitalRead(pin)));
// transmitSerial(reply_key, String(!setting));
// Serial.println(reply_key + ':' + String(!digitalRead(pin)));
}
// all relays off
void allRelaysOff(){
digitalWrite(CANOPY_IN_PIN, HIGH);
digitalWrite(CANOPY_EX_PIN, HIGH);
digitalWrite(ROOT_IN_PIN, HIGH);
digitalWrite(ROOT_EX_PIN, HIGH);
digitalWrite(AMBIENT_IN_PIN, HIGH);
digitalWrite(AMBIENT_EX_PIN, HIGH);
digitalWrite(PASS_RAD_PIN, HIGH);
digitalWrite(ROOT_RAD_PIN, HIGH);
digitalWrite(CANOPY_SPRAY_PIN, HIGH);
digitalWrite(CORE_IN_PIN, HIGH);
digitalWrite(RETURN_IN_PIN, HIGH);
digitalWrite(ROOT_DRAIN_IN_PIN, HIGH);
digitalWrite(MIST_1_PIN, HIGH);
digitalWrite(MIST_2_PIN, HIGH);
digitalWrite(DRAIN_PIN, HIGH);
digitalWrite(PUMP_PIN, HIGH);
digitalWrite(LOCK_PIN, HIGH);
digitalWrite(EMPTY, HIGH);
}
// read pressure
void readPressure(){
static float voltage, pressure;
// Calculations
voltage = analogRead(PRESSURE_PIN) * 5.0 / 1024.0; // Calculate the voltage
pressure = (voltage - pressure_offset) * 400.0; // Calculate water pressure
cSF(sfData, 10);
sfData = pressure;
transmitSerial(PRESSURE, sfData.c_str());
}