Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 16 of 16

Thread: Re-doing my Hammond MIDI controller: ideas and suggestion needed

  1. #1
    Member garubi's Avatar
    Join Date
    Sep 2016
    Location
    Modena, Italy, EU
    Posts
    49

    Re-doing my Hammond MIDI controller: ideas and suggestion needed

    Hallo,
    sorry for the long post, but I'd love to have your suggestion on my next project.

    A premise
    Last year I finished my MIDI drawbars Controller based on Teensy LC and since then I used it on a numbers of gigs without any problem
    Click image for larger version. 

Name:	3105491541770680221.jpg 
Views:	20 
Size:	112.3 KB 
ID:	22434Click image for larger version. 

Name:	801101541770665395.jpg 
Views:	25 
Size:	65.5 KB 
ID:	22435
    (for the whole project see here).
    I also built a bunch of smaller midi controller in foot controller / pedalboard form factor for my musican friends.

    Motivated from that "success" I'm now planning to convert/port to Teensy another DIY controller that I have built some years ago: a dual manual Hammond "clone".
    Click image for larger version. 

Name:	wpid-20150510_224227.jpg 
Views:	31 
Size:	204.3 KB 
ID:	22430
    (detailed project log here)
    At the time I based it on a Livid Instruments "Brain" but it requires a PC to run and moreover it hasn't ever been very reliable.

    The plan is to replace the "brain" wth a Teensy and use the whole "clone" as a MIDI controller for an external sound module hooked up via MIDI (namely the Crumar "Gemini" module) keeping much of the already wired and soldered electronics, a part from the Drawbars set that I'll describe later.

    Let me describe the current controller implementation:

    The control panel
    The controller has a panel with 7 analog potentiometers, that I'll attach to 7 analog inputs.
    There are 28 momentary buttons and 28 leds already wired as a matrix with diodes and resistors (2 4x8 matrix, see below).
    existing-panel-schematic.pdf

    The drawbars set
    Then there is a set of 9 + 2 + 9 Drawbars, coming from an original Hammond organ. They aren't the "contemporary" ones that are just linear potentiometers disguised. No, they are made of busses of rigid wires where the sliding Drawbars make contacts (the usual Drawbars thing, I attach some pictures from the bottom of one of them).
    Click image for larger version. 

