diff --git a/README.md b/README.md
index f5e2c87..00a7af4 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,7 @@
- pyserial
- wxPython
- PlatformIO IDE, which could be downloaded as an extension in vs code
+- ESP32 WROOM-32 Development Board
### Recommended
- Code Runner (for VSCode only)
- wxFormBuilder
@@ -15,28 +16,32 @@
## How to use
### Direct use
- First download the `.ino` file from `ReadRaw` folder using Arduino IDE. Or if you are using Arduino Mega 2560 you can
-use the code in `ReadAnalog` folder by open the folder in VSCode and run with PlatformIO, or just run `flash.py` in a terminal
-Then you can just run `python toplevel.py` and start from the UI. Enter the relevant information and start collect and measuring data.
+ First download the `.ino` file from `espVoltmeter` folder using Arduino IDE. ~~Or if you are using Arduino Mega 2560 you can
+use the code in `ReadAnalog` folder by open the folder in VSCode and run with PlatformIO, or just run `flash.py` in a terminal~~
+ (Arduino Mega and Uno boards are no longer supported. Please use [this link](https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html) to
+ use on Arduino IDE or PlatformIO for VSCode)
+Then you can just run `python test.py` and start from the UI. Enter the relevant information and start collect and measuring data.
### develop & build
Beside the c-based code for the Arduino board to read raw data from the board, everything has now been done in the python
-files. The main program is `toplevel.py`, which calls `UI.py` to prompt for input. It is NOT recommended modifying the `ui.py`
+files. The main program is `test.py`, which calls `UI.py` to prompt for input. It is NOT recommended modifying the `ui.py`
as it is generated from wxFormBuilder from `sealammonia.fbp`, which could be modified if any frontend feature need to change.
the main program will generate `settings.json` which saves all required parameters needed to calculate and graph and save the
sensor's values. It also creates a .csv file under `RecordedData` directory to save all recorded+calculated data.
`read_arduino.pyw` read raw data from Arduino board and convert it to the correct resistance, which could be plotted out
using `serial_plot.pyw`. Note that all .pyw are still Python files and should be correctly opened using any IDE/text edtiors
-as .py file does, except not going to pop up a black terminal when running directly. `test.py` is the alternative version of the frontend writting using `tkinter`.
+as .py file does, except not going to pop up a black terminal when running directly. `frontend.py` is the alternative version of the frontend writting using `tkinter`
+and is not longer supported.
## Issues
-- Currently can only use 5V as input voltage. May need to change the algorithm in `read_arduino.py`. Newer hardware will require 3.3V.
+- Newer hardware will require 3.3V. ~~Currently can only use 5V as input voltage.~~ May need to change the algorithm in `read_arduino.py`.
- Should call `writerandomvalues.py` to simulate Arduino data when nothing is connected but user still want to run. Currently just pop up error(fixed)
- "plot" button is completely disabled, should be enabled whenever is not plotting but is reading data
- Matplotlib cannot really run in multithread, this might going to be an issue for packing the program into an executable
- Csv file is only created after you close the UI
-## Todos & [Specs](https://docs.google.com/document/d/1Km2HZel7rILOvgHG5iXlUcXFx4Of1ot2I7Dbnq8aTwY/edit?usp=sharing):
+## Todos & [Old Specs](https://docs.google.com/document/d/1Km2HZel7rILOvgHG5iXlUcXFx4Of1ot2I7Dbnq8aTwY/edit?usp=sharing):
- [ ] Fix Issues
+- [ ] Automatically setup the driver for ESP32
- [ ] display sensor value in either the UI or on the plot
- [ ] Reopen plot window from the UI when closed
- [x] Need to continue writing to file when graphing window is closed
@@ -48,6 +53,7 @@ as .py file does, except not going to pop up a black terminal when running direc
- [x] Write random values to simulate a sensor if no sensor available (this feature might be removed in the future)
- [ ] Advanced option menu in the UI to allow user to make more adjustments
- [ ] Add resolution option in the UI to allow interchange between arduino (10bit) and esp32 (12 bits)
-- [ ] Possibly adding new module to support ESP32
-- [ ] Support for non-Windows platforms
+- [x] Possibly adding new module to support ESP32
+- [ ] Support for non-Windows platforms (and maybe mobile)
- [ ] Make it into one executable
+- [ ] Possibly adding new module to support Arduino MEGA and older firmwares
diff --git a/__pycache__/read_arduino.cpython-39.pyc b/__pycache__/read_arduino.cpython-39.pyc
new file mode 100644
index 0000000..d00f49c
Binary files /dev/null and b/__pycache__/read_arduino.cpython-39.pyc differ
diff --git a/__pycache__/serial_plot.cpython-39.pyc b/__pycache__/serial_plot.cpython-39.pyc
new file mode 100644
index 0000000..4a91683
Binary files /dev/null and b/__pycache__/serial_plot.cpython-39.pyc differ
diff --git a/__pycache__/ui.cpython-39.pyc b/__pycache__/ui.cpython-39.pyc
new file mode 100644
index 0000000..dc99c7c
Binary files /dev/null and b/__pycache__/ui.cpython-39.pyc differ
diff --git a/espVoltmeter/espVoltmeter.ino b/espVoltmeter/espVoltmeter.ino
new file mode 100644
index 0000000..7b362b1
--- /dev/null
+++ b/espVoltmeter/espVoltmeter.ino
@@ -0,0 +1,57 @@
+// manually define all the An ports on ESP32 board
+#if defined(ESP32)
+#define A0 (36)
+#define A1 (39)
+#define A2 (34)
+#define A3 (35)
+#define A4 (32)
+#define A5 (33)
+#endif
+
+// define the divident of sizeof()'s return value
+#if defined(ESP32)
+#define SIZE_DIV 4 // for esp32, the resolution is doubled than the usual arduino board, so we double the factor, too
+#else
+#define SIZE_DIV 2
+#endif
+#define WAIT_TIME 1000UL
+#define SENSOR1 36
+// FILE *f = fopen("file.txt", "w");
+int pins[] = {A0, A1, A2, A3, A4, A5};
+int i, j;
+unsigned long currTime; // non-blocking time tracker
+
+void setup() {
+ Serial.begin(19200);
+ currTime = millis();
+ analogReadResolution(12);
+ // adcAttachPin(A0);
+ // analogSetClockDiv(255);
+
+}
+
+void loop() {
+ // we might need analogSetAttenuation to make the measurement more accurate and less noisy?
+ if (millis() - currTime >= WAIT_TIME) { // non-blocking time delay
+ // Serial.println();
+ Serial.print("[");
+ for (i = 0; i < sizeof(pins)/SIZE_DIV; i++) {
+
+ // float volts = analogRead(pins[i]);
+ // float result = volts * 3.3 / 4095;
+ // Serial.print(result);
+
+ float volts = analogReadMilliVolts(pins[i]);
+ Serial.print(volts);
+ // Serial.print(61319 * (3.3/volts - 1));
+ if (i != sizeof(pins)/SIZE_DIV - 1) {
+ Serial.print(", ");
+ }
+
+ }
+ Serial.println("]");
+ // Serial.println(analogReadMilliVolts(SENSOR1));
+ currTime = millis();
+ }
+
+}
\ No newline at end of file
diff --git a/read_arduino.py b/read_arduino.py
new file mode 100644
index 0000000..919fe9b
--- /dev/null
+++ b/read_arduino.py
@@ -0,0 +1,54 @@
+"""
+ Read raw data from Arduino and then converted into actual resistance using parameters provided from top level
+"""
+from datetime import datetime
+import serial, os, json
+import serial.tools.list_ports
+import numpy as np
+
+# constant settings
+SENSORS_MAX = 4 # maximum sensor ports
+
+def read():
+ baud = 19200
+ settings = json.load(open('settings.json', 'r'))
+ resolution = settings["resolution"] # this is not in use, but just in case if we decide to switch back to analogRead() instead of ESP32's analogReadMiliVolts() on the firmware
+ v_in = settings["v_in"]
+ refRes = np.array(settings["refRes"])
+ sensor_ports = np.array(settings["sensor_ports"]) # ports that sensor(s) are connected to
+ file_name = settings["file_name"]
+ port = settings["port"]
+ if "- No Device -" in port:
+ # TODO: set to writerandomvalues.py thing instead raise error
+ print("this should generate random values base on # sensors given")
+ exit(0)
+ else:
+ controller = serial.Serial(port, baudrate=baud)
+
+ if np.any(sensor_ports >= SENSORS_MAX):
+ raise ValueError("Port range is 0-3!")
+
+ # TODO: separate data in each run but still keep them in one csv file
+ while controller.isOpen():
+ try:
+ read_data = controller.readline().decode("utf-8")
+ # use numpy so it can make list calculations easier (and possibly faster)
+ dat_list = np.asarray(json.loads(read_data), dtype=np.uint32)[:SENSORS_MAX]
+
+ # if we decided to switch back to analogRead(), replace this line of comment to the algorithm to something like the commented line below
+ # dat_sel = np.take(dat_list, sensor_ports) * v_in / resolution
+
+ # take only the nonzero indices, and truncated to two decimal places to "filter" out some hardware errors
+ dat_sel = np.trunc((np.take(dat_list, sensor_ports) / 1000) * 10**2) / 10**2
+ r_arr = np.take(refRes, sensor_ports) * (v_in / dat_sel - 1)
+ # write + export values as .csv format
+ dat = f", ".join(np.insert(r_arr.astype(str), 0, datetime.now().strftime('%H:%M:%S')))
+ print(dat)
+ f = open(file_name, "a", newline="", encoding="utf-8")
+ f.write(dat + '\n')
+ f.close()
+ # except KeyboardInterrupt as e:
+ # print(e.__class__.__name__)
+ # break
+ except (json.decoder.JSONDecodeError, UnicodeDecodeError):
+ print('decoder error')
diff --git a/read_arduino.pyw b/read_arduino.pyw
deleted file mode 100644
index a318b39..0000000
--- a/read_arduino.pyw
+++ /dev/null
@@ -1,49 +0,0 @@
-"""
- Read raw data from Arduino and then converted into actual resistance using parameters provided from top level
-"""
-from datetime import datetime
-import serial, os, json
-import serial.tools.list_ports
-import numpy as np
-
-# constant settings
-SENSORS_MAX = 4 # maximum sensor ports
-baud = 19200
-
-settings = json.load(open('settings.json', 'r'))
-resolution = settings["resolution"]
-v_src = settings["v_src"]
-v_in = settings["v_in"]
-refRes = np.array(settings["refRes"])
-sensor_ports = np.array(settings["sensor_ports"]) # ports that sensor(s) are connected to
-file_name = settings["file_name"]
-port = settings["port"]
-if "- No Device -" in port:
- # TODO: set to writerandomvalues.py thing instead raise error
- print("this should generate random values base on # sensors given")
- exit(0)
-else:
- controller = serial.Serial(port, baudrate=baud)
-
-if np.any(sensor_ports >= SENSORS_MAX):
- raise ValueError("Port range is 0-3!")
-
-# TODO: separate data in each run but still keep them in one csv file
-while controller.isOpen():
- try:
- read_data = controller.readline().decode("utf-8")
- # use numpy so it can make list calculations easier (and possibly faster)
- dat_list = np.asarray(json.loads(read_data), dtype=np.int16)[:SENSORS_MAX]
- dat_sel = np.take(dat_list, sensor_ports) * v_in / resolution
- r_arr = np.take(refRes, sensor_ports) * (v_in / dat_sel - 1)
- # write + export values as .csv format
- dat = f", ".join(np.insert(r_arr.astype(str), 0, datetime.now().strftime('%H:%M:%S')))
- print(dat)
- f = open(file_name, "a", newline="", encoding="utf-8")
- f.write(dat + '\n')
- f.close()
- # except KeyboardInterrupt as e:
- # print(e.__class__.__name__)
- # break
- except json.decoder.JSONDecodeError:
- print('decoder error')
diff --git a/sealammonia.fbp b/sealammonia.fbp
index 0a3328a..af73cfe 100644
--- a/sealammonia.fbp
+++ b/sealammonia.fbp
@@ -507,7 +507,7 @@
wxFILTER_NONEwxDefaultValidator
-
+ 0
@@ -598,7 +598,7 @@
wxFILTER_NONEwxDefaultValidator
-
+ 0
@@ -689,7 +689,7 @@
wxFILTER_NONEwxDefaultValidator
-
+ 0
@@ -780,7 +780,7 @@
wxFILTER_NONEwxDefaultValidator
-
+ 0
@@ -823,7 +823,7 @@
1