Go Down

Topic: LEDS and 74HC595 shift register (Read 11031 times) previous topic - next topic

John_Ryan

Quote
just wanted to say good job on all your work put into this.  Keep it up

Ryan


;D

Thanks, the project forked into something else quite a number of months ago but was useful for putting the 595 through its paces, now I look back on the code, it's really quite hard to follow.

So it's important to read this tutorial first:

http://www.arduino.cc/en/Tutorial/ShftOut22

There's code examples that explain how to start off with 1 register, then 2.

The key to lighting up all 16 LEDs, while really only having 8 on at a time, is this loop:

Code: [Select]

 digitalWrite(latchPin, 0); // ground the latchpin
 shiftOut(dataPin, clockPin, 255); // 1st register ignite all 8 LEDs
 shiftOut(dataPin, clockPin, 0);    // 2nd register turns off all 8 LEDs
 digitalWrite(latchPin, 1); // return the latch pin high

 digitalWrite(latchPin, 0); // ground the latchpin
 shiftOut(dataPin, clockPin, 0); // 1st register turns off all 8 LEDs
 shiftOut(dataPin, clockPin, 255);    // 2nd register ignite all 8 LEDs
 digitalWrite(latchPin, 1); // return the latch pin high


Because of the speed, the human eye will only see 16 LEDs turned on, while really there is only power going to 8 LEDs. Adding extra 595's to expand on the number of LEDs, while still only having 8 LEDs powered at any one time (thus not blowing up the Arduino), is done per:

Code: [Select]

 digitalWrite(latchPin, 0); // ground the latchpin
 shiftOut(dataPin, clockPin, 255); // 8 on
 shiftOut(dataPin, clockPin, 0);    // 8 off
 shiftOut(dataPin, clockPin, 0);    // 8 off
 shiftOut(dataPin, clockPin, 0);    // 8 off
 digitalWrite(latchPin, 1); // return the latch pin high

 digitalWrite(latchPin, 0); // ground the latchpin
 shiftOut(dataPin, clockPin, 0); // 8 off
 shiftOut(dataPin, clockPin, 255);    // 8 on
 shiftOut(dataPin, clockPin, 0);    // 8 off
 shiftOut(dataPin, clockPin, 0);    // 8 off
 digitalWrite(latchPin, 1); // return the latch pin high

 digitalWrite(latchPin, 0); // ground the latchpin
 shiftOut(dataPin, clockPin, 0); // 8 off
 shiftOut(dataPin, clockPin, 0);    // 8 off
 shiftOut(dataPin, clockPin, 255);    // 8 on
 shiftOut(dataPin, clockPin, 0);    // 8 off
 digitalWrite(latchPin, 1); // return the latch pin high

 digitalWrite(latchPin, 0); // ground the latchpin
 shiftOut(dataPin, clockPin, 0); // 8 off
 shiftOut(dataPin, clockPin, 0);    // 8 off
 shiftOut(dataPin, clockPin, 0);    // 8 off
 shiftOut(dataPin, clockPin, 255);    // 8 on
 digitalWrite(latchPin, 1); // return the latch pin high
 

You can downsize this code using variables and counters.

I had 8 595's wired up to ultra high powered LEDs and this worked fine, I don't think there's a limit to the number of 595's you can piggy-back, so for cost its an economic solution to controlling large numbers of LEDs, you can buy 10 off a number of eBay sellers for just a few bucks :)



biggie

