Sistema autônomo local de coleta de dados (continuação)

Início neste site no link.
A opção mais conveniente para extrair informações sobre a ativação do relé foi a usando o optoacoplador PC817. Diagrama esquemáticoSistema autônomo local de coleta de dados (continuação)As placas contêm três circuitos idênticos, tudo embalado em caixas de plástico ABS, com dimensões de 100x100 mm. Foto do optoacopladorSistema autônomo local de coleta de dados (continuação) Ao conectar a relés com válvulas semicondutoras, a corrente de fuga é suficiente para ativar o PC817 e pode causar um disparo falso do contador. Para evitar tal situação um LED adicional é inserido em série no circuito do optoacoplador e do LED indicador de operação. Para isso, a ponte J1 é desconectada e um LED adicional, LED1, é soldado.
A parte receptora é construída em lado 1Sistema autônomo local de coleta de dados (continuação)lado 2Sistema autônomo local de coleta de dados (continuação)uma placa de protótipo conectada ao ARDUINO MEGA 2560. Para isso, é utilizado um conector de duas fileiras na extremidade. Como dispositivo de exibição de informações, é usado um display resistivo com sensor de temperatura, com resolução de 240x400 HX8352B.Sistema autônomo local de coleta de dados (continuação) Além disso, o conector ICSP na placa do display foi desmantelado e o slot para micro-SD não é utilizado. O motivo é que o slot SD "original" não pode ser usado devido a um conflito na linha SPI. Para o cartão flash, foi utilizado um leitor de cartão separado que possui um estabilizador de 3,3V e um chip buffer com saídas de três estados 74LVS125A. Aqui, encontrei alguns problemas. O buffer com três estados funcionava apenas para E01-ML01DP5 ou para o leitor de cartão. Nos comentários da biblioteca SdFat, notei um aviso sobre a incompatibilidade com outros dispositivos. O conversor de níveis TXS0108E foi removido e substituído por jumpers, pois o E01-ML01DP5 é tolerante a sinais de 5V - mas isso não ajudou. Com um osciloscópio, identifiquei a perda de sinal na linha MISO ao conectar o leitor de cartão. Ao examinar cuidadosamente, descobri que as entradas dos sinais de habilitação OE de 4 canais do 74LVS125A estavam simplesmente soldadas ao fio comum e não havia possibilidade de um terceiro estado. O chip buffer foi usado como um conversor de níveis simples de 5V para 3.3V usando resistores de 3,3 kΩ conectados em série às linhas de sinal, exceto a linha MISO. Sua saída de chave inferior provavelmente puxava os sinais para o nível de "terra". Ao descobrir que o sinal de habilitação da linha MISO é o pino 13, ele foi desconectado da trilha esoldadoSistema autônomo local de coleta de dados (continuação)entre a saída de entrada (9) 74LVS125A seleção de dispositivo CS e o resistor de adaptação. Agora, se não houver acesso ao cartão de memória, o buffer MISO é desativado e não interfere no funcionamento de outro dispositivo.Placa de circuitoSistema autônomo local de coleta de dados (continuação)Receptor em funcionamentoSistema autônomo local de coleta de dados (continuação)Para conectar o relógio DS3231, utiliza-se a interface de software I2C (TWI).
Programa Arduino IDE// 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: dx.com
// 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:
// 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:
// 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 arquivo;
Arquivo myFile;
#define SD_CS_PIN SS

