Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made changes to enable high power output #5

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
Draft

Made changes to enable high power output #5

wants to merge 14 commits into from

Conversation

swissfreek
Copy link
Contributor

@swissfreek swissfreek commented Jan 23, 2021

Made modifications to code to allow for selectable high power in settings menu.
Modified power output bar on display to account for power level.
Added tip type parameter and tip detection code. Need help adding code to automatically modify power output based on tip type. Tip Type can currently only be detected once iron starts running, but power output can only be modified on init, which requires power cycle, so tip type is lost. I could use tip type detection to change the power output setting above, but switching from RTU to RTM would require either a manual change or knowingly running the 40W tip with 150W power limit, which is probably not a good idea, even for a short time. So I need to make it run the tip momentarily on startup and THEN declare max power once tip resistance can be measured.

swissfreek added 12 commits January 19, 2021 20:53
Adds new selectable menu item to settings that is a boolean "high power" setting. When off, this will limit power output via heating.hpp to 40W. When on, it will limit power output via heating.hpp to 150W. This will enable a menu-selectable option to use RT Ultra tips at full power. Requires power cycle to take effect.
Adds a selectable boolean setting called "high power" beneath the "left handed" menu item. Changing this in the menu will modify the HIGH_POWER setting in settings.hpp to allow either 40W (false) or 150W (true) power output in heating.hpp.
Added if statement to change scale of power output bar if using RTU tip (150W limit instead of 40W)
Added new enum for TipType
Added function to calculate tip type based on heater resistance
Added max power calculation in init function to account for either menu setting or determined tip type (that part requires more work)
Add Tip Type and allow for variable max power
Modification to pid constant initialization. Moved from init() to start() so that it actively checks for tip type change and adjusts max power in real time. Also commented out code for manual power level change but left it in for the case it might be desired.
@swissfreek swissfreek closed this Jan 23, 2021
@swissfreek swissfreek reopened this Jan 23, 2021
@swissfreek swissfreek closed this Jan 23, 2021
@swissfreek swissfreek reopened this Jan 23, 2021
@pavelrevak
Copy link
Owner

In general it is OK, but:

  • I see another problem, that RTU need supply 24V (24V is currently my limit, on new HW revision will be limit 30V)
    and currently maximum is 18V, so you never reach 150W (3.5 x 18V = 63W)
    You need with RTU also update this limit.
    Also for RTM is better if limit is set to 14V (not more - better less 13V, sometimes these tips will fail with higher voltage)
    I need to change this in future updates.
    This value is here:
    SUPPLY_VOLTAGE_MAX_MV = 18000; // mV

I prefer automatic selection on base of heating element resistance... Yes I know about PID set_constants, this need to manage this in runtime, somehow.
Or create function, set_max_power and if the resistance will be on begin more than 3ohm, then it will switch to 150W limit and if the resistance will be less it will keep the limit on 40W.

