ЖК-дисплеи мешают работе SD-карты регистратора данных Adafruit

Я использую защитный экран регистратора данных Adafruit (Rev B) и пару дешевых ЖК-дисплеев 20x4 I2C. На задней панели дисплеев имеется небольшая плата модуля расширения ввода-вывода I2C. Я использую следующие ЖК-дисплеи;

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

Я использую библиотеку I2C NewLiquidCrystal 1.3.4. Мой клон UNO — это iteaduino-BT https://www.itead.cc/iteaduino-bt.html, какая плата мне очень нравится.

У меня возникают помехи между ЖК-дисплеем и функцией SD-карты. Иногда я могу писать на SD-карту, а иногда нет. Я пробовал несколько SD-карт. После долгих экспериментов я думаю, что определил проблему. ЖК-дисплеи каким-то образом мешают функциям SD-карты. ЖК-объекты создаются с помощью следующих операторов; // устанавливаем адрес lcd1 на 0x26 // Установите контакты на микросхеме I2C, используемой для соединений lcd1: // адрес, en,rw,rs,d4,d5,d6,d7,bl,blpol LiquidCrystal_I2C lcd1(0x26, 2, 1, 0, 4, 5, 6, 7, 3, ПОЛОЖИТЕЛЬНО);

// устанавливаем адрес lcd2 на 0x27
LiquidCrystal_I2C lcd2(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

Если я закомментирую строки ЖК-дисплея, проблема с SD исчезнет. Я думаю, что четыре линии данных, используемые ЖК-дисплеями (4,5,6,7), могут перекрываться с картой регистратора данных, но, посмотрев на схему регистратора данных, я не вижу проблемы. Я нашел пару веб-сайтов, предлагающих сопоставить ЖК-дисплеи с использованием разных линий данных, но я не уверен, что проблема в этом.

Я также запустил программу для сканирования шины I2C, и она показала, что ЖК-дисплеи были на 26 и 27, а регистратор данных Adafruit на 68. По крайней мере, никаких помех с адресами.

Мне действительно нужно, чтобы это работало вчера. Создание проектов регистрации данных не является чем-то новым, и я не могу поверить, что нет решения для включения ЖК-дисплеев I2C. Должен ли я экспериментировать с различными библиотеками ЖК-дисплеев или попробовать по-разному отображать контакты во время создания объектов ЖК-дисплея? Мне также интересно, могу ли я просто отключить ЖК-дисплеи при записи на SD-карту, а затем снова включить их. Я планирую проводить замеры и записывать результаты каждые 5 минут в течение нескольких дней, так что высокой скорости ничего не требуется.

Приведенный ниже пример кода является частью моей программы. Я использую строку while(1) в качестве жесткого разрыва в целях отладки.

#include <OneWire.h>              // библиотека для термопары DS18B20
#include <DallasTemperature.h>    // библиотека для термопары DS18B20
#include <Wire.h>                 // используется для rtc
#include <SD.h>                   // библиотека для SD карты
#include <SPI.h>                  // библиотека, используемая для SD-карты
#include <RTClib.h>               // библиотека для часов реального времени
#include <LiquidCrystal_I2C.h>    // библиотека для ЖК-дисплеев
#define ONE_WIRE_BUS 8            // Провод данных для термопары подключен к контакту 8 на Arduino
#define SYNC_INTERVAL 1000        // перемалывает между вызовами flush() - для записи данных на карту

RTC_PCF8523 rtc;                  // определяем объект часов реального времени

String datetimestamp;
uint8_t MM;
uint8_t DD;
uint8_t mm;
uint8_t hh;
File logfile;                     // создаем файловый объект для сохранения результатов на SD-карту
const int chipSelect = 10;        // для экрана регистрации данных мы используем цифровой контакт 10 для линии SD cs
OneWire oneWire(ONE_WIRE_BUS);        // Настройте экземпляр oneWire для связи с любыми устройствами OneWire (не только с микросхемами температуры Maxim/Dallas)
DallasTemperature sensors(&oneWire);  // Передаем нашу ссылку oneWire в Dallas Temperature.

// устанавливаем адрес lcd1 на 0x26
// Установите контакты на микросхеме I2C, используемой для соединений lcd1:
// адрес, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd1(0x26, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// устанавливаем адрес lcd2 на 0x27
LiquidCrystal_I2C lcd2(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

String inputString = "";         // строка для хранения входящих данных
String ackString = "ack";        // строка подтверждения с терминала
String temperature;              // температура
boolean stringComplete = false;  // завершена ли входящая строка из последовательного порта с /n
int interval = 60000;            // интервал между измерениями
long previousMillis;
int cycle = 1;                   // номер цикла
int heartbeat = 30000;           // пропинговать терминал, чтобы Bluetooth не отключился
String dim_length;
String dim_width;
String dim_height;
String measurements;              // строка, содержащая измерения для включения в файл SD
int firstcomma;
int secondcomma;
int thirdcomma;
String logEntry;
char filename[] = "logdata.txt";

void setup(void) {
  Serial.begin(9600);
  inputString.reserve(20);               // резервируем место для inputString
  pinMode(10, OUTPUT);
  pinMode(ONE_WIRE_BUS, INPUT);          // используется для термопары

  WaitFor(2000);

  lcd1.begin(20, 4);        // инициализируем первый ЖК-дисплей на 20 символов 4 строки
  lcd1.backlight();         // включаем подсветку
  lcd1.clear();             // очистить lcd11

  lcd2.begin(20, 4);        // инициализируем второй ЖК-дисплей для 20 символов 4 строки
  lcd2.backlight();         // включаем подсветку
  lcd2.clear();             // очистить lcd11

  //Эти подпрограммы обновляют строки на ЖК-дисплеях
  Row1("DATE: ");
  Row2("TEST CYCLE: ");
  Row3(" ");
  Row4(" ");

  // проверяем рабочие часы реального времени
  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());      // отображаем текущую дату и время
  UpdateRow2(cycle);               // отображаем текущий тестовый цикл

  // инициализируем SD-карту
  if (!SD.begin(10)) {
    Row4("SD init failed");
    WaitFor(500);
    while (1);
  } else {
    Row4("SD card initialized");
    WaitFor(500);
  }

  // настройка файла журнала
  if (SD.exists(filename)) {
    Row4("log file exists");
    WaitFor(500);
  } else {
    Row4("log doesn't exist");
    WaitFor(500);
  }

  // пример записи на SD-карту
  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);  //временная остановка для отладки

, 👍2


1 ответ


1

Я думаю, ваша проблема связана с тем, как вы создаете момент на ЖК-дисплее.

Я всегда использовал LiquidCrystal_I2C lcd(0x27, 20, 4); LiquidCrystal_I2C lcd(address, row, col); при использовании модулей I2C .

,