Doug Domke
Published © GPL3+

STEM - Build a Binary Counter from Relays

Use two relays to create a flip flop, then create a binary counter with 10 relays - a great way to introduce students to digital logic

IntermediateFull instructions provided6,170

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
DPDT 12 volt relay
×10
Relay module
×1
Prototype Board
×1
.01 Mfd ceramic capacitor
×1
2N2222 NPN transistor
×6
1800 ohm resistor
×6
100 K ohm resistor
×5
15 K ohm resistor
×1
Blue LED
×6
1" OLED Display
×1
22 gauge tinned copper wire
×1
24 volt, 2 amp DC power supply
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Binary Counter Schematic

Code

Arduino Code for Binary Counter

Arduino
/* This sketch provides pulses a relay based binary counter attached to pin 3.
 * It also reads the status of that counter using pins 5 - 10.
 * It displays the count on an OLED display.
 */
#include <ss_oled.h>  // library for OLED
#include <stdlib.h>  // needed for dtostrf to convert the count into a string for display

#define mySpeed 4  // counts/second;  speed can be 1-20 counts/sec.
// a 50 msec delay is built in waiting for settling and propagation before reading the count
// mySpeed adds additional delay to provide the specified speed, i.e. at 20 myDelay is 
// adding nothing to the 50 msec.

// set up parameters for OLED
#define SDA_PIN A4
#define SCL_PIN A5
#define RESET_PIN -1
#define OLED_ADDR -1
#define FLIP180 0
#define INVERT 0
#define USE_HW_I2C 0
#define MY_OLED OLED_128x64
#define OLED_WIDTH 128
#define OLED_HEIGHT 64

SSOLED ssoled;  // Create instance of OLED display

void setup() {
  // setup OLED
  oledInit(&ssoled, MY_OLED, OLED_ADDR, FLIP180, INVERT, USE_HW_I2C, SDA_PIN, SCL_PIN, RESET_PIN, 400000L);
  oledFill(&ssoled, 0x0, 1);
  oledWriteString(&ssoled, 0,2,1,(char *)"Weather Station", FONT_LARGE, 0, 1);
  // set pinmodes - 6 inputs and 1 output
  for (int j=5; j<11; j++){
    pinMode(j, INPUT);
  }
  pinMode(3, OUTPUT);
}

void loop() {
  int mycount;  // where count is stored
  char mystring[8];  // its string equivalent
  digitalWrite(3, HIGH);   // set pulse output high
  delay(50);  // wait msec. for all relays to reach their new status
  mycount=0; 
  // here is where we collect the status of our counter and turn it into a single integer value
  // note the first term in the line below is a 0.  No idea why, but the compiler didn't process this correctly until I added the 0.
  mycount =  0 + digitalRead(5) + (digitalRead(6)<<1) + (digitalRead(7)<<2) + (digitalRead(8)<<3) + (digitalRead(9)<<4) + (digitalRead(10)<<5);
  dtostrf(mycount, 6, 0, mystring); // convert mycount to a string we can display on the OLED
  oledWriteString(&ssoled, 0,3,3,(char *)mystring, FONT_16x16, 0, 1);  // output the count to the display
  delay((1000/mySpeed)-50);  // more delay, setting the total delay between counts to 250 msec.  or 4 counts per second
  
  // now set pulse output low and repeat everything above
  digitalWrite(3, LOW);  
  delay(50);
  mycount=0;
  mycount = 0 + digitalRead(5) + (digitalRead(6)<<1) + (digitalRead(7)<<2) + (digitalRead(8)<<3) + (digitalRead(9)<<4) + (digitalRead(10)<<5);
  dtostrf(mycount, 6, 0, mystring); 
  oledWriteString(&ssoled, 0,3,3,(char *)mystring, FONT_16x16, 0, 1);
  delay((1000/mySpeed)-50);
}

Credits

Doug Domke

Doug Domke

38 projects • 104 followers

Comments