2

I am using the Adafruit datalogger shield (Rev B) and a pair of cheap 20x4 LCD I2C displays. The displays have a small I2C I/O expansion module board on the back. The LCDs I am using are these;

https://www.amazon.ca/gp/product/B01GPUMP9C/ref=oh_aui_detailpage_o09_s00?ie=UTF8&psc=1

I'm using the NewLiquidCrystal 1.3.4 I2C library. My UNO clone is the iteaduino-BT https://www.itead.cc/iteaduino-bt.html, which is a board I really like.

I am getting interference between the LCD displays and the SD card function. Sometimes I can write to the SD card, and sometimes I can't. I have tried several SD cards. After a lot of experimenting, I think I have identified the problem. The LCDs are interfering somehow with the SD card functions. The LCD objects are created with the following statements; // set the lcd1 address to 0x26 // Set the pins on the I2C chip used for lcd1 connections: // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol LiquidCrystal_I2C lcd1(0x26, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// set the lcd2 address to 0x27
LiquidCrystal_I2C lcd2(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

If I comment out the LCD lines, the SD problem goes away. My thinking is that the four data lines used by the LCDs (4,5,6,7) may be overlapping with the datalogger card, but after looking at the datalogger schematic, I can't see the problem. I found a couple of websites suggesting mapping the LCDs to use different data lines, but I'm not sure if that is the problem.

I also ran a program to scan the I2C bus and it showed that the LCDs were at 26 and 27 and the Adafruit datalogger at 68. No interference with addresses at least.

I really need this working yesterday. Creating datalogging projects is nothing new and I can't believe that there is no solution for including I2C LCD displays. Should I experiment with different LCD libraries or try mapping the pins differently during the creation of the LCD objects? I also am wondering if I can simply shut off the LCDs when writing to the SD card and then turn them back on after. I plan on taking measurements and writing the results every 5 minutes for several days, so high speed anything is not a requirement.

The code sample below is part of my program. I use the while(1) line as a hard break for debugging purposes.

#include <OneWire.h>              // library for DS18B20 thermocouple  
#include <DallasTemperature.h>    // library for DS18B20 thermocouple  
#include <Wire.h>                 // used for rtc
#include <SD.h>                   // library for SD card
#include <SPI.h>                  // library used for SD card
#include <RTClib.h>               // library for real time clock
#include <LiquidCrystal_I2C.h>    // library for lcd displays
#define ONE_WIRE_BUS 8            // Data wire for thermocouple is plugged into pin 8 on the Arduino
#define SYNC_INTERVAL 1000        // mills between calls to flush() - to write data to the card

RTC_PCF8523 rtc;                  // define the Real Time Clock object

String datetimestamp;
uint8_t MM;
uint8_t DD;
uint8_t mm;
uint8_t hh;
File logfile;                     // create file object to save results on SD card
const int chipSelect = 10;        // for the data logging shield, we use digital pin 10 for the SD cs line
OneWire oneWire(ONE_WIRE_BUS);        // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire);  // Pass our oneWire reference to Dallas Temperature.

// set the lcd1 address to 0x26
// Set the pins on the I2C chip used for lcd1 connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd1(0x26, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// set the lcd2 address to 0x27
LiquidCrystal_I2C lcd2(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

String inputString = "";         // a string to hold incoming data
String ackString = "ack";        // acknowledgement string from terminal
String temperature;              // temperature
boolean stringComplete = false;  // whether the incoming string from serial port is complete with /n
int interval = 60000;            // interval between measurements
long previousMillis;
int cycle = 1;                   // cycle number
int heartbeat = 30000;           // ping teminal to prevent bluetooth from shutting down
String dim_length;
String dim_width;
String dim_height;
String measurements;              // string containing measurements for inclusion in SD file
int firstcomma;
int secondcomma;
int thirdcomma;
String logEntry;
char filename[] = "logdata.txt";

void setup(void) {
  Serial.begin(9600);
  inputString.reserve(20);               // reserve space for the inputString
  pinMode(10, OUTPUT);
  pinMode(ONE_WIRE_BUS, INPUT);          // used for thermocouple

  WaitFor(2000);

  lcd1.begin(20, 4);        // initialize the first lcd for 20 chars 4 lines
  lcd1.backlight();         // turn on backlight
  lcd1.clear();             // clear lcd11

  lcd2.begin(20, 4);        // initialize the second lcd for 20 chars 4 lines
  lcd2.backlight();         // turn on backlight
  lcd2.clear();             // clear lcd11

  //These routines update rows on the LCDs
  Row1("DATE: ");
  Row2("TEST CYCLE: ");
  Row3(" ");
  Row4(" ");

  // check for working real time clock
  if (! rtc.begin()) {
    Row4("RTC failed");
    WaitFor(500);
    while (1);
  }
  else {
    Row4("RTC found");
    WaitFor(500);
  }

  if (! rtc.initialized()) {
    Row4("RTC failed");
    WaitFor(500);
    while (1);
  } else {
    Row4("RTC initialized");
    WaitFor(500);
  }

  UpdateRow1(GetTimestamp());      // display current date and time
  UpdateRow2(cycle);               // display current test cycle

  // initialize SD card
  if (!SD.begin(10)) {
    Row4("SD init failed");
    WaitFor(500);
    while (1);
  } else {
    Row4("SD card initialized");
    WaitFor(500);
  }

  //log file setup
  if (SD.exists(filename)) {
    Row4("log file exists");
    WaitFor(500);
  } else {
    Row4("log doesn't exist");
    WaitFor(500);
  }

  // sample write to SD card
  Row4("opening log file");
  logfile = SD.open(filename, FILE_WRITE);
  Row4("writing log file");
  WaitFor(500);
  logfile.println("DateTime,Temperature");
  WaitFor(500);
  for (int x = 1; x < 6; x++) {
    logfile.print("Test # ");
    logfile.println(x);
    delay(1000);
  }
  logfile.flush();
  WaitFor(500);
  Row4("flushed log file");
  WaitFor(1000);

  while (1);  //temporary stop for debugging
1

I think your problem is with the way you create the LCD instants.

I've always used LiquidCrystal_I2C lcd(0x27, 20, 4); LiquidCrystal_I2C lcd(address, row, col); when I'm using the I2C modules.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.