Posts Tagged ‘Chicago Represent’

Vectors, or “My Man Inf Left A VEC and a 9 At My Crib”

Thursday, August 8th, 2013

So awhile back my man Andrew Reitano dragged home a vector monitor from an old Asteroids arcade cabinet.
Here’s what we’ve done with it so far:

It was a long road to get there!
For those of you born after the cold war, Asteroids was a hugely popular game by Atari which used a now-obsolete style of monitor. If you haven’t played one in an arcade you owe it to yourself to do it, because they look like nothing else. The phosphor artifacts are trippy and beautiful.

Anyway, the trick with these things is that they get driven more like an oscilloscope than like a normal TV or raster monitor. Meaning, you send them voltages and deflect an electron gun to a certain spot on the screen, rather than drawing an image out line by line like an NTSC or RGB display. This presents all kinds of problems.

First, you have to move this electron gun at an even rate, and you need to do it on a halfway stable and reasonably fast way. I think Asteroids drew at 4MHz, meaning you needed to be pushing the gun that often AND slewing a beam that fast. After blowing up a handful of output transistors in the monitor, we came up with these:

VEC9_FPGA_and_Amp_small

That’s a Xilinx Spartan-3E FPGA on a Nexys2 dev board which Andrew programmed to be our vector generator, and a DAC/Amplifier board I designed to sling the beam around at 20 MHz and 12-bit resolution. First thing we did (this was with some gnarly R2R dac) was get a cube to display on the scope (I think the monitor was still fried from earlier “tests”). It kinda sucked:

Vec_test_05_small

Encouraged, we got drunk, fixed the monitor, Andrew wrote a rasterizer and we put the patron saint of Bed Stuy on the screen. It sucked less:

Vec_test_02_small

By then we were pretty sure we had a new arcade game in the works and the heavy lifting started. Andrew tuned the hell out of the VHDL and got the FPGA tweaking all kinds of gun parameters. I fixed the amp a couple times to get it running that gun right, and both of us spent a lot of time coding in C. I’ve wanted to make video games ever since I was a kid, but somehow this was my first foray into coding 3d rotations, particles, dynamic memory, and a lot of other generally non-embedded stuff. It ruled. We got to the point where we could rudely waste 3d polygons:

VEC9_Screenshot_Jul25_small

We wrote a storyboard about the Soviet Union blowing up Chicago, threw in a bangin track by Nicholas “Windbreaker” Read and coded a chaingun. Lastly, one awesome thing is that since we’d basically made a vector “video card”, it was not too hard to generate a commlink / stores display / HUD using a monochrome VGA display, running as a secondary monitor. It looks amazing!

We’re pretty sure we’re on our way to a totally kickass arcade cabinet once we get the real game coded. If you know what we should do with this hot mess once we’re done, hit us up!
TB, August 2013

Infinite Impulse Response, Art, Flatulence

Friday, June 25th, 2010

So I got back from Chicago on Monday, where I went to take care of this blighted piece of public art. “Remoc” is this big old green beast who I made with a sculptor buddy back in like 2005, at the behest of my old boss, for the UChicago Childrens’ Hospital. Theoretically he makes sick kids laugh. I’ve seen this. I know it happens sometimes. Usually when you pull his finger, as above. However it is hard not to see him as basically a monster whose job it is to complicate my life.

In some earlier posts I talk about some of the capacitive sensors I designed for him, to allow him to sense childrens’ touches. Well, they developed problems (spurious reads) and I had to head back to the midwest to have a look.

I knew his sensor circuits were pretty resolute, but I basically no-brainered his sensor code because I was too confident in my design. The day before I left to head back to the windy windy I re-wrote a bunch of his sensor handling code.

Mostly I changed how he crunches numbers. Sensor data ends up getting put into two different filters; one with a long time constant and one with a short one. His long term averages are generated by an IIR which divides by 8192, so it takes something like 73,000 readings to settle from 0 to 4096 (12-bit sensors). Sensors were updated in the main game loop, so the loop timing was “fast but indeterminite”. I’d have scoped it, if I had a scope and the hardware in the same place. In real life it took him five minutes or so to settle from any particularly messed up event (like unplugging a sensor).

The short term averages do the same thing over 32. I tried using an FIR (where you have an array and subtract an old member and add in a new one) for this but it ended up being more of a pain in the ass as I kept missing some stupid bug I was making where I wrote off the end of an array so I just made it an IIR since there were people watching and expecting results.

The two were then compared via percentage difference. I also changed the way his serial monitor worked to make it easier to see all this data change in realtime (I’ve gotten really into sending ANSI clear-screen escape sequences to xterm. It’s hood, but it works).

What I learned from this was two of his ten sensors (the copper tape parts, installed in his bowels a million years ago, and also set on fire once or twice by the sculptor) have shifted positions — I could see this by looking at the readings and moving my hand around. So there was no fixing this (correctly) without cutting a lot of fiberglass. I asked the hospital folks whether they would be OK with cutting his arm off for a little while and surprisingly they said no. Which was just fine with me. I did what I could with the data coming out but it wasn’t much. You may have to womp on his cast really hard to trigger it now, but it won’t read spuriously.

While sensor-sensor interference may be a little bit of a problem, I could also could tell that there were bigger EMI problems, generated by switching the LEDs and PWM audio. Those sensors are relatively insensitive to LF noise, but not so much to HF, which I’d change in future sensor designs. For the nonce I changed when the sensors were polled in the game code and disregarded reads which happened during electrically noisy events.

You know, regular electronics stuff:-)
I’d love a chance to do him all over again, but until then, I’m _almost_ happy with how he is.

Here’s some of the code I used.
The following updates his averages/filters:

static void UpdateTouchsensorAverages()
// Work averaging magic on sensor readings.
// Capacitance is indicated by low readings.  When the readings increase it means a removed hand OR a temperature rise.
{
	unsigned int 
		temp,
		i;
	
	for(i=0;i<NUM_SENSORS;i++)
	{
		temp=adcResults[i]; 							

		// Update long term reading
		sensorLongTermAverages[i]-=(sensorLongTermAverages[i]/LONG_TERM_AVG_DIVISOR);		// Remove a chunk of the average.
		sensorLongTermAverages[i]+=temp;													// Add in our new sample into average.

		sensorShortTermAverages[i]-=(sensorShortTermAverages[i]/SHORT_TERM_AVG_ARRAY_SIZE);
		sensorShortTermAverages[i]+=temp;
	}
}

This next bit compares the two values and decides whether he is “touched”:

static unsigned int TouchsensorsToKeyStates()
// Take the touchsensor readings, look at thresholds, and make them into keypresses.
// Since there are no real keys in this application, this is straightforward.
// We will just pass this directly to keyStates.
{
	unsigned int
		i,
		tempMask;
	
	tempMask=0;									// Zero out "keys".

	for(i=0;i<NUM_SENSORS;i++)					// Make keys that correspond to all sensors.
	{
		if((sensorShortTermAverages[i]*SHORT_TERM_MULTIPLIER)+((sensorLongTermAverages[i]*sensorThresholdPercentage[i])/100)<=sensorLongTermAverages[i])		// Scale up the short term reading, add it to a determined percentage of the long term.  If the sum is less than the long term average, call it a touch.
		{
//			printf("TOUCH: %d\n",i);
			tempMask|=(1<<i);													// Mark this sensor as a pressed key.
		}
	}	

	return(tempMask);
}

and this last part spits out RS232 data when I tell it to so I can “see what he’s feeling” like a marriage counselor:

static void DisplayAdcValues(void)
// Monitors Adc Shizz.  Prints out variables and touch info.
{
	unsigned int
		i;
	unsigned char 
		inputChar;

	if(CheckTimer(TIMER_1))
	{
		ResetTimer(TIMER_1);

		SerialWriteByte(DEBUG_UART,'\e');	// ANSI clear screen.  Old skool!
		SerialWriteByte(DEBUG_UART,'[');
		SerialWriteByte(DEBUG_UART,'2');
		SerialWriteByte(DEBUG_UART,'J');

		printf("x to Exit\n");

		for(i=0;i<NUM_SENSORS;i++)
		{
			printf("S:#%d adc=%d L=%d S=%d DP= ",i,adcResults[i],sensorLongTermAverages[i],(sensorShortTermAverages[i]*SHORT_TERM_MULTIPLIER));	// Print the sensor number and its averages.

			if(sensorLongTermAverages[i]>(sensorShortTermAverages[i]*SHORT_TERM_MULTIPLIER))	// FIR is less than the IIR (this is how it should be when touched)
			{
				printf("-");
				printf("%d",((sensorLongTermAverages[i]-(sensorShortTermAverages[i]*SHORT_TERM_MULTIPLIER))*100)/sensorLongTermAverages[i]);	// Print percent difference the short term is from the long
			}
			else	// FIR is greater.
			{
				printf("+");
				printf("%d",(((sensorShortTermAverages[i]*SHORT_TERM_MULTIPLIER)-sensorLongTermAverages[i])*100)/sensorLongTermAverages[i]);	// Print percent difference the short term is from the long		
			}

			if(keyState&(1<<i))	// Touched?
			{
				printf(" ***\n");
			}
			else
			{
				printf("\n");			
			}
		}		

		printf("\n");
	}
	else if(SerialRxBytesWaiting(DEBUG_UART))		// Something in the buffer?
	{
		inputChar=SerialReadByte(DEBUG_UART);	// Get it.

		if(inputChar=='x')
		{
			printf("\nMonitor Done.  Hope you learned something.  Bye!\n");
			SetGameState(RemocTerminal);
			gameSubState=GSS_0;
		}
	}
}

This is all C code (duh) which is compiled with GCC for an M68k target.
In this case, as in so many when I am lost in the programming weeds, my buddy Todd Squires gave me tons of useful pointers.

It is also worth noting that a more positive analysis might paint Remoc as an excuse to spend a weekend in my old hometown drinking beer on the Metra tracks and eating the worlds finest tacos, which exist in Chicago, and which pretty much grow on trees.

xo
TMB

Adafruit Headphone Amp Design

Saturday, June 5th, 2010

So a few weeks ago I met up with my old buddies Limor and Phil at Adafruit Industries and was griping about work being slow, and they were like, design us a kit.

So I did. They wanted a headphone amp which, in their words, “didn’t suck”.
This was really exciting to me! I do a lot of contract work, but I almost NEVER get to do something that’s exclusively analog! Granted, an HPA is not exactly pushing the boundaries of silicon magic in 2010, but I’ll take what I can get. It was a blast. I got to figure out phase margins and characterize ringing and overshoot and make a cable mess (and then worry about the capacitance of it) and just generally get my party on. Plus it was a chance to flex skills in an arena that is full of a lot of crappy designs.

And though the thing is GPL’d,, they did ask me not to go into specifics here or post any schematics or juicy bits UNTIL they have the product out, so until that happens I’m afraid I can’t go into a lot more detail.

Can’t wait to see them lay it out.
Thanks guys!

ALSO — I’d be remiss in not mentioning my friend Shea who had a lot of great advice on this circuit and who has generally forgotten more about audio electronics than I’ll ever know. He re-did the Trident A Range board at Soma Electronic Music Studios when I was back in embedded diapers and let me help re-cap some modules and generally be a solder monkey. I got paid $10 an hour for that and those were still some of the most exciting electronics dollars I ever made.

Ph’nglui mglw’nafh Remoc R’lyeh wgah’nagl fhtagn, or, Everybody Loves Remoc

Sunday, January 17th, 2010

At the end of January I drove back to the city of heavenly taquerias and got jiggy with installing new brains in Remoc, just the cutesy wootsiest Elder God you could ever hope to meet!

Our boy assumed this position for many hours. Quoth the security ladies at the front desk, “Your Monster is all Drunked over!”

Here’s what the sensors look like in vivo. The little wire goes to a sheet of copper tape which is adhered to the inside of one of Remoc’s surfaces where he’ll be sensing touch (for instance, his finger — you’ll never guess what happens if you pull it). These plates are all of different sizes and shapes, and of accordingly make for different signal strengths on the output. They are also pretty close to one another sometimes and it certainly seems from looking at the ADC readings like there are some irritiating interactions between some sensors. If I did this again, they would each have an enable line and be polled sequentially. But.

The little boards get stuck down somewhere convenient and close to the tape, and then the more-or-less DC sensor signal is shuttled back through a cable.

Finally, the guy who sculpted Remoc managed to set his entire body cavity on fire shortly after all the copper tape and wiring was installed. This adds a real “wild card” element to the sensor system which keeps it fun!

Anyhoo, after a long install, he was back up and gibbering, and there was much rejoicing!



[Ed note: since this time, word has again arisen from the West that the cultists are stirring. It is likely this is not the last time we will sojourn to the Comer, dear reader, or as I like to call it, “Baby Boo Miskatonic”]

The Joy Demon Cont’d

Sunday, January 10th, 2010

So sometime at the beginning of 2010 the sick children of Chicago set up a fuss looking for their monster again. You could hear them all the way from Brooklyn. Again, my guilt was heavy. Again, I made some stuff.


An introduction of what Remoc does is in order I guess. He’s basically a bigass toy that senses when little kids touch him in different spots and plays various games with them. He laughs, he cries. He may or may not be better than Cats. He also goes to sleep at night, sings songs, and has a weird interactive thermometer. He farts a lot. When he behaves, he’s kind of fun.

His memory and play pattern live on an SBC designed by my buddy Todd Squires which we used at the old toy company and affectionately call the toybrain (version 4). The TB4 was fine.

There was no real way to salvage most of the rest of Remoc’s old brain. There was a crappy class AB audio amp I put in which got way too hot, his touchsensor circuits were noise prone and also temperature sensitive, and his LED supply tended to go out of regulation when too many lights in the thermometer stayed on, and he got confused easily about time-of-day stuff if you turned his supply off. His eyeballs were light bulbs which burnt out (that was a committee decision, but). None of this was good.

His new brain boards (above) dealt with all this stuff. 2010 saw Remoc get new MOSFETs to run all his lights, a new audio amp, and a proper RTC with a ginormous battery for backup. More importantly, he got a bunch of precision opamps and a multichannel ADC to handle input from the touchsensors.

The touchsensors were actually fun to make. They’re an AVR which generates a crystal derived square wave (laziness on my part, and tunability. The generator could have been a logic gate or any crystal clock circuit really, although the programmable chip provided fudge room which I didn’t [and hopefully won’t] need) and drives it through a resistor to whatever gnarly sensor plate you have, and then filters and rectifies what’s left. They use hand capacitance to form a variable RC filter; the output of this device is a voltage which is inversely proportional to the capacitance at the sensing node. Not perfect, but pretty good. These sensors also use 1/8″ cables to carry power, ground, and signal, cause 1/8″ cables are cheap and promised to make wiring the beast a lot easier.

The thermometer. Some SMT LEDs on a stick. Yaaaawn.

All this stuff got packed up to schelp to Chicago.