aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md55
-rw-r--r--cpu.cpp69
-rw-r--r--cpu.h21
-rw-r--r--datetimeHandler.cpp19
-rw-r--r--datetimeHandler.h13
-rw-r--r--gfx_1.cpp210
-rw-r--r--gfx_1.h14
-rw-r--r--sysmon.ino108
-rw-r--r--sysmon.py99
9 files changed, 608 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b1194b5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,55 @@
+# ESP8266 Based System Monitor
+
+## Disclaimer!
+
+### This project is based on work from [execuc/esp-hw-monitoring](https://github.com/execuc/esp-hw-monitoring) with several modifications to fit my needs. I take no credit for the original work.
+
+### Modifications include but are not limited to:
+
+- Major code cleanup
+- Data format modification
+- More efficient data reading
+
+---
+
+## What is this?
+
+This is a simple ESP8266 based system monitor that can be used to monitor system information and resources. It also shows the current time as well as the ambient temperature and humidity.
+
+## Components used
+
+- ESP8266
+- 240*320 2.8 inch ILI9341 LCD
+- DHT22 temperature module (with resistor)
+
+## Connecting the components
+
+- Connect the LCD to the ESP8266 as follows:
+ - LCD VCC to ESP8266 3.3V
+ - LCD GND to ESP8266 GND
+ - LCD CS to ESP8266 D2
+ - LCD RESET to ESP8266 D3
+ - LCD DC to ESP8266 D4
+
+- Connect the DHT22 to the ESP8266 as follows:
+ - DHT22 VCC to ESP8266 3.3V
+ - DHT22 GND to ESP8266 GND
+ - DHT22 DATA to ESP8266 D8
+
+## How to use
+
+- Install the Arduino IDE
+- Install the ESP8266 board
+- Install the following libraries:
+ - Adafruit GFX Library
+ - Adafruit ILI9341
+ - Adafruit Unified Sensor
+ - DHT sensor library
+
+- Open the `sysmon.ino` file in the Arduino IDE
+
+- Upload the code to the ESP8266
+
+- Run the sysmon.py script on your computer
+
+- Enjoy! \ No newline at end of file
diff --git a/cpu.cpp b/cpu.cpp
new file mode 100644
index 0000000..2c1b437
--- /dev/null
+++ b/cpu.cpp
@@ -0,0 +1,69 @@
+#include "cpu.h"
+
+int16_t cpuUsageGlobal = defaultValue;
+int16_t cpuUsage[8] = {defaultValue, defaultValue, defaultValue,defaultValue, defaultValue, defaultValue, defaultValue, defaultValue};
+int16_t cpuTempGlobal = defaultValue;
+int16_t cpuTemp[8] = {defaultValue, defaultValue, defaultValue,defaultValue, defaultValue, defaultValue, defaultValue, defaultValue};
+uint32_t ramFree = defaultValue;
+uint32_t ramMax = defaultValue;
+
+static int8_t extractArray(String &command, int16_t *array)
+{
+ int8_t startIndex = 1, lastIndex;
+ int8_t index = 0;
+ bool needStop = false;
+ while(index < 8)
+ {
+ lastIndex = command.indexOf(",", startIndex);
+ if(lastIndex == -1)
+ {
+ lastIndex = command.length() - 1;
+ needStop = true;
+ }
+
+ array[index++] = command.substring(startIndex, lastIndex).toInt();
+ if(needStop)
+ break;
+ startIndex = lastIndex +1;
+ }
+ return index;
+}
+
+int8_t setCpuTemp(String command)
+{
+ if(command.substring(0, 1) == "[")
+ {
+ extractArray(command, cpuTemp);
+ }
+ else
+ {
+ cpuTempGlobal = command.toInt();
+ }
+ return 0;
+}
+
+int8_t setCpuUsage(String command)
+{
+ if(command.substring(0, 1) == "[")
+ {
+ extractArray(command, cpuUsage);
+ }
+ else
+ {
+ cpuUsageGlobal = command.toInt();
+ }
+ return 0;
+}
+
+int8_t setRamMax(String command)
+{
+ ramMax = command.toInt();
+ return 0;
+}
+
+int8_t setRamFree(String command)
+{
+ ramFree = command.toInt();
+ return 0;
+}
+
diff --git a/cpu.h b/cpu.h
new file mode 100644
index 0000000..cffd298
--- /dev/null
+++ b/cpu.h
@@ -0,0 +1,21 @@
+#ifndef __CPU_H__
+#define __CPU_H__
+
+#include<Arduino.h>
+
+#define defaultValue 0
+
+extern void initCpuParameters();
+extern int8_t setCpuTemp(String command);
+extern int8_t setCpuUsage(String command);
+extern int8_t setRamMax(String command);
+extern int8_t setRamFree(String command);
+
+extern int16_t cpuUsageGlobal;
+extern int16_t cpuUsage[8];
+extern int16_t cpuTempGlobal;
+extern int16_t cpuTemp[8];
+extern uint32_t ramMax;
+extern uint32_t ramFree;
+
+#endif // __CPU_H__
diff --git a/datetimeHandler.cpp b/datetimeHandler.cpp
new file mode 100644
index 0000000..6e5abd5
--- /dev/null
+++ b/datetimeHandler.cpp
@@ -0,0 +1,19 @@
+#include "datetimeHandler.h"
+
+uint8_t localTemp = 255;
+uint8_t localHum = 255;
+uint8_t hour = 0;
+uint8_t minute = 0;
+uint8_t time_tab[6] = {'-', '-', ':', '-', '-', 0};
+
+void setTime(String time)
+{
+ if(time.length() == 8)
+ {
+ hour = time.substring(0,2).toInt();
+ time.substring(0,5).getBytes(time_tab, 5+1);
+ minute = time.substring(3,5).toInt();
+ }
+}
+
+
diff --git a/datetimeHandler.h b/datetimeHandler.h
new file mode 100644
index 0000000..d51a8d6
--- /dev/null
+++ b/datetimeHandler.h
@@ -0,0 +1,13 @@
+#ifndef __DATETIMEHANDLER_H__
+#define __DATETIMEHANDLER_H__
+
+#include<Arduino.h>
+
+extern uint8_t localTemp;
+extern uint8_t localHum;
+extern uint8_t hour;
+extern uint8_t minute;
+extern uint8_t time_tab[6];
+extern void setTime(String time);
+
+#endif // __DATETIMEHANDLER_H__
diff --git a/gfx_1.cpp b/gfx_1.cpp
new file mode 100644
index 0000000..755ab04
--- /dev/null
+++ b/gfx_1.cpp
@@ -0,0 +1,210 @@
+#include "gfx_1.h"
+#include "datetimeHandler.h"
+#include "cpu.h"
+#include "Adafruit_GFX.h"
+#include <Adafruit_ILI9341.h>
+
+bool gfx1_refresh = true;
+static uint8_t s_time_tab[6] = {'0', '0', ':', '0', '0', 0};
+static uint8_t s_localHum = 0, s_localTemp = 0, s_cpuTemp = 255;
+static int16_t s_cpu_usage = 255;
+static uint32_t s_ram_free = 255, s_ram_max = 255;
+
+
+// 5px size
+static void gfx_update_toolbar();
+static void gfx_update_cpu();
+static void gfx_update_mem();
+
+static void writeArray(const char *buf)
+{
+ uint8_t c= 0;
+ while(buf[c] != 0)
+ tft.write(buf[c++]);
+}
+
+
+void gfx1_udpate()
+{
+ // if(!gfx1_refresh)
+ // return ;
+
+ gfx1_refresh = false;
+ gfx_update_toolbar();
+ gfx_update_cpu();
+ gfx_update_mem();
+}
+
+#define LINE_Y_REL 29
+#define TEXT_Y_REL 9
+#define FIRST_TEXT_Y_REL 40
+#define TEXT_ESPACE_Y 35
+#define TEXT_ESPACE_SHORT_Y 25
+
+char buf[20];
+
+void gfx1_layout()
+{
+ uint8_t c= 0;
+
+ tft.fillScreen(ILI9341_BLACK);
+ tft.drawLine(10, 18, 310, 18, ILI9341_YELLOW);
+ tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
+ tft.setCursor(35, 0);
+ tft.setTextSize(1);
+ tft.write('o');
+ tft.setTextSize(2);
+ tft.setCursor(35+8, 2);
+ tft.write('C');
+ //Humidity
+ tft.setCursor(300, 2);
+ tft.write('%');
+
+ // CPU rect
+ tft.setTextSize(2);
+ tft.drawRoundRect(5, 45, 150, 90, 10, ILI9341_DARKCYAN);
+ tft.drawLine(5, 45+LINE_Y_REL, 154, 45+LINE_Y_REL, ILI9341_DARKCYAN);
+ tft.setTextColor(ILI9341_DARKCYAN, ILI9341_BLACK);
+ tft.setCursor(60, 45+TEXT_Y_REL);
+ sprintf(buf, "CPU");
+ writeArray(buf);
+ tft.setCursor(15, 45+FIRST_TEXT_Y_REL);
+ sprintf(buf, "Usage:");
+ writeArray(buf);
+ tft.setCursor(15, 45+FIRST_TEXT_Y_REL + TEXT_ESPACE_SHORT_Y);
+ sprintf(buf, "Temp:");
+ writeArray(buf);
+ tft.setCursor(15, 45+FIRST_TEXT_Y_REL + TEXT_ESPACE_SHORT_Y *2);
+
+ // memory
+ tft.drawRoundRect(165, 45, 150, 90, 10, ILI9341_GREEN);
+ tft.drawLine(165, 45+LINE_Y_REL, 314, 45+LINE_Y_REL, ILI9341_GREEN);
+ tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
+ tft.setCursor(205, 45+TEXT_Y_REL);
+ sprintf(buf, "MEMORY");
+ writeArray(buf);
+ tft.setCursor(175, 45+FIRST_TEXT_Y_REL);
+ sprintf(buf, "Max:");
+ writeArray(buf);
+ tft.setCursor(175, 45+FIRST_TEXT_Y_REL + TEXT_ESPACE_SHORT_Y);
+ sprintf(buf, "Free:");
+ writeArray(buf);
+
+ gfx1_refresh = true;
+ gfx1_udpate();
+}
+
+void get_formated_space(int32_t valueMb)
+{
+ int8_t unity = 0;
+ if(valueMb > 999)
+ {
+ valueMb = valueMb / 1024;
+ unity = 1; // GB
+ }
+
+ if(valueMb > 9999)
+ {
+ valueMb = valueMb / 1024;
+ unity = 2; // TB
+ }
+
+ if(unity == 0)
+ sprintf(buf, "%4d MB", valueMb);
+ else if(unity == 1)
+ sprintf(buf, "%4d GB", valueMb);
+ else
+ sprintf(buf, "%4d TB", valueMb);
+}
+
+static void gfx_update_mem()
+{
+ tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
+ if(s_ram_max != ramMax)
+ {
+ tft.setCursor(175 + 50, 45+FIRST_TEXT_Y_REL);
+ get_formated_space(ramMax);
+ writeArray(buf);
+ s_ram_free = ramMax;
+ }
+
+ if(s_ram_free != ramFree)
+ {
+ tft.setCursor(175 + 50, 45+FIRST_TEXT_Y_REL + TEXT_ESPACE_SHORT_Y);
+ get_formated_space(ramFree);
+ writeArray(buf);
+ s_ram_free = ramFree;
+ }
+}
+
+//s_cpu_usage = 0;
+static void gfx_update_cpu()
+{
+ tft.setTextColor(ILI9341_DARKCYAN, ILI9341_BLACK);
+ if(cpuUsageGlobal != s_cpu_usage)
+ {
+ tft.setCursor(15+75, 45+FIRST_TEXT_Y_REL);
+ sprintf(buf, "%3d %%", cpuUsageGlobal);
+ writeArray(buf);
+ s_cpu_usage = cpuUsageGlobal;
+ }
+ if(s_cpuTemp != cpuTempGlobal)
+ {
+ tft.setCursor(15 + 75, 45+FIRST_TEXT_Y_REL + TEXT_ESPACE_SHORT_Y);
+ sprintf(buf, "%3d ", cpuTempGlobal);
+ writeArray(buf);
+ tft.setCursor(15 + 115, 45+FIRST_TEXT_Y_REL + TEXT_ESPACE_SHORT_Y - 2);
+ tft.setTextSize(1);
+ tft.write('o');
+ tft.setTextSize(2);
+ tft.setCursor(15 + 115 +8, 45+FIRST_TEXT_Y_REL + TEXT_ESPACE_SHORT_Y);
+ tft.write('C');
+ s_cpuTemp = cpuTempGlobal;
+ }
+}
+
+static void gfx_update_toolbar()
+{
+ uint8_t c= 0;
+ char buf[5];
+ tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
+ //time
+ if(s_time_tab[4] != time_tab[4] || s_time_tab[3] != time_tab[3]
+ || s_time_tab[1] != time_tab[1] || s_time_tab[0] != time_tab[0])
+ {
+ tft.setTextSize(2);
+ tft.setCursor(135, 2);
+
+ while(c < 5)
+ {
+ uint8_t car = time_tab[c];
+ s_time_tab[c] = car;
+ tft.write(car);
+ c++;
+ }
+ }
+
+ //temp
+ if(s_localTemp != localTemp)
+ {
+ tft.setCursor(10, 2);
+ if(localTemp != 255)
+ sprintf(buf, "%2d", localTemp);
+ else
+ sprintf(buf, "--");
+ writeArray(buf);
+ s_localTemp = localTemp;
+ }
+
+ // humidity
+ if(s_localHum != localHum)
+ {
+ tft.setCursor(275, 2);
+ if(localHum != 255)
+ sprintf(buf, "%2d", localHum);
+ else
+ sprintf(buf, "--");
+ writeArray(buf);
+ s_localHum = localHum;
+ }
+}
diff --git a/gfx_1.h b/gfx_1.h
new file mode 100644
index 0000000..601401e
--- /dev/null
+++ b/gfx_1.h
@@ -0,0 +1,14 @@
+#ifndef __GFX_1_H__
+#define __GFX_1_H__
+
+#include "Adafruit_ILI9341.h"
+
+extern Adafruit_ILI9341 tft;
+
+extern void gfx1_udpate();
+extern void gfx1_layout();
+
+extern bool gfx1_refresh;
+
+
+#endif
diff --git a/sysmon.ino b/sysmon.ino
new file mode 100644
index 0000000..b854bfd
--- /dev/null
+++ b/sysmon.ino
@@ -0,0 +1,108 @@
+#include "Adafruit_GFX.h"
+#include "Adafruit_ILI9341.h"
+#include <XPT2046_Touchscreen.h>
+#include "DHT.h"
+#include "cpu.h"
+#include "datetimeHandler.h"
+#include "gfx_1.h"
+
+#define TFT_DC D4
+#define TFT_CS D2
+#define TFT_RESET D3
+#define DHTPIN D8
+#define DHTTYPE DHT22
+
+Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
+DHT dht(DHTPIN, DHTTYPE);
+
+static uint32_t tempTime = 0;
+static uint32_t rtcTime = 0;
+static uint32_t displayTime = 0;
+
+void setup() {
+ Serial.begin(9600);
+ initHardware();
+ gfx1_layout();
+}
+
+void update(String command) {
+ int delimiterIndex = command.indexOf('=');
+ // Serial.println(command);
+ if (delimiterIndex != -1) {
+ String key = command.substring(0, delimiterIndex);
+ String value = command.substring(delimiterIndex + 1);
+ Serial.print(key);
+
+ // Check the key and assign the corresponding value
+ if (key.equals("CpuTemp")) {
+ setCpuTemp(value);
+ Serial.print("Received CPU temperature: ");
+ Serial.println(value);
+ // gfx1_udpate();
+ } else if (key.equals("CpuUsage")) {
+ setCpuUsage(value);
+ Serial.print("Received CPU usage: ");
+ Serial.println(value);
+ // gfx1_udpate();
+ } else if (key.equals("RamFree")) {
+ setRamFree(value);
+ Serial.print("Received Ram free: ");
+ Serial.println(value);
+ // gfx1_udpate();
+ } else if (key.equals("RamMax")) {
+ setRamMax(value);
+ Serial.print("Received Ram max: ");
+ Serial.println(value);
+ // gfx1_udpate();
+ } else if (key.equals("Time")) {
+ setTime(value);
+ Serial.print("Received Time: ");
+ Serial.println(value);
+ // gfx1_udpate();
+ }
+ }
+ gfx1_refresh = true;
+ gfx1_udpate();
+}
+
+void loop() {
+ Serial.println("Enter data:");
+ // while (Serial.available() == 0) {}
+ String command = Serial.readString();
+ command.trim();
+ Serial.println(command);
+
+ if(!isnan(dht.readTemperature()))
+ {
+ localHum = dht.readHumidity();
+ localTemp = dht.readTemperature() - 4;
+ Serial.println(localTemp);
+ gfx1_refresh = true;
+ gfx1_udpate();
+ }
+ // else
+ // {
+ // localHum = 255;
+ // localTemp = 255;
+ // }
+
+ update(command);
+ // delay(1000);
+
+ // if ( currentTime > displayTime ) {
+ // displayTime = currentTime + 100000;
+ // }
+}
+
+void initHardware()
+{
+ pinMode(TFT_RESET, OUTPUT);
+ digitalWrite(TFT_RESET, LOW);
+ delay(1000);
+ digitalWrite(TFT_RESET, HIGH);
+ delay(1000);
+ tft.begin();
+ tft.setRotation(3);
+ dht.begin();
+ // delay(3000);
+} \ No newline at end of file
diff --git a/sysmon.py b/sysmon.py
new file mode 100644
index 0000000..9fd0530
--- /dev/null
+++ b/sysmon.py
@@ -0,0 +1,99 @@
+#!/usr/bin/python
+
+import sys
+from datetime import datetime
+from datetime import timedelta
+import psutil
+import serial
+from gettext import c2py
+from time import sleep
+import sensors
+import subprocess
+import math
+import pyowm
+import os
+
+CPU_TEMP_PATH = '/sys/devices/pci0000:00/0000:00:18.3/hwmon/hwmon2/temp1_input'
+
+file_descriptor = '/dev/ttyUSB0'
+baud_rate = 9600
+
+arduino = serial.Serial(port=file_descriptor, baudrate=baud_rate)
+sleep(6)
+
+def send_command(command):
+ print("sent: " + command)
+ arduino.write(command.encode())
+ sleep(0.1)
+
+def set_time(date_time):
+ request = '\nTime=%s\r\n' % date_time.strftime('%H:%M:%S')
+ send_command(request)
+
+
+def set_max():
+ ram_max = int(psutil.virtual_memory().total / (1024.*1024.))
+ request = 'RamMax=%d\r\n' % ram_max
+ send_command(request)
+
+def set_free():
+ ram_free = int(psutil.virtual_memory().free / (1024.*1024.))
+ request = 'RamFree=%d\r\n' % ram_free
+ send_command(request)
+
+def set_system_info():
+ with open('/etc/os-release', 'r') as f:
+ for line in f:
+ if line.startswith('NAME='):
+ OSName = line.split('"')[1]
+ break
+ request = 'OS=%s\r\n' % OSName
+ send_command(request)
+ sleep(1)
+
+ with open('/proc/version', 'r') as f:
+ for line in f:
+ Kernel = line.split(' ')[2].split('-')[0]
+ break
+ request = 'Kernel=%s\r\n' % Kernel
+ send_command(request)
+ sleep(1)
+
+def set_uptime():
+ uptime_seconds = psutil.boot_time()
+ uptime = datetime.now() - datetime.fromtimestamp(uptime_seconds)
+ uptime_hours = int(uptime.total_seconds() // 3600)
+ uptime_minutes = int((uptime.total_seconds() % 3600) // 60)
+ uptime = f"{uptime_hours:02d}:{uptime_minutes:02d}"
+ request = 'Uptime=%s\r\n' % uptime
+ send_command(request)
+
+def start(tty_serial):
+
+ set_system_info()
+ while 1:
+ set_uptime()
+ sleep(1)
+ cpu_temp = int(subprocess.check_output(['cat', CPU_TEMP_PATH]))/1000
+ requests = "\nCpuTemp="+str(math.trunc(cpu_temp))
+ send_command(requests)
+ sleep(1)
+ cpu_pct = psutil.cpu_percent(interval=None, percpu=False)
+ cpu_global = int(cpu_pct)
+ request = "\nCpuUsage=" + str(math.trunc(cpu_global))
+ send_command(request)
+ sleep(1)
+ set_time(datetime.now())
+ sleep(1)
+ set_max()
+ sleep(1)
+ set_free()
+ sleep(1)
+
+
+def main():
+ start('/dev/ttyUSB0')
+
+
+if __name__ == "__main__":
+ main()