how can I condense a repetitive task into a loop.

I am trying to learn the programming and have got to the shiftin and shiftout instructions with a shift generator. I have added to the program provided on this site with instructions to indicate different numbers on the monitor for different inputs. I now have a fairly repetitive list. Just for the sake of understanding how best to do it as anything else, would someone mind showing me how to rewrite the portion as a loop and cutting out all the repetition. I have only included the portion of the program that I have replaced plus the definition of the variables. The bit I am having most problem with is turning the xBitNum into a variable? or am I going about it the wrong way? The result I am getting at the moment is

1 2 3 4 5 6 7 8

if all the inputs are high or

1 2 4 5 6 7 8

if input 3 is low and that is just what I want. I will look at connecting outputs next but would like to be able to do this with one section instead of 8. Thanks. Bob --------I can see that switching the byte variables around would be required to get a incremental list. But which way?---

byte cBitNum = 7;
byte dBitNum = 6;
byte eBitNum = 5;
byte fBitNum = 4;
byte gBitNum = 3;
byte aBitNum = 2;
byte bBitNum = 1;
byte hBitNum = 0;

boolean aBit;
boolean bBit;
boolean cBit;
boolean dBit;
boolean eBit;
boolean fBit;
boolean gBit;
boolean hBit;
 switchVar1 = shiftIn(dataPin, clockPin);



//--------------------------------the repetition starts here------------------------------------
//just validating a function (no new variable required) 
 if (getBit(switchVar1, dBitNum)) {
    Serial.print("1   ");
    }
    else
    {
      Serial.print("    ");
    }
 if (getBit(switchVar1, cBitNum)) {
    Serial.print("2   ");
    }
    else
    {
      Serial.print("    ");
    }   
  if (getBit(switchVar1, eBitNum)) {
    Serial.print("3   ");
    }
    else
    {
      Serial.print("    ");
    }
  if (getBit(switchVar1, fBitNum)) {
    Serial.print("4   ");
    }
    else
    {
      Serial.print("    ");
    }
  if (getBit(switchVar1, gBitNum)) {
    Serial.print("5   ");
    }
    else
    {
      Serial.print("    ");
    }
 if (getBit(switchVar1, aBitNum)) {
    Serial.print("6   ");
    }
    else
    {
      Serial.print("    ");  
 }
  if (getBit(switchVar1, bBitNum)) {
    Serial.print("7   ");
    }
    else
    {
      Serial.print("    ");
    }
  if (getBit(switchVar1, hBitNum)) {
    Serial.println("8");
 }
     else
    {
      Serial.println("    ");
    }


//white space
Serial.println("-------------------");

If you make a table, with xBitNum and the value that you print, you have

dBitNum = 6; 1 cBitNum = 7; 2 eBitNum = 5; 3 fBitNum = 4; 4 gBitNum = 3; 5 aBitNum = 2; 6 bBitNum = 1; 7 hBitNum = 0; 8

Which makes me suspect a flaw in your code. If not for the first two entries. the value printed and the value in the second argument would add up to 8, and that whole file of code could be replaced by a for loop.

Look up "C array" and see if that helps.

Thanks for the replies.
Paul, the program is from this website and works on my blob board.
I can’t find c array’s but I am trying to understand arrays I have written :-

int xBitNum[] = {0,1,2,3,4,5,6,7};
int i;
int b;
int dataPin = 9;
int clockPin = 7;
int latchPin = 8;
byte switchVar1 = 72;  //01001000

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(clockPin, OUTPUT); 
  pinMode(dataPin, INPUT);
  pinMode(latchPin, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:

 
  //Pulse the latch pin:
  //set it to 1 to collect parallel data
  digitalWrite(latchPin,1);
  //set it to 1 to collect parallel data, wait
  delayMicroseconds(20);
  //set it to 0 to transmit data serially  
  digitalWrite(latchPin,0);
 //   for (b=0; b<=7; b++)
 
 
 
 /* this line compiles without error in the shiftregister sketch from this website but stops with 'error at this point in file' 
 when put here */

 switchVar1 = shiftIn(dataPin, clockPin);

 /* I want to put xBitNum[] in place of switchVar1 eventually but I cant see why this fails? 
(I assume it would be something like xBitNum[b] using the for statement above) but why does this fail? 
Is replacing switchVar1 with xBitNum[b] and using a for loop how I can loads the info into an array?*/
 
 
  
  
  
  for (i=0; i<=8; i++)
    Serial.println("a");
    if (xBitNum[i] = 1)
    {
      Serial.print (i);
      Serial.print ("    ");
    }
    else
    {
      Serial.print ("          ");
    }
}

It all compiled ok until I tried to read the data into xBitNum.
I went back to the original shiftregister program and copied the loading line from there? It failed to compile with ‘error at this point in file’ ? It compiles in the shiftregister program?
I have put more info around the offending line above.

int xBitNum[] = {0,1,2,3,4,5,6,7};

So, the value of xBitNum[n] is n. What value does the array provide?

It all compiled ok until I tried to read the data into xBitNum.

You read data FROM or WRITE data to an array. You don’t read to an array.

Anyway, you need to post the code that causes the error, AND the EXACT error.

    if (xBitNum[i] = 1)

I’m pretty sure == would work better.

It all compiled ok until I tried to read the data into xBitNum[].

You read data FROM or WRITE data to an array. You don't read to an array.

ok I'm reading from a shift register to the array.

Anyway, you need to post the code that causes the error, AND the EXACT error.

I have posted the code and as it says at the end the error is 'error at this point in file' or rather just 'at this point in file'..

    if (xBitNum[i] = 1)

I'm pretty sure == would work better.

I am trying to load info from a shift register so surely if (xBitNum[i] = 1) won't work?

matelot: as it says at the end the error is ...

That is not the complete error message. If you want help fixing a compilation error you need to post the code that caused the error, and the complete error message. Typically, a failed compilation will produce multiple lines of error messages and you need to post the whole lot.

What PaulS is saying is that you want a relational test (==) not an assignment operator(=). Your if statement should be

if (xBitNum[i] == 1)

Notice the double equal sign.

I have posted the code and as it says at the end the error is ‘error at this point in file’ or rather just ‘at this point in file’…

Well, I tried to compile that code, and I got:

C:\Users\pjs9486\Documents\arduino-1.0.5\hardware\arduino\cores\arduino/Arduino.h: In function ‘void loop()’:
C:\Users\pjs9486\Documents\arduino-1.0.5\hardware\arduino\cores\arduino/Arduino.h:112: error: too few arguments to function ‘uint8_t shiftIn(uint8_t, uint8_t, uint8_t)’
sketch_oct25a:35: error: at this point in file

That’s a hell of a lot more information than you claim to get.

Hi Peter,
The whole of the code is there. I have not tried to run it on the arduino but if I compile it, with the offending line // ed out it compiles. The line is

switchVar1 = shiftIn(dataPin, clockPin);

With the line in I get ‘at this point in file’ on the orange bar and nothing else. Under it I get

C:\arduino\cores\arduino/Arduino.h: In function ‘void loop()’:
C:\arduino\cores\arduino/Arduino.h:112: error: too few arguments to function ‘uint8_t shiftIn(uint8_t, uint8_t, uint8_t)’
loop_shift_register:36: error: at this point in file. The line is fine in the code for shiftregister from this site.

I hope to use something like xBitNum = shiftIn(dataPin, clockPin); eventually.
Whilst I am writing this you posted another reply.
Hi econjack,
I am saying assigning xBitNum * with a number 1 is no good to me I want to read the contents of a shift register into the array.*
will for (b=0; b<=7; b++)
_ xBitNum = shiftIn(dataPin, clockPin);
do it ? This is the section I am trying to use in my program that is listed in a previous reply in this thread but even

switchVar1 = shiftIn(dataPin, clockPin); fails with all the variables assigned it gives the above error when compiled._

what is meant by

too few arguments to function 'uint8_t shiftIn(

and why does the line compile in the sketch supplied by this site?

and why does the line compile in the sketch supplied by this site?

What sketch? Your initial post was a bunch of snippets. Your revised code doesn’t compile. I can’t see a progression from working to not working.

The shiftIn() signature is:
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);

The sketch supplied by this site

//**************************************************************//
//  Name    : shiftIn Example 1.2                               //
//  Author  : Carlyn Maw                                        //
//  Date    : 25 Jan, 2007                                      //
//  Version : 1.0                                               //
//  Notes   : Code for using a CD4021B Shift Register    	//
//          :                                                   //
//****************************************************************

//define where your pins are
int latchPin = 8;
int dataPin = 9;
int clockPin = 7;
int led = 12;

