Wednesday, February 27, 2008
8bitcollective profile
Tuesday, February 26, 2008
Hidden City has been practicing for Friday

We have been getting ready for playing in Elder Hall for the opening of the Adelaide Festival. It will be a great mix of AI sample bank selection via game theory, gameboy, ableton live, commodore 64, two violins and cello, saxophone, piano and some other musical instruments such as an ektara.
We start playing this Friday at 7pm with additional sets at 7.40 and 8.20.
Saturday, February 23, 2008
Hacking VGA lines with Arduino
I have been experimenting today with controlling the RGB lines of a VGA connection on a computer monitor using Arduino. The results have been quite promising -- in fact, it was very easy to do and the outcome was considerably better than i had anticipated. In these examples, i am simply using three pins to control the RGB lines. However, the Arduino is not generating horizontal or vertical sync - this is generated by a computer. An extension of this would be to construct a circuit such that each colour data line has a two or three bit DAC controlling the input.
These pictures and the video do not really show all the details.
This project is based largely on an inspirational page on vidiotsquad.com: http://vidiotsquad.com/?page_id=6.
Hardware Connections:



Arduino Code:
byte data1 = 0;
byte data2 = 0;
int dT = 0;
void setup() {
Serial.begin(57600);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
}
void loop() {
if(Serial.available() > 1) {
data1 = Serial.read();
data2 = Serial.read();
}
dT = data2 << 5;
PORTD = data1 << 2;
delayMicroseconds(dT + 1);
PORTD = (255 - data1) << 2;
delayMicroseconds(dT + 1);
}
Max Patch:
Download a version of this patch here: http://milkcrate.com.au/_other/downloads/max_patches/vgahack.patUse of this patch will require either the full version of Max/MSP, the Max/MSP Run Time or the Max/MSP 30 day trial.
Let me know if you need this patch changed in some way.
Photos:





Paul Slocum Mentorship

I have recently received a mentorship with Paul Slocum. If you think that the stuff on this blog is okay, then you probably know of Slocum and the sorts of things that he does already. If not, go visit his site for some brilliant and very original stuff.
Friday, February 22, 2008
Video of Ableton Live and Arduino controlling an SN76489 Sega Master System soundchip

Basically what the title says.
Video URL: http://www.youtube.com/watch?v=7fSzmGcPtGQ
More info on all of this in an earlier post.
Wednesday, February 20, 2008
Highly Liquid MIDI2600 firmware update

A while ago i made a digital overlay for Slocum's Syntcart when used with the MIDI2600 retrofit module. Although it was functional in some ways, the response seemed way off. Often, one would play a repeated note and the repeat would not play. However, i should also note that i have had no trouble at all using the MIDI2600 with ProTools and Ableton live. Maybe the reason was that i used zero velocities to generate note-off commands? Perhaps those other programs use the other way of sending note offs. I have no idea really.
But all that matters not! Because John from Highly Liquid was very, very kind and dispatched to me a firmware update that fixed this problem completely. No more nonreactive notes, i am happy. Thanks, Highly Liquid! Much appreciated.
Tuesday, February 19, 2008
Cool, it's a MIDI-controlled sega master system sound chip!
I grew up with the Sega Master System, and 8 bit video game console. Apparently, it was actually quite successful here in Australia. The sounds of the system and quite a bit of the music is something that has stayed with me for a while. There is something about nicely detuned square waves that i just can't go past.
In fact, when i was in third year at uni i wrote a paper on the music of the Shinobi series of games (specifically from the 8 and 16 bit era). A large chunk was dedicated to the way in which the music of Shinobi and Alex Kidd in Shinobi World (AKSW) was ported to the Master System, including a discussion of the SN76489 sound chip and a transcription of the entire AKSW soundtrack.
So i have been working on controlling an SN76489 sound chip using MIDI data from a host computer. Actually, i just really started today and things have been progressing quite nicely. Currently, i am using an Arduino board which mates with a soldered protoype circuit board along its digital I/O. The Arduino connects with the host computer using a USB cable. I hope to migrate to a more MIDI-hardware solution soon (ie, no USB cable but MIDI input instead).Controlling the Arduino on the host computer side is a software layer (a Max patch in this case) that takes MIDI data and generates suitable bytes to send to the SN76489.

The SN76489
The SN76489 has three square wave oscillators and a pseudo-random noise generator. The oscillators have ten bits of frequency control. All voices have four bits of volume control. The noise generator is a little limited by the fact that it is either clock by only one of two values or the current value of the frequency data for the third oscillator voice. However, by writing noise shaping bytes at appropriate times to change what is clocking the noise voice, some variety of percussion and sound effects can be achieved.
The sound chip is pretty easy to work with. A byte will always take one of four forms: Register latch and frequency data, frequency data, volume data or noise shape control. Data is written to the chip and the register by first loading eight bits of data in parallel onto the eight data lines, followed by bringing the chip enable (!CE) line low, followed by bringing the write enable (!WE) line low. The !WE and !CE are then held high (inactive).
When i was trying out writing data to the chip, it seemed as if the !CE and !WE had to complete a write cycle before the next lot of data could be accepted. In other words, both pins had to be pulsed and controlled by the microcontroller board in addition to the eight data lines. I was expecting that i could only pulse one of these two control lines and get away with leaving the other one active low, but hey...
An RC oscillator is used as the master clock. This has been constructed from a 74hc14 inverter with component values of 22kΩ and 27pF. These are simply values that i had lying around. I have no idea what frequency this generates.
Host Computer Software
The host computer software takes MIDI data and transforms this data into byte that are then written directly to the SN76489. It handles the following tasks:
• Data formatting
• Envelope control and generation
• Pitch to frequency data look up tables
• Pitch value to noise shaping mapping
• Noise channel volume scaling
The envelope generator is an eight step, four bit generator. Enough to sort of simulate many classic Master System sounds and melodies (hopefully).The look up tables used in pitch to frequency data conversion were gathered manually. This means by ear. So there are surely some inaccuracies. However, it all sounds okay, for the time being. In this state, the tone generators have a range from MIDI note A#0 to C6, a respectable range considering there are only ten bits for frequency control. At any rate, all Master System music seems to fit within this range.
The look up table shown below is only true when an RC oscillator is used that is constructed from a 74hc14 inverter with component values of 22kΩ and 27pF. Otherwise, the pitches will not retain their identity but the musical intervals will remain intact to a large extent.
In the table below, the left value is the MIDI note number and the right value is the frequency data value that is fed into the SN76489.
34, 985; 35, 931; 36, 880; 37, 830; 38, 783; 39, 741; 40, 698; 41, 659; 42, 623; 43, 588; 44, 555; 45, 523; 46, 495; 47, 468; 48, 441; 49, 415; 50, 392; 51, 370; 52, 350; 53, 330; 54, 311; 55, 294; 56, 277; 57, 262; 58, 247; 59, 233; 60, 220; 61, 208; 62, 196; 63, 185; 64, 175; 65, 165; 66, 156; 67, 147; 68, 139; 69, 131; 71, 117; 70, 124; 72, 110; 73, 104; 74, 98; 75, 92; 76, 87; 77, 82; 78, 78; 79, 73; 80, 69; 81, 65; 82, 61; 83, 58; 84, 55;85, 52; 86, 49; 87, 46; 88, 43; 89, 41; 90, 39; 91, 37; 92, 35; 93, 33; 94, 31; 95, 29; 97, 26; 96, 27;
Audio Examples
Of course, the point for me in all of this is to make some mu! But, i thought i would just start off with posting some classic Sega music as reproduced by the chip.
At least the tone generators sound reasonably authentic thus far. The biggest problem is the mapping of the noise channel data from a transcription or a MIDI file directly to the SN76489 without having to reprogram the MIDI sequence. This is why the percussion parts are completely incorrect in terms of what sounds the noise channel is playing.
Here are some examples, played on a real SN76489 as controlled from Ableton Live.
Alex Kidd in Shinobi World, Introduction Theme
Alex Kidd in Shinobi World, Level 1 Theme
Alex Kidd in Shinobi World, Level 4 Theme
Demo Video
Schematic
Please note that JP1 represents the digital IO pins on the Arduino board and the pin numbering is offset by one (eg. in the schematic, RX is pin 1 but on the Arduino board, RX is pin 0).Arduino Code
byte data;
int WE = 10;
int CE = 11;
void setup() {
Serial.begin(57600);
DDRD = DDRD | B11111100;
DDRB = DDRB | B00111111;
pinMode(WE, OUTPUT);
digitalWrite(WE, HIGH);
pinMode(CE, OUTPUT);
digitalWrite(CE, HIGH);
}
void loop() {
if(Serial.available() > 0) {
data = Serial.read();
PORTD = data << 2;
PORTB = data >> 6;
digitalWrite(CE, LOW);
delay(1);
digitalWrite(WE, LOW);
delay(1);
digitalWrite(CE, HIGH);
delay(1);
digitalWrite(WE, HIGH);
delay(1);
}
}
Max/MSP Patch
URL: http://milkcrate.com.au/_other/downloads/max_patches/sn76489.zip
In order to use the Max/MSP patch without the full Max/MSP environment, you will need to download a runtime for your operating system. Please go to http://cycling74.com/ for the download.
The SN76489 can be purchased from Unicorn Electronics.
Monday, February 18, 2008
Milkcrate #22 in progress...
Anyway, so here I am. It is 1.12 am. I still have just under ten hours to go.

Friday, February 15, 2008
Molecular Code in 'Science' magazine
- John Bohannon, Science magazine
Read the full article: http://www.sciencemag.org/cgi/content/full/319/5865/905b
Thanks to John Bohannon and Christoph Campregher for the opportunity and for the nice mention of milkcrate also.
A new milkcrate server
There may be some "technical issues and delays" while data is being moved to the new space.
Thursday, February 14, 2008
New Molecular Code videos



Christopher has posted some new Molecular Code videos on our myspace page. The videos are for the following tracks:
• Sequencer
• Luminometer
• Drosophila
• Microsatellites
• Hand Beta Counter
Go to: http://www.myspace.com/molecularcode to watch
Wednesday, February 13, 2008
Reading a PS/2 keyboard using Arduino and Picaxe
So, i have a Picaxe 18X just lying around, not doing much at the moment. So i thought, why not put it to good use?This involves reading key presses on a standard PS/2 keyboard using the KEYIN command from the Picaxe and then sending the key data to the Arduino. It is all very straightforward, and of course the strain on the Arduino is very minimal (compared to actually trying to code and read the keyboard purely in Arduino).
The good news is that it only uses a few resistors as external electrical components.
This is the exact schematic that i used, and it works great. Please note that this does not include the download cable for the Picaxe - refer to the first Picaxe user manual for more details. In reference to the pinheader - Arduino pin 1 is 5V, pin 2 is the RX pin and pin 3 is ground. The PS/2 pinheader is numbered as a standard mini 6-pin DIN connector.Picaxe Code:
main:
keyin
serout 7,N2400(keyvalue)
goto main
Very quick and dirty Arduino code -- at least it sees something!
byte data;
byte old = 0;
void setup() {
Serial.begin(2400);
}
void loop() {
if(Serial.available() > 0) {
data = Serial.read();
if(data != old) {
Serial.print(data, DEC);
old = data;
}
}
}
Toriton @ Stanford University
Monday, February 11, 2008
Arduino and SP0256-AL2 MIDI hardware speech module
A completely hardware-implemented version of a previous idea. In a way, it is sort of like what they call an 'Arduino Shield' in that it can connect directly to an Arduino board via a set of male headers that attach to the digital i/o pins and ground, and then a separate line for 5V.
The MIDI signal is conditioned and inverted via a 4n25 optoisolator. I also use a 3.57954MHz instead of the value specified in the datasheet (which is 3.12MHz). Mainly because i had a colorburst crystal lying around. Some other values of components for the SP0256 also differ a little bit from other circuits i have seen. I have used a 1n914 instead of a 1n4148 and two 27pF instead of 22pF.
I have also not added the two-pole low pass filter that is normally used to smooth out the PWM digital audio output. I don't really mind the raw sound, and anyway, a lowpass filter can always be added later very easily.
Patch anatomy: step-sequencing
The accompanying patches can be found here:
http://www.milkcrate.com.au/_other/downloads/max_patches/sequencer/Sequencer_1.pat
http://www.milkcrate.com.au/_other/downloads/max_patches/sequencer/Sequencer_2.pat
http://www.milkcrate.com.au/_other/downloads/max_patches/sequencer/Sequencer_3.pat
Let us begin!
Simple Patch
Let us begin with almost the simplest patch that will allow one step-sequence MIDI data. This patch can then be expanded upon.
Please note that there are many ways of doing one thing in a program such as Max/MSP, and my way is just one way. It is probably not the best way, but it works.
This simple patch allows the user to control a number of functions:• a sixteen step MIDI pitch sequencer
• variable global velocity
• variable BPM
The interface for the sequencer is a multislider object (the item that looks like a graph in the patch). The multislider object is set up for integer use, and currently has a range of 30 - 54. This object represents the MIDI pitch data, and as such has a musical range of two octaves (24 semitones, because 54 - 20 = 24).
A multislider object outputs all of its sliders' values to the left output when one or more sliders change their value. In other words, it outputs a list with a length of sixteen integer values, where the first number in the list is the left most slider value and the last number in the list is . The aim of this simple patch is to read through these values in sequence, one after the other, with an interval in between reads and convert the values to MIDI notes.
This long list is fed into an object called listfunnel, which is a very simple yet very useful object at times. Listfunnel takes a list of numbers (such as our sixteen integers) and outputs them as a series of indexed pairs, starting with an index beginning at zero.
For example, if there is a list with the value
'57 60 72 43'
and this is put in to the listfunnel object, it will return four lists of two numbers, where the first value in each list is an index and the second is the individual value. In the example, list funnel will return:
'0 57'
'1 60'
'2 72'
'3 43'
This is very useful for sorting and dealing with lists quickly and efficiently.
Now, the MIDI pitch data is represented as a set of sixteen indexed pair. These indexed pairs are fed into the coll collection.
The coll object is a general memory area where values are stored and can be retrieved for later use. To store a value in a coll object, it must have a symbol associated with it. When this symbol (ie. number etc) is sent to the coll, then the coll retrieves the data at the location of the symbol and outputs it to its left most output.
This symbol association can be thought of as an address or an index, somewhere to look something up. So, to store a value in the coll, a list of at least two values must be sent to it. The first value in the list is the address or index (ie. the symbol that is associated with the data) and any other items in the list are then associated with that particular address. Then, when the address (by itself - ie. a single number) is sent to the coll, then the coll retrieves the data from that location.
For example, if we send four lists to the coll, like:
'0 57'
'1 60'
'2 72'
'3 43'
then we have store the value 57 at index 0, 60 at index 1, 72 at index 2 and 43 at index 3. If, after this point in time, we send the value 0 to the coll, the coll will return the value 57 because we stored that value at that index earlier.
Because our sixteen values are now already correctly formatted for the coll object, they will appear at index points 0 to 15.
A tempo object is connected to a bang button, which is in turn connected to a counter object. It is this counter that actually controls which value comes out of the coll when. The counter counts up from 0 to 15 and repeats indefinetaly. This is governed by the arguments '0 0 15'. The first zero represents the direction (o for up, 1 for down, 2 for up / down operation). The other two numbers represents the minimum and maximum values of the counter. This is simply the index range of the data in the coll object.
The counter increments up by one each time it receives a bang to its left input. This bang is sent from the bang button, which is connected to the temp object. Because the tempo object is set to a bpm of 120, with a multiplier of 1 and a beat division of 4, the next note in the sequence will be triggered every crotchet note at 120 bpm. The second-left inlet of the tempo object sets the tempo of the output in bpm by changing the number boxed marked 'bpm'. The left most inlet starts and stops the tempo object (with the toggle marked 'start', 0 for off an 1 for on).
Finally, the data from the coll object (which is the pitch data from the multislider) is sent to a makenote object as the pitch element in a MIDI note. The makenote object generates a note on and follows it up automatically with a note off after a user-defined period of time. The velocity and length of the note are initially set by the arguments '60 300' where 60 is the velocity and 300 the time in ms. The velocity is also user-controllable by the number box marked 'velocity'.
The output (left outlet for pitch and right outlet for velocity) is sent to a noteout object, which makes the transition into actual MIDI data.
And, Sequencing Velcocity

This simple extension adds the following features to the patch described above:
• The ability to sequence not only pitch but also velocity
This straightforward extension of the previous version adds only three objects, yet it allows the user to sequence the pitch of a note as well as velocity.
A second multislider, listfunnel and coll are added and connected to the counter identically to the first set. This multislider is also an integer-based object, but has a range of 0 to 127. The data contained within the second coll and generated by the second multislider is representative of the velocity of a note.
Since both coll objects have their data requested by the same counter object, the first note will also have the first velocity and so on.
The output of the second coll is connected to the makenote object's second inlet (which controls the velocity of the generated note). Because of this, there is no use for a global velocity control (and it has been removed).
Phase-relative step-sequencing
This simple extension adds the following features to the patch described above:• The ability to sequence not only pitch but also velocity using loops of different lengths, creating more complex time signatures and the possibility of simple phase-relative musical structures
Once again, this patch is almost identical to the version preceding it. Only three objects have been added, but these objects offer a different type of control to that explored previously.
Imagine if it were possible to step-sequence in a loop velocity and pitch data where the loops for the velocity and the pitch data are of different lengths. This opens the door for phase-relative phrases and structures, which can produce more complex musical patterns than the source data might have one initially believe.
The idea is that although both coll objects for pitch and velocity are being clocked out by the same tempo object (and are therefore in time), different length loops of the data itself is achieved by using a counter for each coll instead of sharing a counter like the previous example. Furthermore, the maximum point for each counter (which determines the loop range) is user-definable and can be set to any number between 0 and 15. The right-most inlet of the counter objects set the maximum counts and are controlled by the length (pitch) and length (velocity) number boxes.
So, if the pitch length is set to 15, then the pitch coll will always read the index from 0 to 15. But if the velocity is set only to 2, then the velocity coll will only always read from 0 to 2 (in other words, only the first three velocity sliders) before going back to 0.
Sunday, February 10, 2008
"Impossible Buildings" (Ableton Live, Arduino and uVGA)
Video URL: http://www.youtube.com/watch?v=3F0kaLbm9ck

"I am working on trying to incorporate synchronised, synthesised video into performances where a computer is not necessarily available or desirable. This is my first attempt at using 4D system's uVGA module. This is a small circuit board that takes serial commands and generated video that can be displayed on any VGA-compatible display device (projector, monitor etc). In this video, a minimalistic drum track data from Ableton Live is sent to an Arduino, which is in turn connected to a 4D systems uVGA and a 15" monitor. Some nice visuals are thus generated. If only i had a data projector... then this sort of stuff would look much better. "
The uVGA module and Arduino
Below are some pictures of the uVGA module and a breadboard of the Arduino setup. The physical connections are extremely simple - for basic operation (without receiving an acknowledgment byte) only three connections had to be made, namely Arduino TX to uVGA RX, 5V and ground. The filter caps as seen in the manual are not necessarily needed (at least, performance has not suffered due to their exclusion).


A special connection cable was improvised using a left over snippet of stripboard, an eight pin dual inline socket, some rainbow cable and a four pin header. The reason for this cable is simply that the horizontal header pins of the uVGA do not make for a very stable breadboard.Software Interfacing
Writing data to the module is straightforward. The uVGA module is "woken up" by sending 85 after waiting at least 900ms after power up. This is so that the module auto-detects the baud rate. I found it very strange that the device would not respond correctly to Serial.print() commands, but did respond to printByte() (thanks to Oscar G. at the 4D Systems forum for helping me out with this - this is very appreciated).
Once the module has been activated, it is just a matter of sending commands with variables so that the device draws the correct shapes and colours on the screen.
For example, this Arduino sketch makes use of only the "Pain Area" command, which takes the form of "0x70, A, B, C, D, E, F, G, H, I" (sent without the commas or spaces over the serial port), where A to I are bytes as follows:
A = Upper left corner of area, horizontal co-ordinate, most significant byte
B = Upper left corner of area, horizontal co-ordinate, least significant byte
C = Upper left corner of area, vertical co-ordinate, most significant byte
D = Upper left corner of area, vertical co-ordinate, least significant byte
E = Lower right corner of area, horizontal co-ordinate, most significant byte
F = Lower right corner of area, horizontal co-ordinate, least significant byte
G = Lower right corner of area, vertical co-ordinate, most significant byte
H = Lower right corner of area, vertical co-ordinate, least significant byte
I = 8 bit colour variable, b7 and b6 are blue, b5, b4 and b3 are green and b2, b1 and b0 are red
Code
int i;
byte data;
void setup() {
Serial.begin(57600);
DDRB = DDRB | B00000000;
delay(1000);
printByte(85);
delay(100);
}
void loop() {
if(Serial.available() > 0) {
data = Serial.read();
for(int j = 0; j < data; j = j + 8) {
drawP(i % 190, i % 180, i % 20, i % 30, data % j, 1);
delay(1);
i ++;
}
}
if(i == 32767) {
i = 0;
}
}
void drawP(byte X1, byte Y1, byte X2, byte Y2, byte colour, int delayTime) {
printByte(0x70);
printByte(0);
printByte(X1);
printByte(0);
printByte(Y1);
printByte(0);
printByte(X2 + X1);
printByte(0);
printByte(Y2 + Y1);
printByte(colour);
delay(delayTime);
}
Max/MSP Patch
The Arduino receives data from Live via MIDI in this patch.
Download the patch here:http://milkcrate.com.au/_other/downloads/max_patches/vgahack.pat
Prfctday video of "almost two weeks"
Video URL: http://youtube.com/watch?v=eXwUqlF2z0o
Saturday, February 09, 2008
Controlling an SP0256-AL2 speech IC from Live using Arduino

Video URL: http://www.youtube.com/watch?v=Uu-KR1b9jII
"The SP0256-AL2 "Narrator" chip has appeared in many arcade games in the 80's for speech synthesis purposes.
This video shows a hardware ("real") SP0256 IC sequencer from Ableton Live via internal MIDI routing and a serial connection over USB.
In the video, the left track is the SP0256-AL2 and the right track is a drum track that is playing back on a virtual sampler.
I didn't really try to make words or phrases. Instead, i have tried to use the chip in a more musical way.
I really like the sound quality and some of the address sounds heard from the chip. Nice and grainy. "
Friday, February 08, 2008
little-scale: automaton ep [2007 / 2008]
"A pleasant blend of minimalist electronic music, noise and thick textures. All musical structures, forms, rhythms, notes and timbres found on this EP originate from a single 11.6 millisecond sound."track listing
01. crush [1:25]
02. treading water [6:01]
03. the emphasis is on small things [2:17]
04. almost two weeks [7:36]
05. a good career move [1:57]
download
http://www.milkcrate.com.au/_other/downloads/mp3s/automaton.zip
© 2007 / 2008 sebastian tomczak.
Audio -> data -> audio -> data: controlled feedback music
Audio is coming out of Live. This is fed to a Max/MSP patch. This patch generates MIDI data of notes and continuous controllers, based on the amplitude peaks of the incoming audio. EQ can be applied to any stream of data analysis. Four notes and four continuous controllers can be generated at once. This MIDI data then is routed to Live. Which generates audio. Thus, audio is coming out of Live. This is fed to a Max/MSP patch...Video URL: http://www.youtube.com/watch?v=zkntCapCOfw
Tuesday, February 05, 2008
Simple polyphonic synth with just arduino

Video: http://www.youtube.com/watch?v=wJZVMu78T9g
So, i thought it might be possible to generate more than one tone at a time using Arduino. The idea and the outcome is relatively simple, yet i still quite like the character of the sound.
The modulo (with symbol %) of two numbers means that the outcome equals the remainder when the left number is divided by the right number. So:
5 % 2 = 1
and
5 % 3 = 2
and so on.
Consider that we have a counter variable, 'c' that increments with every loop of code. By performing the modulo operation on 'c', it is possible to creates loops within the larger loop that will occur 'alongside' (concurrently with) the main loop.
So, let us set up a loop with a length of eight iterations and add a single modulo function in relation to 'c' (using the variable 'a'):
for(int c = 0; c < 8; c++) {
a = c % 3;
}
So, when c = 0, 1, 2, 3, 4, 5, 6, 7, a = 0, 1, 2, 0, 1, 2, 0, 1 respectively.
The synthesis relies on creating a long loop (based on the integer i). Then, four oscillators are created and controlled by setting digital output pins d2 to d5 based on smaller, concurrent modulo loops.
For the first half of the modulo loop, the pin will be set low. For the second half, it will be held high. The length of the modulo loop (and therefore the frequency of the oscillator in question) is controlled by one of four pots (one for each oscillator).

Code:
/* Very basic polyphonic synth with Arduino
by Sebastian Tomczak
5 February 2008
*/
byte state;
byte mod[] = {
0, 0, 0, 0};
void setup() {
DDRD = DDRD | B11111100;
DDRB = DDRB | B00000000;
}
void loop() {
for(int i = 0; i < 32767; i++) {
for(int j = 0; j < 4; j++) {
state = 0;
mod[j] = analogRead(j) >> 2 & B11111110;
mod[j] = i % mod[j] / (mod[j] / 2);
state = state + mod[j];
state = state << 1;
PORTD = state << 2;
}
}
}


















