Jump to content

k-Pack

Members
  • Posts

    323
  • Joined

  • Last visited

Everything posted by k-Pack

  1. I am not familiar with The VEX hardware or it's capabilities but I found some interesting information and circuits in the book Your Atari 8-Bit Comes Alive. The link to Atarimania and the book: http://www.atarimania.com/documents-atari-400-800-xl-xe-books_1_8.html Lately I've been sending MIDI data from Midi instruments to an Arduino and then the Arduino sends out data to the Atari through the joystick ports to set the sound registers. I've also used the Atari joystick port as outputs to trigger events on the Arduino. I got the information to use a shift register with latch to control stepper motors(28BYJ-48 with driver board) using 3 digital pins (data, clock, latch) on the Arduino from the book. I don't see why the joystick pins could not be configured to do the same thing. And, I do like using optocouplers to isolate the Atari and experiments. I haven't lost a computer yet.
  2. Its been several years since the screen on my brick went bad and was never replaced. Some of this information may be dated. HiTechnic use to produce an Prototype Board that would plug into the MindStorm. It had 6 digital inputs/outputs and 5 Analog outputs. The programing was done using NXT-G Blocks and was a breeze to program. Try getting information info at www.hitechnic.com. I hooked an Atari joystick to the inputs and controlled the robot. Want to go wireless. Kind of depends how far you want to go with this but you can hook an Arduino Uno up to the 850 interface (RS-232) and then have the Arduino retransmitted the commands the BLOCK using Blue Tooth. I have this list of literature on hardware projects with some reference to robots and servo motors and everything else. Might want to look through it for information on interfacing the Atari8 http://atariage.com/forums/blog/572/entry-13212-a8-hardware-project-literature/
  3. Yes, The 4 directional switches inside the joystick control the bits in a 4 bit number. 0 to 15 depending on the logic levels. When the computer is turned on the logic levels are all ones, thus the 15 is returned from a STICK(0) call. Add up all the pin numbers. 1 + 2 + 4 + 8 = 15. Pin 1 - UP - 1 Pin 2 - DOWN - 2 Pin 3 - LEFT - 4 Pin 4 - RIGHT - 8 When one of the 4 switches is on, the pin is grounded resulting in a logic level of 0. You can subtract the direction number from 15. Say you push down. 15 - 2 = 13. When UP and LEFT are activated it becomes 15 - 1 - 4 = 10. If UP and Down are activated your stick is broken. I hope this helps.
  4. While playing Pac-man with a standard Atari Joystick, how often have you missed a turn? I may have a solution, if its due to pushing the joystick to far off the four directional axis. If its due to a slow reaction time then you're still on your own. I noted while playing Pac-man that my granddaughter would rotate the joystick base and start pushing the joystick into the diagonal directions(and so was I to a lesser extent). When 2 directional buttons on the joystick are pressed Pac-man determines that you are not sure which way you want him to go and continues to the end the lane. An Arduino can be used to read a Wii nunchuk analog joystick and determine which of the 4 directions it is closest to and then set the joystick pins. This would double the acceptable error from true UP, DOWN, LEFT and RIGHT. I believe it has improved my Pac-man scores. The first time I used the setup I was able to advance to level 2. The second try got me to level 3. The third game got me to level three with a personal high score of 12,200 points. I'm getting the feeling that I'm RTC (Reaction Time Challenged)? What to do? My first Out of the Pack blog project was using the nunchuk as an Atari Joystick. The circuit hasn't changed much and is still using the same Arduino library from a slightly modified program from "Arduino: A Quick-Start Guide" by Maik Schmidt. You'll need some of this information. http://atariage.com/forums/blog/572/entry-11529-nunchuk-arduino-atari-joystick/ The prototype shield built for the Synthdrum project was reused. This shield has been getting a lot of use . A reset button has been added since the last time it was photographed. You can even leave the MIDI shield plugged on the stack but be sure to turn it off. http://atariage.com/forums/blog/572/entry-13921-midi-music-system-and-two-synth-drums/ The Arduino program is simple enough. Of course, I could have saved myself a couple of days of frustration if I had paid closer attention in trigonometry class. I can still remember 45 years ago saying to myself, "When am I ever going to use this crap." I suppose that it would have been easier to download the MATH library with the required functions to calculate angles but I found a way……. 1. Read the nunchuk x,y 2. Adjust x,y to 0,0 point of origin. 3. Calculate the Radius of a circle through adjusted x,y (a^2=b^2+c^2) 4. Use SIN,COS table to calculate XY limit points at the 45deg limits 5. Determine which limit points the XY is between. 6. Set the joystick port 7. Check the button status 8. Start over. atari_nunchuk_4_Pacman.zip Most of the testing was done with the unit plugged into the ATARI8 and using the following program. 10 X=STRIG(0):Y=15-STICK(0) 20 IF X<>LASTX OR Y<> LASTY THEN ? X,Y 30 LASTX=X:LASTY=Y 40 GOTO 10 Then I remembered that I had made the Joystick Tester for just this situation and that worked too. http://atariage.com/forums/blog/572/entry-11972-pocket-joystick-tester/
  5. Thanks, I have my Wii Guitar setting in the corner and have often thought of trying something with it. Its just a matter of what. Build a game like Guitar Hero(GH) only use AMS files, or build an interface for the Banjo Picker from Antic, or a ukulele picker(it has 4 strings). I didn't use any of the MIDI libraries yet so maybe it would be easier with the use of the GH guitar libraries. I've had the NUNCHUCK and CLASSIC controllers hooked up to the joystick ports. How much harder can it be? I'ld like to find out but it will take a while before I have the time.
  6. Finally got the DH-100 digital horn telling the Atari8 what tones to make and when. There was a couple of times I didn't think it was going to happen. Luckily the compiled basic program runs fast enough to keep up with the filtered data from the Arduino. Some sound tests have been recorded and placed in the following ZIP file. sound checks.zip Nothing has been done to enhance the sound from the Pokey chip other then combining 2 channels to allow the use of 16 bits to define the tones. The breath controller was turned on during the recording to maximize any delay that may exist. While messing with the mixer and sound effects I recorded a bonus file for your listening pleasure. Cranked up the sound effects to full on, so I hope it don't make your ears bleed. I may record some music when I get the band together. (Or should I say, I have to get the ST operational and remember how the Band-In-A-Box software works) The technical stuff: This project has been ongoing over the last 6 months and will continue to be modified/ tweaked probably as often as it is used. Older blog entries begin with "DH100". It should make them easier to find. The Arduino interface hardware hasn't changed since it was last described. It is close to being a good general purpose design for manipulating the joystick port. I'm debating if I should design a PC board for an Arduino shield. I have to build 5 or 6 more interfaces for the Atari MIDI rack of my dreams. The software used for the Arduino and Atari8 are in the following zip file. You should be able to follow most of the logic. I tried to comment. DHMIDI.zip DH100-2-ATARI8 folder. Holds the Arduino program. The biggest difference from the last blog entry is that a counter for the Breath control data was added. The counter keeps track of the number of 208 MIDI commands (pressure control set points) have been received. Then every 15th data point is sent to the Atari and the counter reset. This greatly reduce the number of data points being sent to the Atari and still give some degree of volume control. DHMIDI.ATR contains- DHMIDI.EXE is the compiled DHMIDI.BAS using the MMG BASIC Compiler. The double precession integer math used instead of the floating point package greatly increased the speed of the program. Most of the received MIDI commands are printed to the screen since the display doesn't need to be turned off to save processor time. DHMIDI.BAS is the program that receives the data from the Arduino and turns it into sounds. This may help if you wish to examine the code. 1-9 Title and program information 10 GOSUB 14000 to set up variables, then GOTO 500 to start 100-150 subroutine to get a byte of data from the joystick port- returns x 500-530 gets input - if command then split upper and lower bits 600-630 Pressure sensor command - set new volume 700-720 Set Portomento flag 800-830 Set Atari Distortion level - should be used to select different voice envelopes 900-990 Plays note when portomento is turned off or redirects to portomento routine 2000-2060 portomento slide to next note. Same number steps between any 2 notes 14000-14200 sets up variables, tables, register names, motor control bit, unitize sound registers 15000-15170 data for audio control bytes Low byte, High byte and double byte. Used to save time calculating these number when called. Saved so MIDI note number = index 15500 data for distortion number. 10 -pure tone. upper 4 bits of AUDIO Control 2 location. It hurts my brain when I try to think of all the ways this program can be improved/modified. The system works as a monophonic sound source when any MIDI instrument is hooked up and transmitting data on channel 1.
  7. 1/14/2018 - Got everything working even the Portomento setting. A big problem is hitting the tone button on the horn by mistake. Turns out the data was overflowing the Arduino serial input buffer again. It's one long stream of data when the pressure sensor is outputting the data. It seems to work if I use every 15th data point to set the volume but only when it's not the same as the last set point. And of course, the BASIC program has to be compiled. Now to record some audio examples for the next blog entry.
  8. 1/12/2018 - After the post I started working on the basic program to set the sound registers. I got it working with the breath controller turned off. Play with the breath controller turned on and my logic falls apart. The DH-100 continues to send non zero breath pressure readings even after the note has turned off. Now I have to figure out how to filter out those unnecessary numbers on the Arduino side. The horn sends out a note on command at Zero volume. When this happens the control data can be dropped until the next noteon at some volume. The Arduino will have to be programed to deal with these events to reduce the data stream to the Atari.
  9. Its still in the early thinking stage but I am thinking about doing a tribute to W. Carlos's Switched on Bach album. Recreate the play list on the Atari and call it Switched on Pokey.
  10. I finished work on the last blog entry, unplugged the keyboard and plugged the digital horn. I was a little surprised to see how much data the breath pressure sensor(after touch) was being streamed to the Atari 8. Far more then it could keep up with. The Arduino needed to be reprogramed to reduce the number of bytes being send to the Atari8. The interface software was tested with the previous Atari 8 test program and it performed much better. The data seemed to make sense and it was difficult to overwrite the serial input buffer on the Arduino. These are the ways that the data stream was reduced. The DH-100 has 4 types of data it will generate. The Arduino reads in the data, modifies it and sends it out in the void loop() function. Casio DH-100 MIDI output 1 Note On Event 1001nnnn, 0kkkkkkk, 0vvvvvvv (144+,n,v) 2 Control Change 1011nnnn, 0ccccccc, 0vvvvvvv (176+,65,v) value 0=off, 127=on (portomento) 3 Program Change 1100nnnn,0ppppppp (192+,p) p = 0 to 5 (patch change) 4 Channel Pressure 1101nnnn,0vvvvvvv (208+,v) v = 0-127 scaled to 0-15 for Atari volume(breath controller) The DH-100 will only transmit data on MIDI channel 1. The Arduino will check for any incoming command byte. If it is a command byte, it will have the 7th bit set and bits 0-3 will contain the channel number(zero for channel 1). If the data for the command can be stated in under 4 bits it can be combined with the command in one byte and sent. Channel Pressure: This command generates a continuous stream of data. This 2 byte command is reduced to one byte by scaling the 0-127 from the DH100 to 0 - 15 for the Atari. The Atari value replaces the channel number. It is far less sensitive to changes and by sending the byte only when it has changed will reduce the data flow. Program Change: has a value of 0 to 5. It also can be added to the command byte and sent as one byte. It doesn't happen very often but its still 1/2 the original data byte count. Control Change: The DH-100 only has one controller and it is 65 for the Portomento switch. The Atari can assume that if a Control Change command is received and, the 65 doesn't have to be sent. A value of 0 for off or 127 for on. Change the 127 to 1 and added it to the command byte. Another byte saved. Note On: The third byte of the command is the volume and can be handled the same way as the Channel Pressure. The second byte (note number) may as well be sent as an unmodified second byte. Reducing this to 2 bytes is still a savings in time. All of this data is checked for redundancy and not sent unless there is a change. When a command is not to be sent to the Atari the command is reset to zero and some how makes it back to reading the data until a command byte is detected otherwise it is sent using the second switch-case set of routines. The Atari can split the data off the command byte without to much trouble. The integer math of the MMG Basic complier should make it even faster. Where X = combined input data: Command = int(X/16)*16 DataValue= X - Command /* Midi data transfer test 1/2018 * * This program reads midi data then outputs * the data to the Atari Joystick ports. * * The use of the control lines to the Atari Trigger * and from the cassette motor control line on the SIO * port are used for data flow control. * * An effort to minimize data transfer by combining data bytes * since DH100 uses Midi channel 1 the first four bits of the * data byte can be used for Atari Volume(0-15) and controller * data. Atari can then strip the lower four bits and make the settings. */ // Atari PORTA(54016) mapped to pins on Arduino int porta0 = 4; int porta1 = 5; int porta2 = 6; int porta3 = 7; int porta4 = 8; int porta5 = 9; int porta6 = 10; int porta7 = 11; int DSR = 3; //Arduino ready int DTR = 12;//Atari ready byte zero = 0; byte midiData = 0; byte midiCommand = 0; byte midiNoteNum = 0; byte lastMidiNoteNum = 0; byte volume = 0; byte lastVolume = 0; byte portemento = 0; //0=OFF 127=ON byte patch = 0; //0 - 5 byte controlChange = 0; byte dataByte = 0; //Function to Send a byte to the Atari void sendByte(byte byteToSend){ setPorta(byteToSend); digitalWrite(DSR,LOW); //data ready-Trigger 0 while(digitalRead(DTR) == LOW){} //Wait for Atari to get byte cmc goes low digitalWrite(DSR,HIGH); //data not ready-trigger 1 while(digitalRead(DTR) == HIGH){} //wait for Atari to signal ok to get next byte } void setPorta(byte byteToMap){ // Sets digital pins to transfer data to Atari joystick ports(PORTA) // When digital port high, joystick pin shorted to ground or logic 0 if (byteToMap & B00000001){digitalWrite(porta0,LOW);} else {digitalWrite(porta0,HIGH);} if (byteToMap & B00000010){digitalWrite(porta1,LOW);} else {digitalWrite(porta1,HIGH);} if (byteToMap & B00000100){digitalWrite(porta2,LOW);} else {digitalWrite(porta2,HIGH);} if (byteToMap & B00001000){digitalWrite(porta3,LOW);} else {digitalWrite(porta3,HIGH);} if (byteToMap & B00010000){digitalWrite(porta4,LOW);} else {digitalWrite(porta4,HIGH);} if (byteToMap & B00100000){digitalWrite(porta5,LOW);} else {digitalWrite(porta5,HIGH);} if (byteToMap & B01000000){digitalWrite(porta6,LOW);} else {digitalWrite(porta6,HIGH);} if (byteToMap & B10000000){digitalWrite(porta7,LOW);} else {digitalWrite(porta7,HIGH);} } void setup() { pinMode(porta0,OUTPUT); pinMode(porta1,OUTPUT); pinMode(porta2,OUTPUT); pinMode(porta3,OUTPUT); pinMode(porta4,OUTPUT); pinMode(porta5,OUTPUT); pinMode(porta6,OUTPUT); pinMode(porta7,OUTPUT); pinMode(DSR,OUTPUT); pinMode(DTR,INPUT); Serial.begin(31250); setPorta(zero);// digitalWrite(DSR,HIGH); } void loop() { //read data until its a Midi command //command bytes will have bit 7 true while (midiCommand < 128){ while(Serial.available()<1){}//wait for data midiCommand = Serial.read(); //read MIDI stream } // get data required by command. // volume - make sure it is an incremental change // midiCommand = 0 if not valid or redundant - do not send // patch - should be >6 switch(midiCommand){ case 208:// Breath controller while(Serial.available()<1){} volume = Serial.read(); if(volume != 0){volume = map(volume,1,127,1,15);} if(volume == lastVolume){midiCommand = 0;} break; case 144:// NoteOn command while(Serial.available()<1){} midiNoteNum = Serial.read(); while(Serial.available()<1){} volume = Serial.read(); if(volume != 0){volume = map(volume,1,127,1,15);} if((volume == 0) && (midiNoteNum != lastMidiNoteNum)){midiCommand = 0;} break; case 192: //Patch change while(Serial.available()<1){} patch = Serial.read(); if (patch >5){midiCommand = 0;} break; case 176: //control change (65=portemento) 0 off,127 on while(Serial.available()<1){} controlChange = Serial.read(); if (controlChange == 65){ while(Serial.available()<1){} portemento = Serial.read(); if (portemento >0){portemento = 1;} //1 = on break; } else {midiCommand = 0; break; } default: //if not a DH-100 command ignore midiCommand = 0; break; } // //combine data and send if command <> 0 if (midiCommand != 0){ switch(midiCommand){ case 208: //breath controller dataByte = midiCommand + volume; sendByte(dataByte); lastVolume = volume; break; case 192: dataByte = midiCommand + patch; sendByte(dataByte); break; case 176: dataByte = midiCommand + portemento; sendByte(dataByte); break; case 144: dataByte = midiCommand + volume; sendByte(dataByte); lastVolume = volume; sendByte(midiNoteNum); lastMidiNoteNum = midiNoteNum; break; } } midiCommand = 0; } A8 - Frequency tables De Re Atari has a chapter on sound that is quite interesting. Seems that SOUND 1 and SOUND 2 can be combined to improve pitch control. Then I found the article "Perfect Pitch" by Fred Coffey in COMPUTE!'S SECOND BOOK OF ATARI. It provided the information and formulas to convert frequency data to the equivalent 16 bit numbers needed to produce those numbers and it seemed to make the whole process easy. A utility program has been written to produce the DATA statements for a 108 X 3 array. The MIDI note number from the Arduino can be used to index into the array and then the 16 bit number (to be used for portomento calculations), high byte, and low bit can be accessed for use. This program should make it easy to modify the data statements if changes are to be made. Who knows, maybe the need will arise when they are required in MAC/65 format. The frequency data came from a keyboard chart. <http://newt.phys.unsw.edu.au/jw/notes.html> Line 20 needs to be changed when the DATA statements are to be listed to disk. Then they can be ENTERed into a program. Typing the Frequency DATA once was enough for me. 10 LINE=5000:REM LINE NUMBER 20 OPEN #1,8,0,"S:":REM "D:FTABLE.BTX" 30 ? #1;"4999 REM FREQUENCY FOR MIDINOTE 21-108(NOTE A0 TO C8)" 40 TRAP 300 50 ? #1;LINE;" ";"DATA "; 60 FOR X=1 TO 5 90 READ PITCH 100 P2=INT((1789790/(2*PITCH)-7)/256) 110 P1=INT(1789790/(2*PITCH)-7-256*P2+0.5) 115 P0=P2*256+P1 117 REM 2 BYTE, HI BYTE, LO BYTE 120 ? #1;P0;",";P2;",";P1; 125 IF X<5 THEN ? #1;","; 130 NEXT X 140 ? #1 150 LINE=LINE+10 160 GOTO 50 300 ? #1;-1:CLOSE #1:END 490 REM FREQUENCY FOR MIDINOTE 21-108(NOTE A0 TO C8) 500 DATA 27.5,29.135,30.868,32.703,34.648,36.708,38.891,41.203,43.654,46.249,48.999,51.913 510 DATA 55,58.270,61.735,65.406,69.296,73.416,77.782,82.407,87.307,92.499,97.999,103.83 520 DATA 110,116.54,123.47,130.81,138.59,146.83,155.56,164.81,174.61,185,196,207.65 530 DATA 220,233.08,246.94,261.63,277.18,293.67,311.13,329.63,349.23,369.99,392,415.30 540 DATA 440,466.16,493.88,523.25,554.37,587.33,622.25,659.26,698.46,739.99,783.99,830.61 550 DATA 880,932.33,987.77,1046.5,1108.7,1174.7,1244.5,1318.5,1396.9,1480,1568,1661.2 560 DATA 1760,1864.7,1975.5,2093.0,2217.5,2349.3,2489,2637,2793,2960,3136,3322.4 570 DATA 3520,3729.3,3951.1,4186
  11. Maybe I should have tested this program out with the digital horn. The horn puts out a lot more data that includes the after touch pressure. I believe that it is over running the 127 byte buffer used for serial communication. I think most of the data can be ignored or is redundant. There may even be a way to combine data bytes. Example: Scale the volume data to 0-15 and add it to the command code. The first 4 bytes of the command are free when using channel 1. The data points that is getting through are not totally random numbers so, I think the data transfer algorithm is sound.
  12. I was going to start writing my list of resolutions for 2018. Then I thought about writing about what I didn't accomplish in 2017. Then I decided to just work on programing the interface and get the Atari to read and print the MIDI data stream through the joystick port. I had high hopes of creating a midi monitor that would accept the data and print out the commands as they were received but all that extra code was getting in the way of finding errors. I was happy when I got the Atari8 and Arduino to just reliably print the correct bytes. A SIO cable was to be modified because the SIO2PC dead-ends the SIO chain. I just attached jumper wires with female ends to the 4th and 8th pins on a standard cable. Saved me a lot of plugging and unplugging. I wasn't looking forward to programming the Arduino and Atari 8 because trouble shooting was going to be a painful endeavor. Was it the interface hardware, the Arduino program or the Atari8 program that is the problem. Yes, I had problems with all three and even created more. The Arduino Program. The Arduino performs the following steps. 1. Reads the midi data stream and puts it into a buffer. Continuously. 2. Gets a bit from the buffer. FIFO 3. Sets control pins for the 8 joystick pins 4. Sets trigger to signal that data is ready to be read 5. Waits for Atari to signal it got the data 6. Sets the trigger to signal data not ready 7. Waits for Atari to signal reset the process to step 2. Its simple, when you remember that the logic from the Arduino is inverted. When a pin on the Arduino is set high the transistor in the optocoupler turns on, shorting the pin to ground. Thus making the logic level, read by the Atari, LOW. /* Midi data transfer test 12/2017 * * This program reads midi data then ouputs * the data to the Atari Joystick ports. * * The use of the control lines to the Atari Trigger * and from the cassette motor control line on the SIO * port are used for data flow control. * */ // Atari PORTA(54016) mapped to pins on arduino int porta0 = 4; int porta1 = 5; int porta2 = 6; int porta3 = 7; int porta4 = 8; int porta5 = 9; int porta6 = 10; int porta7 = 11; int DSR = 3; //data set ready int DTR = 12;//Atari ready byte zero = 0; byte tempX = 0; int midiData = 0; //Function to Send a byte to the atari and void sendByte(byte byteToSend){ setPorta(byteToSend); digitalWrite(DSR,LOW); //data ready-Trigger 0 while(digitalRead(DTR) == LOW){} //Wait for Atari to get byte cmc goes low digitalWrite(DSR,HIGH); //data not ready-trigger 1 while(digitalRead(DTR) == HIGH){} //wait for Atari to signal ok to get next byte } void setPorta(byte byteToMap){ // Sets digital pins to transfer data to Atari joystick ports(PORTA) // When digital port high, joystick pin shorted to ground or logic 0 if (byteToMap & B00000001){digitalWrite(porta0,LOW);} else {digitalWrite(porta0,HIGH);} if (byteToMap & B00000010){digitalWrite(porta1,LOW);} else {digitalWrite(porta1,HIGH);} if (byteToMap & B00000100){digitalWrite(porta2,LOW);} else {digitalWrite(porta2,HIGH);} if (byteToMap & B00001000){digitalWrite(porta3,LOW);} else {digitalWrite(porta3,HIGH);} if (byteToMap & B00010000){digitalWrite(porta4,LOW);} else {digitalWrite(porta4,HIGH);} if (byteToMap & B00100000){digitalWrite(porta5,LOW);} else {digitalWrite(porta5,HIGH);} if (byteToMap & B01000000){digitalWrite(porta6,LOW);} else {digitalWrite(porta6,HIGH);} if (byteToMap & B10000000){digitalWrite(porta7,LOW);} else {digitalWrite(porta7,HIGH);} } void setup() { pinMode(porta0,OUTPUT); pinMode(porta1,OUTPUT); pinMode(porta2,OUTPUT); pinMode(porta3,OUTPUT); pinMode(porta4,OUTPUT); pinMode(porta5,OUTPUT); pinMode(porta6,OUTPUT); pinMode(porta7,OUTPUT); pinMode(DSR,OUTPUT); pinMode(DTR,INPUT); Serial.begin(31250); setPorta(zero);// digitalWrite(DSR,HIGH); } void loop() { if (Serial.available()>0){ midiData = Serial.read(); //read MIDI stream tempX = byte(midiData); sendByte(tempX); //Send to Atari } } The Atari Program When the Atari wants data it checks the trigger button to see if there is any to read. If not, this program simply waits for one to show up. 10 GOSUB 29000:REM SET UP VARIABLES 15 POKE PACTL,CMCOFF:REM CAS.OFF 20 IF STRIG(0)=0 THEN GOTO 20:REM WAIT ARDUINO TO SIGNAL DATA READY 30 MIDIDATA=PEEK(PORTA):REM READ 35 ? MIDIDATA;" ";:SOUND 0,200,15,15:SOUND 0,0,0,0:REM SHOW DATA ON SCREEN 40 POKE PACTL,CMCON:REM GOT DATA 60 IF STRIG(0)=1 THEN GOTO 60:REM ARDUINO BUSY GETTING DATA 70 POKE PACTL,CMCOFF:REM TELL ARDUINO TO HOLD DATA UNTILL READY 80 GOTO 20:REM GO WAIT FOR NEXT BYTE TO BE READY 29000 PORTA=54016:REM STICK 0 AND 1 29020 PACTL=54018:REM PORTA CONTROL 29030 CMCON=52:REM CASSETTE MOTOR ON 29040 CMCOFF=60:REM CAS. MOTOR OFF 29050 REM POKE 559,0:REM TRUN OFF SCREEN 29100 RETURN A Casio Keyboard was attached to the interface and data was sent to the Atari and dumped on the screen. The following screen shot shows three 255s that were produced when the Arduino was turned on and the reset button was pushed twice. Then anytime a key was pressed or released a NOTE ON command on channel 0 (144) was sent. You see the 144 then the MIDI key number and then the volume setting. If a volume setting was 0 the key was released. The keyboard is not pressure sensitive so its volume defaults to 100. I didn't see any data being missed by the Atari but it was so slow. I mean, it make 300 baud seem fast. I mean, it was so slow that I tried to turn off the display. I mean, it was soooooo slooooooow that I thought I would have to get out the M65 cartridge. Instead, the program was compiled using the MMG Compiler. The speed improvement was remarkable. I couldn't get the buffer to over flow even when a bunch of keys were pressed and released. Since the digital horn is monophonic, its data output should be manageable even when it is transmitting the breath pressure(after touch) data. I also took the time to load the compiled program onto a Max Flash cartridge. Easily running these programs on computers with out a monitor and disk drive will simplify the hardware setup significantly. There was a problem when the Arduino was powered up, all the joystick pins were reading LOW. This confused the Max Flash menu and the program didn't load when the return was pressed. Pressing the Reset button on the Arduino resets the pins until they are turned off again by void Setup() function and hitting the return key on the Atari before that happens will run the program. Now on to writing the program that actually makes some noise and maybe a little music.
  13. When it’s a camouflaged storage box. It took me years of careful deliberation before I could gut one of my 410 Data Cassette Recorders. I finally came to the conclusion that I wasn't going to replace the belts just so I could play "Sammy the Sea Serpent". Why not put the case to good use and have it out on display? My original thought was to turn it into a bank. Put a coin in front of the cassette door and have a hand reach out and grab the coin. Then I couldn't believe how nicely a tray from my jewelry box fit into the bottom but my wife wasn't sure if she wanted it on the dresser(or maybe she was). I just ended up putting some felt in the bottom and some dividers for general use. I'm going to organize a collection of thumb drives, flash drives, Sony memory sticks, SD cards and a reader. What ever it was going to become, I wanted it to look like a functioning 410 Recorder when the top was closed. These are some photos taken as the build progressed. 1. Opened up 410. Removed four screws on the bottom. 2. Remove guts. 3. Salvage parts. I used the supply spindle and take-up spindle and tape counter. 4. Remove inside plastic pegs and supports that are in the way. Dremel tool and sand paper. 5. Trim the spindle shafts and super glue the parts together. Then insert them into the cassette holder from the bottom and glued. (I trimmed the disks for no good reason and don't think I would do it again.) After a cassette was placed in the holder, the tooth picks are jammed into the latches to keep the cassette door from opening. 6. Simulate the counter. Place the counter on your scanner and make a decent copy of the wheels. (use some white paper as a mask to save some ink). Cut out the numbers and tape in place. The push button was made by gluing a piece of scrap plastic over the hole, trim off a length of the black button and glue it in place. 7. Double sided tape is holding the felt in place and some dividers make of Jumbo Popsicle Sticks were cut, glued and placed on the felt. Now that I think about it, maybe I should take out the felt and sticks and mount a SIO2SD unit inside. Then rig the cassette keys as navigation buttons. I wonder how the display would look mounted in the cassette door.?
  14. This file is also in the ATR. It might be helpful. MIDIDEMO.BAS MIDITRACK III simulated DEMO By Charles Faris This is a tutorial program for the MIDITRACK III software. It explains the screen data and most of the commands of the MIDITRACK software.
  15. The Cassette Motor Control(CMC) bit in the Port A Controller (PACTL ($D302)) address is going to be used as feed back from the Atari8 to the Arduino in the digital horn project. This bit controls the logic state of Pin 8 on the SIO port. This bit has been used to control the data cassette motor. If you're not using the bit to load data from the cassette it is free to be used for other purposes. Put a music tape into a 410 and play 1 audio track through the Monitor or sound system. MIDIMAX uses it to turn itself on/off while accessing other devices in the SIO chain. Control a relay…why not? MAPPING THE ATARI says to POKE 54018, 60 to turn the motor off and POKE 54018,52 to turn it on. Let's see, if (60-52 = AND (8 is the decimal for Bit 3) then changing this bit turns on/off the CMC bit 3. This works until a program changes any of the other bits from their default value. BASIC is not well equipped to do Boolean logic on bits. It can be done but can consume more time then I want to dedicate to the task. Machine language is adept at Boolean logic and can toggle CMC by using the EOR instruction. A BASIC USR call can toggle CMC with just 10 bytes. EOR(exclusive OR) The thing that makes EOR special is that when comparing 2 bits when both are True, the result is False. EOR Logic Table EOR| 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | Watch the logic: 60 = 00111100 8 = 00001000 EOR 52 = 00110100 8 = 00001000 EOR 60 = 00111100 Note that bit 3 (4th bit from the right) is on, off and on. The rest remained unaffected. MAC/65 Assembly Language for the USR call looks like this. 10 ;USR CALL TO TOGGLE CASSETTE MOTOR 20 ;KEVIN PACKARD 09/2017 30 ; 40 ;X=USR(1536) 50 ; 0100 PACTL = $D302 ;bit 3 controls 0105 ; Cassette Motor 0110 ; 0120 *= $0600 0130 ; 0140 PLA 0150 LDA PACTL 0160 EOR #$08 0170 STA PACTL 0180 RTS 0190 .END The code was assembled, the BYTES were converted to decimal, and then put into BASIC DATA statements. These were read into page 6 and run using A= USR(1536). The program could have been placed in a String and called at the string address. This still may get done if page 6 is required for something else. The test. All my Atari cassette drive belts slip so I decided to put an LED and 330ohm resistor between pin 8 and pin 4 for testing. The BASIC program loads the code into Page 6. It then starts the loop to strobe the LED. 1 REM CASSETTE MOTOR CONTROL USR TEST 2 REM BY KEVIN PACKARD 9/2017 100 GOSUB 30000 110 X=USR(1536) 120 FOR X=1 TO 100:NEXT X 130 GOTO 110 29999 REM LOAD MOTOR CONTROL USR 30000 RESTORE 30060 30010 FOR X=1536 TO 1545 30020 READ A 30030 POKE X,A 30040 NEXT X 30050 RETURN 30060 DATA 104,173,2,211,73,8,141,2,211,96 The FOR-NEXT delay was used to slow the blinking. When removed, the LED blinked at about 64.4 hertz. When Direct Memory Access (DMA) was turned off (POKE 559,0) the rate jumped to 94 Hz. Slow but fast enough. What next I wrote this USR for use in an Atari8 BASIC MIDI Data Monitor for the DH100 digital horn project. This should help set the specification for the Arduino interface programing and provide a method of testing the interface.
  16. I have 9 optocouplers setup to receive data from the Arduino for the SAM Rock You project. Eight for the MIDI data byte from the Arduino and 1 to signal the Trigger when new data is ready to be read by the Atari8. A tenth optocoupler needs to be added so that the A8 can let the Arduino know that it is ready for the next byte. That 10th optocoupler can indicate the status set using the Cassette Motor Control. The Cassette Motor Control line on the SIO port (Pin8) is used to turn the cassette motor on and off. I have used an accessory for the Diamond GOS that sets this bit to control the cassette for audio play back. Even though I wrote the accessory, I can't remember which bit to set but I remembered the program would set that bit to test the circuit. The circuit was put together on a breadboard for testing before soldering onto the prototype board. Preliminary tests proved that the optocoupler would switch states to achieve 2000 bytes/sec. Atari BASIC isn't going to outpace this circuit. The input side of the optocoupler was wired to SIO PIN 8(motor control) and PIN4(ground). The Arduino was programed to read a pin status set by the output of the optocoupler and then turning on/off an LED. The Diamond GOS "ON/OFF CAS" accessory successfully toggle SIO-Pin8 when activated. This simple Arduino program is used to read the optocoupler output attached to Arduino digital pin 4 and turn on the LED attached to pin 6. //check connection between A8 sio cassette //motor pin and Arduino int casMotorPin= 4; int ledPin= 6; void setup() { // put your setup code here, to run once: pinMode(casMotorPin, INPUT); pinMode(ledPin, OUTPUT); } void loop() { if (digitalRead(casMotorPin) == HIGH){ digitalWrite(ledPin, HIGH);} else { digitalWrite(ledPin, LOW);} } Later the prototype was soldered together and added to the Arduino hardware board. The next step is to write the software for the Arduino to pass all relevant MIDI data to the Atari and a short Atari program to monitor the incoming data and test the data flow control. I suppose I should also look over the accessory source code to remind myself how to set the cassette motor control bit.
  17. I remember using the horn with the Atari ST and Band-in-a-Box. Transpose any song to the key of C and I could almost keep up. I will probably pull the batteries and box it up when I have finished this project. I should still be able to play the Atari with any MIDI instrument.
  18. I would be interested in a couple of boards. Having a parts list would be of great help also. I had downloaded some files from CompuServe and took a look at them a couple of months back. One of the files is: MIDIDR.DOC (MIDIDR.XMO) MIDIMate Software Interface Documentation 5/21/1985 By Hybrid Arts, Inc. If you haven't seen it, the .atr holding this file and can be downloaded from this blog entry. There is also a MIDI handler that can be used with BASIC and should work with your interface. In case someone wants to program the next MidiMaze game. http://atariage.com/forums/blog/572/entry-13705-a8-midi-and-the-atari-age-of-rediscovery/
  19. Between the time that the Casio DH-100 Digital Horn was introduced and todays prices on eBay, the price dropped to the point where it seemed to be a bargain. I was fortunate enough to have pulled the batteries (15 years ago), so there was a good chance that it would still work. Now I want to build an Atari8 sound module to accept MIDI information from the DH-100's MIDI port(or any MIDI controller). The MIDI Implementation chart for the DH-100 is not extensive but the streaming of the channel pressure data could easily overwhelm the system. I'm going to attempt to do this in Atari BASIC to facilitate experimentation. The plan is to increase the data transfer rate from the MIDI-Arduino interface to the computer by using the cassette motor pin on the SIO port to set up feed back to the Arduino. The Trigger can indicate DataSetReady and cassette motor control for DataTerminalReady thus eliminate the use of delay loops for transfer timing. My previous Atari BASIC MIDI programs have been kept very simple; mostly NOTE ON and NOTE OFF. The MIDI Implementation Chart shows 4 midi commands that can be sent from the DH-100 to control the sound. A closer look at the horn and chart should help define the program requirements for the A8. CASIO DH-100 Call it a digital horn, wind controller, or breath controller, the DH-100 works like a wind instrument. Press some keys to change the pitch and blow into the mouth piece. The harder you blow the louder the sound. On its own as a performance instrument, the internal speaker and sound synthesizer made it sound like an expensive toy. The sounds could get annoying after about 10 min. of play. (A personal observation.) The MIDI OUT port was its redeeming feature. Use it as a MIDI controller on a $500 MIDI synth and it sounded like a $500 instrument. But that's not what I want to do. I want the output for the DH-100 to control a Atari8 programed to be the sound synthesizer. Then it will sound a little POKEY. (The DH-100 has a tendency to develop a squeal(audio feedback loop). This is generally caused by 2 capacitors that can be replaced. It happened to my horn. Even though the internal sounds were useless, the MIDI output still worked. I turned down the volume and played the synth. Eventually I found the information on which capacitors to change and how. The original sound is restored. Sorry, that was a couple of years ago and the link to the information has been lost.) The horn was hooked up to the MIDI monitor to view the data stream. This information will be of value when the Arduino and Atari are programmed. These are my observations while testing the switches and buttons. Casio DH-100 MIDI Implimentation Chart.pdf Breath - off: This allows the playing of the horn without having to blow into it. Press the note keys and the sound will be produced. Press sends a NOTE ON at velocity 64, Release sends a NOTE ON at zero velocity. Breath - on: Press the note keys and then blow into the mouthpiece. A NOTE ON will be sent with a velocity proportional to the force of your exhale. Stop blowing and a NOTE ON at 0 velocity will be sent. While the note is on, the pressure sensor in the horn monitors the air pressure and sends out velocity(or after touch) whenever there is a change. Command 192+channel#, pressure from 1-127. Its difficult to maintain a constant air pressure. Transpose Button - Press the button and the note number being sent by the horn is increased by one note number. This continues up until an octave is reached, then drops 2 octaves. Keep pressing and you end up where you started. The note number is changes by the DH-100, no MIDI data is sent. Tone Selector - cycles the tone from 0 to 5. When this is pressed a PROGRAM CHANGE command is sent. Command 192+channel#,nnnn(0-5). Portamento - When pressed, notes will slide from one to the next. It uses a CONTROL CHANGE command and is controller number 65. Release the key to turn it off. The command is 176+channel#, controller #, value. Value is 0 for off and 127 for on. The command is sent only when the status has changed. That completes the tour of the MIDI Implementation Chart. I noted that there may be a typo at the Note Number - Transmitted numbers cell. The range has to be greater then 36-39. The note numbers may have to be manipulated to stay within the range that the Atari can produce. I'll deal with that at a later date.
  20. I looked at the manual and see that Syncalc files can be saved in DIF file format. Only the data is placed in the DIF files so any formulas will have to be reentered. I know these can be read by Excel 2013. Using DIF files I moved most of the data to LOTUS 1-2-3 but that hasn't been around for many years. I decided to go retro on my spread sheet needs and decided to switch to Calc Magic for the Atari XE. I wrote about the fun I had in this blog entry. Not sure if this will be helpful with what you are thinking about doing. http://atariage.com/forums/blog/572/entry-12696-going-retro-whats-the-dif/
  21. A co-worker gave me his copy of the Spring 1982 Crutchfield catalog knowing I was looking into buying my first computer. This catalog contained 15 pages of Atari product information (page93-107). I was impressed with the graphics capabilities but the onscreen lower case letters made the 800 my first computer. I have never regretted that decision. Recently I was reminiscing and noticed the catalog pages yellowing. Before it turned to dust seemed like a good time to scan and share. The entire catalog was scanned because seeing the Atari pages in with the rest of the hi-tech consumer electronics really shows how advanced the 800 really was. (The phone section is a hoot.) Crutchfield Spring 1982 .pdf I checked out the Crutchfield of today to see how much has changed. Not only has the tech changed but so has the value of the dollar. https://www1.crutchfield.com/
  22. I've added a third computer to the MIDI chain. Computer #1 plays drums, and Computer #2 runs S.A.M. and Computer #3 plays the lead, . Each computer had a specific BASIC program written to read data from the joystick ports. For this example, Queen's -" We Will Rock You" was arranged for the three computers. You can listen to the MP3 file and then decide if you want to read about the how. SAM Rocks - mp3.zip COMPUTER #0 - Control The music was entered using the MIDI MUSIC SYSTEM software. Voice 1 - Lead was assigned to MIDI channel 1, Voice 2 - SAM assigned to MIDI channel 3, and Voice 3 - Drums is Channel 10. All the editing was done using the CASIO-481 keyboard. Once the playback was acceptable, the rest of the computers were programed in BASIC and the Arduino interfaces were built. COMPUTER #1 - MIDI Channel 10 - Drums The same drum setup from the last two blog entries was used. Only one computer was required for this simple drum pattern. Computer #2 - MIDI Channel 3 - S.A.M. Getting SAM to sing the words was accomplished by activating the trigger button at the right time. The Arduino would read the MIDI data stream. Whenever a 146(NOTEON+2) command was received by the Arduino the joystick state was changed to zero for 10 milliseconds. When the Atari program detected the joystick status change, the next word is sung. Before the Atari was programmed the phoneme spelling of the words were created using the SAM Word Editor(another previous blog entry). Then a small test program was used to change the speed and pitch of the voices to meet the requirements of the music. The BASIC program simply reads the joystick port and when it reads 0 the next word is sung. This created a problem. If SAM was speaking it couldn't detect that the next word needed to be sung and resulting in skipped words. This problem was finally solved by changing the TEMPO in MMS from 175 to 160. Computer #3 - MIDI Channel 1 - Lead If I had started the work on the this computer, the project may never have been finished. Since the work on SAM was done I had to continue on. Bad solder joints, program logic and a misunderstanding of the MIDI data from the Casio or MMS added to the confusion. This was the first time a full 8bits were required to be received by the Atari8(A8). Four additional optoisolators were added to the Arduino Uno. This way the Atari could look for the MIDI command number for NOTEON or NOTEOFF. When NOTEON was detected at PORTA(joystick address) the computer would wait till the note number was set and the joystick trigger logic state changed. The note number was then used to calculate the index for an array holding frequency settings. The Arduino did most of the work decoding the midi data. You would almost think that a NOTEON would be followed by the NOTEOFF command before the next NOTEON command. NOTSO, when the Casio Keyboard was being used to test the hardware and software. Eventually the Casio was hooked up to the IBM running a MIDI Monitor. Press a note key and a NOTEON command was sent. Release the key and a NOTEON command was sent. The only difference was the velocity setting. Setting a NOTEON at 0 velocity does stop the note from being heard. You would almost think that a NOTEON would be followed by the NOTEOFF command before the next NOTEON command. NOTSO, when MMS was used to create the MIDI data stream. Some times the NOTEON command was issued before the last note turned on was turned off. So, the NOTEOFF command received by the Arduino was sent to the Atari only if the note matched the last note turned on. A function to set the output pins on the Arduino was used instead of the "case" used in the drum software. Each bit of the note byte is checked starting at bit 0. When the 7th bit is turned on the A8 computer knows it is a command byte that starts the process of turning on or off a note. The A8 then waits for the joystick trigger button to change state to indicate the note number is ready to be read. delay()s are used to give the A8 enough time to check the PORTA and the trigger. Project Software The ATRs and Arduino source code are in the zip file. The computers in the midi chain have no monitor so the programs for the drums and lead will autorun the BASIC programs. SAM would not allow the autorun code to execute the BASIC program when appended onto end of the AUTORUN.SYS file, so an easy name of "A" was used to reduce typing required to RUN "D:A". The Arduino source code for each of the instruments are in the folder. Also, an ATR containing the MMS music and info files is included. SAM Rocks - support files.zip That should be enough information if I ever want to rebuild this setup. Its been nice to be able to write custom programs and build Arduino interfaces for each voice but I have to start thinking about…. 1. A polyphonic A8 program for general use. 2. Two way communication between the Arduino and A8 3. Using commands beyond NOTEON and NOTEOFF 4. Programming using MAC/65 5. An editor for SAM to include pitch and speed manipulation 6. Getting a new furnace before winter sets in.
  23. Found these numbers on the my 800s. AW 306445 (G 154 AW213517-16 3/ 5 L20 H) Pack007 10/82 AW 350162 342 Pack007 03/82 467911 153 Pack007 15/83
  24. Nicely done. Was there any one shield that drained the battery or was it the Arduino? I thought that it might be the XBEE.
  25. A second Atari8 running SYNDRUM3.BAS was added to the MIDI chain without timing problems. There didn't seem to be a delay between the sounds from the two computers when playing 2 drum sounds on the same beat. Listen to the drum patterns and judge for yourself. Two Drum mp3s.zip THE SECOND DRUM Since the SYNDRUM program only allows one percussion sound, I pulled my first 130XE out of storage to be used as a second percussion sound source. The broken keyboard was replaced with a Transkey back in early 90s. One of the guys at the user group was so disturbed by the hole left from the missing keyboard that he made me a vacuum formed insert. It’s the computer I want to be buried with. I had forgotten that the SYNDRUM3 program displayed a title screen and required a "press any key" to continue. It was easier to edit the program then find a keyboard to plug into the Transkey. A line was inserted to bypass this holdup. 30085 RETURN A second Arduino interface was built with a Arduino Uno(clone), MIDI shield with an IN, OUT, and THRU port, and optocoupler circuit. This time, a prototype shield was used as the base for the optocouplers. It’s a little more permanent. The original circuit was moved to the 130XE because a joystick cable was used to make the connection, the DB-9 plug used on the second setup had the wings on the sides and could be used on the 800 without modification. The THRU port is an important feature when using more then one MIDI Sound Module. All data that is coming into the MIDI IN port from the control computer is passed on to the next MIDI device through the THRU port. MIDI OUT data from the sound module is not added to the data stream or passed to the next sound module. Both MIDI/Arduino interfaces receive the same data stream but are programed to look for data specific to the MIDI Channel they are programed for. In this case Channel 10 and Channel 11 was used for the SYNDRUM computers. Drum Patterns Two Drum MMS_MUS_ATR.zip Three drum patterns from the book "200 Drum Machine Patterns" by Rene-Pierre Bardet where modified to be played by the two Atari8s. The patterns consist of a Part A, Part B and BREAK. Using the MIDI MUSIC SYSTEM(MMS), each part of the pattern was programed into different Voices. Six total MMS voices were used with one measure in each voice. MMS uses Voice 1 to 20 as output voices. 2 voices were used to make the calls to play the voice segments in the pattern: A-B-A-Break. This was repeated 5 times. The 2 voices were also assigned to MIDI Channels 10 and 11 before playing. The audio outputs were patched into the mixer, combined and recorded. The EQ was used to drop the high frequencies and the bass was increased. Then the audio inputs were panned slightly left and right to give them a little separation. (I don't know if this is typical. I found that the gain setting for the 130XE needed to be much lower then the 800.) Several different TEMPOs were recorded and one with the FX generator. Loosing much of my hi frequency hearing has effected the way I hear music and when I'm doing the recording it probably effects what you hear. I've been using headphones that have a great bass response to set up the mixer for recording. So, I'm not sure what your hearing when you listen to these MP3 files. What's next? I want to get away from the solder fumes and the technical end of this and just try to use the available equipment/software to be musically creative. Of course my first two creative thoughts require solder fumes and programming.
×
×
  • Create New...