Name:	drawbars_howto.jpg.png 
Views:	20 
Size:	773.0 KB 
ID:	22433

    The drawbars deserve a few more words
    In the current implementation of my controller I soldered an array of resistors across the busses, making the sliders actually behave like potentiometers. Then just attached them to 20 analog inputs.
    This is how the vast majority of DIY projects that readjust "original" organ Drawbars do.
    But in my experience this solution isn't very reliable: often there are spurious value, little jumps, etc, I think because the long wire busses are shared between all of the "sliders" so any movement of one slider from one contact to another causes voltage fluctation, noises etc that propagate to all of them.
    (yes, capacitors are in place, and the things with them are a little better, but anyway not as thight as I would)

    Having said that, my **new** plan is to revert back the Drawbars set to the original state (by removing all the resistors array) then transform it in a "button matrix" (sorta of). It will be a matrix of 9x20...
    It should make sense: the busses are like rows and the sliders can be the columns: when I push/pull a slider and it closes the contact with one of the bus it's the same if I were pushing a button. Isn't it?
    drawbar-matrix-idea.pdf
    There used to be a repository on GitHub from someone who done something similar but now isn't accessible anymore.
    I think that this implementation would be a lot more reliable and precise than the previous one based on the resistors array.

    The two keyboards
    The controller has two identical 61 keys keyboards. They are 2 old MAUDIO keyboard with the case removed. They have MIDI out both via usb and via MIDI DIN port so I plan to connect them to the Teensy making two MIDI in ports for them (or maybe using USB host on Teensy?).

    The outputs
    The controller has to send the Midi stream both via MIDI DIN out and MIDI on usb. But this is the "easy part" ;-)

    My questions
    At the very end it will be just a very big MIDI controller.
    I'm not worried about the performaces: MIDI is a relatively slow protocol and all the buttons and the drawbars changes their state not so often.
    But it will be anyway 3 big matrices to poll and it's required that any change in the buttons state will be detected and transmitted in something around 5/7ms for a good user experience (unnoticeable latency).

    I see a bunch of options for implement all of that:
    1) Using only one Teensy with a huge number of digital input (which one?).
    2) a single smaller Teensy and some multiplexer to handle the matrices
    3) use a second board (Teensy LC or Arduino) to poll for the Drawbars Matrix, and connect it via serial/MIDI to a "main" Teensy that handle all the rest

    What do you suggest? what are your ideas about the whole thing? Are there other issue that you see and that I overlooked?

    Thanks for your time and your help

    Stefano
    Last edited by garubi; 11-13-2020 at 06:01 PM.

  2. #2
    Member
    Join Date
    Nov 2012
    Location
    Portland
    Posts
    61
    3.5, 3.6, and 4.1 all have enough pins to directly read out 8 rows / 20 columns AND 2X Serial ins to do MIDI merging from the two keyboards if you desire. 3.6 and 4.1 can USB host.

    A decade counter or 3 ->8 decoder could strobe through the buss bars and leave enough pins to just pull off column reads with a smaller Teensy. Iíve got a set of drawbars around somewhere and was reticent to do the resistor hack, so Iím interested to see where you land.

    Also since itís MIDI you could put the keyboards on different channels and chain one into the other to save pins or avoid USB hub.

  3. #3
    Member garubi's Avatar
    Join Date
    Sep 2016
    Location
    Modena, Italy, EU
    Posts
    49
    Thanks for your feedback!

    Quote Originally Posted by drjohn View Post
    A decade counter or 3 ->8 decoder could strobe through the buss bars and leave enough pins to just pull off column reads with a smaller Teensy..
    I have problems understending the above sentece, it could be my bad English or my bad electronic knowledge
    Could you elaboarate on it?

    Quote Originally Posted by drjohn View Post
    Also since it’s MIDI you could put the keyboards on different channels and chain one into the other to save pins or avoid USB hub.
    Unfortunately the keyboards only have MDI OUT, not IN nor any merge function...

    Thank you again!
    Stefano

  4. #4
    Member
    Join Date
    Nov 2012
    Location
    Portland
    Posts
    61
    OK, I missed the switches and LEDs PDF in your first post, so this is just a drawbar reading solution. If you use a large Teensy, you can omit an external chip and just cycle through pulling one of the 8 or 9 buss bars high and read the 20 drawbars with input pins. Next buss high, read 20, repeat. Since I broached them, two other possibilities:

    Decade counter approach: http://www.learningaboutelectronics....-with-4017.php
    Instead of LEDS in that reference circuit, you would be pulling one buss bar high and reading state of all 20 of the drawbar pins to see which switches along that buss were down. Similar to the above.
    Then pulse the clock pin and first buss goes low, the second buss bar goes high. Read 20 pins, pulse clock of 4017, repeat, eventually cycles back to 0 buss. You probably need a hard reference to which buss is active by reading back one of the lines*, so...two pins are needed to run the 4017 + 20 to read drawbars.

    3 of 8 decoder approach**: http://www.learningaboutelectronics....er-circuit.php
    In this approach, you would specify the buss bar (1-8) in binary on three lines and the chip decodes it to one of eight output pins. Again, you would be pulling a single buss bar high and reading state of all 20 of the drawbar pins to see which switches were down. So three address pins + 20 to read drawbars.

    Teensy 3.2 has 25 I/O pins on the periphery, including A14 on the end. A10 and A11 are also available without resorting to funky pads on the bottom. So you have around what you need for either "external chip" approach including two pins for serial MIDI in, one for MIDI out, plus maybe a button or two. The code size and speed needs are simple enough you could squeeze it into a Teensy LC, but you will need another processor to read those buttons and display the LEDs.



    John

    *State of counter outs at power-up is not always as expected, so cycling to a known starting position is good practice.

    **You said it was a 20 x 9 matrix but the PDF only shows 8 rows. The 3 of 8 decoder approach won't work if there's 9 busses.

  5. #5
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    226
    You can use 1x 74hc147/cd40147b (10to4 line priority encoder) for the rows, and 3x cd4051 (1of8 analog MUX for the columns)
    Also you need 9 pull up resistors on each row-"output"
    With this only 10pins is required from the MCU/teensy.

  6. #6
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    226
    schematic:
    Click image for larger version. 

Name:	dragbar matrix.png 
Views:	23 
Size:	26.9 KB 
ID:	22453

    truth-table for col-select:
    Click image for larger version. 

Name:	dragbars_colSelTruthtable.png 
Views:	20 
Size:	8.9 KB 
ID:	22454

    truth-table for row "output" (taken from 74hc147 datasheet)
    Click image for larger version. 

