Foobler notes - 1 - "Getting Started"

You’re correct – PicoMite and WebMite were not made with a device like the PicoCalc in mind, and the active users and developer on TheBackShed have little to no interest in supporting the PicoCalc. Largely that’s due to the way Clockwork simply took their software without asking or notifying them, did a somewhat quick and dirty port, and released it as part of the PicoCalc without proper attribution/license. I think the license/attribution thing has been resolved since, but there have been discussions on TheBackShed about how they should make and sell a better device to compete with the PicoCalc, and even an initial discussion of how they considered purposely making the firmware incompatible or difficult to use on PicoCalc. TLDR: there’s been drama.

Since Clockwork rarely does any kind of ongoing software with their devices, and since I wanted to try the newest versions of PicoMite/WebMite on the PicoCalc (rather than the arguably ancient and buggy one that was officially ported by Clockwork), and since it seemed most other development was focusing on MicroPython, uLisp, and Forth, I decided to try to update the PicoMite/WebMite port and created a clean fork from the official git repo.

Functionally it should be the same as the latest official PicoMite or WebMite, but the WebMite firmware for PicoCalc has one “hidden” feature. It actually includes the GUI controls from PicoMite. (The official manual will claim WebMite doesn’t have GUI controls, which is true outside of PicoCalc.) There was interest on the forums here to include them and they seemed to work so I kept them in all PicoCalc builds. GUI controls do seem to be deprecated in the official release though, so maybe it was a mistake for me to include them in WebMite. They also seem to be a bit buggy, and I don’t get the impression they were ever used much or tested well.

It’s worth noting that WebMite seems to be hardly used by enthusiasts on TheBackShed, and seems to be largely considered something to use as a headless webserver and for collecting simple forms of data via unencrypted connections (It doesn’t support HTTPS or SSL, and likely never will.) MMBasic users over there seem to have little interest or use in wireless access or usage via their Pico modules, and PicoMite seems to mostly be used as an offline “retro computer” or “game console” most often connected to a display via HDMI or VGA.

All of this has made the PicoCalc port of PicoMite (and especially WebMite) a curious beast. And since I am just an enthusiast and PicoCalc owner myself, and not connected to Clockwork or TheBackShed in any other way, it makes supporting the “unofficial” PicoCalc port difficult. It will probably never gain some useful features for the PicoCalc hardware (like Bluetooth) since the developer and enthusiasts on TheBackShed have no interest or use in such things. WebMite will probably always have unfortunate tradeoffs like the lower CPU speed for sake of stability compared to PicoMite which can be clocked faster but has no wireless capability. And the bulk of graphics programs written in MMBasic will use commands like TILE and SPRITE which are not supported on anything other than HDMI and VGA displays, which means they won’t work on PicoCalc.

Sorry for the long off-topic digression, but I figured the GUI controls info and HDMI/VGA graphics info were relevant, and unfortunately it required a lot of context to make any sense.

It’s really cool to see the code you’ve been posting, and other people’s code sharing posts here and on git repos! I hope the PicoCalc continues to be fun for everyone with PicoMite/WebMite though I wanted to be honest about the state of things, and I have the feeling that to get the most use out of the hardware it’s necessary to consider using one of the more fully featured (and perhaps supported) options like MicroPython, uLisp, Forth, or Arduino development on the PicoCalc. I don’t plan to abandon the PicoCalc port of PicoMite/WebMite any time soon, but it’s unlikely to ever be more than just a port of the official release with support for the custom hardware (keyboard, display, pin assignments) of the PicoCalc.

EDIT: added links to various referenced topics

6 Likes

Also, note that the latest version of the (draft) manual is available for PicoMite/WebMite V6.00.02.

PicoCalc versions can’t use anything marked as “only for” HDMI or VGA, but LCD related display stuff should work. There are various PicoMite things that are unsupported in WebMite (for instance background FRAMEBUFFER copy). So reading the docs is kind of a puzzle, to figure out what is actually supported on the PicoCalc, and it depends on whether you use PicoMite or Webmite. While it would nice to have a PicoCalc version of the documentation, it probably isn’t feasible since the official version is a moving target and the documentation is… extensive.

The PicoCalc version currently has a few extra commands. I’ll keep these updated on the git repo if they change or more are added. There’s a known issue related to the battery charging indicator – it has a bit of a delay. This is due to how often the internal STM32 updates that information.

Information Command Decription
MM.INFO(BATTERY) PICOCALC ONLY
Returns the current battery level percentage (0-100).
MM.INFO(CHARGING) PICOCALC ONLY
Returns 1 if battery is charging on external power, 0 if battery is not charging.
Option Command Decription
OPTION BACKLIGHT KB brightness PICOCALC ONLY
Sets the brightness of the keyboard backlight. ‘brightness’ is a value between 0 (backlight off) and 255 (maximum brightness).
1 Like

The community on TheBackShed’s always been a bit 'ornery and defensive, and while ClockworkPi definitely put their noses out of joint, they also make it tricky to do right by them in the first place. Best to treat them with full respect, but keep your limbs well away from their teeth. I’d actually recommend not posting questions there unless you happen to own an actual MaxiMite.

1 Like

I’m pretty sure sprites are fully supported on the LCD PicoMite/WebMite but only on a framebuffer. Just do everything on the framebuffer and then copy to the physical screen when required. There is a demo posted https://www.thebackshed.com/forum/ViewTopic.php?TID=17906&PID=238435#238435 but I haven’t run it myself.

1 Like

Right, the framebuffer can be used as a workaround, but the “SPRITE” command, which I was referring to in my post is not supported, as the official manual indicates. Lots of graphics example code uses the SPRITE command on TheBackShed, so if those examples were to run on the PicoCalc, they’d need to be partially rewritten.

1 Like

The example I posted a link to uses the Sprite command and runs on an LCD PicoMite. Just tested on an ILI9488 480x320 Pico2. Try it.

Option console serial
FRAMEBUFFER create
FRAMEBUFFER write f
CLS
'brownian motion demo using sprites
Dim integer x(32),y(32),c(32)
Dim float direction(32)
Dim integer i,j,k, collision=0
Dim string q$
For i=1 To 32
direction(i)=Rnd*360 'establish the starting direction For each atom
c(i)=RGB(Rnd*255,Rnd*255,Rnd*255) 'give each atom a colour
Circle 9,9,9,1,,RGB(white),c(i) 'draw the atom
Sprite read i,0,0,19,19 'read it in as a sprite
Next i
CLS RGB(myrtle)
Box 1,1,MM.HRES-2,MM.VRES-2
k=1
For i=MM.HRES\9 To MM.HRES\9*8 Step MM.HRES\9
For j=MM.VRES\9 To MM.VRES\9*8 Step MM.VRES\5
  Sprite show k,i,j,1
  x(k)=i
  y(k)=j
  vector k,direction(k), 0, x(k), y(k) 'load up the vector move
  k=k+1
Next j
Next i
'
Do
For i=1 To 32
  vector i, direction(i), 1, x(i), y(i)
  Sprite show i,x(i),y(i),1
  If sprite(S,i)<>-1 Then
    break_collision i
  EndIf
Next i
FRAMEBUFFER copy f,n
Print Timer:Timer =0
Loop
'
Sub vector(myobj As integer, angle As float, distance As float, x_new As integer, y_new As integer)
Static float y_move(32), x_move(32)
Static float x_last(32), y_last(32)
Static float last_angle(32)
If distance=0 Then
  x_last(myobj)=x_new
  y_last(myobj)=y_new
EndIf
If angle<>last_angle(myobj) Then
  y_move(myobj)=-Cos(Rad(angle))
  x_move(myobj)=Sin(Rad(angle))
  last_angle(myobj)=angle
EndIf
x_last(myobj) = x_last(myobj) + distance * x_move(myobj)
y_last(myobj) = y_last(myobj) + distance * y_move(myobj)
x_new=Cint(x_last(myobj))
y_new=Cint(y_last(myobj))
Return

' keep doing stuff until we break the collisions
Sub break_collision(atom As integer)
Local integer j=1
Local float current_angle=direction(atom)
'start by a simple bounce to break the collision
If sprite(e,atom)=1 Then
  'collision with left of screen
  current_angle=360-current_angle
ElseIf sprite(e,atom)=2 Then
  'collision with top of screen

current_angle=((540-current_angle) Mod 360 )
ElseIf sprite(e,atom)=4 Then
  'collision with right of screen
  current_angle=360-current_angle
ElseIf sprite(e,atom)=8 Then
  'collision with bottom of screen
  current_angle=((540-current_angle) Mod 360)
Else
  'collision with another sprite or with a corner
  current_angle = current_angle+180
EndIf
direction(atom)=current_angle
vector atom,direction(atom),j,x(atom),y(atom) 'break the collision
Sprite show atom,x(atom),y(atom),1
'if the simple bounce didn't work try a random bounce
Do While (sprite(t,atom) Or sprite(e,atom)) And j<10
  Do
    direction(atom)= Rnd*360
    vector atom,direction(atom),j,x(atom),y(atom) 'break the collision
    j=j+1
  Loop Until x(atom)>=0 And x(atom)<=MM.HRES-sprite(w,atom) And y(atom)>=0 And y(atom)<=MM.VRES-sprite(h,atom)
  Sprite show atom,x(atom),y(atom),1
Loop
' if that didn't work then place the atom randomly
Do While (sprite(t,atom) Or sprite(e,atom))
  direction(atom)= Rnd*360
  x(atom)=Rnd*(MM.HRES-sprite(w,atom))
  y(atom)=Rnd*(MM.VRES-sprite(h,atom))
  vector atom,direction(atom),0,x(atom),y(atom) 'break the collision
  Sprite show atom,x(atom),y(atom),1
Loop
End Sub
3 Likes

Interesting! It does work!

I guess the documentation in the manual is wrong.

3 Likes

What a very detailed and helpful reply! Thank you. It is quite useful to hear the history and backstory that explain our current PicoCalc situation.

I am happy to have a PicoCalc and to explore Basic on it. I’d be happy to see similar devices emerge from other sources. I’d be happy to try out other firmware. I wonder if I should find a ZIF socket for core modules.

My intent with this thread is to encourage and educate others, and to gain and share knowledge, maybe learn new things myself.

1 Like

Wow, that’s cool! The sprite code worked on the PicoCalc, no problem!

Getting programs directly from Android onto the PicoCalc:

Browsed this forum post in this thread using the Android phone, found and then copied the Brownian Motion code to the phone’s clipboard.

Used “Simple Text Editor” app to save the copied code into a text file, “t2.bas”.

Then used the “Serial USB Terminal” app to connect to the PicoCalc with a cable with USB-C connectors on each end. 115200, 8N1 for the serial connection. Sent an “Enter” and got back a “>” prompt.

In the “Serial USB Terminal” app’s menu, chose “Upload file”, “xmodem”, then selected the file to begin the transmission.

On the PicoCalc, started a XMODEM RECEIVE "t2.bas", and got the file.

Good evening lads, got some more apps out today :slight_smile: Calculators

2 Likes

DefineFont looks fun.

I started off by trying to create a one entry font with one 8x12 fake character. Lessee, the codes were

DefineFont #9
   0130080C

   A0BF80FF
   AAABA8AF
   AAAAAAFE
End DefineFont

font 9

print chr$(48)

…and maybe that works, if I didn’t make a typo?

the first eight hex digits should be read in pairs: 01 chars in font, starts at offset 30, width 8 pixels, height C which is 12 pixels.

Then the data for the pixels, grouped in chunks of 4 hex pairs, in backwards order.

I’d recommend downloading the full PicoMite release archive here:
https://geoffg.net/Downloads/picomite/PicoMite_Firmware.zip

You can ignore the firmware binaries since they won’t work on the PicoCalc, but there is useful documentation and some useful tools.

For fonts, check out the “Embedded Fonts” folder, and have a look at “Font Tweak”. It’s not exactly user friendly, but it can get the job done. I used it along with some manual edits to create/adapt a couple of fonts.

Also, see this thread for some additional discussion and background:

1 Like

Well, how about a 5x5 pixel character? That should be easy!

It wasn’t easy. It was worse.

Started with an attempt at lighting up pixels in a 5x5, was confused at where dots appeared. Okay, dammit, then I will walk a bit through the 8 hex digit codewords and see what happens!

Draw a 5x5 grid, decide on a numbering scheme for squares, then as I turn on a bit in the code word, I noted what it lit up.

Then I drew a 4x4 letter “A” and turned on all the bits needed to make it appear.

Whee!




2 Likes

How long will the PicoCalc run on two 2600mAh 18650 batteries?

The newer 6.00.xx firmware offers mm.info(battery) and mm.info(uptime), so i could watch those and make a graph.

But I am already working on something in the program buffer, and don’t want to disturb that. Oh, what if I do a command line one-liner?

for n = 1 to 1200: print mm.info{battery),mm.info(uptime):pause 300000:next n

Then I can make a graph…manually…using…a pencil and a sticky note.

Depends on both backlight levels, processor speed and what programs are running !. Using two 4000Mah batteries here…

1 Like

Well, if a 5x5 font has weird layout, at least I could probably manage a 8 pixel wide by 12 high font, because the layout is reasonable. I found a copy of the Font Tweak exe program, but don’t have a windows machine to run it on. I tried emulation with WINE on Linux, but can’t run a 32b binary.

So I just used a pad of paper and chose pixels by hand, viewing and modifying.

I wasn’t going for legibility, but playing with the idea of making as many letters refer to a square shape as I could. Squares! Blockhead!

Something from Hofsteder’s book from decades ago?

'blockhead font

DefineFont #9
60200c08
'space
00000000
00000000
00000000
'!
0c0c0c00
0c0c0c0c
000c0c00
'"
14141400
00000000
00000000

14000000
77007714
00001414
'$
7f140000
017f4040
00147f01
'%
71000000
17007452
00004725
'amp
22223e00
25140814
00003d22
''
08080800
00000000
00000000
'(
20100800
20202020
00000810
')
08102000
08080808
00002010
'*
00000000
14361422
00000022
'+
00000000
08360808
00000008
',
00000000
00000000
001c0404
'‑
00000000
003e0000
00000000
'.
00000000
00000000
000c0c00
'/
04040000
10100808
00002020
'0
22223e00
222a2a2a
00003e22
'1
08081800
08080808
00001c08
'2
02023e00
203e0202
00003e20
'3
02023e00
020e0202
00003e02
'4
22222200
023e2222
00000202
'5
20203e00
02020c30
00003e02
'6
10080800
22223e20
00003e22
'7
02023e00
08080402
00000808
'8
22223e00
223e003e
00003e22
'9
22223e00
0804023e
00000808
':
00000000
00000000
000c000c
';
00000000
00000000
001c000c
'<
04000000
10201008
00000408
'=
00000000
7e007e00
00000000
'>
10000000
04020408
00001008
'?
02023e00
001e0202
00001e00
'@
7f000000
5f555d41
00007f41
'A
22140800
7f414141
00004141
'B
7f417f00
41414141
00007f41
'C
40407f00
40404040
00007f40
'D
41427c00
41414141
00007c42
'E
7f407f00
40404040
00007f40
'F
7f407f00
40404040
00004040
'G
4f407f00
41414141
00007f41
'H
7f414100
41414141
00004141
'I
01017f00
01010101
00007f01
'J
01010f00
41410101
00007f41
'K
44424100
44685048
00004142
'L
40404000
40404040
00007f40
'M
49497f00
41414141
00004141
'N
51614100
41434549
00004141
'O
41417f00
41414141
00007f41
'P
41417f00
407f4141
00004040
'Q
41417f00
45494141
00007f43
'R
41417f00
447f4141
00004142
'S
7f407f00
01010101
00007f01
'T
01017f00
01010101
00000101
'U
41414100
41414141
00007f41
'V
41414100
42414141
00007844
'W
41414100
49494141
00007f49
'X
14224100
41221408
00004141
'Y
7f414100
01010101
00007f01
'Z
02017f00
20100804
00007f40
'[
10101c00
10101010
00001c10
'\
10202000
04080810
00000204
']
04041c00
04040404
00001c04
'^
22140800
00000000
00000000
'_
00000000
00000000
00007f00
'`
04081000
00000000
00000000
'a
7f000000
41790101
00007f41
'b
7f404000
41414141
00007f41
'c
7f000000
40404040
00007f40
'd
7f010100
41414141
00007f41
'e
7f000000
404f4141
00007f40
'f
7f407800
40404040
00004040
'g
7f000000
41414141
7f017f41
'h
7f404000
41414141
00000041
'i
7f000f00
01010101
00000001
'j
7f000f00
01010101
0f010101
'k
41404000
54484442
00004162
'l
40000000
40404040
00007f40
'm
7f000000
49494949
00004949
'n
7f000000
41414141
00004141
'o
7f000000
41414141
00007f41
'p
7f000000
41414141
40407f41
'q
7f000000
41414141
01017f41
'r
7f000000
40404040
00004040
's
7f000000
017f4040
00007f01
't
7f404000
40404040
00004040
'yoo
41000000
41414141
00007f41
'v
41000000
42414141
00007844
'w
49000000
49494949
00007f49
'x
41000000
14081422
00004122
'y
41000000
41414141
7f017f41
'z
7f000000
10080402
00007f20
'{
08080400
10201008
04080808
'|
08080800
08000808
08080808
'}
08081000
04020408
10080808
'~
00281400
00000000
00000000
'del is nonprinting
End DefineFont

Font 9

'Print "THE QUICK BROWN FOX"
'Print "JUMPED OVER THE LAZY DOG"

Print
  For n = &H20 To &H7f
    If n Mod 16 = 0 Then
      Print
    End If
    Print Chr$(n);
  Next n

Sub review_font
  For n = &H20 To &H7f
    CLS RGB(gray)
    Text 160,100,Chr$(n),C,9,10
    Pause 1000
  Next n
End Sub

2 Likes

Thanks for the example of an oscilloscope. The background flickers because it needs to be redrawn each time. So I thought I could use this as a test of the FRAMEBUFFER commands. I also added timer interrupts to try to ensure that the measurements are regulated by the clock. I added one timer at 1ms intervals for the measurements and a second at 400 ms for the redrawing. I also replaced the pixels with lines. My image sample is the background mains (60Hz). Pressing “S” in the program saves the “BMP” image.

My code:

Option console serial
Option explicit
Const margin=20
Const width=320
Const height=320
Const maxt=width - margin
Const measure_freq = 1 'ms
Const redraw_freq=500 'ms (> maxt)
Const xdiv = 50 'ms divisions

Dim volt(maxt)
Dim t As integer = 0 'global time

SetPin GP28, AIN  'data input PIN28

' draw the oscilloscope graph into
' the frame buffer, so we can blit
' it to screen each time we update
FRAMEBUFFER create
FRAMEBUFFER write f
CLS
draw_grid


'now draw to screen
FRAMEBUFFER write n

On key check_keys
'set up interupts
'  1 ms for measurements
'  400 ms for refreshing display
SetTick redraw_freq,draw_trace,1
SetTick measure_freq,measure,2
Do
  'wait for interupts
Loop

Sub draw_grid
  Local integer x, y, n
  Local dgrn = &H00AA00

  For y=0 To 300 Step 60
    Line margin,y,width,y,,dgrn
  Next y
  Line margin,300,width,300,,dgrn

  For x=margin To width Step xdiv
    Line x,0,x,300,,dgrn
  Next x
  Line width,0,width,300,,dgrn

  For n=0 To 4
    Text 0, 295-n*60,Str$(n)
  Next n
  Text 9,10, "V","RB"

  For n=0 To 5
    Text margin+xdiv*n,310,Str$(n*xdiv),"CT"
  Next n
  Text margin+maxt,310, "ms","RT"
End Sub

Sub draw_waveform
  Local integer i=0
  Local integer x0,y0,x1,y1
  x0=margin
  y0=volt(0)
  For i=0 To maxt-1
    x1=margin+i: y1=volt(i)
    Line x0,y0, x1,y1,, RGB(white)
    x0=x1: y0=y1
  Next i
  t=0 'reset global time counter
End Sub

Sub measure
  If t<maxt Then
    volt(t) = 300 - Int(Pin(GP28)*60)
    t=t+1
  End If
End Sub

Sub draw_trace
  SetTick 0,0,2
  FRAMEBUFFER copy f,n
  draw_waveform
  SetTick measure_freq,measure,2
End Sub

' save to file if "S" is pressed
Sub check_keys
  Local k$
  k$=Inkey$
  If UCase$(k$)="S" Then
    'deactivate timers
    SetTick 0,0,1
    SetTick 0,0,2
    'save file
    Save image "oscill.bmp"
    'reactivate timers
    SetTick redraw_freq,draw_trace,1
    SetTick measure_freq,measure,2
  End If
End Sub

3 Likes

A little bumpy !. For more accurate and less noisy a-d measurements you might need to add a precision reference to your core ADC_VREF pin like the one below (easy job and on my to-do list). Not sure if it should be 3 or 3.3v tho…

To get this noise I had just attached a floating wire to GP28. If I terminate it at GND or the 3.3V pin there is very little noise. I don’t have a signal generator on me at the moment, so the mains noise had to do as a proxy signal for my display.

1 Like