@@ -88,6 +89,13 @@ class Menu : public Screen {
0,
MenuItem::ItemType::VALUE_BINARY,
true,
}, {
"High power:";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comma

Copy link
Contributor Author

@swissfreek swissfreek Jan 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooh, good catch, thank you. But honestly, if we agree that it is better to automatically detect power levels (which I think also, I just hadn't figured out how so I was forcing it with a menu), then all these code changes would go away. The only change required would be to heating.hpp and screen/main.hpp (for the power bar). Settings.hpp and screen/menu.hpp could be unchanged from your version.

But, if the intent is to add RTPico tip function, then we cannot auto-detect this, as they have the same resistance as RTM (I think that's correct?). So you would have to have a setting for RTM vs. RTP to change the PIDs used, if new PIDs are developed for all three tips.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, detecting RTM vs RTU is easy, but RTM vs RTP is also possible, RTP tips are very small and my idea is to somehow provide "heating speed" parameter from PID regulation loop, this can easily identify TIP type. but currently it is only idea, I have no practical researches about this ,-)

Another idea is to select right tip from menu and all these mechanisms can only stop heating if some detection will say something else.

Also RTM and RTP tips uses same parameters (40W/12V/2ohm) so there is no problem.. ok one, RTP tips require little different PID constants.

Copy link
Contributor Author

@swissfreek swissfreek Jan 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would much much prefer to be able to switch between RTU and RTM and not have to worry about going into menus to make changes. But I also don't intend to use RTP tips very much, if at all, it's just not the type of soldering I do. But, I think, if there will be different PIDs for RTP and RTM, then that could be a boolean setting in the menu. I suspect it's pretty unlikely that someone would be switching constantly between RTU, RTM, and RTP all at the same time. Probably more likely to use RTU/RTM together as needed, and then RTM/RTP together as needed. In my mind, RTM is still the primary tip, and RTU or RTP are for situations where the RTM doesn't have the right features. So at least if one of the parts can be automatic, that would probably make life easier for some folks.

And then if you figure out a way to automate detection of the RTP/RTM, then that can be added, too. But that stuff is way above my skill level, haha.

int len = power * 15 / 40000; // default for 40W power limit

/* account for 150W power limit of RTU tips */
if (_heating.getTipType() == Heating::TipType::TRU) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TRU - RTU ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this was a typo. I fixed it in my code, but couldn't figure out how to correct it in here. That's why I was opening and closing the pull requests... 🤦🏻‍♂️

static const int IDLE_MIN_TIME_MS = 3; // ms
static const int STABILIZE_TIME_MS = 2; // ms
static const int HEATING_MIN_POWER_MW = 100; // mW
static const int TIP_MAX_CURRENT_MA = 9000; // mA
static const int SUPPLY_VOLTAGE_HEATING_MIN_MV = 4300; // mV
static const int SUPPLY_VOLTAGE_MAX_MV = 18000; // mV
static const int TIP_RESISTANCE_SHORTED_MO = 500; // mOhm
static const int RTM_TIP_RESISTANCE_MIN_MO = 1500 // mOhm
static const int RTM_TIP_RESISTANCE_MAX_MO = 2500 // mOhm
static const int RTU_TIP_RESISTANCE_MAX_MO = 4000 // mOhm
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RTU tip has normally 3.5ohm, it is OK if upper limit is 4ohm, but i suggest to set also MIN for RTU, to warn, or make fallback switch to RTM if there will be something less than 2.5ohm

in general it is possible to automatically select the right tip with resistance measurement

what is your opinion?
because if you select high power and then you insert RTM then you immediately broke it.

so option one: write message that is 'shorted' or fallback to RTM power limit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, there is a max resistance for the RTM tips. So the logic checks whether it is between min and max of the RTM (1.5 - 2.5 ohm). Then it is RTM. If it is below 1.5 ohm then it is "low resistance" and essentially an error state of some sort. If it is over 2.5 ohm, we can assume it is RTU, so it sets RTU, UNLESS it is higher than the RTU max (4 ohm) in which case we call it "high resistance" which I understand to also be an error state.

If we added an RTU minimum, then the only new functionality it would allow is to detect an error state in between the two types of tips. So, do we think it is likely that we will see a resistance in between 2.5 and 3 ohm and want to declare that an error state? Our ranges for resistance are arbitrary (RTM is about 2ohm, so we capture anything from 1.5 to 2.5, and then I did the same for RTU, from 3 to 4). But if an RTU tip read 2.9 ohms, would we want it to declare an error, or just run normally?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for selecting high power when a RTM tip is inserted, my understanding is that resistance is detected on every clock cycle (that's how I am reading the code, every "tick" is a cycle, is this correct?) that PWM is off, and max power is adjusted the very next clock cycle. So we would very quickly detect that it was an RTM tip, and adjust power limit accordingly, and my assumption is that this wouldn't cause much, if any, damage.

I also set the code so that when the tip is "unknown" (when we first power up the iron, before it runs, it cannot detect resistance), the power limit is 150mW, which isn't even high enough to get the iron warm. But it's just enough power that the iron can detect resistance, and then it adjusts power level. This way, like you said, it won't put full power to a RTM tip (or a tip where it can't tell what it is). Perhaps I can think of a way to always do that on the first cycle when you start heating. That way no matter what, max power will be 150mW until the iron knows for sure what tip is installed.

In my mind there are two ways to do this. We could do it at the beginning or the end. Either very time the "start" routine is called, the iron is set to TipType "UNKNOWN" so that it is forced to 150mW until resistance is confirmed. Or any time the "stop" routine is called, we set TipType to UNKNOWN. Then the routine will immediately determine tip type and continue to function. Then when the user stops the iron, it will remember what type of tip is connected until they start heating again. This could be useful if we, for example, replace the voltage drop display (I don't personally find this useful, maybe it's good for debugging?) with the tip type instead, so a user knows what is detected on their iron (in case they were confused or forgot which tip was which). But once you start you will never accidentally feed 150W to a 40W tip, even for a microsecond.

I will see if I can add this to the code, I don't think it will be too difficult, should just be one line of code, in state_start() or a similar routine, maybe in main.hpp. I will look into it.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RTU can have between 3 and 4ohm, if it will be less (e.g 2.9ohm), then it is a problem, because at 24V it will have peaks higher than 200Watts
If someone find RTU tips with less than 3ohm, we can discuss this again, but now I think it is clear

about detecting resistance: YES I checking resistance in very fast loop when is PWM in ON state, then I immediately react on low resistance or too high power and PWM is stopped immediately in microseconds - reason why PWM is driven by SW and not HW PWM peripheral.

Later I try to draw image where I explain heating principle, but be sure, that detecting resistance is possible in microseconds.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I assumed it happened super fast since it was basically every clock cycle. I highly doubt that applying 150W to a 40W tip for that short a period of time (if it even achieved that high power that quickly) would cause any serious damage.

But last night I did add a line to the _state_start() routine where all the variables are reset to zero that also sets _tip_type to UNKNOWN. So basically every time it starts the heating cycle it redetects the tip type and until it does, the max power is 150mW. I'm not sure if running that routine constantly might have an effect on the pid loop (since I think that means it will constantly be set to a max of 150mW and then back to 40W or 150W?). I ran my 40W tip yesterday to test it, and it seemed like the temperature settled one or two degrees low. I can't remember if it did that before, but I don't think so, if anything it was a couple degrees high before.

As for the resistance, you make a good point. I will establish a minimum as well so that a resistance below 3ohm but above 2.5 will register as an error state and neither RTU or RTP. That is an easy change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so option one: write message that is 'shorted' or fallback to RTM power limit.

I didn't see this before. Yeah, I suppose instead of being set to RTU when the resistance is over 2.5, it could be set as RTU when resistance is over 3. This would expand the range of RTM though and might miss an RTM tip that was failing and had a high resistance (does that happen when they fail? I assume it does). I don't know how quickly the resistance increases but if we have the error state in between we might catch a failing RTM instead of putting 150W into it and very quickly destroying it, maybe causing more damage to something else.

So I think you were right the first time, have a gap between the two types of tips that is accurate to how they are really built.

Copy link
Contributor Author

@swissfreek swissfreek Jan 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also in the check_tip_type(), this will allow a tip type of "UNKNOWN" if the resistance is in between the two, because this is true, we don't know if it's an RTU tip with low resistance, or an RTM tip with high resistance. And since it is declared as UNKNOWN in this case, the max power output will be 150mW which is very safe, even if the rest of the code allows the heater to receive power anyway.

src/heating.hpp Outdated

/** Initialize module
*/
void init() {
_pid.set_constants(PID_K_PROPORTIONAL, PID_K_INTEGRAL, PID_K_DERIVATE, PERIOD_TIME_MS, HEATING_POWER_MAX_MW);
_max_power_mw = (40 + (110 * _settings.get_high_power())) * 1000; // mW
/* Below will use tip resistance to set max power, but need to figure out how to calculate tip resistance before init, or how to change max power after init
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AHA, I see why ,-)
another problem is, that RTU will need probably different PID constants, or it is working also with these constants ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I assume that RTU will work better with different PIDs. I am currently traveling for work, and my RTU tip arrived at the house the day after I left, so it will be about two weeks before I can plug it in to test how it works. I also am not sure I have the resources to test the temperature and create a curve to see how much damping or overshoot needs to be adjusted. But if needed I think I may be able to find a friend that can. No promises, though.

BUT, even if it did require different PIDs, I envision that we would have separate constants for both, and then in the IF statement that decides which max power to allow, it would also select the current PIDs. In my mind, finding better PIDs and the maximum power logic are two separate problems to be solved that don't need to be solved at the same time (unless I test the RTU and find that it the current PIDs don't work at all).

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, btw, for tuning PID constants I have small python tool, which show diagrams of heating and so... (is not currently published)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUPPLY_VOLTAGE_MAX_MV = 18000; // mV

Yes, you are right, I did not implemented this, I forgotten.
but voltage limits is important to implement, my plan is to disable ON if the voltage limit is over maximum allowed.

Thinking about it now, this is more complicated than I thought. I'm looking for a good place that _supply_voltage_mv_idle could be checked to force a STOP state, but then of course it will also need some notification to the user. So I will chew on this some more and find a good way to implement it.

@swissfreek
Copy link
Contributor Author

swissfreek commented Jan 28, 2021

This value is here:
SUPPLY_VOLTAGE_MAX_MV = 18000; // mV

I had seen this before, and searched the code, and I can't find anywhere that this value is used. But I will change it to RTM_SUPPLY_VOLTAGE_MAX_MV = 14000; and then add a similar constant for RTU that is set to 26000 (high enough for any 6S LiPo pack, but still some buffer before it hits the 30V limit. For my iron, 30V is the limit, as I swapped out the input capacitor to a 30V one right after I got it. I think you told me at the time that you were going to make a hardware revision as well for the same thing in the future. Maybe it should be 25000 since anyone with v1.0 hardware that didn't swap the input capacitor would have a hard 25V limit, but even if it was set to 25000, there's no code that uses it to throw an error flag or something, so it wouldn't stop anyone from putting 30V in the iron and blowing it up.

I am indeed concerned that 24V will rapidly destroy an RTM tip. I intend to sacrifice one when I get home to see what happens, because personally I like the idea of just being able to use one kind of battery and not having to worry about switching back and forth. Minor inconvenience, but maybe I'm very lazy haha. I usually power the iron from a bench power supply, too, and in that case I would have to switch between power supplies, or get an adjustable voltage module.

Since there's no onboard regulator, I was thinking about seeing if I could add some code to detect the voltage and then just not allow the heating cycle to start if it's an RTM tip and it's being fed more than 12V (or 14V). That way at least, you wouldn't switch tips and forget and destroy your RTM tip (but knowing me, I would forget going the other direction, and then I would be confused why my RTU tip wasn't melting solder as well as usual).

I prefer automatic selection on base of heating element resistance... Yes I know about PID set_constants, this need to manage this in runtime, somehow.

This could be set at the same time as max power. It would just require new constants for the PIDs for RTU tips, once they are determined. But automatic detection wouldn't work for RTPico since it is the same resistance as RTMicro. So there would need to be a menu setting for those in order to apply different PIDs.

Or create function, set_max_power and if the resistance will be on begin more than 3ohm, then it will switch to 150W limit and if the resistance will be less it will keep the limit on 40W.

Yeah, I suppose that logic could be broken out from start() to clean up the code. But since start() is the only place that logic will ever be tested, I think it's more a style question of how you want to organize the code than a question of functionality.

@pavelrevak
Copy link
Owner

pavelrevak commented Jan 29, 2021

SUPPLY_VOLTAGE_MAX_MV = 18000; // mV

Yes, you are right, I did not implemented this, I forgotten.
but voltage limits is important to implement, my plan is to disable ON if the voltage limit is over maximum allowed.

@swissfreek
Copy link
Contributor Author

SUPPLY_VOLTAGE_MAX_MV = 18000; // mV

Yes, you are right, I did not implemented this, I forgotten.
but voltage limits is important to implement, my plan is to disable ON if the voltage limit is over maximum allowed.

This is what I was thinking as well. I should be able to add an argument to the if statement in start() that forces a stop() command (the place where it checks tip sensor status etc.). It will check tip type, and then either apply a max of 14V or 25V and then stop. I will work on this today.

@swissfreek swissfreek marked this pull request as draft January 29, 2021 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants