Print out integer received from function after initial string

Before we start I’m not 100% sure how to explain this so hopefully you understand;
I’ve currently got my photon speaking to an Arduino over bluetooth. Im currently trying to receive an integer from a webpage, using the Particle.function() I have managed to get the particle to send data over bluetooth when a simple string is received however I wish to parse the two digits after the string ‘SET:’ and send them over bluetooth, can anyone help me with this?

int currentTemp; // Current Temperature in room
int receivedTemp; // Temperature received



//From/to the internet
int inTemp(String command); //Temperature received from        web/application


void setup() 
{
    Serial1.begin(9600);
    Particle.variable("Temp", currentTemp);
    Particle.function("setTemp", inTemp);
}
    
void loop(){
   //Nothing to see here
}


int inTemp(String command)
{
    if(command.substring(0,4) == "SET:"){
        receivedTemp = (command.charAt(4) - ' ');
             if(Serial1.available())
             {
                Serial1.write(receivedTemp);
             }
        return 1;
    }   
    else {
            return -1;
        }
}

Hmm, what is this doing?

Do you intend to transfer binary or ASCII representation of your number?

I thought this would get the numbers after the 4th character in the command string but evidently it doesnt :smile: which I believe is the problem that I am facing

You’d rather use something like this

  receivedTemp = command.substring(4).toInt(); 

But with Serial1.write(receivedTemp); you’d transfer binary and AFAIK only the LSB of that int.
If you want ASCII you should use Serial1.print(receivedTemp);.

2 Likes

oh dear I feel so stupid completely forgot about the .toInt(), but I have edited my code and it is working!

Thanks for your help!

3 Likes

I’ve now run into a different problem, im trying to use the http GET variable using MIT app inventor 2 and I have managed to display some sort of input however it does not show the correct ‘double’ that is being sent from my Arduino. I believe it is something to do with the coding on my photon.

Here is the coding

 //From/to the valve
    int roomTemp; // Temperature received from the valve
    int receivedTemp; // Temperature received from app
    double currentTemp; // Temperature to be sent to app
    
    

//From/to the internet
int inTemp(String command); //Temperature received from application
int valveTemp(String command1); //Call to get current temp off valve


void setup() 
{
    Serial1.begin(9600);
    Particle.variable("rTemp", currentTemp); //current temp to be output to app
    Particle.function("vTemp", valveTemp); //current temp call on valve
    Particle.function("setTemp", inTemp);  //temp received by app
}
    
    
    
    
void loop(){
    //Nothing to see here
}


int valveTemp(String command1)
{
    if(command1.substring(0,4) == "GET:")
    {
        if(Serial1.available())
        {
            Serial1.print("GET:");
            delay(1000);
            roomTemp = Serial.read();
            delay(1000);
            currentTemp = roomTemp;
        }
        return 1;
    }
    else{
        return -1;
    }
}



int inTemp(String command)
{
    if(command.substring(0,4) == "SET:"){
        receivedTemp = command.substring(4).toInt();
             if(Serial1.available())
             {
                 Serial1.print(receivedTemp);
             }
        return 1;
    }
    
    else {
        return -1;
    }
}

Current prototype code for arduino

int ledPin = 13;
String readString;
String inString = "";
double temp = 24;             // decimal value for read temperature from LM35




int tempPin = 1;        //Temperature pin for LM35

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT); 
  Serial.println("Starting Up!"); 
}

void loop() {

  while (Serial.available()) {
    delay(100);  
    char c = Serial.read();
    readString += c; 
  }

  if (readString.length() >0) {
    Serial.println(readString);

    if (readString == "GET:")    
    {
      Serial.print(temp);
      delay(1000);
    }
    
    int inChar = Serial.read();    
    if (isDigit(inChar)) {
      inString +=(char)inChar;
      Serial.println(inString.toInt());  
      
    }
    readString="";
  } 
}

First you should keep your Particle.function()s short and fast. So no delay(1000) and long running loops.

Next I don’t see how the interaction between the two devices should start. Both seem to be waiting for the other to do the first print(), but the only unconditional print() happens in setup() on the Arduino. If this is missed, we have a deadlock (I guess).
On the other hand the Photon seems to read only one byte via USB each time valveTemp() is called, but the Serial1 input buffer is never read.

I’m also unable to find the place where temp is set on the Arduino side, or are you only testing with constant 24?

So you might have to rethink the whole structure.

For test purposes you could even leave the Arduino out and only have the Photon talk to itself (RX <-> TX).

1 Like

Unrelated to the issue, but… is there a specific reason you need the arduino? If you only want to measure some sensors, you can save yourself the communication headache and just use the Photon instead. Just a thought.

1 Like

Sorry I should have clarified earlier on, Im planning on putting the Arduino in a remote location and running it off double A batteries for months at a time putting it to sleep when its not in use, so the photon is used as a gateway to constantly check for data coming in from my app then passing it on and essentially waking up the Arduino

Then you might be interested in bluz, which is made for exactly this. It also runs on the Particle ecosystem, making it really easy to work with. There’s a powered gateway, which can connect to up to 8 nodes. Check it out, might be what you’re looking for :smile:

2 Likes

I’ve actually pre ordered a bluz which is due to arrive mid February and like you said they seem very easy to work with except I am determined to try make my current set up work before that arrives because I’ve came so far with it :grin:

1 Like

Thanks for the advice I have removed the delays from the function. The interaction originally starts from the APP as it uses HTTP POST and GET commands to talk to the photon.

When “SET:” is received by the photon it forwards the int select on the app to the Arduino.
When “GET:” is received the photon requests the current temperature (for testing this is set as 24 as you asked) stores it and then outputs it with the Particle.variable() function defined to the application.

I can get both functions to work correctly the part I am struggling with is receiving the int from the arduino > photon > app.

OK, I’m still not convinced that your flow actually works as you intend.
But nevertheless I think I’ve located some possible issues in this part

int valveTemp(String command1)
{
  ...
  Serial1.print("GET:");
  delay(1000);
  roomTemp = Serial.read();  // <-- here you are reading from USB, is this intended?
                             // but even if, you are only reading one byte
                             // either way transfering from Arduino via `Serial.print()` or
                             // via USB Serial terminal, you'll probably have an ASCII representation
                             // of the number being made up of several digits which
                             // would require multiple reads and parsing into a numeric type
  ...
}

Ah sorry I should have said I added serial1.read() to read from the bluetooth module earlier when you mentioned it, the values I am receiving to my app are varying from 1 - 255 each time I call the currentTemp variable, but it is never the correct value that should be sent as ASCII.

EDIT: I’ve discovered that I can parse.Int() when a serial is read, this does display the correct temperature that I set on my Arduino

If you want to transfer a number binary, you’d need to use Serial.write(value)
If sending via Serial.print(value) you could do the reading like this

int valveTemp(String command1)
{
    char num[16];
    int idx = 0;
    
    if(command1.substring(0,4) == "GET:")
    {
        if(Serial1.available())
        {
            Serial1.print("GET:");
            delay(100);
            
            while(Serial1.available())
            {
                num[idx++] = Serial1.read();
                if (idx >= 15) break;
            }
            num[idx] = 0;
            roomTemp = atoi(num);
            Serial.print(num);
            delay(100);
            currentTemp = roomTemp;
        }
        return roomTemp;
    }
    return -1;
}

But using this way, I receive GET: in addition which was part of my doubts about the communication flow.

Edit: Sure Serial1.parseInt() does it more conveniently, but knowing how to do it “by hand” might become useful sometime :wink:

I’ve had a read through your code and implemented it into my code and is still not returning the correct value, it only displays a ‘0’?

The Serial1.parseInt() ( lazy coder way) does display the correct value after about three calls for the variable, would it be safe to implement a delay within the function even though you advised against it earlier in the post :smile:

I’d still say it’s related to your code flow.
Asynchronous code is not always easy to plan and code.

For example: You read as long as data is there to build your readString = "GET:" on the Arduino side, but it might not yet be finished, so you will not satisfy your following conditions impacting all following reads. Seperating packets just by time is no robust solution!
You either should tokenize or at least terminate your data and parse the data accordingly.


BTW: I tried your original code with my adapted int valveTemp(String command1) on two Photons (using Serial1 on both ;-)) and it does “work”.
Granted, only after the second or third time calling vTemp("GET:") and only via the Serial.print(num) statement and not a roomTemp, but this is due to the said (suspected) error in code flow.
And exactly this is the reason why doing it manually is useful, since you can see and debug things better than having to guess what happens inside a “black box” like parseInt(), where you don’t ever get to see the received data.

1 Like

Thanks for the update, I have not looked at the project this week however the last time I tried it was still receiving after the second or third “GET:” call. It also does not seem to pass the input data “received temp” to the valve as it always displays a zero.
Tonight I am going to try and implement the manual way like you said and I was thinking about using a switch case rather than two if statements on my Arduino.

Yes, this is what I meant with that

Since there is no clean seperation beteween the value and the next GET: the atoi() translation fails and returns 0. With a clean flow control packet seperation will help this issue.

How would you suggest doing this as an alternative method to what I am doing now, seeing as it is not working properly. Would the best method be to send a set of integers from the photon rather than a string, then perhaps send the same integers back separated by a comma with the temperature reading after then maybe send a final two integers after also separated by a comma. That way when the photon receives the final two digits it should be able to parse correctly?

I.e.

Photon - send 34 (equivalent of sending get)
Arduino receives 34, performs temperature read then sends data over serial such as: 34,(temperature-reading),34.
Once they both have sent/recieved the final 34 they can clear the serial buffer ready for the next instruction

Would this be a better solution or will I still encounter the same problem?