Pages: [1] 2   Go Down
Author Topic: Control flow troubles  (Read 1055 times)
0 Members and 1 Guest are viewing this topic.
London
Offline Offline
Full Member
***
Karma: 0
Posts: 192
Yes, we can (solder)!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm building a simple EEPROM programmer that allows me to set individual bytes. The idea is to be able to enter an address on the serial monitor, then the data. I managed to cobble a sketch together which does not work properly. The sketch should take any number entered and turn it into a byte, then set 8 digital outputs (pin 2-9) with the individual bits. My only worry is that the sketch does set the first pin (pin 2) but the rest of them. I think the for loop is executed only once. What am I doing wrong?

Code:
char inData[10];
int index, i;
boolean started = false;
boolean ended = false;

int AP[8] = {
  2,3,4,5,6,7,8,9};
int AD[8] = {
  0,0,0,0,0,0,0,0};

void setup(){
  Serial.begin(9600);
  Serial.println("ready");
  for (i=0;i<8;i++) {
    pinMode(AP[i],OUTPUT);
  }
  // Setup Data Pins
  for (i=0;i<8;i++) {
    pinMode(AD[i],OUTPUT);
  }
}

void loop()
{
  while(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == '>')
    {
      started = true;
      index = 0;
      inData[index] = '\0';
    }
    else if(aChar == '<')
    {
      ended = true;
    }
    else if(started)
    {
      inData[index] = aChar;
      index++;
      inData[index] = '\0';
    }
  }

  if(started && ended){
    int inInt = atoi(inData); // Convert the string to an integer
    for(int j=0; j<8; j++){
      int b = bitRead(inInt,j);
      Serial.println(b);
      if((b&bit(j))>0) {
        AD[j]=HIGH;
      }
      else {
        AD[j]=LOW;
      }      
      digitalWrite(AP[j],AD[j]);
      delay(100);
    }
    Serial.println(" ");
    // Get ready for the next time
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}





Logged

0
Offline Offline
Shannon Member
****
Karma: 161
Posts: 10431
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What you did is fail to read the documentation for bitRead!!

