how do you control a 74ls299 with an arduino

Thread Starter

matelot

Joined Apr 15, 2013
43
I am trying to get a 74ls299 working from an arduino.
I have succeeded to get it to light 4 leds and switch them on and off from the arduino, I am now trying get it to 'see' 4 switches on the other 4 i/o pins so I can read them from the arduino. My ultimate goal is to be able to get it to do both these at once.
I am having problems reading the register, I think what I am getting is the info from the first gate only, if I switch the first switch the signal that should show the condition of all four gates just reflects the condition of the first switch i.e. high when it is on and low when it is off as if the clock pulse isn't working.
I have tried to attach a picture of my connections.
Would someone mind helping me to understand what connections the 74ls299 needs to be able to read from the i/o's in parallel and send the info out of which serial port (s0 or s7).
 

Thread Starter

matelot

Joined Apr 15, 2013
43
no the basic hook ups are not the same . I have been trying to do this for a few weeks now.
I can happily control a hct 4021 to do what I want with respect to switches inputting an arduino and 74ls595 with leds outputting from an arduino but a 74ls299 is quite different.
 

Papabravo

Joined Feb 24, 2006
21,228
You're right it is quite different. What you can't do with this part is parallel load only 4-bits from the I/O pins. When you do a parallel load it is all 8 bits. This is the wrong part to use for 4-in 4-out. If you want to use the part then you should have two of them; one for input and one for output.

On the input device you keep the output drivers tri-stated all the time by wiring OE* to GND.

On the output device you setup the outputs by shifting serial data then enabling the OE*. If you don't do this the LEDs may blink as you are shifting serial data.

What you want is for the outputs to remain stable while you read and shift the input bits. Then you want to update the output bits by shifting them into a register, then loading them in parallel, then enabling the outputs. The 74LS299 is the WRONG part for the job.

Checkout the 74LS595 for the outputs and the 74LS165/74LS166 for the inputs
 
Last edited:

Thread Starter

matelot

Joined Apr 15, 2013
43
I am just trying to get the chip to send the pin information serially back to the arduino at the moment. I can do it with a hct4021 but the pin configuration is so different, with a 299 I can't get it to work.
Do you know which pins of the chip have to be in which state to read the signals on each i/o and then let the arduino read the info on the serial out pins?
 

alexfreed

Joined Oct 8, 2012
72
This CAN be done with 299, except that the LEDs will blink while reading the switches.
On your picture the S0 and S1 are always high. This is the parallel load mode. The switches will be loaded into the register on the positive edge of the clock. Now if you now set S1 low and send a clock pulse, data will shift right. So if you do an 8 bit SPI transfer the 4 switch bits (and 4 garbage bits) will be read by the CPU and new 8 bits set in the register. While this happens the LEDs will be off as the outputs are disabled (OE1 and OE2). Now enable the outputs to light up the LEDs. And make sure the switches have resistors in series - you don't want to short enabled outputs via the switches. Or you can only transfer 4 bits at a time setting the LED bits and at the same time reading the switch bits.
Look at the truth table in the data sheet.
 

Thread Starter

matelot

Joined Apr 15, 2013
43
many thanks for that alex. I have now got the 299 connected to switches and monitoring the switches in the arduino shows I can alter them.
I believed that putting s0 and s1 high put the chip in the parallel input mode so that was where it needed to be to do a parallel input action, it didn't occur to me to put it back after reading the i/o pins so the info could be transfered down the serial out lines.

I take your point about putting resistors on the switches, I hadn't realised that would have been a problem, I was intending getting four bits of info from another source (the railway signals supply), adding four extra bits that would all be low and sending that, the low bits would be where the switches are.
As the system is only working in slow time, a delay of a second wouldn't cause any problem whatsoever, updating can be quite infrequent so the out time of the led's would be minor.

You mention
Rich (BB code):
Or you can only transfer 4 bits at a time setting the LED bits and at the same
 time reading the switch bits.
I can't find any reference in the data sheets for this? would this allow me to split the data into two packets, effectively, one for the read phase and one for the write phase? Would this solve the problem of the led's being out during the switch phase and would you mind giving me an idea how to do this?
thanks,
Bob.
 

alexfreed

Joined Oct 8, 2012
72
If you are using hardware SPI registers of the AVR you can't do a 4 bit transfer. But you can do it by "bit banging". Basically toggling the clock and shifting in the data. Look up "software SPI". Doesn't buy you anything if you use hard SPI.

Now if your switches are between the I/O pins of the 299 and the ground, you can always add pull-up resistors to VCC and no extra resistors are needed as long as you always WRITE 0000 into the high 4 bits during the SPI operation. Or add 4 resistors, say 1K and you don't care if the outputs are high or low. I always design this way. Software can malfunction. Shouldn't cause the magic smoke to escape from the hardware.
 

Papabravo

Joined Feb 24, 2006
21,228
You will always have to tri-state the output drivers to the LEDS when you read the inputs. In order to avoid this you need output latches like on the 74LS595. You may not realize you are doing this with the 74LS299 because S1 and S0 affect the output buffers as well as OE1 and OE2. It's a hard part to get your head around -- probably why I never had occasion to use one.
 

Thread Starter

matelot

Joined Apr 15, 2013
43
Thanks Alex,
my switches were connected with 10k resistors on the i/o pins to 0v and the switches to 5v. I have added 1k resistors to the switch input side (between switch and 5v) as you recommend and the circuit still works fine.
I am now going to try to write a sketch involving both the input and output at the same time and see if I can get the switches to control the lights, I think my first investigation is how to move the first 4 bits of an 8 bit byte to the second four? I will have a play with it, that is really what I am interested in at the moment, discovering for myself if I can do it.
It is good to know if I do get stuck there are people like yourself who are willing to help. I will keep this thread informed.
Thanks,
Bob.
 

alexfreed

Joined Oct 8, 2012
72
Not sure I understand the part about "how to move the first 4 bits of an 8 bit byte to the second four", but if we are talking about the software here, there is of course a shift operation that can be done 4 times, or multiplying a value by 16 (a single operation on AVR) does the same thing.
 

Thread Starter

matelot

Joined Apr 15, 2013
43
if I am going to use the chip for both send and receive I will put 4 i/o pins on switches and 4 on leds.
I will then read the data from the shift register (all 8 pins) consisting of the information from the 4 switches and 4 pins connected to the leds.
If the 4 switches are on the first 4 pins, i/o pins 0 to 3 , then I will have to move the info from the 4 lowest bits to the four highest bits into another variable, move the data back to the chip and display it on the other 4 pins, 4 to 7.
If I load the data in as MSB it loads to one end of the byte and LSB loads to the other so that alone might be enough. i.e. 00001111 if all on and LSB or 11110000 if all on and MSB
I will see tomorrow if I can get that to light the switches.
 

Thread Starter

matelot

Joined Apr 15, 2013
43
I've done it. I've done it.
MY problem and the one that has kept me stumped for a long time is the fact that I have had to hold the program for 1/4 of a second in the 'outputs showing' state.
I assume this is the fact that without the 250 millisecond delay at the start the leds are flashing on and back off so fast you can't see them. With the delay they look to be on constant. I am happy to be corrected.:rolleyes:
Rich (BB code):
/* set up 74ls299 with 
pin1 - S0      latchpinin         pin20 - vcc
pin2 - OE1     latchpinout        pin19 - S1      high
pin3 - OE2     latchpinout        pin18 - DS 7    datapinout
pin4 - I/O 6   sw2                pin17 - Q 7     n/c
pin5 - I/O 4   sw4                pin16 - I/O 7   sw1
pin6 - I/O 2   led3               pin15 - I/O 5   sw3    
pin7 - I/O 0   led1               pin14 - I/O 3   led4   
pin8 - Q 0     datapinin          pin13 - I/O 1   led2    
pin9  - MR     high               pin12 - CP      clockpin
pin10 - 0V                        pin11 - DS 0    n/c
MR is held high as is S1. Outputs to LED's to 0v via resistors.
put PINS 16, 4, 15, 5, to 0v bias (with 10k to 0v) other side of switches
connected to 5v via 1k resistors.*/
const int dataPinin   =  6;   //299 pin 08      (Q0)
const int latchPinin  =  7;   //299 pin 01      (S0)
const int dataPinout  =  8;   //299 pin 18      (Ds7)
const int latchPinout =  9;   //299 pin 2 & 3   (OE1&OE2)
const int clockPin    = 10;   //299 pin 12      (CP)
int myinput;
void setup(){
  Serial.begin(9600);
  pinMode(latchPinin,  OUTPUT); 
  pinMode(dataPinin,    INPUT);
  pinMode(dataPinout,  OUTPUT);
  pinMode(latchPinout, OUTPUT);
  pinMode(clockPin,    OUTPUT);
}
void loop() {
  delay(250);
  digitalWrite       (latchPinin,HIGH);//set it to 1 to collect parallel data  
  digitalWrite       (clockPin,HIGH);//read info from i/o pin  
  delayMicroseconds  (20);             //pause to let digitalWrite finish
  digitalWrite       (latchPinin,LOW); //set it to 0 to transmit data serially 
  delayMicroseconds  (20);             //pause to let latch go low
  myinput = shiftIn (dataPinin, clockPin, MSBFIRST);//read register
  for (int a=0;a<8;a++)
  { 
    Serial.print (bitRead (myinput,(7-a)));//bit read the contents of myinput so
                                  //that it maintains leading '0's for the screen
  }
  Serial.println();
  digitalWrite (latchPinout, HIGH);//set output shift registers to receive serial
                                   //data  
  shiftOut (dataPinout, clockPin, LSBFIRST, myinput); //Send data
  digitalWrite (latchPinout, LOW); //set output shift registers to drive leds
}
The code swaps the inputs round by reading MSB and feeds it back to LSB so it actually goes back from the last bit first but that doesn't matter, I just wire it up that way.
The one advantage over two chips is I am only using 5 wires, plus 2 for power instead of 6 that two chips would use.
Now lets see if I can convert it to use two chips in series.
Quite proud of myself now.;)
 

alexfreed

Joined Oct 8, 2012
72
Not sure I understand a need for 6 wires with 2 chips. One is serial in / parallel out shift register, say 74HC594. You only need a serial out (from AVR) and a clock to drive all 8 outputs.
The other is a Parallel-In/Serial-Out, say 74HC165. You need a clock, parallel load and serial
in. Total of 5 wires, and the clock can be common if you always set the output in the SPI register before reading the input.
 

Thread Starter

matelot

Joined Apr 15, 2013
43
I think you are slightly wrong there, the 594 still needs a latch wire to change it from 'read parallels' to 'ready to send serial' so with clock and data it needs 3 wires.
I am not sure if I could use the clock for both chips, the chip is read or written to with shiftin and shiftout, these instructions deal with when the clock pulse is sent and doing shiftin to one chip will also send clock pulses to the other when I am not doing a shift out? Am I right?

I keep saying I could do it with a 595 and a 4021 which I already have programs for, that would use six wires if I need two clocks.
I just wanted to see if I could do it with one chip which uses five wires and I have.

Each signal head has four leds plus a sensor so the signal needs to be four signals in and one out, hence two directions.

Now I have done that I will link four signal heads in series, so the controller will just have five wires (or i/o pins on the arduino) plus 5v and 0v for the whole thing.

I am not so much interested in the finished product but the pleasure of getting there.
The club is the Society of Model and Experimental Engineers, see
http://www.sheffieldsmee.co.uk/
with emphasis on the experimental. I do the signaling and point control maintenance for the layout.
 

alexfreed

Joined Oct 8, 2012
72
OK, sorry. Indeed the 594 has a latch which is good to never have wrong LEDs light up,
but there are others like 74HC164 where the shifted data is immediately available at the outputs. And BTW the latch input of the 594 could also be shared with the latch for the parallel input register if absolutely needed.

So here is one way to implement it. The MOSI pin of an AVR goes to serial input of the 594. MISO - to serial output of 74HC165. SPI clock is shared. For simplicity 2 more signals for the IN and OUT latches.

So you pulse the /PL on 165 to load the state of up to 8 switches. Load the SPI register with 8 bits of LED data and do an SPI transfer. Send a pulse to the output latch if there is one. In case of using a latch-less 164 the SPI operation only takes a few microseconds so LEDs won't be in a wrong state for long. Read the 8 switch bits from the SPI.
This way up to 8 in and 8 out bits with 4 or 5 wires.
 
Top