Author Topic: 12v to 3.3v converter for GPIO.  (Read 3012 times)

0 Members and 1 Guest are viewing this topic.

Online luiHSTopic starter

  • Frequent Contributor
  • **
  • Posts: 592
  • Country: es
12v to 3.3v converter for GPIO.
« on: April 30, 2023, 01:43:47 am »
Hi

I have a project that needs to read 12v signals through the GPIO ports of a microcontroller. It is an 8x8 switch matrix, the machine's electronics scan the columns of these matrix and give the status of the 8 row switches. I cannot change the electronics of that machine at 12v, I have not done it, the circuit that I have designed has to be connected to that machine and read those signals.

At first I used a 4050, but I have had problems because of the propagation time that is very slow, there are even differences between CD4050, HEF4050 and MC14050. Now I can only use the MC14050 because the delay times that I have set by software to read the data only work with the MC14050, if I put another variant of the 4050 it no longer works well.

So it occurred to me to replace the 4050 with inverted diodes, the BAS16VY. At the output of the diodes, a 3.3v pullup resistor and an array of 2.2nF capacitors to ground. This seems to work for now.

But I'd like to use something on a single chip, like a 4050 or 74LVC, but that will take 12v input signals with a 3.3v output and have a fast propagation time.

Any suggestions?

Thx.
« Last Edit: April 30, 2023, 01:53:14 am by luiHS »
 

Offline dobsonr741

  • Frequent Contributor
  • **
  • Posts: 674
  • Country: us
Re: 12v to 3.3v converter for GPIO.
« Reply #1 on: April 30, 2023, 02:02:28 am »
Can you please provide a schematics? Of what the original machine was, and what the attempt was with the 4050 that did not work.
 

Offline james_s

  • Super Contributor
  • ***
  • Posts: 21611
  • Country: us
Re: 12v to 3.3v converter for GPIO.
« Reply #2 on: April 30, 2023, 02:12:55 am »
You should be able to get away with using resistor dividers if it's only inputs. You could use resistor networks to simplify the construction.
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 4040
  • Country: nz
Re: 12v to 3.3v converter for GPIO.
« Reply #3 on: April 30, 2023, 02:23:21 am »
Do you really need to have this current amplification function? Those chips have about 1 µA inputs and 5 mA outputs. I guess that's the main source of the 50-100 ns propagation delay (which doesn't seem to be all that long tbh).

The chances are your switch electronics can supply a lot more than 1 µA, and also your microcontroller probably doesn't need more than 1 µA to its GPIO pins.

Why can't a simple resistor voltage divider do the job? Say a 10k between gnd and your GPIO input, and a 27k or 33k between the GPIO and the 12V data input?
 

Offline PCB.Wiz

  • Super Contributor
  • ***
  • Posts: 1549
  • Country: au
Re: 12v to 3.3v converter for GPIO.
« Reply #4 on: April 30, 2023, 04:42:53 am »
I have a project that needs to read 12v signals through the GPIO ports of a microcontroller. It is an 8x8 switch matrix, the machine's electronics scan the columns of these matrix and give the status of the 8 row switches. I cannot change the electronics of that machine at 12v, I have not done it, the circuit that I have designed has to be connected to that machine and read those signals.
how exactly does the machine's electronics scan the columns of these matrix and give the status of the 8 row switches.
Do you have their internal circuit ?

At first I used a 4050, but I have had problems because of the propagation time that is very slow, there are even differences between CD4050, HEF4050 and MC14050. Now I can only use the MC14050 because the delay times that I have set by software to read the data only work with the MC14050, if I put another variant of the 4050 it no longer works well.
That makes little sense, relative to a switch matrix, any 4050 should be plenty fast enough << 1us.
You may be missing another factor here ?

Another parallel part you could try, is a ULN2803 or variant, that has a pull down resistor, which may be what is missing here ?
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: 12v to 3.3v converter for GPIO.
« Reply #5 on: April 30, 2023, 04:56:36 am »


Quote
At first I used a 4050, but I have had problems because of the propagation time that is very slow


That seems very unlikely.  Even old CMOS logic ought to be "very fast" compared to the sort of human-oriented timings of a switch matrix.  I implemented a whole keyboard from the basic design in Lancaster's CMOS Cookbook, and that was at 5V, which ought to be slower than it can run at 12V.  (and it might have used A-series chips!)
(Datasheet says propagation time with Vin=10V, Vcc=5V is significantly less than 100ns. I hope your keyboard isn't scanning anywhere near 10MHz!)
 

Offline Faranight

  • Supporter
  • ****
  • Posts: 203
  • Country: si
Re: 12v to 3.3v converter for GPIO.
« Reply #6 on: April 30, 2023, 06:38:47 am »
Hypothetically speaking, how much overvoltage protection does a setup with a resistor divider network offer in this case (12V to 3.3V with resistors in some 10 kOhm range)?
If the user can expect some overvoltage to appear on the 12V input, can the internal uC pin protection diodes handle the current or is there external protection circuitry needed?
e-Mail? e-Fail.
 

Online RoGeorge

  • Super Contributor
  • ***
  • Posts: 6207
  • Country: ro
Re: 12v to 3.3v converter for GPIO.
« Reply #7 on: April 30, 2023, 07:18:32 am »
If you need to output 12V pulses to scan the keys, there are open collector TTL chips that have normal TTL inputs (TTL still works with 3.3V inputs) and can support up to 15-30V output pullup (e.g. SN7407 https://www.ti.com/lit/ds/symlink/sn7407.pdf ).  For inputs, a resistor divider.

If the lines has to be bidirectional, there are level shifters chips, with a transistors for each direction, either bipolar or MOSFET, like this (don't know by heart the part number that can level shift from 3V3 to 12V), like this:
https://electronics.stackexchange.com/questions/296879/logic-level-converter-using-transistors
« Last Edit: April 30, 2023, 07:23:07 am by RoGeorge »
 

Online luiHSTopic starter

  • Frequent Contributor
  • **
  • Posts: 592
  • Country: es
Re: 12v to 3.3v converter for GPIO.
« Reply #8 on: April 30, 2023, 01:21:48 pm »
Well, in this design I really run into two problems.

1.- I connect the columns of the matrix to the GPIO of a microcontroller, in principle I used the 4050, and by software I configure interrupts for each port connected to a column. Regardless of using the 4050, I noticed that the interruptions were triggered incorrectly, so I checked with the oscilloscope that there are fluctuations in the 12v, the machine does not use a stabilized voltage. In case the machine had a fault, I checked and changed the diode bridges, filter capacitors, even the power transformer, but the 12v fluctuation was not resolved. So I changed the design to the one I attached, diode, pullup resistor to 3.3v and 2.2nF capacitor to ground, this works.

2.- For the reading of the rows, I have left the 4050, but by program I have to put a small delay to read the rows, when the column interrupt is triggered, if I don't then the data is still not available. This I suppose is the propagation time of the 4050, which is very high compared to others like the 74LVC, I checked it in the datasheet and the differences in the propagation times are great. Also, some time ago I had that kind of problem with another circuit that didn't work well for me with the 4050, I replaced it with a 74LVC245 and it worked perfectly.

To make matters worse, there are also differences in the propagation time between different manufacturers of the 4050, so with the MC14050 and the delay that I put in software, the row signals are read fine, but if I put a HEF4050 or CD4050 they already fail , I guess for trial and error I would have to calculate a new software delay to capture the state of all 8 rows when the column interrupt is triggered.

The circuitry of the machine, which I cannot change, I only capture these signals and process them with my circuit using a Kinetis MK66 microcontroller and in a new version an RT1064, it consists of a processor that scans the 8 columns with a ULN2803, so that the active column is at 0v and the rest at 12v with pullup resistors. To read the rows it uses LM339 operational configured as comparators to convert the 12v to 5v and from there with 74xx chips it reads them with the microprocessor. I didn't want to use that circuitry with the LM339 to simplify it, I thought that with a 4050 it could work (only for the rows), and although it does it by delaying the data capture with a software delay, I would prefer a cleaner hardware solution.

I think that both rows and columns could work with the attached diagram, I use the diodes in arrays of 3 with the BAS16VY, the resistors in arrays of 8 and the capacitors in arrays of 4.

The question is if there is a chip that allows to convert logic levels from 12v to 3.3v, and that is fast enough, like a 74LVC245, but it only admits maximum 5v signals.

Use a resistive divider to read the rows, I don't know if it will work due to the fluctuations in the 12v logic level, I would have to try it.

« Last Edit: April 30, 2023, 01:26:31 pm by luiHS »
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 4040
  • Country: nz
Re: 12v to 3.3v converter for GPIO.
« Reply #9 on: April 30, 2023, 01:32:07 pm »
I only capture these signals and process them with my circuit using a Kinetis MK66 microcontroller and in a new version an RT1064

180 MHz and 600 MHz "microcontrollers" to read a keyboard? Level shifters with 50 ns or 100 ns propagation delay are too slow?

It is normal with keys and switches to use a debounce time of 20 ms (20,000,000 ns) or so. Certainly more than 1 ms.


What on earth is going on here?

 
The following users thanked this post: thm_w, newbrain

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5913
  • Country: es
Re: 12v to 3.3v converter for GPIO.
« Reply #10 on: April 30, 2023, 02:54:07 pm »
The issue is not propagation delay, but capacitive load, you must wait enough time for the 2.2nf capacitor to charge up, also discharge it before scanning the next row.

It's more than likely you can do the entire thing with just resistor dividers (10K from input to pin, then 3k3 from pin to gnd) and proper software debouncing, using the usual 1KHz systick ISR for the scanning routines will be more than fast enough, you only have to scan 8 sequential rows, while reading 8 columns at once, noting down the last value, last stable values (when having same state for >20ms), exposing the stable values to the software.
Regardless of switching noises, the value should be stable when a key is released or pressed.

For example:
Code: [Select]
typedef struct {
    uint8_t stable[8];        // stable values of 8x8 array
    uint8_t last[8];          // last values of 8x8 array
    uint8_t row;              // current row being scanned
    uint8_t row_time;         // row delay timer
    uint32_t last_time[8][8]; // last time each key changed
}keypad_t;

volatile keypad_t keypad;

void update_column(void){
    keypad.last[keypad.row] = GPIOA->IDR & 0xFF;     // I.e. Port A  8 LSB.
}

void update_row_gpio(void){
    switch (keypad.row){
        case 0:                // pseudo code
            row_7_pin=0;
            row_0_pin=1;
            break;

        case 1:
            row_0_pin=0;
            row_1_pin=1;
            break;

        (...)
       
        case 7:
            row_6_pin=0;
            row_7_pin=1;
            break;
    }
}

void keypad_isr(void){           // called from systick @ 1khz
    if(keypad.row_timer++ < 1){
        return;                     // Let each row charge for 1ms
    }
    keypad.row_timer=0;              // reset row timer
    uint32_t now  = getTick();          // get current tick value
    update_column();            // Some routine that reads the 8 column bits into keypad.last[keypad.row];
    uint8_t change = keypad.last[keypad.row] ^ keypad.stable[keypad.row];               // XOR
    for(uint8_t col=0; col<8; col++){              // update stable values
        if (change & 1<<col) {
            keypad.last_time[keypad.row][col] = now;             // reset timer on change
        }
        else if(now - keypad.last_time[keypad.row][col] >=20) {             // 20ms with same value
            keypad.stable[keypad.row] =  (keypad.stable[keypad.row] & ~bit) | (keypad.last[keypad.row] & bit);              // Clear stable bit, update with last value
        }
    }

    if(++keypad.row > 7){             // Update scanning row
        keypad.row = 0;
    }
   
    update_row_gpio();            // Some routine that sets the correct GPIO for the current keypad row.
}

void get_key(uint8_t key){    // Read debounced key status, from 0 to 63, called from normal program
    return (keypad.stable[key/8] & 1<<(key%8);
}
« Last Edit: April 30, 2023, 04:02:11 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6265
  • Country: fi
    • My home page and email address
Re: 12v to 3.3v converter for GPIO.
« Reply #11 on: April 30, 2023, 07:00:29 pm »
I only capture these signals and process them with my circuit using a Kinetis MK66 microcontroller and in a new version an RT1064
180 MHz and 600 MHz "microcontrollers" to read a keyboard? Level shifters with 50 ns or 100 ns propagation delay are too slow?

It is normal with keys and switches to use a debounce time of 20 ms (20,000,000 ns) or so. Certainly more than 1 ms.

What on earth is going on here?
It's the "MCU is so fast I want the peripherals to match, because otherwise the software gets more complicated to write" problem.

Absolutely no offense/snarkiness/snideness meant, luiHS; I mean the above in the literal sense.  The "better-but-more-complicated" software approach (including software debounce) is to set up the next row immediately after reading, but then do something else useful for the duration.  Using a 1 kHz interrupt (1000 rows per second, thus each key 125 times each second) gives you a maximum key state change latency of 8 ms; 8 kHz interrupt a max latency of 1 ms.  Because I like to minimize the latency, my software debouncing uses the "inactivity period counter" approach: a per-key counter is initialized to a suitable number, and decremented until zero each interrupt; with a nonzero counter meaning the state is not checked.

My preferred implementation uses two bytes per key, in separate arrays.  One array is for the inactivity counters, that also act as the autorepeat interval counters.  The other array acts as key pressed event flags, with the interrupt only setting the flag, and main loop code clearing the flag when performing the key press event.  If you use a full byte per key (and check the compiler uses LDRB/LDRSB for reading it and STRB for clearing it, for both MK66 and RT106x), you won't need any locking at all.  This works even when a single keypress "peck" is faster than a main loop iteration.  To incorporate the initial-repeat and auto-repeat intervals to the same counter, you can use an extra bit (either LSB, or separate actions depending on positive/negative counter value) to distinguish between debounce and repeat.

This is more complex than when the matrix row switching is approximately as fast as the MCU, so that you can just read the entire matrix in a single loop without significant time lost between rows (and no need to spend that time doing something else useful).  My approach is more efficient, because each interrupt only reads a single row (8 keys) and updates their states, so the only time "lost" is interrupt overhead; but the code is more complex, and one needs to think of things like main loop code modifying button state just as an interrupt fires and updates those states also –– and also what kind of latency issues such an interrupt firing at a random moment for other code causes.
« Last Edit: April 30, 2023, 07:03:28 pm by Nominal Animal »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14488
  • Country: fr
Re: 12v to 3.3v converter for GPIO.
« Reply #12 on: April 30, 2023, 07:59:34 pm »
 ::)
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6265
  • Country: fi
    • My home page and email address
Re: 12v to 3.3v converter for GPIO.
« Reply #13 on: April 30, 2023, 08:40:31 pm »
::)
If something gets you to roll your eyes, the least thing you can do is explain why, instead of just showing your condescension like a dick.  >:(

Not everyone of us perceives all the things that are obvious to you.
 
The following users thanked this post: MK14, james_s

Online Zero999

  • Super Contributor
  • ***
  • Posts: 19529
  • Country: gb
  • 0999
Re: 12v to 3.3v converter for GPIO.
« Reply #14 on: April 30, 2023, 09:12:06 pm »
If you need to output 12V pulses to scan the keys, there are open collector TTL chips that have normal TTL inputs (TTL still works with 3.3V inputs) and can support up to 15-30V output pullup (e.g. SN7407 https://www.ti.com/lit/ds/symlink/sn7407.pdf ).  For inputs, a resistor divider.

If the lines has to be bidirectional, there are level shifters chips, with a transistors for each direction, either bipolar or MOSFET, like this (don't know by heart the part number that can level shift from 3V3 to 12V), like this:
https://electronics.stackexchange.com/questions/296879/logic-level-converter-using-transistors
A J-FET will also work. It just needs to have a cut-off voltage of >-3.3V.  J113 or PN4391 should work for J1, instead of 2N4393.



Yes I know this is probably unnecessary. A plain old potential divider will probably do.
 

Offline PCB.Wiz

  • Super Contributor
  • ***
  • Posts: 1549
  • Country: au
Re: 12v to 3.3v converter for GPIO.
« Reply #15 on: April 30, 2023, 09:44:25 pm »
..
The circuitry of the machine, which I cannot change, I only capture these signals and process them with my circuit using a Kinetis MK66 microcontroller and in a new version an RT1064, it consists of a processor that scans the 8 columns with a ULN2803, so that the active column is at 0v and the rest at 12v with pullup resistors. To read the rows it uses LM339 operational configured as comparators to convert the 12v to 5v and from there with 74xx chips it reads them with the microprocessor. I didn't want to use that circuitry with the LM339 to simplify it, I thought that with a 4050 it could work (only for the rows), and although it does it by delaying the data capture with a software delay, I would prefer a cleaner hardware solution.
...
That's old-school, but perfectly valid and multi-sourced.
If you have a working scan design, why change it ? Are you making thousands of these ?
In 2023 you could look at LED drivers with read-back/diagnostics, for a reduced wires solution, but multi sourcing is trickier.

Or go with a generic IO expander like xxA9555 and code scanning software, or use a low cost MCU as a key pad reader.
Ironically, TSSOP20 MCUs can cost less than generic IO expanders ?!
« Last Edit: May 01, 2023, 05:26:01 am by PCB.Wiz »
 

Offline David Hess

  • Super Contributor
  • ***
  • Posts: 16621
  • Country: us
  • DavidH
Re: 12v to 3.3v converter for GPIO.
« Reply #16 on: May 01, 2023, 12:02:02 am »
A pair of 1489 quad line receivers intended for RS-232 level translation might be suitable.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14488
  • Country: fr
Re: 12v to 3.3v converter for GPIO.
« Reply #17 on: May 01, 2023, 03:34:39 am »
::)
If something gets you to roll your eyes, the least thing you can do is explain why, instead of just showing your condescension like a dick.  >:(

Easy there. It was just a smiley. And I'm a condescending dick.

Should have quoted or added possibly some context, but the whole idea of a 4050 not being fast enough for scanning a keyboard, and requiring a Cortex-M7 running at hundreds of MHz to handle a keyboard was a tad much. And Bruce's "What on earth is going on here?" sounded about right. Since we didn't get any further reply from the OP, the question remains unanswered and the rest is just speculation.

So, I'll remove the smiley if you feel offended by it, and I'll replace it with a second "what on earth is going on here?".
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6265
  • Country: fi
    • My home page and email address
Re: 12v to 3.3v converter for GPIO.
« Reply #18 on: May 01, 2023, 04:45:21 am »
::)
If something gets you to roll your eyes, the least thing you can do is explain why, instead of just showing your condescension like a dick.  >:(

Easy there. It was just a smiley. And I'm a condescending dick.

Should have quoted or added possibly some context, but the whole idea of a 4050 not being fast enough for scanning a keyboard, and requiring a Cortex-M7 running at hundreds of MHz to handle a keyboard was a tad much. And Bruce's "What on earth is going on here?" sounded about right.
Sure, I can agree with that.  :-+

Since we didn't get any further reply from the OP, the question remains unanswered and the rest is just speculation.
Well, to me, their post #8, especially "by software I configure interrupts for each [column input]" and "I have to put a small delay to read the rows, when the column interrupt is triggered" indicated that the true problem is that the software solution chosen is simplistic, and my reply #11 (to brucehoult) names the problem and outlines the standard software-debounced, interrupt-per-row scanning routine, with a pointer towards autorepeat and how to avoid missing keypresses and how to avoid sync issues wrt. interrupt updates and main loop updates without resorting to any kind of locks.  (Anyway, I was wrong, too; the problem luiHS has is different.)

I'm pretty sure you'll agree that if our places were reversed (and they have been in the past, in other threads), you'd be miffed at me if I had just posted an eyeroll, too.

So, I'll remove the smiley if you feel offended by it, and I'll replace it with a second "what on earth is going on here?".
No, no, it is not about offense.  It is about posting only a reaction/opinion, and not the focus/reason for it, leaving us hanging and wondering what it is that you reacted to.  It wasn't obvious to me.

Plus, because of this exchange, I realized my own advice to luiHS was useless.
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6265
  • Country: fi
    • My home page and email address
Re: 12v to 3.3v converter for GPIO.
« Reply #19 on: May 01, 2023, 06:28:00 am »
Dammit.  luiHS, your setup differs from typical ones in such unusual ways, my advice earlier is useless to you.  Apologies.

Let me swap rows and columns; it's just much easier for me that way.

I have a project that needs to read 12v signals through the GPIO ports of a microcontroller. It is an 8x8 switch matrix, the machine's electronics scan the [rows] of these matrix and give the status of the 8 [column] switches. I cannot change the electronics of that machine at 12v, I have not done it, the circuit that I have designed has to be connected to that machine and read those signals.

You have 8 row selector inputs, and 8 column data inputs.

The external keyboard matrix, not the microcontroller, is in control of the row selection.  The active row is pulled low, while the rest of the row selector inputs stay high.  I shall assume you also have the 12V available (if nothing else, then via 1-7 common-cathode diodes from the row selectors).

The problem is that using the row selector inputs as the interrupt trigger for the microcontroller occurs before the column data inputs have stabilized (due to whatever delays or capacitances involved in the circuit).

The software solution would be to have the row selector inputs with falling edge interrupts, with the same interrupt handler, that arms a pre-prepared timer (of about 1µs), whose interrupt handler causes the column data to be read and processed.

Another alternative is to use a high frequency timer interrupt, that reads the row selector inputs, and only reads and processes the column data inputs when only one of the row selector inputs has been low for three times in row.  The interrupt frequency should be 4x to 8x the maximum frequency at which the row selector inputs may change (so that this interrupt occurs at least 4 to 8 times per active row).

I think a hardware solution, something based on an 8-way AND or NAND gate on the row selector inputs and delaying the output, is risky, because the row selector inputs may switch (say from 10111111 to 11011111) too fast for the intervening high to be registered.  (In my own code, it can be less than one MCU cycle.)  The simplest I can think of is one of those small MCUs, say an ATtiny404, with 8 inputs and 4 outputs, with the inputs level-shifted to 3.3V somehow.  One of the outputs is the trigger strobe (indicating only one of the inputs is low and should be read now), with the three outputs indicating which input is low.
(The hardware solution using an extra MCU can sound silly, unless you realize it is just programmable logic here, and not dependent on what kind of an MCU it is used with; its operation should be easy to verify with a scope alone.)
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14488
  • Country: fr
Re: 12v to 3.3v converter for GPIO.
« Reply #20 on: May 01, 2023, 06:51:39 am »
I'm pretty sure you'll agree that if our places were reversed (and they have been in the past, in other threads), you'd be miffed at me if I had just posted an eyeroll, too.

I try not to take things too personally especially on forums or expect too much from people either (see below.)

So, I'll remove the smiley if you feel offended by it, and I'll replace it with a second "what on earth is going on here?".
No, no, it is not about offense.  It is about posting only a reaction/opinion, and not the focus/reason for it, leaving us hanging and wondering what it is that you reacted to.  It wasn't obvious to me.

I get that, I try not to do this too often, but sometimes just being not too obvious actually is both "lean" and triggers interesting reactions.

Plus, because of this exchange, I realized my own advice to luiHS was useless.

See, my unobvious smiley may have had some use. ;D

Regarding the OP's problem, your last post looks right. Unless we are missing some key information, the OP is just using a wrong software approach for the task at hand and is trying to make it work with some hardware.
 
The following users thanked this post: Nominal Animal

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8179
  • Country: fi
Re: 12v to 3.3v converter for GPIO.
« Reply #21 on: May 01, 2023, 07:31:30 am »
a second "what on earth is going on here?".

What, you guys really don't get it? To me it's obvious: the high-end microcontroller is probably there for something else. Why would anyone do an input matrix project which discards the inputs and does nothing with them?

As we don't know what the complete project is about, it's quite safe to assume the high end microcontroller is there for some reason (even if not currently, it could be a learning project for something more complex in the future). And if so, the only sensible thing to do is to write software non-blocking, releasing the CPU time for those other tasks, just like Mr. Nominal suggests.

Highly performant microcontrollers routinely combine performance-requiring parts and trivial parts. What is your suggestion, add another simpler MCU just to do the keyboard part with blocking delays, and then come up with MCU-to-MCU communication protocol? Sounds tedious and expensive.

And for the OP, indeed you should not be thinking about HW (propagation delays, capacitances, whatnot). HW delays do not matter because humans and buttons are slow. That slowness should not be wasting your CPU time, though; you need to decouple the HW delays from CPU clock. This is a matter of writing software in the correct way. Periodic interrupts at 1kHz or so are a good start, but of course there are even more efficient ways.
« Last Edit: May 01, 2023, 07:36:12 am by Siwastaja »
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 4040
  • Country: nz
Re: 12v to 3.3v converter for GPIO.
« Reply #22 on: May 01, 2023, 07:41:05 am »
And if so, the only sensible thing to do is to write software non-blocking, releasing the CPU time for those other tasks, just like Mr. Nominal suggests.

Of course. And not expect physical moving systems with a resonant frequency of probably a few KHz to do sensible things at tens of nanosecond time scale.

I think everyone except OP is in agreement on that.
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6265
  • Country: fi
    • My home page and email address
Re: 12v to 3.3v converter for GPIO.
« Reply #23 on: May 01, 2023, 09:01:19 am »
Call me silly, but my own preference in this kind of case would be to create a logic interface to the external matrix, and then interface it to my microcontroller using UART over a digital isolator like ISO6721 (1/1) or ISO6742DWR (2/2).

Looking at Mouser, ATtiny417 is around 1€ apiece, and can be programmed in C/C++ with the same toolchain (GCC or clang) as the MK66 and RT1062, although the backend is different (AVR instead of ARMv7e-m:Cortex-M4/M7).  ISO6721BDR is 1.17€ in hundreds and 1.62€ in singles.  For the 16 input signal lines, I'd use 0603 resistor arrays, 10k and 3.3k (isolated/separate), in voltage divider configuration (3.3/13.3≃0.248, 12V×3.3/(3.3+10)≃2.97V.  With 5% resistors, the factor is 0.248±0.019.

The trick is that I would power the ATtiny417 and ISO6742 from a power opamp output (total maximum current draw is about 20mA), input in a similar voltage divider configuration (making sure the input voltage won't exceed the supply voltage, after the dividers, taking into account the resistor variance), in unity buffer configuration.  Perhaps TI TLV9301IDBVR, at about 0.50€.

The main loop on the ATtiny417 would check the row selector inputs at regular intervals (basically the main loop is written around the row selector checking, with a delay to ensure minimum iteration interval).  When the row selector inputs stabilize (only a specific one remains low for three consecutive main loop iterations), the column data inputs are checked, the matrix state updated accordingly, and applicable events sent.

I personally would prefer UART for the communications if possible, because then the ATtiny could always send one byte per event: 0..63 for keypresses, 64..127 for autorepeats, and 192..255 for releases.  This leaves 0xAA = 0b10101010 = 170 free for synchronization (although the ATtiny417 internal oscillator is 20MHz ± 2%), with code (c<128) indicating matrix key (c&63) press or autorepeat event.  The other side of the UART could be used to request N sync bytes, change key dead time, initial repeat delay, autorepeat interval, etc.

Not only would the 12V keyboard matrix and its associated logic be electrically isolated from the MCU side, but this also makes the UART input on the MK66/RT1064 MCU an event queue, simplifying the main loop a lot.  The UART interrupt is trivial, as it just stuffs the received byte into a circular buffer of sufficient size; and depending on what exactly the buttons are, can even discard the key releases if the duration of each keypress is not important.

I'd also make it a separate unit from the main MCU: just switch that few-euro module if it burns out.  The isolator ensures any oddness on the 12V side should be limited to that side, which helps with expensive MCUs like RT1064 (currently 20€+ in singles, 15€+ even in hundreds).  I like the modularity here, and how using a secondary MCU simplifies the overall design, and even helps with repairability (considering the 12V keyboard matrix a glitchy black box).

Now you are absolutely free to roll your eyes, even I am not sure if this suggestion would work ;D!  Again, I'm just a hobbyist, so I don't know whether this would make any business sense even if it does work; and I'm almost certainly missing things experienced EE's know to avoid here.
« Last Edit: May 01, 2023, 09:04:00 am by Nominal Animal »
 

Online brucehoult

  • Super Contributor
  • ***
  • Posts: 4040
  • Country: nz
Re: 12v to 3.3v converter for GPIO.
« Reply #24 on: May 01, 2023, 09:33:37 am »
which helps with expensive MCUs like RT1064 (currently 20€+ in singles, 15€+ even in hundreds).

RT1062 + 2 MB external flash + USB socket plus other stuff on a board for $20 = Teensy 4.0 :-)

(I believe the RT1064 just has flash in the package)
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6265
  • Country: fi
    • My home page and email address
Re: 12v to 3.3v converter for GPIO.
« Reply #25 on: May 01, 2023, 10:04:03 pm »
Yep, I have a few as you know, and I know luiHS has some too.  (MK66 is used on Teensy 3.6 and RT1062 in Teensy 4.0, 4.1, and MicroMods.  I don't have a 3.6, but I do have several of 4.0, one or two 4.1, and a MicroMod.  And I really like them, and often recommend to people wanting to do either Arduinoy-stuff or bare metal development (without JTAG/debugging) but with more powerful microcontrollers.)

All the prices I quited are from Mouser, as I mentioned.  (I tried to use an apples-to-apples comparison regarding the prices.)
Relatively speaking, my "silly" isolated ATtiny417 keyboard matrix handler will still be a fraction of the price of even a single RT1062; probably about half the price at 1k batches, but smaller fraction at smaller batches (maybe a quarter in singles).

I am very curious about any comments on the approach.  Especially using a power op-amp to provide a fractional supply voltage "feels" nifty, as it gives a nice working range for the actual 12V supply and I/O levels.  Anything between 2.25 and 5.25 V for the ISO6721 and ATtiny417 will work just fine.  High inputs need to be between 0.7×Vcc and 1.0×Vcc, so one might want to use 1% instead of 5% resistors in the dividers, just to keep things reliable.
The isolator of course works as a level shifter: the other side supplies its own Vcc, determining the I/O levels on that side.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8179
  • Country: fi
Re: 12v to 3.3v converter for GPIO.
« Reply #26 on: May 02, 2023, 05:29:00 am »
Well, anytime you need isolation, it's tempting to simultaneously add task separation and move part of digital processing to a small, secondary MCU, because digital communication is usually way easier to isolate than the input signals (analog; or weird voltages; or just too many digital signals). I have nothing against your proposed solution; I would just hard-code those repetition rate etc. configurations to make the link unidirectional, one less signal to isolate, less code to write and test. Make the small MCU "do the right thing" out of box.

Really the biggest hurdle to some is having to program those secondary MCUs. Especially if the software becomes non-trivial enough so that the full functionality can't be completely agreed upon and tested, so that firmware updates will be needed. But this key matrix thing shouldn't be that complex.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf