From 03ae07d762ab8d1b7f81c28aa52591a52eecc2d9 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Wed, 23 Feb 2022 04:03:33 +0100 Subject: [PATCH 01/25] Updated Readme: Added brief summary for project --- README.md | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 50bc276..dd7060d 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,32 @@ # PI-MC-WATCHER -A system that allows Monitoring of Raspberry PI('s) and it's running Minecraft Server(s) on PC and Mac +A system that allows Monitoring of Raspberry PI('s) and it's running Minecraft Server(s) on PC and Mac as well as controlling their cooling ## Why? Because I can. Overcomplicated stupid projects are a lot of fun. ## What it is about -The system contains of three parts. Those are the **PC Module**, **RPi Master Module** and ** RPi Slave Module** +The system contains of three parts. Those are the **PC Module**, **RPi Master Module** and **RPi Slave Module** -Required for this to work without any modifications are: +### To "briefly" explain the concenpt: +- The idea is to have a small server rack containing two Raspberry PI's (PI 4B & PI 1.2B+) +- We will call the PI 4B the *Master* and the PI 1.2B+ will now be the *Slave* +- The Master hosts all the information of its own system (such as CPU temps, frequency, etc.) and the ones from the Slave. +- The PC (or Mac) runs a program that, every cycle, requests all the data from the Master to essentially work as a Monitoring program for both PI's +- Let's introduce the fan control: + - We have a large 80mm Fan that cools both PI's and a smaller 40mm fan that primarily cools the Master (it requires more cooling due to it being overclocked and its hosted Minecraft servers) + - The small fan works as following: + - The small fan is either on at 100% or off at 0%. + - As soon as the Master's CPU reaches `50°C` the small fan starts to spin + - The fan requires a 5V. therefore the additional [fancontrol circuit](#fan-control-circuit): + - As soon as the dedicated GPIO pin on the Master turns on, the transistor switches on and powers the fan with 5V from the 5V GPIO pin. + - The large fan works as following: + - The small fan is either at 25%, 50%, 75% or 100% power + - As it cools both PI's, it needs to prioritize the cooling requirements of both PI's it always chooses the higher cooling requirment +- Now the Minecraft server(s): + - The Master hosts two Minecraft servers and currently implemented is the support for a single Minecraft server. + - The Master collects a variety of informations about the server of choice and throws it together with its other system information to form an array (or list in python) with all the information which then "travels" to the PC + +### Required for this to work without any modifications are: - 1x PC or macboock - 2x Raspberry PI's with GPIO Pins (Model A, A+, B or B+), any version works (I use a **Raspberry PI 4 B** and **Raspberry PI 1.2 B+**) and needed power, ethernet, etc. -connections - 2x cooling fan (I used 1x 5V & 1x 12V fan), external 12V power source (or matching one for the large fan) From f17317be23db8c0f2ef8792bd73f81e6cc46a1b9 Mon Sep 17 00:00:00 2001 From: Jonas_Jones <91549607+J-onasJones@users.noreply.github.com> Date: Mon, 29 Aug 2022 18:37:49 +0200 Subject: [PATCH 02/25] changed project name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dd7060d..fee60ff 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# PI-MC-WATCHER +# PI-server-rack A system that allows Monitoring of Raspberry PI('s) and it's running Minecraft Server(s) on PC and Mac as well as controlling their cooling ## Why? From ee12663b602c98d71cc0bdf920ea13b91b2e5891 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Mon, 29 Aug 2022 18:46:10 +0200 Subject: [PATCH 03/25] removed stuff --- pc/main.py | 105 ----------------- pi-master/main.py | 283 ---------------------------------------------- pi-slave/main.py | 57 ---------- src/circuit.png | Bin 26443 -> 0 bytes 4 files changed, 445 deletions(-) delete mode 100644 pc/main.py delete mode 100644 pi-master/main.py delete mode 100644 pi-slave/main.py delete mode 100644 src/circuit.png diff --git a/pc/main.py b/pc/main.py deleted file mode 100644 index 38689d2..0000000 --- a/pc/main.py +++ /dev/null @@ -1,105 +0,0 @@ -VERSION = "0.1.1" - -from ftplib import FTP -from io import BytesIO -from time import sleep, time - -launch_time = time() - -print("Starting PI-MC-WATCHER v" + VERSION + " for PC and Mac") -print("Initializing...") - -# wehther or not to print the stats to the console -print_stats = True - -# The credentials for the ftp server. These must be tweaked. -hostname = "172.24.1.193" -username = "testuser" -password = "uwu" - -# defining the name of the file the stats are saved to -filename = "output.txt" - -print("Connecting to FTP server...") - -ftp = FTP(hostname, username, password) -ftp.encoding = "utf-8" - -print("Connected!") - -start_time = time() - -print("All setup!") - -# permits user to read console logs from above. Can be removed to accelerate start. -sleep(3) - -while True: - - with open(filename, "wb") as file: - # use FTP's RETR command to download the file - ftp.retrbinary(f"RETR {filename}", file.write) - - file = open(filename, 'r') - content = file.read() - content = content.split(";") - # it is possible for the program to fetch the output text file right inbetween when the program on the Master PI cleared it and before it writes the stats. - # This sends an error message in the rare case of this occuring. - try: - fanmode = content[0] - slave_fanmode = content[1] - fanspeed = content[2] - fanspeed2 = content[3] - thermal = content[4] - slave_thermal = content[5] - cpu_usage = content[6] - cpu_freq = content[7] - cpu_up = content[8] - total_ram = content[9] - ram_usage = content[10] - ram_free = content[11] - ram_percent = content[12] - swap_percent = content[13] - disk_percent = content[14] - - mc_motd = content[15] - mc_version = content[16] - mc_players_max = content[17] - mc_players_on = content[18] - mc_version_brand = content[19] - mc_plugins = content[20] - mc_playerlist = content[21] - except: - # The error message to display if the above explained happens - print("WARNING: Couldn't read the file's data. If this doesn't happen a lot, just ignore this warning.") - - - if print_stats: - print("---------- Uptime: " + str(cpu_up) + " ----------") - # loop_time and stop_time won't be available on the first run as they haven't been measured yet. Therefore this fallback is needed. - try: - print("Loop time:\t" + str(round(loop_time, 2)) + "\ts") - print("CMD Uptime:\t" + str(round(stop_time - launch_time, 2)) + "\ts") - except: - print("Loop time:\t--.--\ts") - print("CMD Uptime:\t--.--\ts") - print("CPU") - print("\tusage:\t" + str(cpu_usage) + "\t%") - print("\tfreq:\t" + str(cpu_freq) + "\tMHz") - print("\ttemp:\t" + str(thermal) + "\tC") - print("RAM") - print("\tusage:\t" + str(ram_percent) + "\t%") - print("\tswap :\t" + str(swap_percent) + "\t%") - print("Disks") - print("\tusage:\t" + str(disk_percent) + "\t%") - print("FANMODE") - print("\tmain:\t" + str(fanmode) + "\t%") - print("\tslave:\t" + str(slave_fanmode) + "\t%") - print("\tglobal:\t" + str(fanspeed) + "\t%") - print("\t2ndary:\t" + str(fanspeed2) + "\t%") - - sleep(2) - - stop_time = time() - loop_time = stop_time - start_time - start_time = time() \ No newline at end of file diff --git a/pi-master/main.py b/pi-master/main.py deleted file mode 100644 index d3f12f3..0000000 --- a/pi-master/main.py +++ /dev/null @@ -1,283 +0,0 @@ -VERSION = "0.1.1" - -from http import server -import RPi.GPIO as GPIO -import subprocess, os, time, psutil - -launch_time = time.time() - -# Wether or not to print system essential stats into the console (This can have a small to medium performance impact.) -print_stats = True -# Wehter or not to ignore the slave PI. This can be useful if no second PI is connected. -ignore_slave = True - -# Starting Messages -print("Starting PI-MC-WATCHER v" + VERSION + " for RPi") -print("Processing first loop. Each loop takes 5 seconds...") -print("\n") -if print_stats: - print("The system essential stats will be printed into the console. (This can be disabled at line 8 in the program file)") -else: - print("The system essential stats will NOT be printed into the console. (This can be enabled at line 8 in the program file)") - -print("\n") - -if ignore_slave: - print("Slave will be ignored. (This can be configured at line 10 in the program file)") -else: - print("Slave will NOT be ignored. (This can be configured at line 10 in the program file)") - -# Program Delay to allow reading the above printed messages -time.sleep(5) -print("\nStarting process MAIN") - -# GPIO setup -GPIO.setmode(GPIO.BCM) -GPIO.setwarnings(False) - -# Powering Status Pin to indicate that control program is up -GPIO.setup(4, GPIO.OUT) -GPIO.output(4, True) - -# setting up communication pins for binary fanmode transmission -GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) -GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) - -# setting up control pin for fancontrol -GPIO.setup(4, GPIO.OUT) - -# setting up power pin for second fancontrol -GPIO.setup(25, GPIO.OUT) - -# define default variables -> fan speed will be at max. if someting goes wrong with getting cpu temps -global thermal, fanmode, slave_fanmode, slave_thermal, i, file, cpu_usage, cpu_freq, cpu_up, total_ram, ram_usage, ram_free, ram_percent, swap_percent, disk_percent, mc_motd, mc_version, mc_players_max, mc_players_on, mc_version_brand, mc_plugins, mc_player_list -thermal = -99 -fanmode = 100 -i = 0 - -file_path = "/home/testuser/output.txt" - -file = open(file_path, 'w') -file.close() - -cpu_usage = 0 -cpu_freq = 0 -cpu_up = 0 -total_ram = 0 -ram_usage = 0 -ram_free = 0 -ram_percent = 0 -swap_percent = 0 -disk_percent = 0 - -# check mc server status too. Set to False to disable Minecraft server module -check_mcserver = True -mc_ip = "127.0.0.1" -mc_port = "25565" - -mc_motd = "-" -mc_version = 0 -mc_players_max = 0 -mc_players_on = 0 -mc_version_brand = "-" -mc_plugins = [] -mc_player_list = [] - -# function to get cpu temperature on linux and macOS and decide on fan speed. -def temp(thermal, fanmode): - thermal = int(round(float(subprocess.check_output("cat /sys/class/thermal/thermal_zone0/temp", shell=True).rstrip())/1000,2)) - thermal = int(thermal) - if thermal <= 20: - fanmode = 0 - elif 20 < thermal <= 35: - fanmode = 25 - elif 35 < thermal <= 50: - fanmode = 50 - elif 50 < thermal <= 65: - fanmode = 75 - elif 65 < thermal: - fanmode = 100 - return thermal, fanmode - -# function to round values -def display(val): - return round(float(val),2) - -# function to get system informations -def sys_monitor(cpu_usage, cpu_freq, cpu_up, total_ram, ram_usage, ram_free, ram_percent, swap_percent, disk_percent): - #cpu_usage = str(round(float(os.popen('''grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage }' ''').readline()),2)) - cpu_usage = psutil.cpu_percent(interval=None) - cpu_freq = psutil.cpu_freq(percpu=False) - cpu_freq = cpu_freq.current - cpu_up = psutil.cpu_times() - cpu_up = cpu_up.user - - ram = psutil.virtual_memory() - #total_ram = str(round(display(subprocess.check_output("free | awk 'FNR == 2 {print $2/1000000}'", shell=True)))) - total_ram = ram.total - #ram_usage = int(subprocess.check_output("free | awk 'FNR == 2 {print $3/($3+$4)*100}'", shell=True)) - ram_usage = ram.used - #ram_free = str(100 - display(ram_usage)) - ram_free = ram.free - ram_percent = ram.percent - - swap = psutil.swap_memory() - swap_percent = swap.percent - - disk = psutil.disk_usage('/') - disk_percent = disk.percent - - - return cpu_usage, cpu_freq, cpu_up, total_ram, ram_usage, ram_free, ram_percent, swap_percent, disk_percent - -# function to get server status if enabled -def mcserver(mc_motd, mc_version, mc_players_max, mc_players_on, mc_version_brand, mc_plugins, mc_player_list): - if check_mcserver: - # importing module mcstatus --> must be installed for this in order to work - from mcstatus import MinecraftServer - mcserver = MinecraftServer.lookup(mc_ip + ":" + mc_port) - try: - status = mcserver.status() - mc_motd = status.description - mc_version = status.version.name - mc_players_max = status.players.max - mc_players_on = status.players.online - except: - status = "offline" - mc_motd = "-" - mc_version = "-" - mc_players_max = "-" - mc_players_on = "-" - - # IMPORTANT! - # for the following code to work, the query must be enabled in the server config file ('server.properties' --> 'enable-query=True'). - # If you don't have access to that file but still want your server status, you can delete the following lines that contain the 'query' argument. - # This will provide you with a more limited status: - # the version brand (vanilla, fabric modded, bukkit, etc.), the plugin list (if any) and the list if players won't be visible in that case - try: - query = mcserver.query() - mc_version = query.software.version - mc_version_brand = query.software.brand - mc_plugins = query.software.plugins - mc_player_list = query.players.names - except: - query = "unreachable" - mc_version = "-" - mc_version_brand = "-" - mc_plugins = "-" - mc_player_list = "-" - - # if no query --> delete 'mc_version_brand', 'mc_plugins' and 'mc_player_list' from the return argument - # the line below should then look like THIS: return mc_motd, mc_version, mc_players_max, mc_players_on - return mc_motd, mc_version, mc_players_max, mc_players_on, mc_version_brand, mc_plugins, mc_player_list - - -while True: - start_time = time.time() - # execute temperature function - - thermal, fanmode = temp(thermal, fanmode) - # determine fanmode of 2nd raspberry PI and guess CPU temps - if GPIO.input(17) == GPIO.HIGH and GPIO.input(18) == GPIO.HIGH: - slave_fanmode = 75 - slave_thermal = "60 - 70" - elif GPIO.input(17) == GPIO.HIGH and not GPIO.input(18) == GPIO.HIGH: - slave_fanmode = 50 - slave_thermal = "40 - 60" - elif not GPIO.input(17) == GPIO.HIGH and GPIO.input(18) == GPIO.HIGH: - slave_fanmode = 25 - slave_thermal = "0 - 40" - elif not GPIO.input(17) == GPIO.HIGH and not GPIO.input(18) == GPIO.HIGH: - slave_fanmode = 100 - slave_thermal = "70 - 100" - else: - slave_fanmode = 100 - slave_thermal = "-" - - # get other system infos and Minecraft Server stats - cpu_usage, cpu_freq, cpu_up, total_ram, ram_usage, ram_free, ram_percent, swap_percent, disk_percent = sys_monitor(cpu_usage, cpu_freq, cpu_up, total_ram, ram_usage, ram_free, ram_percent, swap_percent, disk_percent) - mc_motd, mc_version, mc_players_max, mc_players_on, mc_version_brand, mc_plugins, mc_player_list = mcserver(mc_motd, mc_version, mc_players_max, mc_players_on, mc_version_brand, mc_plugins, mc_player_list) - - # determine the PI with higher CPU temperature - if ignore_slave: - fanspeed = fanmode - else: - if slave_fanmode > fanmode: - fanspeed = slave_fanmode - else: - fanspeed = fanmode - - if fanmode < 50: - fanspeed2 = 0 - GPIO.output(25, False) - elif fanmode >= 50: - fanspeed2 = 100 - GPIO.output(25, True) - elif thermal >= 85: - os.system("sudo poweroff") - - i = 0 - - - if fanmode == 100: - GPIO.output(4, True) - time.sleep(2) - elif fanmode == 75: - while i < 6: - GPIO.output(4, True) - time.sleep(0.3) - GPIO.output(4, False) - time.sleep(0.1) - i = i + 1 - elif fanmode == 50: - while i < 6: - GPIO.output(4, True) - time.sleep(0.2) - GPIO.output(4, False) - time.sleep(0.2) - i = i + 1 - elif fanmode == 25: - while i < 6: - GPIO.output(4, True) - time.sleep(0.1) - GPIO.output(4, False) - time.sleep(0.3) - i = i + 1 - else: - GPIO.output(4, True) - time.sleep(2) - - # write all data to list - system_infos = [fanmode, slave_fanmode, fanspeed, fanspeed2, thermal, slave_thermal, cpu_usage, cpu_freq, cpu_up, total_ram, ram_usage, ram_free, ram_percent, swap_percent, disk_percent, mc_motd, mc_version, mc_players_max, mc_players_on, mc_version_brand, mc_plugins, mc_player_list] - - # delete all text in file and write list to file - file = open(file_path, 'r+') - file.truncate(0) - file.close() - file = open(file_path, 'w') - for e in system_infos: - file.write(str(e)) - file.write(";") - file.close() - - stop_time = time.time() - - if print_stats: - print("---------- Uptime: " + str(cpu_up) + " ----------") - print("Loop time:\t" + str(round(stop_time - start_time, 2)) + "\ts") - print("CMD Uptime:\t" + str(round(stop_time - launch_time, 2)) + "\ts") - print("CPU") - print("\tusage:\t" + str(cpu_usage) + "\t%") - print("\tfreq:\t" + str(cpu_freq) + "\tMHz") - print("\ttemp:\t" + str(thermal) + "\tC") - print("RAM") - print("\tusage:\t" + str(ram_percent) + "\t%") - print("\tswap :\t" + str(swap_percent) + "\t%") - print("Disks") - print("\tusage:\t" + str(disk_percent) + "\t%") - print("FANMODE") - print("\tmain:\t" + str(fanmode) + "\t%") - print("\tslave:\t" + str(slave_fanmode) + "\t%") - print("\tglobal:\t" + str(fanspeed) + "\t%") - print("\t2ndary:\t" + str(fanspeed2) + "\t%") - \ No newline at end of file diff --git a/pi-slave/main.py b/pi-slave/main.py deleted file mode 100644 index 0532fed..0000000 --- a/pi-slave/main.py +++ /dev/null @@ -1,57 +0,0 @@ -import RPi.GPIO as GPIO -import subprocess -import time - -# GPIO setup -GPIO.setmode(GPIO.BCM) -GPIO.setwarnings(False) - -# Powering Status Pin to indicate that control program is up -GPIO.setup(4, GPIO.OUT) -GPIO.output(4, True) - -# setting up communication pins for binary fanmode transmission -GPIO.setup(17, GPIO.OUT) -GPIO.setup(18, GPIO.OUT) - -# define default variables -> fan speed will be at max. if someting goes wrong with getting cpu temps -thermal = -99 -fanmode = 100 -i = 0 - -# function to get cpu temperature on linux and macOS and decide on fan speed. -def temp(thermal, fanmode): - thermal = int(round(float(subprocess.check_output("cat /sys/class/thermal/thermal_zone0/temp", shell=True).rstrip())/1000,2)) - if thermal <= 20: - fanmode = 0 - elif 20 < thermal <= 40: - fanmode = 25 - elif 40 < thermal <= 60: - fanmode = 50 - elif 60 < fanmode <= 70: - fanmode = 75 - elif 70 < fanmode: - fanmode = 100 - return thermal, fanmode - -# main loop -while True: - # get cpu temp - thermal, fanmode = temp(thermal, fanmode) - if fanmode == 0 or fanmode == 25: - GPIO.output(17, False) - GPIO.output(18, True) - elif fanmode == 50: - GPIO.output(17, True) - GPIO.output(18, False) - elif fanmode == 75: - GPIO.output(17, True) - GPIO.output(18, True) - else: - GPIO.output(17, False) - GPIO.output(18, False) - # cpu temp will be updated every 5 seconds - time.sleep(5) - i += 1 - # log cpu temp and fan speed - print("----- Run Nr.:", i, "\nCpu temperature measured: ", str(thermal) + "°C", "- Fanspeed: ", str(fanmode) + "%") \ No newline at end of file diff --git a/src/circuit.png b/src/circuit.png deleted file mode 100644 index 09dff3251ff618fe9d70c5f4c9f35ac2b503210c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26443 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 From 00b78a20d5ba8b5552fa2400d2043fd89bd86f2c Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Mon, 29 Aug 2022 18:49:45 +0200 Subject: [PATCH 04/25] initial cargo commit --- Cargo.toml | 8 ++++++++ src/main.rs | 3 +++ 2 files changed, 11 insertions(+) create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..624cb06 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "hello_world" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} From 3bf2710920f74fb9987aad9c12d070b5de0b82e5 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Mon, 29 Aug 2022 19:26:30 +0200 Subject: [PATCH 05/25] project cleanup --- .idea/.gitignore | 3 +++ .idea/PI-server-rack.iml | 9 +++++++++ .idea/misc.xml | 10 ++++++++++ .idea/modules.xml | 8 ++++++++ .idea/vcs.xml | 6 ++++++ 5 files changed, 36 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/PI-server-rack.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/PI-server-rack.iml b/.idea/PI-server-rack.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/PI-server-rack.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..2ca2389 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..fb31f4b --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From 7179e83fa21bcd4c8d7d174215b63aa4452fde8b Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Mon, 29 Aug 2022 19:26:57 +0200 Subject: [PATCH 06/25] removed depricated parts --- README.md | 80 +++---------------------------------------------------- 1 file changed, 3 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index fee60ff..98d5541 100644 --- a/README.md +++ b/README.md @@ -1,81 +1,7 @@ # PI-server-rack -A system that allows Monitoring of Raspberry PI('s) and it's running Minecraft Server(s) on PC and Mac as well as controlling their cooling +A system that allows Monitoring of Raspberry PI('s) PC and Mac as well as controlling their cooling fans. ## Why? -Because I can. Overcomplicated stupid projects are a lot of fun. +The idea was to create software to allow the different components inside my diy Raspberry PI server rack to communicate which each other. This is done with serial connections as they are very easy to set up and use. -## What it is about -The system contains of three parts. Those are the **PC Module**, **RPi Master Module** and **RPi Slave Module** - -### To "briefly" explain the concenpt: -- The idea is to have a small server rack containing two Raspberry PI's (PI 4B & PI 1.2B+) -- We will call the PI 4B the *Master* and the PI 1.2B+ will now be the *Slave* -- The Master hosts all the information of its own system (such as CPU temps, frequency, etc.) and the ones from the Slave. -- The PC (or Mac) runs a program that, every cycle, requests all the data from the Master to essentially work as a Monitoring program for both PI's -- Let's introduce the fan control: - - We have a large 80mm Fan that cools both PI's and a smaller 40mm fan that primarily cools the Master (it requires more cooling due to it being overclocked and its hosted Minecraft servers) - - The small fan works as following: - - The small fan is either on at 100% or off at 0%. - - As soon as the Master's CPU reaches `50°C` the small fan starts to spin - - The fan requires a 5V. therefore the additional [fancontrol circuit](#fan-control-circuit): - - As soon as the dedicated GPIO pin on the Master turns on, the transistor switches on and powers the fan with 5V from the 5V GPIO pin. - - The large fan works as following: - - The small fan is either at 25%, 50%, 75% or 100% power - - As it cools both PI's, it needs to prioritize the cooling requirements of both PI's it always chooses the higher cooling requirment -- Now the Minecraft server(s): - - The Master hosts two Minecraft servers and currently implemented is the support for a single Minecraft server. - - The Master collects a variety of informations about the server of choice and throws it together with its other system information to form an array (or list in python) with all the information which then "travels" to the PC - -### Required for this to work without any modifications are: -- 1x PC or macboock -- 2x Raspberry PI's with GPIO Pins (Model A, A+, B or B+), any version works (I use a **Raspberry PI 4 B** and **Raspberry PI 1.2 B+**) and needed power, ethernet, etc. -connections -- 2x cooling fan (I used 1x 5V & 1x 12V fan), external 12V power source (or matching one for the large fan) -- 6x GPIO cables -- fan control pcb with control circuit (The needed circuit is described [here](#fan-control-circuit)) - -### PC Module -The PC module requests all kinds of system information from both Raspberry PI'S making use of FTP. The Raspberry PI hosts an FTP server from which the PC fetches the text file `output.txt` containing all infos. - -### RPi Master Module -The Rpi Master Module (or Raspberry Pi Master module) gets all sorts of informations from its own system and Minecraft Servers and writes them to the `output.txt` file. It also gets fanspeed requirments from the **RPi Slave Module** making use of binary signal transmission over 2 GPIO pins. This module then controls the fan speeds. - -### RPi Slave Module -The Rpio Slave Module transmits its fanspeed requirments over 2 GPIO pins to the **RPi Master Module**. - -### Setup -## Raspberry PI basic setup -1. Install a UNIX operating of your choice onto both PI's -2. If both PI's are different, declare the more powerful one as the master and install an FTP server on it -3. Install pytho3 on both PI's -4. Go to the [releases page](https://github.com/J-onasJones/PI-MC-WATCHER/releases) and download the latest release. -5. Copy the single programs to their dedicated devices -6. Make the programs run automatically on launch (optional) -7. Edit **IP adresses**, **ports**, **usernames**, **passwords**, **configs**, etc... on all 3 programs -8. Connect 2 GPIO pins from the Slave on pins `GPIO_17` and `GPIO_18` to the Master pins `GPIO_17` and `GPIO_18` (17 to 17 and 18 to 18) -9. Connect the GPIO pins `GPIO_4` and `3.3V OUt` on both PI'S and pin `GPIO_24`, `GPIO_25` and `5V out` of the Master with the fan control circuit board. For pin mapping, view [here](#fan-control-circuit). -10. Connect the cooling fans like shown [here](#fan-control-circuit) - -## Fan control circuit - -This setup includes a custom designed and built circuit board that manages the cooling fans. The board has the following circuit: - -![image](https://user-images.githubusercontent.com/91549607/154872478-d2807b99-3585-4100-b591-f2baa214ea48.png) - -### Description -- **S1**: Status Pin for Master PI. Connected to `GPIO_4` -- **S2**: Status Pin for Slave PI. Connected to `GPIO_4` -- **P1**: Power Pin for Master PI. Connected to `3.3V Out` -- **P2**: Power Pin for Slave PI. Connected to `3.3V Out` -- **+ 1**: 12V external Power supply for large cooling fan -- **+ 2**: 5V Power supply for small coolimg fan. Connected to `5V Out` on Master PI -- **- 1**: Ground for 12V external power supply -- **- 2**: Ground for `5V Out` on Master PI -- **\~ 1**: Modulation Pin for large cooling fan. Connected to `GPIO_24` on Master PI -- **\~ 2**: Modulation Pin for small cooling fan. Connected to `GPIO_25` on Master PI -- **XOR 1**: XOR-Gate 1. Determines Master PI status -- **XOR 2**: XOR-Gate 2. Determines slave PI status -- **TR1**, **TR2**, **TR3**: NPN Transistors - -# In-more-depth explanation - -//TODO +//TODO: finish README From bde52a6e9b3c21568e622b32f06c5b816b766a89 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Tue, 30 Aug 2022 22:51:07 +0200 Subject: [PATCH 07/25] initial project structure --- .idea/PI-server-rack.iml | 5 ++++- .idea/discord.xml | 7 +++++++ .idea/misc.xml | 4 ---- .vscode/c_cpp_properties.json | 18 ++++++++++++++++++ .vscode/settings.json | 3 +++ Cargo.toml | 8 -------- arduino/README.md | 1 + arduino/arduino.ino | 9 +++++++++ desktop/Cargo.toml | 17 +++++++++++++++++ desktop/README.md | 1 + {src => desktop/src}/main.rs | 0 pi-master/Cargo.toml | 19 +++++++++++++++++++ pi-master/README.md | 1 + pi-master/src/main.rs | 3 +++ pi-slave/Cargo.toml | 17 +++++++++++++++++ pi-slave/README.md | 1 + pi-slave/src/main.rs | 3 +++ 17 files changed, 104 insertions(+), 13 deletions(-) create mode 100644 .idea/discord.xml create mode 100644 .vscode/c_cpp_properties.json create mode 100644 .vscode/settings.json delete mode 100644 Cargo.toml create mode 100644 arduino/README.md create mode 100644 arduino/arduino.ino create mode 100644 desktop/Cargo.toml create mode 100644 desktop/README.md rename {src => desktop/src}/main.rs (100%) create mode 100644 pi-master/Cargo.toml create mode 100644 pi-master/README.md create mode 100644 pi-master/src/main.rs create mode 100644 pi-slave/Cargo.toml create mode 100644 pi-slave/README.md create mode 100644 pi-slave/src/main.rs diff --git a/.idea/PI-server-rack.iml b/.idea/PI-server-rack.iml index d6ebd48..9b4cf84 100644 --- a/.idea/PI-server-rack.iml +++ b/.idea/PI-server-rack.iml @@ -2,7 +2,10 @@ - + + + + diff --git a/.idea/discord.xml b/.idea/discord.xml new file mode 100644 index 0000000..d8e9561 --- /dev/null +++ b/.idea/discord.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 2ca2389..639900d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,9 +1,5 @@ - - diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..5d33845 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", + "/usr/include/openvdb/io", + "/home/jonas_jones/GitHub/PI-server-rack/arduino" + ], + "defines": [], + "compilerPath": "/sbin/clang", + "cStandard": "c17", + "cppStandard": "c++14", + "intelliSenseMode": "linux-clang-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..691a8f6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "C_Cpp.errorSquiggles": "Disabled" +} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 624cb06..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "hello_world" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/arduino/README.md b/arduino/README.md new file mode 100644 index 0000000..10ed215 --- /dev/null +++ b/arduino/README.md @@ -0,0 +1 @@ +# Arduno module \ No newline at end of file diff --git a/arduino/arduino.ino b/arduino/arduino.ino new file mode 100644 index 0000000..95c2b6e --- /dev/null +++ b/arduino/arduino.ino @@ -0,0 +1,9 @@ +void setup() { + // put your setup code here, to run once: + +} + +void loop() { + // put your main code here, to run repeatedly: + +} diff --git a/desktop/Cargo.toml b/desktop/Cargo.toml new file mode 100644 index 0000000..0e062bc --- /dev/null +++ b/desktop/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "desktop" +version = "0.1.0" +authors = "Jonas_Jones" +edition = "2021" +description = "The desktop module of the PI-server-rack project." +documentation = "https://github.com/JonasJones/PI-server-rack" +readme = "README.md" +homepage = "https://jonasjones.me/PI-server-rack" +repository = "https://github.com/J-onasJones/PI-server-rack" +license = "MIT OR Apache-2.0" +keywords = ["server", "raspberry pi"] +categories = ["config"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/desktop/README.md b/desktop/README.md new file mode 100644 index 0000000..ff9c5e3 --- /dev/null +++ b/desktop/README.md @@ -0,0 +1 @@ +# Desktop (PC/MAC) module \ No newline at end of file diff --git a/src/main.rs b/desktop/src/main.rs similarity index 100% rename from src/main.rs rename to desktop/src/main.rs diff --git a/pi-master/Cargo.toml b/pi-master/Cargo.toml new file mode 100644 index 0000000..f80d8db --- /dev/null +++ b/pi-master/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "pi-master" +version = "0.1.0" +authors = "Jonas_Jones" +edition = "2021" +description = "The Raspberry Pi master module of the PI-server-rack project." +documentation = "https://github.com/JonasJones/PI-server-rack" +readme = "README.md" +homepage = "https://jonasjones.me/PI-server-rack" +repository = "https://github.com/J-onasJones/PI-server-rack" +license = "MIT OR Apache-2.0" +keywords = ["server", "raspberry pi"] +categories = ["config"] + + + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/pi-master/README.md b/pi-master/README.md new file mode 100644 index 0000000..408ec74 --- /dev/null +++ b/pi-master/README.md @@ -0,0 +1 @@ +# Raspberry PI master module \ No newline at end of file diff --git a/pi-master/src/main.rs b/pi-master/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/pi-master/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/pi-slave/Cargo.toml b/pi-slave/Cargo.toml new file mode 100644 index 0000000..2e0c46a --- /dev/null +++ b/pi-slave/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "pi-slave" +version = "0.1.0" +authors = "Jonas_Jones" +edition = "2021" +description = "The Raspberry Pi slave module of the PI-server-rack project." +documentation = "https://github.com/JonasJones/PI-server-rack" +readme = "README.md" +homepage = "https://jonasjones.me/PI-server-rack" +repository = "https://github.com/J-onasJones/PI-server-rack" +license = "MIT OR Apache-2.0" +keywords = ["server", "raspberry pi"] +categories = ["config"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/pi-slave/README.md b/pi-slave/README.md new file mode 100644 index 0000000..6a8cffa --- /dev/null +++ b/pi-slave/README.md @@ -0,0 +1 @@ +# Raspberry PI slave module \ No newline at end of file diff --git a/pi-slave/src/main.rs b/pi-slave/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/pi-slave/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} From c66121cfcab86897f480940a9b99652a814e3256 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Wed, 31 Aug 2022 14:30:21 +0200 Subject: [PATCH 08/25] Added arduino libraries --- arduino/LiquidCrystal.cpp | 326 +++++++++++++++++++++++++ arduino/LiquidCrystal.h | 139 +++++++++++ arduino/SoftwareSerial.cpp | 486 +++++++++++++++++++++++++++++++++++++ arduino/SoftwareSerial.h | 114 +++++++++ 4 files changed, 1065 insertions(+) create mode 100644 arduino/LiquidCrystal.cpp create mode 100644 arduino/LiquidCrystal.h create mode 100644 arduino/SoftwareSerial.cpp create mode 100644 arduino/SoftwareSerial.h diff --git a/arduino/LiquidCrystal.cpp b/arduino/LiquidCrystal.cpp new file mode 100644 index 0000000..8c6cdf0 --- /dev/null +++ b/arduino/LiquidCrystal.cpp @@ -0,0 +1,326 @@ +#include "LiquidCrystal.h" + +#include +#include +#include +#include "Arduino.h" + +// When the display powers up, it is configured as follows: +// +// 1. Display clear +// 2. Function set: +// DL = 1; 8-bit interface data +// N = 0; 1-line display +// F = 0; 5x8 dot character font +// 3. Display on/off control: +// D = 0; Display off +// C = 0; Cursor off +// B = 0; Blinking off +// 4. Entry mode set: +// I/D = 1; Increment by 1 +// S = 0; No shift +// +// Note, however, that resetting the Arduino doesn't reset the LCD, so we +// can't assume that its in that state when a sketch starts (and the +// LiquidCrystal constructor is called). + +LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) +{ + init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); +} + +LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) +{ + init(0, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7); +} + +LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) +{ + init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0); +} + +LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) +{ + init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); +} + +void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) +{ + _rs_pin = rs; + _rw_pin = rw; + _enable_pin = enable; + + _data_pins[0] = d0; + _data_pins[1] = d1; + _data_pins[2] = d2; + _data_pins[3] = d3; + _data_pins[4] = d4; + _data_pins[5] = d5; + _data_pins[6] = d6; + _data_pins[7] = d7; + + if (fourbitmode) + _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; + else + _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; + + begin(16, 1); +} + +void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { + if (lines > 1) { + _displayfunction |= LCD_2LINE; + } + _numlines = lines; + + setRowOffsets(0x00, 0x40, 0x00 + cols, 0x40 + cols); + + // for some 1 line displays you can select a 10 pixel high font + if ((dotsize != LCD_5x8DOTS) && (lines == 1)) { + _displayfunction |= LCD_5x10DOTS; + } + + pinMode(_rs_pin, OUTPUT); + // we can save 1 pin by not using RW. Indicate by passing 255 instead of pin# + if (_rw_pin != 255) { + pinMode(_rw_pin, OUTPUT); + } + pinMode(_enable_pin, OUTPUT); + + // Do these once, instead of every time a character is drawn for speed reasons. + for (int i=0; i<((_displayfunction & LCD_8BITMODE) ? 8 : 4); ++i) + { + pinMode(_data_pins[i], OUTPUT); + } + + // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! + // according to datasheet, we need at least 40ms after power rises above 2.7V + // before sending commands. Arduino can turn on way before 4.5V so we'll wait 50 + delayMicroseconds(50000); + // Now we pull both RS and R/W low to begin commands + digitalWrite(_rs_pin, LOW); + digitalWrite(_enable_pin, LOW); + if (_rw_pin != 255) { + digitalWrite(_rw_pin, LOW); + } + + //put the LCD into 4 bit or 8 bit mode + if (! (_displayfunction & LCD_8BITMODE)) { + // this is according to the hitachi HD44780 datasheet + // figure 24, pg 46 + + // we start in 8bit mode, try to set 4 bit mode + write4bits(0x03); + delayMicroseconds(4500); // wait min 4.1ms + + // second try + write4bits(0x03); + delayMicroseconds(4500); // wait min 4.1ms + + // third go! + write4bits(0x03); + delayMicroseconds(150); + + // finally, set to 4-bit interface + write4bits(0x02); + } else { + // this is according to the hitachi HD44780 datasheet + // page 45 figure 23 + + // Send function set command sequence + command(LCD_FUNCTIONSET | _displayfunction); + delayMicroseconds(4500); // wait more than 4.1ms + + // second try + command(LCD_FUNCTIONSET | _displayfunction); + delayMicroseconds(150); + + // third go + command(LCD_FUNCTIONSET | _displayfunction); + } + + // finally, set # lines, font size, etc. + command(LCD_FUNCTIONSET | _displayfunction); + + // turn the display on with no cursor or blinking default + _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; + display(); + + // clear it off + clear(); + + // Initialize to default text direction (for romance languages) + _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; + // set the entry mode + command(LCD_ENTRYMODESET | _displaymode); + +} + +void LiquidCrystal::setRowOffsets(int row0, int row1, int row2, int row3) +{ + _row_offsets[0] = row0; + _row_offsets[1] = row1; + _row_offsets[2] = row2; + _row_offsets[3] = row3; +} + +/********** high level commands, for the user! */ +void LiquidCrystal::clear() +{ + command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero + delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal::home() +{ + command(LCD_RETURNHOME); // set cursor position to zero + delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal::setCursor(uint8_t col, uint8_t row) +{ + const size_t max_lines = sizeof(_row_offsets) / sizeof(*_row_offsets); + if ( row >= max_lines ) { + row = max_lines - 1; // we count rows starting w/0 + } + if ( row >= _numlines ) { + row = _numlines - 1; // we count rows starting w/0 + } + + command(LCD_SETDDRAMADDR | (col + _row_offsets[row])); +} + +// Turn the display on/off (quickly) +void LiquidCrystal::noDisplay() { + _displaycontrol &= ~LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::display() { + _displaycontrol |= LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turns the underline cursor on/off +void LiquidCrystal::noCursor() { + _displaycontrol &= ~LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::cursor() { + _displaycontrol |= LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turn on and off the blinking cursor +void LiquidCrystal::noBlink() { + _displaycontrol &= ~LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::blink() { + _displaycontrol |= LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// These commands scroll the display without changing the RAM +void LiquidCrystal::scrollDisplayLeft(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); +} +void LiquidCrystal::scrollDisplayRight(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); +} + +// This is for text that flows Left to Right +void LiquidCrystal::leftToRight(void) { + _displaymode |= LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This is for text that flows Right to Left +void LiquidCrystal::rightToLeft(void) { + _displaymode &= ~LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'right justify' text from the cursor +void LiquidCrystal::autoscroll(void) { + _displaymode |= LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'left justify' text from the cursor +void LiquidCrystal::noAutoscroll(void) { + _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// Allows us to fill the first 8 CGRAM locations +// with custom characters +void LiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) { + location &= 0x7; // we only have 8 locations 0-7 + command(LCD_SETCGRAMADDR | (location << 3)); + for (int i=0; i<8; i++) { + write(charmap[i]); + } +} + +/*********** mid level commands, for sending data/cmds */ + +inline void LiquidCrystal::command(uint8_t value) { + send(value, LOW); +} + +inline size_t LiquidCrystal::write(uint8_t value) { + send(value, HIGH); + return 1; // assume sucess +} + +/************ low level data pushing commands **********/ + +// write either command or data, with automatic 4/8-bit selection +void LiquidCrystal::send(uint8_t value, uint8_t mode) { + digitalWrite(_rs_pin, mode); + + // if there is a RW pin indicated, set it low to Write + if (_rw_pin != 255) { + digitalWrite(_rw_pin, LOW); + } + + if (_displayfunction & LCD_8BITMODE) { + write8bits(value); + } else { + write4bits(value>>4); + write4bits(value); + } +} + +void LiquidCrystal::pulseEnable(void) { + digitalWrite(_enable_pin, LOW); + delayMicroseconds(1); + digitalWrite(_enable_pin, HIGH); + delayMicroseconds(1); // enable pulse must be >450ns + digitalWrite(_enable_pin, LOW); + delayMicroseconds(100); // commands need > 37us to settle +} + +void LiquidCrystal::write4bits(uint8_t value) { + for (int i = 0; i < 4; i++) { + digitalWrite(_data_pins[i], (value >> i) & 0x01); + } + + pulseEnable(); +} + +void LiquidCrystal::write8bits(uint8_t value) { + for (int i = 0; i < 8; i++) { + digitalWrite(_data_pins[i], (value >> i) & 0x01); + } + + pulseEnable(); +} diff --git a/arduino/LiquidCrystal.h b/arduino/LiquidCrystal.h new file mode 100644 index 0000000..184a517 --- /dev/null +++ b/arduino/LiquidCrystal.h @@ -0,0 +1,139 @@ +/* +CONTENTS FROM INCLUDED LICENSE FILE: + + = Liquid Crystal Library for Arduino = + + This library allows an Arduino board to control LiquidCrystal displays (LCDs) based on the Hitachi HD44780 (or a compatible) chipset, which is found on most text-based LCDs. + + For more information about this library please visit us at + http://www.arduino.cc/en/Reference/LiquidCrystal + + == License == + + Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. + Copyright (c) 2010 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#ifndef LiquidCrystal_h +#define LiquidCrystal_h + +#include +#include "Print.h" + +// commands +#define LCD_CLEARDISPLAY 0x01 +#define LCD_RETURNHOME 0x02 +#define LCD_ENTRYMODESET 0x04 +#define LCD_DISPLAYCONTROL 0x08 +#define LCD_CURSORSHIFT 0x10 +#define LCD_FUNCTIONSET 0x20 +#define LCD_SETCGRAMADDR 0x40 +#define LCD_SETDDRAMADDR 0x80 + +// flags for display entry mode +#define LCD_ENTRYRIGHT 0x00 +#define LCD_ENTRYLEFT 0x02 +#define LCD_ENTRYSHIFTINCREMENT 0x01 +#define LCD_ENTRYSHIFTDECREMENT 0x00 + +// flags for display on/off control +#define LCD_DISPLAYON 0x04 +#define LCD_DISPLAYOFF 0x00 +#define LCD_CURSORON 0x02 +#define LCD_CURSOROFF 0x00 +#define LCD_BLINKON 0x01 +#define LCD_BLINKOFF 0x00 + +// flags for display/cursor shift +#define LCD_DISPLAYMOVE 0x08 +#define LCD_CURSORMOVE 0x00 +#define LCD_MOVERIGHT 0x04 +#define LCD_MOVELEFT 0x00 + +// flags for function set +#define LCD_8BITMODE 0x10 +#define LCD_4BITMODE 0x00 +#define LCD_2LINE 0x08 +#define LCD_1LINE 0x00 +#define LCD_5x10DOTS 0x04 +#define LCD_5x8DOTS 0x00 + +class LiquidCrystal : public Print { +public: + LiquidCrystal(uint8_t rs, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); + LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); + LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3); + LiquidCrystal(uint8_t rs, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3); + + void init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, + uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, + uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); + + void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS); + + void clear(); + void home(); + + void noDisplay(); + void display(); + void noBlink(); + void blink(); + void noCursor(); + void cursor(); + void scrollDisplayLeft(); + void scrollDisplayRight(); + void leftToRight(); + void rightToLeft(); + void autoscroll(); + void noAutoscroll(); + + void setRowOffsets(int row1, int row2, int row3, int row4); + void createChar(uint8_t, uint8_t[]); + void setCursor(uint8_t, uint8_t); + virtual size_t write(uint8_t); + void command(uint8_t); + + using Print::write; +private: + void send(uint8_t, uint8_t); + void write4bits(uint8_t); + void write8bits(uint8_t); + void pulseEnable(); + + uint8_t _rs_pin; // LOW: command. HIGH: character. + uint8_t _rw_pin; // LOW: write to LCD. HIGH: read from LCD. + uint8_t _enable_pin; // activated by a HIGH pulse. + uint8_t _data_pins[8]; + + uint8_t _displayfunction; + uint8_t _displaycontrol; + uint8_t _displaymode; + + uint8_t _initialized; + + uint8_t _numlines; + uint8_t _row_offsets[4]; +}; + +#endif diff --git a/arduino/SoftwareSerial.cpp b/arduino/SoftwareSerial.cpp new file mode 100644 index 0000000..5a387ab --- /dev/null +++ b/arduino/SoftwareSerial.cpp @@ -0,0 +1,486 @@ +/* +SoftwareSerial.cpp (formerly NewSoftSerial.cpp) - +Multi-instance software serial library for Arduino/Wiring +-- Interrupt-driven receive and other improvements by ladyada + (http://ladyada.net) +-- Tuning, circular buffer, derivation from class Print/Stream, + multi-instance support, porting to 8MHz processors, + various optimizations, PROGMEM delay tables, inverse logic and + direct port writing by Mikal Hart (http://www.arduiniana.org) +-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com) +-- 20MHz processor support by Garrett Mace (http://www.macetech.com) +-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +The latest version of this library can always be found at +http://arduiniana.org. +*/ + +// When set, _DEBUG co-opts pins 11 and 13 for debugging with an +// oscilloscope or logic analyzer. Beware: it also slightly modifies +// the bit times, so don't rely on it too much at high baud rates +#define _DEBUG 0 +#define _DEBUG_PIN1 11 +#define _DEBUG_PIN2 13 +// +// Includes +// +#include +#include +#include +#include +#include + +// +// Statics +// +SoftwareSerial *SoftwareSerial::active_object = 0; +uint8_t SoftwareSerial::_receive_buffer[_SS_MAX_RX_BUFF]; +volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0; +volatile uint8_t SoftwareSerial::_receive_buffer_head = 0; + +// +// Debugging +// +// This function generates a brief pulse +// for debugging or measuring on an oscilloscope. +#if _DEBUG +inline void DebugPulse(uint8_t pin, uint8_t count) +{ + volatile uint8_t *pport = portOutputRegister(digitalPinToPort(pin)); + + uint8_t val = *pport; + while (count--) + { + *pport = val | digitalPinToBitMask(pin); + *pport = val; + } +} +#else +inline void DebugPulse(uint8_t, uint8_t) {} +#endif + +// +// Private methods +// + +/* static */ +inline void SoftwareSerial::tunedDelay(uint16_t delay) { + _delay_loop_2(delay); +} + +// This function sets the current object as the "listening" +// one and returns true if it replaces another +bool SoftwareSerial::listen() +{ + if (!_rx_delay_stopbit) + return false; + + if (active_object != this) + { + if (active_object) + active_object->stopListening(); + + _buffer_overflow = false; + _receive_buffer_head = _receive_buffer_tail = 0; + active_object = this; + + setRxIntMsk(true); + return true; + } + + return false; +} + +// Stop listening. Returns true if we were actually listening. +bool SoftwareSerial::stopListening() +{ + if (active_object == this) + { + setRxIntMsk(false); + active_object = NULL; + return true; + } + return false; +} + +// +// The receive routine called by the interrupt handler +// +void SoftwareSerial::recv() +{ + +#if GCC_VERSION < 40302 +// Work-around for avr-gcc 4.3.0 OSX version bug +// Preserve the registers that the compiler misses +// (courtesy of Arduino forum user *etracer*) + asm volatile( + "push r18 \n\t" + "push r19 \n\t" + "push r20 \n\t" + "push r21 \n\t" + "push r22 \n\t" + "push r23 \n\t" + "push r26 \n\t" + "push r27 \n\t" + ::); +#endif + + uint8_t d = 0; + + // If RX line is high, then we don't see any start bit + // so interrupt is probably not for us + if (_inverse_logic ? rx_pin_read() : !rx_pin_read()) + { + // Disable further interrupts during reception, this prevents + // triggering another interrupt directly after we return, which can + // cause problems at higher baudrates. + setRxIntMsk(false); + + // Wait approximately 1/2 of a bit width to "center" the sample + tunedDelay(_rx_delay_centering); + DebugPulse(_DEBUG_PIN2, 1); + + // Read each of the 8 bits + for (uint8_t i=8; i > 0; --i) + { + tunedDelay(_rx_delay_intrabit); + d >>= 1; + DebugPulse(_DEBUG_PIN2, 1); + if (rx_pin_read()) + d |= 0x80; + } + + if (_inverse_logic) + d = ~d; + + // if buffer full, set the overflow flag and return + uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF; + if (next != _receive_buffer_head) + { + // save new data in buffer: tail points to where byte goes + _receive_buffer[_receive_buffer_tail] = d; // save new byte + _receive_buffer_tail = next; + } + else + { + DebugPulse(_DEBUG_PIN1, 1); + _buffer_overflow = true; + } + + // skip the stop bit + tunedDelay(_rx_delay_stopbit); + DebugPulse(_DEBUG_PIN1, 1); + + // Re-enable interrupts when we're sure to be inside the stop bit + setRxIntMsk(true); + + } + +#if GCC_VERSION < 40302 +// Work-around for avr-gcc 4.3.0 OSX version bug +// Restore the registers that the compiler misses + asm volatile( + "pop r27 \n\t" + "pop r26 \n\t" + "pop r23 \n\t" + "pop r22 \n\t" + "pop r21 \n\t" + "pop r20 \n\t" + "pop r19 \n\t" + "pop r18 \n\t" + ::); +#endif +} + +uint8_t SoftwareSerial::rx_pin_read() +{ + return *_receivePortRegister & _receiveBitMask; +} + +// +// Interrupt handling +// + +/* static */ +inline void SoftwareSerial::handle_interrupt() +{ + if (active_object) + { + active_object->recv(); + } +} + +#if defined(PCINT0_vect) +ISR(PCINT0_vect) +{ + SoftwareSerial::handle_interrupt(); +} +#endif + +#if defined(PCINT1_vect) +ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect)); +#endif + +#if defined(PCINT2_vect) +ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect)); +#endif + +#if defined(PCINT3_vect) +ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect)); +#endif + +// +// Constructor +// +SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) : + _rx_delay_centering(0), + _rx_delay_intrabit(0), + _rx_delay_stopbit(0), + _tx_delay(0), + _buffer_overflow(false), + _inverse_logic(inverse_logic) +{ + setTX(transmitPin); + setRX(receivePin); +} + +// +// Destructor +// +SoftwareSerial::~SoftwareSerial() +{ + end(); +} + +void SoftwareSerial::setTX(uint8_t tx) +{ + // First write, then set output. If we do this the other way around, + // the pin would be output low for a short while before switching to + // output high. Now, it is input with pullup for a short while, which + // is fine. With inverse logic, either order is fine. + digitalWrite(tx, _inverse_logic ? LOW : HIGH); + pinMode(tx, OUTPUT); + _transmitBitMask = digitalPinToBitMask(tx); + uint8_t port = digitalPinToPort(tx); + _transmitPortRegister = portOutputRegister(port); +} + +void SoftwareSerial::setRX(uint8_t rx) +{ + pinMode(rx, INPUT); + if (!_inverse_logic) + digitalWrite(rx, HIGH); // pullup for normal logic! + _receivePin = rx; + _receiveBitMask = digitalPinToBitMask(rx); + uint8_t port = digitalPinToPort(rx); + _receivePortRegister = portInputRegister(port); +} + +uint16_t SoftwareSerial::subtract_cap(uint16_t num, uint16_t sub) { + if (num > sub) + return num - sub; + else + return 1; +} + +// +// Public methods +// + +void SoftwareSerial::begin(long speed) +{ + _rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0; + + // Precalculate the various delays, in number of 4-cycle delays + uint16_t bit_delay = (F_CPU / speed) / 4; + + // 12 (gcc 4.8.2) or 13 (gcc 4.3.2) cycles from start bit to first bit, + // 15 (gcc 4.8.2) or 16 (gcc 4.3.2) cycles between bits, + // 12 (gcc 4.8.2) or 14 (gcc 4.3.2) cycles from last bit to stop bit + // These are all close enough to just use 15 cycles, since the inter-bit + // timings are the most critical (deviations stack 8 times) + _tx_delay = subtract_cap(bit_delay, 15 / 4); + + // Only setup rx when we have a valid PCINT for this pin + if (digitalPinToPCICR((int8_t)_receivePin)) { + #if GCC_VERSION > 40800 + // Timings counted from gcc 4.8.2 output. This works up to 115200 on + // 16Mhz and 57600 on 8Mhz. + // + // When the start bit occurs, there are 3 or 4 cycles before the + // interrupt flag is set, 4 cycles before the PC is set to the right + // interrupt vector address and the old PC is pushed on the stack, + // and then 75 cycles of instructions (including the RJMP in the + // ISR vector table) until the first delay. After the delay, there + // are 17 more cycles until the pin value is read (excluding the + // delay in the loop). + // We want to have a total delay of 1.5 bit time. Inside the loop, + // we already wait for 1 bit time - 23 cycles, so here we wait for + // 0.5 bit time - (71 + 18 - 22) cycles. + _rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 75 + 17 - 23) / 4); + + // There are 23 cycles in each loop iteration (excluding the delay) + _rx_delay_intrabit = subtract_cap(bit_delay, 23 / 4); + + // There are 37 cycles from the last bit read to the start of + // stopbit delay and 11 cycles from the delay until the interrupt + // mask is enabled again (which _must_ happen during the stopbit). + // This delay aims at 3/4 of a bit time, meaning the end of the + // delay will be at 1/4th of the stopbit. This allows some extra + // time for ISR cleanup, which makes 115200 baud at 16Mhz work more + // reliably + _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (37 + 11) / 4); + #else // Timings counted from gcc 4.3.2 output + // Note that this code is a _lot_ slower, mostly due to bad register + // allocation choices of gcc. This works up to 57600 on 16Mhz and + // 38400 on 8Mhz. + _rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 97 + 29 - 11) / 4); + _rx_delay_intrabit = subtract_cap(bit_delay, 11 / 4); + _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (44 + 17) / 4); + #endif + + + // Enable the PCINT for the entire port here, but never disable it + // (others might also need it, so we disable the interrupt by using + // the per-pin PCMSK register). + *digitalPinToPCICR((int8_t)_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin)); + // Precalculate the pcint mask register and value, so setRxIntMask + // can be used inside the ISR without costing too much time. + _pcint_maskreg = digitalPinToPCMSK(_receivePin); + _pcint_maskvalue = _BV(digitalPinToPCMSKbit(_receivePin)); + + tunedDelay(_tx_delay); // if we were low this establishes the end + } + +#if _DEBUG + pinMode(_DEBUG_PIN1, OUTPUT); + pinMode(_DEBUG_PIN2, OUTPUT); +#endif + + listen(); +} + +void SoftwareSerial::setRxIntMsk(bool enable) +{ + if (enable) + *_pcint_maskreg |= _pcint_maskvalue; + else + *_pcint_maskreg &= ~_pcint_maskvalue; +} + +void SoftwareSerial::end() +{ + stopListening(); +} + + +// Read data from buffer +int SoftwareSerial::read() +{ + if (!isListening()) + return -1; + + // Empty buffer? + if (_receive_buffer_head == _receive_buffer_tail) + return -1; + + // Read from "head" + uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte + _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF; + return d; +} + +int SoftwareSerial::available() +{ + if (!isListening()) + return 0; + + return ((unsigned int)(_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head)) % _SS_MAX_RX_BUFF; +} + +size_t SoftwareSerial::write(uint8_t b) +{ + if (_tx_delay == 0) { + setWriteError(); + return 0; + } + + // By declaring these as local variables, the compiler will put them + // in registers _before_ disabling interrupts and entering the + // critical timing sections below, which makes it a lot easier to + // verify the cycle timings + volatile uint8_t *reg = _transmitPortRegister; + uint8_t reg_mask = _transmitBitMask; + uint8_t inv_mask = ~_transmitBitMask; + uint8_t oldSREG = SREG; + bool inv = _inverse_logic; + uint16_t delay = _tx_delay; + + if (inv) + b = ~b; + + cli(); // turn off interrupts for a clean txmit + + // Write the start bit + if (inv) + *reg |= reg_mask; + else + *reg &= inv_mask; + + tunedDelay(delay); + + // Write each of the 8 bits + for (uint8_t i = 8; i > 0; --i) + { + if (b & 1) // choose bit + *reg |= reg_mask; // send 1 + else + *reg &= inv_mask; // send 0 + + tunedDelay(delay); + b >>= 1; + } + + // restore pin to natural state + if (inv) + *reg &= inv_mask; + else + *reg |= reg_mask; + + SREG = oldSREG; // turn interrupts back on + tunedDelay(_tx_delay); + + return 1; +} + +void SoftwareSerial::flush() +{ + // There is no tx buffering, simply return +} + +int SoftwareSerial::peek() +{ + if (!isListening()) + return -1; + + // Empty buffer? + if (_receive_buffer_head == _receive_buffer_tail) + return -1; + + // Read from "head" + return _receive_buffer[_receive_buffer_head]; +} diff --git a/arduino/SoftwareSerial.h b/arduino/SoftwareSerial.h new file mode 100644 index 0000000..d8b88ce --- /dev/null +++ b/arduino/SoftwareSerial.h @@ -0,0 +1,114 @@ +/* +SoftwareSerial.h (formerly NewSoftSerial.h) - +Multi-instance software serial library for Arduino/Wiring +-- Interrupt-driven receive and other improvements by ladyada + (http://ladyada.net) +-- Tuning, circular buffer, derivation from class Print/Stream, + multi-instance support, porting to 8MHz processors, + various optimizations, PROGMEM delay tables, inverse logic and + direct port writing by Mikal Hart (http://www.arduiniana.org) +-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com) +-- 20MHz processor support by Garrett Mace (http://www.macetech.com) +-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +The latest version of this library can always be found at +http://arduiniana.org. +*/ + +#ifndef SoftwareSerial_h +#define SoftwareSerial_h + +#include +#include + +/****************************************************************************** +* Definitions +******************************************************************************/ + +#ifndef _SS_MAX_RX_BUFF +#define _SS_MAX_RX_BUFF 64 // RX buffer size +#endif + +#ifndef GCC_VERSION +#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +class SoftwareSerial : public Stream +{ +private: + // per object data + uint8_t _receivePin; + uint8_t _receiveBitMask; + volatile uint8_t *_receivePortRegister; + uint8_t _transmitBitMask; + volatile uint8_t *_transmitPortRegister; + volatile uint8_t *_pcint_maskreg; + uint8_t _pcint_maskvalue; + + // Expressed as 4-cycle delays (must never be 0!) + uint16_t _rx_delay_centering; + uint16_t _rx_delay_intrabit; + uint16_t _rx_delay_stopbit; + uint16_t _tx_delay; + + uint16_t _buffer_overflow:1; + uint16_t _inverse_logic:1; + + // static data + static uint8_t _receive_buffer[_SS_MAX_RX_BUFF]; + static volatile uint8_t _receive_buffer_tail; + static volatile uint8_t _receive_buffer_head; + static SoftwareSerial *active_object; + + // private methods + inline void recv() __attribute__((__always_inline__)); + uint8_t rx_pin_read(); + void setTX(uint8_t transmitPin); + void setRX(uint8_t receivePin); + inline void setRxIntMsk(bool enable) __attribute__((__always_inline__)); + + // Return num - sub, or 1 if the result would be < 1 + static uint16_t subtract_cap(uint16_t num, uint16_t sub); + + // private static method for timing + static inline void tunedDelay(uint16_t delay); + +public: + // public methods + SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false); + ~SoftwareSerial(); + void begin(long speed); + bool listen(); + void end(); + bool isListening() { return this == active_object; } + bool stopListening(); + bool overflow() { bool ret = _buffer_overflow; if (ret) _buffer_overflow = false; return ret; } + int peek(); + + virtual size_t write(uint8_t byte); + virtual int read(); + virtual int available(); + virtual void flush(); + operator bool() { return true; } + + using Print::write; + + // public only for easy access by interrupt handlers + static inline void handle_interrupt() __attribute__((__always_inline__)); +}; + +#endif From d4ed59693ed4275e3c23f7f5adcc7544a10fcfad Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Wed, 31 Aug 2022 14:31:26 +0200 Subject: [PATCH 09/25] vscode arduino extension config --- .vscode/arduino.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .vscode/arduino.json diff --git a/.vscode/arduino.json b/.vscode/arduino.json new file mode 100644 index 0000000..ba07a4e --- /dev/null +++ b/.vscode/arduino.json @@ -0,0 +1,7 @@ +{ + "configuration": "cpu=atmega328", + "board": "arduino:avr:nano", + "port": "/dev/ttyUSB0", + "programmer": "arduino:avrisp", + "sketch": "arduino/arduino.ino" +} \ No newline at end of file From d17fd9877c92d5e9be80ebad58aa05d87579ca32 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Wed, 31 Aug 2022 15:19:01 +0200 Subject: [PATCH 10/25] initial license --- LICENSE | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 9e9677f679d3ca972f45e167d823019312b83ac9 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Wed, 31 Aug 2022 15:21:16 +0200 Subject: [PATCH 11/25] moved arduino libs to /libs/ --- arduino/{ => libs}/LiquidCrystal.cpp | 0 arduino/{ => libs}/LiquidCrystal.h | 40 +++++++++++++-------------- arduino/{ => libs}/SoftwareSerial.cpp | 0 arduino/{ => libs}/SoftwareSerial.h | 0 4 files changed, 20 insertions(+), 20 deletions(-) rename arduino/{ => libs}/LiquidCrystal.cpp (100%) rename arduino/{ => libs}/LiquidCrystal.h (68%) rename arduino/{ => libs}/SoftwareSerial.cpp (100%) rename arduino/{ => libs}/SoftwareSerial.h (100%) diff --git a/arduino/LiquidCrystal.cpp b/arduino/libs/LiquidCrystal.cpp similarity index 100% rename from arduino/LiquidCrystal.cpp rename to arduino/libs/LiquidCrystal.cpp diff --git a/arduino/LiquidCrystal.h b/arduino/libs/LiquidCrystal.h similarity index 68% rename from arduino/LiquidCrystal.h rename to arduino/libs/LiquidCrystal.h index 184a517..5d7dcd2 100644 --- a/arduino/LiquidCrystal.h +++ b/arduino/libs/LiquidCrystal.h @@ -1,31 +1,31 @@ -/* -CONTENTS FROM INCLUDED LICENSE FILE: +/* +CONTENTS OF LICENSE FILE (added by Jonas_Jones): - = Liquid Crystal Library for Arduino = + = Liquid Crystal Library for Arduino = - This library allows an Arduino board to control LiquidCrystal displays (LCDs) based on the Hitachi HD44780 (or a compatible) chipset, which is found on most text-based LCDs. + This library allows an Arduino board to control LiquidCrystal displays (LCDs) based on the Hitachi HD44780 (or a compatible) chipset, which is found on most text-based LCDs. - For more information about this library please visit us at - http://www.arduino.cc/en/Reference/LiquidCrystal + For more information about this library please visit us at + http://www.arduino.cc/en/Reference/LiquidCrystal - == License == + == License == - Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. - Copyright (c) 2010 Arduino LLC. All right reserved. + Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. + Copyright (c) 2010 Arduino LLC. All right reserved. - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This library 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. See the GNU - Lesser General Public License for more details. + This library 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. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/arduino/SoftwareSerial.cpp b/arduino/libs/SoftwareSerial.cpp similarity index 100% rename from arduino/SoftwareSerial.cpp rename to arduino/libs/SoftwareSerial.cpp diff --git a/arduino/SoftwareSerial.h b/arduino/libs/SoftwareSerial.h similarity index 100% rename from arduino/SoftwareSerial.h rename to arduino/libs/SoftwareSerial.h From 056bc005027ab6adc0e874a03a4981295b0bee1d Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Wed, 31 Aug 2022 15:54:36 +0200 Subject: [PATCH 12/25] first version of arduino README --- arduino/README.md | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/arduino/README.md b/arduino/README.md index 10ed215..adced3b 100644 --- a/arduino/README.md +++ b/arduino/README.md @@ -1 +1,37 @@ -# Arduno module \ No newline at end of file +# Arduino module + +## task +The Arduino module manages the overall assets of the server rack. Those are the LCD display, the button panel and the internal and external serial communication between the computer, Raspberry PI4, Raspberry PI1.2 and itself. It also collects data about the system such as package loss, etc... + +## Build from source +1. The following packages/programs need to be installed and setup: + + - arduino-cli with the following libraries installed (or use libs provided in `libs/`): + - SoftwareSerial + - LiquidCristal + - git (or clone repository manually) + +2. open a terminal and run the following commands: + +``` +git clone https://github.com/J-onasJones/PI-server-rack.git +cd PI-server-rack +arduino-cli --fqbn [arduino board of your choice] arduino +``` +3. to upload the sketch to an arduino run the following command: +``` +arduino-cli upload --fqbn [arduino board of your choice] -p [arduino port name] arduino +``` +As an example on Linux for the `Arduino Nano` the following: +``` +arduino-cli upload --fqbn arduino:avr:nano -p /dev/ttyUSB0 arduino +``` + + + +## Credits and Licensing + +This project is licensed under the [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0). + +### Libraries +All provided license files for the arduino libraries at `/arduino/libs` of this repository have been added to the top of the header file of each library (the files ending in `.h`) if provided or required. \ No newline at end of file From 9ee12e423d55ca81778c1a04457db5c3c16c33d4 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Wed, 31 Aug 2022 16:52:43 +0200 Subject: [PATCH 13/25] ignoring temporary files stored in tmp/ --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d03f667 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# temporary files +tmp/ \ No newline at end of file From f74472f62b4e81edf1c68c2cdcd9af6e24b222e8 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Wed, 31 Aug 2022 18:56:15 +0200 Subject: [PATCH 14/25] Added protothread arduino library --- .../ArduinoThread/StaticThreadController.h | 75 ++++++++++++ arduino/libs/ArduinoThread/Thread.cpp | 52 ++++++++ arduino/libs/ArduinoThread/Thread.h | 89 ++++++++++++++ .../libs/ArduinoThread/ThreadController.cpp | 114 ++++++++++++++++++ arduino/libs/ArduinoThread/ThreadController.h | 53 ++++++++ 5 files changed, 383 insertions(+) create mode 100644 arduino/libs/ArduinoThread/StaticThreadController.h create mode 100644 arduino/libs/ArduinoThread/Thread.cpp create mode 100644 arduino/libs/ArduinoThread/Thread.h create mode 100644 arduino/libs/ArduinoThread/ThreadController.cpp create mode 100644 arduino/libs/ArduinoThread/ThreadController.h diff --git a/arduino/libs/ArduinoThread/StaticThreadController.h b/arduino/libs/ArduinoThread/StaticThreadController.h new file mode 100644 index 0000000..6e316ea --- /dev/null +++ b/arduino/libs/ArduinoThread/StaticThreadController.h @@ -0,0 +1,75 @@ +/* + StaticThreadController.h - Controlls a list of Threads with different timings + + Basicaly, what it does is to keep track of current Threads and run when + necessary. + + StaticThreadController is an extended class of Thread, because of that, + it allows you to add a StaticThreadController inside another kind of ThreadController... + + It works exact as ThreadController except you can't add or remove treads dynamically. + + Created by Alex Eremin, September, 2016. + Released into the public domain. +*/ + +#ifndef StaticThreadController_h +#define StaticThreadController_h + +#include "Thread.h" + +template +class StaticThreadController: public Thread{ +protected: + //since this is a static controller, the pointers themselves can be const + //it should be distinguished from 'const Thread* thread[N]' + Thread * const thread[N]; +public: + template + StaticThreadController(T... params) : + Thread(), + thread{params...} + { + #ifdef USE_THREAD_NAMES + // Overrides name + ThreadName = "StaticThreadController "; + ThreadName = ThreadName + ThreadID; + #endif + }; + + // run() Method is overrided + void run() override + { + // Run this thread before + if(_onRun != nullptr && shouldRun()) + _onRun(); + + for(int i = 0; i < N; i++){ + // Is enabled? Timeout exceeded? + if(thread[i]->shouldRun()){ + thread[i]->run(); + } + } + + // StaticThreadController extends Thread, so we should flag as runned thread + runned(); + } + + // Return the quantity of Threads + static constexpr int size() { return N; }; + + // Return the I Thread on the array + // Returns nullptr if index is out of bounds + Thread* get(int index) { + return (index >= 0 && index < N) ? thread[index] : nullptr; + }; + + // Return the I Thread on the array + // Doesn't perform any bounds checks and behaviour is + // unpredictable in case of index > N + Thread& operator[](int index) { + return *thread[index]; + }; +}; + +#endif diff --git a/arduino/libs/ArduinoThread/Thread.cpp b/arduino/libs/ArduinoThread/Thread.cpp new file mode 100644 index 0000000..cd29d98 --- /dev/null +++ b/arduino/libs/ArduinoThread/Thread.cpp @@ -0,0 +1,52 @@ +#include "Thread.h" + +Thread::Thread(void (*callback)(void), unsigned long _interval){ + enabled = true; + onRun(callback); + _cached_next_run = 0; + last_run = millis(); + + ThreadID = (int)this; + #ifdef USE_THREAD_NAMES + ThreadName = "Thread "; + ThreadName = ThreadName + ThreadID; + #endif + + setInterval(_interval); +}; + +void Thread::runned(unsigned long time){ + // Saves last_run + last_run = time; + + // Cache next run + _cached_next_run = last_run + interval; +} + +void Thread::setInterval(unsigned long _interval){ + // Save interval + interval = _interval; + + // Cache the next run based on the last_run + _cached_next_run = last_run + interval; +} + +bool Thread::shouldRun(unsigned long time){ + // If the "sign" bit is set the signed difference would be negative + bool time_remaining = (time - _cached_next_run) & 0x80000000; + + // Exceeded the time limit, AND is enabled? Then should run... + return !time_remaining && enabled; +} + +void Thread::onRun(void (*callback)(void)){ + _onRun = callback; +} + +void Thread::run(){ + if(_onRun != NULL) + _onRun(); + + // Update last_run and _cached_next_run + runned(); +} diff --git a/arduino/libs/ArduinoThread/Thread.h b/arduino/libs/ArduinoThread/Thread.h new file mode 100644 index 0000000..0e580a9 --- /dev/null +++ b/arduino/libs/ArduinoThread/Thread.h @@ -0,0 +1,89 @@ +/* + Thread.h - An runnable object + + Thread is responsable for holding the "action" for something, + also, it responds if it "should" or "should not" run, based on + the current time; + + For instructions, go to https://github.com/ivanseidel/ArduinoThread + + Created by Ivan Seidel Gomes, March, 2013. + Released into the public domain. +*/ + +#ifndef Thread_h +#define Thread_h + +#if defined(ARDUINO) && ARDUINO >= 100 + #include +#else + #include +#endif + +#include + +/* + Uncomment this line to enable ThreadName Strings. + + It might be usefull if you are loging thread with Serial, + or displaying a list of threads... +*/ +// #define USE_THREAD_NAMES 1 + +class Thread{ +protected: + // Desired interval between runs + unsigned long interval; + + // Last runned time in Ms + unsigned long last_run; + + // Scheduled run in Ms (MUST BE CACHED) + unsigned long _cached_next_run; + + /* + IMPORTANT! Run after all calls to run() + Updates last_run and cache next run. + NOTE: This MUST be called if extending + this class and implementing run() method + */ + void runned(unsigned long time); + + // Default is to mark it runned "now" + void runned() { runned(millis()); } + + // Callback for run() if not implemented + void (*_onRun)(void); + +public: + + // If the current Thread is enabled or not + bool enabled; + + // ID of the Thread (initialized from memory adr.) + int ThreadID; + + #ifdef USE_THREAD_NAMES + // Thread Name (used for better UI). + String ThreadName; + #endif + + Thread(void (*callback)(void) = NULL, unsigned long _interval = 0); + + // Set the desired interval for calls, and update _cached_next_run + virtual void setInterval(unsigned long _interval); + + // Return if the Thread should be runned or not + virtual bool shouldRun(unsigned long time); + + // Default is to check whether it should run "now" + bool shouldRun() { return shouldRun(millis()); } + + // Callback set + void onRun(void (*callback)(void)); + + // Runs Thread + virtual void run(); +}; + +#endif diff --git a/arduino/libs/ArduinoThread/ThreadController.cpp b/arduino/libs/ArduinoThread/ThreadController.cpp new file mode 100644 index 0000000..7d8e41c --- /dev/null +++ b/arduino/libs/ArduinoThread/ThreadController.cpp @@ -0,0 +1,114 @@ +#include "Thread.h" +#include "ThreadController.h" + +ThreadController::ThreadController(unsigned long _interval): Thread(){ + cached_size = 0; + + clear(); + setInterval(_interval); + + #ifdef USE_THREAD_NAMES + // Overrides name + ThreadName = "ThreadController "; + ThreadName = ThreadName + ThreadID; + #endif +} + +/* + ThreadController run() (cool stuf) +*/ +void ThreadController::run(){ + // Run this thread before + if(_onRun != NULL) + _onRun(); + + unsigned long time = millis(); + int checks = 0; + for(int i = 0; i < MAX_THREADS && checks < cached_size; i++){ + // Object exists? Is enabled? Timeout exceeded? + if(thread[i]){ + checks++; + if(thread[i]->shouldRun(time)){ + thread[i]->run(); + } + } + } + + // ThreadController extends Thread, so we should flag as runned thread + runned(); +} + + +/* + List controller (boring part) +*/ +bool ThreadController::add(Thread* _thread){ + // Check if the Thread already exists on the array + for(int i = 0; i < MAX_THREADS; i++){ + if(thread[i] != NULL && thread[i]->ThreadID == _thread->ThreadID) + return true; + } + + // Find an empty slot + for(int i = 0; i < MAX_THREADS; i++){ + if(!thread[i]){ + // Found a empty slot, now add Thread + thread[i] = _thread; + cached_size++; + return true; + } + } + + // Array is full + return false; +} + +void ThreadController::remove(int id){ + // Find Threads with the id, and removes + for(int i = 0; i < MAX_THREADS; i++){ + if(thread[i]->ThreadID == id){ + thread[i] = NULL; + cached_size--; + return; + } + } +} + +void ThreadController::remove(Thread* _thread){ + remove(_thread->ThreadID); +} + +void ThreadController::clear(){ + for(int i = 0; i < MAX_THREADS; i++){ + thread[i] = NULL; + } + cached_size = 0; +} + +int ThreadController::size(bool cached){ + if(cached) + return cached_size; + + int size = 0; + for(int i = 0; i < MAX_THREADS; i++){ + if(thread[i]) + size++; + } + cached_size = size; + + return cached_size; +} + +Thread* ThreadController::get(int index){ + int pos = -1; + for(int i = 0; i < MAX_THREADS; i++){ + if(thread[i] != NULL){ + pos++; + + if(pos == index) + return thread[i]; + } + } + + return NULL; +} diff --git a/arduino/libs/ArduinoThread/ThreadController.h b/arduino/libs/ArduinoThread/ThreadController.h new file mode 100644 index 0000000..8e2888c --- /dev/null +++ b/arduino/libs/ArduinoThread/ThreadController.h @@ -0,0 +1,53 @@ +/* + ThreadController.h - Controlls a list of Threads with different timings + + Basicaly, what it does is to keep track of current Threads and run when + necessary. + + ThreadController is an extended class of Thread, because of that, + it allows you to add a ThreadController inside another ThreadController... + + For instructions, go to https://github.com/ivanseidel/ArduinoThread + + Created by Ivan Seidel Gomes, March, 2013. + Released into the public domain. +*/ + +#ifndef ThreadController_h +#define ThreadController_h + +#include "Thread.h" +#include "inttypes.h" + +#define MAX_THREADS 15 + +class ThreadController: public Thread{ +protected: + Thread* thread[MAX_THREADS]; + int cached_size; +public: + ThreadController(unsigned long _interval = 0); + + // run() Method is overrided + void run(); + + // Adds a thread in the first available slot (remove first) + // Returns if the Thread could be added or not + bool add(Thread* _thread); + + // remove the thread (given the Thread* or ThreadID) + void remove(int _id); + void remove(Thread* _thread); + + // Removes all threads + void clear(); + + // Return the quantity of Threads + int size(bool cached = true); + + // Return the I Thread on the array + // Returns NULL if none found + Thread* get(int index); +}; + +#endif From 0a78bf5c6c1a2b8e3b3fc977d26645707a78bfcf Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Wed, 31 Aug 2022 18:56:40 +0200 Subject: [PATCH 15/25] moved libraries (again) --- .../{ => LiquidCrystal}/LiquidCrystal.cpp | 0 .../libs/{ => LiquidCrystal}/LiquidCrystal.h | 31 ------------------- .../{ => SoftwareSerial}/SoftwareSerial.cpp | 0 .../{ => SoftwareSerial}/SoftwareSerial.h | 0 4 files changed, 31 deletions(-) rename arduino/libs/{ => LiquidCrystal}/LiquidCrystal.cpp (100%) rename arduino/libs/{ => LiquidCrystal}/LiquidCrystal.h (68%) rename arduino/libs/{ => SoftwareSerial}/SoftwareSerial.cpp (100%) rename arduino/libs/{ => SoftwareSerial}/SoftwareSerial.h (100%) diff --git a/arduino/libs/LiquidCrystal.cpp b/arduino/libs/LiquidCrystal/LiquidCrystal.cpp similarity index 100% rename from arduino/libs/LiquidCrystal.cpp rename to arduino/libs/LiquidCrystal/LiquidCrystal.cpp diff --git a/arduino/libs/LiquidCrystal.h b/arduino/libs/LiquidCrystal/LiquidCrystal.h similarity index 68% rename from arduino/libs/LiquidCrystal.h rename to arduino/libs/LiquidCrystal/LiquidCrystal.h index 5d7dcd2..da950ce 100644 --- a/arduino/libs/LiquidCrystal.h +++ b/arduino/libs/LiquidCrystal/LiquidCrystal.h @@ -1,34 +1,3 @@ -/* -CONTENTS OF LICENSE FILE (added by Jonas_Jones): - - = Liquid Crystal Library for Arduino = - - This library allows an Arduino board to control LiquidCrystal displays (LCDs) based on the Hitachi HD44780 (or a compatible) chipset, which is found on most text-based LCDs. - - For more information about this library please visit us at - http://www.arduino.cc/en/Reference/LiquidCrystal - - == License == - - Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. - Copyright (c) 2010 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - #ifndef LiquidCrystal_h #define LiquidCrystal_h diff --git a/arduino/libs/SoftwareSerial.cpp b/arduino/libs/SoftwareSerial/SoftwareSerial.cpp similarity index 100% rename from arduino/libs/SoftwareSerial.cpp rename to arduino/libs/SoftwareSerial/SoftwareSerial.cpp diff --git a/arduino/libs/SoftwareSerial.h b/arduino/libs/SoftwareSerial/SoftwareSerial.h similarity index 100% rename from arduino/libs/SoftwareSerial.h rename to arduino/libs/SoftwareSerial/SoftwareSerial.h From 208901d0ba2624bbdff6f6e7a7d531fafb760227 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Wed, 31 Aug 2022 20:41:37 +0200 Subject: [PATCH 16/25] vs code properties update --- .vscode/c_cpp_properties.json | 545 +++++++++++++++++++++++++++++++++- 1 file changed, 540 insertions(+), 5 deletions(-) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 5d33845..a72c8b4 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -1,18 +1,553 @@ { + "version": 4, "configurations": [ { "name": "Linux", + "compilerPath": "/sbin/clang", + "compilerArgs": [], + "intelliSenseMode": "linux-clang-x64", "includePath": [ "${workspaceFolder}/**", "/usr/include/openvdb/io", "/home/jonas_jones/GitHub/PI-server-rack/arduino" ], - "defines": [], - "compilerPath": "/sbin/clang", + "forcedInclude": [], "cStandard": "c17", "cppStandard": "c++14", - "intelliSenseMode": "linux-clang-x64" + "defines": [] + }, + { + "name": "Arduino", + "compilerPath": "/home/jonas_jones/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++", + "compilerArgs": [ + "-std=gnu++11", + "-fpermissive", + "-fno-exceptions", + "-ffunction-sections", + "-fdata-sections", + "-fno-threadsafe-statics", + "-Wno-error=narrowing" + ], + "intelliSenseMode": "gcc-x64", + "includePath": [ + "/home/jonas_jones/.arduino15/packages/arduino/hardware/avr/1.8.5/cores/arduino", + "/home/jonas_jones/.arduino15/packages/arduino/hardware/avr/1.8.5/variants/eightanaloginputs", + "/home/jonas_jones/.arduino15/packages/arduino/hardware/avr/1.8.5/libraries/SoftwareSerial/src", + "/home/jonas_jones/Arduino/libraries/LiquidCrystal/src", + "/home/jonas_jones/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/lib/gcc/avr/7.3.0/include", + "/home/jonas_jones/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/lib/gcc/avr/7.3.0/include-fixed", + "/home/jonas_jones/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/avr/include" + ], + "forcedInclude": [ + "/home/jonas_jones/.arduino15/packages/arduino/hardware/avr/1.8.5/cores/arduino/Arduino.h" + ], + "cStandard": "c11", + "cppStandard": "c++11", + "defines": [ + "F_CPU=16000000L", + "ARDUINO=10819", + "ARDUINO_AVR_NANO", + "ARDUINO_ARCH_AVR", + "__DBL_MIN_EXP__=(-125)", + "__HQ_FBIT__=15", + "__cpp_attributes=200809", + "__UINT_LEAST16_MAX__=0xffffU", + "__ATOMIC_ACQUIRE=2", + "__SFRACT_IBIT__=0", + "__FLT_MIN__=1.17549435e-38F", + "__GCC_IEC_559_COMPLEX=0", + "__BUILTIN_AVR_SLEEP=1", + "__BUILTIN_AVR_COUNTLSULLK=1", + "__cpp_aggregate_nsdmi=201304", + "__BUILTIN_AVR_COUNTLSULLR=1", + "__UFRACT_MAX__=0XFFFFP-16UR", + "__UINT_LEAST8_TYPE__=unsigned char", + "__DQ_FBIT__=63", + "__INTMAX_C(c)=c ## LL", + "__ULFRACT_FBIT__=32", + "__SACCUM_EPSILON__=0x1P-7HK", + "__CHAR_BIT__=8", + "__USQ_IBIT__=0", + "__UINT8_MAX__=0xff", + "__ACCUM_FBIT__=15", + "__WINT_MAX__=0x7fff", + "__FLT32_MIN_EXP__=(-125)", + "__cpp_static_assert=200410", + "__USFRACT_FBIT__=8", + "__ORDER_LITTLE_ENDIAN__=1234", + "__SIZE_MAX__=0xffffU", + "__WCHAR_MAX__=0x7fff", + "__LACCUM_IBIT__=32", + "__DBL_DENORM_MIN__=double(1.40129846e-45L)", + "__GCC_ATOMIC_CHAR_LOCK_FREE=1", + "__GCC_IEC_559=0", + "__FLT_EVAL_METHOD__=0", + "__BUILTIN_AVR_LLKBITS=1", + "__cpp_binary_literals=201304", + "__LLACCUM_MAX__=0X7FFFFFFFFFFFFFFFP-47LLK", + "__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1", + "__BUILTIN_AVR_HKBITS=1", + "__BUILTIN_AVR_BITSLLK=1", + "__FRACT_FBIT__=15", + "__BUILTIN_AVR_BITSLLR=1", + "__cpp_variadic_templates=200704", + "__UINT_FAST64_MAX__=0xffffffffffffffffULL", + "__SIG_ATOMIC_TYPE__=char", + "__BUILTIN_AVR_UHKBITS=1", + "__UACCUM_FBIT__=16", + "__DBL_MIN_10_EXP__=(-37)", + "__FINITE_MATH_ONLY__=0", + "__cpp_variable_templates=201304", + "__LFRACT_IBIT__=0", + "__GNUC_PATCHLEVEL__=0", + "__FLT32_HAS_DENORM__=1", + "__LFRACT_MAX__=0X7FFFFFFFP-31LR", + "__UINT_FAST8_MAX__=0xff", + "__has_include(STR)=__has_include__(STR)", + "__DEC64_MAX_EXP__=385", + "__INT8_C(c)=c", + "__INT_LEAST8_WIDTH__=8", + "__UINT_LEAST64_MAX__=0xffffffffffffffffULL", + "__SA_FBIT__=15", + "__SHRT_MAX__=0x7fff", + "__LDBL_MAX__=3.40282347e+38L", + "__FRACT_MAX__=0X7FFFP-15R", + "__UFRACT_FBIT__=16", + "__UFRACT_MIN__=0.0UR", + "__UINT_LEAST8_MAX__=0xff", + "__GCC_ATOMIC_BOOL_LOCK_FREE=1", + "__UINTMAX_TYPE__=long long unsigned int", + "__LLFRACT_EPSILON__=0x1P-63LLR", + "__BUILTIN_AVR_DELAY_CYCLES=1", + "__DEC32_EPSILON__=1E-6DF", + "__FLT_EVAL_METHOD_TS_18661_3__=0", + "__UINT32_MAX__=0xffffffffUL", + "__GXX_EXPERIMENTAL_CXX0X__=1", + "__ULFRACT_MAX__=0XFFFFFFFFP-32ULR", + "__TA_IBIT__=16", + "__LDBL_MAX_EXP__=128", + "__WINT_MIN__=(-__WINT_MAX__ - 1)", + "__INT_LEAST16_WIDTH__=16", + "__ULLFRACT_MIN__=0.0ULLR", + "__SCHAR_MAX__=0x7f", + "__WCHAR_MIN__=(-__WCHAR_MAX__ - 1)", + "__INT64_C(c)=c ## LL", + "__DBL_DIG__=6", + "__GCC_ATOMIC_POINTER_LOCK_FREE=1", + "__AVR_HAVE_SPH__=1", + "__LLACCUM_MIN__=(-0X1P15LLK-0X1P15LLK)", + "__BUILTIN_AVR_KBITS=1", + "__BUILTIN_AVR_ABSK=1", + "__BUILTIN_AVR_ABSR=1", + "__SIZEOF_INT__=2", + "__SIZEOF_POINTER__=2", + "__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1", + "__USACCUM_IBIT__=8", + "__USER_LABEL_PREFIX__", + "__STDC_HOSTED__=1", + "__LDBL_HAS_INFINITY__=1", + "__LFRACT_MIN__=(-0.5LR-0.5LR)", + "__HA_IBIT__=8", + "__FLT32_DIG__=6", + "__TQ_IBIT__=0", + "__FLT_EPSILON__=1.19209290e-7F", + "__GXX_WEAK__=1", + "__SHRT_WIDTH__=16", + "__USFRACT_IBIT__=0", + "__LDBL_MIN__=1.17549435e-38L", + "__FRACT_MIN__=(-0.5R-0.5R)", + "__AVR_SFR_OFFSET__=0x20", + "__DEC32_MAX__=9.999999E96DF", + "__cpp_threadsafe_static_init=200806", + "__DA_IBIT__=32", + "__INT32_MAX__=0x7fffffffL", + "__UQQ_FBIT__=8", + "__INT_WIDTH__=16", + "__SIZEOF_LONG__=4", + "__UACCUM_MAX__=0XFFFFFFFFP-16UK", + "__UINT16_C(c)=c ## U", + "__PTRDIFF_WIDTH__=16", + "__DECIMAL_DIG__=9", + "__LFRACT_EPSILON__=0x1P-31LR", + "__AVR_2_BYTE_PC__=1", + "__ULFRACT_MIN__=0.0ULR", + "__INTMAX_WIDTH__=64", + "__has_include_next(STR)=__has_include_next__(STR)", + "__BUILTIN_AVR_ULLRBITS=1", + "__LDBL_HAS_QUIET_NAN__=1", + "__ULACCUM_IBIT__=32", + "__UACCUM_EPSILON__=0x1P-16UK", + "__BUILTIN_AVR_SEI=1", + "__GNUC__=7", + "__ULLACCUM_MAX__=0XFFFFFFFFFFFFFFFFP-48ULLK", + "__cpp_delegating_constructors=200604", + "__HQ_IBIT__=0", + "__BUILTIN_AVR_SWAP=1", + "__FLT_HAS_DENORM__=1", + "__SIZEOF_LONG_DOUBLE__=4", + "__BIGGEST_ALIGNMENT__=1", + "__STDC_UTF_16__=1", + "__UINT24_MAX__=16777215UL", + "__BUILTIN_AVR_NOP=1", + "__GNUC_STDC_INLINE__=1", + "__DQ_IBIT__=0", + "__FLT32_HAS_INFINITY__=1", + "__DBL_MAX__=double(3.40282347e+38L)", + "__ULFRACT_IBIT__=0", + "__cpp_raw_strings=200710", + "__INT_FAST32_MAX__=0x7fffffffL", + "__DBL_HAS_INFINITY__=1", + "__INT64_MAX__=0x7fffffffffffffffLL", + "__ACCUM_IBIT__=16", + "__DEC32_MIN_EXP__=(-94)", + "__BUILTIN_AVR_UKBITS=1", + "__INTPTR_WIDTH__=16", + "__BUILTIN_AVR_FMULSU=1", + "__LACCUM_MAX__=0X7FFFFFFFFFFFFFFFP-31LK", + "__INT_FAST16_TYPE__=int", + "__LDBL_HAS_DENORM__=1", + "__BUILTIN_AVR_BITSK=1", + "__BUILTIN_AVR_BITSR=1", + "__cplusplus=201402L", + "__cpp_ref_qualifiers=200710", + "__DEC128_MAX__=9.999999999999999999999999999999999E6144DL", + "__INT_LEAST32_MAX__=0x7fffffffL", + "__USING_SJLJ_EXCEPTIONS__=1", + "__DEC32_MIN__=1E-95DF", + "__ACCUM_MAX__=0X7FFFFFFFP-15K", + "__DEPRECATED=1", + "__cpp_rvalue_references=200610", + "__DBL_MAX_EXP__=128", + "__USACCUM_EPSILON__=0x1P-8UHK", + "__WCHAR_WIDTH__=16", + "__FLT32_MAX__=3.40282347e+38F32", + "__DEC128_EPSILON__=1E-33DL", + "__SFRACT_MAX__=0X7FP-7HR", + "__FRACT_IBIT__=0", + "__PTRDIFF_MAX__=0x7fff", + "__UACCUM_MIN__=0.0UK", + "__UACCUM_IBIT__=16", + "__BUILTIN_AVR_NOPS=1", + "__BUILTIN_AVR_WDR=1", + "__FLT32_HAS_QUIET_NAN__=1", + "__GNUG__=7", + "__LONG_LONG_MAX__=0x7fffffffffffffffLL", + "__SIZEOF_SIZE_T__=2", + "__ULACCUM_MAX__=0XFFFFFFFFFFFFFFFFP-32ULK", + "__cpp_rvalue_reference=200610", + "__cpp_nsdmi=200809", + "__SIZEOF_WINT_T__=2", + "__LONG_LONG_WIDTH__=64", + "__cpp_initializer_lists=200806", + "__FLT32_MAX_EXP__=128", + "__SA_IBIT__=16", + "__ULLACCUM_MIN__=0.0ULLK", + "__BUILTIN_AVR_ROUNDUHK=1", + "__BUILTIN_AVR_ROUNDUHR=1", + "__cpp_hex_float=201603", + "__GXX_ABI_VERSION=1011", + "__INT24_MAX__=8388607L", + "__UTA_FBIT__=48", + "__FLT_MIN_EXP__=(-125)", + "__USFRACT_MAX__=0XFFP-8UHR", + "__UFRACT_IBIT__=0", + "__BUILTIN_AVR_ROUNDFX=1", + "__BUILTIN_AVR_ROUNDULK=1", + "__BUILTIN_AVR_ROUNDULR=1", + "__cpp_lambdas=200907", + "__BUILTIN_AVR_COUNTLSLLK=1", + "__BUILTIN_AVR_COUNTLSLLR=1", + "__BUILTIN_AVR_ROUNDHK=1", + "__INT_FAST64_TYPE__=long long int", + "__BUILTIN_AVR_ROUNDHR=1", + "__DBL_MIN__=double(1.17549435e-38L)", + "__BUILTIN_AVR_COUNTLSK=1", + "__BUILTIN_AVR_ROUNDLK=1", + "__BUILTIN_AVR_COUNTLSR=1", + "__BUILTIN_AVR_ROUNDLR=1", + "__LACCUM_MIN__=(-0X1P31LK-0X1P31LK)", + "__ULLACCUM_FBIT__=48", + "__BUILTIN_AVR_LKBITS=1", + "__ULLFRACT_EPSILON__=0x1P-64ULLR", + "__DEC128_MIN__=1E-6143DL", + "__REGISTER_PREFIX__", + "__UINT16_MAX__=0xffffU", + "__DBL_HAS_DENORM__=1", + "__BUILTIN_AVR_ULKBITS=1", + "__ACCUM_MIN__=(-0X1P15K-0X1P15K)", + "__AVR_ARCH__=2", + "__SQ_IBIT__=0", + "__FLT32_MIN__=1.17549435e-38F32", + "__UINT8_TYPE__=unsigned char", + "__BUILTIN_AVR_ROUNDUK=1", + "__BUILTIN_AVR_ROUNDUR=1", + "__UHA_FBIT__=8", + "__NO_INLINE__=1", + "__SFRACT_MIN__=(-0.5HR-0.5HR)", + "__UTQ_FBIT__=128", + "__FLT_MANT_DIG__=24", + "__LDBL_DECIMAL_DIG__=9", + "__VERSION__=\"7.3.0\"", + "__UINT64_C(c)=c ## ULL", + "__ULLFRACT_FBIT__=64", + "__cpp_unicode_characters=200704", + "__FRACT_EPSILON__=0x1P-15R", + "__ULACCUM_MIN__=0.0ULK", + "__UDA_FBIT__=32", + "__cpp_decltype_auto=201304", + "__LLACCUM_EPSILON__=0x1P-47LLK", + "__GCC_ATOMIC_INT_LOCK_FREE=1", + "__FLT32_MANT_DIG__=24", + "__BUILTIN_AVR_BITSUHK=1", + "__BUILTIN_AVR_BITSUHR=1", + "__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__", + "__USFRACT_MIN__=0.0UHR", + "__BUILTIN_AVR_BITSULK=1", + "__ULLACCUM_IBIT__=16", + "__BUILTIN_AVR_BITSULR=1", + "__UQQ_IBIT__=0", + "__BUILTIN_AVR_LLRBITS=1", + "__SCHAR_WIDTH__=8", + "__BUILTIN_AVR_BITSULLK=1", + "__BUILTIN_AVR_BITSULLR=1", + "__INT32_C(c)=c ## L", + "__DEC64_EPSILON__=1E-15DD", + "__ORDER_PDP_ENDIAN__=3412", + "__DEC128_MIN_EXP__=(-6142)", + "__UHQ_FBIT__=16", + "__LLACCUM_FBIT__=47", + "__FLT32_MAX_10_EXP__=38", + "__BUILTIN_AVR_ROUNDULLK=1", + "__BUILTIN_AVR_ROUNDULLR=1", + "__INT_FAST32_TYPE__=long int", + "__BUILTIN_AVR_HRBITS=1", + "__UINT_LEAST16_TYPE__=unsigned int", + "__BUILTIN_AVR_UHRBITS=1", + "__INT16_MAX__=0x7fff", + "__SIZE_TYPE__=unsigned int", + "__UINT64_MAX__=0xffffffffffffffffULL", + "__UDQ_FBIT__=64", + "__INT8_TYPE__=signed char", + "__cpp_digit_separators=201309", + "__ELF__=1", + "__ULFRACT_EPSILON__=0x1P-32ULR", + "__LLFRACT_FBIT__=63", + "__FLT_RADIX__=2", + "__INT_LEAST16_TYPE__=int", + "__BUILTIN_AVR_ABSFX=1", + "__LDBL_EPSILON__=1.19209290e-7L", + "__UINTMAX_C(c)=c ## ULL", + "__INT24_MIN__=(-__INT24_MAX__-1)", + "__SACCUM_MAX__=0X7FFFP-7HK", + "__BUILTIN_AVR_ABSHR=1", + "__SIG_ATOMIC_MAX__=0x7f", + "__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1", + "__cpp_sized_deallocation=201309", + "__SIZEOF_PTRDIFF_T__=2", + "__AVR=1", + "__BUILTIN_AVR_ABSLK=1", + "__BUILTIN_AVR_ABSLR=1", + "__LACCUM_EPSILON__=0x1P-31LK", + "__DEC32_SUBNORMAL_MIN__=0.000001E-95DF", + "__INT_FAST16_MAX__=0x7fff", + "__UINT_FAST32_MAX__=0xffffffffUL", + "__UINT_LEAST64_TYPE__=long long unsigned int", + "__USACCUM_MAX__=0XFFFFP-8UHK", + "__SFRACT_EPSILON__=0x1P-7HR", + "__FLT_HAS_QUIET_NAN__=1", + "__FLT_MAX_10_EXP__=38", + "__LONG_MAX__=0x7fffffffL", + "__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL", + "__FLT_HAS_INFINITY__=1", + "__cpp_unicode_literals=200710", + "__USA_FBIT__=16", + "__UINT_FAST16_TYPE__=unsigned int", + "__DEC64_MAX__=9.999999999999999E384DD", + "__INT_FAST32_WIDTH__=32", + "__BUILTIN_AVR_RBITS=1", + "__CHAR16_TYPE__=unsigned int", + "__PRAGMA_REDEFINE_EXTNAME=1", + "__SIZE_WIDTH__=16", + "__INT_LEAST16_MAX__=0x7fff", + "__DEC64_MANT_DIG__=16", + "__UINT_LEAST32_MAX__=0xffffffffUL", + "__SACCUM_FBIT__=7", + "__FLT32_DENORM_MIN__=1.40129846e-45F32", + "__GCC_ATOMIC_LONG_LOCK_FREE=1", + "__SIG_ATOMIC_WIDTH__=8", + "__INT_LEAST64_TYPE__=long long int", + "__INT16_TYPE__=int", + "__INT_LEAST8_TYPE__=signed char", + "__SQ_FBIT__=31", + "__DEC32_MAX_EXP__=97", + "__INT_FAST8_MAX__=0x7f", + "__INTPTR_MAX__=0x7fff", + "__QQ_FBIT__=7", + "__cpp_range_based_for=200907", + "__UTA_IBIT__=16", + "__AVR_ERRATA_SKIP__=1", + "__FLT32_MIN_10_EXP__=(-37)", + "__LDBL_MANT_DIG__=24", + "__SFRACT_FBIT__=7", + "__SACCUM_MIN__=(-0X1P7HK-0X1P7HK)", + "__DBL_HAS_QUIET_NAN__=1", + "__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)", + "AVR=1", + "__BUILTIN_AVR_FMULS=1", + "__cpp_return_type_deduction=201304", + "__INTPTR_TYPE__=int", + "__UINT16_TYPE__=unsigned int", + "__WCHAR_TYPE__=int", + "__SIZEOF_FLOAT__=4", + "__AVR__=1", + "__BUILTIN_AVR_INSERT_BITS=1", + "__USQ_FBIT__=32", + "__UINTPTR_MAX__=0xffffU", + "__INT_FAST64_WIDTH__=64", + "__DEC64_MIN_EXP__=(-382)", + "__cpp_decltype=200707", + "__FLT32_DECIMAL_DIG__=9", + "__INT_FAST64_MAX__=0x7fffffffffffffffLL", + "__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1", + "__FLT_DIG__=6", + "__UINT_FAST64_TYPE__=long long unsigned int", + "__BUILTIN_AVR_BITSHK=1", + "__BUILTIN_AVR_BITSHR=1", + "__INT_MAX__=0x7fff", + "__LACCUM_FBIT__=31", + "__USACCUM_MIN__=0.0UHK", + "__UHA_IBIT__=8", + "__INT64_TYPE__=long long int", + "__BUILTIN_AVR_BITSLK=1", + "__BUILTIN_AVR_BITSLR=1", + "__FLT_MAX_EXP__=128", + "__UTQ_IBIT__=0", + "__DBL_MANT_DIG__=24", + "__cpp_inheriting_constructors=201511", + "__BUILTIN_AVR_ULLKBITS=1", + "__INT_LEAST64_MAX__=0x7fffffffffffffffLL", + "__DEC64_MIN__=1E-383DD", + "__WINT_TYPE__=int", + "__UINT_LEAST32_TYPE__=long unsigned int", + "__SIZEOF_SHORT__=2", + "__ULLFRACT_IBIT__=0", + "__LDBL_MIN_EXP__=(-125)", + "__UDA_IBIT__=32", + "__WINT_WIDTH__=16", + "__INT_LEAST8_MAX__=0x7f", + "__LFRACT_FBIT__=31", + "__LDBL_MAX_10_EXP__=38", + "__ATOMIC_RELAXED=0", + "__DBL_EPSILON__=double(1.19209290e-7L)", + "__BUILTIN_AVR_BITSUK=1", + "__BUILTIN_AVR_BITSUR=1", + "__UINT8_C(c)=c", + "__INT_LEAST32_TYPE__=long int", + "__BUILTIN_AVR_URBITS=1", + "__SIZEOF_WCHAR_T__=2", + "__LLFRACT_MAX__=0X7FFFFFFFFFFFFFFFP-63LLR", + "__TQ_FBIT__=127", + "__INT_FAST8_TYPE__=signed char", + "__ULLACCUM_EPSILON__=0x1P-48ULLK", + "__BUILTIN_AVR_ROUNDK=1", + "__BUILTIN_AVR_ROUNDR=1", + "__UHQ_IBIT__=0", + "__LLACCUM_IBIT__=16", + "__FLT32_EPSILON__=1.19209290e-7F32", + "__DBL_DECIMAL_DIG__=9", + "__STDC_UTF_32__=1", + "__INT_FAST8_WIDTH__=8", + "__DEC_EVAL_METHOD__=2", + "__TA_FBIT__=47", + "__UDQ_IBIT__=0", + "__ORDER_BIG_ENDIAN__=4321", + "__cpp_runtime_arrays=198712", + "__WITH_AVRLIBC__=1", + "__UINT64_TYPE__=long long unsigned int", + "__ACCUM_EPSILON__=0x1P-15K", + "__UINT32_C(c)=c ## UL", + "__BUILTIN_AVR_COUNTLSUHK=1", + "__INTMAX_MAX__=0x7fffffffffffffffLL", + "__cpp_alias_templates=200704", + "__BUILTIN_AVR_COUNTLSUHR=1", + "__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__", + "__FLT_DENORM_MIN__=1.40129846e-45F", + "__LLFRACT_IBIT__=0", + "__INT8_MAX__=0x7f", + "__LONG_WIDTH__=32", + "__UINT_FAST32_TYPE__=long unsigned int", + "__CHAR32_TYPE__=long unsigned int", + "__BUILTIN_AVR_COUNTLSULK=1", + "__BUILTIN_AVR_COUNTLSULR=1", + "__FLT_MAX__=3.40282347e+38F", + "__cpp_constexpr=201304", + "__USACCUM_FBIT__=8", + "__BUILTIN_AVR_COUNTLSFX=1", + "__INT32_TYPE__=long int", + "__SIZEOF_DOUBLE__=4", + "__FLT_MIN_10_EXP__=(-37)", + "__UFRACT_EPSILON__=0x1P-16UR", + "__INT_LEAST32_WIDTH__=32", + "__BUILTIN_AVR_COUNTLSHK=1", + "__BUILTIN_AVR_COUNTLSHR=1", + "__INTMAX_TYPE__=long long int", + "__BUILTIN_AVR_ABSLLK=1", + "__BUILTIN_AVR_ABSLLR=1", + "__DEC128_MAX_EXP__=6145", + "__AVR_HAVE_16BIT_SP__=1", + "__ATOMIC_CONSUME=1", + "__GNUC_MINOR__=3", + "__INT_FAST16_WIDTH__=16", + "__UINTMAX_MAX__=0xffffffffffffffffULL", + "__DEC32_MANT_DIG__=7", + "__HA_FBIT__=7", + "__BUILTIN_AVR_COUNTLSLK=1", + "__BUILTIN_AVR_COUNTLSLR=1", + "__BUILTIN_AVR_CLI=1", + "__DBL_MAX_10_EXP__=38", + "__LDBL_DENORM_MIN__=1.40129846e-45L", + "__INT16_C(c)=c", + "__cpp_generic_lambdas=201304", + "__STDC__=1", + "__PTRDIFF_TYPE__=int", + "__LLFRACT_MIN__=(-0.5LLR-0.5LLR)", + "__BUILTIN_AVR_LRBITS=1", + "__ATOMIC_SEQ_CST=5", + "__DA_FBIT__=31", + "__UINT32_TYPE__=long unsigned int", + "__BUILTIN_AVR_ROUNDLLK=1", + "__UINTPTR_TYPE__=unsigned int", + "__BUILTIN_AVR_ROUNDLLR=1", + "__USA_IBIT__=16", + "__BUILTIN_AVR_ULRBITS=1", + "__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD", + "__DEC128_MANT_DIG__=34", + "__LDBL_MIN_10_EXP__=(-37)", + "__BUILTIN_AVR_COUNTLSUK=1", + "__BUILTIN_AVR_COUNTLSUR=1", + "__SIZEOF_LONG_LONG__=8", + "__ULACCUM_EPSILON__=0x1P-32ULK", + "__cpp_user_defined_literals=200809", + "__SACCUM_IBIT__=8", + "__GCC_ATOMIC_LLONG_LOCK_FREE=1", + "__LDBL_DIG__=6", + "__FLT_DECIMAL_DIG__=9", + "__UINT_FAST16_MAX__=0xffffU", + "__GCC_ATOMIC_SHORT_LOCK_FREE=1", + "__BUILTIN_AVR_ABSHK=1", + "__BUILTIN_AVR_FLASH_SEGMENT=1", + "__INT_LEAST64_WIDTH__=64", + "__ULLFRACT_MAX__=0XFFFFFFFFFFFFFFFFP-64ULLR", + "__UINT_FAST8_TYPE__=unsigned char", + "__USFRACT_EPSILON__=0x1P-8UHR", + "__ULACCUM_FBIT__=32", + "__QQ_IBIT__=0", + "__cpp_init_captures=201304", + "__ATOMIC_ACQ_REL=4", + "__ATOMIC_RELEASE=3", + "__BUILTIN_AVR_FMUL=1", + "USBCON" + ] } - ], - "version": 4 + ] } \ No newline at end of file From 735ae1d1337c04bef732261f518bc28526167417 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Wed, 31 Aug 2022 20:41:58 +0200 Subject: [PATCH 17/25] basic arduino main file --- arduino/arduino.ino | 81 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/arduino/arduino.ino b/arduino/arduino.ino index 95c2b6e..ae8b15b 100644 --- a/arduino/arduino.ino +++ b/arduino/arduino.ino @@ -1,9 +1,86 @@ +// options for both vs code and arduino IDE +//include arduino installed libs +#include +#include +#include +#include +// include local libs +#include "libs/SoftwareSerial/SoftwareSerial.h" +#include "libs/LiquidCrystal/LiquidCrystal.h" +#include "libs/ArduinoThread/Thread.h" +#include "libs/ArduinoThread/ThreadController.h" +//#include "src/LcdControl.h" + +/* +Pinmap: + - 1 LCD 1x 6 pins + - 2 software serial ports (one for each pi) 2x 2 pins + - 2 analog shunt voltage measurement pins 2x 1 pins + - 6 buttons for manual display and fan control 6x 1 pins + +Notepad: + + - serial message distributor: + - check recipiant of serial message and forward it to said device + + - collect data of package loss, respond times, etc... + - drive display (show stats such as cpu temps, cpu usage, system load, uptime, server status, power usage, etc.) + - accept button input from button panel + +*/ + +SoftwareSerial pi4(6, 7); // Softwareserial connection for Raspery Pi 4 +SoftwareSerial pi1(8, 9); // SoftwareSerial connection for Raspery Pi 1.2B+ + +LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Initialize the LCD displays + +ThreadController master = ThreadController(); // initialize ThreadController + +Thread serialhandler = Thread(); // initialize Thread for serial handler +Thread lcdcontrol = Thread(); // initialize Thread for lcd control +Thread telemetryhandler = Thread(); // initialize Thread for telemetry handler + void setup() { - // put your setup code here, to run once: + + lcd.begin(16, 2); // Set the LCD size to 16x2 + + Serial.begin(9600); // Serial connection for desktop + pi4.begin(9600); // SoftwareSerial connection for Raspery Pi 4 + pi1.begin(9600); // SoftwareSerial connection for Raspery Pi 1.2B+ + + serialhandler.setInterval(0); + serialhandler.onRun(serialDeliverThreadHandler); + + lcdcontrol.setInterval(100); + lcdcontrol.onRun(lcdControlThreadHandler); + + telemetryhandler.setInterval(1000); + telemetryhandler.onRun(telemetryThreadHandler); + + master.add(&serialhandler); // add serial handler to ThreadController + master.add(&lcdcontrol); // add lcd control to ThreadController + master.add(&telemetryhandler); // add telemetry handler to ThreadController + + + while (!Serial || !pi4 || !pi1) { + ; // wait for serial port to connect + } } void loop() { - // put your main code here, to run repeatedly: + master.run(); // run ThreadController } + + +void serialDeliverThreadHandler() { + Serial.println("serialDeliverThreadHandler"); +} + +void lcdControlThreadHandler() { + Serial.println("lcdControlThreadHandler"); +} +void telemetryThreadHandler() { + Serial.println("telemetryThreadHandler"); +} \ No newline at end of file From 40233de7f3859a876793d0cec961f1a8785fc250 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Wed, 31 Aug 2022 21:33:04 +0200 Subject: [PATCH 18/25] import cleanup --- arduino/arduino.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arduino/arduino.ino b/arduino/arduino.ino index ae8b15b..6277e04 100644 --- a/arduino/arduino.ino +++ b/arduino/arduino.ino @@ -9,7 +9,8 @@ #include "libs/LiquidCrystal/LiquidCrystal.h" #include "libs/ArduinoThread/Thread.h" #include "libs/ArduinoThread/ThreadController.h" -//#include "src/LcdControl.h" + +#include "src/SerialHandler.h" /* Pinmap: From 5891a1a9e3a74c4f65682d3d2c9f552305b8b4e1 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Thu, 1 Sep 2022 02:59:49 +0200 Subject: [PATCH 19/25] vs code extension update --- .vscode/c_cpp_properties.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index a72c8b4..2911f88 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -34,6 +34,7 @@ "/home/jonas_jones/.arduino15/packages/arduino/hardware/avr/1.8.5/variants/eightanaloginputs", "/home/jonas_jones/.arduino15/packages/arduino/hardware/avr/1.8.5/libraries/SoftwareSerial/src", "/home/jonas_jones/Arduino/libraries/LiquidCrystal/src", + "/home/jonas_jones/Arduino/libraries/ArduinoThread", "/home/jonas_jones/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/lib/gcc/avr/7.3.0/include", "/home/jonas_jones/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/lib/gcc/avr/7.3.0/include-fixed", "/home/jonas_jones/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/avr/include" From d1f04d141953bc489a952ddccf5be13d24ff62aa Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Thu, 1 Sep 2022 03:03:57 +0200 Subject: [PATCH 20/25] added links to different module README files --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 98d5541..1f4a438 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,13 @@ A system that allows Monitoring of Raspberry PI('s) PC and Mac as well as contro ## Why? The idea was to create software to allow the different components inside my diy Raspberry PI server rack to communicate which each other. This is done with serial connections as they are very easy to set up and use. +## Description +Each module has it's own `README.md` file. + + - [Arduino Module](https://github.com/J-onasJones/PI-server-rack/tree/main/arduino) + - [Desktop Module](https://github.com/J-onasJones/PI-server-rack/tree/main/desktop) + - [Raspberry PI master](https://github.com/J-onasJones/PI-server-rack/tree/main/pi-master) + - [Raspberry PI slave](https://github.com/J-onasJones/PI-server-rack/tree/main/pi-slave) + + //TODO: finish README From 58c0884c01cacf1d9c34a69774705c6625b2f834 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Thu, 1 Sep 2022 03:04:51 +0200 Subject: [PATCH 21/25] whoops markdown be farting hard --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1f4a438..f364167 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,10 @@ The idea was to create software to allow the different components inside my diy ## Description Each module has it's own `README.md` file. - - [Arduino Module](https://github.com/J-onasJones/PI-server-rack/tree/main/arduino) - - [Desktop Module](https://github.com/J-onasJones/PI-server-rack/tree/main/desktop) - - [Raspberry PI master](https://github.com/J-onasJones/PI-server-rack/tree/main/pi-master) - - [Raspberry PI slave](https://github.com/J-onasJones/PI-server-rack/tree/main/pi-slave) +- [Arduino Module](https://github.com/J-onasJones/PI-server-rack/tree/main/arduino) +- [Desktop Module](https://github.com/J-onasJones/PI-server-rack/tree/main/desktop) +- [Raspberry PI master](https://github.com/J-onasJones/PI-server-rack/tree/main/pi-master) +- [Raspberry PI slave](https://github.com/J-onasJones/PI-server-rack/tree/main/pi-slave) //TODO: finish README From 3c36a24c4ab2b2dc246a6040e6b298208b726192 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Sun, 4 Sep 2022 20:22:08 +0200 Subject: [PATCH 22/25] vscode file updates --- .vscode/c_cpp_properties.json | 1 + .vscode/settings.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 2911f88..bcc01d7 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -20,6 +20,7 @@ "name": "Arduino", "compilerPath": "/home/jonas_jones/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++", "compilerArgs": [ + "-w", "-std=gnu++11", "-fpermissive", "-fno-exceptions", diff --git a/.vscode/settings.json b/.vscode/settings.json index 691a8f6..b4aa6cd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "C_Cpp.errorSquiggles": "Disabled" + "C_Cpp.errorSquiggles": "Disabled", + "rust-analyzer.cargo.buildScripts.enable": true } \ No newline at end of file From 960bebd2f1b2d0b20d2f0663fa601b10c3c6ca95 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Sun, 4 Sep 2022 20:22:43 +0200 Subject: [PATCH 23/25] en_us lang file --- desktop/lang/en_us.json | 53 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 desktop/lang/en_us.json diff --git a/desktop/lang/en_us.json b/desktop/lang/en_us.json new file mode 100644 index 0000000..7fc4ab4 --- /dev/null +++ b/desktop/lang/en_us.json @@ -0,0 +1,53 @@ +{ + "language.name": "English", + "language.region": "United States", + "language.code": "en-US", + "app.name": "PI-server-rack-Config", + "app.description": "A ui based configuration program for the PI-server-rack", + "window.main.title": "PI-server-rack-Config", + "window.main.menu.file": "File", + "window.main.menu.file.new": "New", + "window.main.menu.file.open": "Open", + "window.main.menu.file.save": "Save", + "window.main.menu.file.saveas": "Save as", + "window.main.menu.file.quit": "Quit", + "window.main.menu.edit": "Edit", + "window.main.menu.edit.undo": "Undo", + "window.main.menu.edit.redo": "Redo", + "window.main.menu.edit.cut": "Cut", + "window.main.menu.edit.copy": "Copy", + "window.main.menu.edit.paste": "Paste", + "window.main.menu.edit.delete": "Delete", + "window.main.menu.edit.selectall": "Select all", + "window.main.menu.edit.find": "Find", + "window.main.menu.edit.findnext": "Find next", + "window.main.menu.edit.findprev": "Find previous", + "window.main.menu.edit.replace": "Replace", + "window.main.menu.edit.goto": "Goto", + "window.main.menu.edit.selectline": "Select line", + "window.main.menu.edit.selectword": "Select word", + "window.main.menu.edit.selectblock": "Select block", + "window.main.menu.edit.indent": "Indent", + "window.main.menu.edit.unindent": "Unindent", + "window.main.menu.edit.comment": "Comment", + "window.main.menu.edit.uncomment": "Uncomment", + "window.main.menu.view": "View", + "window.main.menu.view.fullscreen": "Fullscreen", + "window.main.menu.view.zoomin": "Zoom in", + "window.main.menu.view.zoomout": "Zoom out", + "window.main.menu.view.zoomreset": "Zoom reset", + "window.main.menu.preferences": "Preferences", + "window.main.menu.preferences.Settings": "Settings", + "window.main.menu.preferences.keybinds": "Keybinds", + "window.main.menu.help": "Help", + "window.main.menu.help.about": "About", + "window.main.menu.help.documentation": "Documentation", + "window.main.menu.help.tutorial": "Tutorial", + "window.main.menu.help.faq": "FAQ", + "window.main.menu.help.bugreport": "Bug report", + "window.main.menu.help.log": "Log", + "window.main.menu.help.log.clear": "Clear", + "window.main.menu.help.log.saveas": "Save as", + "window.main.tab.overview": "Overview", + "window.main.tab.settings.title": "Settings" +} \ No newline at end of file From 8d85068b483b6bafdd3e28c8a226813fe160ce10 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Sun, 4 Sep 2022 21:04:23 +0200 Subject: [PATCH 24/25] added rust target directory --- .gitignore | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d03f667..31a8824 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ # temporary files -tmp/ \ No newline at end of file +tmp/ + +# rust target +desktop/target/ +pi-master/target/ +pi-slave/target/ \ No newline at end of file From c60e0db035f7f1a80f3315b76d42a034f7bece86 Mon Sep 17 00:00:00 2001 From: Jonas_Jones Date: Sun, 4 Sep 2022 23:28:01 +0200 Subject: [PATCH 25/25] pushed some non functioning code --- arduino/src/LcdControl.cpp | 12 + arduino/src/LcdControl.h | 12 + arduino/src/SerialHandler.cpp | 11 + arduino/src/SerialHandler.h | 14 + desktop/Cargo.lock | 2166 +++++++++++++++++++++++++++++ desktop/Cargo.toml | 26 +- desktop/src/confighandler/mod.rs | 38 + desktop/src/defaultconfigs/mod.rs | 19 + desktop/src/langhandler.rs | 3 + desktop/src/main.rs | 19 +- desktop/src/ui/mod.rs | 53 + desktop/src/ui/tabs/mod.rs | 2 + desktop/src/ui/tabs/overview.rs | 0 desktop/src/ui/tabs/settings.rs | 0 14 files changed, 2364 insertions(+), 11 deletions(-) create mode 100644 arduino/src/LcdControl.cpp create mode 100644 arduino/src/LcdControl.h create mode 100644 arduino/src/SerialHandler.cpp create mode 100644 arduino/src/SerialHandler.h create mode 100644 desktop/Cargo.lock create mode 100644 desktop/src/confighandler/mod.rs create mode 100644 desktop/src/defaultconfigs/mod.rs create mode 100644 desktop/src/langhandler.rs create mode 100644 desktop/src/ui/mod.rs create mode 100644 desktop/src/ui/tabs/mod.rs create mode 100644 desktop/src/ui/tabs/overview.rs create mode 100644 desktop/src/ui/tabs/settings.rs diff --git a/arduino/src/LcdControl.cpp b/arduino/src/LcdControl.cpp new file mode 100644 index 0000000..a13a472 --- /dev/null +++ b/arduino/src/LcdControl.cpp @@ -0,0 +1,12 @@ +// #include "LcdControl.h" +// #include "LiquidCrystal.h" + +// //instance object +// LcdControl::LcdControl(LiquidCrystal lcd) { +// ; +// } + +// //when to update a cycle +// LcdControl::update() { +// ; +// } \ No newline at end of file diff --git a/arduino/src/LcdControl.h b/arduino/src/LcdControl.h new file mode 100644 index 0000000..ec44b7a --- /dev/null +++ b/arduino/src/LcdControl.h @@ -0,0 +1,12 @@ +// #ifndef LcdControl_h +// #define LcdControl_h + +// class LcdControl { + +// private: + +// public: + +// }; + +// #endif diff --git a/arduino/src/SerialHandler.cpp b/arduino/src/SerialHandler.cpp new file mode 100644 index 0000000..d1d37f6 --- /dev/null +++ b/arduino/src/SerialHandler.cpp @@ -0,0 +1,11 @@ +#include "SerialHandler.h" +#include "SoftwareSerial.h" + +SerialHandler::SerialHandler(uint8_t rx, uint8_t tx) { + update(); +} + +//Serialhandler loop +SerialHandler::update() { + ; +} \ No newline at end of file diff --git a/arduino/src/SerialHandler.h b/arduino/src/SerialHandler.h new file mode 100644 index 0000000..75c57f3 --- /dev/null +++ b/arduino/src/SerialHandler.h @@ -0,0 +1,14 @@ +//header file with the SerialHandler class +#ifndef SerialHandler_h +#define SerialHandler_h + +class SerialHandler { + + private: + + public: + SerialHandler(uint8_t rx, uint8_t tx); + void update(); +}; + +#endif \ No newline at end of file diff --git a/desktop/Cargo.lock b/desktop/Cargo.lock new file mode 100644 index 0000000..eaf241a --- /dev/null +++ b/desktop/Cargo.lock @@ -0,0 +1,2166 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ab_glyph" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04a9283dace1c41c265496614998d5b9c4a97b3eb770e804f007c5144bf03f2b" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "363b9b88fad3af3be80bc8f762c9a3f9dfe906fd0327b8e92f1c12e5ae1b8bbb" + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e6e951cfbb2db8de1828d49073a113a29fd7117b1596caa781a258c7e38d72" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "arboard" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc120354d1b5ec6d7aaf4876b602def75595937b5e15d356eb554ab5177e08bb" +dependencies = [ + "clipboard-win", + "log", + "objc", + "objc-foundation", + "objc_id", + "parking_lot", + "thiserror", + "winapi", + "x11rb", +] + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "async-trait" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic_refcell" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b5e5f48b927f04e952dedc932f31995a65a0bf65ec971c74436e51bf6e970d" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" + +[[package]] +name = "bytemuck" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9e1f5fa78f69496407a27ae9ed989e3c3b072310286f5ef385525e4cbc24a9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "bytes" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" + +[[package]] +name = "calloop" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22a6a8f622f797120d452c630b0ab12e1331a1a753e2039ce7868d4ac77b4ee" +dependencies = [ + "log", + "nix 0.24.2", + "slotmap", + "thiserror", + "vec_map", +] + +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cgl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +dependencies = [ + "libc", +] + +[[package]] +name = "clipboard-win" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4ab1b92798304eedc095b53942963240037c0516452cb11aeba709d420b2219" +dependencies = [ + "error-code", + "str-buf", + "winapi", +] + +[[package]] +name = "cmake" +version = "0.1.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" +dependencies = [ + "cc", +] + +[[package]] +name = "cocoa" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" +dependencies = [ + "bitflags", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types 0.3.2", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +dependencies = [ + "bitflags", + "block", + "core-foundation", + "core-graphics-types", + "foreign-types 0.3.2", + "libc", + "objc", +] + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "config" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f1667b8320afa80d69d8bbe40830df2c8a06003d86f73d8e003b2c48df416d" +dependencies = [ + "async-trait", + "json5", + "lazy_static", + "nom", + "pathdiff", + "ron", + "rust-ini", + "serde", + "serde_json", + "toml", + "yaml-rust", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags", + "core-foundation", + "core-graphics-types", + "foreign-types 0.3.2", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types 0.3.2", + "libc", +] + +[[package]] +name = "core-text" +version = "19.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25" +dependencies = [ + "core-foundation", + "core-graphics", + "foreign-types 0.3.2", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc948ebb96241bb40ab73effeb80d9f93afaad49359d159a5e61be51619fe813" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossfont" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f66b1c1979c4362323f03ab6bf7fb522902bfc418e0c37319ab347f9561d980f" +dependencies = [ + "cocoa", + "core-foundation", + "core-foundation-sys", + "core-graphics", + "core-text", + "dwrote", + "foreign-types 0.5.0", + "freetype-rs", + "libc", + "log", + "objc", + "once_cell", + "pkg-config", + "servo-fontconfig", + "winapi", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "deflate" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" +dependencies = [ + "adler32", +] + +[[package]] +name = "desktop" +version = "0.1.0" +dependencies = [ + "config", + "dirs", + "eframe", + "log", + "serde", + "serde_derive", + "serde_json", + "try-catch", +] + +[[package]] +name = "digest" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dlib" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" +dependencies = [ + "libloading", +] + +[[package]] +name = "dlv-list" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "dwrote" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" +dependencies = [ + "lazy_static", + "libc", + "serde", + "serde_derive", + "winapi", + "wio", +] + +[[package]] +name = "eframe" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d49426c3e72a6728b0c790d22db8bf7bbcff10d83b8b6f3a01295be982302e" +dependencies = [ + "bytemuck", + "egui", + "egui-winit", + "egui_glow", + "getrandom", + "glow", + "glutin", + "js-sys", + "percent-encoding", + "tracing", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winit", +] + +[[package]] +name = "egui" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc9fcd393c3daaaf5909008a1d948319d538b79c51871e4df0993260260a94e4" +dependencies = [ + "ahash 0.8.0", + "epaint", + "nohash-hasher", + "tracing", +] + +[[package]] +name = "egui-winit" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ddc525334c416e11580123e147b970f738507f427c9fb1cd09ea2dd7416a3a" +dependencies = [ + "arboard", + "egui", + "instant", + "smithay-clipboard", + "tracing", + "webbrowser", + "winit", +] + +[[package]] +name = "egui_glow" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad77d4a00402bae9658ee64be148f4b2a0b38e4fc7874970575ca01ed1c5b75d" +dependencies = [ + "bytemuck", + "egui", + "glow", + "memoffset", + "tracing", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "emath" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9542a40106fdba943a055f418d1746a050e1a903a049b030c2b097d4686a33cf" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "epaint" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ba04741be7f6602b1a1b28f1082cce45948a7032961c52814f8946b28493300" +dependencies = [ + "ab_glyph", + "ahash 0.8.0", + "atomic_refcell", + "bytemuck", + "emath", + "nohash-hasher", + "parking_lot", +] + +[[package]] +name = "error-code" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21" +dependencies = [ + "libc", + "str-buf", +] + +[[package]] +name = "expat-sys" +version = "2.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa" +dependencies = [ + "cmake", + "pkg-config", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8469d0d40519bc608ec6863f1cc88f3f1deee15913f2f3b3e573d81ed38cccc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "freetype-rs" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74eadec9d0a5c28c54bb9882e54787275152a4e36ce206b45d7451384e5bf5fb" +dependencies = [ + "bitflags", + "freetype-sys", + "libc", +] + +[[package]] +name = "freetype-sys" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" +dependencies = [ + "cmake", + "libc", + "pkg-config", +] + +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "getrandom" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glow" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8bd5877156a19b8ac83a29b2306fe20537429d318f3ff0a1a2119f8d9c61919" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444c9ad294fdcaf20ccf6726b78f380b5450275540c9b68ab62f49726ad1c713" +dependencies = [ + "cgl", + "cocoa", + "core-foundation", + "glutin_egl_sys", + "glutin_gles2_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading", + "log", + "objc", + "once_cell", + "osmesa-sys", + "parking_lot", + "raw-window-handle 0.5.0", + "wayland-client", + "wayland-egl", + "winapi", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68900f84b471f31ea1d1355567eb865a2cf446294f06cef8d653ed7bcf5f013d" +dependencies = [ + "gl_generator", + "winapi", +] + +[[package]] +name = "glutin_gles2_sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094e708b730a7c8a1954f4f8a31880af00eb8a1c5b5bf85d28a0a3c6d69103" +dependencies = [ + "gl_generator", + "objc", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93d0575865098580c5b3a423188cd959419912ea60b1e48e8b3b526f6d02468" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da5951a1569dbab865c6f2a863efafff193a93caf05538d193e9e3816d21696" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "itoa" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" + +[[package]] +name = "jni" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "js-sys" +version = "0.3.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" + +[[package]] +name = "libloading" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "lock_api" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memmap2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys", +] + +[[package]] +name = "ndk" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2032c77e030ddee34a6787a64166008da93f6a352b629261d0fee232b8742dd4" +dependencies = [ + "bitflags", + "jni-sys", + "ndk-sys 0.3.0", + "num_enum", + "thiserror", +] + +[[package]] +name = "ndk" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +dependencies = [ + "bitflags", + "jni-sys", + "ndk-sys 0.4.0", + "num_enum", + "raw-window-handle 0.5.0", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-glue" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d0c4a7b83860226e6b4183edac21851f05d5a51756e97a1144b7f5a6b63e65f" +dependencies = [ + "lazy_static", + "libc", + "log", + "ndk 0.6.0", + "ndk-context", + "ndk-macro", + "ndk-sys 0.3.0", +] + +[[package]] +name = "ndk-glue" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0434fabdd2c15e0aab768ca31d5b7b333717f03cf02037d5a0a3ff3c278ed67f" +dependencies = [ + "libc", + "log", + "ndk 0.7.0", + "ndk-context", + "ndk-macro", + "ndk-sys 0.4.0", + "once_cell", + "parking_lot", +] + +[[package]] +name = "ndk-macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c" +dependencies = [ + "darling", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ndk-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5a6ae77c8ee183dcbbba6150e2e6b9f3f4196a7666c02a715a95692ec1fa97" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "ndk-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21d83ec9c63ec5bf950200a8e508bdad6659972187b625469f58ef8c08e29046" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nix" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "nix" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num_enum" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "once_cell" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" + +[[package]] +name = "ordered-multimap" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" +dependencies = [ + "dlv-list", + "hashbrown", +] + +[[package]] +name = "osmesa-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b" +dependencies = [ + "shared_library", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e6affeb1632d6ff6a23d2cd40ffed138e82f1532571a26f527c8a284bb2fbb" +dependencies = [ + "ttf-parser", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pest" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b0560d531d1febc25a3c9398a62a71256c0178f2e3443baedd9ad4bb8c9deb4" +dependencies = [ + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "905708f7f674518498c1f8d644481440f476d39ca6ecae83319bba7c6c12da91" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5803d8284a629cc999094ecd630f55e91b561a1d1ba75e233b00ae13b91a69ad" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1538eb784f07615c6d9a8ab061089c6c54a344c5b4301db51990ca1c241e8c04" +dependencies = [ + "once_cell", + "pest", + "sha-1", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pkg-config" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" + +[[package]] +name = "png" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc38c0ad57efb786dd57b9864e5b18bae478c00c824dc55a38bbc9da95dde3ba" +dependencies = [ + "bitflags", + "crc32fast", + "deflate", + "miniz_oxide", +] + +[[package]] +name = "proc-macro-crate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" +dependencies = [ + "once_cell", + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "raw-window-handle" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" +dependencies = [ + "cty", +] + +[[package]] +name = "raw-window-handle" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7e3d950b66e19e0c372f3fa3fbbcf85b1746b571f74e0c2af6042a5c93420a" +dependencies = [ + "cty", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + +[[package]] +name = "ron" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" +dependencies = [ + "base64", + "bitflags", + "serde", +] + +[[package]] +name = "rust-ini" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "safe_arch" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ff3d6d9696af502cc3110dacce942840fb06ff4514cad92236ecc455f2ce05" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "sctk-adwaita" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04b7c47a572f73de28bee5b5060d085b42b6ce1e4ee2b49c956ea7b25e94b6f0" +dependencies = [ + "crossfont", + "log", + "smithay-client-toolkit", + "tiny-skia", +] + +[[package]] +name = "serde" +version = "1.0.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "servo-fontconfig" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e3e22fe5fd73d04ebf0daa049d3efe3eae55369ce38ab16d07ddd9ac5c217c" +dependencies = [ + "libc", + "servo-fontconfig-sys", +] + +[[package]] +name = "servo-fontconfig-sys" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36b879db9892dfa40f95da1c38a835d41634b825fbd8c4c418093d53c24b388" +dependencies = [ + "expat-sys", + "freetype-sys", + "pkg-config", +] + +[[package]] +name = "sha-1" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shared_library" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "slotmap" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" + +[[package]] +name = "smithay-client-toolkit" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f307c47d32d2715eb2e0ece5589057820e0e5e70d07c247d1063e844e107f454" +dependencies = [ + "bitflags", + "calloop", + "dlib", + "lazy_static", + "log", + "memmap2", + "nix 0.24.2", + "pkg-config", + "wayland-client", + "wayland-cursor", + "wayland-protocols", +] + +[[package]] +name = "smithay-clipboard" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" +dependencies = [ + "smithay-client-toolkit", + "wayland-client", +] + +[[package]] +name = "str-buf" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d0a539a918745651435ac7db7a18761589a94cd7e94cd56999f828bf73c8a57" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c251e90f708e16c49a16f4917dc2131e75222b72edfa9cb7f7c58ae56aae0c09" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tiny-skia" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "642680569bb895b16e4b9d181c60be1ed136fa0c9c7f11d004daf053ba89bf82" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "png", + "safe_arch", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c114d32f0c2ee43d585367cb013dfaba967ab9f62b90d9af0d696e955e70fa6c" +dependencies = [ + "arrayref", + "bytemuck", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "tracing" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-catch" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ac07b511057dbab5380dbd9be97b8375c577136d45db42b63d039c83e54630" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ttf-parser" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd" + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "ucd-trie" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" + +[[package]] +name = "unicode-bidi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" + +[[package]] +name = "unicode-normalization" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" + +[[package]] +name = "wayland-client" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" +dependencies = [ + "bitflags", + "downcast-rs", + "libc", + "nix 0.24.2", + "scoped-tls", + "wayland-commons", + "wayland-scanner", + "wayland-sys", +] + +[[package]] +name = "wayland-commons" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" +dependencies = [ + "nix 0.24.2", + "once_cell", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-cursor" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" +dependencies = [ + "nix 0.24.2", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-egl" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402de949f81a012926d821a2d659f930694257e76dd92b6e0042ceb27be4107d" +dependencies = [ + "wayland-client", + "wayland-sys", +] + +[[package]] +name = "wayland-protocols" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" +dependencies = [ + "bitflags", + "wayland-client", + "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" +dependencies = [ + "proc-macro2", + "quote", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" +dependencies = [ + "dlib", + "lazy_static", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webbrowser" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a3cffdb686fbb24d9fb8f03a213803277ed2300f11026a3afe1f108dc021b" +dependencies = [ + "jni", + "ndk-glue 0.6.2", + "url", + "web-sys", + "widestring", + "winapi", +] + +[[package]] +name = "widestring" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-wsapoll" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "winit" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a8f3e9d742401efcfe833b8f84960397482ff049cb7bf59a112e14a4be97f7" +dependencies = [ + "bitflags", + "cocoa", + "core-foundation", + "core-graphics", + "dispatch", + "instant", + "libc", + "log", + "mio", + "ndk 0.7.0", + "ndk-glue 0.7.0", + "objc", + "once_cell", + "parking_lot", + "percent-encoding", + "raw-window-handle 0.4.3", + "raw-window-handle 0.5.0", + "sctk-adwaita", + "smithay-client-toolkit", + "wasm-bindgen", + "wayland-client", + "wayland-protocols", + "web-sys", + "windows-sys", + "x11-dl", +] + +[[package]] +name = "wio" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" +dependencies = [ + "winapi", +] + +[[package]] +name = "x11-dl" +version = "2.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c83627bc137605acc00bb399c7b908ef460b621fc37c953db2b09f88c449ea6" +dependencies = [ + "lazy_static", + "libc", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e99be55648b3ae2a52342f9a870c0e138709a3493261ce9b469afe6e4df6d8a" +dependencies = [ + "gethostname", + "nix 0.22.3", + "winapi", + "winapi-wsapoll", +] + +[[package]] +name = "xcursor" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" +dependencies = [ + "nom", +] + +[[package]] +name = "xml-rs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] diff --git a/desktop/Cargo.toml b/desktop/Cargo.toml index 0e062bc..8a9fc0f 100644 --- a/desktop/Cargo.toml +++ b/desktop/Cargo.toml @@ -1,17 +1,25 @@ [package] name = "desktop" version = "0.1.0" -authors = "Jonas_Jones" +#authors = ["Jonas_Jones"] edition = "2021" -description = "The desktop module of the PI-server-rack project." -documentation = "https://github.com/JonasJones/PI-server-rack" -readme = "README.md" -homepage = "https://jonasjones.me/PI-server-rack" -repository = "https://github.com/J-onasJones/PI-server-rack" -license = "MIT OR Apache-2.0" -keywords = ["server", "raspberry pi"] -categories = ["config"] +#description = "The desktop module of the PI-server-rack project." +#documentation = "https://github.com/JonasJones/PI-server-rack" +#readme = "README.md" +#homepage = "https://jonasjones.me/PI-server-rack" +#repository = "https://github.com/J-onasJones/PI-server-rack" +#license = "MIT OR Apache-2.0" +#keywords = ["server", "raspberry pi"] +#categories = ["config"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +eframe = "0.19.0" +try-catch = "0.2.2" +serde = "1.0.144" +serde_json = "1.0.85" +serde_derive = "1.0.144" +config = "0.13.2" +log = "0.4.17" +dirs = "4.0.0" \ No newline at end of file diff --git a/desktop/src/confighandler/mod.rs b/desktop/src/confighandler/mod.rs new file mode 100644 index 0000000..02ec62d --- /dev/null +++ b/desktop/src/confighandler/mod.rs @@ -0,0 +1,38 @@ +use std::{fs::File, io::Read}; +use try_catch::catch; +use serde_json::from_str; +use defaultconfigs::Mainconfig; + +use crate::defaultconfigs::{self, CONFIG_PATH}; + +extern crate serde; +extern crate serde_json; + +pub(crate) fn init() { + catch! { + try { + load() + } catch _error { + create() + } + } +} + +fn load() { + // Load the config file + let mut file = File::open(CONFIG_PATH).unwrap(); + let mut contents = String::new(); + file.read_to_string(&mut contents).unwrap(); + let config: Mainconfig = from_str(&contents).unwrap(); + println!("{:?}", config); +} + +fn create() { + // Create the config file + +} + +fn save() { + // Save the config file + +} \ No newline at end of file diff --git a/desktop/src/defaultconfigs/mod.rs b/desktop/src/defaultconfigs/mod.rs new file mode 100644 index 0000000..2cdf3e7 --- /dev/null +++ b/desktop/src/defaultconfigs/mod.rs @@ -0,0 +1,19 @@ +use std::path::{PathBuf}; + +use serde::{Serialize, Deserialize}; +use dirs::config_dir; + +const SYSTEM_CONFIG_PATH: Option = config_dir(); +const RELATIVE_CONFIG_PATH: &str = "/pi-server-rack/config.json"; + +pub(crate) const VERSION: &str = env!("CARGO_PKG_VERSION"); + +pub(crate) const CONFIG_PATH: PathBuf= SYSTEM_CONFIG_PATH.push(RELATIVE_CONFIG_PATH); //TODO: not die from fucking rust paths + +#[derive(Serialize, Deserialize, Debug)] +pub(crate) struct Mainconfig { + lang : String, + configpath : String, + customwindowframe : bool, + +} \ No newline at end of file diff --git a/desktop/src/langhandler.rs b/desktop/src/langhandler.rs new file mode 100644 index 0000000..4b71823 --- /dev/null +++ b/desktop/src/langhandler.rs @@ -0,0 +1,3 @@ +fn load() { + // Load the language file +} \ No newline at end of file diff --git a/desktop/src/main.rs b/desktop/src/main.rs index e7a11a9..9209ee8 100644 --- a/desktop/src/main.rs +++ b/desktop/src/main.rs @@ -1,3 +1,18 @@ +//import ui +mod ui; +pub(crate) mod confighandler; +pub(crate) mod defaultconfigs; + +use defaultconfigs::VERSION; + +use log::{info}; + fn main() { - println!("Hello, world!"); -} + info!(target: "[THREAD-MAIN]", "Welcome to PI-Server-Rack v{} !", VERSION); + //initialize config + confighandler::init(); + + + //initialiaze ui + ui::mainloop(); +} \ No newline at end of file diff --git a/desktop/src/ui/mod.rs b/desktop/src/ui/mod.rs new file mode 100644 index 0000000..a68c054 --- /dev/null +++ b/desktop/src/ui/mod.rs @@ -0,0 +1,53 @@ +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release + +pub(crate) mod tabs; + +extern crate eframe; +use eframe::egui; + +pub(crate) fn mainloop() { + let options = eframe::NativeOptions::default(); + eframe::run_native( + "Confirm exit", + options, + Box::new(|_cc| Box::new(RootWindow::default())), + ); +} + +#[derive(Default)] +struct RootWindow { + allowed_to_close: bool, + show_confirmation_dialog: bool, +} + +impl eframe::App for RootWindow { + fn on_close_event(&mut self) -> bool { + self.show_confirmation_dialog = true; + self.allowed_to_close + } + + fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) { + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("Try to close the window"); + }); + + if self.show_confirmation_dialog { + // Show confirmation dialog: + egui::Window::new("Do you want to quit?") + .collapsible(false) + .resizable(false) + .show(ctx, |ui| { + ui.horizontal(|ui| { + if ui.button("Cancel").clicked() { + self.show_confirmation_dialog = false; + } + + if ui.button("Yes!").clicked() { + self.allowed_to_close = true; + frame.close(); + } + }); + }); + } + } +} \ No newline at end of file diff --git a/desktop/src/ui/tabs/mod.rs b/desktop/src/ui/tabs/mod.rs new file mode 100644 index 0000000..bde4cd8 --- /dev/null +++ b/desktop/src/ui/tabs/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod overview; +pub(crate) mod settings; \ No newline at end of file diff --git a/desktop/src/ui/tabs/overview.rs b/desktop/src/ui/tabs/overview.rs new file mode 100644 index 0000000..e69de29 diff --git a/desktop/src/ui/tabs/settings.rs b/desktop/src/ui/tabs/settings.rs new file mode 100644 index 0000000..e69de29