Name:	dragbars_rowOutputTruthtable.png 
Views:	14 
Size:	18.7 KB 
ID:	22455

  7. #7
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    226
    there is the alternative to use drjohns approach with 1x 4017 (it have a reset input that when activated put the output to a known state)
    combined with 3x 74hc165 (latch input, 8bit in, serial out) shiftregisters.
    This is only requiring 5 IO from the teensy

    Click image for larger version. 

Name:	dragbar_minimal_IO.png 
Views:	19 
Size:	14.8 KB 
ID:	22457

    edit.
    I forgot to tie all INH (pin15) to GND in the schematic
    also the SER input of IC5 should be tied to GND to make the logic ic stable.
    also I reversed the serial data output so the first ROW input is the first bit out.
    Last edited by manicksan; 11-15-2020 at 01:48 PM. Reason: fixed the schematic

  8. #8
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    226
    update

    * the E-H inputs of the last shift-reg should be tied to gnd

    * for extra stability there should also be (pulldowns + capacitors(optional)) on each of the 20 inputs
    (they are not connected in the schematic, I don't have the energy to make all those connections)

    * shiftregister input pins are in reverse order H = LSB, A = MSH (who did this stupid mistake)

    new updated fixed schematic:
    Attachment 22459

    some code:
    Code:
    char bars[20];
    
    // IO defines (pin-numbers is just an example)
    #define IN_RESET 0
    #define IN_CLK 1
    #define OUT_CLK 2
    #define OUT_LOAD_SHIFT 3
    #define SERIAL_DATA_OUT 4
    
    void setup()
    {
        pinMode(IN_RESET, OUTPUT);
        pinMode(IN_CLK, OUTPUT);
        pinMode(OUT_CLK, OUTPUT);
        pinMode(OUT_LOAD_SHIFT, OUTPUT);
        pinMode(SERIAL_DATA_OUT, INPUT);
    
        // inital states
        digitalWrite(IN_RESET, LOW);
        digitalWrite(IN_CLK, LOW);
        digitalWrite(OUT_CLK, LOW);
        digitalWrite(OUT_LOAD_SHIFT, HIGH); // normal state
    
    }
    
    void loop()
    {
        doBarsRead();
        if (bars[0] == 1) // first drawbar equals one
        {
            // do something
        }
        else if (bars[0] == 2) // first drawbar equals two
        {
            // do something
        }
        // ...
    
        if (bars[19] == 1) // last drawbar equals one
        {
            // do something
        }
        else if (bars[19] == 2) // last drawbar equals two
        {
            // do something
        }
    }
    void doBarsRead()
    {
        digitalWrite(IN_RESET, HIGH);
        // minimum 260nS delay
        digitalWrite(IN_RESET, LOW);
        
        for (int ri = 1; ri <= 10; ri++)
        {
            // LATCH data
            digitalWrite(OUT_LOAD_SHIFT, LOW); 
            // minimum 100nS delay
            digitalWrite(OUT_LOAD_SHIFT, HIGH);
            
            for (int ci = 0; ci < 20; ci++)
            {
                if (digitalRead(SERIAL_DATA_OUT) == HIGH)
                    bars[ci] = ri;
                    
                // next col clock input
                digitalWrite(OUT_CLK, HIGH);
                // minimum 100nS delay
                digitalWrite(OUT_CLK, LOW);
            }
            
            // select next row
            digitalWrite(IN_CLK, HIGH);
            // minimum 100nS delay
            digitalWrite(IN_CLK, LOW);
        }
        // now each bars[i] have the selected value
    }
    Last edited by manicksan; 11-15-2020 at 02:48 PM. Reason: changed ri index to match the numbers on drawbars + usage example

  9. #9
    Member garubi's Avatar
    Join Date
    Sep 2016
    Location
    Modena, Italy, EU
    Posts
    49
    Jannik and John,
    thank you so much for your suggestions and for all the hard work you have put in it.
    Now I have something to study for the next days ...

    I can dedicate only few horus a week to this hobby, I'll be back to you as soon as I have something tested

    Stefano


    p.s. :
    Quote Originally Posted by manicksan View Post
    new updated fixed schematic:
    Attachment 22459
    Unfortunately It says it can't find the attachment, but I think I'll can go without it...
    Last edited by garubi; 11-16-2020 at 11:37 AM.

  10. #10
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    226
    here is the image
    Click image for larger version. 

Name:	dragbar_minimal_IO.png 
Views:	22 
Size:	17.0 KB 
ID:	22482

  11. #11
    Member garubi's Avatar
    Join Date
    Sep 2016
    Location
    Modena, Italy, EU
    Posts
    49
    I found some time today to "study" your suggestions (You know how it happens: click one link, read that article, then follow that other link, read there, but wait what's that? search Google...e tc etc... and now it's evening...)
    I like the solution of the last schematic, it's neat and logic.

    Now I'm wondering if I could use the unused inputs of IC5 and another daisy-chained 74HC165 to read the button matrix of the control panel, maybe driv9ing the rows of the button matrix with onoter chip, maybe a 595 (or it can be another 4017N)?
    Or do you think it's better to wire the button matrix indipendently with its own 74HC165 and for the rows [a to-be-identified chip]?

    the existent button matrix is wired as follows:
    Click image for larger version. 

Name:	Immagine 2020-11-17 173836.jpeg 
Views:	18 
Size:	88.2 KB 
ID:	22500

    ...next there will be the LED matrix... but a step at a time ;-)

  12. #12
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    226
    I haven't check the forum so much today, been busy with the new Design Tool and House maintaining
    I think you can use the current 4017 for the button matrix as well because you have used diodes they will prevent
    false readings.
    and you can combine the LD/SHIFT + OUT_CLK and separate out the SERIAL_DATA_OUT from the added 74HC165

    now in the last minute I did some calculations on the pulldown resistors they should be minimum 33k each,
    because at worst case scenario all 20+8 bars + buttons will be connected to one row and that parallel connects all resistors to GND
    which will be 33k/28 =1.1k => 3mA @ 3v3

    also you should use the faster and "newer" model of the 4017 => 74HC4017E (74HC4017E datasheet specifies the timings down to 2V)


    new schematic (explains much better):
    Click image for larger version. 