#include <SPI.h> // Подключаем библиотеку для работы с шиной SPI
#include <nRF24L01.h> // Подключаем файл настроек из библиотеки RF24
#include <RF24.h> // Подключаем библиотеку для работы с nRF24L01+
RF24 rádio(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 ("DESENVOLVEDORES & CONSTRUIDORES");
tft.setCursor (30, 20);
tft.print (utf8rus("Construtor V.V." ));
tft.setCursor (40, 40);
tft.print (utf8rus("Torneiro I.I." ));
delay (2000);

radio.begin(); // Iniciamos o funcionamento do nRF24L01+
radio.setChannel(120); // Especificamos o canal para recepção de dados (de 0 a 127)
radio.setDataRate (RF24_250KBPS); // Estipulamos a taxa de transmissão de dados (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS), RF24_1MBPS — 1Mbit/s
radio.setPALevel (RF24_PA_MAX); // Definimos a potência do transmissor (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
radio.openReadingPipe (1, 0xAABBCCDD11LL); // Abrimos 1 tubo com identificador 1 do transmissor 0xAABBCCDD11, para recepção de dados
// Открываем 2 трубу с идентификатором 2 передатчика 0xAABBCCDD22, для приема данных
radio.startListening (); // Ativamos o receptor, começamos a escutar os tubos abertos
// radio.stopListening ();
////////Вывод служебной информации
tft.fillScreen(BLACK);
tft.setCursor (8, 0);
tft.setTextSize(1);
////////Начало инициализации SD карты
Serial.println("Cartão SD inicial");
tft.println("Cartão SD inicial");
tft.setCursor (8, 10);
////////Инициализация карты
if (!SD.begin(SD_CS_PIN)) {
Serial.println("falha na inicialização!");
tft.fillRect ( 8, 10, 85, 7, RED);
tft.setTextColor(BLACK);
tft.println("Falha na inicialização!");
return;
}
tft.setTextColor(WHITE);
Serial.println("inicialização concluída");
tft.println("Inicialização concluída");
delay (2000);
////////Считывание времени- даты и присвоение их переменным
t = rtc.getTime();
time_sec_prev = t.sec;
time_day_prev = t.date;
////////Вывод даты принудительно, что б не ждать смены даты для индикации
tft.setCursor ( 180, 0 ); // definição da posição do cursor
tft.fillRect ( 178, 0, 65, 7, GRAY); // limpeza da área de exibição de tempo
tft.setTextSize(1);
tft.print(rtc.getDateStr());
////////Вывод названия объектов контроля
tft.setTextSize(2);
tft.setCursor (60, 25);
tft.println (utf8rus("Guinchos I"));
////////Создание файла лога и вывод результата попытки создания
tft.setTextSize(1);
tft.setCursor(130, 10); // se o arquivo de log 2.txt foi criado, a gravação continuará no arquivo
if (SD.exists (perv)) {
//tft.setCursor(0, 90);
tft.println(perv);
Serial.println(perv);
} else {
myFile = SD.open(perv, FILE_WRITE); // se o arquivo 2.txt não existir, ele será criado
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("erro ao abrir .txt");
}
}
////////Считывание времени
t = rtc.getTime();
tft.setTextColor(WHITE);
////////Если время изменилось, то вывод новых показаний часов
if ( time_sec_prev != t.sec) {
tft.setCursor ( 120, 0 ); // definição da posição do cursor
tft.fillRect ( 118, 0, 50, 7, GRAY); // limpeza da área de exibição de tempo
tft.setTextSize(1);
tft.print(rtc.getTimeStr()); // exibe as leituras do relógio
time_sec_prev = t.sec;
}
////////Если дата изменилась, то вывод новой даты
if ( time_day_prev != t.date) {
tft.setCursor ( 180, 0 ); // definição da posição do cursor
tft.fillRect ( 178, 0, 65, 7, GRAY); // limpeza da área de saída da data
tft.setTextSize(1);
tft.print(rtc.getDateStr()); // exibe as informações da data
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 ++; // apenas um contador
//////// С определённой условием периодичностью обновление данных
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); // se não houver um arquivo chamado «2.txt», ele será criado.
if (myFile) {
myFile.println(dataString);
myFile.close();
tft.fillRect ( 198, 8, 42, 10, GREEN);
tft.println(«SD OK»);
Serial.println(«SD OK»);
delay (900); // atraso, caso contrário, grava 13 medições idênticas até que um segundo passe
} else {
tft.fillRect ( 198, 8, 42, 10, RED);
tft.println(«SD ERR»);
Serial.println(«SD ERR»);
}
}
}Programa de conversão de caracteres/* 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;
} Programa de conversão de caracteres para exibir o cirílico com a biblioteca Adafruit_GFX deve ser colocado em uma pasta com o programa principal. Além disso, é necessário substituir o arquivo glcdfont.c na Adafruit_GFX por outra fonte. Aqui biblioteca com a substituição necessária. Informações sobre a localização estão facilmente disponíveis na internet.
Em resumo, digo que o sistema atendeu às expectativas, facilitou o acompanhamento do tempo de operação do equipamento. Embora tudo esteja montado em placas de ensaio, não houve reclamações urgentes sobre o funcionamento. Os primeiros elementos funcionam há mais de seis meses e sobreviveram ao inverno. A última construção para 9 equipamentos controlados está em funcionamento desde 5 de março e já está registrando o tempo de operação oficialmente.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster