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

MHP30 Soldering/Reflow Temperature Profile #1672

Merged
merged 19 commits into from
Apr 25, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 18 additions & 1 deletion Documentation/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ This OLED screen features burn-in protection; if no buttons or movement have bee

Additionally to the two icons shown, there are two "hidden" actions that can be performed on this menu.

If you press and hold the button near the tip (`+/A`), this enters the temperature adjustment screen. Normally this is not required; but if you would like to adjust the set temperature _before_ the tip starts to heat, this can be useful.
On devices that do not support profile mode, if you press and hold the button near the tip (`+/A`), this enters the temperature adjustment screen. Normally this is not required; but if you would like to adjust the set temperature _before_ the tip starts to heat, this can be useful.

If you press and hold the button near the rear of the iron (`-/B`), it will take you into the [debug menu](https://ralim.github.io/IronOS/DebugMenu/).

Expand Down Expand Up @@ -74,6 +74,23 @@ Pinecil has an unpopulated footprint (U14) for a hall effect sensor (Si7210-B-00

If, after entering sleep mode, the iron still does not see movement for a much longer time (default=10 minutes); it will shut down and return to the home screen.

## Profile Mode (MHP30 only)

On devices that support it, when you long press the button to enter the soldering mode, you enter profile mode which will adjust the temperature according to the profile mode settings.
codingcatgirl marked this conversation as resolved.
Show resolved Hide resolved

Profile mode plays out as follows:

1. Check if the temperature is below 55C. If not, you will get a warning and cannot enter profile mode.
2. Preheat by raising the target temperature to the configured preheat temperature with the configured preheat speed.
3. Wait for the iron to reach the preheat temperature.
discip marked this conversation as resolved.
Show resolved Hide resolved
4. Gradually move the target temperature to the configured end temperature of the first phase over the configured duration.
5. Wait for the iron to reach the end temperature.
discip marked this conversation as resolved.
Show resolved Hide resolved
6. Repeat steps 4 and 5 for the next phases until there are no more phases configured.
7. Cool down by lowering the target temperature to 0 with the configured cooldown speed.
8. Once the temperature is below 55C, sound the buzzer (if available) and exit profile mode.

You can manually exit profile mode manually in the same way as the soldering mode, by pressing and holding the rear button or pressing both buttons at once.

## Settings Menu

The settings menu is the most evolving aspect of the firmware, so each option is not documented here. However, do not panic, as every menu option has an on-screen description so you don't _need_ to come back here to figure them all out.
Expand Down
6 changes: 6 additions & 0 deletions Documentation/Menu.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ In this mode the iron works as you would expect, pressing either button will tak
- Pressing both buttons or holding the rear button (`-/B`) will exit Soldering Mode.
- Holding the front button (`+/A`) will enter [Boost mode](https://ralim.github.io/IronOS/Menu/#boost-mode) (if enabled).

## Profile mode (MHP30 only)

In this mode, accessible by long pressing the button that brings you into soldering mode, the iron will play out the configured profile.
codingcatgirl marked this conversation as resolved.
Show resolved Hide resolved
- You cannot adjust the temperature or enter boost mode.
- Pressing both buttons or holding the rear button (`-/B`) will exit Profile Mode as well.

## Settings mode

This mode allows you to cycle through all the options and set custom values.
Expand Down
48 changes: 42 additions & 6 deletions Translations/make_translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,29 @@ def read_translation(json_root: Union[str, Path], lang_code: str) -> dict:
return lang


def filter_translation(lang: dict, defs: dict, macros: frozenset):
def check_excluded(record):
if "include" in record and not any(m in macros for m in record["include"]):
return True

if "exclude" in record and any(m in macros for m in record["exclude"]):
return True

return False

for category in ("menuOptions", "menuGroups"):
for index, record in enumerate(defs[category]):
if check_excluded(record):
lang[category][record["id"]]["displayText"] = ""
lang[category][record["id"]]["description"] = ""

for index, record in enumerate(defs["messagesWarn"]):
if check_excluded(record):
lang["messagesWarn"][record["id"]]["message"] = ""

return lang


def validate_langcode_matches_content(filename: str, content: dict) -> None:
# Extract lang code from file name
lang_code = filename[12:-5].upper()
Expand Down Expand Up @@ -101,6 +124,8 @@ def get_constants() -> List[Tuple[str, str]]:
("SmallSymbolSpace", " "),
("LargeSymbolDot", "."),
("SmallSymbolDot", "."),
("SmallSymbolSlash", "/"),
("SmallSymbolColon", ":"),
("LargeSymbolDegC", "C"),
("SmallSymbolDegC", "C"),
("LargeSymbolDegF", "F"),
Expand Down Expand Up @@ -250,7 +275,6 @@ def get_letter_counts(defs: dict, lang: dict, build_version: str) -> Dict:
# collapse all strings down into the composite letters and store totals for these
# Doing this seperately for small and big font
def sort_and_count(list_in: List[str]):

symbol_counts: dict[str, int] = {}
for line in list_in:
line = line.replace("\n", "").replace("\r", "")
Expand Down Expand Up @@ -439,7 +463,6 @@ class FontMapsPerFont:
def get_font_map_per_font(
text_list_small_font: List[str], text_list_large_font: List[str]
) -> FontMapsPerFont:

pending_small_symbols = set(text_list_small_font)
pending_large_symbols = set(text_list_large_font)

Expand Down Expand Up @@ -1029,7 +1052,6 @@ def get_translation_strings_and_indices_text(
large_font_symbol_conversion_table: Dict[str, bytes],
suffix: str = "",
) -> str:

# For all strings; we want to convert them to their byte encoded form (using font index lookups)
# Then we want to sort by their reversed format to see if we can remove any duplicates by combining the tails (last n bytes;n>0)
# Finally we look for any that are contained inside one another, and if they are we update them to point to this
Expand Down Expand Up @@ -1118,7 +1140,6 @@ def encode_string_and_add(
translation_strings_text = " /* .strings = */ {\n"

for i, encoded_bytes in enumerate(byte_encoded_strings):

if i > 0:
translation_strings_text += ' "\\0"\n'

Expand Down Expand Up @@ -1285,6 +1306,13 @@ def parse_args() -> argparse.Namespace:
required=False,
dest="compress_font",
)
parser.add_argument(
"--macros",
help="Extracted macros to filter translation strings by",
type=argparse.FileType("r"),
required=True,
dest="macros",
)
parser.add_argument(
"--output", "-o", help="Target file", type=argparse.FileType("w"), required=True
)
Expand All @@ -1305,6 +1333,12 @@ def main() -> None:
logging.error("error: Both --output-pickled and --input-pickled are specified")
sys.exit(1)

macros = (
frozenset(re.findall(r"#define ([^ ]+)", args.macros.read()))
if args.macros
else frozenset()
)

language_data: LanguageData
if args.input_pickled:
logging.info(f"Reading pickled language data from {args.input_pickled.name}...")
Expand All @@ -1329,11 +1363,13 @@ def main() -> None:

defs_ = load_json(os.path.join(json_dir, "translations_definitions.json"))
if len(args.languageCodes) == 1:
lang_ = read_translation(json_dir, args.languageCodes[0])
lang_ = filter_translation(
read_translation(json_dir, args.languageCodes[0]), defs_, macros
)
language_data = prepare_language(lang_, defs_, build_version)
else:
langs_ = [
read_translation(json_dir, lang_code)
filter_translation(read_translation(json_dir, lang_code), defs_, macros)
for lang_code in args.languageCodes
]
language_data = prepare_languages(langs_, defs_, build_version)
Expand Down
65 changes: 65 additions & 0 deletions Translations/translation_BE.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,17 @@
"OffString": {
"message": "Выкл."
},
"ProfilePreheatString": {
"message": "Preheat\n"
},
"ProfileCooldownString": {
"message": "Cooldown\n"
},
"DeviceFailedValidationWarning": {
"message": "Ваша прылада, хутчэй за ўсё, падробка!"
},
"TooHotToStartProfileWarning": {
"message": "Too hot to\nstart profile"
}
},
"characters": {
Expand Down Expand Up @@ -143,6 +152,62 @@
"displayText": "Дазволіць\nблок. кнопак",
"description": "Пры рабоце падоўжаны націск дзьвух кнопак блакуе іх (А=Адключана | Т=Толькі турба | П=Поўная блакіроўка)"
},
"ProfilePhases": {
"displayText": "Profile\nPhases",
"description": "Number of phases in profile mode"
},
"ProfilePreheatTemp": {
"displayText": "Preheat\nTemp",
"description": "Preheat to this temperature at the start of profile mode"
},
"ProfilePreheatSpeed": {
"displayText": "Preheat\nSpeed",
"description": "Preheat at this rate (degrees per second)"
},
"ProfilePhase1Temp": {
"displayText": "Phase 1\nTemp",
"description": "Target temperature for the end of this phase"
},
"ProfilePhase1Duration": {
"displayText": "Phase 1\nDuration",
"description": "Target duration of this phase (seconds)"
},
"ProfilePhase2Temp": {
"displayText": "Phase 2\nTemp",
"description": ""
},
"ProfilePhase2Duration": {
"displayText": "Phase 2\nDuration",
"description": ""
},
"ProfilePhase3Temp": {
"displayText": "Phase 3\nTemp",
"description": ""
},
"ProfilePhase3Duration": {
"displayText": "Phase 3\nDuration",
"description": ""
},
"ProfilePhase4Temp": {
"displayText": "Phase 4\nTemp",
"description": ""
},
"ProfilePhase4Duration": {
"displayText": "Phase 4\nDuration",
"description": ""
},
"ProfilePhase5Temp": {
"displayText": "Phase 5\nTemp",
"description": ""
},
"ProfilePhase5Duration": {
"displayText": "Phase 5\nDuration",
"description": ""
},
"ProfileCooldownSpeed": {
"displayText": "Cooldown\nSpeed",
"description": "Cooldown at this rate at the end of profile mode (degrees per second)"
},
"MotionSensitivity": {
"displayText": "Адчувальнасць\nакселерометра",
"description": "Адчувальнасць акселерометра (0=Выкл. | 1=Мін. | ... | 9=Макс.)"
Expand Down
65 changes: 65 additions & 0 deletions Translations/translation_BG.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,17 @@
"OffString": {
"message": "Изкл."
},
"ProfilePreheatString": {
"message": "Preheat\n"
},
"ProfileCooldownString": {
"message": "Cooldown\n"
},
"DeviceFailedValidationWarning": {
"message": "Your device is most likely a counterfeit!"
},
"TooHotToStartProfileWarning": {
"message": "Too hot to\nstart profile"
}
},
"characters": {
Expand Down Expand Up @@ -143,6 +152,62 @@
"displayText": "Allow locking\nbuttons",
"description": "While soldering, hold down both buttons to toggle locking them (D=disable | B=boost mode only | F=full locking)"
},
"ProfilePhases": {
"displayText": "Profile\nPhases",
"description": "Number of phases in profile mode"
},
"ProfilePreheatTemp": {
"displayText": "Preheat\nTemp",
"description": "Preheat to this temperature at the start of profile mode"
},
"ProfilePreheatSpeed": {
"displayText": "Preheat\nSpeed",
"description": "Preheat at this rate (degrees per second)"
},
"ProfilePhase1Temp": {
"displayText": "Phase 1\nTemp",
"description": "Target temperature for the end of this phase"
},
"ProfilePhase1Duration": {
"displayText": "Phase 1\nDuration",
"description": "Target duration of this phase (seconds)"
},
"ProfilePhase2Temp": {
"displayText": "Phase 2\nTemp",
"description": ""
},
"ProfilePhase2Duration": {
"displayText": "Phase 2\nDuration",
"description": ""
},
"ProfilePhase3Temp": {
"displayText": "Phase 3\nTemp",
"description": ""
},
"ProfilePhase3Duration": {
"displayText": "Phase 3\nDuration",
"description": ""
},
"ProfilePhase4Temp": {
"displayText": "Phase 4\nTemp",
"description": ""
},
"ProfilePhase4Duration": {
"displayText": "Phase 4\nDuration",
"description": ""
},
"ProfilePhase5Temp": {
"displayText": "Phase 5\nTemp",
"description": ""
},
"ProfilePhase5Duration": {
"displayText": "Phase 5\nDuration",
"description": ""
},
"ProfileCooldownSpeed": {
"displayText": "Cooldown\nSpeed",
"description": "Cooldown at this rate at the end of profile mode (degrees per second)"
},
"MotionSensitivity": {
"displayText": "Усещане\nза движение",
"description": "Усещане за движение (0=Изключено | 1=Слабо | ... | 9=Силно)"
Expand Down