Shifting Out a String

Hello guys.
I am working in an installation in witch I want to control 93 bolbs array.
For that I have a simulation running in Flash and a string of chars is coming into arduino trough the serial.
The strings is something like this “fnfffnfnnffnfnf”.
The “f” is for “off” and the “n” for “on”.
Everything is all right till this point.
To control the lamps I am going to use a series of shift registers.
At the moment I am just testing with a 8 char length string, and just one register.
But i am not been able to make it work.
Any help?

The debug leds are working properly and everything seems connected right.

////////////////////////////////

char serInString[8];

int latchPin = 8;
int clockPin = 3;
int dataPin = 4;

int debugPin1 = 5;
int debugPin2 = 6;
int debugPin3 = 7;

boolean dataReady = false;
//////////////////////////////////////////
void setup() {
Serial.begin(57600); //setup serial conversation at 19200 bauds
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(debugPin1, OUTPUT);
pinMode(debugPin2, OUTPUT);
pinMode(debugPin3, OUTPUT);
}
////////////////////
void loop () {
readSerialString(serInString);

if( dataReady )
shiftOutString(serInString);
delay( 3000 );
}
//////////////////////////////////////////
void blinkDebug( int times ){
int t;
for( t = 0 ; t < times ; t++ ){
digitalWrite(debugPin1, HIGH );
delay( 100 );
digitalWrite(debugPin1, LOW );
delay( 100 );
}
}
////////////////////////////////////////////////
boolean isStringEmpty(char *strArray){
if (strArray[0] == 0)
return true;
else
return false;
}
///////////////////////////////////////////////////
void readSerialString (char *strArray){
int i = 0;
if(serialAvailable()){
while( serialAvailable()){
strArray = Serial.read();

  • i++;*

  • }*

  • dataReady = true;*

  • }*
    }
    //////////////////////////////////////////////
    void shiftOutString(char *strArray){

  • int i=0;*

  • digitalWrite(dataPin, LOW);*

  • digitalWrite(clockPin, LOW);*

  • for( i = 0 ; i < 8 ; i++ ) {*

  • digitalWrite(clockPin, LOW);*

  • if( strArray[ i ] == ‘f’ ){*

  • digitalWrite(dataPin, LOW);*

  • digitalWrite(debugPin2 , HIGH );*

  • delay( 50 );*

  • digitalWrite(debugPin2 , LOW );*

  • delay( 50 );*

  • }*

  • if( strArray[ i ] == ‘n’ ){*

  • digitalWrite(dataPin, HIGH);*

  • digitalWrite(debugPin3 , HIGH );*

  • delay( 50 );*

  • digitalWrite(debugPin3 , LOW );*

  • delay( 50 );*

  • }*

  • //register shifts bits on upstroke of clock pin *

  • digitalWrite(clockPin, HIGH);*

  • //zero the data pin after shift to prevent bleed through*

  • digitalWrite(dataPin, LOW);*

  • delay( 100 );*

  • }*

  • blinkDebug( 3 );*

  • //stop shifting*

  • digitalWrite(clockPin, LOW);*

  • dataReady = false;*
    }

Ok I think the problem is your sending individual bits. The shift registers want bytes.

Basically you need to add in a array to store the status of 8 leds and then output it in one go. Either that or learn boolean logic to do it more efficiently. :)

http://www.arduino.cc/en/Tutorial/ShiftOut That page has more detailed information with examples.

I dont thin this ids the problem , in the shift out function in the examples the information is sent bit a bit too. :(

I discovered why it wasn’t doing anything. I missed to change the state of the latch PIN.

It is still not working.
If u want to help me , mail me and i will send u the files for testing it.
Thanks a lot.

:slight_smile:

juliolucio@yahoo.com

/////////////////////////////////////////////////////
int tested = 0;
char serInString[8];

void setup() {
Serial.begin(57600); //setup serial conversation at 19200 bauds
for (int i=2; i<=8; i++) {
pinMode(i, OUTPUT); // sets the digital pins 2-9 as output
}
}

void loop () {

if( !tested ){
//testing
for( int i= 0 ; i < 8 ; i ++ ){
digitalWrite(i+2,LOW);
}
for( int i= 0 ; i < 8 ; i ++ ){
digitalWrite(i+2,HIGH);
delay( 200 );
digitalWrite(i+2,LOW);
}
tested = 1;
}

readSerialString(serInString);

//recived a string
for( int i= 0 ; i < 8 ; i ++ ){
if( serInString[ i ] == ‘f’ ){
digitalWrite(i+2,LOW);
}
if( serInString[ i ] == ‘n’ ){
digitalWrite(i+2,HIGH);
}
}
delay( 100 );
}

boolean isStringEmpty(char *strArray){
if (strArray[0] == 0)
return true;
else
return false;
}

void readSerialString (char *strArray){
int i = 0;
if(serialAvailable())
while( serialAvailable()){
strArray = Serial.read();

  • i++;*
  • }*
    }
    ///////////////////////////////////////////////////////

Ups
I sent the wrong code for the test
Here it is:
///////////////////////////////////////////////
int numeroDeJanelas = 8;
char serInString[ 8 ];

int latchPin = 2;
int clockPin = 3;
int dataPin = 4;

int debugPin1 = 5;
int debugPin2 = 6;
int debugPin3 = 7;

boolean dataReady = false;

void setup() {
Serial.begin(57600); //setup serial conversation at 19200 bauds
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);

pinMode(debugPin1, OUTPUT);
pinMode(debugPin2, OUTPUT);
pinMode(debugPin3, OUTPUT);
}

void loop () {
readSerialString(serInString);
if( dataReady )
shiftOutString(serInString , numeroDeJanelas );
delay( 1000 );
}

void blinkDebug( int times , int pin ){
int t;
for( t = 0 ; t < times ; t++ ){
digitalWrite(pin, HIGH );
delay( 100 );
digitalWrite(pin, LOW );
delay( 100 );
}
}

boolean isStringEmpty(char *strArray){
if (strArray[0] == 0)
return true;
else
return false;
}

void readSerialString (char *strArray){
int i = 0;
if(serialAvailable()){
while( serialAvailable()){
strArray = Serial.read();

  • i++;*
  • }*
  • dataReady = true;*
  • }*
    }
    void shiftOutString(char *strArray , int stringSize ){
  • int i=0;*
  • //start shifting*
  • digitalWrite(latchPin, LOW);*
  • //shifting out the data along the register*
  • digitalWrite(dataPin, LOW);*
  • digitalWrite(dataPin, LOW);*
  • for( i = stringSize ; i != 0 ; i-- ) {*
  • digitalWrite(clockPin, LOW);*
  • if( strArray[ i ] == ‘f’ ){*
  • digitalWrite(dataPin, LOW);*
  • }*
  • if( strArray[ i ] == ‘n’ ){*
  • digitalWrite(dataPin, HIGH);*
  • }*
  • //register shifts bits on upstroke of clock pin *
  • digitalWrite(clockPin, HIGH);*
  • //zero the data pin after shift to prevent bleed through*
  • digitalWrite(dataPin, LOW);*
  • }*
  • //stop shifting*
  • digitalWrite(clockPin, LOW);*
  • //end shifting and puting data in outputs*
  • digitalWrite(latchPin, HIGH);*
  • dataReady = false;*
    }
    //////////////////////////////////////////////////////////////////

Hi. ShiftOut is now included in the Arduino code. Check out this page for more information. Good luck!

I´ve seen the shiftOut function, but i need to shift out a long string ( 93 values ) , and i don’t want to break the string into 8 bit chunks.
I made some corrections in the code and now works, but the re is some delay.
Any suggestions?
Again , if someone is reeeeeeeeally interested in helping, please , mail me to
juliolucio@yahoo.com , and i will send u the files to test it.
Cheers

Here is the code for arduino.
////////////////////////////////////////////////////////////////
int stringSize = 8;
char serInString[ 8 ];

int latchPin = 2;
int clockPin = 3;
int dataPin = 4;

int debugPin1 = 5;

boolean dataReady = false;

void setup() {
Serial.begin(57600); //setup serial conversation at 19200 bauds
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(debugPin1, OUTPUT);

digitalWrite(clockPin, LOW);
digitalWrite(latchPin, LOW);
digitalWrite(dataPin, LOW);

}

void loop () {
readSerialString();
if( dataReady )
shiftOutString();
delay( 100);
}

void blinkDebug( int times , int pin ){
int t;
for( t = 0 ; t < times ; t++ ){
digitalWrite(pin, HIGH );
delay( 100 );
digitalWrite(pin, LOW );
delay( 100 );
}
}

boolean isStringEmpty(){
if (serInString[0] == 0)
return true;
else
return false;
}

void readSerialString (){
int i = 0;
if(serialAvailable()){
while( serialAvailable()){
serInString = Serial.read();

  • i++;*

  • }*

  • dataReady = true;*

  • // blinkDebug( 2 , debugPin1);*

  • }*
    }
    void shiftOutString(){

  • int i=0;*

  • //start shifting*

  • digitalWrite(latchPin, LOW);*

  • delay(10);*

  • for( i = stringSize-1 ; i > -1 ; i-- ) {*

  • digitalWrite(clockPin, HIGH);*

  • if( serInString[ i ] == ‘f’ ){*

  • digitalWrite(dataPin, LOW);*

  • }*

  • if( serInString[ i ] == ‘n’ ){*

  • digitalWrite(dataPin, HIGH);*

  • }*

  • delay( 10);*

  • //register shifts bits on upstroke of clock pin *

  • digitalWrite(clockPin, LOW);*

  • //zero the data pin after shift to prevent bleed through*

  • delay(10);*

  • }*

  • digitalWrite(clockPin, HIGH);*

  • delay( 10);*

  • digitalWrite(clockPin, LOW);*

  • digitalWrite(latchPin, HIGH);*

  • delay(30);*

  • digitalWrite(clockPin, HIGH);*

  • delay(10);*

  • digitalWrite(clockPin, LOW);*

  • digitalWrite(latchPin, LOW);*

  • delay(10);*

  • dataReady = false;*
    }
    ///////////////////////////////////////////////////////////////////////

So it's working now just really slow?

You have two delay(10) in the loop of shiftout(), so if you have 93 characters it's going to take 93*10*2 = 1860ms just to finish the loop, and then there's 60ms delay after the loop. So your shiftout function takes almost 2 seconds, but wait, there's more: a 100ms delay in your main loop.

Do you really need all those delays?

Also, if you are just transfering on/off information, in the time it takes for the serial port to transfer one "n" or "f" character, you can transfer 8 bits if you used bytes instead.

-Z-