Sunday, November 29, 2020

Python Hardware Sequencer Part I: PNG to CV Converter

 For anyone else out there living under a rock: there's a not so new kid in town for us DIY freaks, the SBC--doh, "single board computer". Cool, we all have seen these. How can we use SBCs in our endless pursuit of audio DIwhY craziness?  Lots of ways; too many ways? But OK, how about a synth sequencer/CV logger based on a Raspberry PI running Python with a untraditional UI? 

Why/whynot?

I already messed with Python and an SBC to create simple blinkenlites using PyGame--post is here.  

Recently I created another SBC python program that turns a PNG image into a series of Y-values along an X axis. From here, I figure it'll be easy to turn these Y values into CVs using a I2C D to A converter, with each Y value buffered then going to the sequencer's output, when a trigger or clock is received on a GPIO pin.

So this PNG business is a first step in my attempt to make a sequencer whose I/O is "diff'rent".

PNG PONG? I got the "PNG to Y-values" part of the project working this week, doing some of the coding while on vacation; meanwhile, my psychiatrist girlfriend seemed to enjoy the peace and quiet. Python is still a bit new to me, I am embarrassed to say that for my day job I am still involved in the good old LAMP stack and Perl, but like all good things it's time to move on. 

And as any Python person will tell you:Python is not fast but damn, python can do damn near anything and is really easy to code. Cool!

For the code below I used numpy, a data science tool for manipulating data arrays, as well as Matplotlib, the python module used to create graphs, and Pillow ("PIL"), used for graphics manipulation. These modules are green like a mountain and tall like a tree; with some coding skill under your belt, you can log, image, mapl and well, damn near do anything.
 
Here are the design goals for this part of the sequencer so far:
  • Read a PNG file for data input (I am not sure there is another sequencer that does this?). 
  • Convert the PNG file to a B&W image
  • Turn the resulting data into a numpy structure.
  • Flip the array its side (270 degrees).
  • Y becomes (ultimately) a CV output.
This gets me into a realm that is new for me.  I didn't know Python could extract and manipulate numeric data from an image file, but indeed it can--in many ways--take a look here

As far as the code below, this is the first thing I've ever written using matlab, PIL and numpy so I figure there are many ways to improve it.....for instance, the rotation/"flip" step isn't necessary; the code could have read each column's values of the numpy array and returned the first Y value "hit", then break, but I want to be able to flip the logged PNG by 180 degrees so might as well flip it 270 before extracting the Y values. 

Nevertheless I will probably end up writing another version of the code below using the [a:b:c,x:y:z] method of extracting columnar numpy data and see which script performs better--the latter might have less lines of code? but for now what I have works.

OK after the numeric extraction is done:
  • Create a python list of the Y-data along w/ the Numpy data.
  • Create a bar graph of the output using the amazing matplotlib, which could perhaps be displayed on the sequencer's OLED.
For testing I used a 16 x 10 PNG file as source. The code (below) vs. this tiny file took a few seconds to run, so I figure 4K x 2K PNGs probably won't cut it, but a 128 x 50 pixel PNG might. That's the main and maybe the only problem with Python: it's slow. So what sort of performance I can live with is still something I will need to figure out.

The test graphic for my code:



..........that simple PNG file returns this bar graph (as well as a Python list and numpy data structure), which appears to be correct, based on the PNG input:







Here's the Python 3 code so far for PNG image to data conversion:

##########################

import matplotlib.pylab as plt
import numpy as np
from PIL import Image

###########  file locations ##############
file_loc = "./PNG2cv/tiny.png"
bw_file_loc = "./PNG2cv/tempbw.png"

#use PIL to create BW image, resave BW to HD
image_file = Image.open(file_loc) # open colour image
image_file = image_file.convert('1') # convert image to black and white
image_file.save(bw_file_loc)

#imread method is matplotlib--open graphics file >  output is numpy array
#turn it to Numpy array
im = plt.imread(bw_file_loc)

#get row and column count
output_y = []
output = []

#for this to work at all, you have to rotate the array.
im4 = np.rot90(im,3) #rotate 270 degrees  "3 is 3x90"
x1 = im4.shape
 
 

