Shop OBEX P1 Docs P2 Docs Learn Events
Propeller GUI touchscreen and full color display - Page 15 — Parallax Forums

Propeller GUI touchscreen and full color display

1121315171824

Comments

  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-06-23 20:58
    @average joe, I have been thinking about ways of combining group0 and group1 so that you can latch the 161 chips and then do memory transfers without having to do any I2C access. I think I have the logic right here. 6 prop pins each have to do double duty, but with a few logic chips I think it could work.

    Go ahead and build the boards I am sending. This new one will have a faster bootup, through running programs may not be much different. The nice thing about objects is we can change just one object and all existing code will still work.

    The big thing is proving we can run several different displays and we have shown that now.

    Addit: - this schematic is still not quite right. It will need to toggle a prop pin twice per pixel when doing a ram to display transfer - increasing the time from 5 pasm instructions to 7. Maybe that does not matter? Anyway I have a vague idea that maybe there is another solution using the 4 SD card pins. SD access is never going to happen while talking to the display - SD access is always going to be a transfer to hub, or a transfer to external ram. This means the display pins could be shared with the SD pins, and that means that 161 control pins need not be shared with the display pins. I think that could save some logic gates.
  • average joeaverage joe Posts: 795
    edited 2012-06-25 01:45
    Combining group 0-1 is a great idea and agree that the schematic is not done. I'm thinking a `hc138-137 for the enable. Maybe 0-SD_enable, 1-161-Load or Clock? *Load seems more logical to me.* 2-LCD_WR? 3-Touch_Enable, or something like that? We could also "bump" the numbers up by one and use the other displays sd? I'd need to play around with the schematic to see what I can come up with. Need to finish this week's homework *still* but I will see what I can come up with.

    *edit*
    Even better, if we could eliminate the MCP... Still thinking about this one...
    137- ABC- DI,DO,CK?
    137- EN = SD_CS
    137 - Latch = P22
    
    SD1-CS 137-0
    SD2-CS 137-1
    
    161-Clock = 137-2 or p20?
    161-Load =  137-2 or DI
    
    ILI-RS    = p18
    ILI-WR   = p19
    ILI-CS(1) = 137-2 or DO
    ILI-CS(2) = 137-2 or CK
    ILI_RSTs = 137-7?
    
    RAM-WR = p16
    RAM-RD  = p17
    RAM-CS  = 137-2
    
    TOUCH1_CS = 137-3
    TOUCH2_CS = 137-4
    Touch DI,DO,CK to SD pins!
    

    Something along this line? Need to start drawing it. Not sure what's missing?
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-06-26 23:20
    I'll keep thinking about the speed a bit more too. It gets the speed a bit better but things are good enough as they are to do lots of the things we want with the board as it is.

    I'm going to have a go at a function generator app when I get home http://forums.parallax.com/showthread.php?140927-Propeller-Signal-Generator

    My 'dream machine' though is an additive synth http://www.soundonsound.com/sos/jun00/articles/synthsec.htm with a separate ADSR or even any arbitrary waveform controlling the amplitude of each harmonic. Adding the sine waves is easy - I think the bit that would take time would be multiplying each wave by an amplitude. The amplitude resolution need not be 16 bits though - maybe 10 or 12 bits. So that makes each multiply quicker. I don't know how many multiplies you could do, say, at 22khz? And maybe pull in several cogs working together. Fun to think about. Even to think about simpler effects like flange and phasor and echo and waa waa and a ring modulator. So much to explore!

    Addit - working on getting a function generator going. We have slider knobs but I would like rotary knobs as well as rotary switches. That needs some trig functions, rectangular to polar conversions. And thanks to the obex http://obex.parallax.com/objects/501/ they are all easily available.

    This is some switch code
    CON
      _clkmode      = xtal1 + pll16x                        ' use crystal x 16
      _xinfreq      = 5_000_000
       
    OBJ
      tch:           "Touch"                                 ' touchscreen driver
    '  F          : "FloatMath"                 'From Parallax Inc. v1.0
      Q          : "SPIN_TrigPack"             'v2.0 CompElit Ltd.
    
    VAR
    
    
    PUB Main 
      tch.BeginProgram                                        
      Function
      tch.SetWarmBoot                                           ' clears screen, sets a warm boot and reboots
    
    PUB Function | xval,yval,org_x,org_y,pointx,pointy,r,theta,a,swit  chx,switchy
        tch.ClearRam                                        ' clear all but file 0 and 1
        tch.StringDim(10)                                   ' file 2 = strings if needed
        tch.SDBMPtoRam(string("function.bmp"))              ' file 3
        tch.SDBMPtoRam(string("rot1.bmp"))                  ' file 4
        tch.SDBMPtoRam(string("rot2.bmp"))                  ' file 5
        tch.SDBMPtoRam(string("rot3.bmp"))                  ' file 6
        tch.SDBMPtoRam(string("rot4.bmp"))                  ' file 7
        tch.DrawBMPRam(3,0,0)                               ' draw file 3
        switchx := 120                                      ' centre of the switch, not the top left
        switchy := 120                                      ' switch bitmap is 60x60
        tch.DrawBMPRam(4,switchx-30,switchy-30)                             ' draw file 4
        tch.SelectSPIGroup                                    ' talk to the spi touchscreen
        repeat
          yval := tch.TouchYPercent                           ' decode yval 0-100%               
          xval := tch.TouchXPercent                           ' decode xval 0-100%
          if (xval <> 255)  and (yval <> 255)                    ' valid keypress
             xval := (xval*24)/10                             ' 0-240, use portrait mode 
             yval := (yval*32)/10                             ' 0-320
             'tch.hex(xval,2)
             'tch.hex(yval,2)
             org_x := q.Qval(switchx)                        ' origin x of the switch
             org_y := q.Qval(switchy)                        ' origin y
             pointx := q.Qval(xval)                          ' point touched
             pointy := q.Qval(yval)                          ' point touched
             r := q.Qradius(pointx - org_x, pointy - org_y)
             'tch.text(Q.QvalToStr(r))                       ' debugging
             theta := Q.Deg_ATAN2(pointx - org_x, org_y - pointy)     ' pointy and orgy swapped as 0,0 is top left of the screenpolar coordinates with correct sign
             'tch.text(Q.QvalToStr(theta))  
             theta += q.Qval(180)                                ' rotate 180 degrees and remove negative numbers, 0=9 o'clock, 90=6 o'clock, 180 = 3 o'clock, 270 = 12 o'clock
             'tch.hex(r >> 16,2)
             if (r >> 16) < 100 ' touch close to the switch
               case (theta >> 16)
                 0..90: tch.DrawBMPRam(4,switchx-30,switchy-30)                  ' draw switch position 1
                 91..180:tch.DrawBMPRam(7,switchx-30,switchy-30)                 ' draw switch position 4
                 181..270:tch.DrawBMPRam(6,switchx-30,switchy-30)                ' draw switch position 3
                 271..359:tch.DrawBMPRam(5,switchx-30,switchy-30)                ' draw switch position 2
             'tch.text(Q.QvalToStr(theta))                  ' debugging
             tch.pause1ms(250) ' debounce delay  
             tch.SelectSPIGroup
    
    60 x 60 - 1K
  • average joeaverage joe Posts: 795
    edited 2012-06-27 17:12
    re Rotary Knobs: Very nice work! Those will come in very handy!

    re Additive Synth: Sounds interesting. I prefer subtractive synths myself, it just takes some good filtering... and control of filtering. As a thought, OpenStomp may be a good thing to look into for signal processing. http://forums.parallax.com/showthread.php?99060-Propeller-for-Guitar-Effects&p=690777&viewfull=1#post690777

    re further designs, I think the 137 group mechanism could be refined to work on the SD pins for best speed. I'm not sure of the MPC's speed yet but I would imagine the 137 board to be a bit faster? The original board works quite well, with small software patching. Still waiting on new displays and boards.

    Must run..Homework is chasing me!

    *edit*

    Just saw on Rayman's post about a bugfix. http://forums.parallax.com/showthread.php?138121-DVI-or-HDMI-shield-with-true-color-output-4.3-quot-plugin-works-too&p=1106701&viewfull=1#post1106701
    Not sure if this applies to our problem, but sounds similar so might be worth investigating!
  • Ahle2Ahle2 Posts: 1,178
    edited 2012-06-28 06:43
    There's a reason why additive synthesis isn't very popular by "synth freaks" (like myself)!

    Here's a list from the top of my head:
    * Needs a lot of processing power, like in the range of 100x compared to subtractive synthesis, to even give remotely interesting results
    * Extremely hard to program good patches (and people thought FM synthesis was hard)
    * Forget about having any real "timbre control" on the time axis (a filter is much easier/better in that respect)

    Additive synthesis can theoretically sound like anything with enough oscillators, but like I stated it's almost impossible to program!
    Of course you can analyze real instruments frequency components over time and feed them to an additive synth, but then why not use samples instead?
    Forget about using the propeller as a platform for an additive synth! It will result in too few oscillators and it will be hard to program.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-06-28 16:13
    Thanks Ahle2 - that makes a lot of sense.

    If you do subtractive synthesis, is a sawtooth the best wave to start with? I thinking that square and triangle have half the harmonics missing.

    Also I am working on getting your signal generator working and I see the comment about the audio filter. I think the demoboard might have some issues. Actually I have found that a RC network and a blocking cap and no amplifier still provides decent volume into headphones. I'll do some more tests in the next few days.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-06-29 23:50
    @averagejoe, I have spent several weeks thinking very hard about getting the speed faster. There are 6 pins we can use, and I came to the sudden realisation today that the display /RS line does not need to be toggled fast. Indeed, you can set it high or low *before* setting the /cs pin. I tested this code and it works fine
    PRI Lcd_Write_Com(LCDlong)
        LCD_RS_low                               ' can do rs first then cs - better for latch board
        LCD_CS_Low                               ' not needed for the ILI9325 but the SSD1289 needs this
        LCD_Writ_Bus(LCDlong)
        LCD_CS_High                              ' not needed for the ILI9325 but the SSD1289 needs this  
    
    PRI Lcd_Write_Data(LCDlong)
        LCD_RS_High                              ' can do rs first then cs
        LCD_CS_Low                               ' not needed for the ILI9325 but the SSD1289 needs this  
        LCD_Writ_Bus(LCDlong)
        LCD_CS_High                              ' not needed for the ILI9325 but the SSD1289 needs this  
    

    What that does is saves a pin. Now we can use P22 to control something that sets the groups. By far the simplest and fastest way to set a group is with a latch. We have tried a 137 and a 237 and a MCP23008 and I even pondered a HC595 but a simple octal latch is going to be the fastest. A 137 can only select "one of 8" but with a latch you can control individual pins. So the /RS line can be driven by a latch. Ditto selecting one or the other or both screens. Plus the screen reset.

    The next little challenge - how do you use P0-P7 to set the latch and not upset things driven within a particular group? eg the SPI touchscreen group needs to be disabled prior to a group change. I think a solution is to put the latch in HiZ first and have pullups on the outputs. It needs a gate on the input though - if P22 is high then outputs always HiZ. Then the group change starts by putting all groups to HiZ (weak high pullup) and then latch in the data. Then there is a decision between a 373 and a 374. Either would work but the 374 would have needed an inverter but the 373 can be done with one "and" gate and there happens to be several spare anyway.

    Under the 373 I put some comments about how to do a group change. I think it can be done in 6 pasm instructions. Schematic and board layout below.

    Your thoughts would be most appreciated.
  • average joeaverage joe Posts: 795
    edited 2012-06-30 13:52
    Very nice! I'm pretty sure the new design will work. I'm also fairly sure that it will be the fastest design yet. I will be interested to get a dhrystone on the MPC board to compare against the V1 and the 373. I'm fairly sure the new design will be the fastest, but by how much is the question.

    The only thing I see being a disadvantage would be only having only 8 free pins in group 3? One more group would solve this IMO, even possible to decode the 373's group outs with a 138. A 137 could LATCH the group *then you could change the rest of the pins as you see fit or CLEAR the group?* I might try drafting something like this in the next few weeks.

    I'm still pondering how to merge group 0-1. I'm fairly certain that using the SD pins to control a 137 is a step in the right direction. If we could use THAT, maybe we could free enough pins to have a /RD to display.

    Still buried with homework, at least boards have arrived. I'm STILL waiting on displays. Will keep you updated!
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-06-30 21:13
    Good point re another group. Ok, shuffled everything down one from the latch. Now have group 3 and group 4. Group 3 has 12 pins free and Group 4 has 21 pins free.

    I don't know about merging group 1 and 2. I've tried so many options but nothing works. Even the SD card pins are a problem - eg when reading a bitmap you need the SD file open so the pins can't be used, and the 161 counters need to be set every line because the bmp files start at the end.

    But I think this will work.

    I read somewhere that 10k is better than 100k for a pullup (RC settling times when going to and from HiZ) so I have changed all the pullups everywhere to 10k. It will also make things easier buying parts as there are now five 10kx9 networks (and one 1kx9 for the leds).

    Re displays, the board you have with the MCP23008 will work with your displays, yes?
  • average joeaverage joe Posts: 795
    edited 2012-07-02 10:32
    Much better! 33 pins should be more than enough to interface to anything we want!
    I understand what you mean about merging the groups. I think the prop2 will solve this eventually. We should be able to eliminate the 161's and glue logic too! But until then, I think the most recent revision will do quite well.
    The MPC board should work with my displays. I have started building one, but it will be another week before I can complete :(
  • Ahle2Ahle2 Posts: 1,178
    edited 2012-07-02 11:11
    Dr_Acula wrote: »
    Thanks Ahle2 - that makes a lot of sense.

    If you do subtractive synthesis, is a sawtooth the best wave to start with? I thinking that square and triangle have half the harmonics missing.
    You will need all of them to get interesting results. Otherwise it's lika a painter that only has got one color with different saturation levels to choose from.
    The basic waveforms are very easy to generate from a phase accumulator. At most two instructions. Noise will take more than two instructions if you want frequency controll, otherwise two instructions are enough.
  • average joeaverage joe Posts: 795
    edited 2012-07-04 00:10
    Had another setback today. The displays I ordered STILL have not shown up, and it appears the vendor is a scammer. Ebay will be refunding me, but that's not the problem. Now I need to RE-order from a reputable ebayer *and spend the extra $4 a display.* I can't do that until I get my refund so now I'm behind at least 2 months :( I have been debating ordering an SSD1963 but they are a bit expensive and while I can afford one, ordering two is out of my price range. Decisions, decisions..

    *edit*
    I have the MPC board built and tested. Only have one display for now but should keep me working. SdBMPtoRAM is a bit slow, but still usable. Need to do some tests with RAW's, I'm thinking that might be a workaround for now. Now to order more displays.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-23 06:48
    @averagejoe, did the bag of parts arrive?

    The Touchburger boards have arrived - I posted some to you today. This is the one using the 373 latch instead of the MCP23008 and it is a lot faster. Even in spin it is faster than the MCP23008 in pasm, and I haven't ported the 161 load and the latch load into pasm yet.

    The delay posting here was because the code initially would not work at all :( I ended up stripping it right back to the bare minimum to write one character on the display. Even that would not work. Eventually I found the bug - the /RS line on the display is low for settings and high for data. In all the code we have used up to now, every time a prop pin was reset to HiZ the pullup set the /RS line to the correct value. But in order to save one prop pin the RS needed to be driven by the latch, and that means it explicitly needed to be set high or low in a number of places in the code. Seems obvious now in hindsight!

    I'm very happy with this design. It is faster because the latch is parallel rather than serial, and because no I2C driver is needed, it has ended up using less code as well. I haven't tested the analog in but that will add another useful feature for an audio board.

    Code below is the touch object (will need to recompile all the apps, but hopefully none of the other code needs changing except this object when we change hardware).
  • idbruceidbruce Posts: 6,197
    edited 2012-07-23 07:03
    Hey Doc

    Please excuse me for being a little lazy, but I am not upto searching 20+ pages of posts. I see you now have a dual display, and I was wondering were you are upto with that. If you have a couple seconds, I am little curious.

    I hope all is well.

    Bruce
  • average joeaverage joe Posts: 795
    edited 2012-07-23 19:35
    Doc, the parts bag arrived just fine. Sorry I have not had a chance to post, I'm still struggling with school and household obligations. I did have a chance to play around with the audio in and while I had a simple test program running, I have run into a small issue. To keep the sample rate up during display updates and touch-reads, there needs to be some sort of interleaving mechanism. I have not had enough time to test thoroughly but I suspect the MCP board is particularity venerable due to the I2C code speed.

    I am excited to try the new board! Sounds like just what the doctor ordered :)

    Bruce, I can understand your position with the length of this thread. If I can give a brief explanation hopefully it will give some insight.

    The dual display board is a workaround of sorts. The displays we a currently using are resistive touch meaning they are not capable of multi-touch. By using 2 displays, we can touch 2 areas at the same time, provided they are on separate displays. This will allow for playing intervals on the Tinysynth keyboard, as well as key combos. There is also the bonus of doubling the display area.

    Well must run. Thanks again James!
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-24 02:52
    @averagejoe, yes I think any sampling rate issues will be a lot better with the 373 latch.

    @idbruce, yes what we found is that adding a second display was very easy from a hardware perspective. You don't have to if you don't want to, and that is the nice thing about this design, you can use one display, two displays and smaller or larger ones. They all have advantages and disadvantages - eg the smaller ones have better LCD colors at oblique angles.

    The prop board is a eurocard 160x100mm. Stereo output, and also stereo audio input. RS232 port. 1 megabyte of external ram. The displays come with an SD adapter on the back so you get that for free.

    Boards have propeller pins in "groups" where you can select a group with a latch output. So even though the display and touchscreen etc use up all the pins, once you have sent out a picture you can have 20 propeller pins free. This prop pins are brought out to headers so you could be doing "real world" things like running servos and the like. Just need to use a single 74HC32 gate with each servo to select the group (active low so it is an OR gate rather than an AND gate).

    I think we might be getting close to a design that can be sold. averagejoe was thinking of maybe doing this - so once we both have a board soldered up and working we might head down that road.

    The big holdup in the last few months was getting the speed faster, and also getting two different brands of displays working on the same board.

    Addit - note on the picture there is a logic probe in the background. Still needed that till yesterday!
    640 x 480 - 62K
  • idbruceidbruce Posts: 6,197
    edited 2012-07-24 05:03
    Hey Doc

    Thanks for taking the time to give me a brief run down. And yes, it does sound very exciting. I wish you guys the very best with this project, because I know you both have worked long and hard at it.

    Bruce
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-26 00:58
    Thanks idbruce. I'm hoping soon we can do some useful things with it. And it is very close. Just now I was walking round the shed with a board running Ahle's signal generator. This is a portable board that can run off battery power and I know you can buy signal generators but when I was a kid I inherited one from the local university, and this was a huge box 2 foot on each side which had rotating glass circles with the waveform drawn on the glass. It was mechanical 1950s technology and probably cost the university millions in today's money, and now I can do the same thing with a portable propeller board costing tens of dollars. And it looks almost the equal of an iphone, and is a lot cheaper, and it is flexible and reprogrammable in ways an iphone is not.

    Having said all that, I just found a bug on the schematic. The Left audio is not connected and it needs a wire link to fix. So the board is still not 100%. But all prototypes have at least one wire link, right? :)

    Attached are the files. BTW this is all open source. And once averagejoe gets the boards and can replicate this we can say it is a working design. I got 10 boards made and I've got one and aj has three, so I do have some spares if anyone wants to join in the fun. I'm happy to post boards for free to anyone who is keen enough to promise to solder it up. Those boards just need the single wire link. Next batch will fix that bug.

    Attached also are the Eagle files. However, they may not open properly as there are a number of Library files that are modified library items (mainly PCB outlines where I have shrunk the outline so it does not overhang the edge of the board, eg the DC connector, because Sparkfun charge the PCB size by the outermost component, not by the board outline). The full library is about 40mb and I'm happy to send out my library files and if anyone wants to make boards etc you can do so with these Eagle files. I use a "student" version of Eagle which is $125. It probably will make more sense to get boards made by one person and then sell them on, but anyway, this is open source and I'd just be happy to see these being made by others. I think averagejoe might want to do kits too - we shall see.

    I must say that it is pretty cool to have a series of icons on a screen, hit one, and listen to my favorite music in stereo CD quality. Kudos to all the authors of all the objects that this board is using.
  • average joeaverage joe Posts: 795
    edited 2012-07-26 06:38
    I will not bore everyone with the specifics but after talking to several possible investors, I have decided to finance this project myself. With that said, I am taking pre-preorders for Touchburger kits. Final price will depend on choice and number of displays. That said, I plan on offering the FULL kit with 2- 3.2" displays for $99.99. I am still working on pricing for the 2.4" displays. I will also be selling kits without displays, price pending. I will be offering parts at slightly above cost to pay for shipping, etc. I estimate I will be ready to start shipping orders by September. The reason I will be selling kits is not for profit, but to save those interested time and money. Feel free to drop me a PM if interested!

    Doc, re: wire link, Not a problem. These things happen.
    I have plenty of room for hosting files but I'm still fine-tuning the FTP server. Should be finished next week and ready to start hosting all applicable files!
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-28 21:39
    Sounds good.

    I've just gone off on a bit of a tangent thinking about connecting things to this board. I've got an idea using servos, and another RS232 port and a few other things and initially I was thinking about stackable boards, but then I took a look at some RS232 wireless modules and they really are tiny and it may not be so good to have a huge 160x100mm board just to connect to a tiny wireless board.

    So rather than go for a stackable system, I am wondering about just bringing out a standard 26 pin header? It works out at 26 pins because that brings out P0-P20, and the group 3 and group 4 outputs, and then 5V 3V and Gnd.

    Then any addon boards can be large or small. However, to get this to work, something on the board had to go to make room. I figured the diagnostic leds could all go because now we know this works, we can do clever things like display pictures of leds on the screen if we wanted.

    Attached is a schematic and board layout. Let me know what you think about this as I haven't sent this off to be made (and I'm holding off sending off the board with the fix for the audio link also until you get the boards and have yours soldered up.)

    Meanwhile I have been testing out the audio. I was testing it with a bit of heavy metal Rammstein but in order to really test the quality, classical music is a better choice, so I went for some German music from a slightly earlier period; - Bach's Brandenburg Concertos. I must say that it sounds very good. Volume is fine driving headphones directly. No hiss and no audible distortion. Quite amazing to see a little Propeller chip doing this. And for a bit of eye candy, we can display the album cover on the screens.

    The only minor thing with audio is the pop at the beginning. We talked about that earlier didn't we - need a little routine to ramp up the voltage more slowly.

    Anyway, let me know if the 26 way header is ok or whether you prefer the leds.
  • average joeaverage joe Posts: 795
    edited 2012-07-28 23:17
    Hi James, I received the new boards today, should have one up by Tuesday at the latest. I agree that the leds are not necessary once we have the low-level stuff figured out. I have been thinking of expansion modules myself, and pondered connecting them. I guess great minds DO think alike. The 26 pin connector sounds perfect for this.

    The expansion idea I've been testing is Midi/Audio I/O. The module seems to kick some serious butt so far. I've had it running a "midi merge" function to combine 3 midi outs to one midi in and pushed it to the point where the Midi protocol breaks down. I have also been working on midi time code to midi clock conversion and midi clock to midi time code. Very cool things to be able to do for the price of another propeller chip and some cheap logics. 8 midi in, 8 midi out, leaves 12 pins for audio out, Spidif in, or who knows! Modules out there "do" these functions, but they are quite expensive...

    The propeller does have AMAZING sound quality. I've pushed the DACs a bit and WOW. The pop is annoying, in "final release" I'll look at modifying existing objects with the fix a bit later. Gotta run :)

    Oh, and that was a VERY close Olympic Volleyball game! Very exciting to watch. ;)

    *edit*
    A bit more about the midi expander, it uses the i2c bus to communicate with the propeller. I have the slave monitoring for a device id, and use the 3 bit address to determine the cog it's meant for. Seems to work quite well.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-29 00:33
    Sounds great. I thought I would try to get a few more things on the header - now have a 34 pin header, prop pins 0-20, group 3 and 4, 0V 3V 5V and also have added P28-P31 as that is the I2C bus, and P30,30 could be recycled for a serial port (I'd like to add a wireless module). There are a few unconnected pins on the 34 pin header. Futurlec sell a 26 pin one and 34 is the next one up. Price happens to be the same (40c) for 26 and 34 pin.

    The leds don't matter - if they are really important we can always build a board with leds to fit on the expansion header.

    In fact I can think of a whole lot of boards. The prop pins can do anything they would normally do - the only restriction is that you would have to pause things to refresh the screen. For "workhorse" things like your midi merger, you would start off with icons, push the icon to run that program, maybe put a full screen bitmap to describe what the program is doing and then leave the screen as it is and get on with the job. Just have a cog polling the touch part of the touchscreen waiting for an input eg "stop". So not everything would need the screen being refreshed all the time.

    I put the header on the top right as the screen on the left is the one with the SD card and the SD card might get in the way of the cable for the header.
  • average joeaverage joe Posts: 795
    edited 2012-07-29 02:59
    Sweet deal! The expansion header is WAY more valuable than the leds to me.
    re: wireless. YES PLEASE. This has been a HUGE one on my want list.
    re: 34 pin, I'd need to think about what could be added, and where. I would venture to suggest stuffing the propeller /reset line in there. May come in handy at some point. Otherwise, wire links could always be added to access specific pins.

    The one thing I forgot to mention, the propPlug header... IF you "stuff" the reset line on the header, we could do away with this all together. If not, I need this connection to be AT BOARD EDGE, PARALLEL to edge. This is because the propPlug *along with the miniUSB end molding is a bit long, and I use right-angle headers to compensate for this.
    Also, linear regs could easily be removed, I have a couple of the early boards working and the mod is surprisingly simple. I will document it for those who wish to re-produce. The next board is getting those nice buck-regs you sent me :) I'm a bit curious to see what kind of noise they generate on the supply lines, compared to linear regs.

    For the "workhorse" apps, I think I'll stick with the slave prop. It's cheap enough to implement, and the midi-merger app is QUITE demanding. More than just midi routing, midi effects, midi sync conversion, it needs to function as a control surface too! (and at the same time) One of very few places I can see any need for a slave micro.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-29 05:59
    Ok done all that.

    1) Got rid of the linear regs and saved some space (you can always put them on an expansion board)
    2) Prop plug on an angle (can you check it is round the right way)
    3) Added /reset to the 34 pin header.

    Wireless - there are many modules similar to these http://www.futurlec.com/Radio.shtml you just feed serial data in and it comes out the other end. There are some ones from Sure Electronics where you can program multiple channels too so they don't all interfere.

    I'm tempted to put the two analog input lines on the 34 pin header as well. Then they could go to another board with RCA sockets (which are too big to fit on this board). Thoughts?
    936 x 598 - 112K
  • average joeaverage joe Posts: 795
    edited 2012-07-29 06:25
    Well I took a look at the board and pulled my propPlug out to check. The way the header is placed now will put the LEDs up and label down. Either way WORKS but I think the current placement is best. I'll take a look at the different wireless modules, but it will be a while before I'm ready to head down that road. Currently I'm writing up instructions for soldering these up (TouchBurger1) and will have my brother-in-law *who's never soldered before* run through the instructions to check for clarity.

    *edit*
    I've been getting ready to build a board and just realized I needed to bring something to your attention. The bag of parts you sent me contained a MAX3232 chip that happened to be an SOIC. I will be making an adapter so I can use this but it will take some extra time. Just thought I'd let you know for future reference.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-07-29 06:33
    If you are writing up instructions on how to solder, I tend to put in all the sockets first, then put something flat on top and flip it all over. The solder all the sockets in one go. Then do the bypass caps the same way. Then the resistors. And then it probably doesn't matter which order you do things, but as a general rule, short components before tall ones.

    I then power up the board and check the volts before putting in any chips.

    Re your suggestion on the keyboard thread of creating another temporary I2C bus, I think that is brilliant. And that could be over on another board we can connect to with the 34 way header. In fact, one could think about a board with a few other things - eg TV and VGA (which will work so long as the touchscreen is not being refreshed).

    Leds up is probably better so you can see the data going through.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-08-01 23:04
    Hi averagejoe, how is the latest board going? Let me know if you want some more code to test things.

    I've sent off the boards with the 34 way header. Now it might be worth thinking about an expansion board and what to put on it. There is no reason we can't put a VGA display, TV, keyboard, mouse etc etc. Ok, you can't do VGA at the same time as a touchscreen, but you could briefly blank the VGA, update the touchscreen and then restart the VGA driver.

    I jotted down some ideas - see the attached PDF. For a demo board you could have a larger board and add lots of things and just populate what you need.

    Any other things we could think about adding?
  • average joeaverage joe Posts: 795
    edited 2012-08-02 09:31
    Hi James, I still have not had a chance to solder the latest board up. I will try to get it done today.
    Re: expansions, I think you have it fairly covered. I'll keep thinking about it though.
    Must run for now!
    Joe

    *edit*
    Board is built, preliminary testing without chips (linear regs) reports 4.75v, 3.15v on a 12v 900ma. *I need a better supply, hopefully the rack-mount will have enough kick ;)*
    I'll finish dead short testing, and load chips!

    *aedit*
    Chips loaded, no display and voltage is 4.95v and 3.31v?
    Getting ready for full systems test!


    *more edit*
    I have the desktop running, have not re-compiled the rest of the programs. Did realize I forgot the wire link for audio out... I'll take care of that tomorrow, now to figure out how to mount the breadboard in rack-mount! Need to get my guitar playable...
  • average joeaverage joe Posts: 795
    edited 2012-08-05 00:42
    Well the board is running good and I'm surprised at the speed. I've run through a few simple programs to familiarize myself with the commands. It was necessary to make a few edits to the commands. Most changes were needed for default orientation in landscape. I will try to post the revised Touch.spin later. There is also the issue of translating from xPercent back to pixels... Overall a great start.

    With the board mounted in the rack and the guitar "analog board" nearing testing, I've been trying to understand interfacing. I currently have Pin6 -SPI-Data, Pin7-SPI-Clock, Pin8-`595 SPI-En, Pin9-Dpot-En. All 4 pins are OR'd with group3. Group3 is also inverted (by using 1-4066) to enable 2 other 4066 gates on Pins 10-11. These gates are connected to an On-On-On switch connected to Gnd. The theory of operation is such...

    6 sliders, 8 check-boxes. Each of the 6 sliders controls one channel of the 5206 digital pot. Each check-box is one gate of the '595. I have the basic GUI components outlined, but need to "bind" their values to the outside world. I'm adding 2 functions to the Touch.spin to accomplish this, SetPot and SetSwitch. I'm still a bit unsure of how to make this work..
    PUB SetSwitch(data)
      LatchGroup3
      'set pins 8-9 high
      'set pins 8-9 out, 6-7,10-11 inputs
      'set pin 8 low
      SPI.Stop
      SPI.Start(3,0)
      SPI.SHIFTOUT(6,7, 5, 8 , data)
      'set pin 8 high
      SPI.Stop
    
    Something like this.. I'm worried about enabling group3 with pins 10-11 as outputs. Maybe a 1k resistors will protect from propPins outputting high and switch shorting to GND. I'm also wondering what the "default" Outs and Dirs will be coming out of LatchGroup3. Any advice would be appreciated!

    I'll keep thinking on this, need to check the "analog board" seems I'm missing a cap and some transistors!


    *edit*
    After some thought, here's what I have:
    PUB SetSwitch(data)
      outa[9..8]   := 3
      dira[11..10] := 0
      dira[7..6]   := 0
      dira[9..8]   := 3
      LatchGroup3
      SPI.Start(3,0)
      SPI.SHIFTOUT(6,7, 5, 8 , data)
      outa[8]      := 0
      outa[8]      := 1
      dira[9..8]   := 0
      
    PUB SetPot(potNum,data) | dout
      outa[9..8]   := 3
      dira[11..10] := 0
      dira[7..6]   := 0
      dira[9..8]   := 3
      LatchGroup3
      SPI.Start(3,0)
      outa[9]      := 0
      dout := (potNum << 8) + data
      SPI.SHIFTOUT(6,7, 5, 16 , dout)
      outa[9]      := 1
      dira[9..8]   := 3
      
    PUB GetGswitch
      'outa[9..8]  := 3
      dira[11..10] := 0
      'dira[7..6]  := 0
      LatchGroup3
      Result := INA[11..10]
    
    Still need to test.


    *aedit*
    So, not that simple... I've got some issues so going back to basics...Here's the main program so far:
    DAT
     sysfont  byte "times20.ifn"
     logo     byte "logo.bmp"
    
    
    CON
      _clkmode      = xtal1 + pll16x                        ' use crystal x 16
      _xinfreq      = 5_000_000
    OBJ
      tch:           "Touch"                                 ' touchscreen driver
    
    
    VAR
     byte Slide1,Slide2,Slide3,Slide4,Slide5,Slide6,ButtonStates
                      
                                    
      
    PUB Main | wcboot,xval,yval,n  ' warm or cold boot                   ' 
      wcboot := tch.BeginDesktop("S")                            ' "I" = ILI9325, "S"= SSD1289
      'if wcboot == false                                    ' erase ram chip, checks if a cold or warm boot, sets some variables
          'tch.Clearscreen(tch.RGBtoWord(0,0,0))            ' clear screen to black - uses the display driver above
          tch.SDBMPtoRam(@logo)                  ' file number 1, a 240x320 file called logo.bmp     
          tch.SDBMPtoRam(string("mask.bmp"))                  ' file 2, load this here - if load after the strings get a white line on the icons  
    
          tch.LoadFont(@sysfont)                              'file 3
        
          tch.ChangeOrientation(false)
          tch.DrawBMPRam(1,0,0)                                  ' file number 1, location 0,0
    
         tch.SetCursor(0,5)
         tch.TextT(3,string("!!!New & Improved!!!")) 
         tch.SetCursor(0,220) 
         tch.TextT(3,string("Created by James Moxham & Joe Heinz"))
            
         n:=0
        tch.SelectSPIGroup                                    ' talk to the spi touchscreen
       
         repeat while n == 0 
           yval := tch.TouchYPercent                           ' decode yval 0-100%               
           xval := tch.TouchXPercent                           ' decode xval 0-100%
           if (xval <> 255)  and (yval <> 255)                    ' valid keypress
            n := 1
    
        tch.Clearscreen($FFFF_FFFF)
        
        Buttons
        
        
    PUB Buttons   |   f,sredraw,bredraw, ck1x,ck2x,ck3x,ck4x,ck5x,ck6x,ck7x,ck8x, ck1y,ck2y,ck3y,ck4y,ck5y,ck6y,ck7y,ck8y, ck1s,ck2s,ck3s,ck4s,ck5s,ck6s,ck7s,ck8s, xval,yval
    
       tch.ClearRam                                         ' file 0 and 1 reserve
       tch.LoadFont(@sysfont)                               'file 2   
     f := tch.Loadfont(@sysfont)                            ' file 3 black on white font
    
       tch.SDBMPtoRam(string("butn8430.bmp"))               ' file 4 a button 84x30 in size
       tch.SDBMPtoRam(string("Uncheckd.bmp"))               ' file 5 unchecked checkbox pic3
       tch.SDBMPtoRam(string("Checked.bmp"))                ' file 6 checked checkbox pic4
       tch.SDBMPtoRam(string("synknb.bmp"))                 ' file 7
       tch.SDBMPtoRam(string("synslbk.bmp"))                ' file 8
    
       sredraw := 7
       bredraw := 9      
       ' set all the locations of the objects on the screen                                            
    
       ck1y := ck2y := ck3y := ck4y :=  140
       ck5y := ck6y := ck7y := ck8y := ck1y +  100                                  ' y coordinates all the same    
    
       ck5x :=  ck1x := 25                                           ' x 
    
       ck2x := ck1x + 54 
       ck3x := ck2x + 54
       ck4x := ck3x + 54
       
                                   
       ck6x := ck5x + 54
       ck7x := ck6x + 54 
       ck8x := ck7x + 54
       
       ck1s := true                                         ' startup status
       ck2s := true
       ck3s := true
       ck4s := true
       ck5s := true
       ck6s := true
       ck7s := true
       ck8s := true
       
       ' now wait for touch
       tch.SelectSPIGroup                                   ' talk to the spi touchscreen
       repeat
          if sredraw <> 0
            RefreshSliders(sredraw)
            sredraw := 0
            tch.SelectSPIGroup                                   ' talk to the spi touchscreen
            
          if bredraw == 9                                        ' if redraw true then redraw all the objects
             tch.SelectMemGroup                                         ' display mode
             DrawCheckbox(ck1x,ck1y,ck1s,string("Check1"),5,6,f)        ' checkbox
             DrawCheckbox(ck2x,ck2y,ck2s,string("Check2"),5,6,f)        ' checkbox                    
             DrawCheckbox(ck3x,ck3y,ck3s,string("Check3"),5,6,f)        ' checkbox
             DrawCheckbox(ck4x,ck4y,ck4s,string("Check4"),5,6,f)        ' checkbox                    
             DrawCheckbox(ck5x,ck5y,ck5s,string("Check5"),5,6,f)        ' checkbox
             DrawCheckbox(ck6x,ck6y,ck6s,string("Check6"),5,6,f)        ' checkbox                    
             DrawCheckbox(ck7x,ck7y,ck7s,string("Check7"),5,6,f)        ' checkbox
             DrawCheckbox(ck8x,ck8y,ck8s,string("Check8"),5,6,f)        ' checkbox
            ' tch.SelectSPIGroup                                                  ' talk to the spi touchscreen
    
             ButtonStates := (ck8s << 7)+(ck7s << 6)+(ck6s << 5)+(ck5s << 4)+(ck4s << 3)+(ck3s << 2)+(ck2s << 1)+(ck1s)
             tch.SetSwitch(ButtonStates)
             
             bredraw := 0
             tch.SelectSPIGroup                                          ' talk to the spi touchscreen
             tch.pause1ms(250)                                           ' debounce
                                                            
          elseif bredraw <> 0
            tch.SelectMemGroup                                           ' display mode
            case bredraw
              1:DrawCheckbox(ck1x,ck1y,ck1s,string("Check1"),5,6,f)      ' checkbox
              2:DrawCheckbox(ck2x,ck2y,ck2s,string("Check2"),5,6,f)      ' checkbox         
              3:DrawCheckbox(ck3x,ck3y,ck3s,string("Check3"),5,6,f)      ' checkbox         
              4:DrawCheckbox(ck4x,ck4y,ck4s,string("Check4"),5,6,f)      ' checkbox         
              5:DrawCheckbox(ck5x,ck5y,ck5s,string("Check5"),5,6,f)      ' checkbox         
              6:DrawCheckbox(ck6x,ck6y,ck6s,string("Check6"),5,6,f)      ' checkbox         
              7:DrawCheckbox(ck7x,ck7y,ck7s,string("Check7"),5,6,f)      ' checkbox         
              8:DrawCheckbox(ck8x,ck8y,ck8s,string("Check8"),5,6,f)      ' checkbox
              
            ButtonStates := (ck8s << 7)+(ck7s << 6)+(ck6s << 5)+(ck5s << 4)+(ck4s << 3)+(ck3s << 2)+(ck2s << 1)+(ck1s)
            tch.SetSwitch(ButtonStates)
    
            bredraw := 0
            tch.SelectSPIGroup                                           ' talk to the spi touchscreen
            tch.pause1ms(250)                                            ' debounce
     
             
             
          yval := tch.TouchYPercent                         ' decode yval 0-100%                
          xval := 100 - tch.TouchXPercent                         ' decode xval 0-100%
          if (xval <> 255)  and (yval <> 255)               ' valid keypress
            xval := (xval * 24) / 10                        ' scale to pi8xels as can measure from the picture in paintshop
            yval := (yval * 32) / 10                        ' scale to pixels
           if yval < 100                                                           ' one of the 5 sliders                                                                                
             case xval
                 2..2+34:    Slide1 := ReadSlider(yval,1)                             ' move the slider and scale value
                   sredraw := 1
                 42..42+34:  Slide2 := ReadSlider(yval,2)
                   sredraw := 2      
                 82..82+34:  Slide3 := ReadSlider(yval,3)
                   sredraw := 3
                 122..122+34:Slide4 := ReadSlider(yval,4)
                   sredraw := 4
                 162..162+34:Slide5 := ReadSlider(yval,5)
                   sredraw := 5
                 202..202+34:Slide6 := ReadSlider(yval,6)           
                   sredraw := 6
                   
           ELSEif yval < 200
    
             case xval
                (ck1x-10)..(ck1x+25): !ck1s                   ' checkbox is small so active area bigger than the checkbox
                                      bredraw := 1            ' redraw the screen
                (ck2x-10)..(ck2x+25): !ck2s                   ' checkbox is small so active area bigger than the checkbox
                                      bredraw := 2   
                (ck3x-10)..(ck3x+25): !ck3s                   ' checkbox is small so active area bigger than the checkbox
                                      bredraw := 3            ' redraw the screen
                (ck4x-10)..(ck4x+25): !ck4s                   ' checkbox is small so active area bigger than the checkbox
                                      bredraw := 4            ' redraw the screen
           ELSEif yval < 300  
             CASE xval
                (ck5x-10)..(ck5x+25): !ck5s                   ' checkbox is small so active area bigger than the checkbox
                                      bredraw := 5            ' redraw the screen
                (ck6x-10)..(ck6x+25): !ck6s                   ' checkbox is small so active area bigger than the checkbox
                                      bredraw := 6            ' redraw the screen
                (ck7x-10)..(ck7x+25): !ck7s                   ' checkbox is small so active area bigger than the checkbox
                                      bredraw := 7            ' redraw the screen
                (ck8x-10)..(ck8x+25): !ck8s                   ' checkbox is small so active area bigger than the checkbox
                                      bredraw := 8            ' redraw the screen
                 
                                                     
    
    PUB DrawCheckbox(y,x,Checked,stringptr,c1,c2,f) | i                ' draw a checkbox x,y,checked, string, file for checked, file for unchecked, font file
       if checked
         tch.DrawBMPRam(c1,x,y) 
       else
         tch.DrawBMPRam(c2,x,y)  
       tch.setcurx(x+20)                                         ' add 20 width
       tch.setcury(y)
       tch.TextT(f,stringptr)
    
    
    PUB SynthSlider(x,y,value)                              ' value is 0-255. assumes bitmaps in ram
        tch.DrawBMPRam(8,x,y)                               ' draw background
        tch.DrawBMPRam(7,x+((value*100)/450),y+5)           ' draw the knob
    
    PUB RefreshSliders(s) | n
        If s == 7
          repeat n from 1 to 6
            RedrawOneSlider(n)
        ELSE
          RedrawOneSlider(s)
    PUB ReadSlider(y,n)
       ' y := y - 132                                            ' origin of the slider is 132
        y := y*256                                              ' slider is 69 pixels so convert to 256   
        y := y / 69
        if y < 0                                                ' check bounds
          y := 0
        if y > 255
          y := 255
        tch.SelectMemGroup
        RedrawOneSlider(n)                                  ' redraw this slider
        tch.SelectSPIGroup 
        result := y                    
    
    PUB RedrawOneSlider(n)                                  ' n = 1,2,3,4,5,6
       case n
         1:SynthSlider(0,2,Slide1)                           ' decay     
         2:SynthSlider(0,42,Slide2)                         ' sustain
         3:SynthSlider(0,82,Slide3)                           ' pwminit
         4:SynthSlider(0,122,Slide4)                         ' pwmrate
         5:SynthSlider(0,162,Slide5)                          ' filter (0-12 so multiply by 21)
         6:SynthSlider(0,202,Slide6)                       ' portamento 0 - 16
    
    Main does a basic splash screen, then waits for the screen to be touched. Then clearscreen and runs buttons. This sets up 6 sliders, 8 checkboxes, handles re-draws... I'm trying to get the checkboxes to change ButtonStates, then update the 74hc595 to match.
    Here's where I'm at with the TOUCH.SPIN. It includes revisions to make Landscape mode TEXT display properly, along with ?? *something based on screenwidth**?? Not fully tested.
    PUB SetSwitch(data)
      outa[9..8]   := 3
      dira[11..10] := 0
      dira[7..6]   := 0
      dira[9..8]   := 3
      LatchGroup3
      SPI.Start(5,0)
      SPI.SHIFTOUT(6,7, 5, 8 , data)
      pause1ms(500)
      outa[8]      := 0
      pause1ms(500) 
      dira[9..8]   := 0
      
    PUB SetPot(potNum,data) | dout
      outa[9..8]   := 3
      dira[11..10] := 0
      dira[7..6]   := 0
      dira[9..8]   := 3
      LatchGroup3
      SPI.Start(3,0)
      outa[9]      := 0
      dout := (potNum << 8) + data
      SPI.SHIFTOUT(6,7, 5, 16 , dout)
      outa[9]      := 1
      dira[9..8]   := 3
      
    PUB GetGswitch
      'outa[9..8]  := 3
      dira[11..10] := 0
      'dira[7..6]  := 0
      LatchGroup3
      Result := INA[11..10]
    
    I'm doing something wrong, still not sure what?

    I made some code changes I need to remove because I'm a dummy and using tch.ChangeOrientation(false), not SetOrientation(e) 'just realized!!!
    AND, this one fixes landscape SSD1289
    PUB ChangeOrientation(n) ' pass true = portrait or false = landscape, changes global variable orientation in this object
    ' command $0001
    '8.2.4. Driver Output Control (R01h)
    'R/W RS D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
    'W 1 0 0 0 0 0 SM 0 SS 0 0 0 0 0 0 0 0
    'SS: Select the shift direction of outputs from the source driver.
    'When SS = 0, the shift direction of outputs is from S1 to S720
    'When SS = 1, the shift direction of outputs is from S720 to S1.
    'In addition to the shift direction, the settings for both SS and BGR bits are required to change the
    'assignment of R, G, B dots to the source driver pins.
    'To assign R, G, B dots to the source driver pins from S1 to S720, set SS = 0.
    'To assign R, G, B dots to the source driver pins from S720 to S1, set SS = 1.
    
    ' command $0003
     'R/W RS D15 D14 D13 D12 D11 D10 D9  D8 D7  D6   D5   D4   D3 D2 D1 D0
       'W   1  TRI DFM 0   BGR 0   0   HWM 0  ORG 0    I/D1 I/D0 AM 0  0  0
       ' When AM = 0, the address is updated in horizontal writing direction.
       'When AM = 1, the address is updated in vertical writing direction.
       'I/D[1:0] Control the address counter (AC) to automatically increase or decrease by 1 when update one pixel
       ' display data.
        SelectMemGroup                                      
        orientation := n
        if displaymode == "I"                                         ' ili9325
          if orientation
            ' for origin top left and portrait mode
            Displaycmd($0001,%00000001_00000000)                           ' $0001,$0100 set SS and SM bit 0001 0100   portrait
            Displaycmd($0003,%00010000_00110000)                           ' $0003,$1030 set GRAM write direction and BGR=1. $0003 $1030  
          else
            ' for origin top right and landscape mode 
            Displaycmd($0001,%00000000_00000000)                           ' set SS and SM bit 0001 0000   landscape   
            Displaycmd($0003,%00010000_00111000)              ' landscape  $1028 = original but 1038 is correct - not mirror image
    
    
        if displaymode == "S"              ' SSD1289
          if orientation
                ' for origin top left and portrait mode
                Displaycmd($0001,$2B3F)                           ' $0001,$0100 set SS and SM bit 0001 0100   portrait
                Displaycmd($0011,$6070) '6070                          ' $0003,$1030 set GRAM write direction and BGR=1. $0003 $1030  
          else
                ' for origin top right and landscape mode 
                Displaycmd($0001,$6B3F)  '$4B3F                         ' set SS and SM bit 0001 0000   landscape   
                Displaycmd($0011,$6838 )  '6838                   ' landscape  $1028 = original but 1038 is correct - not mirror image
    
    I'll keep pluggin, see what I can figure out.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-08-05 02:58
    Ah, perfect timing.

    Take a look at this draft schematic. The 74HC4316 chip will do what you want I think and I use it 4 times on this board.

    Better than a 4016 or 4066 as you can turn all the switches on and off at once with the group pins (which end up the correct polarity as well). If the group pins had been active high then the 4016 would have been the chip to use.

    Essentially, anything connecting via group 3 or 4 needs to be isolated if that group is not selected.

    Obviously we are going to need to liase with the pins we use here!

    I've used up all but one of group 4 on this board, and there are 5 free on group 3. Lots of flexibility about the way we do things though - eg the I2C bus can be used, we can share things on an SPI "bus" and also MIDI and the two RS232 ports could be combined. So we still have lots of pins free.
Sign In or Register to comment.