Complier window saying "expected primary-expression before ')' token"

Hi,

I receive via my etherent board data, I am trying to send that data back out to a local server.

But although I can print it out, I cannot send it, I think its because pointers are involved,

If it helps I am using Arduino MQTT, although I don't think it matters as to my problem.
Please see API info at the end of this.

I get an error in the Arduino complier window saying "expected primary-expression before ')' token"

Hopefully you can help as I have tried for hours and still have no clue what is wrong?

regards

Gary

void callback(char* topic, byte* payload, unsigned int length)                                // Data that has been received from server.
{                    
        payload[length] = '\0';                                                                                   // Add a 'null' to the payload. 
        strPayload = String((char*)payload);                                                              // strPayload now holds the contents of the memory pointed to by payload
)
       
	   
	   
void Send_data_back_to_MQTT(void)
 { 
           
		client.publish("sensor/001/mqtt_server_in", strPayload); 	// Fail =  "expected primary-expression before ')' token"
		Serial.print(strPayload); 				// Prints OK 

}

In the API of MQTT these are the options of how to return data:

boolean publish (topic, payload)

Publishes a string message to the specified topic.

The payload must be a null-terminated string. The message is published at QoS 0 with the retain flag set to false.

Parameters

topic – the topic to publish to (char*)
payload – the message to publish (char*)

Returns

false – publish failed.
true – publish succeeded.

boolean publish (topic, payload, length)

Publishes a message to the specified topic.

The message is published at QoS 0 with the retain flag set to false.
Parameters

topic – the topic to publish to (char*)
payload – the message to publish (byte array)
length – the length of the message (byte)

Returns

false – publish failed.
true – publish succeeded.

We may need to see your entire sketch...

Why aren't you just using payload-- what's the additional purpose/benefit of strPayload?

John

You seem to have { to start the function and ) to end the function - they need to match

{                    
        payload[length] = '\0';                                                                                   
        strPayload = String((char*)payload);                                                              
)

Hi,

I have included some more of the code but the whole code is in 8 tabs in the IDE, so cannot paste all of it here.

The reason I want to send that data out in a seperate routine to the original code.
Is that the original code works correctly but is only fired when it receives data from the MQTT server and this could be seconds hours or days before an update happens.

I need to update a webpage every 1 minute as to the latest setting.

Hope that helps.

Regards

Gary

void callback(char* topic, byte* payload, unsigned int length)                              // Check the Data that has been received from MQTT server.
{              
        Serial.println("");                                                                  
        Serial.print("Payload = ");   
      
        payload[length] = '\0';                                                              
         strPayload = String((char*)payload);                                                 // strPayload now holds the contents of the memory pointed to by payload.
                                                                                                          // Use  strPayload  for comparison below
            
       if   (strPayload == "Set to 5.0")                                            
            {                                                                                
              Serial.print(" .... Set Temp To 05.0");                                        
              target_temperature = 05;
            }                
                        
     client.publish("sensor/001/mqtt_server_in", payload, length);                          // **** ORIGINAL THIS WORKS Send to MQTT server ****    
}

 
 
 
void Send_data_back_to_MQTT(void)
   { 
      
      Serial.print(strPayload);  

      client.publish("sensor/001/mqtt_server_in", strPayload);      // On attempt to compile in IDE ,get complier window saying "expected primary-expression before ')' token"
        
 }

I'd go with the non-matching braces hypothesis.
Looks pretty clear to me.
Certainly the best bet in the absence of code.

Hi,

Sorry the braces were just a typo when adding it on here, in the real code its correct.

Regards

Gary

How does cut and paste add a typo?

So post the real code that causes the error.

Hi,

See my reply #3

If theres not anything obvious there I will add more tomorrow , its just the code is about 200 lines and spread over 8 tab pages.

Thanks

Regards

Gary

Be that as it may, a paren instead of curly brace will cause exactly the error message you posted. Though in a different place

Good Luck,
John

The code in reply #3 obviously will not compile, because it is incomplete.

Please stop trying to be cute about which bits of code you post, and show the entire file that causes the compilation error, in its entirety, exactly as it was when you tried to compile it. Please post the complete output from the compiler too.

Hi,

Thanks for your patience, I have thought about how best to demonstrate what I am trying to achieve
and its actually best to show you the original file I downloaded fron the net.
It requires a lib and I have attached this. Also in the second piece of code shows you what I have added.

The purpose of my changes are to update a MQTT server with latest data every 15 seconds
As the original would only update on a received message. which may be seconds or hours away.

Obviously there is a definite fault and its different to the title of this thread.
But it is caused by what I am trying to achieve, it uses pointers and I have
never worked with them. And i do not know how to declare them satifactorly for this to compile.

The errors given are as follows:

Test_MQTT_V1_0.cpp: In function 'void update()':
Test_MQTT_V1_0:35: error: 'payload' was not declared in this scope
Test_MQTT_V1_0:35: error: 'length' was not declared in this scope

Original code:


/*
 Publishing in the callback 
 
  - connects to an MQTT server
  - subscribes to the topic "inTopic"
  - when a message is received, republishes it to "outTopic"
  
  This example shows how to publish messages within the
  callback function. The callback function header needs to
  be declared before the PubSubClient constructor and the 
  actual callback defined afterwards.
  This ensures the client reference in the callback function
  is valid.
  
*/

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.
byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
byte server[] = { 172, 16, 0, 2 };
byte ip[]     = { 172, 16, 0, 100 };

// Callback function header
void callback(char* topic, byte* payload, unsigned int length);

EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);

// Callback function
void callback(char* topic, byte* payload, unsigned int length) {
  client.publish("outTopic", payload, length);
}

void setup()
{
  
  Ethernet.begin(mac, ip);
  if (client.connect("arduinoClient")) {
    client.publish("outTopic","hello world");
    client.subscribe("inTopic");
  }
}

void loop()
{
  client.loop();
}
My addition to original code:


#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.
byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
byte server[] = { 172, 16, 0, 2 };
byte ip[]     = { 172, 16, 0, 100 };

// Callback function header
void callback(char* topic, byte* payload, unsigned int length);

EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);

// Callback function = only received at random intervals could be seconds hours or days.
void callback(char* topic, byte* payload, unsigned int length) {
  client.publish("outTopic", payload, length);
}

void setup()
{
  
  Ethernet.begin(mac, ip);
  if (client.connect("arduinoClient")) {
    client.publish("outTopic","hello world");
    client.subscribe("inTopic");
  }
}

void update()
{
  client.publish("outTopic", payload, length);
}

void loop()
{
  client.loop();
  delay (15000); 
  update();       // Update after 15 seconds
  
}

pubsubclient-1.9.zip (8.55 KB)

The error is in this function:

void update()
{
  client.publish("outTopic", payload, length);
}

It looks as if it is based on this function:

void callback(char* topic, byte* payload, unsigned int length) {
  client.publish("outTopic", payload, length);
}

In the original, the payload and length are being passed in by the PubSubClient, presumably obtained from an incoming message.

Now that you're publishing messages spontaneously you will need to decide what payload you're going to send. I'm not sure what 'latest data' means. You could either remember the last incoming payload (by saving it in a global variable) and keep sending that, or get the payload from some other source. But you need to provide the payload somehow. Here is my guess at how you'd use a hard-coded constant payload containing an ASCII string:

// incomplete, uncompiled, untested
void update()
{
  byte *payload = "my payload";
  int length = strlen(payload);
  client.publish("outTopic", payload , length);
}

Hi PeterH,

Thanks for tyhe reply, tried your code and now it comes up with:

Test_MQTT_V1_0.cpp: In function 'void update()':
Test_MQTT_V1_0:36: error: invalid conversion from 'const char*' to 'byte*'
Test_MQTT_V1_0:37: error: invalid conversion from 'byte*' to 'const char*'
Test_MQTT_V1_0:37: error: initializing argument 1 of 'size_t strlen(const char*)'

