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

In callback(), payload is an argument, of type pointer to byte. You need to copy this data to a global variable, so that it can be used in another function.

What have you tried? There are only 7 lines of code needed - two to declare the variables and 5 to copy the data, using a for loop. Two of those lines of code are the open and close curly braces.

byte copyOfPayload[80];
int payloadSize;
for(byte i=0; i<length; i++)
{
   copyOfPayload[i] = payload[i];
}
payloadSize = length;

Now that you have copies of the data passed to callback(), you can use them in update().

Hi PaulS,

Thanks for that, I can see how its done now, not as complicated as I thought, Will come in handy for the future now.

Just one problem left I pass "test" into the callback, it sends it back to the MQTT server but it comes back as "estt"

I have added update1 so that I can see the text changing.

//My addition to original code:

    #include <SPI.h>
    #include <Ethernet.h>
    #include <PubSubClient.h>
      
    byte copyOfPayload[80];
    int payloadSize;

    byte server[] = {192,168,1,64};                                                       
    byte ip[]     = {192,168,1,1};                                                          
    byte mac[]    = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF };                                 

    // 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);

      for(byte i=0; i<length; i++)
        {
           copyOfPayload[i] = payload[i];
        }
      payloadSize = length;
    }


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


void update()
{ 
  client.publish("outTopic", copyOfPayload , payloadSize);
}


void update1()
{
  char *payload = "blank";
  int length = strlen(payload);
  client.publish("outTopic", (byte *)payload , length);
  Serial.println (payload);
}


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

Hi PaulS,

I have solved that last problem, I remeber I had it before, if the following line was not at the end of the routine it would become corrupt,
but have no idea why, but putting it at the end solves the text error.

client.publish("outTopic", payload, length);
See the code below as it has a note about this.

Thanks for your time PaulS, it was most helpful.

Regards
Gary

Added the working code here, for anyone that may read this in the future.

//My addition to original code:

    #include <SPI.h>
    #include <Ethernet.h>
    #include <PubSubClient.h>
      
    byte copyOfPayload[80];
    int payloadSize;

    byte server[] = {192,168,1,64};                                                       
    byte ip[]     = {192,168,1,1};                                                          
    byte mac[]    = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF };                                 

    // 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) {
    //

      for(byte i=0; i<length; i++)
        {
           copyOfPayload[i] = payload[i];
        }
     
       payloadSize = length;
            
       client.publish("outTopic", payload, length); // NOTE must be placed at end of routine or else it gets corrupted
    }


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


void update()
{ 
  client.publish("outTopic", copyOfPayload , payloadSize);
}


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


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