Simulate analogWrite(PIN, 0-255) with digitalWrite

Hello everyone,

I'm a total noob and have only high school knowledge of electronics.

One part of my project is a 4x4 RGB buttons matrix (how original...). Since I only have 6 PWM pins on my UNO and no TLC5940, I can't really mux the matrix (and I only have common cathode RGB LEDs, apparently it's not good for TLC5940 anyway...).

So I was thinking about using 74HC595 (x2) as a digital shift register but not using PWM. Instead, I wonder if it's possible to simulate analogWrite by flicking digitalWrite ON/OFF real fast and delay the ON state to simulate 0-255 values...

Hope I'm clear enough...

Thanks for your help :slight_smile:

Yes, it's possible, but you won't be able to achieve anything close to the frequency provided by hardware PWM. This means the LEDs may have a visual flicker, especially when they are moving relative to your field of vision. digitalWrite is not very efficient so that will make software PWM even slower. Likely you wouldn't be using digitalWrite with a shift register anyway.

You can also use the analogue pins for the keypad.
Analogue pins are just normal digital pins, with the added functionality of analogue-in.
Leo..

I just saw that you said "Instead" of the shift register. If you're trying to do software PWM directly from the pins I recommend this library:

I found it to be the best option for software PWM and made a small modification to the library that allows you to use Arduino pin numbers when defining the PWM channels. This will be way better than using digitalWrite to roll your own software PWM.

But definitely use hardware PWM if you possibly can.

Thank you for your answers.

I came to conclusion that I could drive the whole matrix (this one by the way) with only 2x74HC595.

In my head, the thing goes like:
Sequence 1-1: Row 1 - analogWrite() to RED1
Sequence 1-2: Row 1 - analogWrite() to GREEN1
Sequence 1-3: Row 1 - analogWrite() to BLUE1
...
Sequence 1-10: Row 1 - analogWrite() to RED4
Sequence 1-11: Row 1 - analogWrite() to GREEN4
Sequence 1-12: Row 1 - analogWrite() to BLUE4

Sequence 2-1: Row 2 - analogWrite() to RED1 etc...

up to Sequence 4-12: Row 4 - analogWrite() to BLUE4

But I fear that in practice it doesn't make any sense...

Am I going in the right direction?

Thanks

You really should have posted that link in your first post. That pre-made board restricts the ways it could be driven. For example I was going to suggest a circuit that would have required a single tpic6c595 chip and 6 pwm pins. That board's internal wiring makes my idea impossible.

I can't understand your description above. It certainly does not sound like it is complete. Can you draw a schematic to explain your idea? Hand drawn is ok.

You can wire it up with Neopixels, my book
/raspberry-pi-projects-for-dummies
Shows you how.

I made a sketch in Tinkercad, you can import my file.

Considering this circuit,

it should be able to scan every led with this code:

byte led1r = 0b00000001;
byte led1g = 0b00000010;
byte led1b = 0b00000100;


//Led 1 RED
analogWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, led1r);
analogWrite(latchPin, 125);

analogWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, led1g);
analogWrite(latchPin, 255);

analogWrite(latchPin, 0);
shiftOut(dataPin, clockPin, MSBFIRST, led1b);
analogWrite(latchPin, 10);

Theoretically, the result is a led with (125, 255, 10) color. But in the simulation, the color is slightly different and the IC breaks because of the current.

In my noob theory I would proceed to scan every led for every row in that way, using other bits to select rows and keeping the first 3 to select R/G/B anodes.

Hope it explains better my problem.

Theoretically, the result is a led with (125, 255, 10) color

No, hopelessly wrong, I'm sorry.

For example this is a crazy thing to do:

analogWrite(latchPin, 125);

You need to go back to basics, design simple circuits and write simple code. You are quite a ways off being ready for your current project.