Added stuff.

This commit is contained in:
YuruC3 2025-05-08 09:39:22 +02:00
commit 8bede8e74e
15 changed files with 969 additions and 0 deletions

5
STM32_MD1200_FAN-CONTROL/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

View File

@ -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"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View File

@ -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

View File

@ -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 <Foo.h>
#include <Bar.h>
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

View File

@ -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) <phy Num (invalid PHY Num=all)>
_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 <M> <H> <SIM offset> <hysteresis>
_flashdump Dump Flash: flashdump <offset> <length>
_fpgaread Read FPGA Register: fpgaread <register> <length>
_fpgawrite Write FPGA Register: fpgawrite <register> <data> [<register> <data>...]
_fail_ts Fail temperature sensor: fail_ts <sensor>
_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 <number><direction><state>
_ledread Read LED GPIO value: ledread <number>
_ledset Set LED GPIO Value: ledset <number><state>
_lm75_trip LM75 Interrrupt Control: lm75_trip <sensor><state>
_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 <l(eft)/r(ight)>
_psfup P/S Module Firmware update: psfup <l(eft)/r(ight)>
_queue Dump the Message Queue usage: queue
_quick Quick regression: quick
_rdcam Read CAM Address contents <address (0-1024)>, <display count>
_rdtxphy Display current SASTX2G Phy settings <phy Num (invalid PHY Num=all)>
_rdrxphy Display current SASRX2G Phy settings <phy Num (invalid PHY Num=all)>
_rdphyerr Display PHY error counters <phy Num (invalid PHY Num=all)>
_rdled LED Control Register Read: rdled <offset> <# 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 <why>
_shutup Slow down fans: _shutup <0-100%> 20 default
_slotled Control Slot LEDs: slotled <slot><pattern> (slot > MaxDrive = 'all')
_splitforce Control Split Override: splitforce <0-switched; 1-ForceJoin; 3-ForceSplit>
_ssc_control Turn SSC on or off <enable 1, disable 0>
_stack Show Stack Usage: stack
_temp_rd Read current temperature values
_temp_thrd Write temp thresholds: temp_thrd <HS> <HC> <HW> <LW> <LC> <LS>
_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 Who's home (installed): who
_wrphy Write SAS2G1-3 Phy setting <phy number,Dword>
_wrphyall Write all SAS2G1-3 Phy setting <uses PHY setting table>
_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 <sensor>
dbs Database Read : dbs <page>
devils Print the Help Screen
drive_led Write drive led: <logicaldrive> <data>
eepromdump EEprom Dump: eepromdump <port><addr><size in K(1,2,4,8,..512>
eepromfill EEprom Fill: eepromfill <port><addr><size in K(1,2,4,8,..512><pattern>
eepromwrite EEprom Write: eepromwrite <port><addr><size in K(1,2,4,8,..512><offset><length><pattern>
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 <Register> <#bytes>
fpga_wr FPGA Access: fpga_wr <Register> <data>[<Register> <data> ...]
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 <number>
heart_beat SIM Heartbeat Control: heart_beat [0=off !0=on] <timeout>
isim_debug Change or view isim stats: <data> <0 - Disable; 1 - Enable>
l4_test L4 integration manufacturing diag: l4_test
lm75 LM75 Read Access: lm75 <Slave Address>
lm75_rd LM75 Read Access: lm75_rd <Slave Address> <Register>
lm75_wr LM75 Write Access: lm75_wr <Slave Address> <Register> <1 byte>
log_ipmi Log an IPMI Event:log_ipmi<Code><Type><Sensor><EV0><EV1><EV2><EV3>
max6654 Display MAX6654 Registers: max6654 <i2c port><slave addr>
noise Write audible alarm: <data>
nvramread8 Read NVram 32bit area: nvramread <address> <length>
nvramread Read NVram 32bit area: nvramread <32bit address> <length>
nvramwrite8 Write NVram 32bit area: nvramwrite <address> <data> [<32bit address> <data> ...]
nvramwrite Write NVram 32bit area: nvramwrite <32bit address> <data> [<32bit address> <data> ...]
page_a Display drive SAS Address: page_a
ps_status Get P/S Module Status: ps_status <l(eft)/r(ight)>
ps_cap Get P/S Module capability: ps_cap <l(eft)/r(ight)>
ps_clear Clear P/S Module Status: ps_clr <l(eft)/r(ight)>
ps_page Get P/S Module Status: ps_status <l(eft)/r(ight)>
ppid Set or Display PPID: ppid {fruNumber}{setvalue}
prompt Prompt on/off
rd_8 8-bit Read: rd_8 <address> <# of 8 bit words>
rd_16 16-bit Read: rd_16 <address> <# of 16 bit words>
rd_32 32-bit Read: rd_32 <address> <# 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 <default-print status, 0-set good, 1-set failed>
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 <page><buffer size>
set_speed Sets Fan Speeds: set_speed <0-100%> 20 default
set_temp set encl temp: set_temp <sensor><temp>( -55 to 125 degrees C)
set_thres Set P/S Module Fan Speed Threshold: set_thres <l(eft)/r(ight)><speed code 0..15>
shelf_led Write shelf led: <data> <0 - Disable; 1 - Enable>
twi_dis TWI device discovery: twi_dis
twi_rd TWI device byte read: twi_rd <port ID> <address> <# of bytes - 0xff max>
twi_stats Dump twi statistics: twi_stats [clear]
twi_wr TWI device byte write: twi_wr <port ID> <address> {0xff bytes max}
twi_wr_rd TWI device wr/rd: twi_wr_rd <port ID> <address> <#read bytes> <write data>
wr_8 8-bit Write: wr_8 <address> <data> [<address> <data> ...]
wr_16 16-bit Write: wr_16 <address> <data> [<address> <data> ...]
wr_32 32-bit Write: wr_32 <address> <data> [<address> <data> ...]
```

View File

@ -0,0 +1,2 @@
set baud rate to 38400

View File

@ -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

View File

@ -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 >
```

View File

@ -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

View File

@ -0,0 +1,207 @@
#include <Arduino.h>
#include <HardwareSerial.h>
// 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;
}
}

View File

@ -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

View File

@ -0,0 +1,205 @@
#include <Arduino.h>
// 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;
}
}

View File

@ -0,0 +1,258 @@
#include <Arduino.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
// -------------------------------------------------------------
// 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);
}