Using a variable in F macros

I'm really new to coding so please know I'll use wrong terms and try to learn whenever corrected.

My problem has something to do with an F macro line. It's a code to send emails through smtp server and has this line:

client.println(F("To:  JohnSmith@gmail.com"));

But I want to change the code so that is uses a char[] variable. In this code, I want to use the char[] blynk_token. I was thinking this:

client.println(F("To:  blynk_token"), blynk_token[32]);

But I get errors compiling like this:
What am I doing wrong? Thanks for looking.

C:\Users\JohnSmith\Documents\Arduino\ExampleCode1\ExampleCode1.ino: In function 'byte sendEmail2()':

ExampleCode1:262: error: call of overloaded 'println(const __FlashStringHelper*, int)' is ambiguous

client.println(F("RCPT To: blynk_token"), (int)blynk_token[32]);

^

C:\Users\JohnSmith\Documents\Arduino\ExampleCode1\ExampleCode1.ino:262:65: note: candidates are:

In file included from C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Stream.h:26:0,

from C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/HardwareSerial.h:31,

from C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Arduino.h:245,

from sketch\ExampleCode1.ino.cpp:1:

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:83:16: note: size_t Print::println(unsigned char, int)

size_t println(unsigned char, int = DEC);

^

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:83:16: note: no known conversion for argument 1 from 'const __FlashStringHelper*' to 'unsigned char'

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:84:16: note: size_t Print::println(int, int)

size_t println(int, int = DEC);

^

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:84:16: note: no known conversion for argument 1 from 'const __FlashStringHelper*' to 'int'

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:85:16: note: size_t Print::println(unsigned int, int)

size_t println(unsigned int, int = DEC);

^

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:85:16: note: no known conversion for argument 1 from 'const __FlashStringHelper*' to 'unsigned int'

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:86:16: note: size_t Print::println(long int, int)

size_t println(long, int = DEC);

^

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:86:16: note: no known conversion for argument 1 from 'const __FlashStringHelper*' to 'long int'

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:87:16: note: size_t Print::println(long unsigned int, int)

size_t println(unsigned long, int = DEC);

^

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:87:16: note: no known conversion for argument 1 from 'const __FlashStringHelper*' to 'long unsigned int'

ExampleCode1:269: error: call of overloaded 'println(const __FlashStringHelper*, int)' is ambiguous

client.println(F("To: blynk_token"), (int)blynk_token[32]);

^

C:\Users\JohnSmith\Documents\Arduino\wireless_gunsafe_4_parameterCHANGE_email1\wireless_gunsafe_4_parameterCHANGE_email1.ino:269:61: note: candidates are:

In file included from C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Stream.h:26:0,

from C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/HardwareSerial.h:31,

from C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Arduino.h:245,

from sketch\wireless_gunsafe_4_parameterCHANGE_email1.ino.cpp:1:

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:83:16: note: size_t Print::println(unsigned char, int)

size_t println(unsigned char, int = DEC);

^

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:83:16: note: no known conversion for argument 1 from 'const __FlashStringHelper*' to 'unsigned char'

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:84:16: note: size_t Print::println(int, int)

size_t println(int, int = DEC);

^

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:84:16: note: no known conversion for argument 1 from 'const __FlashStringHelper*' to 'int'

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:85:16: note: size_t Print::println(unsigned int, int)

size_t println(unsigned int, int = DEC);

^

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:85:16: note: no known conversion for argument 1 from 'const __FlashStringHelper*' to 'unsigned int'

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:86:16: note: size_t Print::println(long int, int)

size_t println(long, int = DEC);

^

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:86:16: note: no known conversion for argument 1 from 'const __FlashStringHelper*' to 'long int'

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:87:16: note: size_t Print::println(long unsigned int, int)

size_t println(unsigned long, int = DEC);

^

C:\Users\JohnSmith\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.h:87:16: note: no known conversion for argument 1 from 'const __FlashStringHelper*' to 'long unsigned int'

exit status 1
call of overloaded 'println(const __FlashStringHelper*, int)' is ambiguous