Name:	dragbar_minimal_IO_ver2.jpg 
Views:	18 
Size:	88.0 KB 
ID:	22509
    code for that:
    Code:
    
    #define NOP3 "nop\n\t""nop\n\t""nop\n\t"
    #define NOP4 "nop\n\t""nop\n\t""nop\n\t""nop\n\t"
    #define NOP5 "nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"
    #define NOP6 "nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"
    #define NOP15 NOP4 NOP6 NOP5
    #define NOP30 NOP10 NOP10 NOP10
    // @ F_CPU @ 600Mhz 60NOP = 100nS
    //                  90NOP = 150nS
    #define P150ns __asm__(NOP30 NOP30 NOP30)
    #define P300ns __asm__(NOP30 NOP30 NOP30 NOP30 NOP30 NOP30)
    
    // IO defines (pin-numbers is just an example)
    #define IN_RESET 0
    #define IN_CLK 1
    #define OUT_CLK 2
    #define OUT_LOAD_SHIFT 3
    #define SERIAL_DATA_OUT 4
    #define SERIAL_DATA2_OUT 5
    
    #define BARCOUNT 20
    #define BARVALUECOUNT 9
    #define MATRIXROWCOUNT 4
    
    byte bars[BARCOUNT];
    byte btnMatrix[MATRIXROWCOUNT];
    byte btnMatrixCurrent;
    
    void setup()
    {
        pinMode(IN_RESET, OUTPUT);
        pinMode(IN_CLK, OUTPUT);
        pinMode(OUT_CLK, OUTPUT);
        pinMode(OUT_LOAD_SHIFT, OUTPUT);
        pinMode(SERIAL_DATA_OUT, INPUT);
    
        // inital states
        digitalWrite(IN_RESET, LOW);
        digitalWrite(IN_CLK, LOW);
        digitalWrite(OUT_CLK, LOW);
        digitalWrite(OUT_LOAD_SHIFT, HIGH); // normal state
    
    }
    
    void loop()
    {
        doBarsRead();
        if (bars[0] == 1) // first drawbar equals one
        {
            // do something
        }
        else if (bars[0] == 2) // first drawbar equals two
        {
            // do something
        }
        // ...
    
        if (bars[19] == 1) // last drawbar equals one
        {
            // do something
        }
        else if (bars[19] == 2) // last drawbar equals two
        {
            // do something
        }
    }
    void doBarsRead()
    {
        digitalWrite(IN_RESET, HIGH);
    	P300ns; // min time @ 2V = 230nS using fast common model 74HC4017E
        digitalWrite(IN_RESET, LOW);
        P300ns; // extra delay to be on the safe side
    	
    	int btnMatrixIndex = 0;
        for (int ri = 1; ri <= BARVALUECOUNT; ri++)
        {
    		
            // LATCH data
            digitalWrite(OUT_LOAD_SHIFT, LOW); 
    		P150ns; // max @ 2v 74HC165 (it must be HC model because it have VCC 2-6V) HCT is 4.5-5.5v only
            digitalWrite(OUT_LOAD_SHIFT, HIGH);
            P150ns; // extra delay to be on the safe side
    		btnMatrixCurrent = 0;
            for (int ci = 0; ci < BARCOUNT; ci++)
            {
                if (digitalRead(SERIAL_DATA_OUT) == HIGH)
                    bars[ci] = ri;
                if (ci < 8)
    			{
    				if (digitalRead(SERIAL_DATA2_OUT) == HIGH)
    					btnMatrixCurrent |= 0x01;
    				btnMatrixCurrent = btnMatrixCurrent << 1;
    			}
                // next col clock input
                digitalWrite(OUT_CLK, HIGH);
    			P150ns;
                digitalWrite(OUT_CLK, LOW);
    			P150ns; // extra delay to be on the safe side
    			
    			btnMatrix
            }
    		if (btnMatrixIndex < MATRIXROWCOUNT)
    			btnMatrix[btnMatrixIndex++] = btnMatrixCurrent;
            
            // select next row
            digitalWrite(IN_CLK, HIGH);
            P300ns; // min time @ 2V = 230nS using fast common model 74HC4017E
            digitalWrite(IN_CLK, LOW);
    		P300ns; // extra delay to be on the safe side
        }
    	// some calculations of the different delays in nS give
    	// 300*2 + (150*2 + 300*2 + 150*20)*9 = 35.7uS => ~28011 in refresh-rate
    	
        // now each bars[i] have the selected value
    }
    if you reverse the button matrix diodes
    you can do this:
    Click image for larger version. 

Name:	dragbar_minimal_IO_ver2.5.png 
Views:	20 
Size:	18.6 KB 
ID:	22510
    and the little different code: (note that I shift each btnMatrix[ci] for each in bit read, this is very efficient)
    Code:
    #define NOP3 "nop\n\t""nop\n\t""nop\n\t"
    #define NOP4 "nop\n\t""nop\n\t""nop\n\t""nop\n\t"
    #define NOP5 "nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"
    #define NOP6 "nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"
    #define NOP15 NOP4 NOP6 NOP5
    #define NOP30 NOP10 NOP10 NOP10
    // @ F_CPU @ 600Mhz 60NOP = 100nS
    //                  90NOP = 150nS
    #define P150ns __asm__(NOP30 NOP30 NOP30)
    #define P300ns __asm__(NOP30 NOP30 NOP30 NOP30 NOP30 NOP30)
    
    // IO defines (pin-numbers is just an example)
    #define IN_RESET 0
    #define IN_CLK 1
    #define OUT_CLK 2
    #define OUT_LOAD_SHIFT 3
    #define SERIAL_DATA_OUT 4
    #define SERIAL_DATA2_OUT 5
    
    #define BARCOUNT 20
    #define BARVALUECOUNT 9
    #define MATRIXROWCOUNT 8
    #define MATRIXCOLCOUNT 4
    
    byte bars[BARCOUNT];
    byte btnMatrix[MATRIXCOLCOUNT];
    
    void setup()
    {
        pinMode(IN_RESET, OUTPUT);
        pinMode(IN_CLK, OUTPUT);
        pinMode(OUT_CLK, OUTPUT);
        pinMode(OUT_LOAD_SHIFT, OUTPUT);
        pinMode(SERIAL_DATA_OUT, INPUT);
    
        // inital states
        digitalWrite(IN_RESET, LOW);
        digitalWrite(IN_CLK, LOW);
        digitalWrite(OUT_CLK, LOW);
        digitalWrite(OUT_LOAD_SHIFT, HIGH); // normal state
    
    }
    
    void loop()
    {
        doBarsRead();
        if (bars[0] == 1) // first drawbar equals one
        {
            // do something
        }
        else if (bars[0] == 2) // first drawbar equals two
        {
            // do something
        }
        // ...
    
        if (bars[19] == 1) // last drawbar equals one
        {
            // do something
        }
        else if (bars[19] == 2) // last drawbar equals two
        {
            // do something
        }
    }
    void doBarsRead()
    {
        digitalWrite(IN_RESET, HIGH);
        P300ns; // min time @ 2V = 230nS using fast common model 74HC4017E
        digitalWrite(IN_RESET, LOW);
        P300ns; // extra delay to be on the safe side
        
        int btnMatrixIndex = 0;
        for (int ri = 1; ri <= BARVALUECOUNT; ri++)
        {
            // LATCH data
            digitalWrite(OUT_LOAD_SHIFT, LOW); 
            P150ns; // max @ 2v 74HC165 (it must be HC model because it have VCC 2-6V) HCT is 4.5-5.5v only
            digitalWrite(OUT_LOAD_SHIFT, HIGH);
            P150ns; // extra delay to be on the safe side
            // first shift in the 20 PULLBARS
            for (int ci = 0; ci < BARCOUNT; ci++)
            {
                if (digitalRead(SERIAL_DATA_OUT) == HIGH)
                    bars[ci] = ri;
            }
            // then shift in the button matrix only the first 8 lines
            if (btnMatrixIndex < MATRIXROWCOUNT)
            {
                for (int ci = 0; ci < MATRIXCOLCOUNT; ci++)
                {
                    if (digitalRead(SERIAL_DATA2_OUT) == HIGH)
                        btnMatrix[ci] |= 0x01;
                    btnMatrix[ci] = btnMatrix[ci] << 1; // visualize this like the matrix is rotated 90 degrees 
    
                    // next col clock input
                    digitalWrite(OUT_CLK, HIGH);
                    P150ns;
                    digitalWrite(OUT_CLK, LOW);
                    P150ns; // extra delay to be on the safe side
                }
                btnMatrixIndex++;
            }
            // select next row
            digitalWrite(IN_CLK, HIGH);
            P300ns; // min time @ 2V = 230nS using fast common model 74HC4017E
            digitalWrite(IN_CLK, LOW);
            P300ns; // extra delay to be on the safe side
        }
        // some calculations of the different delays in nS give
        // 300*2 + (150*2 + 300*2 + 150*20)*9 = 35.7uS => ~28011 in refresh-rate
        
        // now each bars[i] have the selected value
    }

  13. #13
    Member garubi's Avatar
    Join Date
    Sep 2016
    Location
    Modena, Italy, EU
    Posts
    49
    Yes, it would be better to reverse the button matrix diodes...

    For the leds (see the current implementation below) I was thinking to use something like 74HC595 or there are better choices?

    Click image for larger version. 

