Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Extending pins through the 74hc595 shift register


  • Please log in to reply
13 replies to this topic

#1 bildr

bildr

    New Member

  • Members
  • Pip
  • 7 posts

Posted 07 April 2011 - 01:08 PM

Hey guys, I run a site called bildr that documents electronics know-how. Our goal is to have all of our code examples written for the most popular microcontrollers. Recently we did an article on extending the pins on your arduino using the 74hc595 shift register http://bildr.org/2011/02/74hc595/ I wrote arduino code that will allow you to directly call digital pins on the shift register (even dozens chained together) like so: setRegisterPin(147, HIGH); and register pin number 147 (if you had 20 chained together) would go high. Im looking for anyone who could help translate this very simple arduino code for the netduino.

#2 Omar (OZ)

Omar (OZ)

    Advanced Member

  • Members
  • PipPipPip
  • 564 posts

Posted 07 April 2011 - 08:56 PM

Hey guys, I run a site called bildr that documents electronics know-how.
Our goal is to have all of our code examples written for the most popular microcontrollers.


Recently we did an article on extending the pins on your arduino using the 74hc595 shift register http://bildr.org/2011/02/74hc595/

I wrote arduino code that will allow you to directly call digital pins on the shift register (even dozens chained together) like so: setRegisterPin(147, HIGH); and register pin number 147 (if you had 20 chained together) would go high.

Im looking for anyone who could help translate this very simple arduino code for the netduino.


First of all welcome to the community!
Very nice post you made there, if you could tell us what you used to make the schematics/diagrams that would be awesome, I really liked those.
Now to what came for :) : http://forums.netdui...gister-example/ there is some code I posted to show how to use a shift register with the netduino, I hope that helps... let me know if you require more assistance.

#3 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 07 April 2011 - 09:32 PM

If you're patient, I'm working on a set of classes which works like this:
Ic74HC595 IcOut1 = new Ic74HC595(SPI_Devices.SPI1, Pins.GPIO_PIN_D10);
Ic74HC595 IcOut2 = IcOut1.LinkedSlave();
Ic74HC595 IcOut3 = IcOut2.LinkedSlave();

// Observant readers will notice the pins are prefixed GPO instead of GPIO.
// This is because the pins can only function as output pin.
OutputPortShift[] pin = {
    new OutputPortShift(IcOut1, Ic74HC595.Pins.GPO_PIN_D0, false),
    new OutputPortShift(IcOut1, Ic74HC595.Pins.GPO_PIN_D1, false),
    new OutputPortShift(IcOut1, Ic74HC595.Pins.GPO_PIN_D2, false),
    new OutputPortShift(IcOut1, Ic74HC595.Pins.GPO_PIN_D3, false),
    new OutputPortShift(IcOut1, Ic74HC595.Pins.GPO_PIN_D4, false),
    new OutputPortShift(IcOut1, Ic74HC595.Pins.GPO_PIN_D5, false),
    new OutputPortShift(IcOut1, Ic74HC595.Pins.GPO_PIN_D6, false),
    new OutputPortShift(IcOut1, Ic74HC595.Pins.GPO_PIN_D7, false),
    
    new OutputPortShift(IcOut2, Ic74HC595.Pins.GPO_PIN_D0, false),
    new OutputPortShift(IcOut2, Ic74HC595.Pins.GPO_PIN_D1, false),
    new OutputPortShift(IcOut2, Ic74HC595.Pins.GPO_PIN_D2, false),
    new OutputPortShift(IcOut2, Ic74HC595.Pins.GPO_PIN_D3, false),
    new OutputPortShift(IcOut2, Ic74HC595.Pins.GPO_PIN_D4, false),
    new OutputPortShift(IcOut2, Ic74HC595.Pins.GPO_PIN_D5, false),
    new OutputPortShift(IcOut2, Ic74HC595.Pins.GPO_PIN_D6, false),
    new OutputPortShift(IcOut2, Ic74HC595.Pins.GPO_PIN_D7, false),
    
    new OutputPortShift(IcOut3, Ic74HC595.Pins.GPO_PIN_D0, false),
    new OutputPortShift(IcOut3, Ic74HC595.Pins.GPO_PIN_D1, false),
    new OutputPortShift(IcOut3, Ic74HC595.Pins.GPO_PIN_D2, false),
    new OutputPortShift(IcOut3, Ic74HC595.Pins.GPO_PIN_D3, false),
    new OutputPortShift(IcOut3, Ic74HC595.Pins.GPO_PIN_D4, false),
    new OutputPortShift(IcOut3, Ic74HC595.Pins.GPO_PIN_D5, false),
    new OutputPortShift(IcOut3, Ic74HC595.Pins.GPO_PIN_D6, false),
    new OutputPortShift(IcOut3, Ic74HC595.Pins.GPO_PIN_D7, false)
};

while (true)
{
    // Loops all leds to the right
    for (var OutputPortCount = 0; OutputPortCount < pin.Length; ++OutputPortCount)
    {
        pin[OutputPortCount].Write(true);
        Thread.Sleep(50);
        pin[OutputPortCount].Write(false);
    }
    // Loops all leds back to the left
    for (var OutputPortCount = pin.Length - 2; OutputPortCount > 0; --OutputPortCount)
    {
        pin[OutputPortCount].Write(true);
        Thread.Sleep(50);
        pin[OutputPortCount].Write(false);
    }
}

The code isn't yet ready to be released and I hoped I could find some time today for it but I failed to do so :)
But I think it will be ready for release in less then a week.

The reason I won't release it yet is because I'm also working on support for the 74hc165, and that's not finished yet.
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#4 bildr

bildr

    New Member

  • Members
  • Pip
  • 7 posts

Posted 07 April 2011 - 10:58 PM

Thank you very much.
All of the illustrations are done in adobe illustrator. I have a ton of parts that I have drawn up. They are all released as CC BY-SA 3.0 if you would like them. I can post a PDF.


Thanks, Ill check out the code.

I see
Cpu.Pin latch = Pins.GPIO_PIN_D10

I assume that means digital pin 10. So could I do:

SER_Pin = Pins.GPIO_PIN_D8; //pin 15 on the 75HC595
RCLK_Pin = Pins.GPIO_PIN_D9; //pin 12 on the 75HC595
SRCLK_Pin = Pins.GPIO_PIN_D10; //pin 10 on the 75HC595

Then can I set the pin high like so: SRCLK_Pin = 1; // ??



First of all welcome to the community!
Very nice post you made there, if you could tell us what you used to make the schematics/diagrams that would be awesome, I really liked those.
Now to what came for :) : http://forums.netdui...gister-example/ there is some code I posted to show how to use a shift register with the netduino, I hope that helps... let me know if you require more assistance.



#5 bildr

bildr

    New Member

  • Members
  • Pip
  • 7 posts

Posted 07 April 2011 - 11:03 PM

Thanks.
Im hoping to have all the code examples as similar as possible so the rest of the article can stay almost the same.
The really great thing about the netduino, is I dont even need to change the diagram as long as the code connects to the same pins.


If you're patient, I'm working on a set of classes which works like this:


The code isn't yet ready to be released and I hoped I could find some time today for it but I failed to do so :)
But I think it will be ready for release in less then a week.

The reason I won't release it yet is because I'm also working on support for the 74hc165, and that's not finished yet.



#6 Omar (OZ)

Omar (OZ)

    Advanced Member

  • Members
  • PipPipPip
  • 564 posts

Posted 07 April 2011 - 11:45 PM



SER_Pin = Pins.GPIO_PIN_D8; //pin 15 on the 75HC595
RCLK_Pin = Pins.GPIO_PIN_D9; //pin 12 on the 75HC595
SRCLK_Pin = Pins.GPIO_PIN_D10; //pin 10 on the 75HC595

Then can I set the pin high like so: SRCLK_Pin = 1; // ??


[http://www.netduino....uino/specs.htm] - "digital pins 11-13: SPI MOSI, MISO, SPCK"
SPI is 10 for RCLK_Pin, 11 for SER_Pin, and 13 for SRCLK_Pin.

the SPI setup shown in my code is to use those pins that are for spi... and you can just start the SPI port like I did and write byte arrays to it.

to make a digital output pin and make it go HIGH do this:

OutputPort name = new OutputPort(Pins.GPIO_PIN_D0, false) // false is start LOW, use true to start HIGH. for pin 0 on netduino

name.Write(true); // true for high.

the SPI class takes care of the timing though...

remember you write to SPI with byte arrays. but if you want to call each individual pin that become avialible by adding the shift register Stefan's code might suit your needs best...

#7 bildr

bildr

    New Member

  • Members
  • Pip
  • 7 posts

Posted 08 April 2011 - 04:07 AM

Thanks again. That explanation and Looking over your code helped a lot.


I seriously doubt this works. And it is a bit of a pain programming for hardware you dont own. But I think this is at least 80% there.
The biggest issue I didnt know was hot to (if possible) to create a boolean array. boolean because it uses less than an int array.

Do arrays need to define the size or type? like: int array[300]

I also didnt know if I should be using "this" to call methods in the class, or be accessing class variables.

And can you leave a varable undefined, or should you do: int thestInt = new Int();


ShiftExtender extendo = new ShiftExtender(1); //how many registers are chained together?

while (true){
	extendo.setRegisterPin(2, true);
	extendo.setRegisterPin(3, true);
	extendo.setRegisterPin(4, false);
	extendo.setRegisterPin(5, true);
	extendo.setRegisterPin(7, true);
	
	extendo.writeRegisters();  //MUST BE CALLED TO DISPLAY CHANGES
	//Only call once after the values are set how you need.
}
    

		



public class ShiftExtender{
	
	//Will store how many of the shift registers - to calculate number of pins
	private int number_of_74hc595s;
	
	private int numOfRegisterPins;
	
	////////////////////////////////////////////////////////////////////////
	private bool registers[]; //boolean array - NOT SURE HOW TO DO THIS
	////////////////////////////////////////////////////////////////////////
	
	private OutputPort SER_Pin;
	private OutputPort RCLK_Pin;
	private OutputPort SRCLK_Pin;
	
	
	
	public ShiftExtender(int _74hc595s = 1){
	
		number_of_74hc595s = _74hc595s;
		numOfRegisterPins = (number_of_74hc595s * 8);
	
	
		SER_Pin = new OutputPort(Pins.GPIO_PIN_D2, false); //SER pin on Digital 2
		RCLK_Pin = new OutputPort(Pins.GPIO_PIN_D3, false); //RCLK pin on Digital 3
		SRCLK_Pin = new OutputPort(Pins.GPIO_PIN_D4, false); //SRCLK pin on Digital 4
		
		//reset all register pins
		clearRegisters();
		writeRegisters();
	  
	}


	//Set and display registers
	//Only call AFTER all values are set how you would like (slow otherwise)
	public void writeRegisters(){
	
		RCLK_Pin.Write(false); // Set the register-clock pin low
		
		for(int i = numOfRegisterPins; i >  0; i--){
		
			SRCLK_Pin.Write(false); // Set the serial-clock pin low
		
			bool val = registers[i];
			SER_Pin.Write(val);
		
			SRCLK_Pin.Write(true); // Set the serial-clock pin high
		
		}
		
		RCLK_Pin.Write(true);// Set the register-clock pin high to update the output of the shift-register
	}
	
	
	//set all register pins to 0
	public void clearRegisters(){
	  for(int i = numOfRegisterPins; i >  0; i--){
		 registers[i] = 0;
	  }
	} 
	
	
	//set an individual pin true or false
	public void setRegisterPin(int index, bool value){
	  registers[index] = value;
	}    
    
}
		
		
		






#8 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 08 April 2011 - 06:20 AM

Thanks.
Im hoping to have all the code examples as similar as possible so the rest of the article can stay almost the same.

True, the reason of my setup got some thoughts though. I don't only use them for extending pins but it's also still possible to use, for example, 3 IC's as pin extenders and 1 IC as LCD driver in the same serie. That's why every IC will be a seperate class in my code, so they can also fit multiple purposes.

Then the reason I chose for an OutputPortShift class, I did this to make it as much as possible compatible with the calls for the Netduino onboard pins.

I seriously doubt this works. And it is a bit of a pain programming for hardware you dont own. But I think this is at least 80% there.


You really should get the hardware to test it ;)

The biggest issue I didnt know was hot to (if possible) to create a boolean array. boolean because it uses less than an int array.

Do arrays need to define the size or type? like: int array[300]


//This creates a boolean array with 300 values (0 to 299)
bool BoolArray = new bool[300];
They do need a defined size indeed.

By the way, why aren't you using the built in SPI feature? It will take care of the SS and CLCK pin for you at a high and constant speed.
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#9 Troll feeder

Troll feeder

    Advanced Member

  • Members
  • PipPipPip
  • 38 posts
  • LocationArizona, USA

Posted 08 April 2011 - 06:41 AM

Funny thing was I was working on almost the same code, 74HC595 S-P shift registers for driving a display from Pargraph. You have to drive 2 color LEDs per bar x28 bars. There are only 4 reg and 4 green inputs. So unless you use a registor to drive a 595 for CS lines you need a lot of lines and a lot of 595s. So I see a lot of good thoughts here.

#10 bildr

bildr

    New Member

  • Members
  • Pip
  • 7 posts

Posted 08 April 2011 - 12:24 PM

True, the reason of my setup got some thoughts though. I don't only use them for extending pins but it's also still possible to use, for example, 3 IC's as pin extenders and 1 IC as LCD driver in the same serie. That's why every IC will be a seperate class in my code, so they can also fit multiple purposes.

Then the reason I chose for an OutputPortShift class, I did this to make it as much as possible compatible with the calls for the Netduino onboard pins.


Your class sounds like it is going to be really awesome. This class is really just to control 1800 LEDs if someone wanted to.



You really should get the hardware to test it ;)


Yeah, I should. It's just really hard to write one of these blog posts every week, run the site, and try to promote it all at the same time. Now I have to start buying other MCs so I can lean to translate the code as well. - It is the best way I know. I just hope in the future to have help with some of it.

I just use arduino a lot at work, so I in a way get paid to learn that. Time is not my friend. :)


They do need a defined size indeed.


Thanks!


By the way, why aren't you using the built in SPI feature? It will take care of the SS and CLCK pin for you at a high and constant speed.


Would you believe it is because I don't know what I doing?
Im actually a designer who wanted electronics to be easier. So I decided to go out an learn as much as I could to then come back with good documentation and easier ways of working. I just haven't gotten to SPI yet. ( been spending all my time in I2C )

Time to go read up on SPI.

#11 bildr

bildr

    New Member

  • Members
  • Pip
  • 7 posts

Posted 08 April 2011 - 12:57 PM

Ok... So reading up, the potential issue with using SPI is that the ethernet shield (on arduino) also uses it. So if I required it, and a user wanted to use this and the ethernet shield there could be an issue I believe. (the ethernet shield has an issue letting go of MOSI) Though it does look like it would be a ton faster. Right now, it takes about 1ms per 10 959's (80 pins) I have chained together on an arduino.

#12 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 08 April 2011 - 01:12 PM

Would you believe it is because I don't know what I doing?

Never said that, was only asking why it was done that way. Performance is a very good reason. All I needed to know ;) You post your code, hoping for feedback, so I give it, hoping to help you in a positive way. We could learn of each other's approach!

Problem that can occure is if there are multiple devices on the SPI bus it could conflict. The NETMF SPI class can prevent that (although that class has it's flows itself)

Not only the ethernetshield uses SPI, there are many devices that could use the same bus. SD, Ethernet, all kinds of bitshift IC's, led drivers, etc.
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#13 bildr

bildr

    New Member

  • Members
  • Pip
  • 7 posts

Posted 08 April 2011 - 03:57 PM

No... I'm saying I don't know what im doing :)

From what I have read, you can use SPI for many devices at once, but specifically the Wiznet ethernet board used on the arduino ethernet shield has issues sharing the MOSI. But I haven't tried this myself.

I really do appreciate the help, I don't want to come off as defensive or offensive at that.

The original reason for not using SPI, was because I just didn't know it existed or was an option. I does look like the right way to go.
Ill do some testing with the SPI interface on arduino with this and see what kind of speed benefit I can get. Maybe Ill put that in the tutorial if it works out.

I think I may need to go buy a netduino/pic/AVR board so I can test them all.


Never said that, was only asking why it was done that way. Performance is a very good reason. All I needed to know ;) You post your code, hoping for feedback, so I give it, hoping to help you in a positive way. We could learn of each other's approach!

Problem that can occure is if there are multiple devices on the SPI bus it could conflict. The NETMF SPI class can prevent that (although that class has it's flows itself)

Not only the ethernetshield uses SPI, there are many devices that could use the same bus. SD, Ethernet, all kinds of bitshift IC's, led drivers, etc.



#14 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 08 April 2011 - 06:30 PM

No... I'm saying I don't know what im doing :)

Hehe so we had a small miscommunication. I must confess english is only my second language.

From what I have read, you can use SPI for many devices at once, but specifically the Wiznet ethernet board used on the arduino ethernet shield has issues sharing the MOSI. But I haven't tried this myself.

I could understand the board takes quite some priority on the SPI bus, but with a decent SPI driver it should be possible to share it at all time. I know some people on this board used the wiznet with a netduino, perhaps they can respond on that.

I think I may need to go buy a netduino/pic/AVR board so I can test them all.

You won't regret it :)
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.