First Half of CODE

#include <FS.h>                   //this needs to be first, or it all crashes and burns...

#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino

//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager

#include <ArduinoJson.h>          //https://github.com/bblanchon/ArduinoJson

//define your default values here, if there are different values in config.json, they are overwritten.
char mqtt_server[40];
char mqtt_port[6] = "8080";
char blynk_token[34] = "YOUR_BLYNK_TOKEN";

char server[] = "mail.smtpcorp.com";    //email

#define Tilt 4

WiFiClient client;   //email

//flag for saving data
bool shouldSaveConfig = false;

//callback notifying us of the need to save config
void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println();
pinMode(Tilt, INPUT);
  //clean FS, for testing
  //SPIFFS.format();

  //read configuration from FS json
  Serial.println("mounting FS...");

  if (SPIFFS.begin()) {
    Serial.println("mounted file system");
    if (SPIFFS.exists("/config.json")) {
      //file exists, reading and loading
      Serial.println("reading config file");
      File configFile = SPIFFS.open("/config.json", "r");
      if (configFile) {
        Serial.println("opened config file");
        size_t size = configFile.size();
        // Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);

        configFile.readBytes(buf.get(), size);
        DynamicJsonBuffer jsonBuffer;
        JsonObject& json = jsonBuffer.parseObject(buf.get());
        json.printTo(Serial);
        if (json.success()) {
          Serial.println("\nparsed json");

          strcpy(mqtt_server, json["mqtt_server"]);
          strcpy(mqtt_port, json["mqtt_port"]);
          strcpy(blynk_token, json["blynk_token"]);

        } else {
          Serial.println("failed to load json config");
        }
      }
    }
  } else {
    Serial.println("failed to mount FS");
  }
  //end read



  // The extra parameters to be configured (can be either global or just in the setup)
  // After connecting, parameter.getValue() will get you the configured value
  // id/name placeholder/prompt default length
  WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
  WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 5);
  WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 32);

  //WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;

  //set config save notify callback
  wifiManager.setSaveConfigCallback(saveConfigCallback);

  //set static ip
  //wifiManager.setSTAStaticIPConfig(IPAddress(10,0,1,99), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
  
  //add all your parameters here
  wifiManager.addParameter(&custom_mqtt_server);
  wifiManager.addParameter(&custom_mqtt_port);
  wifiManager.addParameter(&custom_blynk_token);

  //reset settings - for testing
  wifiManager.resetSettings();

  //set minimu quality of signal so it ignores AP's under that quality
  //defaults to 8%
  //wifiManager.setMinimumSignalQuality();
  
  //sets timeout until configuration portal gets turned off
  //useful to make it all retry or go to sleep
  //in seconds
  //wifiManager.setTimeout(120);

  //fetches ssid and pass and tries to connect
  //if it does not connect it starts an access point with the specified name
  //here  "AutoConnectAP"
  //and goes into a blocking loop awaiting configuration
  if (!wifiManager.autoConnect("esp8266", "testing")) {
    Serial.println("failed to connect and hit timeout");
    delay(3000);
    //reset and try again, or maybe put it to deep sleep
    ESP.reset();
    delay(5000);
  }

  //if you get here you have connected to the WiFi
  Serial.println("connected...yeey :)");

  //read updated parameters
  strcpy(mqtt_server, custom_mqtt_server.getValue());
  strcpy(mqtt_port, custom_mqtt_port.getValue());
  strcpy(blynk_token, custom_blynk_token.getValue());

  //save the custom parameters to FS
  if (shouldSaveConfig) {
    Serial.println("saving config");
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.createObject();
    json["mqtt_server"] = mqtt_server;
    json["mqtt_port"] = mqtt_port;
    json["blynk_token"] = blynk_token;

    File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile) {
      Serial.println("failed to open config file for writing");
    }

    json.printTo(Serial);
    json.printTo(configFile);
    configFile.close();
    //end save
  }

  Serial.println("local ip");
  Serial.println(WiFi.localIP());
byte ret = sendEmail1();    //email
  
}

