Sunday, July 16, 2023

Blink an LED or do other tasks asynchronously without using delay() on an Arduino

/* Blink Four LEDs Without Delay
  Adapted from Blink Without Delay
  by Steven J Greenfield, aka Polymorph
  Use however you like

I wrote this years ago. I'm not the only one, I'm not claiming that...

Note that I do the math and saving of the current time in such a way as to not cause cumulative timing errors, and to be immune to the rollover of millis(). For faster timed events, you can use micros() in place of millis(). You can even mix them, as long as each variable sticks with one or the other.


// constants won't change. Used here to 

// set pin numbers:

const int ledPin0 =  2;      // the number of the LED0 pin

const int ledPin1 =  3;      // the number of the LED1 pin

const int ledPin2 =  4;      // the number of the LED2 pin

const int ledPin3 =  5;      // the number of the LED3 pin

// Variables will change:

int ledState0 = LOW;             // ledState used to set the LED0

int ledState1 = LOW;             // ledState used to set the LED1

int ledState2 = LOW;             // ledState used to set the LED2

int ledState3 = LOW;             // ledState used to set the LED3

// the follow variables are unsigned long because the time stored in millis() and micros()

// are unsigned long.

unsigned long previousMillis0 = 0;        // will store last time LED0 was updated

unsigned long previousMillis1 = 0;        // will store last time LED1 was updated

unsigned long previousMillis2 = 0;        // will store last time LED2 was updated

unsigned long previousMillis3 = 0;        // will store last time LED3 was updated

// the follow variables are unsigned long because the time stored in millis() and micros()

// are unsigned long.

unsigned long interval0 = 1000;           // interval at which to blink LED0 (milliseconds)

unsigned long interval1 = 457;           // interval at which to blink LED1 (milliseconds)

unsigned long interval2 = 1020;           // interval at which to blink LED2 (milliseconds)

unsigned long interval3 = 742;           // interval at which to blink LED3 (milliseconds)

void setup() {

  // set the digital pin as output:

  pinMode(ledPin0, OUTPUT);    

  pinMode(ledPin1, OUTPUT); 

  pinMode(ledPin2, OUTPUT); 

  pinMode(ledPin3, OUTPUT);   


void loop()


  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the 

  // difference between the current time and last time you blinked 

  // the LED is bigger than the interval at which you want to 

  // blink the LED.

  // save the current time so it doesn't change during an operation

  unsigned long currentMillis = millis();

  // LED0 

  if(currentMillis - previousMillis0 >= interval0) {

    // save the last time you blinked the LED0 

    previousMillis0 += interval0;   // prevents time creep

    // if the LED is off turn it on and vice-versa:

    if (ledState0 == LOW)

      ledState0 = HIGH;


      ledState0 = LOW;



  if(currentMillis - previousMillis1 >= interval1) {

    // save the last time you blinked the LED0 

    previousMillis1 += interval1;   

    // if the LED is off turn it on and vice-versa:

    if (ledState1 == LOW)

      ledState1 = HIGH;


      ledState1 = LOW;



  if(currentMillis - previousMillis2 >= interval2) {

    // save the last time you blinked the LED0 

    previousMillis2 += interval2;   

    // if the LED is off turn it on and vice-versa:

    if (ledState2 == LOW)

      ledState2 = HIGH;


      ledState2 = LOW;



  if(currentMillis - previousMillis3 >= interval3) {

    // save the last time you blinked the LED0 

    previousMillis3 += interval3;   

    // if the LED is off turn it on and vice-versa:

    if (ledState3 == LOW)

      ledState3 = HIGH;


      ledState3 = LOW;

    // set the LEDs with the ledStates of the variable:

    digitalWrite(ledPin0, ledState0);

    digitalWrite(ledPin1, ledState1);

    digitalWrite(ledPin2, ledState2);

    digitalWrite(ledPin3, ledState3);



Sunday, May 7, 2023

How To Draw Schematic Diagrams

By Paul Horowitz and Winfield Hill
Appendix E from The Art of Electronics 2nd Edition
Cambridge University Press 1980, 1989.

A well-drawn schematic makes it easy to understand how a circuit works and aids in troubleshooting; a poor schematic only creates confusion. By keeping a few rules and suggestions in mind, you can draw a good schematic in no more time than it takes to draw a poor one. In this appendix we dispense advice of three varieties: general principles, rules, and hints. We have also drawn some real knee-slappers to illustrate habits to avoid.

General Principles

Schematics should be unambiguous. Therefore, pin numbers, parts values, polarities, etc., should be clearly labeled to avoid confusion.

A good schematic makes circuit functions clear. Therefore, keep functional areas distinct; don't be afraid to leave blank areas on the page, and don't try to fill the page. There are conventional ways to draw functional subunits; for instance, don't draw a differential amplifier as in Figure E1, because the function won't be easily recognized. Likewise, flip-flops are usually drawn with clock and inputs on the left, set and clear on top and bottom, and outputs on the right.

Figure E1: Placement of power rails and conventions

for device alignment (examples of what not to do)


  • Wires connecting are indicated by a heavy black dot; wires crossing, but not connecting, have no dot (don't use a little half-circular ``jog''; it went out in the 1950s).
  • Four wires must not connect at a point; i.e., wires must not cross and connect.
  • Always use the same symbol for the same device; e.g., don't draw flip-flops in two different ways (exception: assertion-level logic symbols show each gate in two possible ways).
  • Wires and components are aligned horizontally or vertically, unless there's a good reason to do otherwise.
  • Label pin numbers on the outside of a symbol, signal names on the inside.
  • All parts should have values or types indicated; it's best to give all parts a label, too, e.g., R7 or IC3.


  • Identify parts immediately adjacent to the symbol, forming a distinct group giving symbol, label, and type or value.
  • In general, signals go from left to right; don't be dogmatic about this, though, if clarity is sacrificed.
  • Put positive supply voltages at the top of the page, negative at the bottom. Thus, npn transistors will usually have their emitter at the bottom, whereas pnp's will have their emitter topmost.
  • Don't attempt to bring all wires around to the supply rails, or to a common ground wire. Instead, use the ground symbol(s) and labels like +Vcc to indicate those voltages where needed.
  • It is helpful to label signals and functional blocks and show waveforms; in logic diagrams it is especially important to label signal lines, e.g., RESET' or CLK.
  • It is helpful to bring leads away from components a short distance before making connections or jogs. For example, draw transistors as in Figure E2.

Figure E2: Component leads

  • Leave some space around circuit symbols; e.g., don't draw components or wires too close to an op-amp symbol. This keeps the drawing uncluttered and leaves room for labels, pin numbers, etc.
  • Label all boxes that aren't obvious: comparator versus op-amp, shift register versus counter, etc. Don't be afraid to invent a new symbol.
  • Use small rectangles, ovals, or circles to indicate card-edge connections, connector pins, etc. Be consistent.
  • The signal path through switches should be clear. Don't force the reader to follow wires all over the page to find out how a signal is switched.
  • Power-supply connections are normally assumed for op-amps and logic devices. However, show any unusual connections (e.g., an op-amp run from a single supply, where V- = ground) and the disposition of unused inputs.
  • It is very helpful to include a small table of IC numbers, types, and power-supply connections (pin numbers for Vcc and ground, for instance).
  • Include a title area near the bottom of the page, with name of circuit, name of instrument, by whom drawn, by whom designed or checked, date, and assembly number. Also include a revision area, with columns for revision number, date, and subject.
  • We recommend drawing schematics freehand on coarse graph paper (nonreproducing blue, 4 to 8 lines per inch) or on plain paper on top of graph paper. This is fast, and it gives very pleasing results. Use dark pencil or ink; avoid ball-point pen.

As an illustration, we've drawn a humble example (Figure E3) showing ``awful'' and ``good'' schematics of the same circuit; the former violates nearly every rule and is almost impossible to understand. See how many bad habits you can find illustrated. We've seen all of them in professionally drawn schematics! (Drawing the ``bad'' schematic was an occasion of great hilarity; we laughed ourselves silly.)

Figure E3 (A): An awful schematic

Figure E3 (B): A good schematic

Reprinted here as it seems it has disappeared from the original website and is only otherwise on a malware site. Cleansed of malware by putting it through text only transformation.

More resources:

Monday, April 24, 2023

Malaprops I've heard and read

What they said versus what they meant or should have meant to say:
For all intensive purposes - For all intents and purposes
Purport - comport
Problematic, problematical - a problem
Dynamical - dynamic
Illicit a response - elicit a response
Glance over - gloss over
Come to the foray - come to the fore
In toto - in total
In total - in toto
Inaction - in action
Prescribe to - subscribe to
Prescribe - proscribe
Insure - ensure
Contemporaneously - contemporary
Casual - causal
Good - well
Electronical - electronic
Deep seeded - deep seated
First seed - first seat
Pass time - pastime
Past time - pastime 
Colloquially - collectively
I'm not going to enact that labor - I'm not going to explain myself
Daring-do - derring-do
Hare's breath - hair's breadth
Interior motive - ulterior motive
Analogical - analog
Mute point - moot point
Digitalize - digitize
Palatable - palpable
Regulated - relegated
Hone in on - Home in on
Not put a fine tooth point on it - not to put too fine a point on it
Wizened - wise
Apart - a part
Clean-cut - clear-cut
Regimen - regime
Into - in to
Reticent - reluctant
Passably - passively
Went down - gone down
Fermented - fomented as in to foment rebellion or foment change
Wroten - written or wrote
Broughten - brought
Boughten - bought
Self-depreciating - self-deprecating
Pacific - specific
Conversating - conversing
Could of, should of, would of - could have, should have, would have
Orientated - oriented
Defying new standards - defining new standards
Lose - loose
Periodically - intermittently
Martyr - pariah
Eminent - imminent
Citate - cite
Complimentary - complementary
Compliment - complement
Degradate - degrade
Misunderestimated - underestimated
Characteristical - characteristic
Epitaph - epithet
Revelation - revolution
Effect - affect
Affect - effect
Is - are
Are - is
Went - gone
Dwell - delve
Cosigned to the past - consigned to the past
Dissidence - dissonance
Configurating - configuring
Saw - seen
Seen - saw
Aloud - allowed
Advice - advise
"cutting off her nose,in spite of herself" - Cut off her nose to spite her face

Of course, the perennial "your, you're" and "their, they're, there"