|
Page 1 of 1
|
[ 3 posts ] |
|
Teaching Pointers and Data Structures for use in Datalogging
Author |
Message |
parkway
Moderator
Joined: Mon Oct 04, 2010 2:18 pm Posts: 196
|
 Teaching Pointers and Data Structures for use in Datalogging
I am attempting to teach an upcoming lesson on the use of pointers and data structures (once again, thanks Xander for the article http://botbench.com/blog/2013/05/08/robot-magazine-article-pointers-and-data-structures-in-robotc/) as they apply to datalogging. The students are to write a proportional line following program. Secondarily, they are to include the data logging because the line that they are following contains a lot of sharp curves. Therefore, I want them to be able to log their sensor and variable values so they can see how they need to adjust their program so that it can quickly follow the line. Below is my code and the comments. The code is borrowed heavily from Xander's article. I'm using his article to learn about pointers and datalogging so I can teach it to my students. I have two questions/requests: First, I am only getting one set of values on the LCD screen when I run the code. I hit the right arrow button to scroll through, but the values (with the exception of the index) never change. Second if anyone has any suggestions/comments on how I can teach this better, either by improving this code or doing something else, I am ears. Please let me know. Thanks,  |  |  |  | Code: #pragma config(Sensor, S3, lightSensor, sensorLightActive)
float Kp=1.5;//difference in light value readings/difference in motor speed int threshold = 56; int Tp=30;//max speed int error; int turn; int powerB; int powerC; const long DATAPOINTS = 500;
struct//variables that we are going to be using..they are in a structure { long motorencoderB; int turn; int powerB; int powerC; int error; long motorencoderC; int lightSensorValue; long timestamp; }tDataEntry;//data type
//array to hold our sensor and motor data
tDataEntry dataEntries[DATAPOINTS];
void readData (tDataEntry *data)//tDataEntry points to data { //individual members of the struct are accessed through the //"->" operator. reason we use "->" is because we are accessing a //pointer member through a structure
data->timestamp = nPgmTime/1000; data->lightSensorValue = (int)SensorValue[lightSensor]; data->turn = Kp * error; data->powerB = Tp - turn; data->powerC = Tp + turn; data->error = threshold - SensorValue[lightSensor];
}
void printData(int index, tDataEntry *data) {//show our information
nxtDisplayTextLine(1, "PowerB: %d", data->powerB); nxtDisplayTextLine(2, "PowerC: %d", data->powerC); nxtDisplayTextLine(3, "turn: %d", data->turn); nxtDisplayTextLine(4, "Time: %d",data->timestamp); nxtDisplayTextLine(5, "lightSensor: %d",data->lightSensorValue); nxtDisplayTextLine(6, "Error: %d",data->error); nxtDisplayTextLine(7, "<< %2d >>", index);
}
task main () { int index = 0; bool updateScreen = true;
//pointer to tDataEntry struct tDataEntry *dataPtr;
ClearTimer(T1);
while(time1[T1] < 7000) { error = threshold - SensorValue(lightSensor); turn = Kp * error; powerC = Tp + turn;//following the right side of the line powerB = Tp - turn; motor[motorB]=powerB; motor[motorC]=powerC; for (index = 0; index < DATAPOINTS; index++) { // dataPtr points to the address of the array of my //senror and variable values dataPtr = &dataEntries[index]; //now that I am pointing to the address of the array, I //can retrieve the values readData(dataPtr);
} motor[motorB] = 0; motor[motorC] = 0;
} // Reset the index index = 0;
while (true) { switch (nNxtButtonPressed) { case kLeftButton: index--; updateScreen = true; break;
case kRightButton: index++; updateScreen = true; break; }
// The user has pressed a button, so we need to fetch the // new data entry and update the screen if (updateScreen == true) { // Make sure we stay within the bounds of the array index = (index > (DATAPOINTS - 1)) ? DATAPOINTS - 1 : index; index = (index < 0) ? 0 : index;
// Point dataPtr to the new data entry dataPtr = &dataEntries[index];
// Print out the new data entry printData(index, dataPtr);
// Make sure we don't update the screen again updateScreen = false;
// wait for button to not be pressed anymore while(nNxtButtonPressed != kNoButton) wait1Msec(100); } wait1Msec(50);
}
} |  |  |  |  |
|
Fri Sep 20, 2013 12:20 pm |
|
 |
MHTS
Guru
Joined: Sun Nov 15, 2009 5:46 am Posts: 1523
|
 Re: Teaching Pointers and Data Structures for use in Datalog
Yes, this is because you overwrote the entire array with the last value set in every outer while loop. So every indexed structure in the array has the same values. I have corrected the problems and optimized it a little (e.g. getting rid of unnecessary global variables, optimized the loops etc). I haven't tested it though so hopefully it will work as expected.  |  |  |  | Code: #pragma config(Sensor, S3, lightSensor, sensorLightActive)
const float Kp=1.5;//difference in light value readings/difference in motor speed const int threshold = 56; const int Tp=30;//max speed const long DATAPOINTS = 500;
struct//variables that we are going to be using..they are in a structure { long timestamp; int lightSensorValue; int error; int turn; int powerB; int powerC; }tDataEntry;//data type
//array to hold our sensor and motor data tDataEntry dataEntries[DATAPOINTS];
// MHTS: I would call this recordData instead of readData // because that's what it is doing. void recordData (tDataEntry *data)//tDataEntry points to data { //individual members of the struct are accessed through the //"->" operator. reason we use "->" is because we are accessing a //pointer member through a structure
// MHTS: I would record in msec instead of dividing by 1000 since the // while loop is approx 50 msec. Otherwise, you will get a // lot of entries with the same timestamp. data->timestamp = nPgmTime; data->lightSensorValue = (int)SensorValue[lightSensor]; // MHTS: Doesn't really matter that much but I rearranged the order of // the following just because it seems backward to me. Also, made // it less dependent on global variables (generally a good practice). data->error = threshold - data->lightSensorValue; data->turn = Kp * data->error; data->powerB = Tp - data->turn; data->powerC = Tp + data->turn; }
void printData(int index, tDataEntry *data) {//show our information // MHTS: Again, doesn't really matter but I like to save LCD // lines since you only have 7 to play with. Also rearranged // the lines to make it more logical to look at in that order. nxtDisplayTextLine(1, "%3d: %d", index, data->timestamp); nxtDisplayTextLine(2, "lightSensor: %d",data->lightSensorValue); nxtDisplayTextLine(3, "Error: %d",data->error); nxtDisplayTextLine(4, "turn: %d", data->turn); nxtDisplayTextLine(5, "PowerB: %d", data->powerB); nxtDisplayTextLine(6, "PowerC: %d", data->powerC); }
task main () { int index = 0;
//pointer to tDataEntry struct tDataEntry *dataPtr;
ClearTimer(T1);
// MHTS: Line follow for 7 seconds??? while(time1[T1] < 7000) { // MHTS: You already have code in recordData() to do this. // Why not just use it. BTW, I think the logic in this // loop was wrong. Here is what I think it should be. dataPtr = &dataEntries[index]; recordData(dataPtr); motor[motorB]=dataPtr->powerB; motor[motorC]=dataPtr->powerC; index++; // MHTS: Make sure we wraparound the array when reaching the end. if (index >= DATAPOINTS) { index = 0; } wait1Msec(50); } // MHTS: Stop the motors outside of the loop. motor[motorB] = 0; motor[motorC] = 0; // Reset the index index = 0; TButtons prevButton = nNxtButtonPressed; TButtons currButton;
while (true) { // MHTS: The following logic will make sure // the buttons are debounced and not // repeating while you are holding it // down. Or else the index will jump // multiple slots even if you pressed it // just once. currButton = nNxtButtonPressed; if (currButton != prevButton) { // MHTS: We need to process the button only if it // changed. switch (currButton) { case kLeftButton: index--; if (index < 0) { // MHTS: I like to wrap around instead of stopping. index = DATAPOINTS - 1; } break;
case kRightButton: index++; if (index >= DATAPOINTS) { // MHTS: I like to wrap around instead of stopping. index = 0; } break; } prevButton = currButton; printData(index, &dataEntries[index]); } } } |  |  |  |  |
Last edited by MHTS on Sat Sep 21, 2013 3:34 pm, edited 2 times in total.
|
Fri Sep 20, 2013 4:54 pm |
|
 |
parkway
Moderator
Joined: Mon Oct 04, 2010 2:18 pm Posts: 196
|
 Re: Teaching Pointers and Data Structures for use in Datalog
Thank you very much. Especially for your comments in the code. That really helped to make things easy for me to understand. I look forward to testing this when I get to school on Monday.
|
Sat Sep 21, 2013 2:55 pm |
|
|
|
Page 1 of 1
|
[ 3 posts ] |
|
Who is online |
Users browsing this forum: No registered users and 2 guests |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|