Name:	Immagine 2020-11-20 175357.jpeg 
Views:	11 
Size:	87.5 KB 
ID:	22550

    Thank for your great help!!

    Stefano

  14. #14
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    226
    Hi,
    I think the 74hc595 will do it + the existing 74hc4017 or a separate if you need a different refresh rate.

    schematic (separate 74HC4017):
    Click image for larger version. 

Name:	ledmatrix_minimal_IO_ver2.5.png 
Views:	12 
Size:	38.7 KB 
ID:	22558

    schematic (common 74HC4017):
    Click image for larger version. 

Name:	dragbar_minimal_IO_andLEDmatrix.jpg 
Views:	12 
Size:	112.3 KB 
ID:	22559
    in the common version I have used diodes to form simple OR-gates
    that make sure that when updating the leds they will get the same on-time
    (maybe it's not needed, I can't verify the results because I don't have any 4017)


    another solution is to use 4x 74hc595 to drive the leds directly without any matrix,
    in this mode you only need to send led update when they are changing

  15. #15
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    226
    and because there is no special thing with the LED:s
    you can use the standard
    shiftOut(dataPin, clockPin, LSBFIRST, j);

    https://www.arduino.cc/reference/en/...d-io/shiftout/

    and have a array containing the 4 led columns to output the data from

  16. #16
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    7,955
    Quote Originally Posted by manicksan View Post
    Code:
    
    #define NOP3 "nop\n\t""nop\n\t""nop\n\t"
    #define NOP4 "nop\n\t""nop\n\t""nop\n\t""nop\n\t"
    #define NOP5 "nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"
    #define NOP6 "nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"
    #define NOP15 NOP4 NOP6 NOP5
    #define NOP30 NOP10 NOP10 NOP10
    You shouldn't use nops.
    It is incompatible between teensys, and different F_CPU. With a new, faster Teensy, it will not work anymore.
    Better is to use delayNanoseconds(). Ther might be cases where your NOPs are a few nanoseconds faster, I know. But they are not good. ...and certainly not NOP30 or anything like that.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •