About 15 years ago, knowing nothing about programming, I decided to use Picase to build a precision version of an LDR-based stereo volume control that required accurate control of four LDRs of wildly varying manufacturing tolerances. This project included a pre-calibration routine plus an operating system that include an LCD display plus rotary-encoder and IR control of various parameters as well as input switching. Took an inordinate amount of time but eventually got it all to work together.
Now, after ten years of doing very little with Picaxe, I'm toying with the idea of cleaning up my very primitive original code. The other day, on a lark, I asked my recently discovered AI "friend" Claude to take my simplest routine -- translate IR input into usable commands -- and clean it up. "He" agreed, and the two short attached files are my original code and his updated version. I wonder if someone who's up on the latest Picaxe methods would look at this and comment on the changes.
This was our conversation:
I have programs written in Picaxe Basic. Are you capable of cleaning up and optimizing the code?
Assessed capability and solicited code samples for optimization
Yes, I can help with that. PICAXE BASIC is a fairly small, well-documented dialect (similar to other microcontroller BASICs — commands like high, low, pause, readadc, serout, sertxd, for...next, if...then, gosub, variable naming limits like b0-b27/w0-w13, etc.), so I can review it for things like:
this is for a picaxe 08m2 chip, here is the code:
Anticipated code submission and prepared to review
It looks like the code didn't come through with your message — could you paste it in or upload the file? Once I can see it, I'll go through it with the 08M2's limits in mind (it's one of the more constrained chips — 2K words of program memory, only b0-b13/w0-w6 variables available, limited pins), and clean it up.
'This program accepts SIRC code at IRIN and translates to ascii characters which are retransmitted through SERTXD. Accelerates transmission when key is held down.#REMFunction Sony Code ArbitraryNumerals1 0 1 Select Input 12 1 2 Select Input 23 2 3 Select Input 34 3 4 Select Input 45 4 5 Select Input 56 5 6 Select Input 67 6 7 Select Input 78 7 8 Select Input 89 8 9 Select Input 90 9 0 Select Input 0Enter 101 L EnterChUp 16 J Input Source UpChDn 17 K Input Source Down Source +--- Not UsedVolUp 18 C Volume Up VolDn 19 D Volume Down Mute 20 E Mute Bal L 38 H standard Sony code Bal R 39 I standard Sony codeBal L 27 H VCR Rewind adapted codeBal R 28 I VCR FF adapted codeMenu 96 M #ENDREM#picaxe 08M2#no_data'#terminal 9600setfreq M8 'make close faster
'PIN ASSIGNMENTS'IR input = C.3 on 08M2'Output on serial out pin'SYMBOLSSYMBOL RxData = b0SYMBOL Last = b1SYMBOL RepCount = b2SYMBOL PauseLength = W2main:IRIN [500,RepReset],C.3,RxData'********'SHOW CODES for Testing Only'SERTXD (cr,lf,"Code ",#RxData," ")'********'ACTION KEYS'IF RxData = 101 THEN : GOSUB Rep : SERTXD ("L") : GoTo SetPause : ENDIF'Enter'IF RxData = 16 THEN : GOSUB Rep : SERTXD ("J") : GoTo SetPause : ENDIF'ChUp'IF RxData = 17 THEN : GOSUB Rep : SERTXD ("K") : GoTo SetPause : ENDIF'ChDnIF RxData = 18 THEN : GOSUB Rep : SERTXD ("C") : GoTo SetPause : ENDIF'Volume UpIF RxData = 19 THEN : GOSUB Rep : SERTXD ("D") : GoTo SetPause : ENDIF'Volume DownIF RxData = 20 THEN : GOSUB Rep : SERTXD ("E") : GoTo SetPause : ENDIF'MuteIF RxData = 38 THEN : GOSUB Rep : SERTXD ("H") : GoTo SetPause : ENDIF'Bal LeftIF RxData = 39 THEN : GOSUB Rep : SERTXD ("I") : GoTo SetPause : ENDIF'Bal RightIF RxData = 27 THEN : GOSUB Rep : SERTXD ("H") : GoTo SetPause : ENDIF'Bal Left (VCR REW)IF RxData = 28 THEN : GOSUB Rep : SERTXD ("I") : GoTo SetPause : ENDIF'Bal Right (VCR FF)'IF RxData = 96 THEN : GOSUB Rep : SERTXD ("M") : GoTo SetPause : ENDIF'Menu'IF RxData = 37 THEN : GOSUB Rep : SERTXD ("N") : GoTo SetPause : ENDIF'Source'NUMERALSIF RxData = 0 THEN : GOSUB Rep : SERTXD ("1") : GoTo SetPause : ENDIF'Digit 1IF RxData = 1 THEN : GOSUB Rep : SERTXD ("2") : GoTo SetPause : ENDIF'Digit 2IF RxData = 2 THEN : GOSUB Rep : SERTXD ("3") : GoTo SetPause : ENDIF'Digit 3IF RxData = 3 THEN : GOSUB Rep : SERTXD ("4") : GoTo SetPause : ENDIF'Digit 4IF RxData = 4 THEN : GOSUB Rep : SERTXD ("5") : GoTo SetPause : ENDIF'Digit 5IF RxData = 5 THEN : GOSUB Rep : SERTXD ("6") : GoTo SetPause : ENDIF'Digit 6IF RxData = 6 THEN : GOSUB Rep : SERTXD ("7") : GoTo SetPause : ENDIF'Digit 7IF RxData = 7 THEN : GOSUB Rep : SERTXD ("8") : GoTo SetPause : ENDIF'Digit 8IF RxData = 8 THEN : GOSUB Rep : SERTXD ("9") : GoTo SetPause : ENDIF'Digit 9IF RxData = 9 THEN : GOSUB Rep : SERTXD ("0") : GoTo SetPause : ENDIF'Digit 0SetPause:'adjust timing between characters to speed up with continuous pressPauseLength=RepCount*RepCount * 2PauseLength=201-PauseLengthPAUSE PauseLengthRxData=255GOTO mainRep: IF RxData<>Last THEN RepCount=0 ELSE RepCount=RepCount + 1 max 10 ENDIF Last=RxDataRETURNRepReset:RepCount=0GOTO Main
Architected lookup table optimization to replace redundant conditionals
Good news — this is a solid, functional program, and the repeated IF/THEN block is the main thing worth optimizing. I'll rewrite the button-matching section using a LOOKUP table instead of 19 near-identical IF...THEN comparisons. That's both smaller (less program memory) and faster (one table lookup vs. up to 19 sequential comparisons in the worst case).
A few other things I checked and cleaned up:
A couple of notes on trade-offs, since "optimize" can mean different things:
Sirc translator optimized
BAS
Looks good, I will try it on a chip and see what happens, thank!
Sounds good — good luck with it. If anything acts up on the chip (timing, a miskeyed mapping, whatever), just paste what you're seeing and I'll help track it down.
Now, after ten years of doing very little with Picaxe, I'm toying with the idea of cleaning up my very primitive original code. The other day, on a lark, I asked my recently discovered AI "friend" Claude to take my simplest routine -- translate IR input into usable commands -- and clean it up. "He" agreed, and the two short attached files are my original code and his updated version. I wonder if someone who's up on the latest Picaxe methods would look at this and comment on the changes.
This was our conversation:
I have programs written in Picaxe Basic. Are you capable of cleaning up and optimizing the code?
Assessed capability and solicited code samples for optimization
Yes, I can help with that. PICAXE BASIC is a fairly small, well-documented dialect (similar to other microcontroller BASICs — commands like high, low, pause, readadc, serout, sertxd, for...next, if...then, gosub, variable naming limits like b0-b27/w0-w13, etc.), so I can review it for things like:
- Redundant or dead code
- Inefficient loops or polling patterns
- Variable reuse/naming clarity
- Reducing EEPROM/program memory usage where relevant
- Timing issues (e.g. unnecessary pause calls)
- Making use of subroutines instead of repeated blocks
- Readability/commenting
this is for a picaxe 08m2 chip, here is the code:
Anticipated code submission and prepared to review
It looks like the code didn't come through with your message — could you paste it in or upload the file? Once I can see it, I'll go through it with the 08M2's limits in mind (it's one of the more constrained chips — 2K words of program memory, only b0-b13/w0-w6 variables available, limited pins), and clean it up.
'This program accepts SIRC code at IRIN and translates to ascii characters which are retransmitted through SERTXD. Accelerates transmission when key is held down.#REMFunction Sony Code ArbitraryNumerals1 0 1 Select Input 12 1 2 Select Input 23 2 3 Select Input 34 3 4 Select Input 45 4 5 Select Input 56 5 6 Select Input 67 6 7 Select Input 78 7 8 Select Input 89 8 9 Select Input 90 9 0 Select Input 0Enter 101 L EnterChUp 16 J Input Source UpChDn 17 K Input Source Down Source +--- Not UsedVolUp 18 C Volume Up VolDn 19 D Volume Down Mute 20 E Mute Bal L 38 H standard Sony code Bal R 39 I standard Sony codeBal L 27 H VCR Rewind adapted codeBal R 28 I VCR FF adapted codeMenu 96 M #ENDREM#picaxe 08M2#no_data'#terminal 9600setfreq M8 'make close faster
'PIN ASSIGNMENTS'IR input = C.3 on 08M2'Output on serial out pin'SYMBOLSSYMBOL RxData = b0SYMBOL Last = b1SYMBOL RepCount = b2SYMBOL PauseLength = W2main:IRIN [500,RepReset],C.3,RxData'********'SHOW CODES for Testing Only'SERTXD (cr,lf,"Code ",#RxData," ")'********'ACTION KEYS'IF RxData = 101 THEN : GOSUB Rep : SERTXD ("L") : GoTo SetPause : ENDIF'Enter'IF RxData = 16 THEN : GOSUB Rep : SERTXD ("J") : GoTo SetPause : ENDIF'ChUp'IF RxData = 17 THEN : GOSUB Rep : SERTXD ("K") : GoTo SetPause : ENDIF'ChDnIF RxData = 18 THEN : GOSUB Rep : SERTXD ("C") : GoTo SetPause : ENDIF'Volume UpIF RxData = 19 THEN : GOSUB Rep : SERTXD ("D") : GoTo SetPause : ENDIF'Volume DownIF RxData = 20 THEN : GOSUB Rep : SERTXD ("E") : GoTo SetPause : ENDIF'MuteIF RxData = 38 THEN : GOSUB Rep : SERTXD ("H") : GoTo SetPause : ENDIF'Bal LeftIF RxData = 39 THEN : GOSUB Rep : SERTXD ("I") : GoTo SetPause : ENDIF'Bal RightIF RxData = 27 THEN : GOSUB Rep : SERTXD ("H") : GoTo SetPause : ENDIF'Bal Left (VCR REW)IF RxData = 28 THEN : GOSUB Rep : SERTXD ("I") : GoTo SetPause : ENDIF'Bal Right (VCR FF)'IF RxData = 96 THEN : GOSUB Rep : SERTXD ("M") : GoTo SetPause : ENDIF'Menu'IF RxData = 37 THEN : GOSUB Rep : SERTXD ("N") : GoTo SetPause : ENDIF'Source'NUMERALSIF RxData = 0 THEN : GOSUB Rep : SERTXD ("1") : GoTo SetPause : ENDIF'Digit 1IF RxData = 1 THEN : GOSUB Rep : SERTXD ("2") : GoTo SetPause : ENDIF'Digit 2IF RxData = 2 THEN : GOSUB Rep : SERTXD ("3") : GoTo SetPause : ENDIF'Digit 3IF RxData = 3 THEN : GOSUB Rep : SERTXD ("4") : GoTo SetPause : ENDIF'Digit 4IF RxData = 4 THEN : GOSUB Rep : SERTXD ("5") : GoTo SetPause : ENDIF'Digit 5IF RxData = 5 THEN : GOSUB Rep : SERTXD ("6") : GoTo SetPause : ENDIF'Digit 6IF RxData = 6 THEN : GOSUB Rep : SERTXD ("7") : GoTo SetPause : ENDIF'Digit 7IF RxData = 7 THEN : GOSUB Rep : SERTXD ("8") : GoTo SetPause : ENDIF'Digit 8IF RxData = 8 THEN : GOSUB Rep : SERTXD ("9") : GoTo SetPause : ENDIF'Digit 9IF RxData = 9 THEN : GOSUB Rep : SERTXD ("0") : GoTo SetPause : ENDIF'Digit 0SetPause:'adjust timing between characters to speed up with continuous pressPauseLength=RepCount*RepCount * 2PauseLength=201-PauseLengthPAUSE PauseLengthRxData=255GOTO mainRep: IF RxData<>Last THEN RepCount=0 ELSE RepCount=RepCount + 1 max 10 ENDIF Last=RxDataRETURNRepReset:RepCount=0GOTO Main
Architected lookup table optimization to replace redundant conditionals
Good news — this is a solid, functional program, and the repeated IF/THEN block is the main thing worth optimizing. I'll rewrite the button-matching section using a LOOKUP table instead of 19 near-identical IF...THEN comparisons. That's both smaller (less program memory) and faster (one table lookup vs. up to 19 sequential comparisons in the worst case).
A few other things I checked and cleaned up:
- Bug risk avoided: LOOKUP on PICAXE leaves the destination variable unchanged if the index is outside the table's range — it doesn't zero it out for you. Since your active button codes only go up to 39, any code ≥40 (or any future re-enabled code like Enter=101 or Menu=96) would leave a stale value in the output variable instead of correctly reporting "no match." I added an explicit reset (OutChar = 0) before every lookup to guard against this.
- Preserved your exact original behavior for unmatched codes: no GOSUB Rep, no SERTXD, straight to SetPause — same as before.
- Kept your commented-out Enter/ChUp/ChDn/Menu/Source lines as comments near the table (as placeholders) so you can re-enable any of them by just changing one table entry, instead of re-adding a whole IF block.
- Left your Rep and RepReset subroutines and the deceleration pause math untouched — they were already efficient, and I verified the RepCount*RepCount*2 calc can't overflow (PICAXE evaluates expressions in word-width internally, and RepCount is capped at 10, so max is 200).
A couple of notes on trade-offs, since "optimize" can mean different things:
- Program memory: this version should compile smaller than the original, since one LOOKUP table replaces 19 IF/THEN/GOSUB/SERTXD/GOTO blocks — each of those was several instructions.
- Execution speed: comparable or slightly better on average, since worst-case was 19 sequential comparisons before, and a table lookup is closer to constant time.
- Readability/maintainability: much easier to add or change a button mapping — one table entry instead of a whole new IF line.
- One thing I preserved rather than "fixed": if an unmatched button is held, RepCount stays whatever it was from before, which can slightly skew the pause timing on the next real button press. This was true in your original code too — I didn't change the behavior, just flagged it. If you'd like, I can make RepReset-style behavior trigger on unmatched codes too, but that changes behavior, so I left it as-is by default.
Sirc translator optimized
BAS
Looks good, I will try it on a chip and see what happens, thank!
Sounds good — good luck with it. If anything acts up on the chip (timing, a miskeyed mapping, whatever), just paste what you're seeing and I'll help track it down.