Unable to get the serial1 read to work correctly

Hello Everyone!,

This is my first post on the particle community. I am stuck with a simple project already! :confused:

I am trying to get the serial1 (TX RX pins) read function working and to do something if it reads the right text. This code works fine on the Arduino but it does not seem to want to work on the Particle Photon.
I know I can use just one byte, like a number which will perhaps work but I’m trying to get a string of text to work as it is easier to understand without having to look up what the number correlates too. :disappointed:

Here is a look at the code. I want it to use the Particle.publish feature if it reads text from the serial1 (TX RX pins) but it just seems to want to read each letter on it’s own :cry:

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() {
  String input = "";
  while (Serial1.available() > 0){
    input += (char) Serial1.read();
    delay(5);
    Serial.println(input);
  }
  if (input == "IFTTT-HUE-ON") {
    Serial.println("Hue On Sent");
    Particle.publish("Hue", "ON");
  }
  if (input == "IFTTT-HUE-OFF") {
    Serial.println("Hue Off Sent");
    Particle.publish("Hue", "OFF");
  }
}

I have tried changing “while” with “if” but that also does not work. I have tried read until \n function, that will output on serial (usb) the exact text but then the if statement does not want to seem to work, it doesn’t even print the sent text. The Particle.publish command’s does work fine if I put them in the setup() of the code, that has all been setup and works fine.

If anyone can help me I will be very grateful.

Thanks everyone!,

James

How do you provide your data to the device?
Since your input is local you’ll loose all the already read data, so if you are not perfectly in sync with loop() and rather quick with entering your data, you might be out of luck with this approach.

It is just from an Arduino Nano. It is the same from a seperate USB serial only device aswell. For example I have just got this code on the Nano:

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.print("Test");
  delay(1000);
}

and all I am getting out of the Particle Photon is :

T
e
s
t

Even if I change the Nano code from Serial.print to Serial.write, it does the same thing aswell. This would perhaps be why the Photon's IF statments are not working as it seems to be reading each character on its own line rather than reading it as "Test".

You’re resetting input to be an empty string on every iteration of loop. There is no guarantee all input data will be available in a single loop. In fact, it’s pretty much guaranteed to not be.

You should make input a global variable and accumulate data in input until you get some sort of a delimiter, like an LF, you have a valid command, etc…

If I chage the code of the Nano to:

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.print("A");
  delay(1000);
}

And the Photon to:

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() {
  String input = "";
  if (Serial1.available() > 0){
    input += (char) Serial1.read();
    delay(5);
    Serial.println(input);
  }
  if (input == "A") {
    Serial.println("Hue On Sent");
    Particle.publish("Hue", "ON");
  }
  if (input == "IFTTT-HUE-OFF") {
    Serial.println("Hue Off Sent");
    Particle.publish("Hue", "OFF");
  }
}

I get out of the Photon:

A
Hue On Sent

And it works as expected, every time. Does not seem to be a sync issue. It just cannot read a string of text otherwise it just does what my last replay says. It is strange though, as the code to read would read fine on two Arduino's "talking" to each other.

Right, because Serial.read() reads a single byte. The problem is that in a call to loop only a single byte of data may be available when you call serial.available(). It will almost certainly take several calls to loop() before you get a whole string, which is why you can’t start with an empty input string on every call to loop.

1 Like

The clock speed on an Arduino is much slower than the Photon, so it could be that you get the whole string in one turn of the loop there, but not with he Photon. You should try what both @rickkas7 and @ScruffR have suggested.

2 Likes

Ah right I understand. That would make sense. Would anyone know what sort of code I should use then in this case? I’m not too sure myself. Just tried a direct input of a string of text via the COM port of the Photon and it does the same thing I have been having the issue with.

Move the line, String input = “”; out of loop to the top of the file to make it global. You can reset it back to empty inside your 2 if statements. That will work for a quick check to see if this fixes the problem. However, input would never get reset to empty if you don’t receive one of those two strings.

That sort of works with the long string of text. I can call the “IFTTT-HUE-OFF” function now and that comes back with “Hue Off Sent”. How to reset the input string after it has received all the data though?

I’m not sure what the best way to do that is, but you can do it like I said, by putting that same line, String input = “”; inside both of your if statements. A better way to do it might depend on what you particular use case is. Will you be sending one of these 2 strings all the time? Is it an infrequent thing, or could it happen multiple times in rapid succession?

Long term for my main project it could fire many commands at a given time. The main project is for a automation alarm system, so it could send a command to say the alarm has been triggered but then right away another to trigger the lights.

In that case, I think it might be best to use a termination character as @rickkas7 suggested. Terminate all your commands with a LF, or some other unique character. When that character is received, you process the received string, and reset input to empty. You would do that inside the if(Serial1.available()) loop.

This sort of works but then the IF statments don’t work and I can’t understand why…

Nano Code:

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println("IFTTT-HUE-OFF");
  delay(1000);
}

Photon code:

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() {
  String input = "";
  if (Serial1.available() > 0){
    input = Serial1.readStringUntil('\n');
    delay(5);
    Serial.println(input);
  }

  if (input == "A") {
    Serial.println("Hue On Sent");
    Particle.publish("Hue", "ON");
  }
  if (input == "IFTTT-HUE-OFF") {
    Serial.println("Hue Off Sent");
    Particle.publish("Hue", "OFF");
  }
}

I can send just “A” or “IFTTT-HUE-OFF” and it will print the same on the serial COM port from the Photon. BUT for some reason, the Photon will not do the IF statments, IE it does not print “Hue Off Sent” back, it is just like I have missed them out all together. The string does not get reset until the start of the loop so I don’t understand why this method does not work? :cry:

I have also tried putting the if statments inside the “if (Serial1.available() > 0){” loop, that also does not work.

I’m not sure if readStringUntil includes the terminator in the result (I don’t think it does, but worth a try). Try using “$” as the terminator, and see if that shows up in your print out.

That does not seem to work at all now :disappointed:

Never mind my last post. I think the problem is that you can’t use “==” to compare 2 strings. Use the String method, compareTo(),

if (input.compareTo("A") == 0) {
    Serial.println("Hue On Sent");
    Particle.publish("Hue", "ON");
}

That also does not seem to work. I can get just 1 byte to work with the IF statment. IE “if (input == “A”) {” but for some reason it does not like the string. The last code I wrote works fine with the Arduino but not the Photon.

Hmm…, I almost out of ideas. Try printing out the length of input (with input.length() ) when you send “IFTTT-HUE-OFF” to the photon to see if it gives you 13.

It just seems to flood the serial COM with loads of 1’s :frowning: