Voting resources, early voting, and poll worker information - VOTE. ... Adafruit is open and shipping.
0

ASCII LED control
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Re: ASCII LED control

by adafruit_support_bill on Tue Aug 24, 2010 5:56 pm

My comments on the loop code below

Code: Select all | TOGGLE FULL SIZE
void loop()
{
  if (Serial.available())
  // You need an open bracket here to establish the start of the scope of ths 'if'
   
    Serial.println(nextChar); // This should be a 'nextchar = Serial.read();' to read the 'passChar'
    {   
    if (charCount == 0) // check for the first char of the pwd...
    {     
       if (nextChar == passChar) // nextChar has no value yet because you have not read it.
       {
         charCount = 1;  // got it, so update the character counter
       }
       else
       {
         charCount = 0;  // wrong character, so reset count to zero
         
         {
           nextChar = Serial.read();  // read just one character
         }
           if (nextChar == red)  // check for 'r'
           {
             ledState1 = HIGH;
             ledState2 = LOW;
             Serial.println("led 1 On-red");
           }
           else if (nextChar == yellow)  // check for 'y'
           {
             ledState1 = LOW;
             ledState2 = HIGH;
             Serial.println("led 2 On-yellow");
           }
           else if (nextChar == off)  // check for 'o'
           {                 
             ledState1 = LOW;
             ledState2 = LOW;
             Serial.println("leds Off");
           }   
           else if (nextChar == blue)  // check for 'b'
           {
             ledState3 = HIGH;
             ledState4 = LOW;
             Serial.println("led 3 On-blue");
           }
           else if (nextChar == green)  // check for 'g'
           {
             ledState3 = LOW;
             ledState4 = HIGH;
             Serial.println("led 4 On-green");
           }
           else if (nextChar == off2)  // check for 'f'
           {                 
             ledState3 = LOW;
             ledState4 = LOW;
             Serial.println("leds2 Off");
           }
           else if (nextChar == M1)  // check for '1'
           {
             ledState1 = HIGH;
             ledState2 = LOW;
             ledState3 = HIGH;
             ledState4 = LOW;
             Serial.println("led 1 & 3 On-red & blue");
           }
           else if (nextChar == M2)  // check for '2'
           {
             ledState1 = LOW;
             ledState2 = HIGH;
             ledState3 = LOW;
             ledState4 = HIGH;
             Serial.println("led 2 & 4 On-yellow & green");
           }
           else if (nextChar == Moff)  // check for 'a'
           {
             ledState1 = LOW;
             ledState2 = LOW;
             ledState3 = LOW;
             ledState4 = LOW;
             Serial.println("All leds Off");
           } 
       }
     
       digitalWrite(led1, ledState1);
       digitalWrite(led2, ledState2);
       digitalWrite(led3, ledState3);
       digitalWrite(led4, ledState4);
    }

}  // braces are unbalanced because there was no opening brace '{' after the initial 'if'

adafruit_support_bill
 
Posts: 78635
Joined: Sat Feb 07, 2009 10:11 am

Re: ASCII LED control

by utoto on Tue Aug 24, 2010 6:22 pm

I'm sorry. I do not follow what is needed here.
I try to follow your thoughts, but, I must be messing up somehow and I don't know where because it still brings up errors. Only, I can't seem to find the place(s).
utoto
 
Posts: 28
Joined: Mon Aug 23, 2010 3:08 pm

Re: ASCII LED control

by westfw on Tue Aug 24, 2010 6:33 pm

I recommend three things:

  1. Add comments to your code so that you/we can easily see which section of code is doing what.
  2. Investigate subroutines/functions. Move LED manipulation to a subroutine so that it doesn't obscure the logic of the color decisions.
  3. Investigate the "switch/case" statement

You should wind up with something a bit like:

Code: Select all | TOGGLE FULL SIZE
byte redstate, greenstate, bluestate;

void lightRGB(byte r,g,b) {
    if (r != redstate) {  //change in status of red led.  Report and Write.
       redstate = r;
       Serial.print("Changing Red to ");
       Serial.print(r, INT);
       digitalWrite(redLed, r);
   }
   if (g != greenstate) {
   // etc
   }
}
loop() {
   c = Serial.read();
   if (c > 0) {  // Serial.read returns -1 if there is no data.
      Serial.print("Read ");
      Serial.print(c); 
      Serial.print(" ('");
      Serial.print(c, BYTE);
      Serial.println("')");
      switch(c) {
      case 'y':
         lightRGB(HIGH, HIGH, LOW); // yellow = red+ green
         break;
      case 'r':
         lightRGB(HIGH, LOW, LOW);  // red only
         break;
      // etc
      } // end of switch
   } // end of "c > 0"
}


westfw
 
Posts: 1711
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: ASCII LED control

by adafruit_support_bill on Tue Aug 24, 2010 6:37 pm

The most fundamental concept you must understand is that compilers are not very smart. You must be very explicit in what you tell them.

The scope of an "if" or "if else" is determined by the braces: "{" & "}". Everything that is controlled by the 'if' must be between these braces. For every "{" there must be a "}". If the braces are not balanced, the compiler gets confused.

adafruit_support_bill
 
Posts: 78635
Joined: Sat Feb 07, 2009 10:11 am

Re: ASCII LED control

by utoto on Tue Aug 24, 2010 7:05 pm

OK. Thanks. I did have that feeling with all the problems. There is just no room for mistakes I guess.

I am really trying to grasp the overall picture so that when I want to add or change something I am able to.

Can you explain some of the "why's" for me? Perhaps I will be better able to understand then.

I know that I must start with labeling the IO's and such. Then begin comm with "Serial.begin(9600) as the speed.
This makes sense.

At void loop(), starting with a "{" is to show that what is coming next is how to utilize the components and parameters listed above. Is this accurate so far?
utoto
 
Posts: 28
Joined: Mon Aug 23, 2010 3:08 pm

Re: ASCII LED control

by westfw on Tue Aug 24, 2010 7:57 pm

Can you explain some of the "why's" for me? Perhaps I will be better able to understand then.

I don't know if it will make sense. Compilers (or actually programming languages) operate on a defined "syntax" that describes what the various piece of program should look like.
So C is based around "statements." A simple statement in C is something like "A=B;" But then you add the concept of a "compound statement", which looks like:
{ simplestatement; another-simplestatement; more-simplestatements; }
Where the additional statements are actually optional.
Then, something like an IF statement is defined:
if (condition) statement else statement2
where "statement" and "statement2" can either be simple statements OR they can be a complex statement (any number of statements (which in turn can be either simple or complex) inside a set of braces.)

It is a common "good coding practice" to NEVER use simple statements for language constructs. It makes it too easy to break your code by adding a line where the added line causes the statement to become two statements. For example:
Code: Select all | TOGGLE FULL SIZE
if (a)
    digitalWrite(pin, 1);
else
    digitalWrite(pin, 0);
is perfectly legal, but:
Code: Select all | TOGGLE FULL SIZE
if (a)
    digitalWrite(pin, 1);
    Serial.print("test");
else
    digitalWrite(pin, 0);
will result in an error because there are now TWO statements between the if and the else. A set of braces around the two statements would make them a single compound statement and it would be OK.

One technique for preventing errors is to type both open and closing braces when you first enter the expression. If you start with:
Code: Select all | TOGGLE FULL SIZE
if () {
} else {
}
before you start filling in the code for each part, it is easier to keep track.

The formality of all this is usually taught in a Sophomore or Junior level college compiler class, by which time you have hopefully seen enough computer languages that you "get it."

westfw
 
Posts: 1711
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: ASCII LED control

by utoto on Wed Aug 25, 2010 1:02 pm

OK. I think I get it. SO, Java is using macros including different statements and "C" would otherwise use individual statements to reach the same end. Perhaps if I am able to learn a way to compare to what I already know, like paragraphs, sentences, etc. in English, I might be more quickly able to grasp Java?
I guess I need to learn what is a comparable term to define an area in the code.

-----
if (a) // What does the (a) mean here?
digitalWrite(pin, 1); // This looks like "turn this pin ON (or OFF depending on how it was setup in the preface)"
Serial.print("test"); // Why is this the wrong place for this to be? What does this mean that the grammer here is wrong?
else
digitalWrite(pin, 0); // This looks like "OR turn this pin ON (or OFF depending on how it was setup in the preface)"
-----

In a bit of code I uploaded, the digitalWrite's are at the bottom of the entire thing just before the END }. When or how to tell when to move them to the end as opposed to in the actual mix as you have them here and how I was learning them before. It doesn't seem wrong. In fact, I can see how it might be more efficient and neat. I have been trying to glean from arduwino and his seems quite nice doing it this way. Or is this simply how this type of code should be?

Having an entire scope ready when I begin would be nice. Then I could have all my braces in, as you say, prior to filling in the meat, but, how to achieve this?

Also, I think I understand the "if" part, but not the "if else"? What about just the "else"? I believe I am seeing 3 different things here. Is that correct?

Please, forgive my ignorance here. I am trying.
utoto
 
Posts: 28
Joined: Mon Aug 23, 2010 3:08 pm

Re: ASCII LED control

by adafruit_support_bill on Wed Aug 25, 2010 1:49 pm

There are formal language specifications for C++ available on-line or in reference books, but it can be pretty intimidating. The best way to learn it is to start with something simple and make incremental changes. As you become confident with the language, you will understand the structure and can start designing programs from scratch.

Some general suggestions:

    Start with some of the example programs that are included in the Arduino IDE. Compile them, run them and modify them until you understand how they work.

    Check out the "Getting Started" books in the Adafruit Store. http://www.adafruit.com/index.php?main_page=index&cPath=40

    When you modify programs, change one thing at a time and re-compile. It only takes a few seconds to recompile and you will know exactly which change caused the error.

And some specific answers:
In a bit of code I uploaded, the digitalWrite's are at the bottom of the entire thing just before the END }. When or how to tell when to move them to the end as opposed to in the actual mix as you have them here and how I was learning them before. It doesn't seem wrong. In fact, I can see how it might be more efficient and neat. I have been trying to glean from arduwino and his seems quite nice doing it this way. Or is this simply how this type of code should be?


Either way is correct. I prefer them inline as westfw has done, but they will work fine as you had them.

Having an entire scope ready when I begin would be nice. Then I could have all my braces in, as you say, prior to filling in the meat, but, how to achieve this?

That's the nice part about starting with the examples. You can find something close to what you want to do and just change the parts you need. Study the code wesfw and I have posted here as well as the "Control" examples in the IDE.

adafruit_support_bill
 
Posts: 78635
Joined: Sat Feb 07, 2009 10:11 am

Re: ASCII LED control

by utoto on Wed Aug 25, 2010 2:10 pm

I got it! After stewing a bit on what you both have been saying and then cleaning up things in the code I was able to more clearly think through it. As you will notice I commented a label for each brace used. This helped me get them in an order. It was a lot of typing, but, seems to have helped.

Please, let me know what you think!

Code: Select all | TOGGLE FULL SIZE
/*
* Turn 4 leds split into 2 sets on and off with special characters
* sent over the serial connection with only 1 led allowed on at a
* time. If  the 2nd led is commanded on, the first will be turned
* off prior.
* Now with 1st Place char address.
*/

int led1 = 13;      // led is hoooked up to this pin
int led2 = 12;      // led is hoooked up to this pin
int led3 = 11;      // led is hoooked up to this pin
int led4 = 10;      // led is hoooked up to this pin
int ledState1;
int ledState2;
int ledState3;
int ledState4;
int pswdChar = 'p';   // the first character of the password
int charCount;

char red = 'r';     // ascii LED 1 on
char off = 'o';     // ascii leds off
char yellow = 'y';  // ascii LED 2 on
char blue = 'b';    // ascii LED 3 on
char off2 = 'f';    // ascii leds2 off
char green = 'g';   // ascii LED 4 on
char M1 = '1';      // ascii LED 1&3 on
char Moff = 'a';    // ascii ledsAll off
char M2 = '2';      // ascii LED 2&4 on
char nextChar;

void setup()
{
   Serial.begin(9600);
   
   pinMode(led1, OUTPUT);
   digitalWrite(led1, LOW);
   ledState1 = LOW;
   
   pinMode(led2, OUTPUT);
   digitalWrite(led2, LOW);
   ledState2 = LOW;
   
   pinMode(led3, OUTPUT);
   digitalWrite(led3, LOW);
   ledState3 = LOW;
   
   pinMode(led4, OUTPUT);
   digitalWrite(led4, LOW);
   ledState4 = LOW;
   
   charCount = 0;
}
void loop()
{                          // open main thought
  if (Serial.available())
   {                       // open sub thought
    pswdChar = Serial.read();
    Serial.println(pswdChar);
   
    if (charCount == 0)     // check for the first char of the pwd...
      {                             // open sub-2 thought             
        if (charCount == pswdChar) // ie. "p"
         {                          //open a sub-3 thought
           charCount = 1;   // because the first place holds a "p" then
                                   // move on to the next char which designates
                                   // the particular LED
         }                         // close sub-3 thought
         else                    // if there is no "p" in the first place then:
         {                        // open a sub-3 thought
           charCount = 0;  // it is the wrong character, so reset count
                                  // to zero and do not
                                  // allow anything further to happen
         }                        // close sub-3 thought
         nextChar = Serial.read();      // read just one character
         {                                         // open a sub-3 thought
         if (nextChar == red)             // check for 'r'
           {                                       // open a sub-4 thought
             ledState1 = HIGH;
             ledState2 = LOW;
             Serial.println("led 1 On-red");
           }                                          // close sub-4 thought
           else if (nextChar == yellow)  // check for 'y'
           {                                          // open a sub-4 thought
             ledState1 = LOW;
             ledState2 = HIGH;
             Serial.println("led 2 On-yellow");
           }                                        // close sub-4 thought
           else if (nextChar == off)     // check for 'o'
           {                                       // open a sub-4 thought                 
             ledState1 = LOW;
             ledState2 = LOW;
             Serial.println("leds Off");
           }                                         // close sub-4 thought   
           else if (nextChar == blue)    // check for 'b'
           {                                        // open a sub-4 thought
             ledState3 = HIGH;
             ledState4 = LOW;
             Serial.println("led 3 On-blue");
           }                                          // close sub-4 thought
           else if (nextChar == green)   // check for 'g'
           {                                         // open a sub-4 thought
             ledState3 = LOW;
             ledState4 = HIGH;
             Serial.println("led 4 On-green");
           }                                        // close sub-4 thought
           else if (nextChar == off2)    // check for 'f'
           {                                        // open a sub-4 thought                 
             ledState3 = LOW;
             ledState4 = LOW;
             Serial.println("leds2 Off");
           }                                        // close sub-4 thought
           else if (nextChar == M1)      // check for '1'
           {                                        // open a sub-4 thought
             ledState1 = HIGH;
             ledState2 = LOW;
             ledState3 = HIGH;
             ledState4 = LOW;
             Serial.println("led 1 & 3 On-red & blue");
           }                                        // close sub-4 thought
           else if (nextChar == M2)      // check for '2'
           {                                       // open a sub-4 thought
             ledState1 = LOW;
             ledState2 = HIGH;
             ledState3 = LOW;
             ledState4 = HIGH;
             Serial.println("led 2 & 4 On-yellow & green");
           }                                        // close sub-4 thought
           else if (nextChar == Moff)   // check for 'a'
           {                                       // open a sub-4 thought
             ledState1 = LOW;
             ledState2 = LOW;
             ledState3 = LOW;
             ledState4 = LOW;
             Serial.println("All leds Off");
           }                           // close sub-4 thought 
        }                              // close sub-3 thought     
     }                                 // close sub-2 thought
     digitalWrite(led1, ledState1);
     digitalWrite(led2, ledState2);
     digitalWrite(led3, ledState3);
     digitalWrite(led4, ledState4);
  }                                    // close sub thought
}                                      // close main thought


So, the digitalWrites can be at the bottom of the sub thought because it keeps them inside of the proper braces and out of the way of the other parts, no?
utoto
 
Posts: 28
Joined: Mon Aug 23, 2010 3:08 pm

Re: ASCII LED control

by utoto on Wed Aug 25, 2010 2:49 pm

OK. Not quite done yet. Apparently I need a 2-char string with the 1st char being pswdChar or "p". My code allows for ANY char to be used in the 1st position allowing the 2nd position for my LED command chars.

Hmmmm. I am definitely needing to rethink this. Any ideas?
utoto
 
Posts: 28
Joined: Mon Aug 23, 2010 3:08 pm

Re: ASCII LED control

by adafruit_support_bill on Wed Aug 25, 2010 3:16 pm

See commented changes to your loop:
Code: Select all | TOGGLE FULL SIZE
/*
* Turn 4 leds split into 2 sets on and off with special characters
* sent over the serial connection with only 1 led allowed on at a
* time. If  the 2nd led is commanded on, the first will be turned
* off prior.
* Now with 1st Place char address.
*/

int led1 = 13;      // led is hoooked up to this pin
int led2 = 12;      // led is hoooked up to this pin
int led3 = 11;      // led is hoooked up to this pin
int led4 = 10;      // led is hoooked up to this pin
int ledState1;
int ledState2;
int ledState3;
int ledState4;
int pswdChar = 'p';   // the first character of the password
int charCount;

char red = 'r';     // ascii LED 1 on
char off = 'o';     // ascii leds off
char yellow = 'y';  // ascii LED 2 on
char blue = 'b';    // ascii LED 3 on
char off2 = 'f';    // ascii leds2 off
char green = 'g';   // ascii LED 4 on
char M1 = '1';      // ascii LED 1&3 on
char Moff = 'a';    // ascii ledsAll off
char M2 = '2';      // ascii LED 2&4 on
char nextChar;

void setup()
{
   Serial.begin(9600);
   
   pinMode(led1, OUTPUT);
   digitalWrite(led1, LOW);
   ledState1 = LOW;
   
   pinMode(led2, OUTPUT);
   digitalWrite(led2, LOW);
   ledState2 = LOW;
   
   pinMode(led3, OUTPUT);
   digitalWrite(led3, LOW);
   ledState3 = LOW;
   
   pinMode(led4, OUTPUT);
   digitalWrite(led4, LOW);
   ledState4 = LOW;
   
   charCount = 0;
}
void loop()
{                          // open main thought
  if (Serial.available())
   {                       // open sub thought
    //pswdChar = Serial.read();  // pswdChar is the passwqord.  You don't want to read over it!
    char check_password = Serial.read();
    Serial.println(pswdChar);
   
    /* - this code is unnecessary - you care about typing the correct character, not how many characters you type
   
    if (charCount == 0)     // check for the first char of the pwd...  // this will always be true!
                           
      {                             // open sub-2 thought             
        if (charCount == pswdChar) // ie. "p"           // You are comparing a character to a count!
                                                        // this will never be true so your count will remain 0.
         {                          //open a sub-3 thought
           charCount = 1;   // because the first place holds a "p" then
                                   // move on to the next char which designates
                                   // the particular LED
         }                         // close sub-3 thought
         else                    // if there is no "p" in the first place then:
         {                        // open a sub-3 thought
           charCount = 0;  // it is the wrong character, so reset count
                                  // to zero and do not
                                  // allow anything further to happen
         }                        // close sub-3 thought
         */
         
    if (check_password == pswdChar) // does the password match?
    {
      // YES it matches, so we continue with the next character!
     
         nextChar = Serial.read();      // read just one character
         {                                         // open a sub-3 thought
         if (nextChar == red)             // check for 'r'
           {                                       // open a sub-4 thought
             ledState1 = HIGH;
             ledState2 = LOW;
             Serial.println("led 1 On-red");
           }                                          // close sub-4 thought
           else if (nextChar == yellow)  // check for 'y'
           {                                          // open a sub-4 thought
             ledState1 = LOW;
             ledState2 = HIGH;
             Serial.println("led 2 On-yellow");
           }                                        // close sub-4 thought
           else if (nextChar == off)     // check for 'o'
           {                                       // open a sub-4 thought                 
             ledState1 = LOW;
             ledState2 = LOW;
             Serial.println("leds Off");
           }                                         // close sub-4 thought   
           else if (nextChar == blue)    // check for 'b'
           {                                        // open a sub-4 thought
             ledState3 = HIGH;
             ledState4 = LOW;
             Serial.println("led 3 On-blue");
           }                                          // close sub-4 thought
           else if (nextChar == green)   // check for 'g'
           {                                         // open a sub-4 thought
             ledState3 = LOW;
             ledState4 = HIGH;
             Serial.println("led 4 On-green");
           }                                        // close sub-4 thought
           else if (nextChar == off2)    // check for 'f'
           {                                        // open a sub-4 thought                 
             ledState3 = LOW;
             ledState4 = LOW;
             Serial.println("leds2 Off");
           }                                        // close sub-4 thought
           else if (nextChar == M1)      // check for '1'
           {                                        // open a sub-4 thought
             ledState1 = HIGH;
             ledState2 = LOW;
             ledState3 = HIGH;
             ledState4 = LOW;
             Serial.println("led 1 & 3 On-red & blue");
           }                                        // close sub-4 thought
           else if (nextChar == M2)      // check for '2'
           {                                       // open a sub-4 thought
             ledState1 = LOW;
             ledState2 = HIGH;
             ledState3 = LOW;
             ledState4 = HIGH;
             Serial.println("led 2 & 4 On-yellow & green");
           }                                        // close sub-4 thought
           else if (nextChar == Moff)   // check for 'a'
           {                                       // open a sub-4 thought
             ledState1 = LOW;
             ledState2 = LOW;
             ledState3 = LOW;
             ledState4 = LOW;
             Serial.println("All leds Off");
           }                           // close sub-4 thought 
        }                              // close sub-3 thought     
     }                                 // close sub-2 thought
     digitalWrite(led1, ledState1);
     digitalWrite(led2, ledState2);
     digitalWrite(led3, ledState3);
     digitalWrite(led4, ledState4);
  }                                    // close sub thought
}                                      // close main thought

adafruit_support_bill
 
Posts: 78635
Joined: Sat Feb 07, 2009 10:11 am

Re: ASCII LED control

by utoto on Wed Aug 25, 2010 3:55 pm

Thank you!

Is all that I need here is a "check" on what came back from the "read serial for password" command?
utoto
 
Posts: 28
Joined: Mon Aug 23, 2010 3:08 pm

Re: ASCII LED control

by adafruit_support_bill on Wed Aug 25, 2010 4:01 pm

Yes. You don't need to count the characters because you will just ignore everything until you see the 'password' character.

adafruit_support_bill
 
Posts: 78635
Joined: Sat Feb 07, 2009 10:11 am

Re: ASCII LED control

by utoto on Wed Aug 25, 2010 5:42 pm

If I want to add a timer for each led so that when it is sent HIGH, a delay will be enabled to send it LOW after the delay times out, should it be an "if an LEDs state is high then a starts delay of (?) and then send it LOW. Or should it be after each digitalWrite at the bottom?

I think it must be up above as the digitalWrites are not specific but simply act according to the ledState which could be LOW or HIGH.
utoto
 
Posts: 28
Joined: Mon Aug 23, 2010 3:08 pm

Re: ASCII LED control

by adafruit_support_bill on Wed Aug 25, 2010 6:04 pm

In this case, it would be best to put it at the end with the DigitalWrite(). That way you only need to check for HIGH or LOW once.

adafruit_support_bill
 
Posts: 78635
Joined: Sat Feb 07, 2009 10:11 am

Please be positive and constructive with your questions and comments.