Debugging Arrays and printing to serial [SOLVED]

OK, my Toolcabin is comming together and so I'm moving on!!
My dad wants some light for his modeltrain tivoli.
As the code looks now it's ok but I want more :slight_smile:

/*Alittle something for my dad's H0 modeltrain
*this is the light for a swing from the '50s
*based on a 8 LED kit from some web retailer.
*the code is simple, as were the Tivoli light in the '50s
*/
 
//LED Pin Variables
int ledPins[] = {2,3,4,5,6,7,8,9,10,11}; //An array to hold the pin each LED is connected to
                                   //i.e. LED #0 is connected to pin 2, LED #1, 3 and so on
                                   //to address an array use ledPins[0] this would equal 2
                                   //and ledPins[9] would equal 11
 
/*
 * setup() - this function runs once when you turn your Arduino on
 * We the three control pins to outputs
 */
void setup()
{
  
  //Set each pin connected to an LED to output mode (pulling high (on) or low (off)
  for(int i = 0; i < 10; i++){         //this is a loop and will repeat ten times
      pinMode(ledPins[i],OUTPUT); //we use this to set each LED pin to output
  }                                   //the code this replaces is below
 
  /* (commented code will not run)
   * these are the lines replaced by the for loop above they do exactly the
   * same thing the one above just uses less typing
  pinMode(ledPins[0],OUTPUT);
  pinMode(ledPins[1],OUTPUT);
  pinMode(ledPins[2],OUTPUT);
  pinMode(ledPins[3],OUTPUT);
  pinMode(ledPins[4],OUTPUT);
  pinMode(ledPins[5],OUTPUT);
  pinMode(ledPins[6],OUTPUT);
  pinMode(ledPins[7],OUTPUT);
  pinMode(ledPins[8],OUTPUT);
  pinMode(ledPins[9],OUTPUT);
  (end of commented code)*/
}
 
 
/*
 * loop() - this function will start after setup finishes and then repeat
 * we call a function called oneAfterAnother(). 
*/
 
void loop()                     // run over and over again
{
  oneAfterAnotherLoop();
}


void oneAfterAnotherLoop(){
  int delayTime = 350; //the time (in milliseconds) to pause between LEDs
                       //make smaller for quicker switching and larger for slower
 
//Turn Each LED on one after another
  for(int i = 0; i <= 9; i++){
    digitalWrite(ledPins[i], HIGH);  //Turns on LED #i each time this runs i
    delay(delayTime);                //gets one added to it so this will repeat 
  }                                  //8 times the first time i will = 0 the final
                                     //time i will equal 7;
 
//Turn Each LED off one after another
  for(int i = 9; i >= 0; i--){  //same as above but rather than starting at 0 and counting up
                                //we start at seven and count down
    digitalWrite(ledPins[i], LOW);  //Turns off LED #i each time this runs i
    delay(delayTime);                //gets one subtracted from it so this will repeat 
  }                                  //8 times the first time i will = 7 the final
                                     //time it will equal 0
                                     
                                     
}

My big question is: is there some way to "test" the pins in the array and tell if someting is wrong, and then print it to Serial.Println()?
I think that it would be in the setup...

I'm also going to add some more different styles, would it be a good idea to move the code to its own Void and use the loop to shift between?

What do you want to print?

My big question is: is there some way to "test" the pins in the array and tell if someting is wrong, and then print it to Serial.Println()?

What test do you want to apply ? You could write something that set each of the pins HIGH in turn and read the output using another pin I suppose. If a particular pin does not produce LOW and HIGH outputs at the appropriate time then report it. But how do you know that the pin used to read the output is working ?

More usefully perhaps, flash each LED in turn at startup and watch them. Simple to do and use. No need to even have a PC connected.

would it be a good idea to move the code to its own Void and use the loop to shift between?

Definitely not. Moving code to a void rarely helps anything.

Moving the code to a function, on the other hand, IS a good thing.

The void keyword defines the function return type, just like int, float, or String would. No one calls functions that return ints ints, so no one should call a function that doesn't return a value a void.

