Начало на данном сайте по ссылке.
Самым удобным для использования вариантом съёма информации о включении пускателя оказался вариант с оптопарой PC817.
Платы содержат по три одинаковых схемы, всё помещено в коробки из ABS пластика, размер 100х100 мм.
При подключении к пусковым аппаратам с полупроводниковыми вентилями их ток утечки достаточен для открытия РС817 и будет ложное срабатывание счётчика. Для исключения такой ситуации последовательно в цепь светодиода оптопары и светодиода индикации работы добавляется ещё один. Для этого размыкается перемычка J1 и впаивается дополнительный светодиод LED1.
Приёмная часть выполнена на
макетной плате подключаемой к ARDUINO MEGA 2560. Для этого используется двухрядный разъём на торце. В качестве устройства отображения информации используется имеющий резистивный тач и датчик температуры экран с разрешением 240х400
Причём разъём к ICSP на плате экрана демонтирован и не используется гнездо для микро- SD. Дело в том, что «родное» гнездо SD нельзя применить по причине конфликта на шине SPI. Для флеш- карты был применен отдельный кардридер имеющий в составе стабилизатор 3,3В и буферную микросхему с тремя состояниями выходов 74LVS125A. Вот тут ждали меня грабли. Буфер с тремя состояниями, но работал или E01-ML01DP5 или кардридер. В комментариях библиотеки SdFat разглядел предупреждение о несовместимости с другими устройствами. Был удалён конвертер уровней на TXS0108E и заменён перемычками, т.к. E01-ML01DP5 толерантен к 5В сигналам- не помогло. С помощью осциллографа выявлено пропадание сигнала на линии MISO при подключении кардридера. При внимательном рассмотрении было установлено, что входы разрешающих сигналов ОЕ 4-х каналов 74LVS125A были просто припаяны к общему проводу и ни о каком третьем состоянии речи быть не могло. Буферная микросхема использовалась как примитивный преобразователь уровней от 5В к 3.3В с использованием резисторов 3,3 КОм включенных последовательно с сигнальными линиями. Кроме линии MISO. Её выходной нижний ключ вероятно притягивал сигналы к уровню «земли». Определив что разрешающий сигнал линии MISO- это вывод 13, он был оторван от дорожки и
между выводом входа (9) 74LVS125A выбора устройства CS и резистором согласования. Теперь если нет обращения к карте памяти, MISO- буфер отключается и не мешает работе другого устройства.
Для подключения часов на DS3231 используется программная шина I2C (TWI).
// IMPORTANT: Adafruit_TFTLCD LIBRARY MUST BE SPECIFICALLY
// CONFIGURED FOR EITHER THE TFT SHIELD OR THE BREAKOUT BOARD.
// SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h FOR SETUP.
//by Open-Smart Team and Catalex Team
//catalex_inc@163.com
//Store: http://dx.com
// https://open-smart.aliexpress.com/store/1199788
//Demo Function: Display graphics, characters
//Arduino IDE: 1.6.5
// Board: Arduino UNO R3, Arduino Mega2560,Arduino Leonardo
// Board:OPEN-SMART UNO R3 5V / 3.3V, Arduino UNO R3, Arduino Mega2560
//3.2INCH TFT:
// https://www.aliexpress.com/store/product/3-2-TFT-LCD-Display-module-Touch-Screen-Shield-board-onboard-temperature-sensor-w-Touch-Pen/1199788_32755473754.html?spm=2114.12010615.0.0.bXDdc3
//OPEN-SMART UNO R3 5V / 3.3V:
// https://www.aliexpress.com/store/product/OPEN-SMART-5V-3-3V-Compatible-UNO-R3-CH340G-ATMEGA328P-Development-Board-with-USB-Cable-for/1199788_32758607490.html?spm=2114.12010615.0.0.ckMTaN
#include <Adafruit_GFX.h> // Core graphics library
//#include <Adafruit_TFTLCD.h> // Hardware-specific library
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#include "SdFat.h" // Use the SdFat library
SdFat SD;
SdFile file;
File myFile;
#define SD_CS_PIN SS
#include <SPI.h> // Подключаем библиотеку для работы с шиной SPI
#include <nRF24L01.h> // Подключаем файл настроек из библиотеки RF24
#include <RF24.h> // Подключаем библиотеку для работы с nRF24L01+
RF24 radio(47, 49);
#include <DS3231.h>
DS3231 rtc(27, 25);
Time t;
uint16_t r = 6000;
uint32_t k = 0;
volatile unsigned long data;
float leb_1;
float leb_2;
float leb_3;
float leb_4;
uint8_t pipe;
int rc = 0;
uint8_t time_sec_prev;
uint8_t time_day_prev;
//***********************************************//
// If you use OPEN-SMART TFT breakout board //
// Reconmmend you to add 5V-3.3V level converting circuit.
// Of course you can use OPEN-SMART UNO Black version with 5V/3.3V power switch,
// you just need switch to 3.3V.
// The control pins for the LCD can be assigned to any digital or
// analog pins...but we'll use the analog pins as this allows us to
//----------------------------------------|
// TFT Breakout -- Arduino UNO / Mega2560 / OPEN-SMART UNO Black
// GND -- GND
// 3V3 -- 3.3V
// CS -- A3
// RS -- A2
// WR -- A1
// RD -- A0
// RST -- RESET
// LED -- GND
// DB0 -- 8
// DB1 -- 9
// DB2 -- 10
// DB3 -- 11
// DB4 -- 4
// DB5 -- 13
// DB6 -- 6
// DB7 -- 7
// Assign human-readable names to some common 16-bit color values:
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define GRAY 0x8C51
#define GRAYD 0x39E7
//Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
// If using the shield, all control and data lines are fixed, and
// a simpler declaration can optionally be used:
// Adafruit_TFTLCD tft;
uint16_t g_identifier;
String dataString;
//String numfileMonth ="1.txt";
char perv [] = {"2.txt"};
//String *numfileMonth="1.txt" (sizeof (numfileMonth));
///////////////////////////////////////////////////////////////////
void setup(void) {
rtc.begin();
// Для установки времени- раскомментировать нужные строки
// rtc.setDOW(6); // День недели
// rtc.setTime(22, 04, 0); // Время, в формате 24 часа.
// rtc.setDate(4, 5, 2019); // Дата, 29 октября 2018г.
Serial.begin(2000000);
//////// Инициализация экрана
tft.begin(0x65);
tft.reset();
tft.setRotation(0);
tft.cp437(true);
//////////////////Вывод имен, принадлежности оборудования, название организации
tft.fillScreen(BLACK);
tft.setTextColor(WHITE);
tft.setTextSize(2);
tft.setCursor (8, 0);
tft.println ("DEVELOPERS & BUILD" );
tft.setCursor (30, 20);
tft.print (utf8rus("Конструктор В.В." ));
tft.setCursor (40, 40);
tft.print (utf8rus("Токарь И.И." ));
delay (2000);
radio.begin(); // Инициируем работу nRF24L01+
radio.setChannel(120); // Указываем канал приёма данных (от 0 до 127)
radio.setDataRate (RF24_250KBPS); // Указываем скорость передачи данных (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS), RF24_1MBPS - 1Мбит/сек
radio.setPALevel (RF24_PA_MAX); // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
radio.openReadingPipe (1, 0xAABBCCDD11LL); // Открываем 1 трубу с идентификатором 1 передатчика 0xAABBCCDD11, для приема данных
// Открываем 2 трубу с идентификатором 2 передатчика 0xAABBCCDD22, для приема данных
radio.startListening (); // Включаем приемник, начинаем прослушивать открытые трубы
// radio.stopListening ();
////////Вывод служебной информации
tft.fillScreen(BLACK);
tft.setCursor (8, 0);
tft.setTextSize(1);
////////Начало инициализации SD карты
Serial.println("Initial SD card");
tft.println("Initial SD card");
tft.setCursor (8, 10);
////////Инициализация карты
if (!SD.begin(SD_CS_PIN)) {
Serial.println("initial failed!");
tft.fillRect ( 8 , 10 , 85 , 7 , RED);
tft.setTextColor(BLACK);
tft.println("Initial failed!");
return;
}
tft.setTextColor(WHITE);
Serial.println("initialization done");
tft.println("Initialization done");
delay (2000);
////////Считывание времени- даты и присвоение их переменным
t = rtc.getTime();
time_sec_prev = t.sec;
time_day_prev = t.date;
////////Вывод даты принудительно, что б не ждать смены даты для индикации
tft.setCursor ( 180 , 0 ); // установка позиции курсора
tft.fillRect ( 178 , 0 , 65 , 7 , GRAY); // очистка области вывода времени
tft.setTextSize(1);
tft.print(rtc.getDateStr());
////////Вывод названия объектов контроля
tft.setTextSize(2);
tft.setCursor (60, 25);
tft.println (utf8rus("Лебёдки I"));
////////Создание файла лога и вывод результата попытки создания
tft.setTextSize(1);
tft.setCursor(130, 10); // если файл лога 2.txt создан, то будет продолжена запись в файл
if (SD.exists (perv)) {
//tft.setCursor(0, 90);
tft.println(perv);
Serial.println(perv);
} else {
myFile = SD.open(perv, FILE_WRITE); // если файла 2.txt нет, то он будет создан
myFile.close();
tft.println(perv);
Serial.println(perv);
}
}
void loop(void) {
////////Проверка существования запроса вывода лога в монитор СОМ- порта
if (Serial.available() > 0) {
if (1 == Serial.read());
////////И если принята "1"- то вывод
File myFile = SD.open(perv);
// if the file is available, write to it:
if (myFile) {
while (myFile.available()) {
Serial.write(myFile.read());
}
myFile.close();
}
else {
Serial.println("error opening .txt");
}
}
////////Считывание времени
t = rtc.getTime();
tft.setTextColor(WHITE);
////////Если время изменилось, то вывод новых показаний часов
if ( time_sec_prev != t.sec) {
tft.setCursor ( 120 , 0 ); // установка позиции курсора
tft.fillRect ( 118 , 0 , 50 , 7 , GRAY); // очистка области вывода времени
tft.setTextSize(1);
tft.print(rtc.getTimeStr()); // вывод показаний часов
time_sec_prev = t.sec;
}
////////Если дата изменилась, то вывод новой даты
if ( time_day_prev != t.date) {
tft.setCursor ( 180 , 0 ); // установка позиции курсора
tft.fillRect ( 178 , 0 , 65 , 7 , GRAY); // очистка области вывода даты
tft.setTextSize(1);
tft.print(rtc.getDateStr()); // вывод показаний даты
time_day_prev = t.date;
}
////////Если доступен радиоприём, то
if (radio.available(&pipe)) {
////////проверка заполнения буфера приёма,
radio.read(&data, sizeof(data));
////////если доступен нужный адрес передатчика, то
if (pipe == 1) {
////////ждём синхронизирующую последовательность нулей для определения
//начала блока данных
if ( data == 0000 ) {
rc = 0;
} else {
rc ++;
}
////////Запись значений счётчиков и расчёт их в 10 и 100-х долях часа
if ( rc == 1 ) {
leb_1 = data / 3600.0;
}
if ( rc == 2 ) {
leb_2 = data / 3600.0;
}
if ( rc == 3 ) {
leb_3 = data / 3600.0;
}
if ( rc == 4 ) {
leb_4 = data / 3600.0;
}
}
}
r ++;
k ++; // просто счётчик
//////// С определённой условием периодичностью обновление данных
if ( r >= 6500) {
tft.setTextSize(2);
tft.fillRect ( 0 , 41 , 180 , 64 , GRAYD);
Serial.println ("Lebedki I");
tft.setCursor (0, 41);
tft.println (leb_1);
Serial.println (leb_1);
tft.println (leb_2);
Serial.println (leb_2);
tft.println (leb_3);
Serial.println (leb_3);
tft.println (leb_4);
Serial.println (leb_4);
Serial.println (k);
r = 0;
}
////////Запись данных в лог на SD каждые 10 мин.
if ((t.min % 10 == 0) && ( t.sec == 0)) {
tft.setTextSize(1);
tft.setCursor(200, 10);
tft.setTextColor(BLACK);
////////Создание строки в формате .csv
String dataString = String (rtc.getDateStr()) + ", "+(rtc.getTimeStr()) + ", " + (leb_1) + ", " + (leb_2)
+ ", " + (leb_3) + ", " + (leb_4) + ", ";
////////Запись в файл и вывод результатов процесса записи
myFile = SD.open(perv, FILE_WRITE); // если файла с именем "2.txt" - нет, то он будет создан.
if (myFile) {
myFile.println(dataString);
myFile.close();
tft.fillRect ( 198 , 8 , 42 , 10 , GREEN);
tft.println("SD OK");
Serial.println("SD OK");
delay (900); // задержка, иначе записывает 13 одинаковых показаний, пока секунда не пройдёт
} else {
tft.fillRect ( 198 , 8 , 42 , 10 , RED);
tft.println("SD ERR");
Serial.println("SD ERR");
}
}
}
/* Recode russian fonts from UTF-8 to Windows-1251 */
String utf8rus(String source)
{
int i,k;
String target;
unsigned char n;
char m[2] = { '0', '' };
k = source.length(); i = 0;
while (i < k) {
n = source[i]; i++;
if (n >= 0xC0) {
switch (n) {
case 0xD0: {
n = source[i]; i++;
if (n == 0x81) { n = 0xA8; break; }
if (n >= 0x90 && n <= 0xBF) n = n + 0x30;//0x2F
break;
}
case 0xD1: {
n = source[i]; i++;
if (n == 0x91) { n = 0xB8; break; }
if (n >= 0x80 && n <= 0x8F) n = n + 0x70;//0x6F
break;
}
}
}
m[0] = n; target = target + String(m);
}
return target;
}
Программа перекодировки символов для вывода кириллицы библиотекой Adafruit_GFX помещается в одну папку с основной программой. Еще надо в Adafruit_GFX заменить файл glcdfont.с с другим шрифтом. Здесь библиотека с требуемой заменой. Подробнее о русификации легко ищется в интернете.
Подводя итог скажу что система оправдала надежды, стало проще следить за наработкой оборудования. Хоть всё собрано на макетных платах, и в срочном порядке нареканий в работе нет.
Первые элементы работают уже более полугода и пережили зиму. Последняя конструкция на 9 контролируемых агрегатов работает с 5 марта и по ней идет регистрация времени наработки уже официально.
Автор: viktoin