Categories

Follow

A quick look at the Wemos TFT 2.4 Touch Shield

This is a 2.4 inch TFT shield for a Wemos, its a large shield thats more than twice the size of a D1 mini but its an excellent little TFT screen and there are a couple of example to let you get up and running quick unlike some of the Arduino TFT shields which I have had trouble with in the past

This is a picture of the shield

Features

  • 2.4” diagonal LCD TFT display
  • 320×240 pixels
  • TFT Driver IC: ILI9341
  • Touch Screen controller IC: XPT2046

 

Code

You need to install various libraries – Adafruit_GFXAdafruit_ILI9341 and XPT2046_Touchscreen Library

Touchscreen example

#include <SPI.h>
#include <XPT2046_Touchscreen.h>
 
#define TS_CS D3 //for D1 mini or TFT I2C Connector Shield (V1.1.0 or later)
// #define TS_CS  12 //for D32 Pro
 
XPT2046_Touchscreen ts(TS_CS);
 
void setup()
{
  Serial.begin(115200);
  ts.begin();
  ts.setRotation(1);
  while (!Serial && (millis() <= 1000))
    ;
}
 
void loop()
{
  if (ts.touched())
  {
    TS_Point p = ts.getPoint();
    Serial.print("Pressure = ");
    Serial.print(p.z);
    Serial.print(", x = ");
    Serial.print(p.x);
    Serial.print(", y = ");
    Serial.print(p.y);
    delay(30);
    Serial.println();
  }
}

 

Default graphics example

 

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
 
#define TFT_CS D0  //for D1 mini or TFT I2C Connector Shield (V1.1.0 or later)
#define TFT_DC D8  //for D1 mini or TFT I2C Connector Shield (V1.1.0 or later)
#define TFT_RST -1 //for D1 mini or TFT I2C Connector Shield (V1.1.0 or later)
#define TS_CS D3   //for D1 mini or TFT I2C Connector Shield (V1.1.0 or later)
 
// #define TFT_CS 14  //for D32 Pro
// #define TFT_DC 27  //for D32 Pro
// #define TFT_RST 33 //for D32 Pro
// #define TS_CS  12 //for D32 Pro
 
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
 
void setup()
{
  Serial.begin(115200);
  Serial.println("ILI9341 Test!");
 
  tft.begin();
 
  // read diagnostics (optional but can help debug problems)
  uint8_t x = tft.readcommand8(ILI9341_RDMODE);
  Serial.print("Display Power Mode: 0x");
  Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDMADCTL);
  Serial.print("MADCTL Mode: 0x");
  Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDPIXFMT);
  Serial.print("Pixel Format: 0x");
  Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDIMGFMT);
  Serial.print("Image Format: 0x");
  Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDSELFDIAG);
  Serial.print("Self Diagnostic: 0x");
  Serial.println(x, HEX);
 
  Serial.println(F("Benchmark                Time (microseconds)"));
  delay(10);
  Serial.print(F("Screen fill              "));
  Serial.println(testFillScreen());
  delay(500);
 
  Serial.println(F("Done!"));
}
 
void loop(void)
{
  for (uint8_t rotation = 0; rotation < 4; rotation++)
  {
    tft.setRotation(rotation);
    testText();
    delay(1000);
  }
}
 
unsigned long testFillScreen()
{
  unsigned long start = micros();
  tft.fillScreen(ILI9341_BLACK);
  yield();
  tft.fillScreen(ILI9341_RED);
  yield();
  tft.fillScreen(ILI9341_GREEN);
  yield();
  tft.fillScreen(ILI9341_BLUE);
  yield();
  tft.fillScreen(ILI9341_BLACK);
  yield();
  return micros() - start;
}
 
