Shop OBEX P1 Docs P2 Docs Learn Events
My SimpleBot — Parallax Forums

My SimpleBot

RsadeikaRsadeika Posts: 3,837
edited 2013-11-27 13:54 in Robotics
I just installed SimpleIDE 0-9-45 and the latest abdrive library, I noticed a couple of things, sonyremote.h is missing, and I am getting some unexpected things with the SD usage.

I thought that at one time that if you did not have an SD card inserted and tried to write to it, the program had a hang up, now it seems that the program does not care if you have an SD card inserted or not, it just continues on.

The actual writing to the SD card, in this program, is not what I am expecting. The program below I expect to see a 'START' and 'STOP' on separate lines, but all I see is 'STOP', on the same line, in the statAB0.txt file.

I am not sure what is going on, was there some changes made to the SD support program that we should be aware of?

Ray

/*
  SimpleBot.c

  Semi-autonomous ActivityBot.
  November 21, 2013
*/
#include "simpletools.h"
#include "abdrive.h"
#include "sonyremote.h"
#include "simpletext.h"
/////////////////////////////////////////////////////////////////////////////
volatile unsigned int IRpin = 8;

static volatile int speedLeft = 0;
static volatile int speedRight = 0;
static volatile int speedLeftOld = 0;
static volatile int speedRightOld = 0;

serial *xbee;

FILE *sp;

/* Function prototype */
int IR_remote(int irPin);
void ab_nav(void);

void statAB0(int status);

/////////////////////////////////////////////////////////////////////////////
int main()
{
  // Add startup code here.
/* SD socket pins. */
  int DO = 22, CLK = 23, DI = 24, CS = 25;
/* Mount SD card. */
  sd_mount(DO, CLK, DI, CS);
  pause(50);

/* Open serial port. */
/*                     Rx Tx MODE BAUD */
  xbee = fdserial_open(7, 6, 0, 9600);
  pause(50);

  int key = -1;

/* Start the diagnostic data log. */
  statAB0(1);
 
  while(1)
  {
    // Add main loop code here.
    key = IR_remote(IRpin);
    ab_nav();    
  }  
}
/////////////////////////////////////////////////////////////////////////////
void ab_nav(void)
{
  if(speedLeftOld != speedLeft || speedRightOld != speedRight)
  {
    drive_speed(speedLeft, speedRight);
    speedLeftOld = speedLeft;
    speedRightOld = speedRight;
  }
  pause(20);
}

/////////////////////////////////////////////////////////////////////////////
/* IR remote control */
int IR_remote(int irPin)
{
  int key;
  ir_tLimit(50);

  key = ir_key(irPin);
/* PWR key to stop bot. */
  if(key == PWR)
  {
    speedLeft = 0;
    speedRight = 0;
  }
/* CH_UP key to go forward. */
  if(key == CH_UP)
  {
    speedLeft = 32;
    speedRight = 32;
  }
/* CH_DN key to go backward. */
  if(key == CH_DN)
  {
    speedLeft = -32;
    speedRight = -32;
  }
/* VOL_UP key to turn right on center. */
  if(key == VOL_UP)
  {
    speedLeft = 10;
    speedRight = -10;
  }
/* VOL_DN key to turn left on center. */
  if(key == VOL_DN)
  {
    speedLeft = -10;
    speedRight = 10;
  }
/* 0 key to prepare for SimpleBot POWER OFF. */
  if(key == 0)
  {
    statAB0(0);
  }
  return key;
}

/////////////////////////////////////////////////////////////////////////////
/* SimpleBot diagnostic data log. */
void statAB0(int status)
{
  high(26);
  char start[] = {'S','T','A','R','T'};
  char stop[] = {'S','T','O','P'};
  char cr[] = {'\n'};

  sp = fopen("statAB0.txt","a");
  pause(50);

  if(status == 1)
  {
    fwrite(cr, 1, 1, sp);
    pause(50);
    fwrite(start, 1, 5, sp);
    pause(50);

    low(26);
  }
  else
  {
    fwrite(cr, 1, 1, sp);
    pause(50);
    fwrite(stop, 1, 4, sp);
    pause(50);

    fclose(sp);
    pause(50);
    high(27);
    high(26);
    while(1);  // Stop access to SimpleBot.
  }

}
«1

