Arduino file compile errors

Hi there,

i’m totally new into PlatformIO.

I build a weatherstation with an esp32 + bme280 transmitting the data via mqtt to my rasp-pi (influxdb + grafana).
I made this code with Arduino but with boardversion 1.0.4 is an anoying wifi reconnect bug, so i need to use 1.10.0 with PlatformIO.

Evertyhing is working fine except of this wifi bug.

I added #include <Arduino.h> but i got 4 errors.

‘setupWifi’ was not declared in this scope (58 , 13)
‘mqttReconnect’ was not declared in this scope (66, 19)
‘mqttPublish’ was not declared in this scope (86, 52)
“BME280_ADDRESS” redefined (21, 1)

I need some help please, i installed all missing libraries and installed board esp32 1.10.0

This is my code:

 /**
 Required libraries:
  - Adafruit BME280 Library
  - Adafruit Unified Sensor
  - PubSubClient
**/

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <PubSubClient.h>
#include <WiFi.h>

#define MQTT_TOPIC_HUMIDITY "home/bme280/humidity"
#define MQTT_TOPIC_TEMPERATURE "home/bme280/temperature"
#define MQTT_TOPIC_STATE "home/bme280/status"
#define MQTT_PUBLISH_DELAY 5000
#define MQTT_CLIENT_ID "esp32bme280"

#define BME280_ADDRESS 0x76


#define uS_TO_S_FACTOR 1000000 // micro seconds for sleep mode
#define TIME_TO_SLEEP 300 // seconds for sleep mode, the esp32 sends data every 10 seconds 
and goes to sleep mode, you can change this value as your mind

const char *WIFI_SSID = "xxxxx";
const char *WIFI_PASSWORD = "xxxx";

const char *MQTT_SERVER = "10.0.1.3";
const char *MQTT_USER = "pi"; // NULL for no authentication
const char *MQTT_PASSWORD = "123"; // NULL for no authentication

float humidity;
float temperature;
long lastMsgTime = 0;

Adafruit_BME280 bme;
WiFiClient espClient;
PubSubClient mqttClient(espClient);

void setup() {
Serial.begin(115200);
while (! Serial);

if (!bme.begin(BME280_ADDRESS)) {
Serial.println("Could not find a valid BME280 sensor, check wiring or BME-280 address!");
while (1);
}

// Use force mode so that the sensor returns to sleep mode when the measurement is finished
bme.setSampling(Adafruit_BME280::MODE_FORCED,
              Adafruit_BME280::SAMPLING_X1, // temperature
              Adafruit_BME280::SAMPLING_NONE, // pressure
              Adafruit_BME280::SAMPLING_X1, // humidity
              Adafruit_BME280::FILTER_OFF);

setupWifi();
mqttClient.setServer(MQTT_SERVER, 1883);
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);

}

void loop() {
if (!mqttClient.connected()) {
mqttReconnect();
}
mqttClient.loop();

long now = millis();
if (now - lastMsgTime > MQTT_PUBLISH_DELAY) {
lastMsgTime = now;

// Reading BME280 sensor data
bme.takeForcedMeasurement(); // has no effect in normal mode
humidity = bme.readHumidity();
temperature = bme.readTemperature();
if (isnan(humidity) || isnan(temperature)) {
  Serial.println(temperature);
  Serial.println(humidity);
  Serial.println("BME280 reading issues");
  return;
}

// Publishing sensor data
mqttPublish(MQTT_TOPIC_TEMPERATURE, temperature);
mqttPublish(MQTT_TOPIC_HUMIDITY, humidity);
delay(100);
esp_deep_sleep_start();
}


}

void setupWifi() {
Serial.print("Connecting to ");
Serial.println(WIFI_SSID);

WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

Serial.println();
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}

void mqttReconnect() {
while (!mqttClient.connected()) {
Serial.print("Attempting MQTT connection...");

// Attempt to connect
if (mqttClient.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD, 
MQTT_TOPIC_STATE, 1, true, "disconnected", false)) {
  Serial.println("connected");

  // Once connected, publish an announcement...
  mqttClient.publish(MQTT_TOPIC_STATE, "connected", true);
} else {
  Serial.print("failed, rc=");
  Serial.print(mqttClient.state());
  Serial.println(" try again in 5 seconds");
  delay(5000);
}
}
}

void mqttPublish(char *topic, float payload) {
Serial.print(topic);
Serial.print(": ");
Serial.println(payload);

mqttClient.publish(topic, String(payload).c_str(), true);
}

There are a few things to fix and improve:

1. Declaration of function

In C++, functions need to be declared before they are used. Before refers to processing the .cpp file top to bottom. Arduino IDE uses some non-standard mechanism to work around this. But PlatformIO builds on standard C++. So add the following declarations (at about line 40):

void setupWifi();
void mqttReconnect();
void mqttPublish(const char *topic, float payload);

That way the functions can be called before the definition (implementation) appears in the file.

2. Macro redifinition

The macro BME280_ADDRESS is defined by the Adafruit BME280 library. If you declare it also, there is a conflict and some files are compiled with Adafruit’s definition and some with your definition. The solution is to use a different name:

#define MY_BME280_ADDRESS 0x76

...

if (!bme.begin(MY_BME280_ADDRESS))

3. String conversion warning

PlatformIO runs with useful warnings enabled and will complain about a string conversion because a string constant is passed as a modifiable character array:

src/main.cpp:98:52: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

The fix is easy: Add the const modifier to the topic parameter of mqttPublish:

void mqttPublish(const char *topic, float payload)

4. Installation of libraries

You don’t specify in detail how you installed the libraries. But I assume you clicked the flashy Install button. I strongly recommend against installing them because it affects other projects as well and makes it difficult to share projects with other people.

PlatformIO has a far better approach. Just declare them as a dependency of your project. You would do this in platformio.ini:

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino

lib_deps =
    Adafruit Unified Sensor
    Adafruit BME280 Library
    PubSubClient

The last four lines are all that’s needed. PlatformIO will download them automatically.

To clean up your installation, remove all files from /User/username/.platformio/lib (Mac) or C:\Users\username\.platformio\lib. Clean out the lib folder in your project folder as well (unless you need a modified version of a library).

2 Likes

Thank you for your little guide. I did everything but i got 1 error.
I added: void mqttPublish(const char *topic, float payload) at line 131

but the error message is still displayed:
‘mqttPublish’ was not declared in this scope (86,52)

At line 131, your code probably contains the definition of mqttPublish(). So you added const to the already existing line (and not an entire new line), right?

The error messages refers to line 86 where you probably use mqttPublish() for the first time in the file. So a declaration of mqttPublish() before this first use is missing.

Add the line:

void mqttPublish(const char *topic, float payload);

somewhere before line 86 and outside any function/methods. My recommendation was to add all necessary function declarations around line 40, after all variable declarations and before the first function definition.

1 Like

You are right. I put it in the wrong line, thats why it wont work. Now it compiles but i think i have to configure the connection with the esp. I got the following error:

Open On-Chip Debugger v0.10.0-esp32-20190708 (2019-07-08-11:04)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
none separate
adapter speed: 20000 kHz
Info : Configured 2 cores
esp32 interrupt mask on
Info : telnet server disabled
Error: no device found
Error: unable to open ftdi device with vid 0403, pid 6010, description ‘', serial '’ at bus location ‘*’
Warn : Flash driver of esp32.flash does not support free_driver_priv()
Warn : Flash driver of irom does not support free_driver_priv()
Warn : Flash driver of drom does not support free_driver_priv()
.pioinit:11: Error in sourced command file:
Remote communication error. Target disconnected.: No error.

So i added:

upload_port = COM7
monitor_port = COM7
monitor_speed = 115200

to the platformio.ini but nothing changed.

What action are you trying to execute? Upload? Debug?

Can you show your entire platformio.ini? What board are you using? How is it connected to your computer?

It looks as if you’re expecting it to upload via the regular USB connection while the board is configured to use the debugger.

I pressed start debugging, after some time i got ‘passed’ after that the error occurs.

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino

upload_port = COM7 
monitor_port = COM7
monitor_speed = 115200

lib_deps =
Adafruit Unified Sensor
Adafruit BME280 Library
PubSubClient

I use this boad: AZDelivery ESP32 NodeMCU and its connected via usb (com7).
Platform is 1.10.0
I just want to upload it into the esp32. The compile was ok.


I uploaded it and i got no errors.I’ll test it now, if i still got the freezes with wifi.

Thanks for your help !

In order to debug code in-circuit, you would need a separate debug probe connected to your board (see Low-cost ESP32 In-circuit Debugging).

However, to just upload and run the code (and use Serial.print debugging), click the Arrow button in the status bar or click the PlatformIO icon in the left bar and the click Upload.

1 Like

I think something is wrong, after i uploaded the file i recieve no datas on my pi. Arduino Monitor displays some data, the last recieved datas on my pi are from 9:59:14.

Maybe the change of #define MY_BME280_ADDRESS 0x76 ?

Or the missing MQTT clients? I think the esp will send the data, but maybe in a wrong type.

For problems of this kind it’s difficult to provide remote support.

Add print statement to get information what your code is doing. That way you can quickly figure out if the communication with the sensor is the problem or the MQTT connection. Once that’s clear, you can dig deeper and test for an invalid I2C address or WiFi connection problems.

1 Like

I connected the monitor and i got the following message. Code used and edited with Platformio:

rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:928
ho 0 tail 12 room 4
load:0x40078000,len:8740
load:0x40080400,len:5800
entry 0x4008069c
home/bme280/temperature: 20.92
home/bme280/humidity: 56.32

Nothing to see of my serial.print

This is my ‘old’ code that works with Arduino:

rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:9720
ho 0 tail 12 room 4
load:0x40080400,len:6352
entry 0x400806b8
Connecting to Unifi
.
WiFi connected
IP address: 10.0.1.66
Attempting MQTT connection...connected
home/bme280/temperature: 21.14
home/bme280/humidity: 55.48

The monitor output contains these two lines:

home/bme280/temperature: 20.92
home/bme280/humidity: 56.32

These a very reasonable temperature and humidity values. So obviously the communication with the sensor is working and the I2C address is correct. These lines are output by mqttPublish(). So some of your Serial.print statements are working.

However, there is no output regarding WiFi. If you still had the same code that you posted at the start of this thread, this would be impossible. That code never gets to loop() and mqttPublish() without at least printing Connecting to SSID.

So changes are you have modified your setup() function, possibly commented some line, and setupWifi() is no longer called.

1 Like

Thank you manuelbl, your recommendation is very helpful.