unsigned long testText()
{
  tft.fillScreen(ILI9341_BLACK);
  unsigned long start = micros();
  tft.setCursor(0, 0);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(ILI9341_YELLOW);
  tft.setTextSize(2);
  tft.println(1234.56);
  tft.setTextColor(ILI9341_RED);
  tft.setTextSize(3);
  tft.println(0xDEADBEEF, HEX);
  tft.println();
  tft.setTextColor(ILI9341_GREEN);
  tft.setTextSize(5);
  tft.println("Groop");
  tft.setTextSize(2);
  tft.println("I implore thee,");
  tft.setTextSize(1);
  tft.println("my foonting turlingdromes.");
  tft.println("And hooptiously drangle me");
  tft.println("with crinkly bindlewurdles,");
  tft.println("Or I will rend thee");
  tft.println("in the gobberwarts");
  tft.println("with my blurglecruncheon,");
  tft.println("see if I don't!");
  return micros() - start;
}
 
unsigned long testLines(uint16_t color)
{
  unsigned long start, t;
  int x1, y1, x2, y2,
      w = tft.width(),
      h = tft.height();
 
  tft.fillScreen(ILI9341_BLACK);
  yield();
 
  x1 = y1 = 0;
  y2 = h - 1;
  start = micros();
  for (x2 = 0; x2 < w; x2 += 6)
    tft.drawLine(x1, y1, x2, y2, color);
  x2 = w - 1;
  for (y2 = 0; y2 < h; y2 += 6)
    tft.drawLine(x1, y1, x2, y2, color);
  t = micros() - start; // fillScreen doesn't count against timing
 
  yield();
  tft.fillScreen(ILI9341_BLACK);
  yield();
 
  x1 = w - 1;
  y1 = 0;
  y2 = h - 1;
  start = micros();
  for (x2 = 0; x2 < w; x2 += 6)
    tft.drawLine(x1, y1, x2, y2, color);
  x2 = 0;
  for (y2 = 0; y2 < h; y2 += 6)
    tft.drawLine(x1, y1, x2, y2, color);
  t += micros() - start;
 
  yield();
  tft.fillScreen(ILI9341_BLACK);
  yield();
 
  x1 = 0;
  y1 = h - 1;
  y2 = 0;
  start = micros();
  for (x2 = 0; x2 < w; x2 += 6)
    tft.drawLine(x1, y1, x2, y2, color);
  x2 = w - 1;
  for (y2 = 0; y2 < h; y2 += 6)
    tft.drawLine(x1, y1, x2, y2, color);
  t += micros() - start;
 
  yield();
  tft.fillScreen(ILI9341_BLACK);
  yield();
 
  x1 = w - 1;
  y1 = h - 1;
  y2 = 0;
  start = micros();
  for (x2 = 0; x2 < w; x2 += 6)
    tft.drawLine(x1, y1, x2, y2, color);
  x2 = 0;
  for (y2 = 0; y2 < h; y2 += 6)
    tft.drawLine(x1, y1, x2, y2, color);
 
  yield();
  return micros() - start;
}
 
unsigned long testFastLines(uint16_t color1, uint16_t color2)
{
  unsigned long start;
  int x, y, w = tft.width(), h = tft.height();
 
  tft.fillScreen(ILI9341_BLACK);
  start = micros();
  for (y = 0; y < h; y += 5)
    tft.drawFastHLine(0, y, w, color1);
  for (x = 0; x < w; x += 5)
    tft.drawFastVLine(x, 0, h, color2);
 
  return micros() - start;
}
 
unsigned long testRects(uint16_t color)
{
  unsigned long start;
  int n, i, i2,
      cx = tft.width() / 2,
      cy = tft.height() / 2;
 
  tft.fillScreen(ILI9341_BLACK);
  n = min(tft.width(), tft.height());
  start = micros();
  for (i = 2; i < n; i += 6)
  {
    i2 = i / 2;
    tft.drawRect(cx - i2, cy - i2, i, i, color);
  }
 
  return micros() - start;
}
 
unsigned long testFilledRects(uint16_t color1, uint16_t color2)
{
  unsigned long start, t = 0;
  int n, i, i2,
      cx = tft.width() / 2 - 1,
      cy = tft.height() / 2 - 1;
 
  tft.fillScreen(ILI9341_BLACK);
  n = min(tft.width(), tft.height());
  for (i = n; i > 0; i -= 6)
  {
    i2 = i / 2;
    start = micros();
    tft.fillRect(cx - i2, cy - i2, i, i, color1);
    t += micros() - start;
    // Outlines are not included in timing results
    tft.drawRect(cx - i2, cy - i2, i, i, color2);
    yield();
  }
 
  return t;
}
 
unsigned long testFilledCircles(uint8_t radius, uint16_t color)
{
  unsigned long start;
  int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
 
  tft.fillScreen(ILI9341_BLACK);
  start = micros();
  for (x = radius; x < w; x += r2)
  {
    for (y = radius; y < h; y += r2)
    {
      tft.fillCircle(x, y, radius, color);
    }
  }
 
  return micros() - start;
}
 
unsigned long testCircles(uint8_t radius, uint16_t color)
{
  unsigned long start;
  int x, y, r2 = radius * 2,
            w = tft.width() + radius,
            h = tft.height() + radius;
 
  // Screen is not cleared for this one -- this is
  // intentional and does not affect the reported time.
  start = micros();
  for (x = 0; x < w; x += r2)
  {
    for (y = 0; y < h; y += r2)
    {
      tft.drawCircle(x, y, radius, color);
    }
  }
 
  return micros() - start;
}
 
unsigned long testTriangles()
{
  unsigned long start;
  int n, i, cx = tft.width() / 2 - 1,
            cy = tft.height() / 2 - 1;
 
  tft.fillScreen(ILI9341_BLACK);
  n = min(cx, cy);
  start = micros();
  for (i = 0; i < n; i += 5)
  {
    tft.drawTriangle(
        cx, cy - i,     // peak
        cx - i, cy + i, // bottom left
        cx + i, cy + i, // bottom right
        tft.color565(i, i, i));
  }
 
  return micros() - start;
}
 
unsigned long testFilledTriangles()
{
  unsigned long start, t = 0;
  int i, cx = tft.width() / 2 - 1,
         cy = tft.height() / 2 - 1;
 
  tft.fillScreen(ILI9341_BLACK);
  start = micros();
  for (i = min(cx, cy); i > 10; i -= 5)
  {
    start = micros();
    tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
                     tft.color565(0, i * 10, i * 10));
    t += micros() - start;
    tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
                     tft.color565(i * 10, i * 10, 0));
    yield();
  }
 
  return t;
}
 
unsigned long testRoundRects()
{
  unsigned long start;
  int w, i, i2,
      cx = tft.width() / 2 - 1,
      cy = tft.height() / 2 - 1;
 
  tft.fillScreen(ILI9341_BLACK);
  w = min(tft.width(), tft.height());
  start = micros();
  for (i = 0; i < w; i += 6)
  {
    i2 = i / 2;
    tft.drawRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(i, 0, 0));
  }
 
  return micros() - start;
}
 
unsigned long testFilledRoundRects()
{
  unsigned long start;
  int i, i2,
      cx = tft.width() / 2 - 1,
      cy = tft.height() / 2 - 1;
 
  tft.fillScreen(ILI9341_BLACK);
  start = micros();
  for (i = min(tft.width(), tft.height()); i > 20; i -= 6)
  {
    i2 = i / 2;
    tft.fillRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(0, i, 0));
    yield();
  }
 
  return micros() - start;
}

 

CCS811 digital gas sensor and ESP8266 example

CCS811 is a low-power digital gas sensor solution, which integrates a gas sensor solution for detecting low levels of VOCs typically found indoors, with a microcontroller unit (MCU) and an Analog-to-Digital converter to monitor the local environment and provide an indication of the indoor air quality via an equivalent CO2 or TVOC output over a standard I2C digital interface.

Features

Integrated MCU
On-board processing
Standard digital interface
Optimised low power modes
IAQ threshold alarms
Programmable baseline
2.7mm x 4.0mm LGA package
Low component count
Proven technology platform

Specs

