Category Archives: Programming

Getting Started with the ESP32 S2 Mini

Getting Started with the ESP32 S2 Mini

The ESP32 S2 Mini i s a small development board based on the ESP32-S2FN4R2 chip. The ESP32-S2 Mini by Wemos can be used as an Arduino, which is what this post covers. It can also be programmed in other ways, including with MicroPython, CircuitPython and with the chip manufacturer’s (Espressif) own software development kit.

Capabilities

The board can be used as an Arduino, although as with all different Arduino boards, it will have quirks that will mean some libraries will need special versions. This is the same as different boards within the Arduino family to a degree, and is often due to a mixture of hardware features being on different pins, or software maturity. It is worth pushing through these issues for the benefits the chip brings over a standard Arudino Uno or similar.

  • Processor Speed – 240MHz (32bit)
  • 3.3V Power and digital outputs, but 5v tolerant digital input pins (you can send it 5V signals without harm)
  • USB-C Connector
  • Wifi capable (can be turned off if not needed)
  • 4MB Flash (for programs, and for storing resources such as images, html files or sounds)
  • 2MB of RAM
  • 27 I/O pins
  • 12 Digital I/O pins
  • 18 Analogue Input Pins
  • 2 Proper Analogue Output Pins (not PWM)
  • 27 PWM Capable Pins
  • 27 Pins Serial Capable
  • Multiple I2C and SPI Busses

Note this specific chip doesn’t support Bluetooth (unlike other related products which sometimes do).

Reference Materials

Handy for looking up electrical specifications, the chip datasheet can be found here, and there is information on Arduino compatibility here.

The development board manufacturer has reference materials here and Arduino getting started here.

Pinout Diagram

Adding the Board to the Arduino IDE and First Test

  • Launch the Arduino IDE (I’m using version 1.8.9 on Linux).
  • Go to Tools>Boards>Board Manager, and type in “ESP32”.
  • Select and install Version 3.1 (3.1 is the newest at the time of writing – version 3.0.5 didn’t work properly for me) “esp32 by Espressif Systems” (not “Arduino ESP32 Boards”).
  • If “esp32 by Espressif Systems” doesn’t show up in the list when you search, go to File>Preferences and add the following text to the “Additional Boards Manager URLs” text box. If there is already text in there, you need to add it to the end, after a comma and a space.

The text to add : https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

Returning to the Boards Manager as above, you should now be able to see the “esp32 by Espressif Systems” option when you search.

  • From the Tools>Boards sub menu, pick the option LOLIN S2 MINI.
  • Open the Blink example from File>Examples>01.Basics>Blink.
  • Plug in the board using a USB-C cable.
  • Press and hold the button on the board labelled “0”, and briefly press the “Reset” button, wait another two seconds and then release the “0” button.
  • Select the board in the Tools>Port menu.
  • Click the “Upload” arrow.
  • Once the upload has finished, it might show an error, but regardless, press the “Reset” button on the board. The onboard LED should start blinking.

If you’re on Linux, you may need to set up USB permissions as per the instructions here.

If you have any issues, try a different USB cable. The first one I tried didn’t work properly (some don’t have all of the wires inside them).

A More Interesting Example

The most useful starting point is the provided example found at File>Examples>WiFi>WiFiAccessPoint. This example turns the board into its own WiFi network (separate to the house network). You can use your phone or laptop to connect to this network, and then load one or more web pages served up by a mini web server on the board. I often use this to provide an easy control interface (buttons and feedback). It is also possible to do firmware updates over WiFi, which can be very useful when the controller is buried deep in a machine. Obviously, make sure you use a password on the WiFi to stop other people messing with things.

Upload the WiFiAccessPoint example onto the S2 Mini board. I’m not certain why, but I had to completely power cycle my S2 Mini before the WiFi appeared.

Plug the S2 Mini into a USB port on your computer and open the serial monitor. Using your phone or laptop, connect to the WiFi access point that has the name yourAP. The default password is yourPassword. You should see information appear in the Serial Monitor, including the “host” IP. This is probably 192.168.4.1. Go to this address in your browser by entering http://192.168.4.1 or just click that link if you have this page open on the computer you connected to the S2 Mini with.

You should be presented with a simple webpage that has two lines of text, each with a link in it. The two links turn the LED on the board On or Off. Clicking them causes more activity in the serial monitor.

How Registration Details are Stored in ClarisWorks 2.0 and 2.1

How Registration Details are Stored in ClarisWorks 2.0 and 2.1

Where is the Registration Data Stored?

Older versions of Claris software store the registration details in the data fork. In the 68k only versions of software, it is the only information stored there and so deleting all data in the data fork resets the software to unregistered (only ever try this on a duplicate copy of the program) and you are prompted to enter new registration details when you next launch the software. This is how utilities such as Repersonalize clear the registered details in early Claris software, as well as Microsoft software.

PowerPC code in Mac applications is actually stored in the data fork, in both PPC and FAT applications. This means that running a program like Repersonalize on a PPC version will damage the application by removing all the PPC code. Looking at the data fork and comparing before and after registering a fresh copy, I found that the registration information is stored at the very end of the data fork and if you know which section it is, it can be still manually removed. I used the software Resorcerer which lets you view the data fork as well as the resource fork.

The first version of ClarisWorks to support PowerPC processors natively that I know of is version 2.1, and it is specifically 2.1CDv3 that I’ve been looking at. In this exact version, the data/code at the end of the PowerPC code in the data fork is “0012 24EC” and the first offset of the registration data is at offset 134448. This will likely vary between versions.

I might write an automated tool for this at some point if I can make sure it works with various versions.

How is the Registration Data Stored?

When you register ClarisWorks 2.1CDv3 (and some other Claris software), there are three fields, Name, Company and Serial Number. All three accept just about any text. The three strings are obfuscated, concatenated, and then appended to the data fork as three pascal strings. This means that the first byte of each string is the length of the string, and the three strings are joined together (each starting with their length).