Replace this section of loop()
Code:
  if(started && ended){
    int inInt = atoi(inData); // Convert the string to an integer
    for(int j=0; j<8; j++){
      int b = bitRead(inInt,j);
      Serial.println(b);
      if((b&bit(j))>0) {
        AD[j]=HIGH;
      }
      else {
        AD[j]=LOW;
      }     
      digitalWrite(AP[j],AD[j]);
      delay(100);
    }
by the succinct:

Code:
  if(started && ended){
    int inInt = atoi(inData); // Convert the string to an integer
    for(int j=0; j<8; j++){
      digitalWrite (AP[j], bitRead (inInt,j));  // extract relevant bit and output on relevant pin.
    }
Logged

[ I won't respond to messages, use the forum please ]

London
Offline Offline
Full Member
***
Karma: 0
Posts: 192
Yes, we can (solder)!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you!
Logged

0
Offline Offline
Shannon Member
****
Karma: 161
Posts: 10431
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes, the bitRead() function returns 1 or 0 (a single bit, already shifted appropriately).

BTW digitalWrite () treats any non-zero value as HIGH, (LOW is the same as 0 is the same as false), so you often don't need
to convert values specifically to HIGH or LOW - just pass directly to digitalWrite.
Logged

[ I won't respond to messages, use the forum please ]

London
Offline Offline
Full Member
***
Karma: 0
Posts: 192
Yes, we can (solder)!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you, that's a very good point! I'm having trouble with the control flow again. This time a for loop gets executed continuously (as it's supposed to) but cannot make it run only once. Tried the break statement with no success.

Code:
char addressBit[10];
char dataBit[6];
int arrayIndex, dataIndex,i;
boolean startedA, endedA, startedD, endedD = false;

int CE  = 47;
int OE  = 48;
int WE  = 49;

int AP[13] = {22,24,26,28,30,32,34,36,38,40,42,44,46};
int DP[8] =  {23,25,27,29,31,33,35,37};

void setup(){
  Serial.begin(9600);
  Serial.println("Enter address in decimal starting with the letter a and finishing it with a period!");
  Serial.println("Then enter data in decimal between d and comma!");
  for (i=2;i<10;i++) {
    pinMode(AP[i],OUTPUT); // address pins
  }
  for (i=9;i<14;i++) {
    pinMode(DP[i],INPUT); // data pins
  }
  // Setup Control Pins
  pinMode(CE, OUTPUT);
  pinMode(WE, OUTPUT);
  pinMode(OE, OUTPUT);
  pinMode(45, OUTPUT);
  
  // Setup Chip
  digitalWrite(CE, HIGH);
  digitalWrite(WE, LOW);
  digitalWrite(OE, HIGH);
}

void loop(){
  digitalWrite(45, HIGH);
  while(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == 'r') //beginning of the string
    {
      startedA = true;
      arrayIndex = 0;
      addressBit[arrayIndex] = '\0';
    }
    else if(aChar == '/') ///end of string
    {
      endedA = true;
    }
    else if(startedA)
    {
      addressBit[arrayIndex] = aChar;
      arrayIndex++;
      addressBit[arrayIndex] = '\0';
    }
  }  
if(startedA && endedA){
    int incomingByteA = atoi(addressBit); // Convert the string to an integer
    for(int j=0; j<13; j++){
      digitalWrite (AP[j], bitRead (incomingByteA,j));  // extract relevant bit and output on relevant pin.
      int a = bitRead (incomingByteA,j);
      Serial.println(a);
    }
    Serial.println(" ");
    // Get ready for the next time
    startedA = false;
    endedA = false;
    arrayIndex = 0;
    addressBit[arrayIndex] = '\0';
  }
   delay(1);
    digitalWrite(WE,LOW);      // Write Disabled
    delay(1);
    digitalWrite(CE,HIGH);      // Chip enabled
    delay(1);
    digitalWrite(OE,HIGH);       // Reads Enabled
    delay(1);
  
for(int i=0; i<8; i++){       /// FOR LOOP
  int DD = digitalRead(DP[i]);
  Serial.println(DD);
  }
 
  delay(100);
}

It's the last bit that gives me headache:

Code:

for(int i=0; i<8; i++){       /// FOR LOOP
  int DD = digitalRead(DP[i]);
  Serial.println(DD);
  }

It seems that this bit prints whatever is coming from the serial as opposed to print the state of the pins. Where did I go wrong? Any suggestions would be appreciated!
« Last Edit: December 10, 2012, 02:20:53 pm by alkopop79 » Logged

London
Offline Offline
Full Member
***
Karma: 0
Posts: 192
Yes, we can (solder)!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I cleaned up the code a bit and still get strange results on the serial monitor.

Code:
char addressBit[15];
char dataBit[10];
int arrayIndex, i;
boolean startedA, endedA, flow = false;

int CE  = 47;
int OE  = 48;
int WE  = 49;

int AP[13] = {
  22,24,26,28,30,32,34,36,38,40,42,44,46};
int DP[8] =  {
  23,25,27,29,31,33,35,37};

void setup(){
  Serial.begin(9600);
  Serial.println("Enter address in decimal starting with the letter a and finishing it with a period!");
  Serial.println("Then enter data in decimal between d and comma!");
  for (i=2;i<10;i++) {
    pinMode(AP[i],OUTPUT); // address pins
  }
  for (i=9;i<14;i++) {
    pinMode(DP[i],INPUT); // data pins
  }
  // Setup Control Pins
  pinMode(CE, OUTPUT);
  pinMode(WE, OUTPUT);
  pinMode(OE, OUTPUT);
  pinMode(45, OUTPUT);

  // Setup Chip
  digitalWrite(CE, HIGH);
  digitalWrite(WE, LOW);
  digitalWrite(OE, HIGH);
}

void loop(){
  digitalWrite(45, HIGH);
  while(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == 'r') //beginning of the string
    {
      startedA = true;
      arrayIndex = 0;
      addressBit[arrayIndex] = '\0';
    }
    else if(aChar == '/') //end of string
    {
      endedA = true;
    }
    else if(startedA)
    {
      addressBit[arrayIndex] = aChar;
      arrayIndex++;
      addressBit[arrayIndex] = '\0';
    }
  } 
  if(startedA && endedA){ // string filled up
    int incomingByteA = atoi(addressBit); // Convert the string to an integer
    for(int j=0; j<13; j++){
      digitalWrite (AP[j], bitRead (incomingByteA,j));  // extract relevant bit and output on relevant pin.
      int a = bitRead (incomingByteA,j);
      //Serial.println(a);
    }
   
    // Get ready for the next time
    startedA = false;
    endedA = false;
    arrayIndex = 0;
    addressBit[arrayIndex] = '\0';
  }
 
   digitalWrite(WE,LOW);      // Write Disabled
    delay(1);
    digitalWrite(CE,HIGH);      // Chip enabled
    delay(1);
    digitalWrite(OE,HIGH);       // Reads Enabled
    delay(1);

  for(int i=0; i<8; i++){
    int data = digitalRead(DP[i]);
    Serial.print(data);
  }
  Serial.println(" ");
  delay(300);
}

Anyone could verify if it works? Just looking at the serial monitor doesn't help. Still struggle with that last for loop, I wish I knew how to execute it one!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46042
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I wish I knew how to execute it one!

Code:
bool doItThisTime = true;

void loop()
{
   // some stuff to do every time

   if(doItThisTime)
   {
      // some stuff to do once

      doItThisTime = false;
   }
}

Printing numbers to the serial monitor is an exercise in frustration unless you label them.

Code:
  Serial.println("Enter address in decimal starting with the letter a and finishing it with a period!");
    if(aChar == 'r') //beginning of the string
a != r!
Logged

London
Offline Offline
Full Member
***
Karma: 0
Posts: 192
Yes, we can (solder)!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I tried what you suggested and now it won't work. What did I do wrong?

Code:
char addressBit[15];
char dataBit[10];
int arrayIndex, i;
boolean startedA, endedA = false;
boolean once = true;

int CE  = 47;
int OE  = 48;
int WE  = 49;

int AP[13] = {
  22,24,26,28,30,32,34,36,38,40,42,44,46};
int DP[8] =  {
  23,25,27,29,31,33,35,37};

void setup(){
  Serial.begin(9600);
  Serial.println("Enter address in decimal starting with the letter a and finishing it with a period!");
  Serial.println("Then enter data in decimal between d and comma!");
  for (i=2;i<10;i++) {
    pinMode(AP[i],OUTPUT); // address pins
  }
  for (i=9;i<14;i++) {
    pinMode(DP[i],INPUT); // data pins
  }
  // Setup Control Pins
  pinMode(CE, OUTPUT);
  pinMode(WE, OUTPUT);
  pinMode(OE, OUTPUT);
  pinMode(45, OUTPUT);

  // Setup Chip
  digitalWrite(CE, HIGH);
  digitalWrite(WE, LOW);
  digitalWrite(OE, HIGH);
}

void loop(){
  digitalWrite(45, HIGH);
  while(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == 'r') //beginning of the string
    {
      startedA = true;
      arrayIndex = 0;
      addressBit[arrayIndex] = '\0';
    }
    else if(aChar == '/') //end of string
    {
      endedA = true;
    }
    else if(startedA)
    {
      addressBit[arrayIndex] = aChar;
      arrayIndex++;
      addressBit[arrayIndex] = '\0';
    }
  } 
  if(startedA && endedA){ // string filled up
    int incomingByteA = atoi(addressBit); // Convert the string to an integer
    for(int j=0; j<13; j++){
      digitalWrite (AP[j], bitRead (incomingByteA,j));  // extract relevant bit and output on relevant pin.
      int a = bitRead (incomingByteA,j);
      //Serial.println(a);
    }
   
    // Get ready for the next time
    startedA = false;
    endedA = false;
    arrayIndex = 0;
    addressBit[arrayIndex] = '\0';
  }
 
   digitalWrite(WE,LOW);      // Write Disabled
    delay(1);
    digitalWrite(CE,HIGH);      // Chip enabled
    delay(1);
    digitalWrite(OE,HIGH);       // Reads Enabled
    delay(1);
if(once){
  for(int i=0; i<8; i++){
    int data = digitalRead(DP[i]);
    Serial.print(data);
  }
  once = false;
  }
  Serial.println(" ");
  delay(300);
}


Logged

London
Offline Offline
Full Member
***
Karma: 0
Posts: 192
Yes, we can (solder)!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Printing numbers to the serial monitor is an exercise in frustration unless you label them.

Code:
  Serial.println("Enter address in decimal starting with the letter a and finishing it with a period!");
    if(aChar == 'r') //beginning of the string
a != r!

Not sure what you meant by that. Can you explain that please?
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46042
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
What did I do wrong?
It's more what you failed to do. That is, you failed to put each { on a new line. You failed to use Tools + Auto Format to fix the indenting.

Code that bounces
            all over the place is
    very hard to read. The
        Tools + Auto Format
menu item
                           fixes that problem.

Quote
Can you explain that please?
Sure. The message you print says that the text entered should start with an a. The code expects the text to start with an r. An a is not equal to an r.
Logged

London
Offline Offline
Full Member
***
Karma: 0
Posts: 192
Yes, we can (solder)!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh, cr*p, I copied it from an other sketch. Makes sense. Thanks you!
Logged

London
Offline Offline
Full Member
***
Karma: 0
Posts: 192
Yes, we can (solder)!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
t's more what you failed to do. That is, you failed to put each { on a new line. You failed to use Tools + Auto Format to fix the indenting.

Code that bounces
            all over the place is
    very hard to read. The
        Tools + Auto Format
menu item
                           fixes that problem.

I do use Auto Format it's just I can't stand the bracket taking up an extra line. Never thought it can be a problem.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46042
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
I do use Auto Format
Really? And it did this?

Code:
   digitalWrite(WE,LOW);      // Write Disabled
    delay(1);
    digitalWrite(CE,HIGH);      // Chip enabled
    delay(1);
    digitalWrite(OE,HIGH);       // Reads Enabled
    delay(1);
if(once){
  for(int i=0; i<8; i++){
    int data = digitalRead(DP[i]);
    Serial.print(data);
  }
  once = false;
  }
Logged

London
Offline Offline
Full Member
***
Karma: 0
Posts: 192
Yes, we can (solder)!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I appreciate your help and am grateful but I feel a but uncomfortable with your schooling.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46042
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I appreciate your help and am grateful but I feel a but uncomfortable with your schooling.
OK. I'll knock it off. The only reason I harp on this issue is that I feel that lining up the { and }, and doing consistent indenting, reveals a lot of issues with out-of-order execution and "why isn't his happening here" types of problems.

I suspect that that is why your print statements don't seem to be executed, but because nothing lines up, the only way for me to know that is to copy and paste your code into the IDE, put each { on a new line, and use Tools + Auto Format.
Logged

Pages: [1] 2   Go Up
Jump to: