Go Down

Topic: Control flow troubles (Read 1 time) previous topic - next topic

alkopop79

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: [Select]
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';
 }
}






MarkT

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

Replace this section of loop()
Code: [Select]
  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: [Select]
  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.
    }

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

alkopop79


MarkT

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.
[ I won't respond to messages, use the forum please ]

alkopop79

#4
Dec 10, 2012, 07:16 pm Last Edit: Dec 10, 2012, 08:20 pm by alkopop79 Reason: 1
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: [Select]
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: [Select]

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!

Go Up