The strings are not readable as stored because each character has been XOR’d with a number. Claris alternated between two numbers, 79 and 66 (at least in ClarisWorks 2.1CDv3). XOR means Exclusive OR, and is a binary operation. XORing a byte with another byte (which we’ll call Brian for clarity) effectively inverts (flips) any bits in the byte that match locations that are a ‘1’ in Brian, when viewed in binary notation.

For example, if our byte is 11110000, and Brian is 10101010, then XORing our byte with Brian will give the result “01011010” – we flipped every second bit. By applying Brian a second time, the bits are flipped back, and we get the original data.

You can work out what the XOR value is (i.e. Brian), if you have the input byte and the result, by XORing the original value and recorded result. So, because

Result = Byte XOR Brian

It is also true that…

Brian = Byte XOR Result

Remembering that in this case the byte is the ASCII value of a known letter in the registration details.

A Worked Example

Imagine we enter the following data into the three fields in ClarisWorks to register the software…

First, lets consider the easy bit. The first string is 8 characters long, the second is 7, and the third is 6. We now know that the three lengths that will be included will be those. I made a little spreadsheet to get the ASCII values of each letter, XOR it with 79 or 66, and then display the result in Hex.

Putting the lengths and three strings together in hex we would have…

080A 2E2A 3227 2321 3607 0C2A 2621 2427 2106 1C27 3D2B 2E2E

So lets check if we got it right by loading the registered copy of ClarisWorks in Resorcerer…

Yay! It matches, so I’m not daft. The reverse is also possible, lets start with the data as stored in the datafork…

So our hex data is…

060C 2E2E 3026 3105 182D 3D29 3C03 7D6C 7E

We can see the first byte is a 6 (in hex remember, but in this instance it is 6 in hex and in decimal), so we count 6 bytes, then one more, to find the next length… which is 05, so we count 5 bytes, then one more, and find 03. So our three strings are 6, 5 and 3 characters long. Lets make another spreadsheet.

Oh look, it says “Claris”, “Works” and “2.1”! If you would like a play, you can download the spreadsheet (in OpenOffice format, compatible with Excel and LibreOffice) here :

A Couple of Clone Arduino Linux Issues

A Couple of Clone Arduino Linux Issues

The serial port appears for a single second, and then vanishes before you can upload any code.

This has been happening to me with Pop OS, but apparently also happens with other Ubuntu variants. I can’t believe what the cause is, but if you check dmesg and you will possibly find the following occurring :

[   98.044600] usb 3-2: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice=81.33
[   98.044606] usb 3-2: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[   98.044607] usb 3-2: Product: USB Serial
[   98.046052] ch341 3-2:1.0: ch341-uart converter detected
[   98.046409] usb 3-2: ch341-uart converter now attached to ttyUSB0
[   98.608979] input: BRLTTY 6.4 Linux Screen Driver Keyboard as /devices/virtual/input/input41
[   98.887664] usb 3-2: usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1
[   98.888541] ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0

What we see happening is the OS finds the newly plugged in CH340 based serial device on your board and creates a new serial port, in my case, ttyUSB0. Excellent. But then, along comes “BRLTTY”. BRLTTY has decided it knows what this device is, removes the serial port and turns the device into an input / keyboard device. BRLTTY apparently knows best and claims all devices with the manufacturer / product ID of a USB to UART adapter chip, that is absolutely not always the product they think it is. This is really poor default behaviour, especially as this all happens silently. Apparently BRLTTY is accessibility software for the blind that is installed by default.

To solve the issue, assuming you’re not blind, simply type “sudo apt remove brltty” (without quotes) at the command line and it will be uninstalled, making the issue go away.

Not in Sync

The not in Sync error, where you get a repeated message such as the following :

avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00

… is an old one with many causes. One cause now seems to be that if you use a clone device, the Arduino IDE refuses to talk to it by default. The solution might be to change the “Processor” in the Tools menu to “ATmega328P (Old Bootloader)”. This would apply to boards such as Unos and Nanos. This might actually also apply to older genuine Arduino Boards.

As you might guess, I’ve had a slightly frustrating day. All I did was try to load a program into a clone board someone gave me the other day.

Overclocking the LC 475 in Software

Overclocking the LC 475 in Software

If you want to dive right in, it is recommended that you download and install the Control Strip Module version as this has the most up to date version of the software. The Control Strip Module version works in Systems from 7.1 through to 8.1, and supports overclocks in 24 bit addressing mode (my extension currently doesn’t). It also has better memory timings, and can often overclock slightly faster. It even has slightly different timings for the LC 475 and LC 575, to account for the difference in onboard memory speed. You can find a copy of the latest version on Macintosh Garden : https://macintoshgarden.org/apps/control-strip-475-overclock

The overclock is specifically designed to work with the stock 80ns RAM and VRAM in an LC 475 (etc.) And 70ns RAM in an LC 575.

A little while ago Mustermann posted on the 68kmla forums that he was doing some experiments relating to overclocking the LC 475 without any hardware modifications. This was being achieved by controlling the LC 475’s programmable clock from the LC’s memory controller. The same process is possible on similar hardware such as the Q605 and LC 575.

Mustermann was kind enough to share his source code, and so zigzagjoe made an extension version for a fixed speed of 40MHz. Using Mustermann and zigzagjoe’s code as a basis, plus code from cheesestraw’s github, I started extending the functionality of the extension, including adding boot-time status icons, the ability to dynamically generate parameters based on a target clock speed and the ability to read instructions from the resource fork. I then made a control panel (actually a small application programme) to present user friendly interface for changing the extension’s settings.

An initial version apparently worked on some people’s 475s, but only allowed 20, 25, 33 and 40MHz on my own LC 475. After much digging, Mustermann was able to work out that I was providing values in an incompatible format to his magic sauce function that set the arbitrary speeds. This was fixed and now means I’m happy that the extension works as expected and so find enclosed the current version of the software installer :