ok, first of all I want to post my code I have now

/*Alittle something for my dad's H0 modeltrain
*this is the light for a swing from the '50s
*based on a 8 LED kit from some web retailer.
*the code is simple, as were the Tivoli light in the '50s
************************************************************************/

 const int buttonPin = 2;    // the number of the pushbutton pin
//LED Pin Variables
int ledPins[] = {2,3,4,5,6,7,8,9,10,11}; //An array to hold the pin each LED is connected to
                                   //i.e. LED #0 is connected to pin 2, LED #1, 3 and so on
                                   //to address an array use ledPins[0] this would equal 2
                                   //and ledPins[9] would equal 11
 int delayTime = 350;
 int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers

/***********************************************************************************
 * setup() - this function runs once when you turn your Arduino on
 * We the three control pins to outputs
 ******************************************************************************/
void setup() {
    //Set each pin connected to an LED to output mode (pulling high (on) or low (off)
  for(int i = 2; i < 11; i++){         //this is a loop and will repeat ten times
      pinMode(ledPins[i],OUTPUT); //we use this to set each LED pin to output
  }
  pinMode(buttonPin, INPUT);
}
  /**************************************************************
  (commented code will not run)
   * these are the lines replaced by the for loop above they do exactly the
   * same thing the one above just uses less typing
  pinMode(ledPins[2],OUTPUT);
  pinMode(ledPins[3],OUTPUT);
  pinMode(ledPins[4],OUTPUT);
  pinMode(ledPins[5],OUTPUT);
  pinMode(ledPins[6],OUTPUT);
  pinMode(ledPins[7],OUTPUT);
  pinMode(ledPins[8],OUTPUT);
  pinMode(ledPins[9],OUTPUT);
  pinMode(ledPins[10],OUTPUT);
  pinMode(ledPins[11],OUTPUT);
  (end of commented code)
  **********************************************************************************/
  
 void oneAfterAnotherLoop(){
//  int delayTime = 350; //the time (in milliseconds) to pause between LEDs
                       //make smaller for quicker switching and larger for slower
 
//Turn Each LED on one after another
  for(int i = 2; i <= 11; i++){
    digitalWrite(ledPins[i], HIGH);  //Turns on LED #i each time this runs i
    delay(delayTime);                //gets one added to it so this will repeat 
  }                                  //8 times the first time i will = 0 the final
                                     //time i will equal 7;
//Turn Each LED off one after another
  for(int i = 11; i >= 2; i--){  //same as above but rather than starting at 0 and counting up
                                //we start at seven and count down
    digitalWrite(ledPins[i], LOW);  //Turns off LED #i each time this runs i
    delay(delayTime);                //gets one subtracted from it so this will repeat 
  }                                  //8 times the first time i will = 7 the final
                                     //time it will equal 0
 }
/*******************************************************************************************
*/
                                     
void slowonalloff(){
 // int delaytime = 350; //the time (in milliseconds) to pause between LEDs
                       //make smaller for quicker switching and larger for slower
//Turn each LED on one after another
 for(int i = 2; i <= 11; i++){
    digitalWrite(ledPins[i], HIGH);  //Turns on LED #i each time this runs i
    delay(delayTime);                //gets one added to it so this will repeat 
  }                                  //8 times the first time i will = 0 the final
                                     //time i will equal 7;
//Turn all LED off at one
for(int i = 2; i <=11; i){
digitalWrite(ledPins[i], LOW);        //Turns all LED off at once
delay(delayTime);
  }
}
/*************************************************************************************/

void LowToHigh(){ //This will run the light from the buttom to the top
  for(int i = 2; i < 11; i++) { 
    digitalWrite(i, HIGH); //Will turn the LED on
    delay(delayTime);
  digitalWrite(i, LOW); //Now we turn it off

  }
}

/**********************************************************************************/
void HighToLow(){ //This runs the light from the top to the buttom
  for(int i = 11; i >=2; i--) { 
    digitalWrite(i, HIGH); //Turn the LED on
    delay(delayTime); //Wait a little
  digitalWrite(i, LOW);//And off again

  }
}
/****************************************************************************************
 * loop() - this function will start after setup finishes and then repeat
 * we call a function called oneAfterAnother().
*****************************************************************************************/
 
void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button 
  // (i.e. the input went from LOW to HIGH),  and you've waited 
  // long enough since the last press to ignore any noise:  

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  } 
  
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
  }
  
{                     // run over and over again
  oneAfterAnotherLoop();
}
}

yes I know that the button dos'ent do anything now, but I need to go to bed now.

I will have a PC on at all time and the tivoli will be in a place that is not possible to se from where I will turn it on.
Think of it as if your modern car tells you that your tail light is broken.
You could see for yourself, but it's more convinient to have it on the display in front of you :slight_smile:

What do you want to print?

That LED number# is dead

What test do you want to apply ? You could write something that set each of the pins HIGH in turn and read the output using another pin I suppose. If a particular pin does not produce LOW and HIGH outputs at the appropriate time then report it. But how do you know that the pin used to read the output is working ?

Really that is my big question, how do you do it??

Maybe in a later update there will be more Arduinos to drive the whole tivoli and 1 to keep track of everything and time it all :slight_smile:
The idea is to test everything before starting and report to the "Master" Arduino and that will in turn tell the PC if something is wrong.
The "Master" will also have some sensors, so the lightshow will alter depending on, if it is day or night or if a train passes.
Yeah I think you get the picture :slight_smile:

You can take this as far as you like with separate hardware to test for all sorts of errors, but it's hardly justified for a train set.

The simplest method would be to dedicate 2 pins for every control output, and read back the value you wrote. But this won't necessarily tell you if the attached hardware is working.

If you were driving a LED you could for example read back the voltage on the anode, if it's > than the Vf of the LED then the LED has blown. etc etc etc.

Are you sure you want to double (or more) the hardware to test for this sort of thing on a train set? I design industrial controls and have so far never been asked to implement such fault detection.

BTW, what the heck is a "modeltrain tivoli"? Maybe it's more important than I think :slight_smile:


Rob

BTW, what the heck is a "modeltrain tivoli"? Maybe it's more important than I think

I could not get the word yesterday. It's a train set theme park :slight_smile:

Yeah I can see that it's a lot more hardware, but how do they do it on cars? I have to ask :slight_smile:

Yeah I can see that it's a lot more hardware, but how do they do it on cars? I have to ask

Maybe by measuring the current flowing (or not). Turn a pin HIGH. Current flows through a resistor and LED. Measure the voltage across the resistor to determine if current is flowing. But again, is it worth it ? How many LEDs are we talking about here compared with the number of lights in a car and how much are you prepared to pay ?

For starters, it's 10 LED's...
But the aspect of learning how to do it is in there as well :slight_smile:
How could I measure the voltage over the resistor?? By measuring on an analogRead??
If there is current, it's good. If not it's broken??
The LED's is driven directly from an Mini Pro 5V :slight_smile: 2 LED's in parallel. I have testet and it's ok to drive them.
As of paying, i'm not going to put a lot of money in it for now, I just thought that it would be fun to learn how to do the faulty alarm :slight_smile:

Assuming you are driving the LEDs with a logic high like this

pin->resistor->LED->GND

If you connect an AI to the LED anode you will see approx 2-3v if the LED is conducting (depends on the LED and the colour) and 5v if not. As you know that the pin is providing 5v you are effectively measuring the voltage across the resistor.

2 LED's in parallel

Each with their own resistor I hope.


Rob

So that would mean one analog input for each LED? and AI is a voltmeter? Or some fancy component?

Each with their own resistor I hope.

Yes :slight_smile: first I thought about putting them in series, but someone said that the voltage drop should be over the resistor and not the LED, for better lifetime :slight_smile:

So that would mean one analog input for each LED?

Yes, or a multiplexer but that's more ICs.

and AI is a voltmeter?

Yep.

the voltage drop should be over the resistor and not the LED, for better lifetime

Dunno about that, the LEDs will have the same forward voltage and current no matter how many you have in series, whatever is left it "used" by the resistor. So having them in series saves one resistor. But with only 5v headroom using 2 LEDs in series can be awkward depending on the LEDs in question.