//Define variables to hold the data 
//for shift register.
//starting with a non-zero numbers can help
//troubleshoot
byte switchVar1 = 72;  //01001000

//define an array that corresponds to values for each 
//of the shift register's pins
char note2sing[] = {
  'C', 'd', 'e', 'f', 'g', 'a', 'b', 'c'}; 


void setup() {
  //start serial
  Serial.begin(9600);

  //define pin modes
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT); 
  pinMode(dataPin, INPUT);
  pinMode(led, OUTPUT);

}

void loop() {

  //Pulse the latch pin:
  //set it to 1 to collect parallel data
  digitalWrite(latchPin,1);
  //set it to 1 to collect parallel data, wait
  delayMicroseconds(20);
  //set it to 0 to transmit data serially  
  digitalWrite(latchPin,0);

  //while the shift register is in serial mode
  //collect each shift register into a byte
  //the register attached to the chip comes in first 
  switchVar1 = shiftIn(dataPin, clockPin);

  //Print out the results.
  //leading 0's at the top of the byte 
  //(7, 6, 5, etc) will be dropped before 
  //the first pin that has a high input
  //reading  
  Serial.println(switchVar1, BIN);


  //This for-loop steps through the byte
  //bit by bit which holds the shift register data 
  //and if it was high (1) then it prints
  //the corresponding location in the array
  for (int n=0; n<=7; n++)
  {
    //so, when n is 3, it compares the bits
    //in switchVar1 and the binary number 00001000
    //which will only return true if there is a 
    //1 in that bit (ie that pin) from the shift
    //register.
    if (switchVar1 & (1 << n) ){
      //print the value of the array location
      Serial.println(note2sing[n]);
    }
    //if (note2sing[n] = a){
    //  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
   // }
    //  else
    //{
    //  digitalWrite(led, LOW);}
 // delay(100);               // wait for a second
 // digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 // delay(100);          
  //  }
  }

//white space
Serial.println("-------------------");
//delay so all these print satements can keep up. 
delay(500);

}

//------------------------------------------------end main loop

////// ----------------------------------------shiftIn function
///// just needs the location of the data pin and the clock pin
///// it returns a byte with each bit in the byte corresponding
///// to a pin on the shift register. leftBit 7 = Pin 7 / Bit 0= Pin 0

byte shiftIn(int myDataPin, int myClockPin) { 
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);
//we will be holding the clock pin high 8 times (0,..,7) at the
//end of each time through the for loop

//at the begining of each loop when we set the clock low, it will
//be doing the necessary low to high drop to cause the shift
//register's DataPin to change state based on the value
//of the next bit in its serial information flow.
//The register transmits the information about the pins from pin 7 to pin 0
//so that is why our function counts down
  for (i=7; i>=0; i--)
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(0.2);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      //set the bit to 0 no matter what
      myDataIn = myDataIn | (1 << i);
    }
    else {
      //turn it off -- only necessary for debuging
     //print statement since myDataIn starts as 0
      pinState = 0;
    }

    //Debuging print statements
    //Serial.print(pinState);
    //Serial.print("     ");
    //Serial.println (dataIn, BIN);

    digitalWrite(myClockPin, 1);

  }
  //debuging print statements whitespace
  //Serial.println();
  //Serial.println(myDataIn, BIN);
  return myDataIn;
}

there is a line in the above sketch switchVar1 = shiftIn(dataPin, clockPin); that compiles fine.
When I try to reproduce the same thing in a sketch I am writing

