Requesting an assessment of "Claude's" updating of my old, primitive Picaxe program

wapo54001

Senior Member
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:

  • 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
Go ahead and paste the code, or upload the file, and let me know which PICAXE chip you're targeting (e.g. 08M2, 18M2, 20X2, etc.) since some commands and memory limits vary by chip — that affects what optimizations are actually possible.

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).
Created a file, read a file

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.
Want me to also extend the table to cover Enter (101) and Menu (96) so they're ready to re-enable, or keep the table capped at 39 to save memory?

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.
 

Attachments

Here's another version of your PICAXE code.

Interesting how different engines produce completely independent results. This was created using the Gemini Flash 3.6 AI engine. Over a year ago it produced "PURE DUFF", today! it's much better. Although, it still once in a while has a response like; "I'm sorry, I think I was hallucinating...". Oh! it does veer off course at times too. The results really depend on the vocabulary used with the particular engine. Most times I just have to say "SHUTUP" when it spews out garbage. I find you always can control the results. I have locked up the engine (meaning it could not provide any answer) twice with my off center logic.

Compiles: 140 BYTES

Code:
'## The Hybrid PICAXE Code

#picaxe 08M2
#no_data
'#terminal 9600
SETFREQ m8                  ' Run clock at 8MHz for fast execution

' --- PIN ASSIGNMENTS ---
' IR input = C.3 on 08M2
' Output on serial out pin

' --- SYMBOLS ---
SYMBOL RxData      = b0     ' Stores incoming SIRC code
SYMBOL Last        = b1     ' Stores previous SIRC code
SYMBOL RepCount    = b2     ' Tracks key repeat level (0 to 10)
SYMBOL MapIndex    = b3     ' Index helper for code translation
SYMBOL OutChar     = b4     ' Ascii character to transmit
SYMBOL PauseLength = w3     ' Changed to w3 (b6/b7) to completely avoid b4/b5 overlap

' --- MAIN PROGRAM LOOP ---
main:
    ' Listen for IR signal. 500ms timeout resets repeat logic.
    IRIN [500, RepReset], C.3, RxData

    ' Clear previous character match state
    OutChar = 0

    ' COMPACT LOOKUP: Maps Sony codes directly to compressed index positions (0 to 19)
    ' No empty zeros needed. Ready for Menu (96) and Enter (101) to be uncommented.
    LOOKDOWN RxData, ("1","2","3","4","5","6","7","8","9","0", 18, 19, 20, 38, 39, 27, 28 ,96, 101), MapIndex
    LOOKUP MapIndex, ("1","2","3","4","5","6","7","8","9","0","C","D","E","H","I","H","I","M","L"), OutChar

    ' Guard against invalid lookup positions (LOOKDOWN defaults to 0 if unmatched)
    IF RxData <> "1" AND MapIndex = 0 THEN SetPause

    ' If code matches an assigned character, process and send it
    IF OutChar <> 0 THEN
        GOSUB Rep
        SERTXD (OutChar)
    ENDIF

SetPause:
    ' YOUR PARABOLIC ACCELERATION MATH
    ' Smoothly ramps down delay from 201ms to 1ms as RepCount goes from 0 to 10
    PauseLength = RepCount * RepCount * 2
    PauseLength = 201 - PauseLength
    PAUSE PauseLength

    RxData = 255            ' Clear state to prepare for next loop iteration
    GOTO main

' --- SUBROUTINES ---
Rep:
    ' If it's a held key, increase speed multiplier up to a safe cap of 10
    IF RxData <> Last THEN
        RepCount = 0
    ELSE
        RepCount = RepCount + 1 MAX 10
    ENDIF
    Last = RxData           ' Track history
    RETURN

RepReset:
    RepCount = 0
    GOTO main


Three-Way Comparison Matrix - via GEMINI
Feature / Metric1. Your Original Code2. Gemini
LOOKDOWN / LOOKUP
3. Claude
Direct-Index Code
Execution Speed🔴 Slowest
(Scans every IF line by line until a match is found)
🟡 Medium-Fast
(Performs a rapid sequential search through a tight list)
🟢 Fastest
(Instantly jumps directly to the array index without scanning)
Memory Consumption (Code Size)🔴 Highest
(Each repetitive IF/THEN block uses lots of program bytes)
🟢 Lowest
(Extremely compact; no zero-padding bytes required)
🟡 Medium
(Saves space on logic, but loses space padding empty zeros)
Ease of Adding High Codes (e.g., 96, 101)🟢 Easy
(Just add another IF line)
🟢 Easiest
(Just add code to list A, and letter to list B)
🔴 Hardest
(Requires adding 60+ zeros to pad the lookup string)
Key Repeat Ramping Profile🟡 Stepped
(Jarring jumps between Slow, Medium, and Fast)
🟢 Smooth Curve
(Uses your parabolic math to ramp speed fluidly)
🟢 Smooth Curve
(Uses your parabolic math to ramp speed fluidly)

Don't seek to be known, seek to know, and the world will seek to know you. Matthew 7:7-12
 
Last edited:
Interesting, very! The comparison is fascinating and informative. The last time I remember AI being discussed here, it was simply not useful at all, and now it's amazing, at least in my eyes.

I was pretty delighted with what I got from Claude, and I'm going to try it again -- I'm going to ask it to look at my really long calibration routine. As I recall, I over-killed it by calibrating at something like fifteen points along the log volume control curve and I'm going to ask how many points I actually need to accurately track the curve along with optimizing the code. This is very exciting because my coding experience is limited and very old and out of date and I'm arriving at my 81st BD shortly and I'd have to start over to relearn current coding practices before I did anything so I'd probably never finish!

Do you think Gemini still would have offered its own code if it had started with Claude's which is already perfectly current, or would it have just said the code is fine?

Would I be better served by using a different AI to clean up my code? If so, which would it be (while not spending big bucks every month!)?
 
Last edited:
I got a syntax error with the Gemini code when I checked it in PE6 -- Gemini commented out the close parenthesis and "mapindex' and 'outchr' along with the optional two other codes. So, not perfect, but darn near!
 
You grabbed the code very fast before I could correct it in the code above.

Also ya know, it did suggest a fix that wasn't applied.
' No empty zeros needed. Ready for Menu (96) and Enter (101) to be uncommented.

Code:
error line: notice the message the single quote between 28 and 96,  "I" and "M"
   LOOKDOWN RxData, ("1","2","3","4","5","6","7","8","9","0", 18, 19, 20, 38, 39, 27, 28 ' ,96, 101), MapIndex
    LOOKUP MapIndex, ("1","2","3","4","5","6","7","8","9","0","C","D","E","H","I","H","I" ' ,"M","L"), OutChar

fixed:
   LOOKDOWN RxData, ("1","2","3","4","5","6","7","8","9","0", 18, 19, 20, 38, 39, 27, 28, 96, 101), MapIndex
    LOOKUP MapIndex, ("1","2","3","4","5","6","7","8","9","0","C","D","E","H","I","H","I","M","L"), OutChar

Edit what you grabbed to fix it.

Do you think Gemini still would have offered its own code if it had started with Claude's which is already perfectly current, or would it have just said the code is fine?
I fed Gemini both, your original code and from Claude, to get the code I posted above. Then asked for a compare and got the analysis table.
 
Last edited:
A year ago lesser-known variants of languages, like Picaxe Basic, would trip up these LLMs. Now they do a decent job of it, but you should still closely review the output. Sometimes patterns from other languages are used to do things like declare variables, etc.
 
I consider the fact that Claude reported the sertxd command and the variable naming limits b0-b27/w0-w13 as being features of PICAXE BASIC a very good sign that it understands the correct BASIC syntax to use for PICAXE programs.

I checked ChatGPT, Claude, GLM, Gemini and Qwen and, ignoring those products that cloned the PICAXE system:
  • Only two other dialects of BASIC also used the b0-b27/w0-w13 variable naming convention, Parallax PBASIC and melabs PICBASIC.
  • No other dialect of basic defines the sertxd command.
 
Back
Top