Extending pins through the 74hc595 shift register
#1
Posted 07 April 2011 - 01:08 PM
#2
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.
- Arron Chapman likes this
#3
Posted 07 April 2011 - 09:32 PM
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.
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs
#4
Posted 07 April 2011 - 10:58 PM
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
Posted 07 April 2011 - 11:03 PM
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
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
Posted 08 April 2011 - 04:07 AM
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
Posted 08 April 2011 - 06:20 AM
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.Thanks.
Im hoping to have all the code examples as similar as possible so the rest of the article can stay almost the same.
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.
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs
#9
Posted 08 April 2011 - 06:41 AM
#10
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
Posted 08 April 2011 - 12:57 PM
#12
Posted 08 April 2011 - 01:12 PM
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!Would you believe it is because I don't know what I doing?
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.
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs
#13
Posted 08 April 2011 - 03:57 PM
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
Posted 08 April 2011 - 06:30 PM
Hehe so we had a small miscommunication. I must confess english is only my second language.No... I'm saying I don't know what im doing
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.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.
You won't regret itI think I may need to go buy a netduino/pic/AVR board so I can test them all.
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users