BME280 gives wrong values after Ethernet begin with W5500

Post here all questions related to STM32 core if you can't find a relevant section!
adrian_123
Posts: 8
Joined: Thu Jul 01, 2021 12:54 pm
Answers: 1

BME280 gives wrong values after Ethernet begin with W5500

Post by adrian_123 »

Hi community!
I will try to briefly comment my project and my issue. Then I will post the code and the errors. This is my first post.
My project is a PCB with an STM32 blue pill, a BME280 sensor and a 128x32 SSD1306 display connected at B6/B7 I2C bus. I got also a W5500 DEVMO USR-ES1 ethernet module to connect to a MQTT server. This project aims to publish temperature and humidity to an IoT platform and to detect fire.

My core is the one from stm32duino. JSONs included in Arduino:
https://github.com/stm32duino/BoardMana ... index.json
http://dan.drown.org/stm32duino/package ... index.json

Sensor, display and W5500 are powered from the 3.3V pin, and the blue pill is powered with 5V from the PC. Both voltages have two caps in order to stabilize them. The project gets an IP and posts to the MQTT server without any problem, but I do have a problem with the sensor. Sensor gives correct values only before the Ethernet.begin(mac) call.

I list some possible errors, things that Ive tried, notes and some thoughts:
- Not enough power (strange, bme280 just requires 1mA)
- They just share GND and +3.3V
- There is no drop of voltage
- After pulling down reset pin (PA4 PIN) on the ethernet module I keep getting wrong values
- Colisions between libraries(?)

Things pending to try:
-Power the bme280 with 5V instead
-Try another I2C channel
-Try another bme280 library

Code: Select all

//##########################################################
include <Ethernet.h> // https://github.com/arduino-libraries/Ethernet
#include <MQTT.h> // https://github.com/256dpi/arduino-mqtt
//#include <SPI.h>
//#include <Wire.h>
//#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
#define SIZE_HIST 20  // 10min
#define SENSIBILITY  7  // ºC/min
#define FIXED_TEMP 80  // ºC
#define SAMPLE_TIME 30000  // ms
#define PUB_TIME 60000   // ms

#define BME_MISO PB7
#define BME_MOSI PB6
#define LED_ PC13

//byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte mac[] = { 0xAA, 0xDD, 0x44, 0x11, 0x99, 0x77 };
EthernetClient net; 
//byte ip[] = {192, 168, 1, 142}; 
//IPAddress ip(192, 168, 1, 142); // Set the static IP address to use if the DHCP fails to assign
MQTTClient client(1024); //1kb
int eth_flag=0;
int mqtt_flag=0;
unsigned long lastMillis_fire = 0;
unsigned long lastMillis_mqtt = 0;

Adafruit_BME280 bme;

char buffer_t[10], buffer_h[10], buffer_p[10];
int historical[SIZE_HIST];
int delta[SIZE_HIST];
int fire_alarm=0;

float bme_pressure;

void setup(){
  Serial.begin(9600);
  bme.begin(0x76);
  //display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  delay(2000);
  pinMode(LED_, OUTPUT);
  
  digitalWrite(LED_, HIGH);
  delay(1000); 
  digitalWrite(LED_, LOW); 
  delay(1000);
  digitalWrite(LED_, HIGH);
  delay(1000); 
  digitalWrite(LED_, HIGH);
  delay(2000);

  pinMode(PA4, OUTPUT);  

  dtostrf(bme.readTemperature(),6,2,buffer_t);    
  dtostrf(bme.readHumidity(),6,2,buffer_h);
  bme_pressure=bme.readPressure()/100.0 + 70.0;
  dtostrf(bme_pressure,8,2,buffer_p);
  dtostrf(bme.readTemperature(),6,2,buffer_t);    
  dtostrf(bme.readHumidity(),6,2,buffer_h);
  bme_pressure=bme.readPressure()/100.0 + 70.0;
  dtostrf(bme_pressure,8,2,buffer_p);
   //
  Serial.println("Ti");
  Serial.println(buffer_t);
  Serial.println(buffer_h);
  Serial.println(buffer_p);
  Ethernet.init(PA4); //get IP via DHCP
  //Ethernet.begin(mac);
  delay(2000);
  eth_connect();
  Serial.print("Local IP is  ");
  Serial.println(Ethernet.localIP());
  //Ethernet.begin(mac,ip);
  client.begin("acme.thinger.io", net); //Broker address, port and client 
  //client.onMessage(messageReceived); 
  //mqtt_connect();

}

void loop(){
  float bme_t;
  float bme_h;
  float bme_p;

  if (millis() - lastMillis_mqtt > PUB_TIME) {
    lastMillis_mqtt = millis();
    
    
    bme_t=bme.readTemperature();
    bme_h=bme.readHumidity();
    bme_p=bme.readPressure()/100.0 + 70.0;
    dtostrf(bme_t,6,2,buffer_t); 
    delay(10);   
    dtostrf(bme_h,6,2,buffer_h);
    delay(10);
    dtostrf(bme_p,8,2,buffer_p);
    delay(10);
    eth_connect();
    mqtt_connect();

    Serial.println("T2");
    client.publish("/temperature", buffer_t);
    client.publish("/humidity", buffer_h);
    client.publish("/pressure", buffer_p);

    client.disconnect();
  }
  Ethernet.maintain();
  delay(10); 
}

void mqtt_connect(){
  int mqtt_attempts=0;
  mqtt_flag=0;
  while ( (!client.connect("mqtt_2", "adrian_test", "cXFguAbmzha")) && (!(mqtt_attempts==10)) ){   // clientId, username, password 
    Serial.println(".");    
    delay(100);
    mqtt_attempts++;
    if(mqtt_attempts==10){
      mqtt_flag=1;
      Serial.println("Mqtt connect fail"); 
      //NVIC_SystemReset();
    }
  }

  //client.subscribe("/temperature");
  //client.subscribe("/humidity");
  //client.subscribe("/pressure");
  //client.unsubscribe("/temperature");
}

void eth_connect(){
  int w5500=0;
  int eth_reconnect=0;
  delay(2000);
  dtostrf(bme.readTemperature(),6,2,buffer_t);    
  dtostrf(bme.readHumidity(),6,2,buffer_h);
  bme_pressure=bme.readPressure()/100.0 + 70.0;
  dtostrf(bme_pressure,8,2,buffer_p);
  dtostrf(bme.readTemperature(),6,2,buffer_t);    
  dtostrf(bme.readHumidity(),6,2,buffer_h);
  bme_pressure=bme.readPressure()/100.0 + 70.0;
  dtostrf(bme_pressure,8,2,buffer_p);
   //
  Serial.println("Ti2");
  Serial.println(buffer_t);
  Serial.println(buffer_h);
  Serial.println(buffer_p);
  delay(2000);
  Ethernet.begin(mac);
  Serial.println("eth begin");
  dtostrf(bme.readTemperature(),6,2,buffer_t);    
  dtostrf(bme.readHumidity(),6,2,buffer_h);
  bme_pressure=bme.readPressure()/100.0 + 70.0;
  dtostrf(bme_pressure,8,2,buffer_p);
  dtostrf(bme.readTemperature(),6,2,buffer_t);    
  dtostrf(bme.readHumidity(),6,2,buffer_h);
  bme_pressure=bme.readPressure()/100.0 + 70.0;
  dtostrf(bme_pressure,8,2,buffer_p);
   //
  Serial.println("Ti3");
  Serial.println(buffer_t);
  Serial.println(buffer_h);
  Serial.println(buffer_p);
  Serial.println("LOW");
  digitalWrite(PA4, LOW);
  delay(5000);  
  Serial.println("HIGH");
  digitalWrite(PA4, HIGH);
  delay(5000);
  dtostrf(bme.readTemperature(),6,2,buffer_t);    
  dtostrf(bme.readHumidity(),6,2,buffer_h);
  bme_pressure=bme.readPressure()/100.0 + 70.0;
  dtostrf(bme_pressure,8,2,buffer_p);
  dtostrf(bme.readTemperature(),6,2,buffer_t);    
  dtostrf(bme.readHumidity(),6,2,buffer_h);
  bme_pressure=bme.readPressure()/100.0 + 70.0;
  dtostrf(bme_pressure,8,2,buffer_p);
   //
  Serial.println("Ti4");
  Serial.println(buffer_t);
  Serial.println(buffer_h);
  Serial.println(buffer_p);   
   
  while((!(Ethernet.hardwareStatus() == EthernetW5500)) && (!eth_reconnect) ){
    if(Ethernet.linkStatus() == LinkOFF)
      Serial.println("N-L");
    if(Ethernet.hardwareStatus() == EthernetNoHardware)
      Serial.println("N-HW");
    delay(100);
    w5500++; 
    if(w5500==3) eth_reconnect=1;
    else  eth_reconnect=0;
  }
  w5500=0;

  //Serial.print("Local IP is  ");
  //Serial.println(Ethernet.localIP());
  delay(10);
}

void messageReceived(String &topic, String &payload) {
  //Serial.println("Incoming: from topic \"" + topic + "\" Payload \"" + payload + "\"");
}

//#########################################################
The could at the beginning pulls to serial the values and after Ethernet.begin(mac) they are wrong, even if I reset the module, as long as there is no reset in the ethernet library:
Captura de pantalla 2021-07-01 a las 16.04.40.png
Captura de pantalla 2021-07-01 a las 16.04.40.png (42.84 KiB) Viewed 3804 times
by adrian_123 » Thu Jul 29, 2021 7:45 am
Hi there,
I got the problem. Theres no problem with the stm32 going out of resources, thres no problem of power nor problems with library collisions. I had a defective via in my pcb. STM32 is suitable to work with a ethernet w5500 module, and a display and a bme280 at the same i2c bus. Thanks for all the replies and concerns.
Go to full post
Last edited by adrian_123 on Thu Jul 01, 2021 3:43 pm, edited 4 times in total.
stevestrong
Posts: 502
Joined: Fri Dec 27, 2019 4:53 pm
Answers: 8
Location: Munich, Germany
Contact:

Re: BME280 gives wrong values after Ethernet begin with W5500

Post by stevestrong »

Which core do you use?
Please include code information in code tags in your posts.

Seems to have a conflict:
1. "128x32 SSD1306 display connected at B6/B7 I2C bus"
2. "#define BME_MISO PB7
#define BME_MOSI PB6"
adrian_123
Posts: 8
Joined: Thu Jul 01, 2021 12:54 pm
Answers: 1

Re: BME280 gives wrong values after Ethernet begin with W5500

Post by adrian_123 »

Core is stm32duino. PB6 -> SCL and PB7 -> SDA to both display and sensor. I dont see any conflict on that.
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: BME280 gives wrong values after Ethernet begin with W5500

Post by ag123 »

if you are using a 'blue pill' stm32f103c8, just remember that you have only 20k sram, everything is running within that constraint.

try using a FreeStack() code that looks like this
source
https://github.com/greiman/SdFat/blob/m ... reeStack.h

Code: Select all

extern "C" char* sbrk(int incr);
inline int FreeStack() {
  register uint32_t sp asm("sp");
  return reinterpret_cast<char*>(sp) - reinterpret_cast<char*>(sbrk(0));
}
call and print that at strategic places to figure if it is possibly running out of memory etc.
mrburnette
Posts: 633
Joined: Thu Dec 19, 2019 1:23 am
Answers: 7

Re: BME280 gives wrong values after Ethernet begin with W5500

Post by mrburnette »

2 things ...
Please use CODE TAGS for code embedded in this forum ... they are the "</>" icon on the toolbar.

Next, while this works, it is not best practice:
Sensor, display and W5500 are powered from the 3.3V pin, and the blue pill is powered with 5V from the PC.
The BluePill has a 3.3V input and you benefit from not using the onboard 5V-3.3V regulator.
Just EXERCISE CARE if you continue to utilize the USB.
BluePill LDO.JPG
BluePill LDO.JPG (22.66 KiB) Viewed 3786 times
adrian_123
Posts: 8
Joined: Thu Jul 01, 2021 12:54 pm
Answers: 1

Re: BME280 gives wrong values after Ethernet begin with W5500

Post by adrian_123 »

ag123, Im sorry but I dont get what do you want me to do.
mrburnette, I think it might not be the best idea as you said, to power things from STM32. As I have seen, ethernet module consumption could go till 200mA, display till 25mA and BM280 1mA. I would think that if there is not enough power, the ethernet module would not work, but it works, and there is not drop of voltage.
Well I just saw that RESET pin of the ethernet module is not connected to the stm32 so it might work if i can reset it, take the data, connect and then post. I will try next week when I will be able to unsolder the PCB. Despite of that, it is strange the behaviour of the sensor. I dont know if this approach could get the sensor to work.

I attach some of the schematic:
Captura de pantalla 2021-07-01 a las 17.26.38.png
Captura de pantalla 2021-07-01 a las 17.26.38.png (55.52 KiB) Viewed 3782 times
And the look of the PCB: (DRIVE)
https://drive.google.com/drive/folders/ ... sp=sharing
mrburnette
Posts: 633
Joined: Thu Dec 19, 2019 1:23 am
Answers: 7

Re: BME280 gives wrong values after Ethernet begin with W5500

Post by mrburnette »

adrian_123 wrote: Thu Jul 01, 2021 3:38 pm ag123, Im sorry but I dont get what do you want me to do.
...
ag123 wanted to get (using a function added to your code) the free memory ...
To avoid potential:

Image
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: BME280 gives wrong values after Ethernet begin with W5500

Post by ag123 »

adrian_123 wrote: Thu Jul 01, 2021 3:38 pm ag123, Im sorry but I dont get what do you want me to do.
try this little sketch, select USB CDC serial as the serial interface.
connect to it with a serial monitor
i've not tested this, it is coded out of the blue, it may work.

Code: Select all

extern "C" char* sbrk(int incr);
inline int FreeStack() {
  register uint32_t sp asm("sp");
  return reinterpret_cast<char*>(sp) - reinterpret_cast<char*>(sbrk(0));
}

void setup() {
	Serial.begin();	
	while(!Serial) delay(1000);
}

void stackup(uint8_t layer) {
	char waste[20]; //waste some memory on the stack
	strcpy(waste,"0123456789");
	if(layer > 0) 
	  stackup(--layer);
	else { // no more layers to stack
	  Serial.print("Free memory:");
	  Serial.println(Freestack());
	}
}

void loop() {
        Serial.println("how many layers of stack do you want? :")
        while(!Serial.available()) delay(100);
	uint16_t c = Serial.read();
	uint8_t layers = c - '0';
	if( layers < 10 && layers > 0) {
	  Serial.print(layers);
	  Serial.println(" layers");
	  stackup(layers);
	  }
}
adrian_123
Posts: 8
Joined: Thu Jul 01, 2021 12:54 pm
Answers: 1

Re: BME280 gives wrong values after Ethernet begin with W5500

Post by adrian_123 »

Ok, I will try to insert the code in mine. About this "select USB CDC serial as the serial interface" I program the stm32 through UART on pins A9 and A10. I first need to explore how to program it through USB, but it may be difficulties as long as I work on a Mac OS. I guess that it is mandatory to use USB programming to do the test, right?
Thanks so far.
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: BME280 gives wrong values after Ethernet begin with W5500

Post by ag123 »

you could use your normal programming means, the usb cdc serial part is just needed when it runs
mainly as i used Serial.print() to send the response back to the serial monitor / terminnal
i think usb cdc is 'widely' supported, and commonly 'driverless'. Hence, it'd probably just be detected as a 'com' port and show up somewhere.

that Freestack() function is kind of a useful hack to check free memory. the trouble is in microcontrollers the stack build downwards, the heap (all the global variables) is placed below. the stack normally silently smash the global variables a lot of times with no clues. more commonly, it just corrupt the data, it is in that 20k.
but lets just say the stack goes into a global variable and you write something in there, more than likely it would just crash. this is quite interesting in that on micro-controllers you could just smash the stack and make it run a different way. on desktops, these are normally deemed vulnerabilities, whether it is a 'feature' or 'bug' depends on how you use it.
Post Reply

Return to “General discussion”