I’m using Arduino 1.6.8 on a WIN10 machine for a generic ESP8266 board
Using large delays in loops isn’t recommended. Instead of that I’m use a ticker event leaving the main loop complete empty – let the processor do whatever he is suppose to do.
The task of the program is to read out two sensors an AM2321 humidity sensor and a BMP180 air pressure sensor. Both connected via I2C. Yes, pullup resistors are in place.
First version of the Program using delay(2000) in the main loop works fine for both sensors. See the logic analyser screen shots named ‘with delay AM2321 ok.pdf’ and ‘with delay BMP189 ok’. Critical point is the gap after addressing the devices. Here 1 ms for the AM2321 and 5 ms for the BMP180 sensor.
Switching to the program version using a ticker event instead of the delay(1) in the main loop sensors reading give false results – there is almost no gap after addressing the device. See screen shot ‘with ticker delay AM2321 failed’. Just tinkering around I replaced delay(1) with delayMicroseconds(1000) and voila I got correct humidity and temperature readings from the AM2321 see screen shot ‘with ticker delayMicroseconds AM2321’.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#include <TimeLib.h>
#include <Ticker.h>
Ticker Tick; // create a ticker instance named Tick
int intervall=2000; // ticker intervall 10000 eq to 10 sec <<*****************************
// BMP085 pressure & temp stuff -------------------------------------------------------------
#include <Adafruit_BMP085.h>
Adafruit_BMP085 bmp;
int AM_trigger=2; // logic analyser trigger test only at GPIO2************************************
int BP_trigger=4; // logic analyser trigger test only at GPIO4************************************
void setup() {
Tick.attach_ms(intervall, Tack); //config ticker instance "Tick"" to call "Tack" every intevall(milli seconds)
pinMode(AM_trigger,OUTPUT); digitalWrite(AM_trigger,LOW); //logic analyser trigger test only
pinMode(BP_trigger,OUTPUT); digitalWrite(BP_trigger,LOW); //logic analyser trigger test only
digitalWrite(AM_trigger,LOW); //logic analyser trigger test only
digitalWrite(BP_trigger,LOW); //logic analyser trigger test only
Wire.begin(12,13);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize and setup for text display
display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0);
display.setTextColor(WHITE,BLACK);display.clearDisplay(); // overwriting with black background!
display.println(" AM2321 & BMP180 "); display.display(); // write some text to the display buffer and finally show it
bmp.begin();
delay(1000);
}
byte char_cnt = 0; // received char's counter
byte readback[6]; // received data from AM2321
char R_code; // return code from I2C transmission
char cmd[]={0x03,0x00,0x06}; // AM2321 cmd_string read registers/start at reg. no 0/read 6 registers
// 1.=>cmd, 2.=>start address/3.+4.=>16 bit humidity*10/5.+6.=>16 bit temperature*10
float hum; // humidity
float temp; // temperature
void Tack(){ // called every timer tick
digitalWrite(AM_trigger,HIGH); //logic analyser trigger test only****************************************
Wire.beginTransmission(0x5C); // empty write to wakeup / activate the AM2321
R_code = Wire.endTransmission(); // thanks go to Koepel from arduino forum
Wire.beginTransmission(0x5C);
Wire.write(cmd,3);
R_code = Wire.endTransmission(); // writes qued data
// delay(1); // requiered by AM2321
delayMicroseconds(1000);
char_cnt=0,
Wire.requestFrom(0x5c, 6); // request 6 bytes from slave device #2
while(Wire.available()) // slave may send less than requested
{
readback[char_cnt] = Wire.read(); // receive a byte as character
char_cnt++;
}
hum=float(readback[2]*256+readback[3])/10;
temp=float(readback[4]*256+readback[5])/10;
digitalWrite(AM_trigger,LOW); //logic analyser trigger test only****************************************
// display.clearDisplay();
display.setCursor(0,0);
display.print(hum,1); display.print(" % ");
display.print(temp,1); display.println(" C ");
display.display();
//read pressure (& temp) from BMP085
digitalWrite(BP_trigger,HIGH); //logic analyser trigger test only****************************************
long pressure_414 = (bmp.readPressure() + 4750.0) / 100.0; // adopt seelevel correction
digitalWrite(BP_trigger,LOW); //logic analyser trigger test only****************************************
int Pressure = pressure_414;
display.print(pressure_414); display.print(" hPa ");
display.print(bmp.readTemperature(),1); display.println(char(222)); //internal BMP085 temp
display.display();
}
void loop() {
// no delay here free to used by
// processor background tasks
}
After that change the BMP180 still gives false readings, see screenshot ‘with ticker delayMicroseconds BMP180 failed’. There is almost no delay (app. 28 µs) after firs addressing the BMP180.
Looking for advice - very confused
with delay AM2321 ok.pdf (146 KB)
with delay BMP180 ok.pdf (130 KB)
With ticker delay AM2321 failed.pdf (146 KB)