Now that you're publishing messages spontaneously you will need to decide what payload you're going to send. I'm not sure what 'latest data' means. You could either remember the last incoming payload (by saving it in a global variable) and keep sending that, or get the payload from some other source.

Yes the latest data is sent from a server when it has new data.
I think although I may be wrong, 'payload' remains in memory until it receives a new update.

Thanks so far

regards

Gary

Thanks for tyhe reply, tried your code and now it comes up with:

We need to see HOW you integrated that snippet in YOUR code yo determine what YOU did wrong. Most likely, all that is needed is some casting.

Hi PaulS

This how I added the code

regards

Gary

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.
byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
byte server[] = { 172, 16, 0, 2 };
byte ip[]     = { 172, 16, 0, 100 };

// Callback function header
void callback(char* topic, byte* payload, unsigned int length);

EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);

// Callback function = only received at random intervals could be seconds hours or days.
void callback(char* topic, byte* payload, unsigned int length) {
  client.publish("outTopic", payload, length);
}

void setup()
{
  
  Ethernet.begin(mac, ip);
  if (client.connect("arduinoClient")) {
    client.publish("outTopic","hello world");
    client.subscribe("inTopic");
  }
}


void update()
{
  byte *payload = "my payload";
  int length = strlen(payload);
  client.publish("outTopic", payload , length);
}


void loop()
{
  client.loop();
  delay (15000); 
  update();       // Update after 15 seconds
  
}

This how I added the code

void update()
{
  byte *payload = "my payload";
  int length = strlen(payload);
  client.publish("outTopic", payload , length);
}

"my payload" is a string - a null terminated array of chars. That's what strlen() expects. If you are going to point to that string, you need a char pointer.

Then, if client.publish() expects the second argument to be a pointer to byte, lie to it and tell it that that is what payload is:

void update()
{
  char *payload = "my payload";
  int length = strlen(payload);
  client.publish("outTopic", (byte *)payload , length);
}

Although, why you would publish the constant string "my payload" over and over is a mystery. That is not what PeterH was suggesting.

Hi PaulS,

Thanks that compiles and now works sending the string to my MQTT server.

Now all i need is to get the variable from:
void callback() 'byte* payload'

in place of the dummy "my payload"
Please find highlighted with *** below in routine 'update()'

Any ideas ?

regards

Gary

//My addition to original code:


#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.
byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xEF };
byte server[] = {192,168,1,64};     
byte ip[]     = {192,168,1,1};

// Callback function header
void callback(char* topic, byte* payload, unsigned int length);

EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);


// Callback function = only received at random intervals could be seconds hours or days.
void callback(char* topic, byte* payload, unsigned int length) 
{
  client.publish("outTopic", payload, length);
}

void setup()
{
  Ethernet.begin(mac, ip);
  
  if (client.connect("arduinoClient")) {
     client.publish("outTopic","hello world");
     client.subscribe("inTopic");
  }
}


void update()
{
  char *payload = "my payload"; // *** Need this to get variable from byte* payload in 'void callback' code above ***
  int length = strlen(payload);
  client.publish("outTopic", (byte *)payload , length);
}

void loop()
{
  client.loop();
  delay (1000); 
  update();       // Update after 1 second
}

callback describes the purpose of the function, but is a really crappy name for the function.

When the PubSubClient instance has something to report, it does so be calling that function.

You'll need to copy the data from the payload argument to some global variable (that is an array), and use the data in the global array in the update() function.

Hi,

I have tried various ways of trying to do what PaulS said, but cannot figure out how to do it.
I have googled arrays, pointers, chars and Strings, I do understand more but not yet enough to make the code work.
And am now a bit overwhelmed by it all :~

If someone could help that would be appreciated, then when I have the answer I will google again to find out how it works.

My code is still that same as my last reponse.

Thanks

regards

Gary