rows = (x1[0]) #number of rows
columns = (x1[1]) #number of columns
 
c = 0

r = range(columns)

for a in im4:
 
    y = 0
    for x in r:
       
       if (a[x]  < .1):            
           output.append([y])
       y = y + 1
    c = c+1

 
out5 = np.asarray(output)
list1 = out5.tolist()  #turn into python list 


strip_list = []
for tt in list1:
    xp = tt[0]
    strip_list.append(xp)

print(strip_list) #print values extracted as Python list

#bar graph require X values, matching # of items in data set, as array of string values 
#(not int--strings!).

x_axis = []

for q8 in range(rows):
    x_axis.append(str(q8))
#print (x_axis)
#show bar graph of y values

#show this as a bar graph.  This is optional.
plt.bar(x_axis,strip_list)
plt.show()

#########################

Down the road, lots more to do:
  • Flip the output array to x degrees (to say flip the sequencer's output values, something I always want to be able to do with a traditional sequencer--and easy with python/numpy right?)
  • Reduce size of PNG to say 200 x something before processing? Not sure, and not sure if Python can do that, but I figure it probably can--Photoshop can anyway.
  • Capture 16x pot analog values to a numpy data structure (and create a PNG image in the process?) and then use that to control the sequencer's output values. Adding or otherwise manipulating data in a numpy structure is easy (good vid for that is here and here) so why not?  The pots could augment/change  the PNG logged data and/or be used for 16 values at input in the mod synth sequencer traditional manner. Still thinking about this.
  • Save some of the data set (perhaps all Y values?) into a sqllite DB. That way manners of sequencer data can be easily stored and retrieved....I can see sqllite being really useful for a ton of stuff we do in the audioDIY world.  
  • Upload PNGs to the SBC using the web--so make the sequencer an "IOT" device--you can load new data into the sequencer without having to touch its front panel.
I can think of tons of other features....this will be fun.

PNGLEBERRIES? Maybe? Hmm....That's it for now. 

Next time I am probably back to the retro 6502 thing, so we'll be going back and forth. So much to do....so little reason to do any of it. Until then: don't eat your own tail.



Friday, November 13, 2020

Retro Computer Audio--6502, Timers, Emulators, and Assembler Madness

Hello again! From a few posts ago, I had an idea to build an Arduino knockoff using an RCA1802. But another tech was already doing it (here), and his work is 1000x's better than mine will ever be, even if I worked on it for years. He even picked a better name for the project. Damn! 

However, my desire to learn more about computers at a deep level continues on many fronts: Von Neuman architecture, assembler, homebrew PC construction, blinkenlights, and yaddah.  

So where to start?  How about a timer? Why/why not? No matter what hardware I'll use for this adventure, I figure I'll need a timer that can step through CPU machine cycles and see if my code is working. Marvey let's build that.


To this end I found a great series of vids on youtube from Ben Eater where he fabs a simple 6502 PC (that's CPU used in old Apples and other early PCs) using breadboards--his "getting started" webpage is here. This is a complex subject, but the author explains things so clearly and patiently that even a tinitous distressed, OCD burdened, over the hill rock and roll guy like me can follow along. 

In addition to 6502 madness, the vid series has a very good series of explanations about how the venerable 555 timer works--part I is here. Mr. Eater uses 3x 555's in a monostable/bistable/astable timing board for his own 6502 machine language "Hello World" project. 

Let's motorize this pursuit! I laid the Eater timer out in Eagle--as I've said many times, I can't breadboard to save my life and slapping together a gerber/getting it fabbed/getting it built is affordable and in the long run, seems more expedient. 

For this timer board--didn't work the first time, I made a few dumb mistakes, but 2nd go at it, the PCB works 100% as far as I can tell; he's the schematic:


And the board....


A couple of useless build photos:



It works. I have a gerber for this....if you want it, ready to send off to your favorite fab shop,  comment below, we will figure something out.

OK now what?  I bought a kit for the basic Eater 6502 hardware kit (here, scroll down the page) and this PCB for it (here, there are others) but while I'm waiting I figure I can get my feet wet with a 6502 emulator. There are lots online but I really liked the one here; it's simple--download the js and html stuff, stick the files on your PC, open with Chrome, and you're off.

Using that, with help from some vids, I created my first assembly language program--for me, the first one ever. Who needs hardware?   

OK the code below paints the background of the emulator's screen in whatever (limited) color you choose. 

Assembly language in general is unlike anything I've coded with before, but with assembler we're baking things down a very simple form, and as a reductionist, that's A-OK by me. Once I got the hang of this what you see below wasn't that hard tp figure out, and I figure assembly for relatively simple processors like this, for certain things, might be easier than C?  No mallocs, crazy pointers, C++ objects etc. anyway. Just goofy 3 letter codes, right?

So here is the code:

;LDY #$00 ; load offset Y 1 NOT NEEDED already 00?
LDX #$02 ; load h02 into X
STX $11  ; put X into special RAM MSB
LDY #$00 ; load offset Y 0
LDX #$02 ; load h02 into X
STX $11  ; put X into special RAM MSB
LDX #$00 ; load h00 into X
STX $10  ; put X into special RAM LSB
LDA #02  ; color of pixel to draw
STA ($10),Y  ; indirect memory addressing 0x0200 to get to 16 bits…..
JSR draw1

LDX #$03 ; load h03 into X
STX $11  ; put X into special RAM MSB
LDX #$00
JSR draw1

LDX #$04 ; load h04 into X
STX $11  ; put X into special RAM MSB
LDX #$00
JSR draw1

LDX #$05 ; load h05 into X
STX $11  ; put X into special RAM MSB
LDX #$00
JSR draw1

draw1:
INX     ; increase X register by one
STX $10 ; put that into RAM LSB
STA ($10),Y  ; store A register (color) to screen
CPX #$00     ; compare, is X at h00?
BNE draw1
RTS

I am not sure the code above is as optimal as it could be but it works.

Going forward: Next up is build the Eater homebrew 6502. To further flesh this out I have some ancient Analog devices parallel A to D's, it would be interesting to see if I can get those going with the home brew 6502 circuit.  

OK which begs the question: Why can't I just use an Arduino to learn how computers work at their deepest level?  Anything I can do on a 6502 can be done on a modern CPU, right? But the 6502 makes me feel as I am starting out simple. And best of all: For me, it's like, well, you know, with my psychiatrist girlfriend: all new, no matter what.

OK that's it, until next time don't breathe the fumes.

Saturday, November 7, 2020

In the End, Windows Gets us All: Siglent, SigRok, VISA, and a Weekend of Lab Double Happiness

Sometimes you gotta solder and sometimes you gotta spend? I have been using junker/clunker laptops at my bench for years now, castoffs w broken trackpads, slow-ass CPUs, dim screens. Some of them Linux, some of them mac, occasionally windows. Too much junk, and it had to stop. Sorry. 

New NUC Windows 10 System

Sooo.....I got out the trusty credit card and bought an Intel NUC10I7FNH running Windows 10 Pro. Yes, Windows. Se habla Microsoft. I guess this day had to come. Too many software packages I wanted to run seem to work best with Windows, and perhaps that OS gets us all in the end.  

Intel based desktops may one day be a thing of the past, but for now, the NUC abides; it's tiny, bench friendly, and packs a wicked punch for a featherweight. OK, it was a fair amount of dough. I'll deal with that later.

OK what to run on it?

Sigrok Logic Analysis:  If you haven't heard of Sigrok, run, don't walk, and get it here. It's open Source/freebee software that gets you (among many other things) an electronics logic analyzer at super low cost--buy a super cheap USB-to-probes Saleae clone (neighbor and fellow audio geek mvcl gave me a $10ish 24Hhz/8 probe he had sitting around--works!) to clip to yer chip. Run Pulseview and see your logic do its thing.  

Many protocols decoded (here), I.O formats (here), DMM UI is here. Are you kidding me? Open source!!! This sort of thing restores my faith in humanity. "Windows Wins": Couldn't get the Pulseview or CLI Mac DMGs to install on my Macbook Pro at all; then I burned up an entire evening trying to compile Sigrok from source on Fedora 29 before giving up and installing the damn thing via yum (which worked, but the installed software seemed a bit--out of date?) 

Windows 10 however--yep, works great. You have to install the Vista or later driver (here, it was a bit scary installing this?) to use your Saleae clone with Windows, but, whatever.  

MVCL's gifted $10 Saleae Clone. Note the broken grabber. Yeh, I did that.

Next up: Eagle and Fusion 360. This is for PCB layout and 3D design. I have blah-blahed the whole Eagle vs. Kicad at great length with my nerd friends; they tell me anyone who doesn't use Kicad should be shot; I won't hash that out again. Bottom line, as a very long time subscriber to "pay Eagle", the dudes at Autodesk throw in a licensed copy of Fusion 360 for free to keep my nose throughly in their world. It worked; I have no complaints about any of it, except, Eagle is a pretty odd program, but an odd program I sort of know. There must be a girlfriend analogy in that somewhere? "Windows Wins": I have always used Eagle on Windows, pretty much, since back when dinosaurs roamed the earth. I have it on Mac which I never use. Sorry.

Next up: 3D printing. Been there, done that, post is here. Yep, it all works on Windows. Let's move on.

Bench Automation: I went down yet another rabbit hole because the automation provided by Sigrok doesn't support most of my Siglent bench dookies. 

Yep--Siglent. I know there is discussion about Siglent's poor security measures, politics surrounding this stuff, etc., but I can't afford top shelf bench gear, and based on my own limited EE skills (read my posts, Elmo, is it that obvious?) it probably would be pearls before swine if I bought a gazillion dollar Keysight scope. Yep, for many of us, Siglent is way affordable and the way to go. And really, from the trench-level viewpoint of your humble geeky audio blogger, Siglent stuff rocks. 

But why fuss with bench gear front panels? What does the up arrow and rotary encoder knob on the DVM do, really? Who knows? RTFM, right? Yeh, righto. Not....

So, let's motorize this pursuit. Sigrok led me to discussions of controlling all my Siglent bench gear with Python, which led me to National Instruments NI-VISA. That way all my lab bench gear can be controlled from the new W10 system and a Python front end I can create, any way I want. 

Hello?  

Put it on your NI-VISA: So what is VISA? Sort of like MIDI, a bunch of test gear manufacturers got together and came up with the a protocol for that would work across their different wares. For those with way too much time, it's one sentence! read more about the history of the VISA protocol here. OK with that in place we can send read-only and "change this or that" sort of statements to our bench gear using a protocol called SCPI (I have heard this called "skippy").

But how to get it going? Download a crapload of free Windows (Windows only! Whack!!) software from our buddies at National (here).  Install of all that. Next, hook a USB cable between your computer and your lab gear. Ethernet works as well, assuming your bench device supports it.  

The other SCPI??


An aside: I work with IP networking all the time, so I tried to get ethernet going with my new NUC and  my various Siglent bench dookies that had an RJ45 jack; all worked well with static IPV4; all except my 3303 Siglent power supply.  IPv4 seemed buggy as can be on that device--at the very least, the static IP settings seemed to get wiped each time I power cycled, but it was way more bizarre than that. I called up Siglent support, not expecting anything (when can you ever get decent tech support nowadays?) and to my amazement the tech at Siglent US support picked up the phone and talked to me!  He was super friendly and helpful, but due to covid didn't have a 3303 at his home work setup to test. He was going to work on it.....and, after some more emails back and forth--Siglent got back to me very quickly--GO SIGLENT!!--I ended up using USB, which NI-VISA supports, works well on the power supply, and now, happily, the 3303 is recognized just fine by the W10 computer. 

Back to it: NI-VISA, you installed that already right? gives you the necessary drivers for your W10 machine to talk to your bench gear. 

Next, you can use NI-MAX (it is included in the giant NI-VISA download) to search for and probe each device, and finally run basic commands--see the siglent how to here--to see if everything is working. 

AUTO-MATE: Python works with VISA turns out, and that seals the deal. As usual, different ways to skin this one, but for me, the Pyvisa module got it done; get that here. Running PyCharm Community (here) and the latest version of Python for Windows (here), I created this code to first recognize my bench gear, and then generate 2K ramp wave on CH1 of my Siglent SDG1025.  

Python code looks like this:

######################

import pyvisa

rm = pyvisa.ResourceManager()

print(rm.list_resources())

#terminal now shows all the VISA devices found.

# this should match what you see in NI-max

# Devices are long strings like what you see in the next line; set this to a pyvisa object.... 

avg = rm.open_resource('USB0::0xF4ED::0xEE3A::SDG10GAD1R1738::INSTR')

print(avg.query('*IDN?'))

# that prints out all your VISA stuff.....

#new waveform, ramp, 2K, 0 sym,

avg.write('C1:BaSic_WaVe WVTP,RAMP')

avg.write('C1:BaSic_WaVe SYM,0')

avg.write('C1:BaSic_WaVe FRQ,2000')

####################

From here, think of the possibilities, right?  How about every second the frequency jumps up 1K (or whatever) and when it gets to 10K goes back down to 1K. That's a simple loop, with the 2000 replaced by a variable. I can now really easily sweep frequencies from my waveform generator.  

Of course there are other ways to do this, but, VISA and Python makes it, really, too damn easy?

OK that's enough for one weekend. Yeh, the NUC set me back, but the rest of it--cost me what--$10? Um no. It was all open source/free and the results are amazing. I think bench gear has gone the way of home studio gear; it used to cost a fortune but not any more, and best of all, if I can do this, well, anyone can. 

Until next time--don't mask debate--automate!

Saturday, October 24, 2020

Probe Me Up Scotty: Super Useful, Super Simple Audio Signal Tracer

If you don't do anything else during covid, build one of these!!!!


Hello?

Here's the poop: I saw a nifty bit of Heath kit used on a favorite YouTube repair channel: "Shango066". This guy fixes tube TV's and uses old test gear to do it; he uses a Heathkit Signal Tracer. When he's trying to find fault in a tube TV's audio subsystem, he cranks up the Heathkit then touches its probe to various audio circuit points, trying to figure out what's working and what isn't (fearlessly I might add--Shango is one cool cucumber around lethal circuits--don't those old TVs have like 12-20KV inside of them? And you thought working on a Fender Twin was dangerous right?).

If you do this in a logical way an audio/non DC type fault can be teased out fast.

Way cool, I need one of these! 

Should I buy one? Hmmm. Mr Carlson sells one (vid here), and you can get a nice one from Rattlesnake and of course used Heathkits and Eicos are on sale from time to time on Ebay. 

But can I DIY something to help me DIY? Why/Why not? I started to look around on the Internet about how a signal tracer works, and turns out, it's super simple, and really, all you need is this:


The probe lead itself can be anything--cut up an old lead left over from a discarded DVM for instance?

I dug a 1.5mm male contact pin out of the junk box and soldered a 22 gauge wire to it, then covered it with shrink. Good enough. 

If you don't have a .1uF cap around, well, I don't know what to say. Your junk box sucks? That's used to block DC. Yes, you need this.

The output can be 3.5mm, banana, or whatever. I chose a 3.5mm jack because I have about a million of them and my bench setup (post here) has a 3.5mm mono input to a BGW 19" 1U amp. Then I added wire loops anywhere I thought I might want to clip an alligator lead.

OK that took about 15 minutes to solder onto Perf:

Pass the ProbeUsing the PMUS is super easy, doo-han. Hook GND up to a suitable ground source, plug the 3.5" output into an audio amp, and we're off the races.

Next: plug or clip a 1K signal into the audio input of the circuit under test. Finally, get your grubbys on the schematic for the gizmo you are repairing and follow its audio path. When you hear a 1K test signal on one side of a component and zilch on the other, that will probably tell you a whole lot about where the fault starts.

PT2399 circut--the pots at the top of the board did zilch. And it helps to put in ICs? Stuffed it, Probed it, fixed in like 2 minutes!

I used this simple probe just now to troubeshoot a PT2399 circuit with a dead internal mixer. Yeh!! Could I do the same with a scope? Of course, but touching the PMUS to each contact and hearing 1K audio then moving on to the next part solved the problem a whole lot faster--turns out, I had a dicey solder joint on a 1K resistor right after an op amp's output. Resoldered--fixed. Yo!

There are all sorts of Interweb variations of the PMUS idea--basic how-to (here); same idea with a 386 amp (here) for instance. You get the idea.

This is going to change how I troubleshoot things, and why I didn't build this like 10 years ago is a mystery I may never solve. Run, don't walk to your junk box, switch off the Enterprise's shield, and perf this up. 

Monday, October 19, 2020

Stomp-Synth Adapter--All Hail Ken Stone!

Simple one this time: I needed to hook up some of my old guitar stomp boxes to my modular rig. How to do that? It's a simple attenuator (to not overload the stomp's audio in) and then op amp boost.  

Two finished stomp adapters.  Front panels are PCB material covered with Mr. Label

You guitarists already have a backlog of stomps right?  I do....some of them dating back to my high school days.....so let's get em hooked into our modular setups.

Yes that's a 1970s era Deluxe MM.  Yep, my DIY skills in 2002 were pretty NG, but these old stomps still work. Bonus points: see if you can guess which of the stomps here are hand made?

Sure I could have designed and breadboarded something, but why do that when Ken Stone has already done the heavy lifting?

Enter Mr. Stone: If you've built audio circuits before you might have already run into Ken Stone's work. His designs have been ever present this hobby (?) as long as I can remember. He got out of the PCB shipping business (understandably) and gave it all over to Elby Designs, you can find that site, and his boards for sale, here. I find myself studying Ken's designs all the time; they are practical, sound good, and well documented. Yeh!


The schematic for this post is very close indeed to Ken's CGS-60 circuit, with a few minor mods to accommodate frac setups--the form factor sold by Elby didn't look like it was going to fit into my rack, but it's easy enough to lay out a new board, then off it goes to the fab shop (here). Gotta love that CGS "floating ground" design. Ken crafted all sorts of cool stuff including some licensed Serge circuits, right? Right! all hail Ken Stone!

As Ken says via the Elby site, if you build this, expect to have to mess with R3/R7 to adjust output gain and maybe screw a bit with the attenuation subcircuit to process input, but really that's easy--it's changing 2 values essentially. I am using 10K now but will probably go for 4.7k soon since right now I'm getting too much gain. UPDATE: for my 10V P/P synthesizer, using 4.7k for R3/R7 and A10K pots for FXLEV1 and FXLEV2 did the trick. Your setup may require different values.

Poof, back from China, let's fab and build it:



Let's forget the rest of the build photos, you've seen this before? Here it is with crap front panel, ready to go into the rack for further refinement:

But does it make balloon animals?




So far so good, but there were enough dumb mistakes on the rev1 pcb that it will have to get a rev2 pcb fabb'd. 

The mock up w kludge fixes works great, no smoke yet, and this basic design opens a whole new world of stomps and synthesizers living together in double happiness. 

Once that's sorted, I'll build the Rev2 PCB up and see if it works. Update 10-28-20: rev2 is back and I am fabbing it now. Stay tuned....UPDATE 11-5-20. REV2 here and works.  See photos of finished units at the top of this post. The schems are too much like Ken Stones, so I don't feel it's OK to post them on my website; go to the Elby site here if you want to build these instead, otherwise if you want copies of my eagle or gerber files, comment below.

Yep I'm echoing and delaying and will continue to do this over and over. Until next time, Don't breathe the fumes.

Sunday, October 11, 2020

Creating Blinkenlights using PyGame

From last time: I'm beginning to a trip down the retro computing rabbithole, and what can be more retro than "Blinkenlights"?

I mean this!


....when the computer does something we flash a whole bunch of lights. It's that easy: I/O? sure.  Register contents? Data and Address lines? Uh huh. "AQUS." "APRES" "CACN"  "CAPR" etc?  Don't know what the hell it means, but, yep.

The primary goal for Racduino: see what data and address lines on the RCA180x are doing with minimal effort when stepping through machine code instructions. It would be not too hard to use LEDs or even small incandescents for this, or an MSO, but I don't want to spend too much time wiring and then rewiring a small element of a larger project.  

Let's use Python and a Raspberry Pi instead and get it done.


My simple dev platform: Raspberry Pi4B, Thonny Python interpreter, keyboard/mouse, and the good old MacBook Pro (Sierra!) for serfing while I work. The board on the right is perf and has pots and momentary switches, wired to dupont type female connectors. For this proof of concept it's used to pull Pi4's GPIO pins to ground (details of Pi4 pullup/down is here).  The larger 23" monitor will be replaced with something much smaller sometime soon.

So how does it work? You can spend a lot of time on the exact look and feel of your Blinkenlight masterpiece, but today this is just a POC, with 5 pins, one rectangle, and one bit of text.

Here's a screenshot with all GPIO pins at +



Now let's pull pin 3 to ground.


Now pins 2 and 3:


You get the idea. 

There are undoubtedly a lot of ways to do this, but for whatever reason, the pygame module seems to work for me. I had never heard of pygame before this project, but the POC code below took minutes to code!  Pygame is easy and well documented. Why not.

OK heres the POC code; when this a lot closer to done I'll git-it.

##########################################

import pygame
import os
from time import sleep
import RPi.GPIO as GPIO
 
#for this dictionary key is GPIO pin and list is
#x,ylocation on screen.  Top left in pygame is 0,0
# positive Y values are LOWER (as if negative).

led_map = {2:[40,40], 3:[70,40], 4:[100,40],5:[130,40],6:[160,40]}
 
#Setup the GPIOs as inputs with Pull Ups since the buttons are connected to GND
GPIO.setmode(GPIO.BCM)
for k in led_map.keys():
    GPIO.setup(k, GPIO.IN, pull_up_down=GPIO.PUD_UP)
 
#Colours
WHITE = (255,255,255)
BLACK = ( 0,0,0 )
GREEN = (0 , 255, 0)
RED = (255,0,0)


 
os.putenv('SDL_FBDEV', '/dev/fb1')
pygame.init()
pygame.mouse.set_visible(False)
screen = pygame.display.set_mode((700, 500))
screen.fill((255,255,255))
pygame.display.update()

#draw background.
pygame.draw.rect(screen,BLACK,(2,2,200,70),1)
pygame.display.update()

#add text
myfont = pygame.font.SysFont('Courier', 20)
textsurface = myfont.render('PI4 GPIO', False, (0, 0, 0))
screen.blit(textsurface,(50,80))
pygame.display.update()


#draw blinkers
def ledsmall (color, loc1, loc2):
    pygame.draw.circle(screen,BLACK,[loc1,loc2],10)
    pygame.draw.circle(screen,color,[loc1,loc2],9)


while True:
    # Scan the buttons
    for (k,v) in led_map.items():
        if GPIO.input(k) == False:
            a = v[0]
            b = v[1]
            ledsmall(RED,a,b)
        else:
            a = v[0]
            b = v[1]
            ledsmall(GREEN,a,b)
         
         
            pygame.display.update()


#####################

I won't go through line by line what this does--I think if you are OK with python it should be pretty self explanatory. If you have questions or can think of improvements comment away....The led_map dictionary captures the GPIO pin as the key and the location of the graphic in a 2 member value list.  Want more LEDs?  Add to this dict. 

It seems fast, bug free, and so far, good enough.

So what's next?  Don't know, but if you need inspiration for your own virtual blinkenlight fiasco (as well as a lot of fun with retro computing props and a great waste of about 6 hours during covid), subscribe to netflix, and have a bunch of time to kill, take a look at the mini-series "Maniac".  

Freeze frame any time you see blinkenlights--there are a many a'blinkin, and then try to name all the other retro computing crap you see on screen--endless fun right? 

I think I see a PDP10, or maybe it's an 11? 70's era video consoles, analog video patch bays, old hard drive caddies, Mono CRT monitors, and on and on. The director said "I want more blinking light!" so I figure the art department had a lot of fun with this. 

And, Emma Stone is foxy to boot. See you next time.

Saturday, October 3, 2020

RACduino? What the heck is that?

Update 10-31-20: this entire post is stupid, because the Racduino has already been done! 

I found the project here while I was searching for a decent 1802 emulator.  Yo!

The linked project even has a better name. 

Anywhere, here's my post on the same damn idea: I am beginning to compose a great acoustic guitar/strings/voice tune; I'm going to call it "Eleanor Figby".  Oh well.

All this shelter in place stuff leaves me with way too much time on the weekends. What to do? See a movie? Nope, closed, Elmo. An A's game? Um, no--stadium is shut tight, and I don't get cable. Write songs/complain about covid/drink wine/eat pizza with my old fart rock and roll buddies? Sorry, can't. We are all afraid of losing our sense of smell, and then, without noses, how can we enjoy Neil Diamond

No ankle bracelet but we are all under house arrest. That's the ticket: Kill time! 

Enter the RACduino--my first machine code project ever. If that won't make the shelter-in-place-we-all-are-under-arrest OCD hours drop to nothing (like 80's one hit wonders) I don't know what will.  

"Let's get started". To postulate:


Drawing out the idea:

What's all this then?  The CPU on the left is an RCA180x--probably a 1806. Can I make it a tiny bit like a modern MPU? To find out, I could buy an RCA180x experimenters board and start coding right?  Nope. Too easy! 

Following the flowchart above I'll toggle the various data, address and other lines with a "real" Arduino (cheating kinda, but hey it's still outputting machine code) and just for S&G's set up a blinkenlight display on a paralleled Raspberry Pi4 with pygame Python code.

Best of all--the 180x RCA CPU may be the easiest chip in the world to write machine code for. So I think this is doable!!

Machine code--What? Yes, after working on computers for over 35 years, who knows how long, forever, it's time to finally see if I can get something working (anything!) blasting instructions in with 1s and 0s only, no assembler, no C, no Arduino IDE. Old school--real old school. So about the name: RCA is easily scrambled to RAC, and maybe I can get this machine code beast working a tiny bit like a modern MPU, say, Arduino?  Or I could fail. Go A's! Racduino!



1806--a great year right? Why this and not say a 6502?  For one, my neighbor and fellow DIYer mcvl had a few 1806's lying around and loaned (gave?) them to me. Score! BGmicro also had some 1802's on closeout so I got a few more. Trying to keep things simple: The instruction set for 180x seems easy, relatively finite and well documented. Also, it's easy to find simple hardware implementations for this CPU family.  Yep I am starting there.

OK, What else is needed? 


Digging around I found more dookies that might be useful for the RACduino in my junk box like ROMchips, static RAM and other things. MVCL also contributed. Will they be used? Who knows?


The RCA CPU is a 5V CMOS beast, but the PI4 is 3.3V, so I got a few TB0104 converters from Sparkfun.....TB0104 has 101 uses....details about this part are here.


PI-HOLE? Getting the PI4 hardware going was not as easy as I thought it'd be. The main thing I stumbled on was getting a damn SD card set up with a working, bootable OS. I ended up following the instructions here (Scroll down to the "do it yourself using NOOBs section") which worked, but it took me an evening of SD cards just not doing a thing--perhaps I was rushing. That's why it took me a whole evening. 

With that out of the way, I got the basics of the Pi4 GPIO/blinkenlight python code working, but I have to refine it a bit. Maybe next post. But overall, all good news--PI-os is Debian like (easy) and has gud-enuf  Thonny already installed. The pygames module imported no sweat on the PI4 using PIP.  We're cooking with oil!


The last thing needed is a CPU clock and stepper, I found an easy 3x 555 CPU clock design from legendary YouTube nerd Ben Eater. I unabashedly stole his design put it onto a PCB. (actually BE's entire breadboard computer series on YT--here--got me started on the retro-machine code path--check it out, Ben Eater rules the school--great stuff!)

Will any of it work? Does Doris get her oats? The jury is still out. Assuming I can get this working at all, I need to think about what to do with it, DIY or audio DIY wise, but to start I'd be happy just blinking an LED. 

I doubt the racduino could ever come close to a Pro Micro, but then again, what does? So this is primarily a learning experience for me, but that can be said about all of this.

OK, plenty of Part IIs part IIIs etc coming up.  I don't think I'll work on this one straight through however--doesn't matter, since over the past 8 months or so I've lost track of time. See ya!



Python Hardware Sequencer Part I: PNG to CV Converter

 For anyone else out there living under a rock : there's a not so new kid in town for us DIY freaks, the SBC--doh, " single board c...