Tuesday 11 February 2014

42. Working with the 74193 - 4 bit binary up/down counter.

The 74193 is quite a useful IC to have in your collection.  It can count up or down in binary from 0000 to 1111.  You can reset the value to zero, you can pre-set the start value (useful as a buffer when not used as a counter) and if you count above or below the four bits it can flag a carry or borrow condition. This last bit is quite important as it means you can daisy chain lots of 74193s together to count with 8, 12, 16 bits and so on.

The pins are:

16 Vcc        Input Voltage
 8 GND        Ground

15 A      IN  Input Bit 0
 1 B      IN  Input Bit 1
10 C      IN  Input Bit 2
 9 D      IN  Input Bit 3

11 LOAD   IN  Load Inputs   - Inactive state HIGH.  Go LOW/HIGH to load inputs.

 3 QA     OUT Output Bit 0
 2 QB     OUT Output Bit 1
 6 QC     OUT Output Bit 2
 7 QD     OUT Output Bit 3

14 CLEAR  IN  Reset Outputs - Inactive State LOW.  Go HIGH/LOW to reset.

 4 DOWN   IN  Count Down    - Inactive state HIGH.  Go LOW/HIGH to count down.
 5 UP     IN  Count Up      - Inactive State HIGH.  Go LOW/HIGH to count up.

13 BORROW OUT Count has gone below 0000.  Connect this to DOWN of IC below.
12 CARRY  OUT Count has gone above 1111.  Connect this to UP of IC above.

In this example below I have daisy chained 3x Philips 74HC193Ns together to produce a 12 bit value:



The red jump wires are connected to the UP input. Initially from an Arduino UNO providing a simple pulse with a 100ms delay, then from the CARRY to the UP of the next IC.

A/B/C/D and BORROW are not connected. LOAD and DOWN connected to +5V as I'm not going to load a value and I am not going to count down.

Just to show how this works I connect the outputs to some red LEDs followed by some inline 1K resistors (which are hidden behind the LEDs in the picture).

Using this method, these 3x 74193s create a 12 bit address line which could be used help program or read a 4K by 8 bit EEPROM.



Here's the Arduino code to pulse the 74193:
/*
  74193 Synchronous 4 bit binary up/down counter
*/

int RESET = 2;    // Connect to Pin 14 on the IC
int COUNT_UP = 3; // Connect to Pin  5 on the IC

void setup() {
  
  // Initialise Pins
  pinMode(RESET,OUTPUT);
  pinMode(COUNT_UP,OUTPUT);
  
  // Set default pin states
  digitalWrite(COUNT_UP,HIGH);
  digitalWrite(RESET,LOW);
  
  // Perform a reset.  Clears outputs to low state i.e. 0000
  digitalWrite(RESET,HIGH);
  digitalWrite(RESET,LOW);

}

void loop() {
  
  // Clock Up Pulse
  digitalWrite(COUNT_UP,LOW);
  digitalWrite(COUNT_UP,HIGH);
  delay(100);

}

Friday 31 January 2014

41. PS/2 Keyboard Test

Now a computer is no good, unless you can type something into it.  Although it is possible to read a USB keyboard you need additional hardware if you are just using an Arduino UNO.  However there is an Arduino library for PS/2 Keyboards. I found it at http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html.  You'll need to add it to the Arduino IDE Libraries. Click on Sketch->Import Library->Add Library...

All I needed now was a PS/2 Keyboard as all my keyboards are USB these days.  Fortunately they can still be found in plentiful supply at your favourite online stores.

Of course, with s PS/2 keyboard you need a PS/2 socket to plug it in.  I had an old motherboard and a hot air gun soon melted the solder to free it from the main board.  Now to make it breadboard friendly.

You only need 4 pins.  +5V, GND, Clock and Data.  See http://en.wikipedia.org/wiki/PS/2_port for details of the pin outs.  I used a continuity tester to check which pins underneath matched which ps/2 port inputs and soldered on four jump wires.



Using just the LiquidCrystal library and the PS2Keyboard library, I was able to write all over my 20x4 LCD display.

The PS2Keyboard library defaults to US layout doesnt have the UK layout defined so I might tweak that later.

Heres the code:
#include <LiquidCrystal.h>

#include <PS2Keyboard.h>

LiquidCrystal lcd(10,9,8,7,6,5,4);
PS2Keyboard keyboard;
const int DataPin = 3;
const int IRQpin =  2;

int row=1;
int col=0;

void setup() {
  // put your setup code here, to run once:
  delay(1000);
  keyboard.begin(DataPin, IRQpin);
  lcd.begin(20,4);
  lcd.print("Keyboard Test");
  //lcd.cursor();
  lcd.blink();
  lcd.setCursor(col,row);

}

void loop() {
  // put your main code here, to run repeatedly: 
  if (keyboard.available()) {
    
    // read the next key
    char c = keyboard.read();
    
    // check for some of the special keys
    if (c == PS2_ENTER) {
      col=0;
      row=row+1;
    } else if (c == PS2_ESC) {
      lcd.clear();  // clear screen if ESC is pressed.
      col=0;
      row=0;
    } else if (c == PS2_LEFTARROW) {
      col=col-1;
    } else if (c == PS2_RIGHTARROW) {
      col=col+1;
    } else if (c == PS2_UPARROW) {
      row=row-1;
    } else if (c == PS2_DOWNARROW) {
      row=row+1;
    } else if (c == PS2_DELETE) {
      col=col-1;
      lcd.setCursor(col,row);
      c=32;
      lcd.print(c);
      lcd.setCursor(col,row);
    } else {
      
      // otherwise, just print all normal characters
      lcd.print(c);
      col=col+1;
   }
   if (col>19) {
     col=0;
     row=row+1;
   }
   if (col<0) {
     col=19;
     row=row-1;
   }
   if (row>3) row=0;
   if (row<0) row=3;
  }
  lcd.setCursor(col,row);
}

Monday 20 January 2014

40. A foray with I²C

It's been a while since I built something that didn't come in a kit.

I've had a RTC (Real Time Clock) chip (PCF8563) in my collection for a while as I wanted to get to grips with I²C.

I²C is a protocol for allowing ICs to communicate via a 2 wire interface.  One wire is the clock (SCL) and the other is the data (SDA).  This saves on the number of connections and also simplifies circuit design.

My early experiments writing bit bashing code on a PIC to speak I²C ended up fruitless and I thought I had missed some vital information.  Needless to say, it put me off for a bit.  I got other people's code to work on the PIC but I wanted to understand it because I thought it might be cool to get the Z80 to talk to a RTC.

However, the Arduino boards have a dedicated I²C interface and library code that makes it a piece of cake to get started.  So I dug out the PCF8563 and started coding.  Fortunately there was even code examples for Arduino using the PCF8563. Once you've seen how the code should be written its a lot easier to roll your own.

So I got the RTC clock wired up, and added my 16x2 LCD and in no time had a clock working.  It seemed a bit too easy, so I wondered what else I could connect to the I²C bus.  I found the DS1631 temperature/thermostat IC.

Each I²C device has a different address.  I don't know how unique they are as there are only 128 addresses available.  Bit 0 is used to signify read or write.  Luckily the RTC and Temp IC are different.

Needless to say it wasn't to hard to talk to the DS1631 as well using the Wire library and display the temperature.

To spice things up a bit more I wanted to divorce the ATMega328P from my Arduino Uno and put it directly on the breadboard.  This needed an additional 16MHz crystal and 2x 22pF capacitors.

Lastly a battery backup for the RTC clock which is quite easy to connect by using diodes to make sure the current goes in the right direction.

The software allows you (via the 2 buttons) to set the date and time and set a thermostat temperature, which when reached lights the red LED via a 1K resistor at the bottom.  In fact the DS1631 will operate on its own once configured to control a heating system.

Update: somehow the 1K resistor was a 47 ohm.  I noticed that when the thermostat temperature was reached and the LED lit up the temperature would go back up again.  It seems without much resistance on the output it causes the IC to warm up due to the current flow.  What I have done now it put a 10k resistor and fed that into a BC548B transistor to light the LED.


39. Time on my hands.

I bought this watch kit from Cool Components.  Easy to solder and assemble.  I realised afterwards that I could customize the PIC chip as the source code is available.   I prefer a 24 hour clock, and this is programmed just to display the 12 hour clock.  But its still a great watch and wearing it about at work has become a conversation piece.