Local Autonomous Data Collection System (continued)

Local Autonomous Data Collection System (continued)

Start on this site by reference .

The most convenient option to use the information about the starting of the starter was the option with the PC817 optocoupler.

Schematic diagram
image alt

The boards contain three identical circuits, everything is placed in ABS plastic boxes, size 100x100 mm.

Photo optocoupler
image alt

When connected to the starters with semiconductor valves, their leakage current is sufficient for opening the PC817 and there will be a false trigger. To avoid such a situation, , one more is added to the optocoupler LED and work indication LED circuit. To do this, jumper J1 opens and solder the additional LED1.

The receiving part is made on

side 1
image alt

side 2
image alt

prototype board connected to ARDUINO MEGA 2560. For this purpose, a double-row connector is used on the end. As a display device, a resistive touch screen and a temperature sensor with a resolution of 240x400 are used.

image alt

Moreover, the connector to the ICSP on the screen board is removed and the slot for micro SD is not used. The fact is that the “native” SD slot cannot be applied due to a conflict on the SPI bus. A separate card reader with a 3.3V stabilizer and a three-state buffer chip 74LVS125A was used for the flash card. Here a rake waited for me. A tri-state buffer, but it worked either as an E01-ML01DP5 or card reader. In the comments of the library SdFat saw a warning about incompatibility with other devices. The level converter on TXS0108E has been removed and replaced by jumpers, as E01-ML01DP5 tolerant to 5V signals, did not help. Using an oscilloscope, the signal was lost on the MISO line when the card reader was connected. On closer examination, it was found that the inputs of the enabling signals of the OE 4 channels 74LVS125A were simply soldered to the common wire and there could be no third state of speech. The buffer chip was used as a primitive level converter from 5V to 3.3V using 3.3 KΩ resistors connected in series with the signal lines. Besides the MISO line. Her bottom output key probably pulled the signals to ground level. Having determined that the resolution signal of the MISO line is pin 13, it was cut off from the track and

image alt

between the output of the input device selection (9) 74LVS125A CS and the matching resistor. Now, if there is no access to the memory card, the MISO buffer is disabled and does not interfere with the operation of another device.

Breadboard layout
image alt

Receiver at work
image alt

To connect the clock on the DS3231, I2C (TWI) software bus is used.

Arduino IDE program
 //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 & lt; Adafruit_GFX.h & gt;//Core graphics library//# include & lt; Adafruit_TFTLCD.h & gt;//Hardware-specific library
 #include & lt; MCUFRIEND_kbv.h & gt;
 MCUFRIEND_kbv tft;
 #include "SdFat.h"//Use the SdFat library
 SdFat SD;
 SdFile file;
 File myFile;
 #define SD_CS_PIN SS

 #include & lt; SPI.h & gt;//Connect the library for working with the SPI bus
 #include & lt; nRF24L01.h & gt;//Connect the settings file from the RF24 library
 #include & lt; RF24.h & gt;//Connect the library to work with nRF24L01 +
 RF24 radio (47, 49);

 #include & lt; DS3231.h & gt;

 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 LCD can be assigned to any digital or//analog pins ... but it 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 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 ();

//To set the time - uncomment the necessary lines
//rtc.setDOW (6);//Day of the week
//rtc.setTime (22, 04, 0);//Time, in the format of 24 hours.
//rtc.setDate (4, 5, 2019);//Date, October 29, 2018

  Serial.begin (2,000,000);////////Initialize the screen
  tft.begin (0x65);
  tft.reset ();
  tft.setRotation (0);
  tft.cp437 (true);//////////////////Display of names, equipment accessories, organization name
  tft.fillScreen (BLACK);
  tft.setTextColor (WHITE);
  tft.setTextSize (2);
  tft.setCursor (8, 0);
  tft.println ("DEVELOPERS & amp; BUILD");
  tft.setCursor (30, 20);
  tft.print (utf8rus ("Designer V.V."));
  tft.setCursor (40, 40);
  tft.print (utf8rus ("Tokar II."));
  delay (2000);

  radio.begin ();//Initiate nRF24L01 + operation
  radio.setChannel (120);//Specify the data receiving channel (from 0 to 127)
  radio.setDataRate (RF24_250KBPS);//Specify the data transfer rate (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS), RF24_1MBPS - 1Mbit/s
  radio.setPALevel (RF24_PA_MAX);//Specify the transmitter power (RF24_PA_MIN = -18dBm, RF24_PA_LOW = -12dBm, RF24_PA_HIGH = -6dBm, RF24_PA_MAX = 0dBm)
  radio.openReadingPipe (1, 0xAABBCCDD11LL);//Open 1 pipe with transmitter identifier 1 0xAABBCCDD11, for receiving data
//Open 2 pipe with transmitter identifier 2 0xAABBCCDD22, for receiving data
  radio.startListening ();//Turn on the receiver, start listening to open pipes
//radio.stopListening ();////////Output of service information
  tft.fillScreen (BLACK);
  tft.setCursor (8, 0);
  tft.setTextSize (1);////////Start of initialization of the SD card
  Serial.println ("Initial SD card");
  tft.println ("Initial SD card");
  tft.setCursor (8, 10);////////Initialize the card
  if (! SD.begin (SD_CS_PIN)) {
  Serial.println ("initial failed!");
  tft.fillRect (8, 10, 85, 7, RED);
  tft.setTextColor (BLACK);
  tft.println ("Initial failed!");
  tft.setTextColor (WHITE);
  Serial.println ("initialization done");
  tft.println ("Initialization done");
  delay (2000);////////Reading time-dates and assigning them to variables
  t = rtc.getTime ();
  time_sec_prev = t.sec;
  time_day_prev = t.date;////////Forced date output, so as not to wait for the date to change to indicate
  tft.setCursor (180, 0);//set the cursor position
  tft.fillRect (178, 0, 65, 7, GRAY);//clear time display area
  tft.setTextSize (1);
  tft.print (rtc.getDateStr ());////////Display the name of objects of control
  tft.setTextSize (2);
  tft.setCursor (60, 25);
  tft.println (utf8rus ("Winch I"));////////Create a log file and display the result of an attempt to create
  tft.setTextSize (1);
  tft.setCursor (130, 10);//if the log file 2.txt is created, it will continue writing to the file
  if (SD.exists (perv)) {
//tft.setCursor (0, 90);
  tft.println (perv);
  Serial.println (perv);
  } else {
  myFile = SD.open (perv, FILE_WRITE);//if there is no 2.txt file, it will be created
  myFile.close ();
  tft.println (perv);
  Serial.println (perv);

 void loop (void) {////////Check for the existence of a request for log output in the COM port monitor
  if (Serial.available () & gt; 0) {
  if (1 == Serial.read ());////////And if "1" is accepted, then the output
  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");
  }////////Read time
  t = rtc.getTime ();
  tft.setTextColor (WHITE);////////If the time has changed, then the output of new clocks
  if (time_sec_prev! = t.sec) {
  tft.setCursor (120, 0);//set the cursor position
  tft.fillRect (118, 0, 50, 7, GRAY);//clear time display area
  tft.setTextSize (1);
  tft.print (rtc.getTimeStr ());//display hours
  time_sec_prev = t.sec;
  }////////If the date has changed, then display the new date
  if (time_day_prev! = t.date) {
  tft.setCursor (180, 0);//set the cursor position
  tft.fillRect (178, 0, 65, 7, GRAY);//clear the date display area
  tft.setTextSize (1);
  tft.print (rtc.getDateStr ());//display date readings
  time_day_prev = t.date;
  }////////If radio reception is available, then
  if (radio.available (& amp; pipe)) {////////check the fill buffer reception,
  radio.read (& amp; data, sizeof (data));////////if the desired address of the transmitter is available, then
  if (pipe == 1) {////////wait for the synchronization sequence of zeros to determine//start of data block
  if (data == 0000) {
  rc = 0;
  } else {
  rc ++;
  }////////Record the values ​​of counters and calculate them in 10 and 100ths of an hour
  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 ++;//just a counter
////////With a certain condition, the frequency of updating data
  if (r & gt; = 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;
  }////////Writing data to the SD log every 10 minutes.
  if ((t.min% 10 == 0) & amp; & (t.sec == 0)) {
  tft.setTextSize (1);
  tft.setCursor (200, 10);
  tft.setTextColor (BLACK);////////Create a string in .csv format
  String dataString = String (rtc.getDateStr ()) + "," + (rtc.getTimeStr ()) + "," + (leb_1) + "," + (leb_2)
  + "," + (leb_3) + "," + (leb_4) + ",";////////Write to file and output the results of the write process
  myFile = SD.open (perv, FILE_WRITE);//if the file with the name "2.txt" is not, then it will be created.
  if (myFile) {
  myFile.println (dataString);
  myFile.close ();
  tft.fillRect (198, 8, 42, 10, GREEN);
  tft.println ("SD OK");
  Serial.println ("SD OK");
  delay (900);//delay, otherwise it records 13 identical readings until a second passes
  } else {
  tft.fillRect (198, 8, 42, 10, RED);
  tft.println ("SD ERR");
  Serial.println ("SD ERR");

Character Conversion Program
 /* 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', '\ 0'};

  k = source.length ();  i = 0;

  while (i & lt; k) {
  n = source [i];  i ++;

  if (n & gt; = 0xC0) {
  switch (n) {
  case 0xD0: {
  n = source [i];  i ++;
  if (n == 0x81) {n = 0xA8;  break;  }
  if (n & gt; = 0x90 & amp; & n; n & lt; = 0xBF) n = n + 0x30;//0x2F
  case 0xD1: {
  n = source [i];  i ++;
  if (n == 0x91) {n = 0xB8;  break;  }
  if (n & gt; = 0x80 & amp; & n; n & lt; = 0x8F) n = n + 0x70;//0x6F
  m [0] = n;  target = target + String (m);
 return target;

The program for recoding characters for Cyrillic output by the Adafruit_GFX library is placed in the same folder as the main program. It is also necessary in Adafruit_GFX to replace the file glcdfont.c with a different font. Here is a library with the required replacement. More information about the Russification is easily searched on the Internet.

Summing up, I will say that the system has met expectations, it has become easier to follow the equipment. Although everything is collected on the mockups, and there are no urgent complaints about the work.

The first elements have been working for more than six months and have survived the winter. The latest design on 9 controlled units has been in operation since March 5th and it is recording the running time already officially.

Source text: Local Autonomous Data Collection System (continued)