Download Soft 475 Overclock

(Updated to Version 0.5.2 on 23rd October 2024)

The latest version, 0.5.2, is mostly identical to version 0.5.1, other than it contains a bug fix in the Advanced mode, where previously the Max and Min values were not being correctly saved.

Requirements

  • An LC 475, Performa 475, Quadra 605, Performa 476, LC 575 or Performa 577
  • Mac OS 7.5 or later.
  • Do not use this software if you have replaced the speed setting resistors on your logic board with blobs of solder. You really shouldn’t do this, and I don’t expect people have, but if someone has, it may cause damage (not limited to in conjunction with this software).

Optionally…

  • A heatsink for your CPU.
  • Move the zero ohm resistor at R96 to the R95 position to adjust the SCSI clock for 33MHz and above on LC 475 style logic boards. Not on the LC 575 type board, it already is set up for faster speeds.
  • A faster grade CPU.

Using the Software

This .bin file contains an installer to run on your LC / Performa. It is pretty self explanatory. Once you’ve installed it, the software is “off” by default, so you’ll need to go to the “Soft 475 OC Setup” control panel and select what speed you want to try to run your computer at. This software will only work on the LC 475, Quadra 605, LC 575 and their Performa Equivalents. It may also work on the Apple STB. For an initial test, try selecting 33MHz from the menu, click “Set”, and then restart. Use Newer’s Clockometer software to verify the speed has taken. If this works, try 40MHz. If the computer crashes, or otherwise shows signs that it isn’t able to run at 40MHz, power off the computer, and power back on while holding the shift key to disable extensions. Once the computer has booted, use the control panel to set the overclock back to 33MHz or another speed known to work.

With some additional hardware modifications, namely changing the SCSI clock, replacing the clock multiplier with a higher grade chip and swapping in a higher grade CPU, I was able to get my LC 475 to run at 50MHz.

Selecting “Custom” from the “Select Speed” popup menu allows you to enter an arbitrary speed, recommended to be between about 20 and 40MHz, but depending on your exact configuration you might be able to go outside these bounds. You can enter fairly granular speeds, for example 37.6MHz, although Clockometer and other speed calculating software often isn’t accurate to this degree.

The “Advanced” option isn’t recommended unless you’ve read and understood the clock generator chip’s datasheet, but is there for users who want to exactly tweak parameters. Entering values in this dialogue box without understanding them will very likely just crash your computer.

LC 475 SCSI Clock Modification

For best compatibility while overclocking the LC 475 and other machines with the same logic board (not the LC 575 etc., which shipped with this modification as stock), it is beneficial to move the resistor located at R96 to the empty R95 position. This divides the SCSI clock by two and brings it back within specification. Note that this does not halve the performance of your SCSI bus. If you don’t do this modification, some people find that their computer crashes during large file copies, even at speeds as low as 33MHz. With this modification, the SCSI clock is within specification all the way up to 50MHz… if your computer still crashes, the issue is more likely your RAM (including onboard), VRAM or CPU grade. The good news is that all of these can be replaced with faster parts, although replacing the soldered RAM is a little tricky.

Potential Issues

When overclocking, sooner or later you will hit the limits of your hardware.

The first limit you reach is likely to be the SCSI clock on the LC 475 (not the LC 575, which is already set for higher speeds), meaning you’ll need to do the SCSI clock modification identified above. After that, you might want to fit a faster CPU, VRAM and RAM. Removing the RAM soldered to the logic board can help, and you don’t need to solder new RAM onto the board if you don’t want to, as long as you have a SIMM fitted. Remember the LC 475 can work with SIMMs up to 128MB in size, so the onboard RAM isn’t too critical.

I have also fitted an MC88916DW80 in place of the original XC88920 to hopefully improve performance at high speed. These can be bought from your favourite Chinese online retailer, although be cautious of re-labelled parts.

Once you exceed 40MHz, there will come a point at which you may have issues with the serial ports and floppy drive. I haven’t done extensive testing of this myself yet.

Note that most 25MHz 68LC040 CPUs will happily overclock to at least 33MHz, although it is always good to fit a heatsink. It is generally not a good idea to run an LC 475, and especially an overclocked one, with the lid off as the lid helps ensure airflow over the CPU and other components.

Future Development

Moving forward I’d like to add some more features and tidy up the user interface. Things I’d like to add include…

  • On the fly clock speed changes.
  • Estimated current speed display.
  • Holding numeric keys during boot sets predefined clock speeds.

Coming Soon… Cancelled

Version 0.6 was undergoing testing and has some cool new features, including the ability to set independent speeds for your 68040 and PPC601 if you have a PowerPC upgrade… which I don’t.

1728563016567.png
  • On the fly clock setting.
  • Independent speeds for 68040 and PPC.
  • Built in speed estimation.
  • Hopefully improved user interface.
  • Included speed change XCMD for use in your own projects.
  • Reduced file size for easy install from 800k floppy disks (possibly even 400k, depending on how much formatted space they have).
  • Technical improvements to ensure you don’t accidentally run the wrong control panel with the wrong extension.
  • A shutdown item that sets the speed back to the default for your computer, or you could just leave it on your desktop to reset to the baseline frequency manually.
  • Some pretty icons.
  • A visual indication of whether you are currently booted as a 68k or PPC Mac.

Sadly I’ve been unable to get the PowerPC upgrade specific code tested, as multiple months have passed I’m moving on from the project.

However…

… I made a Control Strip Module which allows on the fly speed switching (i.e. without needing to restart). I found this very helpful template to use.

The control strip module can be downloaded here. https://macintoshgarden.org/apps/control-strip-475-overclock

Thank you to the author of CSShell for permission to release it.

Feedback

Please let me know if this software works well for you. The github project can be found here the actual download for the software is near the top of this page and you’ve scrolled past it. Feel free to use the software as the basis of your own projects.

Using Smart Move on a Modern Computer

Using Smart Move on a Modern Computer

This page is a DRAFT as I do not currently have the correct hardware to fully test and debug the process. Feedback welcome, but do not rely on this being correct!

The Economatics Smart Box serial interface boxes used to come with a program called “Smart Move”. The software appears to have been available for a number of platforms (BBC Micro, RISCOS, MacOS and DOS), but I have only seen copies of the DOS software while searching. The software appears to load machine code directly into the memory of the Smart Box rather than sending serial commands. This is interesting as it goes some way to overcoming the speed limitations of the 9600 baud serial connection.

The following details my experiments in trying to get the DOS version of Smart Move running on a modern Linux computer, although most of the detail should also be applicable to other modern OSes. Note that the original DOS software will no longer natively run on Windows.

Step 1 – Get DOSBox

On Linux, DOSBox is installed from you packet manager of choice. If you’re using a Debian / Ubuntu style setup, you can just type “sudo apt install dosbox” at the command line.

Step 2 – Finding the Serial Port

If you don’t have a built in serial port (not many people do these days), you’ll need a USB to RS232 adapter. There are really cheap ones available, but just to warn you – I’ve been through two of the cheap ones that have a silver cable and blue plugs. I’d advise spending double the money and getting something that will last. I have one of these, which seems to be marginally better made.

On Linux, run the command “ls /dev/tty*” – this will list all available terminals (including serial ports). Now plug in your USB adapter, and run the same command again… an extra file should have appeared. This is your serial port. In my case, it is called “/dev/ttyUSB0”. If you’re using Windows, you’ll need to work out what COM port the device is connected as. Past experience on Windows says that sometimes you need to keep plugging into the same USB port to get the same COM port between sessions, but this might just be a permissions thing at work. On MacOS, the process for finding the name of the serial port is basically identical, except that the name of the port is usually a little bit different under MacOS.

Step 3 – Configuring DOSBox for Serial

Now that you have written down the exact name of your serial port (either something like “/dev/ttyUSB0” for Linux/MacOS, or “COM9” for Windows), open the DOSBox configuration file. On Linux, mine was located in “~/.doxbox/” and was called “dosbox-0.74-3.conf”. I opened it in nano to edit it by running “nano ~/.dosbox/dosbox-0.74-3.conf”.

Note that a foldername starting with “.” is an invisible folder on Linux. Additionally, it looks like the config file name will change depending on the version you have installed. The fastest way to open the file on Linux will be to type “nano ~/.dosbox/*.conf” and then press enter.

Details of where to find the config file on other platforms can be found here.

Within the now open config file, find the section titled “[serial]”. This can be done in nano by pressing “Ctrl-w”, typing “serial” and pressing enter. There are a load of examples / explanation lines which start with the “#” symbol indicating that they are comments. Scroll past these to where there are (in my file) for lines, each starting with “serial” and then a number. Modify the first of these lines, which starts with “serial1” to the following, substituting your own serial port (note on Linux, you do not need the “/dev/” as shown) :

serial1=directserial realport:ttyUSB0
serial2=dummy
serial3=disabled
serial4=disabled

Or perhaps on Windows :

serial1=directserial realport:COM9
serial2=dummy
serial3=disabled
serial4=disabled

Save and close the config file.

Get the Software

The following two downloads are the Smat Move DOS software for the Economatic Smart Box (“SmartV1-6”) and a DOS serial driver (“adf_150”). Both are needed to connect to the Smart Box.

The Smart Move software has kindly been made available here : http://flaxcottage.com/Oddments/default.asp – I have removed the “Finder.dat” file as this is a file added by MacOS and is not needed.

The driver comes from here : http://www.digsys.se/Obsolete/ADF.aspx.

Setup the Software

Extract the SmartV1-6 archive as a folder and store in a convenient location. You should now have a folder containing “SMART.EXE” and “AL.COD”. Create an additional folder called “Driver” within this first folder, and extract the contents of adf_150 into this folder.

Within the “Driver” folder, find the file “ADFCOM1.BAT”. Copy it, and name the copy “SBCOM1.BAT”. Open the file in a text editor. The contents should like like this :

@echo off
rem
rem Loading ADF for COM1
rem
rem    ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄCOM-port number, COM1-COM127.
rem    ³   ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄAddress in hex of COM-port, 0-FFFF.
rem    ³   ³  ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄIRQ number of COM-port, 0-15.
rem    ³   ³  ³      ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄLocked baud-rate, 1-115200.
rem    ³   ³  ³      ³     ÚÄÄÄÄÄÄÄÄÄÄSize of receive buffer, 256-16384.
rem    ³   ³  ³      ³     ³     ÚÄÄÄÄSize of transmit buffer, 256-16384.
rem    ³   ³  ³      ³     ³     ³  ÚÄReceiver FIFO trigger level, 1, 4, 8, 14.
rem    ³   ³  ³      ³     ³     ³  ³
adf COM1 3F8  4  57600  8192  8192  8
rem                        ³        ³
rem    ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ        ³
rem    ³               ÚÄÄÄÄÄÄÄÄÄÄÄÄÙ   Advanced options:
rem    ³               ³
rem 8192,7168,6144 16650,16,8    3  11
rem         ³    ³        ³ ³    ³   ³
rem         ³    ³        ³ ³    ³   ÀÄ Modem Control Register.
rem         ³    ³        ³ ³    ÀÄÄÄÄÄ Line Control Register.
rem         ³    ³        ³ ÀÄÄÄÄÄÄÄÄÄÄ 16650 Transmit FIFO trigger level:
rem         ³    ³        ³             8, 16, 24 or 30.
rem         ³    ³        ÀÄÄÄÄÄÄÄÄÄÄÄÄ 16650 Receive FIFO trigger level:
rem         ³    ³                      8, 16, 24 or 28.
rem         ³    ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Flow control continue or restart.
rem         ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Flow control hold or stop.
rem

Edit the line “adf COM1 3F8 4 57600 8192 8192 8”, replacing the number “57600” with “9600”. This is the serial baud rate (the speed of the connection). 57600 baud is way too fast for the Smart Box, which runs at 9600 baud. Save the changes and close the file.

As an aside, 9600 is 9600 bytes per second, plus one stop bit. If I remember correctly about this, this means that 9 bits are sent for every 8 bits of data, which is why technical people get irritated when you say 9600 bits/second instead of baud.

Run the Software

With the USB serial adapter connected, the Smart Box connected and the Smart Box powered on, launch DOSBox in the folder containing “SMART.EXE” (but don’t actually use it to run any specific program, we just want it to open at the command line). On linux this is done by navigating to the folder you want to start in in the terminal, then running “dosbox ./”. I can only assume it is the same under Windows, but I do not have any way of testing. Windows user can get a command line by typing “cmd” straight after opening the Start menu, and then pressing enter.

At the DOSBox command line, enter “cd DRIVER” to move into the Driver folder. Then enter “SBCOM1.BAT” to run the serial driver setup script we modified with a 9600 baud rate.

This should tell us “ADF loaded.” and dump us back at the command prompt.

Enter the command “cd ..” to return to the parent directory. The command “dir” shows us the files in this folder which should include “SMART.EXE”. Enter the command “SMART.EXE”.

At this point the Smart Move software is running. You should see “FOSSIL detected” showing that the serial driver is running and working with Smart Move.

Unfortunately, this is as far as I have got. The software sits at this point with a spinning progress glyph until it times out ages later. I am not yet sure if the issue is because I have the more modern SB-04 (this will surely cause issues as it must speak a different assembly language, and doesn’t have as much RAM as the older 6502 based variants?), or I have more software issues to solve. Hopefully this will be solved if either I get my hands on an SB-01, or someone else tests these instructions for me 🙂

Note the copyright notice names G.W.Babb – a name that is all over the internet, but I haven’t found any recent forum posts by him to ask for help tracking down the software. Gareth – if you’re still about, please get in touch with us as we’re trying to bring the Smart Boxes back to life and would love to know more about loading code into RAM and executing it!

Smart Box Analogue Sensor Types

Smart Box Analogue Sensor Types

Based on the responses from the “ReadSensorTable” command in my Economatics Smart Box SB-04, I’ve concluded that the following official sensor exist :

IndexNameVal1Val2Units
3Temp range 1TmpTempdegC
4Voltage range 1VVoltsmV
5Temp range 2TmpTempdegC
6Voltage range 2VVoltsvolts
7Temp range 3TmpTempdegC
8Voltage range 3VVoltsvolts
9Temp range 4TmpTempdegC
10Sound (standard)SndSound?
11pHpHpH?
13PositionPosPostndeg
17Light (standard)LtLight?
21R’HumidityHmdHumid%RH
22Sound range 1SndSounddbA
23Light range 1LtLightLux
24Sound range 2SndSounddbA
25Light range 2LtLightLux
26Barometric PressureAtmAtmosmBars
27Light range 3LtLightLux
28User adaptorUAUser?
290-1 Volt adapatorVAdapt?
30Temp (low range)TmpTempdegC
31Light gateLGLGate?
33Temp (standard)TmpTempdegC

There is more data being fed back by the box regarding these sensor types, but it is a little bit of a pig to understand as my terminal is reading it as escape characters. I suspect it would be easier to understand if I had some official sensors myself. I suspect that some experimentation is in order! I’ll connect a variable voltage to the detection pin and watch what sensor types the box detects at each voltage. With an ADC connected to my computer I might be able to automate the process… but that is probably more effort than it is worth.

Smart Box List of Commands

Smart Box List of Commands

Having got a copy of the Economatics Smart Box “Operating System Serial Protocols” document curiosity of John and flaxcottage.com, I noted that one of the commands returns the name of a command based on the provided command number. Given that the instruction manual is most likely for an older version of the Smart Box (mine is an “SB-04”, rather than the older “SB-01”), which is build around a 6502 processor rather than the Mitsubishi microcontroller in mine, I wrote a short program which iterates through every command number between 0 and 99 and returns the “CodeName”. The following table shows the resulting output – I’ve also included room for other Smart Box variants for when I get access to one, or if someone runs the same program for me.

Command No.SB-01SB-01/EVSB-04
0Blank*Blank
1VersionVersion
2ResetReset
3NameCodeNameCode
4CodeNameCodeName
5MultipleSetupMultipleSetup
6MultipleReadMultipleRead
7MultipleServerMultipleServer
8IdentSystem
9CreditsCredits
10WriteMotorsWriteMotors
11ReadMotorsReadMotors
12MotorForwardMotorForward
13MotorReverseMotorReverse
14MotorHaltMotorHalt
15MotorPowerMotorPower
16PatchMF*PatchMF
17MotorVoltage
20WriteOutputsWriteOutputs
21OutputPowerOutputPower
22GetSensors*GetSensors
23CheckSensors*CheckSensors
25ReadSensorTable
28SetBitHighSetBitHigh
29SetBitLowSetBitLow
30ReadADCReg*
31WriteADCReg*
32ReadACIAReg*
33WriteACIAReg*
34ReadVIAReg*
35WriteVIAReg*
36SetVIAHigh*
37SetVIALow*
40ReadADCReadADC
41ReadADCsReadADCs
42ForcedADCReadForcedADCRead
44HighResADCHighResADC
45LowResADCLowResADC
47ReadResolutionReadResolution
50DownloadDataDownloadData375
52UploadDataUploadData375
54ExecuteCodeExecuteCode375
55StoreByteStoreByte375
56ReadByteReadByte375
57ReadRAMSize
59ExtendCall
60SetClockSetClock
61ReadClockReadClock
62ReadTopmem
63WriteTopmem
64ReadLomem
65WriteLomem
66ReadHimem
67WriteHimem
90ReadInputsReadInputs
91ReadBitReadBit
92ReadOutputs
93CountReset
94CountRead

Items marked with a * in the SB-01 column are undocumented. The SB-01 commands were taken from a machine belonging to mph1708 on the stardot.org.uk forums. The machine was running ROM OS 2.073 dated 12/07/96.

The program I used is as follows – don’t forget to change the serial port from “/dev/ttyUSB0” to whatever is applicable on your setup :

#!/usr/bin/python
import time
import serial

ser = None

def getCommandName(cmd):
        global ser
        if ser.is_open:
                ser.write(chr(4)+chr(cmd))
                time.sleep(0.2)
                readText = ""
                while ser.inWaiting() > 0:
                        readText += ser.read(1)
        return readText

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)

x=0
while x<100:
	theText = getCommandName(x)
	if len(theText)>1:
		print str(x)+" : "+theText
	x+=1

ser.close()

Please let me know if you have any interesting results via my contact page.

Things to note looking at the results, compared to the available documentation…

  • Command 0 (Blank) is undocumented
  • Command 8 (IdentSystem) is undocumented
  • Command 9 is called “Credits” instead of “Copyright”
  • The documentation contains both “MotorHalt” and “MotorPower” (an typo?) as Command 14. The SB-04 box reports Command 14 as “MotorHalt” and Command 15 as “MotorPower”
  • Command 16 (PatchMF) is undocumented
  • Command 17 (MotorVoltage) is undocumented – this is not a surprise as some older Smart Boxes used a key to change voltages, whereas it seems that this is a software feature on the SB-04
  • Command 22 (GetSensors) is undocumented. I assume this reports what sensor types are connected?
  • Command 23 (CheckSensors) is undocumented
  • Command 25 (ReadSensorTable) is undocumented
  • The documentation contains both “SetBitHigh” and “SetBitLow” (an typo?) as Command 28. The SB-04 box reports Command 28 as “SetBitHigh” and Command 29 as “SetBitLow”
  • Command 43 is not present on the SB-04. This is “ReadSensor” and may have been replaced by Command 22, 23, and 25
  • Commands 50, 52, 54, 55 and 56, all of which relate to accessing the Smart Box memory and executing the contents of the memory, have been renamed with “375” on the end. I believe this refers to the microcontroller type? I am surprised to see they are still implemented at all.
  • Commands 51 and 53 have been omitted. These commands related to transferring data to and from the Smart Box using an Xmodem transfer format (with and without error checking)
  • Command 57 has been omitted (ReadRAMSize)
  • Command 58 has been omitted (ReadModule). This command seems to be for identifying some kind of hardware additions fitted to the equipment when the Smart Box was used embedded within a machine or similar.
  • Command 59 has been omitted (ExtendCall) this seems to be a method by which additional commands could be added and it seems unfortunate that it has been excluded. Reference is made to “Appendix B, machine code programming”. Unfortunately I don’t appear to have a copy of this appendix.
  • Command 62 is omitted (ReadTopMem)
  • Command 63 is omitted (WriteTopMem)
  • 64, 65, 66 and 67 (“ReadLoMem”, “WriteLowMem”, “ReadHiMem” and “WriteHiMem” respectively) are all omitted
  • Command 93 (CountReset) is undocumented. I guess this is a hardware counter, but don’t currently know what input it is connected to.
  • Command 94 (CountRead) is undocumented. I guess this is a hardware counter, but don’t currently know what input it is connected to.

I’d be very interested to run the same program on an older Smart Box to see if there are any undocumented commands there. A fair few commands appear to have been removed for the SB-04, many of which were likely difficult or impossible to implement on the microcontroller as opposed to the full 6502 embedded computer that existed before.

Working with the Economatics Smart Box Serial Interface on a Modern Computer

Working with the Economatics Smart Box Serial Interface on a Modern Computer

Well, I had all sorts of fancy plans for how I would reverse engineer the serial protocol to control my ebay purchase “Smart Box” (some of which I will document at some point as they’re useful). Ultimately, I had so much difficulty installing MS .net 1.1 in Wine / PlayOnLinux that I went back to trawling the internet looking for alternative software to wire tap.

Smart Box
Smart Box

I struck gold when I found the following website :

http://old.ftcommunity.de/ftComputingFinis/smartboxe.html

The website includes a download of example code, the core of which is in VB6 and includes many serial commands for controlling the Smart Box (SB-04 version – I understand that older versions work differently, so be warned!), as well as an instruction manual that goes some way to explaining how the box data formats work.

After a bit of messing about in Python, it was fairly trivial to test a number of commands and witness the results. The only major feature I’m not currently sure about is the Analogue Inputs – I don’t know what the pinout is of the 5 pin DIN sockets, and so can’t easily test them. Perhaps a bit of circuit board investigation will help with this.

In summary, I have found the following :

DescriptionCommandParameterResponsePython Example
Set All Motors108 bit value. Note, each pair of bits represents a motor. 01=left, 10=right and 00=stopn/aser.write(chr(10)+chr(0b01010101)) # rotate all motors to the left
Motor <x> Left121 to 4n/aser.write(chr(12)+chr(1)) # rotate motor ‘A’ to the left
Motor <x> Right131 to 4n/aser.write(chr(13)+chr(1)) # rotate motor ‘A’ to the right
Motor <x> Stop141 to 4n/aser.write(chr(14)+chr(1)) # stop motor ‘A’
Set All Digital Outputs208 bit valuen/aser.write(chr(20)+chr(0b11111111)) # turn all digital outputs on
Get Analogue <x>40 (TBC)1 to 48 bit value??ser.write(chr(40)+chr(1)) # send me analogue input ‘A’
Set Low Resolution Analogue45 (TBC)n/an/aser.write(chr(45)) # set low resolution analogue mode
Get All Digital Inputs90n/a8 bit value. Note the command seems to respond with three bytes, although the first identifies the status of each input.ser.write(chr(90)) # send me the status of the digital inputs
Get Digital Input <x>91 (TBC)1 to 80 or 1 (in 8 bit value)ser.write(chr(45)+chr(1)) # send me the status of digital input 0

The following example switches on motor ‘A’ for 5 seconds, stops it for 0.5 seconds, runs it backwards for 2 seconds and then stops it. Note the serial port will need setting – I have used ‘/dev/ttyUSB0’ as this is the correct port for my USB to RS232 adapter on my Linux machine.

#!/usr/bin/python

# https://elephantandchicken.co.uk/stuffandnonsense
# 04/03/2020

import time
import serial

# This example tests motor output A

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)

ser.write(chr(12)+chr(1))
time.sleep(5)
ser.write(chr(14)+chr(1))
time.sleep(0.5)
ser.write(chr(13)+chr(1))
time.sleep(2)
ser.write(chr(14)+chr(1))

ser.close()

The following example reads the status of all digital inputs (aka “Digital Sensors”) 20 times.

#!/usr/bin/python

# https://elephantandchicken.co.uk/stuffandnonsense
# 04/03/2020

import time
import serial

# This example reads in the digital sensors and displays their status

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)

# Flash Digital Outputs to show that the program is running
ser.write(chr(20)+chr(255)) # all on
time.sleep(0.1)
ser.write(chr(20)+chr(0)) # all off
time.sleep(0.1)

i = 0

while i < 20:
	ser.write(chr(90)+chr(1)) # request digital input status
	time.sleep(1) # wait (ages) for the response
	readVal = 0 # clear variables
	readByte = 0
	readByte = ord(ser.read(1)) # read the first waiting byte in the buffer
	while ser.inWaiting() > 0: # if there is more data in the buffer
		readVal = ord(ser.read(1)) # read it to clear it
	print "result : ",format(readByte, '08b') # print the first byte in boolean format
	i+=1 # increment counter for the while loop
ser.close()

I still have some more work to do, regarding confirming exactly how these commands work (for example, what are the second and third bytes from the digital read response?). Additionally, I suspect that it is possible to set the voltages, but don’t know how. I’m (absolutely) guessing that command 11 might be motor speed.

Additionally, please contact me if you know any more details of the control scheme, or the analogue port pinout.

68008 SBC LCD Control

68008 SBC LCD Control

The following is my first attempt at controlling the LCD on my Wichit Sirichote (URL updated 2024 to new website) Single Board Computer. Please forgive any terrible programming as I’m not very familiar with assembly language, and even less so with 68k assembly language programming. I’ve tried to make the code a little modular so the subroutines can be re-used. I previously described the software setup I’m using to program the board from Linux here. There are two versions of the same program (almost) in this post, the second of which animates the little stickman using interrupts for timing.

; Hardware Locations in Memory
gpio1		equ	$f0000		; LED PORT
lcdcw		equ	$60000		; LCD command WR
lcddw		equ	$60001		; LCD data WR
lcdcr		equ	$60002		; LCD command RD
lcddr		equ	$60003		; LCD data RD

; LCD Commands
lcdbsy		equ	$80		; LCD BUSY
lcd8bt		equ	$38		; Select 8 bits interface
lcdinc		equ	$06		; Entry Mode - Increment
lcddcb		equ	$0E		; Display On, Cursor On, Blink OFF
lcddnc		equ	$0C		; Display On, Cursor Off, Blink Off
lcdoff		equ	$08		; Display Off, Cursor Off
lcdclr		equ	$01		; Clear Display
lcd1st		equ	$80		; Set first line start
lcd2nd		equ 	$C0		; Set second line start

; Program location in memory
		org 	$400		; start of program

START
		move.l	#stack,a7	; sure
		move.w	#$2100,sr	; what these do
		bsr 	subinit		; initialise LCD
		bsr 	subcust		; send little man
		bsr 	subclr		; clear screen
		bsr 	subrow1		; go to home address
;send text
		lea	text1,A2	; get address of text string
		bsr 	subsend		; send the text located at A2
		bsr 	subrow2		; go to second line
		lea 	text2,A2	; next line text address
		bsr 	subsend		; send it
loop		jmp	loop		; forever

; ---------------------------------------------------

sublcdr	; wait for lcd ready
		movem.l	D0-D1,-(sp)
		move.w	#$ffff,D1
lcd_bu0
		move.b	(lcdcr),D0
		andi.b	#lcdbsy,D0
		beq.s	lcd_bu1
		dbra	D1,lcd_bu0
		moveq	#1,D1
lcd_bu1
		movem.l	(sp)+,D0-D1
		rts

subinit ; set up the display
		move.b	#lcd8bt,(lcdcw)	; write command $38 - 8 bit mode
		move.b	#lcd8bt,(lcdcw)
		move.b	#lcd8bt,(lcdcw)
		bsr	sublcdr		; wait for ready
		move.b	#lcdinc,(lcdcw)	; write command $06 increment cursor
		bsr	sublcdr
		move.b	#lcddnc,(lcdcw)	; display on, cursor off, blink off
		rts

subclr	; clear the display
		bsr	sublcdr		; wait for ready
		move.b	#lcdclr,(lcdcw)	; write command $01, clear display
		rts

subrow1	; go to first line
		bsr	sublcdr
		move.b	#lcd1st,(lcdcw)	; write command $80, first line start
		rts
	
subrow2	; go to second line
		bsr	sublcdr
		move.b	#lcd2nd,(lcdcw)	; write command $C0, first line start
		rts
	
subsend	; send string that starts at A2, and ends with zero
		movem.l	D0,-(sp)
ss1		bsr	sublcdr
		move.b	(A2)+,D0
		beq.s	senddone
		bsr	sublcdr
		move.b	D0,(lcddw)
		bra ss1			; blt next
senddone
		movem.l	(sp)+,D0
		rts

subcust	; create and send a custom character
			bsr	sublcdr
			move.b	#$48,(lcdcw)	; custom char 0 edit
			lea man,A2		; send data for man (note, can't have 0 in data)
			bsr	subsend
			rts

; string to display, terminating with zero
text1		dc.b	'This is a M68008',0
text2		dc.b	1,' Doing Stuff! ',1,0	; 1 gives special char 1. (a little man)
man			dc.b	%01110,%01110,%00100,%01110,%10101,%00100,%01010,%01010,0

ram	ds.b	32		; not sure
stack		equ	*	; what these do

This second version uses interrupts for timing a simple animation, but there is more code that I do not understand in it, so please forgive me if there are non-critical errors. The code isn’t very efficient in its use of data registers.

; Hardware Locations in Memory
gpio1		equ	$f0000			; LED PORT
lcdcw		equ	$60000			; LCD command WR
lcddw		equ	$60001			; LCD data WR
lcdcr		equ	$60002			; LCD command RD
lcddr		equ	$60003			; LCD data RD

; LCD Commands
lcdbsy		equ	$80			; LCD BUSY
lcd8bt		equ	$38			; Select 8 bits interface
lcdinc		equ	$06			; Entry Mode - Increment
lcddcb		equ	$0E			; Display On, Cursor On, Blink OFF
lcddnc		equ	$0C			; Display On, Cursor Off, Blink Off
lcdoff		equ	$08			; Display Off, Cursor Off
lcdclr		equ	$01			; Clear Display
lcd1st		equ	$80			; Set first line start
lcd2nd		equ 	$C0			; Set second line start

; Program location in memory
		org 	$400			; start of program

START
		move.l	#service_level2,$68	; not
		move.l	#stack,a7		; sure
		move.w	#$2100,sr		; what these do
		move.b	#$0,d2
		move.b	#$0,d3
		move.b	#0,d4
		bsr 	subinit			; initialise LCD
		bsr 	subcust			; set up little man in char 1 & 2
		bsr 	subclr			; clear screen
		bsr 	subrow1			; go to home address
;send text
		lea	text1,A2		; get address of text string
		bsr 	subsend			; send the text located at A2
loop		cmpi.b	#1,d4			; Don't re-send if you've already done so
		bge	loop			; loop if already shown
		bsr	subrow2			; pre-move to the start of the second line
		cmpi.b	#1,d3		
		blt	alt			; go to alt if d3<1
		lea 	text2,A2		; send text2
		bsr 	subsend			; send it
		move.b	#1,d4
		bra	loop
alt		lea	text3,A2		; send text3
		bsr	subsend
		move.b	#1,d4
		bra	loop			; forever - note jmp is an absolute address, bra is rel

; ---------------------------------------------------

service_level2
		addi.b	#1,d2		; increment d2
		cmpi.b	#50,d2		; check if d2 is 50 or more
		blt	skip		; rte if not 50
		clr.b	d2		; reset d2 to 0
		move.b	d3,gpio1	; debug code - shows status on leds
		clr.b	d4		; reset "don't send again" value
		addi.b	#1,d3		; increase d3 (which line 2 to send)
		cmpi.b	#2,d3		; check if d3 is too big
		blt		skip	; if it isn't, finish
		clr.b	d3		; if it is, make it = 0
skip		rte			; return

sublcdr	; wait for lcd ready
		movem.l	D0-D1,-(sp)
		move.w	#$ffff,D1
lcd_bu0
		move.b	(lcdcr),D0
		andi.b	#lcdbsy,D0	; check if the lcd is busy
		beq.s	lcd_bu1
		dbra	D1,lcd_bu0
		moveq	#1,D1
lcd_bu1
		movem.l	(sp)+,D0-D1
		rts

subinit ; set up the display
		move.b	#lcd8bt,(lcdcw)	; write command $38 - 8 bit mode
		move.b	#lcd8bt,(lcdcw)
		move.b	#lcd8bt,(lcdcw)
		bsr	sublcdr				; wait for ready
		move.b	#lcdinc,(lcdcw)	; write command $06 increment cursor
		bsr	sublcdr
		move.b	#lcddnc,(lcdcw)	; display on, cursor off, blink off
		rts

subclr	; clear the display
		bsr	sublcdr				; wait for ready
		move.b	#lcdclr,(lcdcw)	; write command $01, clear display
		rts

subrow1	; go to first line
		bsr	sublcdr
		move.b	#lcd1st,(lcdcw)	; write command $80, first line start
		rts
	
subrow2	; go to second line
		bsr	sublcdr
		move.b	#lcd2nd,(lcdcw)	; write command $C0, first line start
		rts
	
subsend	; send string that starts at A2, and ends with zero
		movem.l	D0,-(sp)
ss1		bsr	sublcdr
		move.b	(A2)+,D0
		beq.s	senddone
		bsr	sublcdr
		move.b	D0,(lcddw)
		bra 	ss1					; blt next
senddone
		movem.l	(sp)+,D0
		rts

subcust	; create and send a custom character
		bsr	sublcdr
		move.b	#$48,(lcdcw)	; custom char 0 edit
		lea 	man,A2		; send data for man (note, can't have 0 in data)
		bsr 	subsend
		rts

; --------------------------------------------------------


; string to display, terminating with zero
text1		dc.b	'This is a M68008',0
text2		dc.b	2,' Doing Stuff! ',1,0	; 1 gives special char 1. (a little man)
text3		dc.b	1,' Doing Stuff! ',2,0	; 2 gives special char 2. (a little man arms up)
man			dc.b	%01110,%01110,%00100,%01110,%10101,%00100,%01010,%01010,%01110,%01110,%10101,%01110,%00100,%00100,%01010,%01010,0

ram	ds.b	32		; not sure
stack		equ	*	; what these do