London
Offline
Full Member
Karma: 0
Posts: 192
Yes, we can (solder)!
|
 |
« on: December 10, 2012, 08:05:41 am » |
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? 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
Tesla Member
Karma: 71
Posts: 6597
Arduino rocks
|
 |
« Reply #1 on: December 10, 2012, 08:13:29 am » |
What you did is fail to read the documentation for bitRead!! Replace this section of loop() 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: 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
|
|
|
|
|
London
Offline
Full Member
Karma: 0
Posts: 192
Yes, we can (solder)!
|
 |
« Reply #2 on: December 10, 2012, 08:22:21 am » |
Thank you!
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 71
Posts: 6597
Arduino rocks
|
 |
« Reply #3 on: December 10, 2012, 09:14:25 am » |
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
|
|
|
|
|
London
Offline
Full Member
Karma: 0
Posts: 192
Yes, we can (solder)!
|
 |
« Reply #4 on: December 10, 2012, 01:16:15 pm » |
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. 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: 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
Full Member
Karma: 0
Posts: 192
Yes, we can (solder)!
|
 |
« Reply #5 on: December 10, 2012, 02:58:34 pm » |
I cleaned up the code a bit and still get strange results on the serial monitor. 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
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #6 on: December 10, 2012, 03:12:49 pm » |
I wish I knew how to execute it one! 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. 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
Full Member
Karma: 0
Posts: 192
Yes, we can (solder)!
|
 |
« Reply #7 on: December 10, 2012, 03:25:27 pm » |
I tried what you suggested and now it won't work. What did I do wrong? 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
Full Member
Karma: 0
Posts: 192
Yes, we can (solder)!
|
 |
« Reply #8 on: December 10, 2012, 03:27:42 pm » |
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
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #9 on: December 10, 2012, 03:38:11 pm » |
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. 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
Full Member
Karma: 0
Posts: 192
Yes, we can (solder)!
|
 |
« Reply #10 on: December 10, 2012, 03:47:07 pm » |
Oh, cr*p, I copied it from an other sketch. Makes sense. Thanks you!
|
|
|
|
|
Logged
|
|
|
|
|
London
Offline
Full Member
Karma: 0
Posts: 192
Yes, we can (solder)!
|
 |
« Reply #11 on: December 10, 2012, 03:49:35 pm » |
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
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #12 on: December 10, 2012, 03:51:30 pm » |
I do use Auto Format Really? And it did this? 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
Full Member
Karma: 0
Posts: 192
Yes, we can (solder)!
|
 |
« Reply #13 on: December 10, 2012, 04:02:28 pm » |
I appreciate your help and am grateful but I feel a but uncomfortable with your schooling.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #14 on: December 10, 2012, 04:06:46 pm » |
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
|
|
|
|
|
|