Lokalny autonomiczny system akwizycji danych (ciąg dalszy)

Zacznij od tej strony по ссылке.
Najwygodniejszą opcją odzyskania informacji o włączeniu rozrusznika okazała się opcja z transoptorem PC817. Schemat obwoduLokalny autonomiczny system akwizycji danych (ciąg dalszy)Na płytkach znajdują się trzy identyczne obwody, wszystko umieszczono w plastikowych pudełkach ABS o wymiarach 100x100 mm. Zdjęcie transoptorówLokalny autonomiczny system akwizycji danych (ciąg dalszy) Po podłączeniu do urządzeń rozruchowych z zaworami półprzewodnikowymi, ich prąd upływowy jest wystarczający do otwarcia PC817, a licznik uruchomi się fałszywie. Aby wykluczyć taką sytuację jeszcze jeden jest dodawany szeregowo do obwodu diody LED transoptora i diody LED sygnalizującej działanie. W tym celu należy rozpiąć zworkę J1 i wlutować dodatkową diodę LED LED1.
Część odbiorcza jest wykonana strona 1Lokalny autonomiczny system akwizycji danych (ciąg dalszy)strona 2Lokalny autonomiczny system akwizycji danych (ciąg dalszy)płytka rozwojowa podłączona do ARDUINO MEGA 2560. W tym celu na końcu zastosowano dwurzędowe złącze. Jako urządzenie wyświetlające informacje służy ekran o rozdzielczości 240x400, posiadający rezystancyjny ekran dotykowy i czujnik temperatury. HX8352B.Lokalny autonomiczny system akwizycji danych (ciąg dalszy) Co więcej, złącze do ICSP na płycie ekranu jest usunięte, a gniazdo micro SD nie jest używane. Faktem jest, że „natywnego” gniazda SD nie można używać z powodu konfliktu na magistrali SPI. Dla karty flash zastosowano oddzielny czytnik kart, który zawierał stabilizator 3,3 V oraz układ buforujący z trzema stanami wyjściowymi 74LVS125A. Tutaj czekał na mnie grabie. Bufor trójstanowy, ale działał albo E01-ML01DP5, albo czytnik kart. W komentarzach biblioteki SdFat zobaczył ostrzeżenie o niezgodności z innymi urządzeniami. Konwerter poziomu w TXS0108E został usunięty i zastąpiony zworkami, ponieważ E01-ML01DP5 jest tolerancyjny na sygnały 5V - nie pomogło. Za pomocą oscyloskopu wykryto utratę sygnału na linii MISO po podłączeniu czytnika kart. Po dokładnym zbadaniu stwierdzono, że wejścia sygnałów włączających kanałów OE 4 układu 74LVS125A zostały po prostu przylutowane do wspólnego przewodu i nie można było mówić o żadnym trzecim stanie. Układ buforowy posłużył jako prymitywny przetwornik poziomu z 5 V na 3.3 V wykorzystujący rezystory 3,3 KΩ połączone szeregowo z liniami sygnałowymi. Z wyjątkiem linii MISO. Jego dolny przełącznik wyjściowy prawdopodobnie przyciągał sygnały do ​​poziomu gruntu. Po ustaleniu, że sygnałem włączającym linię MISO był pin 13, został on oderwany od toru ilutowaneLokalny autonomiczny system akwizycji danych (ciąg dalszy)pomiędzy urządzeniem 9LVS74A CS wybierz pin wejściowy (125) i rezystor końcowy. Teraz w przypadku braku dostępu do karty pamięci bufor MISO zostaje wyłączony i nie zakłóca pracy innego urządzenia.Schemat płytki rozwojowejLokalny autonomiczny system akwizycji danych (ciąg dalszy)Odbiornik działającyLokalny autonomiczny system akwizycji danych (ciąg dalszy)DS3231 wykorzystuje programową magistralę I2C (TWI) do podłączenia zegara.
Program Arduino IDE// WAŻNE: BIBLIOTEKA Adafruit_TFTLCD MUSI BYĆ KONKRETNA
// SKONFIGUROWANY DLA TFT SHIELD LUB TABLICY WYŁĄCZENIOWEJ.
// ZOBACZ ODPOWIEDNIE KOMENTARZE W Adafruit_TFTLCD.h DOTYCZĄCE KONFIGURACJI.
//przez zespół Open-Smart i zespół Catalex
//[email chroniony]
//Sklep: dx.com
// open-smart.aliexpress.com/store/1199788
//Funkcja demonstracyjna: wyświetla grafikę i znaki
//Arduino IDE: 1.6.5
// Płytka: Arduino UNO R3, Arduino Mega2560, Arduino Leonardo

