Hardware components | ||||||
| × | 1 |
Mini serial console is a simple serial console that can be used for data display and data input. It can handle three (different) serial interfaces at the same time: 3.3V TTL for single-board computers and microcontrollers, via traditional RS-232 and serial over USB. The console has four operation modes, the first three for display only can be used, these are pre-programmed, the fourth is reserved for unique solutions.
See original project page for detailed information about Mini serial console.
II. My first applicationThe first application of the console is a multifunctional display on the control unit of our mini farm.
1. Differences from the standard versiona. Difference in modes of operation
b. Difference in button functions
c. Difference in Incoming data
d. Difference in operation
At start-up, the program initializes serial ports and if consol messages is enabled sends status message. After that, it sets the GPIO ports, clears the virtual screen and initializes the display. Sets its own operating mode according to the jumpers (JP2-3). (Note: only MODE #3 is used in this application.) The display shows brief information about the device.
The program then continuously monitors all serial ports, the state of the buttons, and the state of the mode selection jumpers. If data is received on one of the ports, the software decides on the type of incoming data. If it is a plain text log file record, it stores it on the virtual screen. If it is a binary channel data, it is stored in the state and override buffer.
In MODE #3/0, the software creates the current page from the stored status data, in MODE #3/1 from the stored override data. In MODE #3/2 the LCD display shows a part of the virtual screen as a 'window'.
The program turns off the backlight after 60 s of inactivity, then turns it back on when data is received or a button is pressed.
e. Difference in operation check
Testing the display is easily done with mm8d-msctest.py, which is included with MM8D starting from version 0.4.
The equipment was placed on the front of the central control cabinet (ESz-1).
Communication with the control computers takes place via a serial connection. The main computer (Raspberry Pi 2 B+) is connected via a 3.3V TTL serial connection, the spare computer (Compaq PC) via a traditional RS-232 port. It receives the power supply from the common 5V DC power supply of the cabinet.
At start-up, brief information about the device appears on the display: software version, transmission speed of the communication ports and the selected operating mode. This disappears after 3 seconds and the status of channel CH #0 is displayed. You can scroll between the channels (0-8) with the up and down arrows. The sign of the usable arrow buttons can also be seen on the display. By pressing the F1 key, we can see the CH #0 channel override status. You can scroll between the channels with the up and down arrows. By pressing the F1 key, we can see the log. This log contains the same content as the MM8D debug log file when the MM8D debug mode is on. (Attention! You don't need to turn on this mode for display only.) The display is a 'window' above the 80x25 character size virtual screen, which can be moved anywhere with the arrows. After the 80th incoming log entry, the text automatically scrolls up, the content of the first line is lost. Automatic scrolling of the log screen can be locked with the F2 button. By pressing the F1 key, we can see the status of a channel again.
Note: The number of status and override pages and the position of the log are preserved, after switching we will be where we were last.
// +---------------------------------------------------------------------------+
// | Mini serial console for MM8D * v0.1 |
// | Copyright (C) 2022 Pozsár Zsolt <pozsarzs@gmail.com> |
// | mini_serial_console-mm8d.ino |
// | Program for Raspberry Pi Pico |
// +---------------------------------------------------------------------------+
/*
This program is free software: you can redistribute it and/or modify it
under the terms of the European Union Public License 1.2 version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.
*/
/*
Operation modes
~~~~~~~~~~~~~~~
Mode #0: read only mode,
no cursor,
20x4 size displayed area on 80x4 size virtual screen,
automatically scrolling lines,
the displayed area can be moved horizontally with pushbuttons.
Mode #1: read only mode,
no cursor,
20x4 size displayed area on 80x25* size virtual screen,
automatically scrolling lines,
the displayed area can be moved horizontally and vertically with pushbuttons.
Mode #2: read only mode,
no cursor,
20x4 size displayed area on 80x25* size virtual screen,
the displayed area can be moved horizontally and vertically with pushbuttons,
after FormFeed (0x12), a new, clean page starts.
Mode #3/0: read only mode,
no cursor,
20x4 size displayed area on 80x25* size virtual screen,
the displayed page can be change with pushbuttons,
switch to other submode with PB4 button.
Mode #3/1: read only mode,
no cursor,
20x4 size displayed area on 80x25* size virtual screen,
the displayed page can be change with pushbuttons,
switch to other submode with PB4 button.
Mode #3/2: read only mode,
no cursor,
20x4 size displayed area on 80x25* size virtual screen,
automatically scrolling lines,
the displayed area can be moved horizontally and vertically with
pushbuttons,
switch to other submode with PB4 button,
lock scroll with PB5 button.
Note:
'*': You can set size of the virtual screen with virtscreenxsize and
virtscreenysize constants in operation mode #1 and #2.
Button functions
~~~~~~~~~~~~~~~~
Button Mode #0 Mode #1 Mode #2 Mode #3/0 Mode #3/1 Mode #3/2
-------------------------------------------------------------------------------
PB0 move left move left move left move left
PB1 move right move right move right move right
PB2 move up move up page up page up scroll up
PB3 move down move down page down page down scroll down
PB4 submode submode submode
PB5 lock scroll
Serial ports
~~~~~~~~~~~~
Serial0: via USB port
Serial1: UART0 TTL 0/3.3V
Serial2: UART1 RS232 +/-12V
Example incoming (binary) data lines in Mode #3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0123456789ABC
"CH..........."
0: 'C' 0x43
1: 'H' 0x48
2: number of channel 0x00
3: overcurrent breaker error 0x00: closed 0x01: opened
4: water pump pressure error (no water) 0x00: good 0x01: bad
5: water pump pressure error (clogging) 0x00: good 0x01: bad
6: external temperature in °C (0x00-0x80)
7: status of water pump and tube #1 0x00: off 0x01: on 0x02: always off 0x03: always on
8: status of water pump and tube #2 0x00: off 0x01: on 0x02: always off 0x03: always on
9: status of water pump and tube #3 0x00: off 0x01: on 0x02: always off 0x03: always on
A-C: unused 0x00
0: 'C' 0x43
1: 'H' 0x48
2: number of channel 0x01-0x08
3: temperature in °C (0x00-0x80)
4: relative humidity (0x00-0x80)
5: relative unwanted gas concentrate (0x00-0x80)
6: operation mode 0x00: hyphae 0x01: mushr. 0x7F: disabled channel
7: manual mode 0x00: auto 0x01: manual
8: overcurrent breaker error 0x00: closed 0x01: opened
9: status of door (alarm) 0x00: closed 0x01: opened
A: status of lamp output 0x00: off 0x01: on 0x02: always off 0x03: always on
B: status of ventilator output 0x00: off 0x01: on 0x02: always off 0x03: always on
C: status of heater output 0x00: off 0x01: on 0x02: always off 0x03: always on
Example incoming (text) log lines in Mode #3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0 1 2 3
"221213 114421 I Configuration is loaded."
"221213 114427 W CH2: MM6D is not accessible."
"221213 114427 E ERROR #18: There is not enabled channel!"
0: date in yymmdd format
1: time in hhmmss format
2: level (information, warning, error)
3: short description
*/
#define LCD_8BIT // enable 8 bit mode of the LCD
#define COM_USB // enable Serial #0 port
#define COM_TTL // enable Serial #1 port
#define COM_RS232C // enable Serial #2 port
#define COM_USB_MESSAGES // enable console messages on Serial #0 port
// #define COM_TTL_MESSAGES // enable console messages on Serial #1 port
// #define COM_RS232C_MESSAGES // enable console messages on Serial #2 port
// #define TEST // enable test mode of scrolling
#define BEL 0x07 // ASCII code of the control characters
#define TAB 0x09
#define FF 0x0B
#define SPACE 0x20
#define DEL 0x7F
#include <LiquidCrystal.h>
// settings
const int lcd_bloffinterval = 60000; // LCD backlight off time after last button press
const byte lcd_xsize = 20; // horizontal size of display
const byte lcd_ysize = 4; // vertical size of display
const byte virtscreenxsize = 80; // horizontal size of virtual screen
const byte virtscreenysize = 25; // vertical size of virtual screen
// serial ports
const int com_speed[3] = {115200,
9600,
9600
}; // speed of the USB serial port
#ifdef ARDUINO_ARCH_MBED_RP2040
const byte com_rxd2 = 8;
const byte com_txd2 = 9;
#endif
// GPIO ports
const byte lcd_bl = 14; // LCD - backlight on/off
const byte lcd_db0 = 2; // LCD - databit 0
const byte lcd_db1 = 3; // LCD - databit 1
const byte lcd_db2 = 4; // LCD - databit 2
const byte lcd_db3 = 5; // LCD - databit 3
const byte lcd_db4 = 10; // LCD - databit 4
const byte lcd_db5 = 11; // LCD - databit 5
const byte lcd_db6 = 12; // LCD - databit 6
const byte lcd_db7 = 13; // LCD - databit 7
const byte lcd_en = 7; // LCD - enable
const byte lcd_rs = 6; // LCD - register select
const byte prt_jp2 = 16; // operation mode (JP2 jumper)
const byte prt_jp3 = 15; // operation mode (JP3 jumper)
const byte prt_pb0 = 17; // pushbutton 0
const byte prt_pb1 = 18; // pushbutton 1
const byte prt_pb2 = 19; // pushbutton 2
const byte prt_pb3 = 20; // pushbutton 3
const byte prt_pb4 = 21; // pushbutton 4
const byte prt_pb5 = 22; // pushbutton 5
const byte prt_led = LED_BUILTIN; // LED on the board of Pico
byte uparrow[8] = {B00100, // up arrow character for LCD
B01110,
B10101,
B00100,
B00100,
B00100,
B00100
};
byte downarrow[8] = {B00100, // down arrow character for LCD
B00100,
B00100,
B00100,
B10101,
B01110,
B00100
};
// general constants
const String swversion = "0.1"; // version of this program
const int btn_delay = 200; // time after read button status
// general variables
byte virtoverridepagenum = 0; // page num. for copy data (virtstatuspage->display)
byte virtstatuspage[9][10]; // virtual status pages
byte virtstatuspagenum = 0; // page num. for copy data (virtstatuspage->display)
char virtscreen[virtscreenxsize][virtscreenysize]; // virtual screen
byte virtscreenline = 0; // y pos. for copy data (rxdbuffer->virtscreen)
byte virtscreenxpos = 0; // x pos. for copy data (virtscreen->display)
byte virtscreenypos = 0; // y pos. for copy data (virtscreen->display)
byte virtscreenscrolllock = 0; // lock autoscroll of the log
byte operationmode; // operation mode of device
byte operationsubmode = 0; // sub operation mode of device in mode #3
unsigned long currenttime; // current time
unsigned long previoustime = 0; // last time of receiving or button pressing
// messages
String msg[28] = {" MM8D console", // 00
"--------------------", // 01
"sw.: v", // 02
"(C)2022 Pozsar Zsolt", // 03
"Initializing...", // 04
" * GPIO ports", // 05
" * LCD", // 06
" * Serial ports:", // 07
"operation mode: #", // 08
"Read a line from serial port #", // 09
"Button pressed: PB", // 10
"Change to status pages", // 11
"Change to override pages", // 12
"Change to log page", // 13
"Lock autoscroll of log page", // 14
"STATUS", // 15
"val", // 16
"in", // 17
"out", // 18
"disabled channel", // 19
"OVERRIDE", // 20
"tube #", // 21
"neutral", // 22
" off", // 23
" on", // 24
"lamp: ", // 25
"ventilator:", // 26
"heater: " // 27
};
#ifdef ARDUINO_ARCH_MBED_RP2040
UART Serial2(com_rxd2, com_txd2, NC, NC);
#endif
#ifdef LCD_8BIT
LiquidCrystal lcd(lcd_rs, lcd_en, lcd_db0, lcd_db1, lcd_db2, lcd_db3, lcd_db4, lcd_db5, lcd_db6, lcd_db7);
#else
LiquidCrystal lcd(lcd_rs, lcd_en, lcd_db4, lcd_db5, lcd_db6, lcd_db7);
#endif
void com_writetoconsole(String message) {
#ifdef COM_USB_MESSAGES
Serial.println(message);
#endif
#ifdef COM_TTL_MESSAGES
Serial1.println(message);
#endif
#ifdef COM_RS232C_MESSAGES
Serial2.println(message);
#endif
}
// LCD - turn on/off background light
void lcd_backlight(byte opmode) {
switch (opmode) {
case 0:
digitalWrite(lcd_bl, LOW);
break;
case 1:
digitalWrite(lcd_bl, HIGH);
break;
case 2:
previoustime = millis();
break;
case 3:
currenttime = millis();
if (currenttime - previoustime >= lcd_bloffinterval) {
digitalWrite(lcd_bl, LOW);
} else {
digitalWrite(lcd_bl, HIGH);
}
break;
}
}
// copy selected virtual status page to LCD
void copyvirtstatuspage2lcd(byte page) {
if (page == 0) {
/*
+--------------------+
|CH #0 [ ] STATUS|
|val T:00°C |
|in BE:0 LP:0 HP:0|
|out T1:0 T2:0 T3:0|
+--------------------+
*/
lcd.clear();
lcd.setCursor(0, 0); lcd.print("CH #" + String(page));
lcd.setCursor(7, 0); lcd.print("[ ]");
lcd.setCursor(8, 0); lcd.write(byte(0));
lcd.setCursor(lcd_xsize - msg[15].length(), 0); lcd.print(msg[15]);
lcd.setCursor(0, 1); lcd.print(msg[16]);
lcd.setCursor(0, 2); lcd.print(msg[17]);
lcd.setCursor(0, 3); lcd.print(msg[18]);
lcd.setCursor(lcd_xsize - 14, 1);
lcd.print("T:" + String(virtstatuspage[page][3]) + char(0xDF) + "C");
lcd.setCursor(lcd_xsize - 14, 2);
lcd.print("BE:" + String(virtstatuspage[page][0]) + " " +
+"LP:" + String(virtstatuspage[page][1]) + " " +
+"HP:" + String(virtstatuspage[page][2]));
byte tube[3];
for (byte b = 4; b < 7; b++) {
tube[b - 4] = virtstatuspage[page][b];
switch (virtstatuspage[page][b]) {
case 0x02: tube[b - 4] = 0x00;
break;
case 0x03: tube[b - 4] = 0x01;
break;
}
}
lcd.setCursor(lcd_xsize - 14, 3);
lcd.print("T1:" + String(tube[0]) + " " + "T2:" + String(tube[1]) + " " + "T3:" + String(tube[2]));
} else {
if (virtstatuspage[page][3] == 0x7F) {
/*
+--------------------+
|CH #3 [ ] STATUS|
| |
| disabled channel |
| |
+--------------------+
*/
lcd.clear();
lcd.setCursor(0, 0); lcd.print("CH #" + String(page));
lcd.setCursor(7, 0); lcd.print("[ ]");
if (page < 8) {
lcd.setCursor(8, 0); lcd.write(byte(0));
}
lcd.setCursor(9, 0); lcd.write(byte(1));
lcd.setCursor(lcd_xsize - msg[15].length(), 0); lcd.print(msg[15]);
lcd.setCursor(lcd_xsize / 2 - msg[19].length() / 2, 2); lcd.print(msg[19]);
} else {
/*
+--------------------+
|CH #1 [ ] STATUS|
|val T:00°C RH:100%|
|in OM:H CM:A BE:0|
|out LA:0 VE:0 HE:0|
+--------------------+
*/
lcd.clear();
lcd.setCursor(0, 0); lcd.print("CH #" + String(page));
lcd.setCursor(7, 0); lcd.print("[ ]");
if (page < 8) {
lcd.setCursor(8, 0); lcd.write(byte(0));
}
lcd.setCursor(9, 0); lcd.write(byte(1));
lcd.setCursor(lcd_xsize - msg[15].length(), 0); lcd.print(msg[15]);
lcd.setCursor(0, 1); lcd.print(msg[16]);
lcd.setCursor(0, 2); lcd.print(msg[17]);
lcd.setCursor(0, 3); lcd.print(msg[18]);
lcd.setCursor(lcd_xsize - 14, 1);
lcd.print("T:" + String(virtstatuspage[page][0]) + char(0xDF) + "C " +
+"RH:" + String(virtstatuspage[page][1]) + "%");
lcd.setCursor(lcd_xsize - 14, 2);
String OM;
String CM;
OM = "?";
CM = "?";
switch (virtstatuspage[page][3]) {
case 0x00:
OM = 'H';
break;
case 0x01:
OM = 'M';
break;
case 0x7F:
OM = 'D';
break;
}
switch (virtstatuspage[page][4]) {
case 0x00:
CM = 'A';
break;
case 0x01:
CM = 'M';
break;
}
lcd.print("OM:" + OM + " " + "CM:" + CM + " " + "BE:" + String(virtstatuspage[page][5]));
byte out[3];
for (byte b = 7; b < 10; b++) {
out[b - 7] = virtstatuspage[page][b];
switch (virtstatuspage[page][b]) {
case 0x02: out[b - 7] = 0x00;
break;
case 0x03: out[b - 7] = 0x01;
break;
}
}
lcd.setCursor(lcd_xsize - 14, 3);
lcd.print("LA:" + String(out[0]) + " " + "VE:" + String(out[1]) + " " + "HE:" + String(out[2]));
}
}
}
// clear virtual status pages
void clearvirtstatuspage() {
for (byte y = 0; y <= 9; y++) {
for (byte x = 0; x <= 8; x++) {
virtstatuspage[x][y] = 0;
}
}
}
// copy selected virtual override page to LCD
void copyvirtoverridepage2lcd(byte page) {
if (page == 0) {
/*
+--------------------+
|CH #0 [ ] OVERRIDE|
|tube #1: neutral|
|tube #2: neutral|
|tube #3: neutral|
+--------------------+
*/
lcd.clear();
lcd.setCursor(0, 0); lcd.print("CH #" + String(page));
lcd.setCursor(7, 0); lcd.print("[ ]");
lcd.setCursor(8, 0); lcd.write(byte(0));
lcd.setCursor(lcd_xsize - msg[20].length(), 0); lcd.print(msg[20]);
for (byte b = 1; b < 4; b++) {
lcd.setCursor(0, b); lcd.print(msg[21] + String(b) + ":");
lcd.setCursor(lcd_xsize - msg[22].length(), b);
switch (virtstatuspage[page][b + 3]) {
case 0x00: lcd.print(msg[22]);
break;
case 0x01: lcd.print(msg[22]);
break;
case 0x02: lcd.print(msg[23]);
break;
case 0x03: lcd.print(msg[24]);
break;
}
}
} else {
/*
+--------------------+
|CH #1 OVERRIDE|
|lamp: on|
|ventilator: neutral|
|heater: off|
+--------------------+
*/
lcd.clear();
lcd.setCursor(0, 0); lcd.print("CH #" + String(page));
lcd.setCursor(7, 0); lcd.print("[ ]");
if (page < 8) {
lcd.setCursor(8, 0); lcd.write(byte(0));
}
lcd.setCursor(9, 0); lcd.write(byte(1));
lcd.setCursor(lcd_xsize - msg[20].length(), 0); lcd.print(msg[20]);
for (byte b = 1; b < 4; b++) {
lcd.setCursor(0, b); lcd.print(msg[24 + b]);
lcd.setCursor(lcd_xsize - msg[22].length(), b);
switch (virtstatuspage[page][b + 6]) {
case 0x00: lcd.print(msg[22]);
break;
case 0x01: lcd.print(msg[22]);
break;
case 0x02: lcd.print(msg[23]);
break;
case 0x03: lcd.print(msg[24]);
break;
}
}
}
}
// scroll up one line on virtual screen (log page in Mode #3)
void scroll(byte lastline) {
if (virtscreenscrolllock == 0 ) {
for (byte y = 1; y <= lastline; y++) {
for (byte x = 0; x <= virtscreenxsize - 1; x++) {
virtscreen[x][y - 1] = virtscreen[x][y];
if (y == lastline) {
virtscreen[x][y] = SPACE;
}
}
}
}
}
// copy text from virtual screen (log page in Mode #3) to LCD
void copyvirtscreen2lcd(byte x, byte y) {
for (byte dy = 0; dy <= lcd_ysize - 1; dy++) {
for (byte dx = 0; dx <= lcd_xsize - 1; dx++) {
lcd.setCursor(dx, dy);
lcd.write(virtscreen[x + dx][y + dy]);
}
}
}
// clear virtual screen (log page in Mode #3)
void clearvirtscreen() {
for (byte y = 0; y <= virtscreenysize - 1; y++) {
for (byte x = 0; x <= virtscreenxsize - 1; x++) {
virtscreen[x][y] = SPACE;
}
}
}
// read communication port and move data to virtual screen
byte com_handler(byte port) {
const byte rxdbuffersize = 255;
boolean newpage = false;
byte lastline;
char rxdbuffer[rxdbuffersize];
int rxdlength = 0;
// read port and write to receive buffer
switch (port) {
case 0:
if (Serial.available()) {
digitalWrite(prt_led, HIGH);
rxdlength = Serial.readBytes(rxdbuffer, rxdbuffersize);
com_writetoconsole(msg[9] + String(port));
digitalWrite(prt_led, LOW);
// lcd_backlight(2);
}
break;
case 1:
if (Serial1.available()) {
digitalWrite(prt_led, HIGH);
rxdlength = Serial1.readBytes(rxdbuffer, rxdbuffersize);
com_writetoconsole(msg[9] + String(port));
digitalWrite(prt_led, LOW);
// lcd_backlight(2);
}
break;
case 2:
if (Serial2.available()) {
digitalWrite(prt_led, HIGH);
rxdlength = Serial2.readBytes(rxdbuffer, rxdbuffersize);
com_writetoconsole(msg[9] + String(port));
digitalWrite(prt_led, LOW);
// lcd_backlight(2);
}
break;
}
lcd_backlight(3);
// check datalenght
if (rxdlength > virtscreenxsize) {
rxdlength = virtscreenxsize;
}
// copy line from receive buffer to virtual screen
if (rxdlength) {
switch (operationmode) {
// in Mode #0
case 0:
lastline = 3;
if (virtscreenline == lastline + 1) {
scroll(lastline);
virtscreenline = lastline;
}
for (byte b = 0; b < rxdlength; b++) {
if (rxdbuffer[b] == BEL) {
lcd_backlight(0);
delay(250);
lcd_backlight(1);
delay(250);
lcd_backlight(0);
delay(250);
lcd_backlight(1);
delay(250);
lcd_backlight(0);
delay(250);
lcd_backlight(1);
}
if (rxdbuffer[b] == TAB) {
rxdbuffer[b] = SPACE;
}
if ((rxdbuffer[b] >= SPACE) and (rxdbuffer[b] < DEL)) {
virtscreen[b][virtscreenline] = rxdbuffer[b];
}
}
virtscreenline++;
copyvirtscreen2lcd(virtscreenxpos, 0);
break;
// in Mode #1
case 1:
lastline = virtscreenysize - 1;
if (virtscreenline == lastline + 1) {
scroll(lastline);
virtscreenline = lastline;
}
for (byte b = 0; b < rxdlength; b++) {
if (rxdbuffer[b] == BEL) {
lcd_backlight(0);
delay(250);
lcd_backlight(1);
delay(250);
lcd_backlight(0);
delay(250);
lcd_backlight(1);
delay(250);
lcd_backlight(0);
delay(250);
lcd_backlight(1);
}
if (rxdbuffer[b] == TAB) {
rxdbuffer[b] = SPACE;
}
if ((rxdbuffer[b] >= SPACE) and (rxdbuffer[b] < DEL)) {
virtscreen[b][virtscreenline] = rxdbuffer[b];
}
}
virtscreenline++;
copyvirtscreen2lcd(virtscreenxpos, virtscreenypos);
break;
// in Mode #2
case 2:
lastline = virtscreenysize - 1;
if (virtscreenline == lastline + 1) {
virtscreenline = 0;
}
for (byte b = 0; b < rxdlength; b++) {
if (rxdbuffer[b] == BEL) {
lcd_backlight(0);
delay(250);
lcd_backlight(1);
delay(250);
lcd_backlight(0);
delay(250);
lcd_backlight(1);
delay(250);
lcd_backlight(0);
delay(250);
lcd_backlight(1);
}
if (rxdbuffer[b] == TAB) {
rxdbuffer[b] == SPACE;
}
if (rxdbuffer[b] == FF) {
newpage = true;
}
if ((rxdbuffer[b] >= SPACE) and (rxdbuffer[b] < DEL)) {
virtscreen[b][virtscreenline] = rxdbuffer[b];
}
}
if (newpage) {
clearvirtscreen();
virtscreenline = 0;
newpage = false;
} else {
virtscreenline++;
}
copyvirtscreen2lcd(virtscreenxpos, virtscreenypos);
break;
case 3:
// in Mode #3
if ((rxdbuffer[0] == 0x43) and (rxdbuffer[1] == 0x48)) // "CH"
{
for (byte b = 3; b < 13; b++) {
virtstatuspage[rxdbuffer[2]][b - 3] = rxdbuffer[b];
}
if (operationsubmode < 2) {
switch (operationsubmode) {
case 0:
copyvirtstatuspage2lcd(virtstatuspagenum);
break;
case 1:
copyvirtoverridepage2lcd(virtoverridepagenum);
break;
}
}
} else
{
// if the received line is log
lastline = virtscreenysize - 1;
if (virtscreenline == lastline + 1) {
scroll(lastline);
virtscreenline = lastline;
}
for (byte b = 0; b < rxdlength; b++) {
if (rxdbuffer[b] == BEL) {
lcd_backlight(0);
delay(250);
lcd_backlight(1);
delay(250);
lcd_backlight(0);
delay(250);
lcd_backlight(1);
delay(250);
lcd_backlight(0);
delay(250);
lcd_backlight(1);
}
if (rxdbuffer[b] == TAB) {
rxdbuffer[b] = SPACE;
}
if ((rxdbuffer[b] >= SPACE) and (rxdbuffer[b] < DEL)) {
virtscreen[b][virtscreenline] = rxdbuffer[b];
}
}
virtscreenline++;
if (operationsubmode == 2) {
copyvirtscreen2lcd(virtscreenxpos, virtscreenypos);
}
}
break;
}
}
return rxdlength;
}
// read status of pushbuttons and write text to LCD
void btn_handler(byte m, byte sm) {
// horizontal move
if ((m >= 0) and (m < 3)) {
// [LEFT] button in Mode #0, #1 and #2
if (not digitalRead(prt_pb0)) {
com_writetoconsole(msg[10] + "0");
delay(btn_delay);
lcd_backlight(2);
// move lines
if (virtscreenxpos > 0) {
virtscreenxpos--;
copyvirtscreen2lcd(virtscreenxpos, virtscreenypos);
}
}
// [RIGHT] button in Mode #0, #1 and #2
if (not digitalRead(prt_pb1)) {
com_writetoconsole(msg[10] + "1");
delay(btn_delay);
lcd_backlight(2);
// move lines
if (virtscreenxpos + lcd_xsize < virtscreenxsize) {
virtscreenxpos++;
copyvirtscreen2lcd(virtscreenxpos, virtscreenypos);
}
}
}
if (m == 3) {
// [LEFT] button in Mode #3
if (not digitalRead(prt_pb0)) {
com_writetoconsole(msg[10] + "0");
delay(btn_delay);
lcd_backlight(2);
switch (sm) {
case 0:
// SubMode #0: nothing
break;
case 1:
// SubMode #1: nothing
break;
case 2:
// SubMode #2: move lines
if (virtscreenxpos > 0) {
virtscreenxpos--;
copyvirtscreen2lcd(virtscreenxpos, virtscreenypos);
}
break;
}
}
// [RIGHT] button in Mode #3
if (not digitalRead(prt_pb1)) {
com_writetoconsole(msg[10] + "1");
delay(btn_delay);
lcd_backlight(2);
switch (sm) {
case 0:
// SubMode #0: nothing
break;
case 1:
// SubMode #1: nothing
break;
case 2:
// SubMode #2: move lines
if (virtscreenxpos + lcd_xsize < virtscreenxsize) {
virtscreenxpos++;
copyvirtscreen2lcd(virtscreenxpos, virtscreenypos);
}
break;
}
}
}
// vertical move
if ((m > 0) and (m < 3)) {
// [UP] button in Mode #0, #1 and #2
if (not digitalRead(prt_pb2)) {
com_writetoconsole(msg[10] + "2");
delay(btn_delay);
lcd_backlight(2);
// scroll lines
if (virtscreenypos > 0) {
virtscreenypos--;
copyvirtscreen2lcd(virtscreenxpos, virtscreenypos);
}
}
// [DOWN] button in Mode #0, #1 and #2
if (not digitalRead(prt_pb3)) {
com_writetoconsole(msg[10] + "3");
delay(btn_delay);
lcd_backlight(2);
// scroll lines
if (virtscreenypos + lcd_ysize < virtscreenysize) {
virtscreenypos++;
copyvirtscreen2lcd(virtscreenxpos, virtscreenypos);
}
}
}
if (m == 3) {
// [UP] button in Mode #3
if (not digitalRead(prt_pb2)) {
com_writetoconsole(msg[10] + "2");
delay(btn_delay);
lcd_backlight(2);
switch (sm) {
case 0:
// SubMode #0: change page
if (virtstatuspagenum > 0) {
virtstatuspagenum--;
copyvirtstatuspage2lcd(virtstatuspagenum);
}
break;
case 1:
// SubMode #1: change page
if (virtoverridepagenum > 0) {
virtoverridepagenum--;
copyvirtoverridepage2lcd(virtoverridepagenum);
}
break;
case 2:
// SubMode #2: scroll lines
if (virtscreenypos > 0) {
virtscreenypos--;
copyvirtscreen2lcd(virtscreenxpos, virtscreenypos);
}
break;
}
}
// [DOWN] button in Mode #0, #1 and #2
if (not digitalRead(prt_pb3)) {
com_writetoconsole(msg[10] + "3");
delay(btn_delay);
lcd_backlight(2);
switch (sm) {
case 0:
// SubMode #0: change page
if (virtstatuspagenum < 8) {
virtstatuspagenum++;
copyvirtstatuspage2lcd(virtstatuspagenum);
}
break;
case 1:
// SubMode #1: change page
if (virtoverridepagenum < 8) {
virtoverridepagenum++;
copyvirtoverridepage2lcd(virtoverridepagenum);
}
break;
case 2:
// SubMode #2: scroll lines
if (virtscreenypos + lcd_ysize < virtscreenysize) {
virtscreenypos++;
copyvirtscreen2lcd(virtscreenxpos, virtscreenypos);
}
break;
}
}
}
// function buttons
if (m == 3) {
// [F1] button in Mode #3
if (not digitalRead(prt_pb4)) {
com_writetoconsole(msg[10] + "4");
delay(btn_delay);
lcd_backlight(2);
// change SubMode and view actual page
if (operationsubmode < 2) {
operationsubmode++;
} else {
operationsubmode = 0;
}
lcd.clear();
switch (operationsubmode) {
case 0:
copyvirtstatuspage2lcd(virtstatuspagenum);
com_writetoconsole(msg[11]);
break;
case 1:
copyvirtoverridepage2lcd(virtoverridepagenum);
com_writetoconsole(msg[12]);
break;
case 2:
virtscreenscrolllock = 0;
copyvirtscreen2lcd(virtscreenxpos, virtscreenypos);
com_writetoconsole(msg[13]);
break;
}
}
// [F2] button in Mode #3
if (not digitalRead(prt_pb5)) {
com_writetoconsole(msg[10] + "5");
delay(btn_delay);
lcd_backlight(2);
// SubMode #2: lock autoscroll of the log
if (operationsubmode == 2) {
virtscreenscrolllock = not virtscreenscrolllock;
}
if (virtscreenscrolllock == 1) {
com_writetoconsole(msg[14]);
}
}
}
}
// get operation mode of device
byte getmode() {
delay(250);
return ((not digitalRead(prt_jp3)) * 2 + (not digitalRead(prt_jp2)));
}
// * * * MAIN FUNCTION * * *
// initializing
void setup() {
String s;
delay(3000);
// serial ports
Serial.begin(com_speed[0]);
Serial1.begin(com_speed[1]);
Serial2.begin(com_speed[2]);
// write program information to console
for (int b = 0; b <= 4; b++) {
if (b == 2) {
com_writetoconsole(msg[b] + swversion);
} else {
com_writetoconsole(msg[b]);
}
}
// initializing I/O devices
// GPIO ports
com_writetoconsole(msg[5]);
pinMode(lcd_bl, OUTPUT);
pinMode(lcd_db0, OUTPUT);
pinMode(lcd_db1, OUTPUT);
pinMode(lcd_db2, OUTPUT);
pinMode(lcd_db3, OUTPUT);
pinMode(lcd_db4, OUTPUT);
pinMode(lcd_db5, OUTPUT);
pinMode(lcd_db6, OUTPUT);
pinMode(lcd_db7, OUTPUT);
pinMode(lcd_en, OUTPUT);
pinMode(lcd_rs, OUTPUT);
pinMode(prt_jp2, INPUT);
pinMode(prt_jp3, INPUT);
pinMode(prt_led, OUTPUT);
pinMode(prt_pb0, INPUT);
pinMode(prt_pb1, INPUT);
pinMode(prt_pb2, INPUT);
pinMode(prt_pb3, INPUT);
pinMode(prt_pb4, INPUT);
pinMode(prt_pb5, INPUT);
// display
com_writetoconsole(msg[6]);
lcd.createChar(0, uparrow);
lcd.createChar(1, downarrow);
lcd.begin(lcd_xsize, lcd_ysize);
lcd_backlight(1);
lcd_backlight(2);
// write program information to display
for (int b = 0; b <= 3; b++) {
lcd.setCursor(0, b);
if (b == 2) {
lcd.print(msg[b] + swversion);
} else {
lcd.print(msg[b]);
}
}
delay(3000);
lcd.clear();
com_writetoconsole(msg[7]);
for (int b = 0; b <= 2; b++) {
s = "#" + String(b) + ": " + String(com_speed[b]) + " baud";
com_writetoconsole(" " + s);
lcd.setCursor(0, b); lcd.print(s);
}
// get operation mode
operationmode = getmode();
s = msg[8] + String(operationmode);
com_writetoconsole(" * " + s);
lcd.setCursor(0, 3); lcd.print(s);
delay(3000);
lcd.clear();
// clean of fill data virtual screen and copy LCD
#ifdef TEST
char ch = 33;
...
This file has been truncated, please download it to see its full contents.
#!/usr/bin/python3
# +----------------------------------------------------------------------------+
# | MM8D v0.4 * Growing house and irrigation controlling and monitoring system |
# | Copyright (C) 2020-2022 Pozsar Zsolt <pozsar.zsolt@szerafingomba.hu> |
# | mm8d-msctest.py |
# | Mini serial console test program |
# +----------------------------------------------------------------------------+
# This program is free software: you can redistribute it and/or modify it
# under the terms of the European Union Public License 1.1 version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.
# Exit codes:
# 0: normal exit
# 1: cannot open configuration file
import configparser
import io
import os
import serial
import sys
import time
from time import localtime, strftime
USRLOCALDIR = 1
if (USRLOCALDIR == 1):
conffile = '/usr/local/etc/mm8d/mm8d.ini'
else:
conffile = '/etc/mm8d/mm8d.ini'
# write a debug log line to serial port
def writedebuglogtocomport(level,text):
if com_enable == "1":
dt = (strftime("%y%m%d %H%M%S",localtime()))
try:
com.open
com.write(str.encode(dt + ' ' + str.upper(level) + ' ' + text + eol))
com.close
except:
print("")
# send channels' data to display via serial port
def writechannelstatustocomport(channel):
transmitbuffer = [0x00 for x in range(13)]
line = ""
if com_enable == "1":
if channel == 0:
transmitbuffer[0x00] = ord("C")
transmitbuffer[0x01] = ord("H")
transmitbuffer[0x02] = channel
transmitbuffer[0x03] = mainsbreakers
transmitbuffer[0x04] = waterpressurelow
transmitbuffer[0x05] = waterpressurehigh
transmitbuffer[0x06] = exttemp
transmitbuffer[0x07] = relay_tube1
transmitbuffer[0x08] = relay_tube2
transmitbuffer[0x09] = relay_tube3
transmitbuffer[0x0A] = 0x00
transmitbuffer[0x0B] = 0x00
transmitbuffer[0x0C] = 0x00
if override[channel][0] == 2:
transmitbuffer[0x07] = 0x03
if override[channel][0] == 1:
transmitbuffer[0x07] = 0x02
if override[channel][1] == 2:
transmitbuffer[0x08] = 0x03
if override[channel][1] == 1:
transmitbuffer[0x08] = 0x02
if override[channel][2] == 2:
transmitbuffer[0x09] = 0x03
if override[channel][2] == 1:
transmitbuffer[0x09] = 0x02
else:
transmitbuffer[0x00] = ord("C")
transmitbuffer[0x01] = ord("H")
transmitbuffer[0x02] = channel
transmitbuffer[0x03] = in_temperature[channel]
transmitbuffer[0x04] = in_humidity[channel]
transmitbuffer[0x05] = in_gasconcentrate[channel]
transmitbuffer[0x06] = in_opmode[channel]
transmitbuffer[0x07] = in_swmanu[channel]
transmitbuffer[0x08] = in_ocprot[channel]
transmitbuffer[0x09] = in_alarm[channel]
transmitbuffer[0x0A] = out_lamps[channel]
transmitbuffer[0x0B] = out_vents[channel]
transmitbuffer[0x0C] = out_heaters[channel]
if override[channel][0] == 2:
transmitbuffer[0x0A] = 0x03
if override[channel][0] == 1:
transmitbuffer[0x0A] = 0x02
if override[channel][1] == 2:
transmitbuffer[0x0B] = 0x03
if override[channel][1] == 1:
transmitbuffer[0x0B] = 0x02
if override[channel][2] == 2:
transmitbuffer[0x0C] = 0x03
if override[channel][2] == 1:
transmitbuffer[0x0C] = 0x02
for x in range(0,13):
line = line + chr(transmitbuffer[x])
try:
com.open
com.write(str.encode(line))
com.close
except:
print("")
# load configuration
def loadconfiguration(conffile):
global com
global com_device
global com_speed
global com_enable
com_enable = "1"
try:
with open(conffile) as f:
mm8d_config=f.read()
config=configparser.RawConfigParser(allow_no_value=True)
config.read_file(io.StringIO(mm8d_config))
com_device=config.get('COMport','com_device')
com_speed=int(config.get('COMport','com_speed'))
except:
print("ERROR #1: Cannot open configuration file!");
sys.exit(1);
# main function
global channel
global ena_ch
global eol
global exttemp
global in_alarm
global in_gasconcentrate
global in_humidity
global in_ocprot
global in_opmode
global in_swmanu
global in_temperature
global mainsbreakers
global out_heaters
global out_lamps
global out_vents
global override
global ovrstatus
global relay_tube1
global relay_tube2
global relay_tube3
global waterpressurehigh
global waterpressurelow
channel = 0
ena_ch = [1 for channel in range(9)]
eol = "\r"
exttemp = 23
in_alarm = [0 for channel in range(9)]
in_gasconcentrate = [3 for channel in range(9)]
in_humidity = [75 for channel in range(9)]
in_ocprot = [0 for channel in range(9)]
in_opmode = [0 for channel in range(9)]
in_swmanu = [0 for channel in range(9)]
in_temperature = [18 for channel in range(9)]
mainsbreakers = 0
out_heaters = [0 for channel in range(9)]
out_lamps = [0 for channel in range(9)]
out_vents = [0 for channel in range(9)]
override = [[0 for x in range(3)] for x in range(9)]
ovrstatus = ["neutral","off","on"]
relay_tube1 = 0
relay_tube2 = 0
relay_tube3 = 0
waterpressurehigh = 0
waterpressurelow = 0
print("\nMM8D Mini serial console test utility * (C) 2020-2022 Pozsar Zsolt")
print("--------------------------------------------------------------------")
print(" * load configuration: %s..." % conffile)
loadconfiguration(conffile)
print(" * setting ports...")
com = serial.Serial(com_device, com_speed)
while True:
print(" * What do you like?")
menuitem = input(" \
1: Set parameters of the Channel #0\n \
2: Set parameters of the Channel #1-8\n \
q: Quit\n")
if menuitem is "Q" or menuitem is "q":
break;
if menuitem is "1":
channel = 0
while True:
print(" * Set variables of the Channel #0")
print(" channel ",channel)
print(" 1: mainsbreakers ",mainsbreakers)
print(" 2: waterpressurelow ",waterpressurelow)
print(" 3: waterpressurehigh ",waterpressurehigh)
print(" 4: exttemp ",exttemp)
print(" 5: relay_tube1 ",relay_tube1)
print(" 6: relay_tube2 ",relay_tube2)
print(" 7: relay_tube3 ",relay_tube3)
print(" 8: override[" + str(channel) + "][0] ",ovrstatus[override[channel][0]])
print(" 9: override[" + str(channel) + "][1] ",ovrstatus[override[channel][1]])
print(" a: override[" + str(channel) + "][2] ",ovrstatus[override[channel][2]] + "\n")
print(" Enable/disable CH #" + str(channel) + " ",ena_ch[channel])
print(" x: Send data")
print(" q: Back to main menu")
submenuitem = input()
if submenuitem is "1":
mainsbreakers = int(not mainsbreakers)
if mainsbreakers == 1:
writedebuglogtocomport("e","Overcurrent breaker is opened!")
if submenuitem is "2":
waterpressurelow = int(not waterpressurelow)
if waterpressurelow == 1:
writedebuglogtocomport("e","Pressure is too low after water pump!")
if submenuitem is "3":
waterpressurehigh = int(not waterpressurehigh)
if waterpressurehigh == 1:
writedebuglogtocomport("e","Pressure is too high after water pump!")
if submenuitem is "4":
exttemp = int(input("Enter new value (0-100): "))
writedebuglogtocomport("i","External temperature: " + str(exttemp) + " degree Celsius")
if submenuitem is "5":
relay_tube1 = int(not relay_tube1)
if relay_tube1 == 1:
writedebuglogtocomport("i","CH0: Output water pump and valve #1 ON")
else:
writedebuglogtocomport("i","CH0: Output water pump and valve #1 OFF")
if submenuitem is "6":
relay_tube2 = int(not relay_tube2)
if relay_tube2 == 1:
writedebuglogtocomport("i","CH0: Output water pump and valve #2 ON")
else:
writedebuglogtocomport("i","CH0: Output water pump and valve #2 OFF")
if submenuitem is "7":
relay_tube3 = int(not relay_tube3)
if relay_tube3 == 1:
writedebuglogtocomport("i","CH0: Output water pump and valve #3 ON")
else:
writedebuglogtocomport("i","CH0: Output water pump and valve #3 OFF")
if submenuitem is "8":
override[channel][0] = override[channel][0] + 1
if override[channel][0] == 3:
override[channel][0] = 0
if override[channel][0] == 2:
writedebuglogtocomport("i","CH0: -> water pump and valve #1 ON")
if override[channel][0] == 1:
writedebuglogtocomport("i","CH0: -> water pump and valve #1 OFF")
if submenuitem is "9":
override[channel][1] = override[channel][1] + 1
if override[channel][1] == 3:
override[channel][1] = 0
if override[channel][1] == 2:
writedebuglogtocomport("i","CH0: -> water pump and valve #2 ON")
if override[channel][1] == 1:
writedebuglogtocomport("i","CH0: -> water pump and valve #2 OFF")
if submenuitem is "a":
override[channel][2] = override[channel][2] + 1
if override[channel][2] == 3:
override[channel][2] = 0
if override[channel][2] == 2:
writedebuglogtocomport("i","CH0: -> water pump and valve #3 ON")
if override[channel][2] == 1:
writedebuglogtocomport("i","CH0: -> water pump and valve #3 OFF")
if submenuitem is "x":
writechannelstatustocomport(channel)
if submenuitem is "Q" or submenuitem is "q":
break
if menuitem is "2":
channel = 1
while True:
print(" * Set variables of the Channel #1-8")
print(" 0: channel ",channel)
print(" 1: in_temperature[" + str(channel) + "] ",in_temperature[channel])
print(" 2: in_humidity[" + str(channel) + "] ",in_humidity[channel])
print(" 3: in_gasconcentrate[" + str(channel) + "]",in_gasconcentrate[channel])
print(" 4: in_opmode[" + str(channel) + "] ",in_opmode[channel])
print(" 5: in_swmanu[" + str(channel) + "] ",in_swmanu[channel])
print(" 6: in_ocprot[" + str(channel) + "] ",in_ocprot[channel])
print(" 7: in_alarm[" + str(channel) + "] ",in_alarm[channel])
print(" 8: out_lamps[" + str(channel) + "] ",out_lamps[channel])
print(" 9: out_vents[" + str(channel) + "] ",out_vents[channel])
print(" a: out_heaters[" + str(channel) + "] ",out_heaters[channel])
print(" b: override[" + str(channel) + "][0] ",ovrstatus[override[channel][0]])
print(" c: override[" + str(channel) + "][1] ",ovrstatus[override[channel][1]])
print(" d: override[" + str(channel) + "][2] ",ovrstatus[override[channel][2]] + "\n")
print(" y: Enable/disable CH #" + str(channel) + "",ena_ch[channel])
print(" x: Send data")
print(" q: Back to main menu")
submenuitem = input()
if submenuitem is "0":
channel = channel + 1
if channel == 9:
channel = 1
if submenuitem is "1":
in_temperature[channel] = int(input("Enter new value (0-100): "))
writedebuglogtocomport("i","CH" + str(channel) + ": Measured T is " + str(in_temperature[channel]) + " C")
if submenuitem is "2":
in_humidity[channel] = int(input("Enter new value (0-100): "))
writedebuglogtocomport("i","CH" + str(channel) + ": Measured RH is " + str(in_humidity[channel]) + "%")
if submenuitem is "3":
in_gasconcentrate[channel] = int(input("Enter new value (0-100): "))
writedebuglogtocomport("i","CH" + str(channel) + ": Measured RUGC is " + str(in_gasconcentrate[channel]) + "%")
if submenuitem is "4":
if in_opmode[channel] < 2:
in_opmode[channel] = int(not in_opmode[channel])
if in_opmode[channel] == 1:
writedebuglogtocomport("i","CH" + str(channel) + ": Operation mode: growing hyphae.")
else:
writedebuglogtocomport("i","CH" + str(channel) + ": Operation mode: growing mushroom.")
if submenuitem is "5":
in_swmanu[channel] = int(not in_swmanu[channel])
if in_swmanu[channel] == 1:
writedebuglogtocomport("w","CH"+ str(channel) +": Manual mode switch is on position.")
if submenuitem is "6":
in_ocprot[channel] = int(not in_ocprot[channel])
if in_ocprot[channel] == 1:
writedebuglogtocomport("e","CH"+ str(channel) +": Overcurrent breaker of MM6D is opened!")
if submenuitem is "7":
in_alarm[channel] = int(not in_alarm[channel])
if in_alarm[channel] == 1:
writedebuglogtocomport("i","CH"+ str(channel) +": Alarm input of MM6D device is active.")
if submenuitem is "8":
out_lamps[channel] = int(not out_lamps[channel])
if out_lamps[channel] == 1:
writedebuglogtocomport("i","CH" + str(channel) + ": Output lamps ON")
else:
writedebuglogtocomport("i","CH" + str(channel) + ": Output lamps OFF")
if submenuitem is "9":
out_vents[channel] = int(not out_vents[channel])
if out_vents[channel] == 1:
writedebuglogtocomport("i","CH" + str(channel) + ": Output ventilators ON")
else:
writedebuglogtocomport("i","CH" + str(channel) + ": Output ventilators OFF")
if submenuitem is "a":
out_heaters[channel] = int(not out_heaters[channel])
if out_heaters[channel] == 1:
writedebuglogtocomport("i","CH" + str(channel) + ": Output heaters ON")
else:
writedebuglogtocomport("i","CH" + str(channel) + ": Output heaters OFF")
if submenuitem is "b":
override[channel][0] = override[channel][0] + 1
if override[channel][0] == 3:
override[channel][0] = 0
if override[channel][0] == 2:
writedebuglogtocomport("i","CH" + str(channel) + ": -> lamps ON")
if override[channel][0] == 1:
writedebuglogtocomport("i","CH" + str(channel) + ": -> lamps OFF")
if submenuitem is "c":
override[channel][1] = override[channel][1] + 1
if override[channel][1] == 3:
override[channel][1] = 0
if override[channel][1] == 2:
writedebuglogtocomport("i","CH" + str(channel) + ": -> ventilators ON")
if override[channel][1] == 1:
writedebuglogtocomport("i","CH" + str(channel) + ": -> ventilators OFF")
if submenuitem is "d":
override[channel][2] = override[channel][2] + 1
if override[channel][2] == 3:
override[channel][2] = 0
if override[channel][2] == 2:
writedebuglogtocomport("i","CH" + str(channel) + ": -> heaters ON")
if override[channel][2] == 1:
writedebuglogtocomport("i","CH" + str(channel) + ": -> heaters OFF")
if submenuitem is "y":
ena_ch[channel] = int(not ena_ch[channel])
if ena_ch[channel] == 0:
in_opmode[channel] = 127
else:
in_opmode[channel] = 0
if submenuitem is "x":
writechannelstatustocomport(channel)
if submenuitem is "Q" or submenuitem is "q":
break
sys.exit(0)
; +----------------------------------------------------------------------------+
; | MM8D v0.4 * Growing house and irrigation controlling and monitoring system |
; | Copyright (C) 2020-2022 Pozsr Zsolt <pozsar.zsolt@szerafingomba.hu> |
; | mm8d.ini |
; | Main settings |
; +----------------------------------------------------------------------------+
[user]
; user's data
usr_nam=Szerafin Gomba
usr_uid=00000000
usr_dt1=Gombakert
usr_dt2=5430 Tiszafoldvar, Kurazsi Fo ut 1.
usr_dt3=11-18. sator
[names]
; name of channels
nam_ch0=Irrigator
nam_ch1=Tent #11
nam_ch2=Tent #12
nam_ch3=Tent #13
nam_ch4=Tent #14
nam_ch5=Tent #15
nam_ch6=Tent #16
nam_ch7=Tent #17
nam_ch8=Tent #18
[enable]
; enable/disable channels
ena_ch1=1
ena_ch2=1
ena_ch3=0
ena_ch4=0
ena_ch5=0
ena_ch6=0
ena_ch7=0
ena_ch8=0
[MM6D]
; IP address of MM6D controllers
adr_mm6dch1=192.168.1.11
adr_mm6dch2=192.168.1.12
adr_mm6dch3=192.168.1.13
adr_mm6dch4=192.168.1.14
adr_mm6dch5=192.168.1.15
adr_mm6dch6=192.168.1.16
adr_mm6dch7=192.168.1.17
adr_mm6dch8=192.168.1.18
[MM7D]
; IP address of MM7D controllers
adr_mm7dch1=192.168.1.21
adr_mm7dch2=192.168.1.22
adr_mm7dch3=192.168.1.23
adr_mm7dch4=192.168.1.24
adr_mm7dch5=192.168.1.25
adr_mm7dch6=192.168.1.26
adr_mm7dch7=192.168.1.27
adr_mm7dch8=192.168.1.28
[GPIOports]
; number of used GPIO ports
prt_i1=12
prt_i2=16
prt_i3=20
prt_i4=21
prt_ro1=18
prt_ro2=23
prt_ro3=24
prt_ro4=25
prt_lo1=2
prt_lo2=3
prt_lo3=4
prt_lo4=17
[LPTport]
; address of used LPT port
; 0: 0x378
; 1: 0x278
; 2: 0x3BC
lpt_prt=0
[COMport]
; enable/disable external serial display
com_enable=1
; port name
com_device=/dev/ttyS0
; port speed
com_speed=9600
[directories]
; directories of program
dir_htm=/var/www/html
dir_lck=/var/local/lock
dir_log=/var/local/log
dir_msg=/usr/local/share/locale
dir_shr=/usr/local/share/mm8d
dir_tmp=/var/tmp
dir_var=/var/local/lib/mm8d
[openweathermap.org]
; access data
api_key=00000000000000000000000000000000
base_url=http://api.openweathermap.org/data/2.5/weather?
city_name=Tiszafoldvar
[IPcameras]
; camera of growing tents
; show camera picture on webpage
cam_show=0
; jpg snapshot link of IP cameras
cam_ch1=http://camera-th11.lan/snapshot.cgi?user=username&pwd=password
cam_ch2=http://camera-th12.lan/snapshot.cgi?user=username&pwd=password
cam_ch3=http://camera-th13.lan/snapshot.cgi?user=username&pwd=password
cam_ch4=http://camera-th14.lan/snapshot.cgi?user=username&pwd=password
cam_ch5=http://camera-th15.lan/snapshot.cgi?user=username&pwd=password
cam_ch6=http://camera-th16.lan/snapshot.cgi?user=username&pwd=password
cam_ch7=http://camera-th17.lan/snapshot.cgi?user=username&pwd=password
cam_ch8=http://camera-th18.lan/snapshot.cgi?user=username&pwd=password
[language]
; language of webpage (en/hu)
lng=en
[log]
; create and show log
; storing time of log
day_log=7
; enable/disable verbose debug log
dbg_log=0
; number of log lines on web interface
web_lines=30
Comments