View unanswered posts | View active topics It is currently Sun Dec 21, 2014 6:39 pm






Reply to topic  [ 3 posts ] 
Teaching Pointers and Data Structures for use in Datalogging 
Author Message
Moderator
Moderator

Joined: Mon Oct 04, 2010 2:18 pm
Posts: 196
Post 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
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1372
Post Re: Teaching Pointers and Data Structures for use in Datalog
parkway wrote:
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,

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
Profile
Moderator
Moderator

Joined: Mon Oct 04, 2010 2:18 pm
Posts: 196
Post 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
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 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

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.