// Płytka:OPEN-SMART UNO R3 5V / 3.3V, Arduino UNO R3, Arduino Mega2560
//3.2-calowy wyświetlacz 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

#włączać // Podstawowa biblioteka graficzna
//#włączać // Biblioteka specyficzna dla sprzętu
#włączać
MCUFRIEND_kbv tft;
#include "SdFat.h" // Użyj biblioteki SdFat
SdFat SD;
plik SdFile;
Plik mójPlik;
#zdefiniuj SD_CS_PIN SS

#włączać // Podłącz bibliotekę do pracy z magistralą SPI
#włączać // Połącz plik ustawień z biblioteki RF24
#włączać // Podłącz bibliotekę do pracy z nRF24L24+
Radio RF24(47, 49);

#włączać

DS3231 rtc(27, 25);
Czas t;

uint16_t r = 6000;
uint32_t k = 0;

lotne, długie dane bez znaku;
pływający leb_1;
pływający leb_2;
pływający leb_3;
pływający leb_4;

uint8_t potok;
int rc = 0;

uint8_t time_sec_prev;
uint8_t time_day_prev;

//************************************************** ****************/ /
// Jeśli używasz tablicy rozdzielczej OPEN-SMART TFT //
// Zalecamy dodanie obwodu konwertującego poziom 5 V-3.3 V.
// Oczywiście można zastosować wersję OPEN-SMART UNO Black z wyłącznikiem zasilania 5V/3.3V,
// wystarczy przełączyć na 3.3 V.
// Piny sterujące wyświetlacza LCD można przypisać do dowolnego cyfrowego lub
// piny analogowe...ale użyjemy pinów analogowych, ponieważ nam to pozwala
//—————————————-|
// TFT Breakout - Arduino UNO / Mega2560 / OPEN-SMART UNO Czarny
// GND - GND
// 3V3 - 3.3V
//CS-A3
//RS-A2
//WR-A1
//RD-A0
// RST – RESETUJ
// Dioda - GND
//DB0 - 8
//DB1 - 9
//DB2 - 10
//DB3 - 11
//DB4 - 4
//DB5 - 13
//DB6 - 6
//DB7 - 7

// Przypisz czytelne dla człowieka nazwy do niektórych popularnych 16-bitowych wartości kolorów:
#zdefiniuj CZARNY 0x0000
#zdefiniuj NIEBIESKI 0x001F
#zdefiniuj CZERWONY 0xF800
#zdefiniuj ZIELONY 0x07E0
#zdefiniuj CYJAN 0x07FF
#zdefiniuj MAGENTA 0xF81F
#zdefiniuj ŻÓŁTY 0xFFE0
#zdefiniuj BIAŁY 0xFFFF
#zdefiniuj SZARY 0x8C51
#zdefiniuj SZARY 0x39E7

//Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
// Jeśli używasz tarczy, wszystkie linie sterujące i dane są naprawione, i
// opcjonalnie można zastosować prostszą deklarację:
// Adafruit_TFTLCD tft;
uint16_t g_identifier;

Ciąg danychString;
//String numfileMonth = "1.txt";
char perv [] = {"2.txt"};
//String *numfileMonth="1.txt" (sizeof (numfileMonth));
///////////////////////////////////////////////// /////////////////

nieważne ustawienia (unieważnione) {

rtc.begin();

// Aby ustawić godzinę, odkomentuj niezbędne linie
// rtc.setDOW(6); // Dzień tygodnia
// rtc.setTime(22, 04, 0); // Czas w formacie 24-godzinnym.
// rtc.setDate(4, 5, 2019); // Data, 29 października 2018 r

Serial.begin (2000000);
//////// Inicjalizacja ekranu
tft.begin(0x65);
tft.reset();
tft.setRotation(0);
tft.cp437(true);
//////////////////Wyprowadzanie nazw, akcesoriów sprzętowych, nazwy organizacji
tft.fillScreen(CZARNY);
tft.setTextColor(BIAŁY);
tft.setTextSize(2);
tft.setCursor(8, 0);
tft.println("DEWELOPERS I BUDUJ");
tft.setCursor(30, 20);
tft.print (utf8rus("Konstruktor V.V." ));
tft.setCursor(40, 40);
tft.print (utf8rus("Turner II.I." ));
opóźnienie (2000);

radio.begin(); // Rozpocznij pracę nRF24L01+
radio.setKanał(120); // Określ kanał odbioru danych (od 0 do 127)
radio.setDataRate(RF24_250KBPS); // Określ szybkość przesyłania danych (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS), RF24_1MBPS - 1Mbit/s
radio.setPALevel(RF24_PA_MAX); // Określ moc nadajnika (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm)
radio.openReadingPipe(1, 0xAABBCCDD11LL); // Otwórz 1 potok z identyfikatorem 1 nadajnika 0xAABBCCDD11, aby odebrać dane
// Otwórz potok 2 z identyfikatorem nadajnika 2xAABBCCDD0, aby odebrać dane
radio.startSłuchanie(); // Włącz odbiornik, zacznij słuchać otwartych rur
// radio.stopListening();
////////Wyprowadzanie informacji serwisowych
tft.fillScreen(CZARNY);
tft.setCursor(8, 0);
tft.setTextSize(1);
////////Rozpocznij inicjalizację karty SD
Serial.println("Początkowa karta SD");
tft.println("Początkowa karta SD");
tft.setCursor(8, 10);
////////Inicjowanie karty
if (!SD.begin(SD_CS_PIN)) {
Serial.println("Inicjacja nie powiodła się!");
tft.fillRect(8, 10, 85, 7, CZERWONY);
tft.setTextColor(CZARNY);
tft.println("Początkowe niepowodzenie!");
powrotu;
}
tft.setTextColor(BIAŁY);
Serial.println("Inicjalizacja zakończona");
tft.println("Inicjalizacja zakończona");
opóźnienie (2000);
////////Odczyt czasu i daty oraz przypisanie ich do zmiennych
t = rtc.getTime();
time_sec_prev = t.s;
time_day_prev = t.data;
////////Wymuś wyświetlenie daty, aby nie czekać na zmianę daty w celu wyświetlenia
tft.setCursor(180, 0); // ustawienie pozycji kursora
tft.fillRect(178, 0, 65, 7, SZARY); // czyszczenie obszaru wyjściowego czasu
tft.setTextSize(1);
tft.print(rtc.getDateStr());
////////Wypisz nazwę obiektów kontrolnych
tft.setTextSize(2);
tft.setCursor(60, 25);
tft.println (utf8rus("Wciągarki I"));
////////Tworzenie pliku dziennika i wyświetlanie wyniku próby utworzenia
tft.setTextSize(1);
tft.setCursor(130, 10); // jeśli utworzony zostanie plik dziennika 2.txt, zapis do pliku będzie kontynuowany
if (SD.istnieje(perv)) {
//tft.setCursor(0, 90);
tft.println(perv);
Serial.println(perv);
} Else {
mójPlik = SD.open(perv, FILE_WRITE); // jeśli plik 2.txt nie istnieje, zostanie utworzony
mójPlik.close();
tft.println(perv);
Serial.println(perv);
}
}

void loop (void) {
////////Sprawdzanie istnienia żądania wysłania dziennika do monitora portu COM
if (Serial.available() > 0) {
if (1 == Serial.read());
////////A jeśli zostanie zaakceptowane „1”, to wynik
Plik mójPlik = SD.open(perv);
// jeśli plik jest dostępny napisz do niego:
jeśli (mój plik) {
póki (mójPlik.dostępny()) {
Serial.write(myFile.read());
}
mójPlik.close();
}
else {
Serial.println("Błąd podczas otwierania .txt");
}
}
////////Czas czytania
t = rtc.getTime();
tft.setTextColor(BIAŁY);
////////Jeśli czas się zmienił, wyświetl nowe wskazania zegara
if ( time_sec_prev != t.s) {
tft.setCursor(120, 0); // ustawienie pozycji kursora
tft.fillRect(118, 0, 50, 7, SZARY); // czyszczenie obszaru wyjściowego czasu
tft.setTextSize(1);
tft.print(rtc.getTimeStr()); // odczyty zegara wyjściowego
time_sec_prev = t.s;
}
////////Jeśli data się zmieniła, wyświetl nową datę
if (time_day_prev != t.data) {
tft.setCursor(180, 0); // ustawienie pozycji kursora
tft.fillRect(178, 0, 65, 7, SZARY); // wyczyść obszar wyświetlania daty
tft.setTextSize(1);
tft.print(rtc.getDateStr()); // wyświetla odczyty dat
time_day_prev = t.data;
}
////////Jeśli odbiór radiowy jest dostępny, oznacza to
if (radio.available(&pipe)) {
////////sprawdzenie czy bufor odbioru jest pełny,
radio.read(&data, sizeof(data));
////////jeśli wymagany adres nadajnika jest dostępny
if (rura == 1) {
////////oczekiwanie na synchronizującą sekwencję zer w celu ustalenia
//początek bloku danych
if (dane == 0000) {
rc = 0;
} Else {
rc++;
}
////////Rejestrowanie wartości liczników i obliczanie ich w dziesiątych i setnych częściach godziny
jeśli (rc == 1) {
leb_1 = dane / 3600.0;
}

jeśli (rc == 2) {
leb_2 = dane / 3600.0;
}

jeśli (rc == 3) {
leb_3 = dane / 3600.0;
}

jeśli (rc == 4) {
leb_4 = dane / 3600.0;
}
}
}
r++;
k++; //tylko licznik
//////// Aktualizacja danych z określoną częstotliwością
jeśli ( r >= 6500) {
tft.setTextSize(2);
tft.fillRect(0, 41, 180, 64, SZARY);
Serial.println("Łębedki 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;
}
////////Zapis danych do logu na SD co 10 minut.
if ((t.min % 10 == 0) && ( t.s == 0)) {
tft.setTextSize(1);
tft.setCursor(200, 10);
tft.setTextColor(CZARNY);
////////Tworzenie ciągu znaków w formacie .csv
String dataString = String (rtc.getDateStr()) + ", "+(rtc.getTimeStr()) + ", " + (leb_1) + ", " + (leb_2)
+ ", " + (leb_3) + ", " + (leb_4) + ", ";
////////Zapisz do pliku i wyślij wyniki procesu zapisu
mójPlik = SD.open(perv, FILE_WRITE); // jeśli nie ma pliku o nazwie „2.txt”, zostanie on utworzony.
jeśli (mój plik) {
mójPlik.println(ciąg danych);
mójPlik.close();
tft.fillRect(198, 8, 42, 10, ZIELONY);
tft.println("SD OK");
Serial.println("SD OK");
opóźnienie (900); // opóźnij, w przeciwnym razie zarejestruje 13 identycznych odczytów, aż upłynie sekunda
} Else {
tft.fillRect(198, 8, 42, 10, CZERWONY);
tft.println("BŁĄD SD");
Serial.println("BŁĄD SD");
}
}
}Program do konwersji znaków/* Przekoduj rosyjskie czcionki z UTF-8 na Windows-1251 */

String utf8rus (źródło ciągu)
{
int i,k;
Cel ciągu;
znak bez znaku n;
znak m[2] = { '0', ' ' };

k = źródło.długość(); ja = 0;

podczas gdy (i < k) {
n = źródło[i]; ja++;

jeśli (n >= 0xC0) {
przełącznik (n) {
przypadek 0xD0: {
n = źródło[i]; ja++;
jeśli (n == 0x81) { n = 0xA8; przerwa; }
jeśli (n >= 0x90 && n <= 0xBF) n = n + 0x30;//0x2F
break;
}
przypadek 0xD1: {
n = źródło[i]; ja++;
jeśli (n == 0x91) { n = 0xB8; przerwa; }
jeśli (n >= 0x80 && n <= 0x8F) n = n + 0x70;//0x6F
break;
}
}
}
m[0] = n; cel = cel + String(m);
}
cel powrotu;
} Program do transkodowania znaków w cyrylicy przy użyciu biblioteki Adafruit_GFX jest umieszczony w tym samym folderze co program główny. Musisz także zastąpić plik glcdfont.c w Adafruit_GFX inną czcionką. Tutaj bibliotekę z wymaganą zamianą. Więcej informacji na temat rusyfikacji można łatwo znaleźć w Internecie.
Podsumowując powiem, że system spełnił oczekiwania, łatwiej było monitorować czas pracy sprzętu. Mimo, że wszystko jest zmontowane na płytkach stykowych, nie ma od razu żadnych zastrzeżeń do pracy. Pierwsze elementy pracowały ponad pół roku i przetrwały zimę. Najnowszy projekt Od 9 marca działa już dla 5 kontrolowanych jednostek i przy jego pomocy oficjalnie rejestrowany jest czas pracy.

Źródło: www.habr.com

Dodaj komentarz