int xBitNum[] = {0,1,2,3,4,5,6,7};
int i;
int b;
int dataPin = 9;
int clockPin = 7;
int latchPin = 8;
byte switchVar1 = 72;  //01001000

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(clockPin, OUTPUT); 
  pinMode(dataPin, INPUT);
  pinMode(latchPin, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:

 
  //Pulse the latch pin:
  //set it to 1 to collect parallel data
  digitalWrite(latchPin,1);
  //set it to 1 to collect parallel data, wait
  delayMicroseconds(20);
  //set it to 0 to transmit data serially  
  digitalWrite(latchPin,0);
//  for (b=0; b<=7; b++)
//   xBitNum[b] = shiftIn(dataPin, clockPin);    
 
 
 /* this line compiles without error in the shiftregister sketch 
 from this website but stops with 'error at this point in file' 
 when put here */
 switchVar1 = shiftIn(dataPin, clockPin);
 /* I want to put xBitNum[] in place of switchVar1 eventually
 but I cant see why this fails? (I assume it would be something like 
 xBitNum[b] using the for statement above) but why does this fail?
 Is replacing switchVar1 with xBitNum[b] and using a for loop how I 
 can loads the info into an array?*/
 
 
  
  
  
  for (i=0; i<=8; i++)
    Serial.println("a");
    if (xBitNum[i] = 1)
    {
      Serial.print (i);
      Serial.print ("    ");
    }
    else
    {
      Serial.print ("          ");
    }

It fails. If I put // before the line

switchVar1 = shiftIn(dataPin, clockPin);

it compiles.
Just above the offending line in the bottom sketch is two lines

// for (b=0; b<=7; b++)
// xBitNum **= shiftIn(dataPin, clockPin); **
If I remove the // and put // before the line switchVar1 = shiftIn(dataPin, clockPin); this also fails to comply with the same message as above.
What instruction/s do I need to read a shift register into an array?

there is a line in the above sketch switchVar1 = shiftIn(dataPin, clockPin); that compiles fine.

Yes, there is, and yes it does. Why? Because of this:

byte shiftIn(int myDataPin, int myClockPin) { 
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);
//we will be holding the clock pin high 8 times (0,..,7) at the
//end of each time through the for loop

//at the begining of each loop when we set the clock low, it will
//be doing the necessary low to high drop to cause the shift
//register's DataPin to change state based on the value
//of the next bit in its serial information flow.
//The register transmits the information about the pins from pin 7 to pin 0
//so that is why our function counts down
  for (i=7; i>=0; i--)
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(0.2);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      //set the bit to 0 no matter what
      myDataIn = myDataIn | (1 << i);
    }
    else {
      //turn it off -- only necessary for debuging
     //print statement since myDataIn starts as 0
      pinState = 0;
    }

    //Debuging print statements
    //Serial.print(pinState);
    //Serial.print("     ");
    //Serial.println (dataIn, BIN);

    digitalWrite(myClockPin, 1);

  }
  //debuging print statements whitespace
  //Serial.println();
  //Serial.println(myDataIn, BIN);
  return myDataIn;
}

That sketch is NOT using the Arduino-supplied shiftIn function. Copy that code into your sketch, and your sketch will compile, too.

That was the cause of my problem.
I have corrected the error and been 'tinkering with the program this evening and have now got it to work as I want.
But (and there is always a but) but there is one line that has me confused.

int xBitNum[9];
int i;
int b;
int dataPin = 9;
int clockPin = 7;
int latchPin = 8;
int ledoutPin = 10;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);//set up to send info to monitor
  pinMode(clockPin, OUTPUT); //send a clock pulse to tell shift register to send next info 
  pinMode(dataPin, INPUT);//read next shift register state
  pinMode(latchPin, OUTPUT);//set to 1 to collect data, 0 to write data to arduino
  pinMode(ledoutPin, OUTPUT);//set pin/s to test array
}

void loop() {
  //Pulse the latch pin:
  //set it to 1 to collect parallel data
  digitalWrite(latchPin,1);
  //set it to 1 to collect parallel data, wait
  delayMicroseconds(20);
  //set it to 0 to transmit data serially  
  digitalWrite(latchPin,0);
  
  
  
  
  xBitNum[b] = shiftIn(dataPin, clockPin);
 
 
 
  
  if (xBitNum[4] == 1)
  {
    digitalWrite (ledoutPin, HIGH);
  }
  else
  {
    digitalWrite (ledoutPin, LOW);
  }
//     Serial.print ("             ");
//     Serial.print(xBitNum[4]);
  Serial.println();//add a return to move the monitor signal down 1 line (out of the sub routine below) 
}
//end of loop
//sub routine instead of using the library shift reg?
byte shiftIn(int myDataPin, int myClockPin) { 
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);
  //we will be holding the clock pin high 8 times (0,..,7) at the
  //end of each time through the for loop
  //at the begining of each loop when we set the clock low, it will
  //be doing the necessary low to high drop to cause the shift
  //register's DataPin to change state based on the value
  //of the next bit in its serial information flow.
  //The register transmits the information about the pins from pin 7 to pin 0
  //so that is why our function counts down
  for (i=7; i>=0; i--)
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(0.2);
    temp = digitalRead(myDataPin);
    xBitNum[i] = temp;
    Serial.print (xBitNum[i]);
    Serial.print ("  ");
    if (temp) {
      pinState = 1;
      //set the bit to 0 no matter what
      myDataIn = myDataIn | (1 << i);
    }
    else 
    {
      pinState = 0;
    }
    digitalWrite(myClockPin, 1);//move shift register on to next bit
  }
   return myDataIn;//end of subroutine
}

I have entered my sketch above and put spaces round the line.
xBitNum = shiftIn (dataPin, clockPin);
I think at sometime I had this line as an instruction if a for loop was true with the variable ‘b’ as the counter.
I have removed the for loop and the line still works.
I assume this is the line writing the data from the shift register into the array xBitNum[]. Is this correct? If I remove this line or // it out (what do you call //ing a line out?) it doesn’t write to the array. How does ‘b’ know to move the array onto the next bit?

That was the cause of my problem.
I have corrected the error and been 'tinkering with the program this evening and have now got it to work as I want.
But (and there is always a but) but there is one line that has me confused.

int xBitNum[9];
int i;
int b;
int dataPin = 9;
int clockPin = 7;
int latchPin = 8;
int ledoutPin = 10;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);//set up to send info to monitor
  pinMode(clockPin, OUTPUT); //send a clock pulse to tell shift register to send next info 
  pinMode(dataPin, INPUT);//read next shift register state
  pinMode(latchPin, OUTPUT);//set to 1 to collect data, 0 to write data to arduino
  pinMode(ledoutPin, OUTPUT);//set pin/s to test array
}

void loop() {
  //Pulse the latch pin:
  //set it to 1 to collect parallel data
  digitalWrite(latchPin,1);
  //set it to 1 to collect parallel data, wait
  delayMicroseconds(20);
  //set it to 0 to transmit data serially  
  digitalWrite(latchPin,0);
  
  
  
  
  xBitNum[b] = shiftIn(dataPin, clockPin);
 
 
 
  
  if (xBitNum[4] == 1)
  {
    digitalWrite (ledoutPin, HIGH);
  }
  else
  {
    digitalWrite (ledoutPin, LOW);
  }
//     Serial.print ("             ");
//     Serial.print(xBitNum[4]);
  Serial.println();//add a return to move the monitor signal down 1 line (out of the sub routine below) 
}
//end of loop
//sub routine instead of using the library shift reg?
byte shiftIn(int myDataPin, int myClockPin) { 
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);
  //we will be holding the clock pin high 8 times (0,..,7) at the
  //end of each time through the for loop
  //at the begining of each loop when we set the clock low, it will
  //be doing the necessary low to high drop to cause the shift
  //register's DataPin to change state based on the value
  //of the next bit in its serial information flow.
  //The register transmits the information about the pins from pin 7 to pin 0
  //so that is why our function counts down
  for (i=7; i>=0; i--)
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(0.2);
    temp = digitalRead(myDataPin);
    xBitNum[i] = temp;
    Serial.print (xBitNum[i]);
    Serial.print ("  ");
    if (temp) {
      pinState = 1;
      //set the bit to 0 no matter what
      myDataIn = myDataIn | (1 << i);
    }
    else 
    {
      pinState = 0;
    }
    digitalWrite(myClockPin, 1);//move shift register on to next bit
  }
   return myDataIn;//end of subroutine
}

I have entered my sketch above and put spaces round the line.
xBitNum[b} = shiftIn (dataPin, clockPin); I think at sometime I had this line as an instruction if a for loop was true with the variable ‘b’ as the counter. I have removed the for loop and the line still works. I assume this is the line writing the data from the shift register into the array xBitNum. Is this correct? If I remove this line or // it out (what do you call //ing a line out?) it doesn’t write to the array. How does ‘b’ know to move the array onto the next bit?

Half your code is bold and italics.

Please use code tags.

Read this before posting a programming question

what do you call //ing a line out?

Commenting a line out.

Thanks for that.
sorry I thought it had code tags. It has now and I have just discovered the reason for the bold. I am trying to write an array
xBitNum(squarebracket)b(squarebracket)
but that is a control code for bold so I have entered it as [b} instead.
Are you saying the answer to my query is in your link?

No, my link showed how to make posts. I don’t understand this line:

xBitNum[b] = shiftIn(dataPin, clockPin);

b never changes, so it will always be zero.

thats why Im asking ?
If I comment that line out I don’t get the proper output showing up on the monitor as if the array is not filling.
I have been checking it since you replied and it always shows the same.
Its as if that line is writing to the array.