Rob

This it getting fun, just sitting and thinking about it :slight_smile:
So that multiplexer: is it something like this?

The LED's is small 3mm in red, it's ok not to run them in full strengh, så maybe il'l hook it up in series and see what happens :slight_smile:
How does an example of the code for that mother, look like?? Or is there a good toturial?

Yes a 4052 should work, or a 4051. I don't have any code examples but using that chip to increase the number of AIs is very common so there will be some on the forum.

is there a good toturial?

Don't know, try here Arduino Playground - HomePage


Rob

You could make a checker device with light detectors. If you were making 100's of tivoli lights it might be worth it.
You would also benefit from learning to make stand-alone AVR's and get PCB's even making 10's of those.

For 1 or a few, use your Mark I eyeballs. Maybe have a slow run-through in setup() just for startup test?

If you REALLY want to take this farther then here is a clear and simple explanation of how to do multiple things at once with Arduino. And I do mean multiple, like run the lights and other things at the same time.

What you learn there may blow your mind for a while.

Ok, you gave me a lot to think about, this is looking good, and when It take only to more chips, I might go with it, but I'm not sure yet.
On the other hand I'm sure that I will use this sometime, it's beautiful and fantastic that this is possible :slight_smile: thank you all.
Another [SOLVED] to the stack :slight_smile:
BTW how do I change to [SOLVED] in the Subject?

BTW how do I change to [SOLVED] in the Subject?

Select Modify for your initial post. Add {SOLVED} to the subject line. Save.

You can multiplex directly from the Arduino/AVR chip pins. How many leds are you running?
With 16 pins you can do 8x8. Or 6x10. No extra chips needed but you would need 8 resistors and 8 transistors and a lot of wires and leds and an external power supply. You'd also need to do software tricks to light more than 1 led at a time.

Another "pin-multiplier" method is daisy-chaining shift registers or led drivers on SPI bus. You can light them all or any combination that way. It needs external power and small components per led as well.

For now, it's only 10 LED's, and it will never get over 13 LED's per setup, but with the "pin-multiplier" I won't have to get more Arduinos, that would be nice :slight_smile:
I'll look into it if my dad wan't more than this...
As it is right now, I just want my button to work as a charm and maybe control the sequences from the PC as well...

13 leds maximum? You should have more free pins than that! UNO/328P has 20 open I/O pins.
You don't need extra chips for that!

Time to save you some money, perhaps. Arduino is a development board .
You can use it to program chips that "stand alone" in final projects.

For example, the UNO chip is an ATmega328P that usually costs less than $3 new. Some other components are needed to run but that is 2x 5 or 10 cent capacitors and a power supply (running on the internal clock) though you need more (like to your leds) to see any output.

Here's the blog with complete, clear and concise instructions, of course it's Nick Gammon's blog!

How to make an Arduino-compatible minimal board

It doesn't have to be on a breadboard. You can solder parts and wires to a socket and plug the chip in there.
You can program the chip however you want and package the end product however you want.

You can get much advice here on where to buy/find parts. China is cheaper but the shipping can take weeks or cost extra. I usually wait. When I do buy with shipping, I get extra bits to fill out my collection of parts.

Or you can check out the Arduino Micro and Arduino Mini that cost less than an UNO and are far smaller.

If you only make 1, the stand-alone or the Micro may be your best choice with the Micro being the quick route.

Actually there are many small boards and u-solder kits out there. Many many.

If you -want- to use pin multipliers then you might drive them with an ATtiny.

Here's the MAKE Magazine Youtube version of that. They're in California.

That video is old. ATtiny85 runs less than $1.50 and the MIT site updated (I linked the newer one above).

Also note that if you run on the internal clock (oscillator really) that you run at 8 MHz max. Time variables, even delay() have to be adjusted but 8 MHz or even 1 MHz is more than fast enough for your Tivoli lights plus you can run a lower voltage and use less power, a real concern if you'll be using batteries. You can run any AVR chip that way.