Merge pull request #2520 from MRprusa3d/PFW-x001bPR

FS PCB auto-detect
This commit is contained in:
DRracer 2020-03-26 17:36:18 +01:00 committed by GitHub
commit 65228a046e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 169 additions and 74 deletions

View File

@ -46,6 +46,7 @@
//-//
#include "Configuration.h"
#include "Marlin.h"
#include "config.h"
#ifdef ENABLE_AUTO_BED_LEVELING
#include "vector_3.h"
@ -9484,10 +9485,15 @@ static void handleSafetyTimer()
}
#endif //SAFETYTIMER
#define FS_CHECK_COUNT 15
void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument set in Marlin.h
{
bool bInhibitFlag;
#ifdef FILAMENT_SENSOR
bool bInhibitFlag;
#ifdef IR_SENSOR_ANALOG
static uint8_t nFSCheckCount=0;
#endif // IR_SENSOR_ANALOG
if (mmu_enabled == false)
{
//-// if (mcode_in_progress != 600) //M600 not in progress
@ -9496,11 +9502,35 @@ bool bInhibitFlag;
#endif // PAT9125
#ifdef IR_SENSOR
bInhibitFlag=(menu_menu==lcd_menu_show_sensors_state); // Support::SensorInfo menu active
#ifdef IR_SENSOR_ANALOG
bInhibitFlag=bInhibitFlag||bMenuFSDetect; // Settings::HWsetup::FSdetect menu active
#endif // IR_SENSOR_ANALOG
#endif // IR_SENSOR
if ((mcode_in_progress != 600) && (eFilamentAction != FilamentAction::AutoLoad) && (!bInhibitFlag)) //M600 not in progress, preHeat @ autoLoad menu not active, Support::ExtruderInfo/SensorInfo menu not active
{
if (!moves_planned() && !IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LcdCommands::Layer1Cal) && ! eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE))
{
#ifdef IR_SENSOR_ANALOG
bool bTemp=current_voltage_raw_IR>IRsensor_Hmin_TRESHOLD;
bTemp=bTemp&&current_voltage_raw_IR<IRsensor_Hopen_TRESHOLD;
bTemp=bTemp&&(!CHECK_ALL_HEATERS);
bTemp=bTemp&&(menu_menu==lcd_status_screen);
bTemp=bTemp&&((oFsensorPCB==ClFsensorPCB::_Old)||(oFsensorPCB==ClFsensorPCB::_Undef));
bTemp=bTemp&&fsensor_enabled;
if(bTemp)
{
nFSCheckCount++;
if(nFSCheckCount>FS_CHECK_COUNT)
{
nFSCheckCount=0; // not necessary
oFsensorPCB=ClFsensorPCB::_Rev03b;
eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,(uint8_t)oFsensorPCB);
printf_IRSensorAnalogBoardChange(true);
lcd_setstatuspgm(_i("FS rev. 03b or newer"));
}
}
else nFSCheckCount=0;
#endif // IR_SENSOR_ANALOG
if (fsensor_check_autoload())
{
#ifdef PAT9125

View File

@ -5,10 +5,12 @@
#include "Configuration_prusa.h"
#include "pins.h"
#define IR_SENSOR_ANALOG (defined(VOLT_IR_PIN) && defined(IR_SENSOR))
#if (defined(VOLT_IR_PIN) && defined(IR_SENSOR))
# define IR_SENSOR_ANALOG
#endif
//ADC configuration
#if !IR_SENSOR_ANALOG
#ifndef IR_SENSOR_ANALOG
#define ADC_CHAN_MSK 0b0000001001011111 //used AD channels bit mask (0,1,2,3,4,6,9)
#define ADC_DIDR_MSK 0b0000001001011111 //AD channels DIDR mask (1 ~ disabled digital input)
#define ADC_CHAN_CNT 7 //number of used channels)
@ -56,7 +58,7 @@
#define W25X20CL_SPSR SPI_SPSR(W25X20CL_SPI_RATE)
//LANG - Multi-language support
//define LANG_MODE 0 // primary language only
//#define LANG_MODE 0 // primary language only
#define LANG_MODE 1 // sec. language support
#define LANG_SIZE_RESERVED 0x3000 // reserved space for secondary language (12288 bytes)

View File

@ -119,7 +119,7 @@ int16_t fsensor_oq_yd_max;
uint16_t fsensor_oq_sh_sum;
//! @}
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
ClFsensorPCB oFsensorPCB;
ClFsensorActionNA oFsensorActionNA;
bool bIRsensorStateFlag=false;
@ -188,7 +188,7 @@ void fsensor_init(void)
fsensor_not_responding = true;
}
#endif //PAT9125
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
bIRsensorStateFlag=false;
oFsensorPCB=(ClFsensorPCB)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_PCB);
oFsensorActionNA=(ClFsensorActionNA)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA);
@ -198,7 +198,7 @@ void fsensor_init(void)
else
fsensor_disable(false); // (in this case) EEPROM update is not necessary
printf_P(PSTR("FSensor %S"), (fsensor_enabled?PSTR("ENABLED"):PSTR("DISABLED")));
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
printf_P(PSTR(" (sensor board revision: %S)\n"),(oFsensorPCB==ClFsensorPCB::_Rev03b)?PSTR("03b or newer"):PSTR("03 or older"));
#else //IR_SENSOR_ANALOG
printf_P(PSTR("\n"));
@ -231,7 +231,7 @@ bool fsensor_enable(bool bUpdateEEPROM)
FSensorStateMenu = 1;
}
#else // PAT9125
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
if(!fsensor_IR_check())
{
bUpdateEEPROM=true;
@ -244,7 +244,7 @@ bool fsensor_enable(bool bUpdateEEPROM)
fsensor_enabled=true;
fsensor_not_responding=false;
FSensorStateMenu=1;
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
}
#endif //IR_SENSOR_ANALOG
if(bUpdateEEPROM)
@ -660,7 +660,7 @@ void fsensor_update(void)
{
if(digitalRead(IR_SENSOR_PIN))
{ // IR_SENSOR_PIN ~ H
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
if(!bIRsensorStateFlag)
{
bIRsensorStateFlag=true;
@ -703,7 +703,7 @@ void fsensor_update(void)
#endif //IR_SENSOR_ANALOG
fsensor_checkpoint_print();
fsensor_enque_M600();
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
}
}
}
@ -717,7 +717,7 @@ void fsensor_update(void)
#endif //PAT9125
}
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
bool fsensor_IR_check()
{
uint16_t volt_IR_int;

View File

@ -81,7 +81,7 @@ extern void fsensor_st_block_chunk(int cnt);
#endif //PAT9125
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
#define IR_SENSOR_STEADY 10 // [ms]
enum class ClFsensorPCB:uint_least8_t

View File

@ -73,7 +73,7 @@ int current_voltage_raw_pwr = 0;
int current_voltage_raw_bed = 0;
#endif
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
int current_voltage_raw_IR = 0;
#endif //IR_SENSOR_ANALOG
@ -210,6 +210,14 @@ static void temp_runaway_check(int _heater_id, float _target_temperature, float
static void temp_runaway_stop(bool isPreheat, bool isBed);
#endif
// return "false", if all extruder-heaters are 'off' (ie. "true", if any heater is 'on')
bool checkAllHotends(void)
{
bool result=false;
for(int i=0;i<EXTRUDERS;i++) result=(result||(target_temperature[i]!=0));
return(result);
}
void PID_autotune(float temp, int extruder, int ncycles)
{
pid_number_of_cycles = ncycles;
@ -1588,7 +1596,7 @@ void adc_ready(void) //callback from adc when sampling finished
#ifdef VOLT_BED_PIN
current_voltage_raw_bed = adc_values[ADC_PIN_IDX(VOLT_BED_PIN)]; // 6->9
#endif
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
current_voltage_raw_IR = adc_values[ADC_PIN_IDX(VOLT_IR_PIN)];
#endif //IR_SENSOR_ANALOG
temp_meas_ready = true;

View File

@ -47,6 +47,8 @@
void tp_init(); //initialize the heating
void manage_heater(); //it is critical that this is called periodically.
extern bool checkAllHotends(void);
// low level conversion routines
// do not use these routines and variables outside of temperature.cpp
extern int target_temperature[EXTRUDERS];
@ -76,7 +78,7 @@ extern int current_voltage_raw_pwr;
extern int current_voltage_raw_bed;
#endif
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
extern int current_voltage_raw_IR;
#endif //IR_SENSOR_ANALOG
@ -222,6 +224,9 @@ FORCE_INLINE bool isCoolingBed() {
#error Invalid number of extruders
#endif
// return "false", if all heaters are 'off' (ie. "true", if any heater is 'on')
#define CHECK_ALL_HEATERS (checkAllHotends()||(target_temperature_bed!=0))
int getHeaterPower(int heater);
void disable_heater();
void updatePID();

View File

@ -68,6 +68,10 @@ uint8_t SilentModeMenu_MMU = 1; //activate mmu unit stealth mode
int8_t FSensorStateMenu = 1;
#ifdef IR_SENSOR_ANALOG
bool bMenuFSDetect=false;
#endif //IR_SENSOR_ANALOG
#ifdef SDCARD_SORT_ALPHA
bool presort_flag = false;
@ -114,7 +118,7 @@ static const char* lcd_display_message_fullscreen_nonBlocking_P(const char *msg,
// void copy_and_scalePID_d();
/* Different menus */
static void lcd_status_screen();
//static void lcd_status_screen(); // NOT static due to using inside "Marlin_main" module ("manage_inactivity()")
#if (LANG_MODE != 0)
static void lcd_language_menu();
#endif
@ -235,8 +239,9 @@ static FanCheck lcd_selftest_fan_auto(int _fan);
static bool lcd_selftest_fsensor();
#endif //PAT9125
static bool selftest_irsensor();
#if IR_SENSOR_ANALOG
static bool lcd_selftest_IRsensor();
#ifdef IR_SENSOR_ANALOG
static bool lcd_selftest_IRsensor(bool bStandalone=false);
static void lcd_detect_IRsensor();
#endif //IR_SENSOR_ANALOG
static void lcd_selftest_error(TestError error, const char *_error_1, const char *_error_2);
static void lcd_colorprint_change();
@ -975,7 +980,7 @@ void lcdui_print_status_screen(void)
}
// Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependent
static void lcd_status_screen()
void lcd_status_screen() // NOT static due to using inside "Marlin_main" module ("manage_inactivity()")
{
if (firstrun == 1)
{
@ -1952,7 +1957,7 @@ static void lcd_menu_temperatures()
menu_back_if_clicked();
}
#if defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN) || IR_SENSOR_ANALOG
#if defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN) || defined(IR_SENSOR_ANALOG)
#define VOLT_DIV_R1 10000
#define VOLT_DIV_R2 2370
#define VOLT_DIV_FAC ((float)VOLT_DIV_R2 / (VOLT_DIV_R2 + VOLT_DIV_R1))
@ -1964,27 +1969,24 @@ static void lcd_menu_temperatures()
//! | |
//! | PWR: 00.0V | c=12 r=1
//! | Bed: 00.0V | c=12 r=1
//! | |
//! | IR : 00.0V | c=12 r=1 optional
//! ----------------------
//! @endcode
//! @todo Positioning of the messages and values on LCD aren't fixed to their exact place. This causes issues with translations.
static void lcd_menu_voltages()
{
lcd_timeoutToStatus.stop(); //infinite timeout
float volt_pwr = VOLT_DIV_REF * ((float)current_voltage_raw_pwr / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
float volt_bed = VOLT_DIV_REF * ((float)current_voltage_raw_bed / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
lcd_home();
#if !IR_SENSOR_ANALOG
lcd_printf_P(PSTR("\n"));
#endif //!IR_SENSOR_ANALOG
lcd_printf_P(PSTR(" PWR: %4.1fV\n" " BED: %4.1fV"), volt_pwr, volt_bed);
#if IR_SENSOR_ANALOG
float volt_IR = VOLT_DIV_REF * ((float)current_voltage_raw_IR / (1023 * OVERSAMPLENR));
lcd_printf_P(PSTR("\n IR : %3.1fV"),volt_IR);
lcd_timeoutToStatus.stop(); //infinite timeout
float volt_pwr = VOLT_DIV_REF * ((float)current_voltage_raw_pwr / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
float volt_bed = VOLT_DIV_REF * ((float)current_voltage_raw_bed / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
lcd_home();
lcd_printf_P(PSTR(" PWR: %4.1fV\n" " BED: %4.1fV"), volt_pwr, volt_bed);
#ifdef IR_SENSOR_ANALOG
float volt_IR = VOLT_DIV_REF * ((float)current_voltage_raw_IR / (1023 * OVERSAMPLENR));
lcd_printf_P(PSTR("\n IR : %3.1fV"),volt_IR);
#endif //IR_SENSOR_ANALOG
menu_back_if_clicked();
menu_back_if_clicked();
}
#endif //defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN) || IR_SENSOR_ANALOG
#endif //defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN) || defined(IR_SENSOR_ANALOG)
#ifdef TMC2130
//! @brief Show Belt Status
@ -2158,6 +2160,23 @@ static void lcd_support_menu()
MENU_ITEM_BACK_P(_i("Date:"));////MSG_DATE c=17 r=1
MENU_ITEM_BACK_P(PSTR(__DATE__));
#ifdef IR_SENSOR_ANALOG
MENU_ITEM_BACK_P(STR_SEPARATOR);
MENU_ITEM_BACK_P(PSTR("Fil. sensor v.:"));
switch(oFsensorPCB)
{
case ClFsensorPCB::_Old:
MENU_ITEM_BACK_P(PSTR(" 03 or older"));
break;
case ClFsensorPCB::_Rev03b:
MENU_ITEM_BACK_P(PSTR(" 03b or newer"));
break;
case ClFsensorPCB::_Undef:
default:
MENU_ITEM_BACK_P(PSTR(" state unknown"));
}
#endif // IR_SENSOR_ANALOG
MENU_ITEM_BACK_P(STR_SEPARATOR);
if (mmu_enabled)
{
@ -5635,7 +5654,7 @@ SETTINGS_VERSION;
MENU_END();
}
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
static void lcd_fsensor_actionNA_set(void)
{
switch(oFsensorActionNA)
@ -5701,8 +5720,9 @@ void lcd_hw_setup_menu(void) // can not be "static"
SETTINGS_NOZZLE;
MENU_ITEM_SUBMENU_P(_i("Checks"), lcd_checking_menu);
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
FSENSOR_ACTION_NA;
MENU_ITEM_FUNCTION_P(PSTR("Fsensor Detection"), lcd_detect_IRsensor);
#endif //IR_SENSOR_ANALOG
MENU_END();
}
@ -7121,7 +7141,7 @@ static void lcd_tune_menu()
else {
MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR), _T(MSG_ON), lcd_fsensor_state_set);
}
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
FSENSOR_ACTION_NA;
#endif //IR_SENSOR_ANALOG
#endif //FILAMENT_SENSOR
@ -7501,39 +7521,60 @@ void lcd_belttest()
}
#endif //TMC2130
#if IR_SENSOR_ANALOG
static bool lcd_selftest_IRsensor()
{
bool bAction;
bool bPCBrev03b;
uint16_t volt_IR_int;
float volt_IR;
#ifdef IR_SENSOR_ANALOG
// called also from marlin_main.cpp
void printf_IRSensorAnalogBoardChange(bool bPCBrev03b){
printf_P(PSTR("Filament sensor board change detected: revision %S\n"), bPCBrev03b ? PSTR("03b or newer") : PSTR("03 or older"));
}
volt_IR_int=current_voltage_raw_IR;
bPCBrev03b=(volt_IR_int<((int)IRsensor_Hopen_TRESHOLD));
volt_IR=VOLT_DIV_REF*((float)volt_IR_int/(1023*OVERSAMPLENR));
printf_P(PSTR("Measured filament sensor high level: %4.2fV\n"),volt_IR);
if(volt_IR_int<((int)IRsensor_Hmin_TRESHOLD))
{
lcd_selftest_error(TestError::FsensorLevel,"HIGH","");
return(false);
}
lcd_show_fullscreen_message_and_wait_P(_i("Please insert filament (but not load them!) into extruder and then press the knob."));
volt_IR_int=current_voltage_raw_IR;
volt_IR=VOLT_DIV_REF*((float)volt_IR_int/(1023*OVERSAMPLENR));
printf_P(PSTR("Measured filament sensor low level: %4.2fV\n"),volt_IR);
if(volt_IR_int>((int)IRsensor_Lmax_TRESHOLD))
{
lcd_selftest_error(TestError::FsensorLevel,"LOW","");
return(false);
}
if((bPCBrev03b?1:0)!=(uint8_t)oFsensorPCB) // safer then "(uint8_t)bPCBrev03b"
{
printf_P(PSTR("Filament sensor board change detected: revision %S\n"),bPCBrev03b?PSTR("03b or newer"):PSTR("03 or older"));
oFsensorPCB=bPCBrev03b?ClFsensorPCB::_Rev03b:ClFsensorPCB::_Old;
eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,(uint8_t)oFsensorPCB);
}
return(true);
static bool lcd_selftest_IRsensor(bool bStandalone)
{
bool bAction;
bool bPCBrev03b;
uint16_t volt_IR_int;
float volt_IR;
volt_IR_int=current_voltage_raw_IR;
bPCBrev03b=(volt_IR_int<((int)IRsensor_Hopen_TRESHOLD));
volt_IR=VOLT_DIV_REF*((float)volt_IR_int/(1023*OVERSAMPLENR));
printf_P(PSTR("Measured filament sensor high level: %4.2fV\n"),volt_IR);
if(volt_IR_int < ((int)IRsensor_Hmin_TRESHOLD)){
if(!bStandalone)
lcd_selftest_error(TestError::FsensorLevel,"HIGH","");
return(false);
}
lcd_show_fullscreen_message_and_wait_P(_i("Please insert filament (but not load them!) into extruder and then press the knob."));
volt_IR_int=current_voltage_raw_IR;
volt_IR=VOLT_DIV_REF*((float)volt_IR_int/(1023*OVERSAMPLENR));
printf_P(PSTR("Measured filament sensor low level: %4.2fV\n"),volt_IR);
if(volt_IR_int > ((int)IRsensor_Lmax_TRESHOLD)){
if(!bStandalone)
lcd_selftest_error(TestError::FsensorLevel,"LOW","");
return(false);
}
if((bPCBrev03b?1:0)!=(uint8_t)oFsensorPCB){ // safer then "(uint8_t)bPCBrev03b"
printf_IRSensorAnalogBoardChange(bPCBrev03b);
oFsensorPCB=bPCBrev03b?ClFsensorPCB::_Rev03b:ClFsensorPCB::_Old;
eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,(uint8_t)oFsensorPCB);
}
return(true);
}
static void lcd_detect_IRsensor(){
bool bAction;
bMenuFSDetect = true; // inhibits some code inside "manage_inactivity()"
bAction = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Is the filament loaded?"), false, false);
if(!bAction){
lcd_show_fullscreen_message_and_wait_P(_i("Please unload the filament first, then repeat this action."));
return;
}
bAction = lcd_selftest_IRsensor(true);
if(bAction)
lcd_show_fullscreen_message_and_wait_P(_i("Sensor verified, remove the filament now."));
else
lcd_show_fullscreen_message_and_wait_P(_i("Verification failed, remove the filament and try again."));
bMenuFSDetect=false; // de-inhibits some code inside "manage_inactivity()"
}
#endif //IR_SENSOR_ANALOG
@ -7547,7 +7588,8 @@ bool lcd_selftest()
int _progress = 0;
bool _result = true;
bool _swapped_fan = false;
#if IR_SENSOR_ANALOG
//#ifdef IR_SENSOR_ANALOG
#if (0)
bool bAction;
bAction=lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Is the filament unloaded?"),false,true);
if(!bAction)
@ -7559,7 +7601,7 @@ bool lcd_selftest()
#ifdef TMC2130
FORCE_HIGH_POWER_START;
#endif // TMC2130
_delay(2000);
// _delay(2000);
FORCE_BL_ON_START;
@ -7756,7 +7798,8 @@ bool lcd_selftest()
_progress = lcd_selftest_screen(TestScreen::FsensorOk, _progress, 3, true, 2000); //fil sensor OK
}
#endif //PAT9125
#if IR_SENSOR_ANALOG
//#ifdef IR_SENSOR_ANALOG
#if (0)
_progress = lcd_selftest_screen(TestScreen::Fsensor, _progress, 3, true, 2000); //check filament sensor
_result = lcd_selftest_IRsensor();
if (_result)

View File

@ -55,8 +55,10 @@ extern bool lcd_selftest();
void lcd_menu_statistics();
void lcd_status_screen(); // NOT static due to using inside "Marlin_main" module ("manage_inactivity()")
void lcd_menu_extruder_info(); // NOT static due to using inside "Marlin_main" module ("manage_inactivity()")
void lcd_menu_show_sensors_state(); // NOT static due to using inside "Marlin_main" module ("manage_inactivity()")
#ifdef TMC2130
bool lcd_crash_detect_enabled();
void lcd_crash_detect_enable();
@ -138,6 +140,11 @@ extern uint8_t farm_status;
#define SILENT_MODE_OFF SILENT_MODE_POWER
#endif
#ifdef IR_SENSOR_ANALOG
extern bool bMenuFSDetect;
void printf_IRSensorAnalogBoardChange(bool bPCBrev03b);
#endif //IR_SENSOR_ANALOG
extern int8_t SilentModeMenu;
extern uint8_t SilentModeMenu_MMU;
@ -251,7 +258,7 @@ enum class WizState : uint8_t
void lcd_wizard(WizState state);
#define VOLT_DIV_REF 5
#if IR_SENSOR_ANALOG
#ifdef IR_SENSOR_ANALOG
#define IRsensor_Hmin_TRESHOLD (3.0*1023*OVERSAMPLENR/VOLT_DIV_REF) // ~3.0V (0.6*Vcc)
#define IRsensor_Lmax_TRESHOLD (1.5*1023*OVERSAMPLENR/VOLT_DIV_REF) // ~1.5V (0.3*Vcc)
#define IRsensor_Hopen_TRESHOLD (4.6*1023*OVERSAMPLENR/VOLT_DIV_REF) // ~4.6V (N.C. @ Ru~20-50k, Rd'=56k, Ru'=10k)