Interface I²C
Supply Voltage [V] 1.8 to 3.6
Power Consumption [mW] 1.2 to 46
Dimension [mm] 2.7 x 4.0 x 1.1 LGA
Ambient Temperature Range [°C] -40 to 85
Ambient Humidity Range [% r.h.] 10 to 95

Parts List

 

Amount Part Type
1 CJMCU-811 CCS811 Air Quality Gas Sensor
1 Wemos D1 mini V2

 

Schematics/Layout

Remember and connect WAKE to gnd

esp8266 and ccs811

esp8266 and ccs811

 

Code

Again we use a library –

And this ios the out of the box example

#include "Adafruit_CCS811.h"
Adafruit_CCS811 ccs;
void setup() {
Serial.begin(9600);
Serial.println("CCS811 test");
if(!ccs.begin()){
Serial.println("Failed to start sensor! Please check your wiring.");
while(1);
}
//calibrate temperature sensor
while(!ccs.available());
float temp = ccs.calculateTemperature();
ccs.setTempOffset(temp - 25.0);
}
void loop() {
if(ccs.available()){
float temp = ccs.calculateTemperature();
if(!ccs.readData()){
Serial.print("CO2: ");
Serial.print(ccs.geteCO2());
Serial.print("ppm, TVOC: ");
Serial.print(ccs.getTVOC());
Serial.print("ppb Temp:");
Serial.println(temp);
}
else{
Serial.println("ERROR!");
while(1);
}
}
delay(500);
}

 

Output

Open the serial monitor – this is what I saw. The higher CO2 level was when I breathed on the sensor

CO2: 400ppm, TVOC: 0ppb Temp:35.34
CO2: 400ppm, TVOC: 0ppb Temp:34.42
CO2: 400ppm, TVOC: 0ppb Temp:34.04
CO2: 770ppm, TVOC: 56ppb Temp:32.90
CO2: 400ppm, TVOC: 0ppb Temp:32.53
CO2: 400ppm, TVOC: 0ppb Temp:31.67
CO2: 672ppm, TVOC: 41ppb Temp:30.59
CO2: 476ppm, TVOC: 11ppb Temp:27.43
CO2: 588ppm, TVOC: 28ppb Temp:29.09
CO2: 400ppm, TVOC: 0ppb Temp:30.95
CO2: 400ppm, TVOC: 0ppb Temp:31.67

 

Links

ccs811 datasheet

CJMCU-811 CCS811 Air Quality Gas Sensor

SHT20 temperature and humidity sensor and ESP8266

The SHT2x series consists of a low-cost version with the SHT20 humidity sensor. the SHT2x provides calibrated, linearized sensor signals in digital, I2C format. The SHT2x humidity sensor series contains a capacitive-type humidity sensor, a band-gap temperature sensor, and specialized analog and digital integrated circuits – all on a single CMOSens® chip. This yields superior sensor performance in terms of accuracy and stability as well as minimal power consumption.

Every sensor is individually calibrated and tested. Furthermore, the resolution of the SHT2x humidity sensor can be changed on command (8/12 bit up to 12/14 bit for RH/T) and a checksum helps to improve communication reliability.

 

Parts List

 

Amount Part Type
1 Temperature and humidity detection sensor module SHT20
1 Wemos D1 mini V2

 

Schematics/Layout

 

 

Code

Again we use a library – https://github.com/DFRobot/DFRobot_SHT20

#include <Wire.h>
#include "DFRobot_SHT20.h"
 
DFRobot_SHT20    sht20;
 
void setup()
{
    Serial.begin(9600);
    Serial.println("SHT20 Example!");
    sht20.initSHT20();                                  // Init SHT20 Sensor
    delay(100);
    sht20.checkSHT20();                                 // Check SHT20 Sensor
}
 
void loop()
{
    float humd = sht20.readHumidity();                  // Read Humidity
    float temp = sht20.readTemperature();               // Read Temperature
    Serial.print("Time:");
    Serial.print(millis());
    Serial.print(" Temperature:");
    Serial.print(temp, 1);
    Serial.print("C");
    Serial.print(" Humidity:");
    Serial.print(humd, 1);
    Serial.print("%");
    Serial.println();
    delay(1000);
}

 