void loop() {
  // put your main code here, to run repeatedly:
if (digitalRead (Tilt) == HIGH){
  byte ret = sendEmail2(); 
}
else{
  
}

}

SECOND HALF OF FULL CODE:

byte sendEmail1()
{
  byte thisByte = 0;
  byte respCode;

  if (client.connect(server, 2525) == 1) {
    Serial.println(F("connected"));
  } else {
    Serial.println(F("connection failed"));
    return 0;
  }
  if (!eRcv()) return 0;

  Serial.println(F("Sending EHLO"));
  client.println("EHLO www.example.com");
  if (!eRcv()) return 0;
  Serial.println(F("Sending auth login"));
  client.println("auth login");
  if (!eRcv()) return 0;
  Serial.println(F("Sending User"));
  // Change to your base64, ASCII encoded user
  client.println("xxxxxxxxxx"); //<---------User
  if (!eRcv()) return 0;
  Serial.println(F("Sending Password"));
  // change to your base64, ASCII encoded password
  client.println("xxxxxxxxx");//<---------Passw
  if (!eRcv()) return 0;
  Serial.println(F("Sending From"));
  // change to your email address (sender)
  client.println(F("MAIL From: xxxxxxxxx@gmail.com"));
  if (!eRcv()) return 0;
  // change to recipient address
  Serial.println(F("Sending To"));
  client.println(F("RCPT To: JohnSmith@gmail.com"));
  if (!eRcv()) return 0;
  Serial.println(F("Sending DATA"));
  client.println(F("DATA"));
  if (!eRcv()) return 0;
  Serial.println(F("Sending email"));
  // change to recipient address
  client.println(F("To:  JohSmith@gmail.com"));
  // change to your address
  client.println(F("From: xxxxxxxx@gmail.com"));
  client.println(F("Subject: Esp8266 email test\r\n"));
  client.println(F("This is from my ESP8266\n"));
  client.println(F("This is line 2 from my ESP8266"));
  client.println(F("This is line 3 from my ESP8266"));

  client.println(F("."));
  if (!eRcv()) return 0;
  Serial.println(F("Sending QUIT"));
  client.println(F("QUIT"));
  if (!eRcv()) return 0;
  client.stop();
  Serial.println(F("disconnected"));
  return 1;
}

byte sendEmail2()
{
  byte thisByte = 0;
  byte respCode;

  if (client.connect(server, 2525) == 1) {
    Serial.println(F("connected"));
  } else {
    Serial.println(F("connection failed"));
    return 0;
  }
  if (!eRcv()) return 0;

  Serial.println(F("Sending EHLO"));
  client.println("EHLO www.example.com");
  if (!eRcv()) return 0;
  Serial.println(F("Sending auth login"));
  client.println("auth login");
  if (!eRcv()) return 0;
  Serial.println(F("Sending User"));
  // Change to your base64, ASCII encoded user
  client.println("xxxxxxxxxx"); //<---------User
  if (!eRcv()) return 0;
  Serial.println(F("Sending Password"));
  // change to your base64, ASCII encoded password
  client.println("xxxxxxxxxxx");//<---------Passw
  if (!eRcv()) return 0;
  Serial.println(F("Sending From"));
  // change to your email address (sender)
  client.println(F("MAIL From: xxxxxxxxx@gmail.com"));
  if (!eRcv()) return 0;
  // change to recipient address
  Serial.println(F("Sending To"));
  client.println(F("RCPT To: blynk_token"), blynk_token[32]);
  if (!eRcv()) return 0;
  Serial.println(F("Sending DATA"));
  client.println(F("DATA"));
  if (!eRcv()) return 0;
  Serial.println(F("Sending email"));
  // change to recipient address
  client.println(F("To:  blynk_token"), blynk_token[32]);
  // change to your address
  client.println(F("From: xxxxxxxx@gmail.com"));
  client.println(F("Subject:  it works \r\n"));
  client.println(F("This is from my ESP8266\n"));
  client.println(F("This is line 2 from my ESP8266"));
  client.println(F("This is line 3 from my ESP8266"));

  client.println(F("."));
  if (!eRcv()) return 0;
  Serial.println(F("Sending QUIT"));
  client.println(F("QUIT"));
  if (!eRcv()) return 0;
  client.stop();
  Serial.println(F("disconnected"));
  return 1;
}

