N00b, 1 shift register, 8 LEDs

Pic attached of my hardware setup.

ok. Hopefully I can edit this post.

What you are looking at is an Arduino R3, with project #12 from the Vilros starter kit, 8 leds slaved to a 595 shift register. When I compile and upload the sketch that came with the kit, everything works. The Vilros code includes a section that can light up one LED at a time, a ping pong function, a random function, a binary counter, all those work just fine. They compile, upload, and the LEDs do what they are supposed to do, as long as I have all but one of the included functions commented out when I compile and upload.

What I want to do, the sketch I am writing, is suppose to light up the LEDs in the same firing order as the third generation V8 introduced by GM in the late 1990s. Other options would be the Ford flathead V8 of fame in song and story, and there are the Ferrari V8s to consider as well.

For starters, GM and Ford not only have different firing orders, they also number the cylinders in the physical engine differently. I could write a sketch (I think) to just light up the LEDs one at a time and then move all my wiring around every time I want to look at a different engine; but I don't want to do that. I want to be able to leave the wiring alone and just comment in and out "1957 Chevy" "2012 Corvette" "Thomas Magnum's Ferrari" "1932 Ford" and so on.

I have, I think, three fundamental questions.

  1. Can this be done with a 595 shift register? Do I need to write clunky if/else/then function? Look at arrays? Look at strings? From reading about strings here it seems like I should avoid strings.

  2. If I can't do it with a shift register easily, what IC do I need to look at instead?

  3. Is there a book or website I can grab to learn more about this aspect of the arduino? For the projects I want to do, passing switching off the Arduino board to free up pins on the Arduino board is a good thing.

Next I shall try to attach the code I have. The 1,8,7 blah blah is the cylinder firing order that looks like a single number value to the compiler...

[code]
int datapin = 2;
int clockpin = 3;
int latchpin = 4;
byte data = 0;

void setup() {
pinMode(datapin, OUTPUT);
pinMode(clockpin, OUTPUT);
pinMode(latchpin, OUTPUT);
}

void loop() {
  GMgen3firingorder();
}

void shiftWrite(int desiredPin, boolean desiredState)
{
bitWrite(data, desiredPin, desiredState);
shiftOut(datapin, clockpin, MSBFIRST, data);
digitalWrite(latchpin, HIGH);
digitalWrite(latchpin, LOW);
}

void GMgen3firingorder()
{
  int index;
  int delayTime = 250;
  for (index 1,8,7,2,6,5,4,3);
  {
    shiftWrite(index, HIGH);
    delay(delayTime);
    shiftwrite(index, LOW);
  }
}
[/code]

Crud. My error message wasn't included in the copy/paste.

The compiler error reads:

exit status 1
expected ';' before numeric constant

and the highlighted line of code is for (index 1,8,7,2,6,5,4,3);

Thanks in advance. Not looking to be spoon fed. A bit of guidance for exact terms to search on should be adequate.

Hello Poindexter
Take a view here to gain the knowledge.

Have a nice day and enjoy coding in C++.
Дайте миру шанс!

Hi,

Try this code below:
Comment on unused models


int datapin = 2;
int clockpin = 3;
int latchpin = 4;
byte data = 0;
// Comment on unused models
byte car[] = {1, 3, 2, 4};                // Bee
//byte car[] = {1, 2, 5, 8, 6, 7, 4, 3};    // GM
//byte car[] = {1, 8, 7, 2, 6, 5, 4, 3};    // Ford
//byte car[] = {1, 8, 7, 2, 6, 5, 4, 3};    // Ferrari

//-----------------------------------------------------------------------
void setup() {
//  Serial.begin(115200);
  pinMode(datapin, OUTPUT);
  pinMode(clockpin, OUTPUT);
  pinMode(latchpin, OUTPUT);
}
//-----------------------------------------------------------------------
void loop() {
  GMgen3firingorder();
}
//-----------------------------------------------------------------------
void shiftWrite(int desiredPin, boolean desiredState)
{
//  Serial.print(desiredPin); Serial.print(" "); Serial.println(desiredState);
  bitWrite(data, desiredPin, desiredState);
  shiftOut(datapin, clockpin, MSBFIRST, data);
  digitalWrite(latchpin, HIGH);
  digitalWrite(latchpin, LOW);
}
//-----------------------------------------------------------------------
void GMgen3firingorder()
{
  int delayTime = 250;
  for (int i = 0; i < sizeof(car); i++)
  {
    shiftWrite(car[i], HIGH);
    delay(delayTime);
    shiftWrite(car[i], LOW);
  }
}

