commit 8bede8e74ebd642e791c7c562bdb6ef90d51580d Author: YuruC3 <98943911+YuruC3@@users.noreply.github.com> Date: Thu May 8 09:39:22 2025 +0200 Added stuff. diff --git a/STM32_MD1200_FAN-CONTROL/.gitignore b/STM32_MD1200_FAN-CONTROL/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/STM32_MD1200_FAN-CONTROL/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/STM32_MD1200_FAN-CONTROL/.vscode/extensions.json b/STM32_MD1200_FAN-CONTROL/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/STM32_MD1200_FAN-CONTROL/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/STM32_MD1200_FAN-CONTROL/STM32F103C6T6.jpg b/STM32_MD1200_FAN-CONTROL/STM32F103C6T6.jpg new file mode 100644 index 0000000..4c1d568 Binary files /dev/null and b/STM32_MD1200_FAN-CONTROL/STM32F103C6T6.jpg differ diff --git a/STM32_MD1200_FAN-CONTROL/STM32F103C8T6.webp b/STM32_MD1200_FAN-CONTROL/STM32F103C8T6.webp new file mode 100644 index 0000000..fb23bff Binary files /dev/null and b/STM32_MD1200_FAN-CONTROL/STM32F103C8T6.webp differ diff --git a/STM32_MD1200_FAN-CONTROL/include/README b/STM32_MD1200_FAN-CONTROL/include/README new file mode 100644 index 0000000..49819c0 --- /dev/null +++ b/STM32_MD1200_FAN-CONTROL/include/README @@ -0,0 +1,37 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the convention is to give header files names that end with `.h'. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/STM32_MD1200_FAN-CONTROL/lib/README b/STM32_MD1200_FAN-CONTROL/lib/README new file mode 100644 index 0000000..9379397 --- /dev/null +++ b/STM32_MD1200_FAN-CONTROL/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into the executable file. + +The source code of each library should be placed in a separate directory +("lib/your_library_name/[Code]"). + +For example, see the structure of the following example libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +Example contents of `src/main.c` using Foo and Bar: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +The PlatformIO Library Dependency Finder will find automatically dependent +libraries by scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/STM32_MD1200_FAN-CONTROL/other/_devils_boot_AKAcommands.md b/STM32_MD1200_FAN-CONTROL/other/_devils_boot_AKAcommands.md new file mode 100644 index 0000000..36e92cb --- /dev/null +++ b/STM32_MD1200_FAN-CONTROL/other/_devils_boot_AKAcommands.md @@ -0,0 +1,137 @@ +``` +BlueDress.105.001 >_devils +_boot Download the boot image (FW image 1 and 2 erased) +_clrphyerr Clear PHY error counter(s) +_date Date: date +_debugpage2 Dispalys Page 2 data when Host read it : 0 = OFF !0 = Active +_devils Print the Extended help +_dwd_reset Disable WatchDog reset: dwd_reset +_download Down load code using Xmodem: Region[0-9] Offset Erase[y/n] +_download_fpga Down FPGA load code using Xmodem: _download_fpga +_drive_pres Return Drive presense: _drive_pres +_ecc Display ECC counts: ecc {clear} +_ema_poll Turns on or off the analysis polling. Disables SES & LED update +_erase Erase F/W Region: erase [0..10] NOTE: This can mess up your code! +_event Event log test +_fan_ctrl_thrd Write fan control parameters in C: fan_ctrl_thrd +_flashdump Dump Flash: flashdump +_fpgaread Read FPGA Register: fpgaread +_fpgawrite Write FPGA Register: fpgawrite [ ...] +_fail_ts Fail temperature sensor: fail_ts +_flashpeer Flash Peer: <0=ACTIVE ; 1=BOOT> +_gpio_setting Read a GPIO Setting: gpio_settings <0..7> +_history Show CLI History: history +_hotswap Enable/disable Hotswap +_icid_clear Clears the ICID value to default. +_isim_msg Send message to ISIM thread +_ledconfig Show LED Configuration Settings +_ledmode Set Mode for led: ledmode +_ledread Read LED GPIO value: ledread +_ledset Set LED GPIO Value: ledset +_lm75_trip LM75 Interrrupt Control: lm75_trip +_loadcpld Load xsvf file from flash into CPLD +_map Display SES Sensor Data: map +_phy_info Display SAS phy information +_ps_pmb_test Test P/S Module PMBUS commands: ps_pmb_test +_psfup P/S Module Firmware update: psfup +_queue Dump the Message Queue usage: queue +_quick Quick regression: quick +_rdcam Read CAM Address contents
, +_rdtxphy Display current SASTX2G Phy settings +_rdrxphy Display current SASRX2G Phy settings +_rdphyerr Display PHY error counters +_rdled LED Control Register Read: rdled <# of 32 bit words> +_runtime Down load code using Xmodem to the non-active region: runtime +_set_cid Set company ID of ELI: cid_set [0-From Exp, 1-Custom <32bit data>] +_shutdown Invoke a thermal shut down sequence: _shutdown +_shutup Slow down fans: _shutup <0-100%> 20 default +_slotled Control Slot LEDs: slotled (slot > MaxDrive = 'all') +_splitforce Control Split Override: splitforce <0-switched; 1-ForceJoin; 3-ForceSplit> +_ssc_control Turn SSC on or off +_stack Show Stack Usage: stack +_temp_rd Read current temperature values +_temp_thrd Write temp thresholds: temp_thrd +_test_stub test_stub +_thread Display Threadx Information: thread +_timer Display Timer information: timer +_trace Display Trace Log [- for Tail] [+ for Head]: trace [-]count +_traceclear Clear trace log: traceclear +_twi_hang Hang the TWI bus for testing purposes only +_ver Version Information: ver +_wdt WatchDog test: wdt +_who Who's home (installed): who +_wrphy Write SAS2G1-3 Phy setting +_wrphyall Write all SAS2G1-3 Phy setting +_zone_mask Display Zone Mask for all PHYs +``` + + +``` +BlueDress.105.001 >devils +asset_tag Set or Display the Asset Tag: asset_tag {setvalue} +asd_offset Set or Display the Auto-Shudown Offset value: asd_offset {setvalue} +broadcast Send Broadcast SES Message: broadcast +chassistype Display and or Set Chassis Type: chassistype <0 = Blue Devil !0 = Red Devil> +clear_eel Clear Event Error Log: clear_eel +clear_temp Remove override of Temperature: clear_temp +dbs Database Read : dbs +devils Print the Help Screen +drive_led Write drive led: +eepromdump EEprom Dump: eepromdump +eepromfill EEprom Fill: eepromfill +eepromwrite EEprom Write: eepromwrite +fanlog Fan fault count for each power supply fan [8 per unit] +fpgadisable Put FPGA in Slave Mode: fpgadisable> +fpgaenable Put FPGA in Master Mode: fpgaenable> +fpga_rd FPGA Access: fpga_rd <#bytes> +fpga_wr FPGA Access: fpga_wr [ ...] +fru_display Display FRU Status: fru_display +fru_clear Clear Fru: fru_clear [0-SIM0, 1-SIM1, 2-PBP, 3-PS0, 4-PS1 5-SBP] +fru_download Download Fru: fru_download [0-SIM0, 1-SIM1, 2-PBP, 3-PS0, 4-PS1 5-SBP] +fru_read Read Fru: fru_read [0-SIM0, 1-SIM1, 2-PBP, 3-PS0, 4-PS1 5-SBP]] +get_time get encl time: get_time +gpio_rd Read a GPIO: gpio_rd +heart_beat SIM Heartbeat Control: heart_beat [0=off !0=on] +isim_debug Change or view isim stats: <0 - Disable; 1 - Enable> +l4_test L4 integration manufacturing diag: l4_test +lm75 LM75 Read Access: lm75 +lm75_rd LM75 Read Access: lm75_rd +lm75_wr LM75 Write Access: lm75_wr <1 byte> +log_ipmi Log an IPMI Event:log_ipmi +max6654 Display MAX6654 Registers: max6654 +noise Write audible alarm: +nvramread8 Read NVram 32bit area: nvramread
+nvramread Read NVram 32bit area: nvramread <32bit address> +nvramwrite8 Write NVram 32bit area: nvramwrite
[<32bit address> ...] +nvramwrite Write NVram 32bit area: nvramwrite <32bit address> [<32bit address> ...] +page_a Display drive SAS Address: page_a +ps_status Get P/S Module Status: ps_status +ps_cap Get P/S Module capability: ps_cap +ps_clear Clear P/S Module Status: ps_clr +ps_page Get P/S Module Status: ps_status +ppid Set or Display PPID: ppid {fruNumber}{setvalue} +prompt Prompt on/off +rd_8 8-bit Read: rd_8
<# of 8 bit words> +rd_16 16-bit Read: rd_16
<# of 16 bit words> +rd_32 32-bit Read: rd_32
<# of 32 bit words> +reset_peer Reset other SIM using GPIO <1-reset peer> +reset Reset ARM using Watch Dog timer +rev SIM Firmware and Diagnogstic Revision +sas_address Display SAS Address from Phys: (option for magic addr <1>) +sbb_status Set SBB status: sbb_set +scratchpad Display Location of Memory Test Area: scratchpad +service_tag Set or Display the Service Tag: service_tag {setvalue} +ses_page Display SES Page: ses_page +set_speed Sets Fan Speeds: set_speed <0-100%> 20 default +set_temp set encl temp: set_temp ( -55 to 125 degrees C) +set_thres Set P/S Module Fan Speed Threshold: set_thres +shelf_led Write shelf led: <0 - Disable; 1 - Enable> +twi_dis TWI device discovery: twi_dis +twi_rd TWI device byte read: twi_rd
<# of bytes - 0xff max> +twi_stats Dump twi statistics: twi_stats [clear] +twi_wr TWI device byte write: twi_wr
{0xff bytes max} +twi_wr_rd TWI device wr/rd: twi_wr_rd
<#read bytes> +wr_8 8-bit Write: wr_8
[
...] +wr_16 16-bit Write: wr_16
[
...] +wr_32 32-bit Write: wr_32
[
...] +``` \ No newline at end of file diff --git a/STM32_MD1200_FAN-CONTROL/other/info.md b/STM32_MD1200_FAN-CONTROL/other/info.md new file mode 100644 index 0000000..de02daa --- /dev/null +++ b/STM32_MD1200_FAN-CONTROL/other/info.md @@ -0,0 +1,2 @@ +set baud rate to 38400 + diff --git a/STM32_MD1200_FAN-CONTROL/other/links.md b/STM32_MD1200_FAN-CONTROL/other/links.md new file mode 100644 index 0000000..09b56e9 --- /dev/null +++ b/STM32_MD1200_FAN-CONTROL/other/links.md @@ -0,0 +1,12 @@ +# little how to and commands to use +https://forums.servethehome.com/index.php?threads/fun-with-an-md1200-md1220-sc200-sc220.27487/ + +# Set of all commands in MD1200 +https://pastebin.com/C0y5eavr + +# Here is also a reddit post that is "somewhat" usefull +https://www.reddit.com/r/unRAID/comments/l5pa2g/guide_how_to_quiet_md1200_or_sc200_via_serial/ + +# How to start with STM32 +https://stm32-base.org/guides/platformio + diff --git a/STM32_MD1200_FAN-CONTROL/other/outputs.md b/STM32_MD1200_FAN-CONTROL/other/outputs.md new file mode 100644 index 0000000..3180bd9 --- /dev/null +++ b/STM32_MD1200_FAN-CONTROL/other/outputs.md @@ -0,0 +1,21 @@ +# _temp_rd +``` +BlueDress.105.001 >_temp_rd + + BP_1[2] = 25c + BP_2[3] = 25c + SIM0[0] = 25c + SIM1[1] = 26c + EXP0[4] = 37c + EXP1[5] = 38c + + AVG = 29c + +BlueDress.105.001 > +``` +# set_speed 21 +``` +BlueDress.105.001 >set_speed 21 +BlueDress.105.001 > + +``` diff --git a/STM32_MD1200_FAN-CONTROL/platformio.ini b/STM32_MD1200_FAN-CONTROL/platformio.ini new file mode 100644 index 0000000..b8501c9 --- /dev/null +++ b/STM32_MD1200_FAN-CONTROL/platformio.ini @@ -0,0 +1,18 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:genericSTM32F103C6] +platform = ststm32 +board = genericSTM32F103C6 +framework = arduino +lib_deps = adafruit/DHT sensor library@^1.4.6 +upload_protocol = stlink +; Enable RX and TX 3 +; build_flags = -D SERIAL_USB -D ENABLE_HWSERIAL3 \ No newline at end of file diff --git a/STM32_MD1200_FAN-CONTROL/src/main.cpp b/STM32_MD1200_FAN-CONTROL/src/main.cpp new file mode 100644 index 0000000..9879961 --- /dev/null +++ b/STM32_MD1200_FAN-CONTROL/src/main.cpp @@ -0,0 +1,207 @@ +#include +#include + +// VARS +const int MD1200BAUDS = 38400; // From what I've read it is always 38400 +//const int EPYSLEEPY = 600000; / 10 minutes +const int EPYSLEEPY = 300000; // 5 minutes +//const int EPYSLEEPY = 150000; // 2,5 minutes +HardwareSerial Serial1(31, 30); + +// declarations +int getTemp(); +int setFanTrsh(int); + +void setup() { + // Setup connection to MD1200 + // Serial1 because we're using RX/TX pins + Serial1.begin(MD1200BAUDS); + + // Just debug + Serial.begin(9600); + Serial.print("skibidi"); +} + +void loop() { + + int fanPercnt = getTemp(); + + if (fanPercnt < 10) { + setFanTrsh(fanPercnt); + } + + /* + check temperature and + set fan speed every X minutes + */ + delay(EPYSLEEPY); + +} + +// Get current temperature +int getTemp() { + + int bp1 = 0; + int bp2 = 0; + int exp0 = 0; + int exp1 = 0; + int simm0 = 0; + int simm1 = 0; + String MD1200output; + + Serial1.println("_temp_rd"); + + // wait for MD1200 to answer + delay(30); + + while (Serial1.available()) { + MD1200output = Serial1.readStringUntil('\n'); + + // Check backplane 1 + if (MD1200output.startsWith("BP_1")) { + // check index number of = + int eq = MD1200output.indexOf('='); + // check index number of c + int c = MD1200output.indexOf('c'); + // check if both exists + if (eq != -1 && c != -1) { + /* + take value between "= " and "c". + NOTICE that eq + 1 is there because in + "BP_1[2] = 25c" there is a space between = and 25. + */ + bp1 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Check backplane 2 + if (MD1200output.startsWith("BP_2")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + bp2 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Uncomment if you want to also get temperature for expanders + /* + + // Check expander 0 + if (MD1200output.startsWith("EXP0")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + exp0 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Check expander 1 + if (MD1200output.startsWith("EXP1")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + exp1 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Check controller 0 + if (MD1200output.startsWith("SIM0")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + simm0 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Check controller 1 + if (MD1200output.startsWith("SIM1")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + simm1 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + */ + + // Stop when prompt returns + if (MD1200output.endsWith(">")) { + break; + } + } + + // Do (BP_1 + BP_2) / 2 to get the average of backplane + if (bp1 != -1 && bp2 != -1) { + int bpAvg = (bp1 + bp2) / 2; + + // define default + int outPrcntg = 21; + + // a + switch (bpAvg) { + case 23: + outPrcntg = 21; + break; + // Minimum is 21 (akhsually 20) + case 25: + outPrcntg = 23; + break; + case 27: + outPrcntg = 24; + break; + case 29: + outPrcntg = 26; + break; + case 31: + outPrcntg = 27; + break; + case 33: + outPrcntg = 30; + break; + case 35: + outPrcntg = 34; + break; + case 37: + outPrcntg = 38; + break; + /* + I don't wan't to become deaf so max is 40. + */ + + default: + return -1; + + } + + return outPrcntg; + + } else { + return -1; // failed to read temp + } + + /* + BP_1[2] - Back plane, maybe left + BP_2[3] - Back plane, maybe right + SIM0[0] - Controller A + SIM1[1] - Controller B + EXP0[4] - Expander 0 + EXP1[5] - Expander 1 + + AVG - average of all sensors + */ +} + +// take percentage as int and set it. +int setFanTrsh(int fanTrshInp) { + String outputStatement = "set_speed " + String(fanTrshInp); + + Serial.println("Sending " + outputStatement + " to MD1200"); + + if (Serial1.println(outputStatement)) { + return 1; + } + else { + return -1; + } + +} \ No newline at end of file diff --git a/STM32_MD1200_FAN-CONTROL/test/README b/STM32_MD1200_FAN-CONTROL/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/STM32_MD1200_FAN-CONTROL/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/STM32_MD1200_FAN-CONTROL/versions/main.bck.cpp b/STM32_MD1200_FAN-CONTROL/versions/main.bck.cpp new file mode 100644 index 0000000..e2f7dc5 --- /dev/null +++ b/STM32_MD1200_FAN-CONTROL/versions/main.bck.cpp @@ -0,0 +1,205 @@ +#include + + +// VARS +const int MD1200BAUDS = 38400; // From what I've read it is always 38400 +//const int EPYSLEEPY = 600000; / 10 minutes +const int EPYSLEEPY = 300000; // 5 minutes +//const int EPYSLEEPY = 150000; // 2,5 minutes + +// declarations +int getTemp(); +int setFanTrsh(int); + +void setup() { + // Setup connection to MD1200 + // Serial1 because we're using RX/TX pins + Serial1.begin(MD1200BAUDS); + + // Just debug + Serial.begin(9600); +} + +void loop() { + + int fanPercnt = getTemp(); + + if (fanPercnt < 10) { + setFanTrsh(fanPercnt); + } + + /* + check temperature and + set fan speed every X minutes + */ + delay(EPYSLEEPY); + +} + +// Get current temperature +int getTemp() { + + int bp1 = 0; + int bp2 = 0; + int exp0 = 0; + int exp1 = 0; + int simm0 = 0; + int simm1 = 0; + String MD1200output; + + Serial1.println("_temp_rd"); + + // wait for MD1200 to answer + delay(30); + + while (Serial1.available()) { + MD1200output = Serial1.readStringUntil('\n'); + + // Check backplane 1 + if (MD1200output.startsWith("BP_1")) { + // check index number of = + int eq = MD1200output.indexOf('='); + // check index number of c + int c = MD1200output.indexOf('c'); + // check if both exists + if (eq != -1 && c != -1) { + /* + take value between "= " and "c". + NOTICE that eq + 1 is there because in + "BP_1[2] = 25c" there is a space between = and 25. + */ + bp1 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Check backplane 2 + if (MD1200output.startsWith("BP_2")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + bp2 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Uncomment if you want to also get temperature for expanders + /* + + // Check expander 0 + if (MD1200output.startsWith("EXP0")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + exp0 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Check expander 1 + if (MD1200output.startsWith("EXP1")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + exp1 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Check controller 0 + if (MD1200output.startsWith("SIM0")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + simm0 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Check controller 1 + if (MD1200output.startsWith("SIM1")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + simm1 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + */ + + // Stop when prompt returns + if (MD1200output.endsWith(">")) { + break; + } + } + + // Do (BP_1 + BP_2) / 2 to get the average of backplane + if (bp1 != -1 && bp2 != -1) { + int bpAvg = (bp1 + bp2) / 2; + + // define default + int outPrcntg = 21; + + // a + switch (bpAvg) { + case 23: + outPrcntg = 21; + break; + // Minimum is 21 (akhsually 20) + case 25: + outPrcntg = 23; + break; + case 27: + outPrcntg = 24; + break; + case 29: + outPrcntg = 26; + break; + case 31: + outPrcntg = 27; + break; + case 33: + outPrcntg = 30; + break; + case 35: + outPrcntg = 34; + break; + case 37: + outPrcntg = 38; + break; + /* + I don't wan't to become deaf so max is 40. + */ + + default: + return -1; + + } + + return outPrcntg; + + } else { + return -1; // failed to read temp + } + + /* + BP_1[2] - Back plane, maybe left + BP_2[3] - Back plane, maybe right + SIM0[0] - Controller A + SIM1[1] - Controller B + EXP0[4] - Expander 0 + EXP1[5] - Expander 1 + + AVG - average of all sensors + */ +} + +// take percentage as int and set it. +int setFanTrsh(int fanTrshInp) { + String outputStatement = "set_speed " + String(fanTrshInp); + + Serial.println("Sending " + outputStatement + " to MD1200"); + + if (Serial1.println(outputStatement)) { + return 1; + } + else { + return -1; + } + +} \ No newline at end of file diff --git a/STM32_MD1200_FAN-CONTROL/versions/main.dht22.cpp b/STM32_MD1200_FAN-CONTROL/versions/main.dht22.cpp new file mode 100644 index 0000000..08de357 --- /dev/null +++ b/STM32_MD1200_FAN-CONTROL/versions/main.dht22.cpp @@ -0,0 +1,258 @@ +#include +#include +#include +#include + +// ------------------------------------------------------------- +// DHT PreConfiguration +#define DHTPIN 18 // Digital pin connected to the DHT sensor +//#define DHTPIN PB0 +// Pin 15 can work but DHT must be disconnected during program upload. +#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 +// ------------------------------------------------------------- +// Initialize DHT sensor. +// Note that older versions of this library took an optional third parameter to +// tweak the timings for faster processors. This parameter is no longer needed +// as the current DHT reading algorithm adjusts itself to work on faster procs. +DHT dht(DHTPIN, DHTTYPE); + + +// VARS +const int MD1200BAUDS = 38400; // From what I've read it is always 38400 +//const int EPYSLEEPY = 600000; / 10 minutes +const int EPYSLEEPY = 300000; // 5 minutes +//const int EPYSLEEPY = 150000; // 2,5 minutes + +// declarations +int getTemp(); +int setFanTrsh(int); +float dhtRead(); + +void setup() { + // Setup connection to MD1200 + // Serial1 because we're using RX/TX pins + Serial1.begin(MD1200BAUDS); + + // Just debug + Serial.begin(9600); + + dht.begin(); +} + +void loop() { + + int fanPercnt = getTemp(); + + if (fanPercnt < 10) { + setFanTrsh(fanPercnt); + } + + /* + check temperature and + set fan speed every X minutes + */ + delay(EPYSLEEPY); + +} + +// Get current temperature +int getTemp() { + + int bp1 = 0; + int bp2 = 0; + int exp0 = 0; + int exp1 = 0; + int simm0 = 0; + int simm1 = 0; + String MD1200output; + + Serial1.println("_temp_rd"); + + // wait for MD1200 to answer + delay(30); + + while (Serial1.available()) { + MD1200output = Serial1.readStringUntil('\n'); + + // Check backplane 1 + if (MD1200output.startsWith("BP_1")) { + // check index number of = + int eq = MD1200output.indexOf('='); + // check index number of c + int c = MD1200output.indexOf('c'); + // check if both exists + if (eq != -1 && c != -1) { + /* + take value between "= " and "c". + NOTICE that eq + 1 is there because in + "BP_1[2] = 25c" there is a space between = and 25. + */ + bp1 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Check backplane 2 + if (MD1200output.startsWith("BP_2")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + bp2 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Uncomment if you want to also get temperature for expanders + /* + + // Check expander 0 + if (MD1200output.startsWith("EXP0")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + exp0 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Check expander 1 + if (MD1200output.startsWith("EXP1")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + exp1 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Check controller 0 + if (MD1200output.startsWith("SIM0")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + simm0 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + // Check controller 1 + if (MD1200output.startsWith("SIM1")) { + int eq = MD1200output.indexOf('='); + int c = MD1200output.indexOf('c'); + if (eq != -1 && c != -1) { + simm1 = MD1200output.substring(eq + 1, c).toInt(); + } + } + + */ + + // Stop when prompt returns + if (MD1200output.endsWith(">")) { + break; + } + } + + // Do (BP_1 + BP_2) / 2 to get the average of backplane + if (bp1 != -1 && bp2 != -1) { + int bpAvg = (bp1 + bp2) / 2; + + // define default + int outPrcntg = 21; + + // check external sensor temp + int ownReadTemp = int(dhtRead()); + + // a + switch (bpAvg) { + case 23: + outPrcntg = 21; + break; + /* + Minimum is 21 (akhsually 20) + BUT + https://forums.servethehome.com/index.php?threads/fun-with-an-md1200-md1220-sc200-sc220.27487/ + */ + case 25: + outPrcntg = 23; + break; + case 27: + outPrcntg = 24; + break; + case 29: + outPrcntg = 26; + break; + case 31: + outPrcntg = 27; + break; + case 33: + outPrcntg = 30; + break; + case 35: + outPrcntg = 34; + break; + case 37: + outPrcntg = 38; + break; + /* + I don't wan't to become deaf so max is 40. + */ + + default: + return -1; + + } + + return outPrcntg; + + } else { + return -1; // failed to read temp + } + + /* + BP_1[2] - Back plane, maybe left + BP_2[3] - Back plane, maybe right + SIM0[0] - Controller A + SIM1[1] - Controller B + EXP0[4] - Expander 0 + EXP1[5] - Expander 1 + + AVG - average of all sensors + */ +} + +// take percentage as int and set it. +int setFanTrsh(int fanTrshInp) { + String outputStatement = "set_speed " + String(fanTrshInp); + + Serial.println("Sending " + outputStatement + " to MD1200"); + + if (Serial1.println(outputStatement)) { + return 1; + } + else { + return -1; + } + +} + +float dhtRead() { + // Reading temperature or humidity takes about 250 milliseconds! + // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) + // float humidt = dht.readHumidity(); + // Read temperature as Celsius (the default) + float tempr = dht.readTemperature(); + // Read temperature as Fahrenheit (isFahrenheit = true) + // f = dht.readTemperature(true); + + // Check if any reads failed and exit early (to try again). + // if (isnan(humidt) || isnan(tempr)) + if (isnan(tempr)) + { + Serial.println("Failed to read from DHT sensor!"); + return -1; + } + else { + return tempr; + } + + // Compute heat index in Fahrenheit (the default) + // hif = dht.computeHeatIndex(f, h); + // Compute heat index in Celsius (isFahreheit = false) + // hicc = dht.computeHeatIndex(tempr, humidt, false); + +} \ No newline at end of file