byte eRcv()
{
  byte respCode;
  byte thisByte;
  int loopCount = 0;

  while (!client.available()) {
    delay(1);
    loopCount++;
    // if nothing received for 10 seconds, timeout
    if (loopCount > 10000) {
      client.stop();
      Serial.println(F("\r\nTimeout"));
      return 0;
    }
  }

  respCode = client.peek();
  while (client.available())
  {
    thisByte = client.read();
    Serial.write(thisByte);
  }

  if (respCode >= '4')
  {
    //  efail();
    return 0;
  }
  return 1;
}
client.print(F("To:  blynk_token "); client.println(blynk_token[32]);

Try that. Not positive it'll work 'cause I don't know what client is. But Serial works like that.

-jim lee

jimLee:

client.print(F("To:  blynk_token ");Serial.println(blynk_token[32]);

try that.

-jim lee

But maybe use client.println() :slight_smile:

look ^^

I caught it right after hitting post.

-jim lee

jimLee:

client.print(F("To:  blynk_token "); client.println(blynk_token[32]);

Try that. Not positive it'll work 'cause I don't know what client is. But Serial works like that.

-jim lee

UKHeliBob:
But maybe use client.println() :slight_smile:

It compiles now but the serial monitor prints out that null characters are not allowed in smtp commands.

Thanks for your responses!

Did you really mean

client.print(F("To:  blynk_token "); 
client.println(blynk_token);

?

Then of course close the parentheses

client.print(F("To:  blynk_token "));
client.println(blynk_token);

But yeah, still doesn't work.

Did you really mean
Code: [Select]

client.print(F("To: blynk_token ");
client.println(blynk_token);

?

Or even:

client.print(F("To: ");
client.println(blynk_token);

?

But yeah, still doesn't work.

Oh, look, there's that useless stupid phrase again...

PaulS:
Oh, look, there's that useless stupid phrase again...

It's not that stupid. I keep trying until I get something to work. It usually doesn't work until then. Not sure why you get so frustrated with people trying to learn why things happen.

Frozenguy:
Then of course close the parentheses

client.print(F("To:  blynk_token "));

client.println(blynk_token);




But yeah, still doesn't work.

So what does it do ?

It is that stupid, and then some.
Describe what the code does do that you don't expect.
Describe what the code doesn't do that you do expect.
Post the code.
Never just bleat "it doesn't work".

UKHeliBob:
So what does it do ?

It says this:

501 blynk_token: recipient address must contain a domain

AWOL:
It is that stupid, and then some.
Describe what the code does do that you don't expect.
Describe what the code doesn't do that you do expect.
Post the code.
Never just bleat "it doesn't work".

The entire code is posted in posts 2 and 3.

I did post clearly what my code was not doing, and what I wanted it to do.

Closing the brackets still gives this: (you can find it in post 6)

501 NULL characters are not allowed in SMTP commands

The entire code is posted in posts 2 and 3.

And it has been suggested that you need to make some changes. If you haven't made them, then any expectations that the code is going to magically start working are complete misguided.

If you have made them, POST THE REVISED CODE.

501 NULL characters are not allowed in SMTP commands

You shouldn't be able to get NULL characters using the "xx.print" methods.

Exactly when does it show this error? The fact that it says "SMTP commands" implies that it is complaining about commands from before the "TO:" line that people people have been suggesting you change.
In other words, you started out with a compile problem, because xxx.print() only allows one argument. Now you seem to be sending bad data to the SMTP server, which is a run-time problem, and ENTIRELY DIFFERENT from your original issue.

#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino

Oh - you're using an ESP8266 based Arduino, rather than a regular AVR arduino connected to an ESP8266?
You might have mentioned that. I'm not sure that F() is useful or necessary on an ESP (though it does look like it's supposed to work.)