Yes.

No

Probably

Probably not.

FYI, you may have read posts telling you to avoid using Strings (upper-case 'S') as opposed to strings (lower-case 's'). They are subtly different things in C++ language. But for your project I don't think either would be a good choice.

You don't have to use a shift register or any other external chip for this. 8 Arduino pins would do the job, and you seem to have plenty of pins free on your Uno.

In fact, I suspect it could be done with only 4 Arduino pins, and no extra chips, which means you could use a DigiSpark board instead of your Uno. I'm not certain of that because I'm no expert in V8 engines. Do two or more cylinders ever fire at the same moment in any of the designs? If not, my 4-pin idea should work. You would only need 4 resistors.

For suggestions and ideas about different ways to approach a project, and help with the circuit and code, this website/forum is probably the best out there. Don't expect everything to be done for you. This forum likes to help those who want to learn.

for (index 1,8,7,2,6,5,4,3);

As you have probably figured out by now, that's not valid C/C++, hence the error message. But even if it was, you made another, much more subtle error. Unfortunately for beginners, that error might not throw up any message at all:

  for (index 1,8,7,2,6,5,4,3);
  {
    shiftWrite(index, HIGH);
    delay(delayTime);
    shiftwrite(index, LOW);
  }

You wanted the code lines between the { and } to be repeated 8 times over. But because you put a semi-colon at the end of the line starting "for", that marks the end of the for-loop and so the code lines inside the { } are not part of the loop and would only be executed once.

Charlieplexing?

1 Like

Yeah, only problem is loss of a little brightness when you multiplex.

Thanks one and all so far. I am just coming off 12 days in a row and have a bunch of springtime chores to get done this weekend. My plan, when I get back to this is fool with the byte function, or byte command, and see if I can make that work.

In a previous iteration I had this thing running without the shift register, just using 8 output pins on the main board. That can be done, I have done it. Years ago, same user name as I have now. I think in the education subforum back in the day. I had a piezo clicker and a rheostat as a throttle on there too, but I was running out of pins.

One of my kids needed an arduino for school back in the day, so I just boxed everything up and let her use it.

Well it is running. I commented in the physical cylinder arrangement in the car for 1997+ GM and 1930s Ford, as well as the corresponding IC pin numbers - and data address- for the LEDs as wired to the shift register IC. Once I figured out fifteen is equal to zero I was in tall cotton.

The drudgery, once the firing order and cylinder numbering scheme is known, is to list LEDs 0-7 in the correct order within the byte.

Now I have to figure out why it works, but I have terms to search on. Thanks again.

[code]
int datapin = 2;
int clockpin = 3;
int latchpin = 4;
byte data = 0;
byte car[] = {0, 7, 3, 4, 6, 2, 5, 1}; //gen3GM

//front of engine, IC pin numbers
// 15 aka 0, 4
// 1, 5
// 2, 6
// 3, 7

// front of engine, GM 1997+
// 1,2
// 3,4
// 5,6
// 7,8
// spark plug firing order in car 1-8-7-2-6-5-4-3

//front of engine, ford flat head
// 5,1
// 6,2
// 7,3
// 8,4

void setup() {
pinMode(datapin, OUTPUT);
pinMode(clockpin, OUTPUT);
pinMode(latchpin, OUTPUT);
}

void loop() {
  GMgen3firingorder();
}

void shiftWrite(int desiredPin, boolean desiredState)
{
bitWrite(data, desiredPin, desiredState);
shiftOut(datapin, clockpin, MSBFIRST, data);
digitalWrite(latchpin, HIGH);
digitalWrite(latchpin, LOW);
}

void GMgen3firingorder()
{
    int delayTime = 500;
  for (int i=0; i< sizeof(car); i++)
  {
    shiftWrite(car[i], HIGH);
    delay(delayTime);
    shiftWrite(car[i], LOW);
  }
}
[/code]

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.