#46
Mar 31, 2008, 11:47 pm Last Edit: Mar 31, 2008, 11:48 pm by biggie Reason: 1
This is killing me... am I missing the serial library or something ?? (i don't think I am)

Trying to read an external .txt file just like Ryan's sketch but can't compile past this:

import processing.serial.*;
Serial port;

returning this error:

error: 'import' does not name a type

Any ideas?

John_Ryan

Quote
This is killing me... am I missing the serial library or something ?? (i don't think I am)

Trying to read an external .txt file just like Ryan's sketch but can't compile past this:

import processing.serial.*;
Serial port;

returning this error:

error: 'import' does not name a type

Any ideas?


What version of processing are you using? and what code snippet? This post is quite old, and I no longer have the code or processing for that matter.

Processing refers to this IDE.

http://www.processing.org/download/index.html

I'm not sure if this is the same snippet.

Code: [Select]

/* http client
original code by Tom Igoe
Starts a network client that connects to a server on port 80,
sends an HTTP 1.1 GET request.
Sends an input value to php
php writes the value to a text file on a web server
 */
import processing.net.*;
Client client;
int inputValue = 33;                    // number representing the input switch - this would be determined by the value Arduino sends to processing

void setup()
{
 // open a TCP socket to the host:
 client = new Client(this, "yourserver.com", 80);
 // send the HTTP GET request:
 client.write("GET /~youraccount/switch.php?receivedValue=" + inputValue + " HTTP/1.1\n");
 client.write("HOST: yourserver.com\n\n");
  println("\n\nSend complete\n");
}



Oracle

What would be really nice is modifying this so it stores the data from the text file in the EEPROM.  You can program the LED display off the PC and then run it independently.

John_Ryan

Quote
What would be really nice is modifying this so it stores the data from the text file in the EEPROM.  You can program the LED display off the PC and then run it independently.


Apologies. My 'subscribe to thread' somehow got substituted with another thread, so I've been getting notifications about the "encoder" project  ;D

Yes, an EEPROM would be an excellent elaboration. However, I've since dumped using processing entirely, and now use php via the php_serial library. It's awesome. A full web interface with patterns stored in a mySql database, communicating in real-time with an Arduino connected by USB.

I'll post a tutorial when I get some free time.


Oracle

That tutorial is something I'd love to see.  I haven't yet had a chance to get into processing for the PC side of the connection but have a fair bit of experience coding PHP for web pages.

John_Ryan

It's easier with php, processing doesn't provide a method to catch errors, instead, it throws exceptions and stops, which is maybe fine if you know your way around java. It's also "just" php, a bit of xhtml & css for the API, and a LAMP stack for running the script on your local host, and then making that host accessible to the outside world, usually by creating a DMZ on your router/modem and port forwarding 8888 (the MAMP default).

The "php_serial_class", is excellent, particularly if you've got experience with php you'll be very comfortable creating web accessible real-time physical computing applications, complete with attractive css/xhtml/ajaxified API's

The php serial class can be downloaded here:-

http://www.modxhost.com/php_serial.class.txt

You'll need to change the extension to .php, or copy/paste the code into a blank document, and save it as php_serial.class.php

It can be used on Windows/Linux "and" this is the OSX compatible version.

Here's the php script which uses the class:-

http://www.modxhost.com/php-arduino-led-example.txt

Again, you'll need to change the extension to .php, and rename the file to something shorter like example.php

The button sprite used by the embedded css, can be downloaded here:-

http://www.modxhost.com/rocker_79x62.gif

I've used a CSS sprite so two buttons (ON/OFF) are loaded on the first instance the class is used.

And, here's the Arduino code (a quick hack) for toggling a LED. The Arduino is connected via USB to the computer that has the LAMP stack.

http://www.modxhost.com/arduino-code-4-php.txt

Here's an excellent tutorial on how to use the class, although, the class used isn't the OSX version - no big deal if your not using a mac :)

http://www.communitymx.com/content/article.cfm?page=2&cid=8658A



mem

Quote
It's easier with php, processing doesn't provide a method to catch errors, instead, it throws exceptions and stops, ...


Hi John, are you sure? I haven't tried it but I would think you could do something like this in Processing:

try{
    somethingDodgy(); // a function that could fail
} catch (Exception e){
    safetyNet();   // this should be called if there is an exception in somethingDodgy()
}


John_Ryan

#53
Apr 09, 2008, 12:02 pm Last Edit: Apr 09, 2008, 12:10 pm by John_Ryan Reason: 1
Quote
Quote
It's easier with php, processing doesn't provide a method to catch errors, instead, it throws exceptions and stops, ...


Hi John, are you sure? I haven't tried it but I would think you could do something like this in Processing:

try{
    somethingDodgy(); // a function that could fail
} catch (Exception e){
    safetyNet();   // this should be called if there is an exception in somethingDodgy()
}



Looks promising, but like I said, if you know your way around Java, which I don't, it's perhaps not a problem.

Try finding a solution to "NullPointerException" - I got invited to "contribute" the solution if I ever came up with one. And that's the other problem with processing, it's a one man band, and he's a very busy person. Questions and issues go unanswered in the forum, sometimes for days, weeks, months, and sometimes not at all. And that can result in stalled projects if you've built a framework that involves processing, only to hit a problem that you eventually discover, has no solution.

There's way more support for php, and with php_serial.class.php, most of the hard work has already been done. And particularly for use on the web, you can parse xhtml and css, and build nice 'all browser/platform compatible' clean 'standards compliant/device independent' web2.0 front ends.

I could never figure out how you'd make anything look nice using processing, so the php_serial.class was a very lucky find - particularly the OSX compatible version :)

The only draw-back is, you need to do a crash course on setting up a LAMP stack, I've "read" it's something of a feat on Linux, and XAMPP on Windows XP, just looks out of place, lol.

MAMP on OSX was a breeze, it took under half an hour to set up, then to make it visible on the www, took another half an hour reading through the modem documentation.

The other good thing about a LAMP stack, is that you can install it on ITX motherboards (with XP&HDD), and that's a full Apache server on a low-powered mini computer, 802.11 wifi enabled, which provides an inexpensive long range web-accessible real-time physical computing platform.

Add a few dualCoreDuino's, and your robot gets wings *lol*

mem

John, I agree that if one wants to do more than run the example code, the learning curve in Processing is unnecessarily awkward. The Processing documentation is not very well organized and by the time I got an answer to a simple newbie question on the Processing forum, 3 or 4 days had gone by so I had bodged my own solution.

But for those that want to write code on a PC that talks to an Arduino and they don't know another language (or already know java) then Processing is worth a look. It's a shame that despite its family resemblance to the Arduino, Processing seems nowhere near as user friendly.

John_Ryan

Quote
John, I agree that if one wants to do more than run the example code, the learning curve in Processing is unnecessarily awkward. The Processing documentation is not very well organized and by the time I got an answer to a simple newbie question on the Processing forum, 3 or 4 days had gone by so I had bodged my own solution.

But for those that want to write code on a PC that talks to an Arduino and they don't know another language (or already know java) then Processing is worth a look. It's a shame that despite its family resemblance to the Arduino, Processing seems nowhere near as user friendly.


I agree absolutely, the IDE is very familiar and not a bad place to start. I also asked numerous questions at their forum when I first got an Arduino, some got answered, some didn't, and nearly always there was a considerable passage of time involved.

It took a while before I realized the capabilities of processing were ideal for bench testing applications. More serious applications, though not overly intricate, require a stability such as that offered by php.

Unfortunately, there wasn't much reference here to php as an alternative to processing, and it took the eventual discovery of the php_serial class, plus a very good example at the communitymx site, to realize it was viable.  

So the material is there now for others to explore, all it needs is an Ajax routine to update the GUI whenever there's a serial event initiated by the Arduino - for example, if a button is pushed you want the web page to do something or display a response to that event without needing to refresh the page every (x) seconds, and Ajax is the perfect solution.

I've got a script here that I've used for displaying mySql table updates in real time without refreshing the page, I should be able to adapt it to update elements on a web page in response to Arduino serial events, so it would be possible to monitor environmental sensors in real time from a web page over the www, without the page re-loading every 5 seconds.

In the button example, it's addressing a segment of an image using css sprites to display two button states (ON/OFF), so the same method can be applied for displaying segments of a bar graph, an analog meter, or a digital display like an LCD panel.  

So I might start with a PIR, and see if I can get a graphic to blip whenever it's tripped :)  

GreatOne

@John_Ryan
When I try this example: http://www.modxhost.com/php-arduino-led-example.txt - i got following php error:
Fatal error: Cannot redeclare class phpserial in ...php_serial.class.php on line 21

Another issue:
you wrote following code
Code: [Select]

//Specify the serial port to use... in this case COM1
     $serial->deviceSet("/dev/tty.usbserial-A4001nU7");


What´s the "/dev/tty.usbserial-A4001nU7" for - isn´t it possible to write "COM1"?

GreatOne

update:
I replaced "/dev/tty.usbserial-A4001nU7" with my COM-Port - "COM3" and even if I got these fatal error message - it worked to turn the LED off.

But turning the Led on isn´t working...

steffensen

By using this code by John_Ryan, would it be possible to hook up let say, 20-24 pieces of 595's, without destroying my Arduino? Would the flickering of the LED:s be somewhat noticeable then?

Code: [Select]
 digitalWrite(latchPin, 0); // ground the latchpin
 shiftOut(dataPin, clockPin, 255); // 1st register ignite all 8 LEDs
 shiftOut(dataPin, clockPin, 0);    // 2nd register turns off all 8 LEDs
 digitalWrite(latchPin, 1); // return the latch pin high

 digitalWrite(latchPin, 0); // ground the latchpin
 shiftOut(dataPin, clockPin, 0); // 1st register turns off all 8 LEDs
 shiftOut(dataPin, clockPin, 255);    // 2nd register ignite all 8 LEDs
 digitalWrite(latchPin, 1); // return the latch pin high

artemispap

hi everyone
I am in the middle of putting together some code for activating LEDs according to specific rfid tags and I came accross this topic which is very complex for the simple task i am putting together. anyway, i have chosen the elements I need and before I could test it, i realised the arduino software does not recognize the TextString Library because i dont have this directory in my arduino012 software file: lib/targets/libraries. I created it anew and copied the library there, but still doesnt recognize the library. I downloaded arduino013 but my mac cannot even unzip it. so i dont know what is really the problem here.
any ideas?............. many thanx

Go Up