Output

Open the serial monitor – this is what I saw

Time:105462 Temperature:21.1C Humidity:55.6%
Time:106565 Temperature:21.1C Humidity:55.6%
Time:107669 Temperature:22.0C Humidity:55.7%
Time:108772 Temperature:24.8C Humidity:58.0%
Time:109875 Temperature:26.3C Humidity:61.1%
Time:110978 Temperature:27.3C Humidity:63.1%
Time:112081 Temperature:28.0C Humidity:64.4%

 

Links

Sensirion_Humidity_Sensors_SHT20_Datasheet.pdf

 

ADS1115 analog-to-digital converter and ESP8266

The ADS1115 device is a precision, low-power, 16-bit, I2C-compatible, analog-to-digital converters (ADCs) offered in an ultra-small, leadless, X2QFN-10 package, and a VSSOP-10 package. The ADS1115 device incorporates a low-drift voltage reference and an oscillator. The ADS1115 also incorporate a programmable gain amplifier and a digital comparator. These features, along with a wide operating supply range, make the ADS1115 well suited for power- and space-constrained, sensor measurement applications.

The ADS1115 perform conversions at data rates up to 860 samples per second (SPS). The PGA offers input ranges from ±256 mV to ±6.144 V, allowing precise large- and small-signal measurements. The ADS1115 features an input multiplexer  that allows two differential or four single-ended input measurements. Use the digital comparator in the ADS1115 for under- and overvoltage detection.

The ADS1115 operates in either continuous-conversion mode or single-shot mode. The devices are automatically powered down after one conversion in single-shot mode; therefore, power consumption is significantly reduced during idle periods.

Features

Wide Supply Range: 2.0 V to 5.5 V
Low Current Consumption: 150 µA
(Continuous-Conversion Mode)
Programmable Data Rate: 8 SPS to 860 SPS
Single-Cycle Settling
Internal Low-Drift Voltage Reference
Internal Oscillator
I2C Interface: Four Pin-Selectable Addresses
Four Single-Ended or Two Differential Inputs (ADS1115)
Programmable Comparator (ADS1114 and ADS1115)
Operating Temperature Range: –40°C to +125°C

Parts List

This module will cost less than $2

Amount Part Type
1 ADS1115
1 Wemos D1 mini V2

 

Schematics/Layout

 

In the layout below we just show basic connection between Wemos Mini and ADS1115 – you can add a pot, connect an LDR to one of the A0 – A3 inputs of the ADS1115

esp8266 and ads1115

esp8266 and ads1115

 

Code

Again we use a library and again its an adafruit one – https://github.com/adafruit/Adafruit_ADS1X15

 

 

#include <Wire.h>
#include <Adafruit_ADS1015.h>
 
Adafruit_ADS1115 ads(0x48);
 
void setup(void)
{
Serial.begin(9600);
Serial.println("Hello!");
 
Serial.println("Getting single-ended readings from AIN0..3");
Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)");
 
ads.begin();
}
 
void loop(void)
{
int16_t adc0, adc1, adc2, adc3;
 
adc0 = ads.readADC_SingleEnded(0);
adc1 = ads.readADC_SingleEnded(1);
adc2 = ads.readADC_SingleEnded(2);
adc3 = ads.readADC_SingleEnded(3);
Serial.print("AIN0: ");
Serial.println(adc0);
Serial.print("AIN1: ");
Serial.println(adc1);
Serial.print("AIN2: ");
Serial.println(adc2);
Serial.print("AIN3: ");
Serial.println(adc3);
Serial.println(" ");
 
delay(1000);
}

 

 

Links

http://www.ti.com/lit/ds/symlink/ads1115.pdf

I2C ADS1115 16 Bit ADC 4 channel Module with Programmable Gain Amplifier 2.0V to 5.5V RPi