Showing posts with label Raspberry Pi. Show all posts
Showing posts with label Raspberry Pi. Show all posts

Monday, March 30, 2020

ZX80 Replica

I always had a soft spot for the original ZX-80 computer. Never owned one since it was too expensive for me when it was released, and now I got the money it is still too expensive. Even though almost 50000 units were made, lots of them were lost over the years due to the bad build-quality. So €200-€500,- on eBay is not uncommon for a unit in good condition. 
The original ZX80
When I started building my first 3D printer it was always in the back of my head that it could be used for creating a ZX-80 replica. That did not really work out, since it was too inaccurate and the effective build plate was just too small. 
But my new printer has a build plate of 210x210 and it prints significantly better, so now is the time to build my own ZX-80.
Fortunately, thanks to the current retro computing revival, there are a lot of resources.First there is the ZX80 replacement keyboard on Sell My Retro. This is an excellent keyboard, with actual tactile switches, which makes it much easier to type on than the original. Also available:
original rivets, again on Sell my Retro.
And the design files are on Thingiverse. These were not exactly to my liking, so I made quite some changes. Mainly to make them easier to print, and to make sure that the new keyboard would fit.

There are a lot of images available, but most are just showing the complete computer from the front or side. There are lots of images on this site that also show the rear, bottom and inside. I used these to refine my 3D design, which is now available on Thingiverse.

And if you don't want or cannot print the case yourself, it is also available as a complete printed part on Shapeways. It's not cheap (about € 140,- for the set) but it obviously has a smoother finish and the bottom part is in one piece.

First part : the top cover. 

It took 27.3 hours to print, but turned out really nice. Unfortunately  there was some warping on the edges, but not too bad and I can probably correct this by heating it a little. And 4 solid layers for the top was not enough to completely hide the support structure, so the honeycomb pattern is still vaguely visible on the surface.

Part two : the bottom section.

Since I could not print the whole bottom section on my printer I had to split it into two parts. By adding some support and making some minor changes to the basic shapes, I ended up with two printable pieces that can be bolted and glued together.

The electronics

The internals are based on a Raspberry Pi Zero W. This is nice and small, and has enough power to emulate a ZX80. Since I wanted to make it close to the original I decided the rear connections had to be the same as on the original unit. 

Three 3.5 mm jack sockets, an RCA jack and the board edge connector. The manual shows what is connected where:

If we just apply 5V to the power jack we can connect that straight to the RPi (pin  2,4 and 6 on the header). The RCA jack can be connected to the TV out connection :



 The keyboard

 The ZX 80 or ZX81 keyboard is a simple matrix-keyboard. 
Original keyboard schematic


It is actually 2 matrices of 4 x 5 each, and we will need 5+8 = 13 I/O pins to read it. Most people use an Arduino to read the matrix and emulate a standard USB keyboard. And I actually went the same route when converting a C64 to USB keyboard. Since space in the ZX80 case is limited it would be nice to read the keyboard straight into the Pi. The Pi has 27 GPIO pins so that should be enough. Unfortunately the GPIO pins are spread almost at random over the connector, and some pins are better not used (like 0 and 1). But since we can just map IO pins in software this is not so relevant and I just connected both keyboard cables to all GPIOs on the left side (1..39)

Numbering scheme:
KB1      5 ,4 ,3 ,2 ,1  KB2 6,4,2,1 ,3 ,5 ,7 ,9
GPIO     19,13,6 ,5 ,11     2,3,4,17,27,22,10,9
WiringPi 24,23,22,21,14     8,9,7,0 ,2 ,3 ,12,13


Note that I also mounted the 8 diodes in the KB2 lines, but I mounted them the other way around as compared to the original schematic.Basically this does not matter, it just inverts the logic as used in the software to read the pins. As I had already written the software before I notice that the diodes were reversed I decided to leave it that way.


To keep the PCB in place I simply bolted it to a small piece of wood that I taped to the bottom using some double sided tape.

Software

Reading the keyboard

Controlling the IOpins on an RPi is easiest using the wiringPi library, which is already installed on Raspbian. Check if this is really the case by typing 'gpio -v' on the command-line. If it is there it will return the copyright and version info. Typing 'gpio - readall' will give the pin-mapping from the GPIO to WiringPi pin numbers.

Since I'm not the first one to read a matrix keyboard, I quickly found a Python project that does exactly what I wanted. This was created by Mr PJ Evans, and he did exactly what I'm trying to do now, only for a Spectrum.The Python code was not hard to translate to C.
I added one special combined key command to force a soft reset:

SHIFT + '1'  + SPACE  :Reset the ZX80(soft reset)

The Emulator

There are plenty ZX80 / 81 emulators available, but I needed one that was written in C, open source, and not too complex so I could inject my own keyboard reading code. I looked at Zesarux, which is a great emulator that supports teh full range of Sinclair computers. This however also makes it quite a massive project. And most of the naming and comments are in Spanish, which makes a bit hard for me to find my way around. 
So I opted for the SZ81 project. Since this is just for emulating the ZX80 and ZX81 it is much smaller. I assumed it was just a matter of finding where the keyboard is read, and add my own function to read it from the hardware keyboard. Which is partially true: I could get it to work for entering basic commands and running it. But as soon as the emulator switches to 'special' modes like loading or saving a file the program uses all kind of tricks to send virtual  keyboard, joystick and mouse commands. And these always seem to conflict with the keys as pressed on the keyboard so after several days I just gave up on this one too.
So I went one step back, to the original xz81 emulator which SZ81 was based on. This uses standard X-Windows, and is pretty basic :http://www.svgalib.org/rus/z81.html. It's already an old project, and the source code is only available as a .ZIP file. 

My version, with the keyboard reading routine, is available on GitHub.Note that I included the ZX80.rom and ZX81.rom file. This may be somewhat illegal, as mentioned by most emulator projects, but since they are that easy to find at multiple places I thought it would be rather odd not to include them.
You can check out the project using the following command:

git clone https://github.com/Cees-Meijer/ZX81-RPi.git

Before compiling it, make sure you have installed the X11 development libraries:

sudo apt-get install libx11-dev           // for X11/Xlib.h
sudo apt-get install libxt-dev
sudo apt-get install libxtst-dev 

It is set to compile for ZX80, but if you want the ZX81 version you can change the line:
int zx80=1;  in 'common.c' to int zx80=0;

The scaling is set to 2 in the Makefile:

XDEF=-DSCALE=2 -DMITSHM

This is the right setting for using the composite video output. When using the standard HDMI output this can be set to 3 or maybe even 4.

Build the software:
sudo make xz81
Install everything to the right position:
sudo make install
Make sure the ZX80.rom and / or the ZX81.ROM file are in '/usr/local/lib/z81/'. (This should be taken care of by the 'sudo make install' ).

Setting up the Pi

When the emulator starts it will take a while to boot and show all the Raspbian images and start screen, which does not add to the retro feeling. So I first considered using the pipaOS distro, which is also used by  'Obsolescence Guaranteed' for the PiPDP-8. This is very lightweight and boots really fast. But in the end I did have to install XWin, GCC and GIT anyway, so it's probably simpler to start with the standard Raspbian Lite.

First use raspi-config to enable SSH, so you can use FileZilla to transfer files to the system. (Interfacing Options->SSH). By doing this first you make sure that if something goes wrong, and you get stuck in the emulator, you can still access the Pi.
Next go to boot options, and make sure it boots automatically using the 'Console Autologin' option.


Under 'Advanced settings', disable screen blanking ! This is very important, or else the screen will go blank after 10 minutes, and since there is no 'real' keyboard attached it will not come back again if you press a key on the ZX80 keyboard.

To start the emulator automatically on startup, edit the rc.local file:

 sudo nano /etc/rc.local 

Add the line:
 sudo xinit /home/pi/projects/ZX81-RPi/xz81 &

Right before the 'exit 0'. (Don't forget the ampersand '&'  on the end)

If this works, you can follow the instructions on how to remove all Raspbian boot images and texts.

We can speed up the boot time by adding the following lines to boot/config.txt:

 # Disable bluetooth 
 dtoverlay=pi3-disable-bt
 # Set the bootloader delay to 0 seconds. 
 boot_delay=0

Also in config.txt are the settings for the video output. To make sure the composite video output works, check these two lines:

#uncomment to force a a HDMI mode rather than DVI
 #hdmi_drive=2

#uncomment for composite PAL
 sdtv_mode=2

(or any of the other 5 available video modes)
Note that though 'hdmi_drive' is commented out, the Pi will likely still boot on HDMI if a HDMI monitor is connected.


Finishing touch: the stickers

After some research I found that the size of the 'sinclair ZX80' logo is 27 x 70 mm. That was enough to scale the image that I already found somewhere and so create some really nice stickers. 


The .pdf is available here. When printed on glossy sticker sheets they look really good.

Zesarux

Currently ZEsaRUX is one of the best ZX type emulators. As mentioned, I have looked into this one but decided not to use it for my project. For reference I do include some suggestions on how to compile and use it.
The program is only available as source code, but there are instructions on how to build it on the Raspberry Pi as well.

When running Raspbian Lite from the command line, we will have to start from there.
First : Install GIT
$ sudo apt-get install git
Next install SDL
$ sudo apt-get install libsdl1.2-dev
Now I created a folder zesarux in my ./Projects folder and cloned it as follows:
$ sudo git clone https://github.com/chernandezba/zesarux.git
This does require that you have a GitHub account yourself, as it could ask you for your username and password !

cd /usr/src/zesarux/zesarux/src 
We must be in the src directory of the zesarux project


 $ export CFLAGS=-O2
 $ export LDFLAGS=-O2




 $ sudo ./configure --enable-raspberry


If this command executes successfully it will create the make file.

    $ sudo make clean
    $ sudo make

The 'make' command will start the compiling. This will take a while. On the Rpi Zero it took about 3 minutes.
According to the docs, The recommended way to start the emulator is using the following settings:
--disableborder --zoom 1 --fullscreen --vo fbdev --ao sdl --no-detect-realvideo

$ ./zesarux  --disableborder --zoom 1 --fullscreen --vo fbdev --ao sdl --no-detect-realvideo
And yes, this works! after selecting the ZX80 in the menu we get a very realistic ZX80 screen.




It doesn't always work as expected. When starting it from a system with full Raspbian I got the emulator just in the top left corner, and had to add --zoom=4 to get to fullscreen.
Since I wanted it to start as ZX80, I also added the --machine ZX80 option. 

Sunday, March 05, 2017

LoRa with the LoRa Bee

For some time already LoRa is the new hype. This Long Range Low Power radio technology makes it possible to send small amounts of data over long distances using very little power. I's associated mainly with the LoRaWAN network and IOT applications, but LoRa itself is just the radio and the low-level protocol that is used to transmit and receive bytes. You could just use two transceivers to transfer data one to one, not using any network protocol or dedicated access points.

As I wanted to start experimenting with LoRa at lowest possible costs I bought a set of LoRa Bee modules from Dragino. At US$36 ( including shipping) for a set of two, it was the cheapest option at the time (Second half of 2016). That they also came with a neat antenna was definitely a plus.
But when it became time to actually connect them and send some data,I found this a little bit harder than expected.
First the 'Bee' form factor itself. Its got a 2 mm pitch header that will not fit a standard breadboard. And the pins are too small for standard female to male jumper wires.
Second it is 3.3V only. So I bought an Arduino Mini Pro, 8MHz - 3.3V version, and made some jumper wires from an IC socket and a standard header.
It's connected as follows: NSS-10, MOSI-11, MISO-12, SCK-13.

The WAZIUP LoRa Project


Next we need some software to drive it. And here it gets a bit harder. There are so many options, many extensively documented but usually in an experimental state. I found the article by Congduc Pham, 'A DIY low-cost LoRa gateway' to come closest to what I wanted to achieve. And it actually contains a lot of information on connections, theory and applications. Professor Pham developed a simple protocol for just transferring data from multiple end-points to  central server, without the overhead of the full LoRaWAN stack. All this as part of a 'WAZIUP' project that aims to bring this type of networking to sub-Saharan African countries.
By just following the instructions in the .pdf it's easy to install the program to the Arduino and get the software on the Raspberry pi.

A few pitfalls that I found while getting this all to work:


- The instructions tell you to clone the GIT repository . But GIT is not installed by default on  Raspbian. Use the following commands to get it :

$ sudo apt-get update
$ sudo apt-get install git-core

- Compiling the Lora Gateway software for Raspberry Pi B+. Since it is a B+, I compiled it for the the Raspberry Pi 2 , but later I found that my board is the original Raspberry Pi B+, which actually is a Raspberry 1. So if nothing happens after you start the lora_gateway, check your version.

- Minimal time between messages. I started with the 'Arduino_LoRa_temp' program, but I changed the time between messages on the Arduino to 1 minute  ( idlePeriodInMin = 1; ).  After a while I noticed that the gateway did not receive every message, but actually only one in two. It looks like the software limits the amount of transmitted bytes per hour. After increasing the interval to 2 minutes it worked fine. When using the 'Arduino_LoRa_InteractiveDevice' program I noticed that this has no limitations, and you can send multiple messages with short intervals. Officially there is a limit on the available radio time (Time On Air or ToA) of 1%, meaning you should not have actual transmissions for more than a total of 3.6 seconds per hour. This is explained in section 29 of the FAQ.


- The driver software is called SX1272.cpp, but I have a RF95 . The SX1272 is identical to the RF-95 as used on the Lora Bee.

- When the messages are received on the gateway, but the message itself is unreadable they ar probably AES encrypted, and the gateway does not decode this. For testing it's easier to disable AES. Just comment out the define:
//#define WITH_AES

- CAD = Channel Activity Detection.
- SIFS =  Short InterFrame Space

What it looks like on the RPi when it's running:

(And a minor issue, actually only related to the Rasperry Pi: SSH is now disabled on Raspbian. I could not connect through SSH to my Raspberry Pi running Raspbian Lite. An article on the RPi site explains that on newer version SSH is disabled by default. It also has the solution: just add a file 'ssh' to the root folder of the SD card. Make sure you change the password..)

What's really cool about the code is that mr. Pham made clever use of the ArduPi library so the code for the Raspberry Pi and the Arduino is (almost) identical.

LoraWan

When you want to go for a solution that is compatible with the LoraWan network, I suppose nothing beats the simplicity of the LoPy, an integrated module with Lora, WiFi and bluetooth, programmed in Pyton. There is a nice introduction on Element14.

Using LoraWan and the associated 'The Things Network' requires a nearby gateway. Which, if none is available, you can build yourself. At a total cost of about €200,- this is definitely not a bad deal. But if that's a little too much for just  some simple experiments you can also build a super cheap single channel gateway.