Comments

  • edited 2013-11-23 10:36
    Hi Ray,

    Most of the sd functions return 0 if success or an error code. It's up to your code to check. For an example, take a look at:

    ...Documents\SimpleIDE\Learn\Examples\Devices\Memory\SD with Tests.side

    Andy
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-11-23 13:14
    I made some changes to the program, but the one thing I can not get to work the way I want is the "a", which is to append to a file. I can get it to append while the ActivityBot is still powered, but when I power down the bot, and then power it up again, it seems that it over writes the existing data, and does not append to the end of the file. So I am wondering is that the way it is supposed to work or is there a problem with my SD?

    Ray
    /*
      SimpleBot.c
    
      Semi-autonomous ActivityBot.
      November 21, 2013
    */
    #include "simpletools.h"
    #include "abdrive.h"
    #include "sonyremote.h"
    #include "simpletext.h"
    /////////////////////////////////////////////////////////////////////////////
    volatile unsigned int IRpin = 8;
    
    static volatile int speedLeft = 0;
    static volatile int speedRight = 0;
    static volatile int speedLeftOld = 0;
    static volatile int speedRightOld = 0;
    
    serial *xbee;
    
    FILE *sp;
    
    /* Function prototype */
    int IR_remote(int irPin);
    void ab_nav(void);
    
    void statAB0(int status);
    
    /////////////////////////////////////////////////////////////////////////////
    int main()
    {
      // Add startup code here.
    /* SD socket pins. */
      int DO = 22, CLK = 23, DI = 24, CS = 25;
    /* Mount SD card. */
      int erc = sd_mount(DO, CLK, DI, CS);
      if(erc != 0)
      {
    /* If no SD card inserted, flash both LEDs */
        while(1)
        {
          high(26);
          high(27);
          pause(500);
          low(26);
          low(27);
          pause(500);
        }
      }
      else
      {
        sp = fopen("statAB0.txt", "w");
      }
      pause(50);
    
    /* Open serial port. */
    /*                     Rx Tx MODE BAUD */
      xbee = fdserial_open(7, 6, 0, 9600);
      pause(50);
    
      int key = -1;
    
    /* Start the diagnostic data log. */
      statAB0(1);
     
      while(1)
      {
        // Add main loop code here.
        key = IR_remote(IRpin);
        ab_nav();    
      }  
    }
    /////////////////////////////////////////////////////////////////////////////
    void ab_nav(void)
    {
      if(speedLeftOld != speedLeft || speedRightOld != speedRight)
      {
        drive_speed(speedLeft, speedRight);
        speedLeftOld = speedLeft;
        speedRightOld = speedRight;
      }
      pause(20);
    }
    
    /////////////////////////////////////////////////////////////////////////////
    /* IR remote control */
    int IR_remote(int irPin)
    {
      int key;
      ir_tLimit(50);
    
      key = ir_key(irPin);
    /* PWR key to stop bot. */
      if(key == PWR)
      {
        speedLeft = 0;
        speedRight = 0;
      }
    /* CH_UP key to go forward. */
      if(key == CH_UP)
      {
        speedLeft = 32;
        speedRight = 32;
      }
    /* CH_DN key to go backward. */
      if(key == CH_DN)
      {
        speedLeft = -32;
        speedRight = -32;
      }
    /* VOL_UP key to turn right on center. */
      if(key == VOL_UP)
      {
        speedLeft = 10;
        speedRight = -10;
      }
    /* VOL_DN key to turn left on center. */
      if(key == VOL_DN)
      {
        speedLeft = -10;
        speedRight = 10;
      }
    /* 0 key to prepare for SimpleBot POWER OFF. */
      if(key == 0)
      {
        statAB0(0);
      }
      return key;
    }
    
    /////////////////////////////////////////////////////////////////////////////
    /* SimpleBot diagnostic data log. */
    void statAB0(int status)
    {
      high(26);
      //char start[] = {'S','T','A','R','T'};
      //char stop[] = {'S','T','O','P'};
     // char cr[] = {'\n'};
    
      sp = fopen("statAB0.txt","a+");
      pause(50);
    
      if(status == 1)
      {
        //fwrite(cr, 1, 1, sp);
        //pause(50);
        //fwrite(start, 1, 5, sp);
        fwrite("START\r\n", 1, 7, sp);  // Need \r\n for actual CR written.
        pause(50);
        //fclose(sp);
        //pause(50);
    
        low(26);
      }
      else
      {
        //fwrite(cr, 1, 1, sp);
        //sp = fopen("statAB0.txt","a+");
        //pause(50);
        //fwrite(stop, 1, 4, sp);
        fwrite("STOP\n", 1, 5, sp);
        pause(50);
    
        fclose(sp);
        pause(50);
        high(27);
        high(26);
        while(1);  // Stop access to SimpleBot.
      }
    
    }
    
    
  • jazzedjazzed Posts: 11,803
    edited 2013-11-23 19:05
    Ray,

    Close and reopen a file to change the write behavior from "w" to "a".
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-11-24 03:20
    I think I got the append business working as expected, but now I have another problem, trying to log the volts float value. It seems I can get the first value written, but I cannot get the decimal point and the rest of the value written. The get_Volts() function provides a float value (6.7543), but all I am able to get written is the value (6), any ideas or hints as to how that should be done?

    Ray

    /////////////////////////////////////////////////////////////////////////////
    /* SimpleBot diagnostic data log. */
    void statAB0(int status)
    {
      float gvolts;
      char cvolts[] = {' ',' ',' '};
      high(26);
    
      sp = fopen("statAB0.txt","a");
      pause(50);
    
      if(status == 1)
      {
        fwrite("START\r\n", 1, 7, sp);  // Need \r\n for actual CR written.
        pause(50);
        gvolts = get_Volts();  // Get volts.
        pause(50);
        itoa(gvolts,cvolts,10);  // Convert to writable format.
        fwrite(cvolts,1,3, sp);  // Write volts.
        pause(50);
        fwrite("Volts\r\n", 1, 8, sp);
        pause(50);
        fclose(sp);
        pause(50);
        low(26);
      }
      else
      {
        sp = fopen("statAB0.txt","a");
        pause(50);
        fwrite("STOP\r\n", 1, 6, sp);
        pause(50);
        gvolts = get_Volts();  // Get volts.
        pause(50);
        itoa(gvolts,cvolts,10);  // Convert to writable format.
        fwrite(cvolts,1,3, sp);  // Write volts.
        pause(50);
        fwrite("Volts\r\n", 1, 8, sp);
        pause(50);
        fclose(sp);
        pause(50);
        high(27);
        high(26);
        while(1);  // Stop access to SimpleBot.
      }
    
    }
    
    int get_Volts()
    {
      float v3;
      v3 = adc_volts(3);
      v3 = v3*2;
    
      return v3;
    }
    
    
  • jazzedjazzed Posts: 11,803
    edited 2013-11-24 08:43
    Two functions in libsimpletext can be used to convert to/from float and a char buffer: sprint and sscan.

    The functions do not require the floating point library the way sprintf and scanf do, but they work about the same.
    A sprint snippet:
    char buffer[80];
    
    sprint(buffer, "Value of PI to 6 digits is %f\n", 3.14159);
    
    fwrite(buffer,1,strlen(buffer), filepointer);
    
    A sscan snippet:
    char *buffer = "3.14159 2.7128 1.414";
    float pi, e, root2;
    
    sscan(buffer, "%f %f %f\n", &pi, &e, &root2);
    
    fwrite(pi,1,sizeof(float), filepointer);
    fwrite(e,1,sizeof(float), filepointer);
    fwrite(root2,1,sizeof(float), filepointer);
    
    Both snippets are untested code fragments, but give the general idea.
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-11-25 02:06
    The function below needs to be scrubbed(code consolidated), but I am not sure how to go about it. I do see that I would probably have to come up with maybe three separate functions, 1. get_Volts() 2. get_Date() 3. get_Time(). Each one of these functions will have to have a 'return xx', for the get_Volts(), because it is dealing with an integer, that one I think I know how to deal with, not absolutely positive. The other two functions, because it deals with string variables, and the 'return xx' deals with integers, I have no idea as to how to approach this. How do I pass string variables between two functions?

    For the get_Time() and get_Date(), I created a Python script that runs on my Raspberry Pi (RPi). Since the RPi runs 24/7, and I use Putty to quickly start up the script, I find this to be a very good solution. This will probably be expanded to help out other ActivityBot/Boards in the future.

    So, again, I am open to suggestions and help.

    Ray

    /////////////////////////////////////////////////////////////////////////////
    /* SimpleBot diagnostic data log. */
    void statAB0(int status)
    {
      char cvolts[10];
      char inBuff[10];
      float v3;
      v3 = adc_volts(3);
      v3 = v3*2;
      sprint(cvolts,"%f",v3);
      high(26);
    
      sp = fopen("statAB0.txt","a");
      pause(50);
    
      if(status == 1)
      {
        fwrite("START\r\n", 1, 7, sp);  // Need \r\n for actual CR written.
        pause(50);
        writeStr(xbee,"dtime");  // Get time.
        pause(200);
        readStr(xbee,inBuff,10);  // Got time.
        pause(200);
        fwrite(inBuff, sizeof(char), sizeof(inBuff), sp);  // Write time.
        pause(50);
        fwrite("\r\n",1,2,sp);  // Write CR.
        pause(50);
        writeStr(xbee,"\nddate");  // Get date.
        pause(200);
        readStr(xbee, inBuff, 10);  // Got date.
        pause(200);
        fwrite(inBuff, sizeof(char), sizeof(inBuff), sp);  // Write date.
        pause(50);
        fwrite("\r\n",1,2,sp);  // Write CR.
        pause(50);
        fwrite(cvolts,1,strlen(cvolts), sp);  // Write volts.
        pause(50);
        fwrite(" Volts\r\n", 1, 8, sp);
        pause(50);
        fclose(sp);
        pause(50);
        low(26);
      }
      else
      {
        sp = fopen("statAB0.txt","a");
        pause(50);
        fwrite("STOP\r\n", 1, 6, sp);
        pause(50);
        writeStr(xbee,"dtime");
        pause(200);
        readStr(xbee,inBuff,10);
        pause(200);
        fwrite(inBuff, sizeof(char), sizeof(inBuff), sp);
        pause(50);
        fwrite("\r\n",1,2,sp);
        pause(50);
        writeStr(xbee,"\nddate");
        pause(200);
        readStr(xbee, inBuff, 10);
        pause(200);
        fwrite(inBuff, sizeof(char), sizeof(inBuff), sp);
        pause(50);
        fwrite("\r\n",1,2,sp);
        pause(50);
        fwrite(cvolts,1,strlen(cvolts), sp);  // Write volts.
        pause(50);
        fwrite(" Volts\r\n", 1, 8, sp);
        pause(50);
        fclose(sp);
        pause(50);
        high(27);
        high(26);
        while(1);  // Stop access to SimpleBot.
      }
    
    }
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-11-25 08:45
    This is a question about 'drive_getTicks'. In the code snippet below, I am trying to record the servo movements. The way it is setup is, when I press the 'PWR' button the 'drive_getTicks()' gets the ticks of the servo movement, it gets recorded then it waits for the next 'PWR'. I get a correct reading for the first movement, but the movements after that are incorrect. So for instance what I do is I hit the go forward button, I count to five, hit the 'PWR' then I hit the go backward button, count to five, record the session and read the values. What I am getting is, for example, L165,R165,L28,R28, now the last two should be in the 165 range, but it always shows a low number on repeated runs. Is there something else that has to be added to the code to get it too read from a zero starting point?

    Ray
    /* Part of the learn capability.
       Start a learn session.
    */
      if(key == ENTER)
      {
        high(26);
        lp = fopen("learnAB.txt", "a"); 
    
        pause(200);
        low(26);
      }
    /* Part of the learn capability.
       Stop a learn session.
    */
      if(key == MUTE)
      {
        high(26);
        
        fclose(lp);
        pause(50);
        low(26);
      }
    /* Part of the learn capability.
       Record a bot movement.
    */
      if(key != -1)
      {
        high(26);
    /* Record a key press. */
        char kval[] = {' ',' ',' ','\r','\n'};
        char lval[] = {' ','\r','\n'};
        char rval[] = {' ','\r','\n'};
        itoa(key, kval, 10);
        fwrite(kval,1,5,lp);
        pause(50);
    /* Check to see if PWR was pressed. */
        if(key == PWR)
        {
          int ticksL, ticksR;
    
          drive_getTicks(&ticksL, &ticksR);  // Get movement in tics.
          pause(50);
          itoa(ticksL,lval,10); // Convert left ticks to write value.
          pause(50);
          itoa(ticksR,rval,10);  // Convert right ticks to write value.
          pause(50);
          fwrite("L", 1, 1, lp);  // Label
          pause(50);
          fwrite(lval, 1, 3, lp);  // Write the left wheel.
          pause(50);
          fwrite("\r\n", 1, 2, lp);  // CR
          pause(50);
          fwrite("R", 1, 1, lp);
          pause(50);
          //drive_getTicks(&ticksL, &ticksR);  // Get movement in tics.
          //pause(50);
          //itoa(ticksR,rval,10);  // Convert to write value.
          //pause(50);
          fwrite(rval, 1, 3, lp);  // Write the right wheel.
          pause(50);
          fwrite("\r\n", 1, 2, lp);  // CR
          pause(50);
          //ticksL = 0;
          //ticksR = 0;
          speedLeft = 0;
          speedRight = 0;      
        }
        low(26);
      }
    
  • edited 2013-11-25 10:11
    Hi Ray,

    The first step in your debugging process should be to isolate the problem. Start by testing if the problem is in getTicks or the sd writing process. One way to go about this would be to comment sd writing stuff and display the values with print. To continue the debugging, let's say the values display correctly. Next, try displaying the strings you created with print (and %s), to see what they look like. You can use the result of this to determine the string manipulation or SD writing process needs attention.

    Another thing, you can use sprint with %d to write a decimal value to a string too; it's not just for float.

    Andy
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-11-25 12:28
    Below is a small example that sort of illustrates the problem I am having. When I run this program I expect to see the same value for both drive_speed, which in fact they are different. Now if I comment out the drive_speed(32,32) related code, and just run the drive_speed(-32,-32) related code, that works as expected. It seems to me that if you run the code back to back, the way I have it, it does not work the way I expect. What am I missing here?

    Ray
    /*
      test_AB1.c
    */
    #include "simpletools.h"
    #include "abdrive.h"
    
    int ticksL, ticksR;
    
    int main()
    {
      // Add startup code here.
      drive_speed(32,32);
      pause(3000);
      drive_getTicks(&ticksL, &ticksR);  
      print("ticksL = %d, ticksR = %d \n", ticksL, ticksR);
      drive_speed(0,0);
      pause(250); 
      drive_speed(-32,-32);
      pause(3000);
      drive_getTicks(&ticksL, &ticksR);  
      print("ticksL = %d, ticksR = %d \n", ticksL, ticksR);
      drive_speed(0,0);
    }
    
    
  • edited 2013-11-25 13:23
    Try drive_goto instead.
  • edited 2013-11-25 13:27
    You were also taking a snapshots of positions while the servos were still in motion. Try this instead:
    /*
      test_AB1.c
    */
    #include "simpletools.h"
    #include "abdrive.h"
    
    int ticksL, ticksR;
    
    int main()
    {
      // Add startup code here.
      drive_speed(0, 0);
      pause(250);
      drive_speed(32,32);
      pause(3000);
      drive_speed(0,0);
      pause(250); 
      drive_getTicks(&ticksL, &ticksR);  
      print("ticksL = %d, ticksR = %d \n", ticksL, ticksR);
      drive_speed(-32,-32);
      pause(3000);
      drive_speed(0,0);
      pause(250);
      drive_getTicks(&ticksL, &ticksR);  
      print("ticksL = %d, ticksR = %d \n", ticksL, ticksR);
    }
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-11-25 14:11
    I just tried your code, and I am getting the same results as my code, no improvement.

    Ray
  • edited 2013-11-25 14:25
    You should be getting 96 96 on the forward, and 0 0 on the backward. +/- a tick or two is reasonable since the control system needs to detect an error before it can correct it.
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-11-25 14:44
    ticksL = 96, ticksR = 96
    ticksL = -1, ticksR = -3
    I just ran the program again, I guess I will have to think about how 'drive_getTics()' could work for what I want to do, I was starting to think this would be an easy solution.

    Ray
  • edited 2013-11-25 14:46
    What are you trying to do?
  • SEvesSEves Posts: 1
    edited 2013-11-25 15:46
    Andy
    I am a student from St Lawrence College in Kingston Ontario
    We are trying to keep the robot moving but we are having
    a problem with the demand of the servos
    We have only a 2 volt threshold to play with where the
    robot will continue to move
    with a full charge 11 volts ~ the robot will work to
    9 volts and then the battry has to be charged
    Is the problem the type of servo drives that we are using for
    the wheels? any suggestions

    Steve
    seves@kingston.net
  • edited 2013-11-25 16:02
    Hi Steve,

    This looks like it might be a different topic. If so, please start a new thread. If you are using the material in learn.parallax.com, start the thread in this (Learn) forum. If this is different robot hardware (not ActivityBot), the Robotics forum would probably be a better home for the post. Please also be more specific about what kind of servo and other hardware you are using.

    Andy
  • dgatelydgately Posts: 1,628
    edited 2013-11-25 17:18
    Rsadeika wrote: »
    I just tried your code, and I am getting the same results as my code, no improvement.

    Ray

    I ran this on my ActivityBt and got the following:
    ticksL = 96, ticksR = 96 
    ticksL = -1, ticksR = -1 
    

    So, seems that the code is working basically as expected... Ray, Is your bot wired differently than the ActivityBot learn examples? Calibrated the encoders?


    dgately
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-11-26 02:10
    Yes, I have my ActivityBot wired just like the Learn tutorial shows. I had to calibrate the servos just before I started testing out my SimpleBot code, but I am noticing that the more use that the ActivityBot gets the more times that you have to calibrate the servos. I am not sure what is causing this, after all the calibration information is stored in the EEPROM, I think. I am wondering if, when you do a 'Load to EEPROM' of the program, maybe something gets changed in the top 32K? Maybe I will have to add, if I have enough room, the caliration program to my program, and have it re-calibrate after every 25th start up, or something along those lines.

    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-11-26 04:39
    I decided to run my SimpleBot program, and see what kind of data I was getting for the learn mode. I did a re-calibration of the servos, and the ActivityBot is sitting on some "blocks", meaning wheels are not contacting a surface. I am somewhat concerned with the right/left turn data, it should be showing (-) for the wheel that is going backwards. I guess I could make an assumption that the forward data is correct, and make it a negative number for a re-producible run. It is also showing a slight pull in the short runs that I made, it will be interesting to see what the data will show when I have the bot contacting a surface, and making a substantial longer run.

    Ray

    This is the actual data recording:
    11
    16
    21
    L79
    R79
    19
    19
    21
    L69
    R118
    16
    16
    21
    L135
    R193
    18
    18
    21
    L175
    R182
    16
    16
    21
    L262
    R259
    This the data analysis:
    11 - ENTER, start recording
    16 - CH+ , forward
    21 - PWR , stop
    L79 - forward tics left wheel, short run looks ok
    R79 - forward tics right wheel, short run looks ok
    19 - VOL- , left turn
    19 - Not sure why it recorded again
    21 - PWR , stop
    L69 - Left wheel, turn on center, this should be a negative number
    R118 - Right wheel, turn on center
    16 - CH+ , forward
    16 - Not sure why it recorded again
    21 - PWR , stop
    L135 - forward tics left wheel,
    R193 - forward tics right wheel, pulling to the left
    18 - VOL+, right turn
    18 - Not sure why it recorded again
    21 - PWR , stop
    L175 - Left wheel, turn on center
    R182 - Right wheel, turn on center, this should be a negative number
    16 - CH+ , forward
    16 - Not sure why it recorded again
    21 - PWR , stop
    L262 - forward tics left wheel
    R259 - forward tics right wheel, pulling to the right
  • edited 2013-11-26 10:28
    ...but I am noticing that the more use that the ActivityBot gets the more times that you have to calibrate the servos...

    Ray

    This is not enough information to go on. What are the symptoms you are correcting when you recalibrate? You have the ability to display calibration settings and stream data to XBee. If they really need to be recalibrated, the XBee data should show the inability of one wheel to keep up with another, or significant drift between drive_getTicks and drive_getTicksCalc, or movement with speed(0, 0), things like that. Please substantiate with data and test code.

    Andy
  • edited 2013-11-26 10:35
    I am somewhat concerned with the right/left turn data, it should be showing (-) for the wheel that is going backwards. I guess I could make an assumption that the forward data is correct, and make it a negative number for a re-producible run.

    Again, not enough data. It would help to have zipped test code attached to the post along with a brief description of what the application is trying to do in your post.

    Also, I suggested a test procedure yesterday for narrowing down the problem. What are the results from those tests?
  • edited 2013-11-26 11:49
    So, first step: Find out if drive_getTicks is returning correct negative/positive values. Here is a simple test to check that. It drives forward for 1 second at a speed of 32, then backward at a speed of 48, also for 1 second. The expected output would be a short stop at 32, 32, then a come to rest at -16, -16.
    #include "simpletools.h"
    #include "abdrive.h"
    
    int left, right;
    
    int main()                    
    {
      drive_speed(0, 0);
      pause(250);
    
      drive_speed(32, 32);
      pause(1000);
      drive_speed(0, 0);
      pause(250);
      drive_getTicks(&left, &right);
      print("left = %d, right = %d\n", left, right);
      
      drive_speed(-48, -48);
      pause(1000);
      drive_speed(0, 0);
      pause(250);
      drive_getTicks(&left, &right);
      print("left = %d, right = %d\n", left, right);
    }
    

    For my bot, it did turn out to be precise, calibrated on the ground and then run on the ground with the USB cable connected, but I wouldn't worry if it were a tick or two off.

    attachment.php?attachmentid=105240&d=1385494517

    The main point here is that we tested drive_getTicks and see that it is correctly displaying negative values.

    Now that that has been ruled out, we need to pick the next thing to focus on. Assuming you are using sprint to make the conversions from int to string, you could use print("myIntString = %s" myIntString) to test the output of sprint.

    Continue focusing on one thing at a time, and narrow down the problem that way. It's the most important way to find bugs in your code, and also to find a question that coders are willing to look at and give advice. Large application programs are less approachable, so when you have a small test program that produces unexpected output, it will attract interest and advice.
    549 x 192 - 16K
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-11-26 12:35
    Thanks Andy, I am getting closer to a solution. Putting that pause(250) in front of 'drive_getTics()' probably solved the problem, plus removing all of the pause(50) after the sprint() and fwrite() helped also. Now I have a possible new problem, the li-ion batteries. My statAB0() function is showing the battery voltage is at 6.5887, after I had it on a charge. I wonder if that might be contributing to the problem, I have to look and see if I have some replacements.

    Ray
  • edited 2013-11-26 13:30
    Thanks for the update Ray. The battery voltage is definitely an important data point. You're right, if the voltage measurement is correct, the batteries might be worn out. Lion batteries that are transitioning to worn out could also explain an abnormally frequent need to re-run the servo calibration.

    Now, what about the signs of the tick counts remaining positive. Is that resolved?

    Andy
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-11-26 13:52
    Yes, now I am starting to see negative signs where they are supposed be. The bigger problem is the batteries, not sure but there might be a problem with the bot li-ion battery pack. I just did a test, I found some li-ion batteries in my li-ion power pack/charger. I plugged that into the bot and had the voltage measured - 7.0655V, took out the batteries and plugged them into the bot battery pack, measured it - 6.5162V. I was expecting to see 7.0655V. The batteries were charged, flashing blue LEDs. Is that supposed to be what should be happening, that much of a voltage drop between the packs?

    Ray
  • edited 2013-11-26 14:11
    Hi Ray,

    With no load, my lions measure 7.7 V at the terminals, but at the barrel jack, it's 7.4 V. I'm assuming there's a diode at work there. With Propeller system load, battery voltage at the terminals is more or less unchanged, but barrel jack voltage drops to 7.2 V. So, like yourself, I'm seeing about 1/2 a volt difference.

    Take a look at its schematic.

    http://www.parallax.com/sites/default/files/downloads/28988-Li-ion-Boe-Bot-Power-Pack-A-Schematic.pdf

    There's D6 in series, a fuse, and a couple transistors. I could see that adding up to 1/2 a volt.

    Andy
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-11-26 14:31
    I just pulled the bot li-ion pack from my boebot, plugged that into the ActivityBot, measured it - 7.357V. I ran the program and it seems like the problems vanished. Definitely will have to run some tests to determine what a good useable voltage rate is. I already know that at 6.5V, and some problems start to appear. For anybody that is following this thread, my program makes use of the XBee Pro series 1 module, which definitely draws a lot of power, plus the constant use of the servos, that all starts to add up very quickly. Now I am thinking that for my program I have to figure out some way of letting me know when the battery voltage is getting close to the lower limit, which still has to be determined. It would be nice if the Activity Board had a couple of more LEDs, maybe a green one, and a red one. Any suggestions for a visual Que of the battery state, my breadboard is running out of space?

    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-11-27 02:40
    First I want to set the tone of this post, Parallax makes an excellent product line, and they are very very responsive too customer satisfaction. Having said that, the posts up till now have been my transparent observations, which should NOT be construed as an introduction to product confusion, nor is it in any way an indictment of product quality, they are just my observations which people can Learn from, while I keep making the same mistakes over an over again.

    The hardware:
    SimpleBot is an ActivityBot which is a stock build using the Learn tutorial and the pamphlet that came with the product, the only deviation from the stock build is the insertion of the li-ion battery pack. I do not have the dexterity or patience to do a stock implementation, so I have a well insulated "loose fit" that takes care of my problem. I have installed an XBee Pro series 1 module, an SD card, a ping device with support circuitry, an IR detector with support circuitry, and the battery voltage circuitry. Plus I have just enough room left to install a Parallax compass module, which will be done in the next prototype phase.

    The software:
    First I have to mention that I have a Raspberry Pi(RPi) that is running a real time/date server, which uses an XBee to broadcast the data. The SimpleBot program basically is IR remote controlled, which broadcasts commands to the RPi to get the real time/date data. The program has an init process and a shutdown procedure, plus a learn segment. The program starts up by opening up some files, one of which is statAB0.txt, broadcasts to the RPi for real time/date, does a battery voltage reading and records the data. The shutdown procedure is by pressing '0' which again requests a real time/date, and gets another battery voltage reading, then goes into no access mode, you have to power down.

    The learn mode basically uses the 'start' and 'mute' buttons to do a data recording/logging of the ActivityBot movements. The immediate use for this is it eliminates, or it least reduces the need for a tape measure and a protractor. I will probably have to implement a small interpreter so you will be able to play back the program that you will have developed from the learn mode session.

    This is just a brief overview of which way I am heading with this, today I will probably do some code scrubbing, add some more comments, and do some real trial runs using surface contact. I will try to post the program tomorrow, if I have not infused my body with to much serotonin and pumpkin pie.

    Ray
  • edited 2013-11-27 13:54
    Hi Ray,

    I am graduating your Rasberry Pi / XBee / TV remote/ ActivityBot Project from the Learn forum to the Projects forum. As you'll see from the descriptions of the two forums, Projects is a much better fit:

    - Project forum: "Post your in-process and completed projects here, made from Parallax products. We encourage you to provide a schematic, code, and an explanation."

    - Learn forum "Learners of all ages discuss Parallax tutorials, such as the Propeller C Learning System, Stamps in Class, PE Kit Labs, Shield-Bot, etc."

    We really appreciate your posts and the interesting projects that you publish. They are awesome, especially this one! I just want to try to make sure they are in the right places.

    Andy
Sign In or Register to comment.