Shop OBEX P1 Docs P2 Docs Learn Events
RemoteBot program — Parallax Forums

RemoteBot program

RsadeikaRsadeika Posts: 3,837
edited 2013-11-20 17:24 in Propeller 1
This is the start of the RemoteBot program, the first post contains a starting point with just the diluted RemoteBot.c code shown. I am showing the code so everybody can look at the statements that I have made, and if their are any objections, lets get it out of the way. From this point I will be putting everything into a zip file which will contain the use of SimpleIDE exclusively.

This is a working piece of code, and I notice that the code size, using CMM, is at 14,232 bytes. I am just getting started and I am at the half way point of memory available already, I guess code optimization starts now.



Ray

/**
 * @file RemoteBot.c
 *
 *
 * This is the main RemoteBot program start point.
 */
#include <propeller.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/sd.h>
#include <dirent.h>

extern _Driver _SimpleSerialDriver;
extern _Driver _FileDriver;

_Driver *_driverlist[] = {
    &_SimpleSerialDriver,
    &_FileDriver,
    NULL
};

char *FindChar(char *ptr, int val);

FILE *stdoutfile;
FILE *stdinfile;
FILE *cmdinfile;

void Help()
{
    printf("Commands - help, quit, \n");
}

char *SkipChar(char *ptr, int val)
{
    while (*ptr)
    {
        if (*ptr != val) break;
        ptr++;
    }
    return ptr;
}

char *FindChar(char *ptr, int val)
{
    while(*ptr)
    {
        if (*ptr == val) break;
        ptr++;
    }
    return ptr;
}

int tokenize(char *ptr, char *IOtokens[])
{
    int num = 0;
    
    while(*ptr)
    {
        ptr = SkipChar(ptr, ' ');
        if (*ptr == 0) break;
        if (ptr[0] == '>')
        {
            ptr++;
            if (ptr[0] == '>')
            {
                IOtokens[num++] = ">>";
                ptr++;
            }
            else
                IOtokens[num++] = ">";
            continue;
        }
        if (ptr[0] == '<')
        {
            ptr++;
            IOtokens[num++] = "<";
            continue;
        }
        IOtokens[num++] = ptr;
        ptr = FindChar(ptr, ' ');
        if (*ptr) *ptr++ = 0;
    }    
    return num;
}

int CheckRedirection(char **tokens, int num)
{
    int i, j;
    for (i = 0; i < num-1; i++)
    {
        if (!strcmp(tokens[i], ">"))
        {
            if (!stdoutfile)
            {
                perror(tokens[i+1]);
                stdoutfile = stdout;
                return 0;
            }
        }
        else if (!strcmp(tokens[i], ">>"))
        {
            stdoutfile = fopen(tokens[i+1], "a");
            if (!stdoutfile)
            {
                perror(tokens[i+1]);
                stdoutfile = stdout;
                return 0;
            }
        }
        else if (!strcmp(tokens[i], "<"))
        {
            stdinfile = fopen(tokens[i+1], "r");
            if (!stdinfile)
            {
                perror(tokens[i+1]);
                stdinfile = stdin;
                return 0;
            }
        }
        else
            continue;
        for (j = 1 + 2; j < num; j++) tokens[j-2] = tokens[j];
        i--;
        num -= 2;
    }
    return num;
}

/* This routine closes files that were open for redirection */
void CloseRedirection()
{
    if (stdinfile != stdin)
    {
        fclose(stdinfile);
        stdinfile = stdin;
    }
    if (stdoutfile != stdout)
    {
        fclose(stdoutfile);
        stdoutfile = stdout;
    }
}

/**
 * Main program function.
 */
int main(void)
{
    int num;
    char *IOtokens[10];
    uint8_t IObuff[40];
    
    stdinfile = stdin;
    stdoutfile = stdout;
    cmdinfile = stdin;
    
    waitcnt(CLKFREQ + CNT);
    printf("Start RemoteBot\n");
    
    while(1)
    {
        if (cmdinfile == stdin)
        {
            printf(":");
            fflush(stdout);
            gets(IObuff);
        }
        else if (!fgets(IObuff, 80, cmdinfile))
        {
            cmdinfile = stdin;
            continue;
        }
        num = tokenize(IObuff, IOtokens);
        num = CheckRedirection(IOtokens, num);
        if (num == 0) continue;
        if (!strcmp(IOtokens[0], "help"))
            Help();
        else if (!strcmp(IOtokens[0], "quit"))
            break;
        else
        {
            printf("Invalid command\n");
        }
        CloseRedirection();
    }
    printf("System Stop\n");
    return 0;
}
«1

Comments

  • jazzedjazzed Posts: 11,803
    edited 2012-12-15 17:31
    Hi Ray.

    The stdio file functions and standard printf are pretty big. There should be enough space left to do many useful things in CMM. Of course it's always good to optimize for size where possible on Propeller. We can put PASM in to "ECOG" if necessary and save some space if there is enough PASM.

    I look forward to following you on this project. I've been putting off doing my own PropBOE bot, but I have one with the tank tracks sitting on my desk and it is a little lonely sometimes. My grandson loves playing with the bot. There is some servo and ping code here somewhere on my PC that I've used. I'll see if I can find it. I do have some XBEE stuff I bought in the summer, but I have to find it LOL. I also have some Bluetooth modules for experimenting.

    I've been taking classes, but now that they are over I have more time for focused projects like this.

    --Steve
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-17 02:26
    Having a slight setback with the project, my PropBOE is not responding as expected. Since I have decided to use a threaded cognew, for the XBee component and a background run of batch/script files, this threaded cognew concept has to work in CMM mode.

    Since working with the PropBOE for a couple of days, some personal observations - the use of a dead load( as opposed to a spring load) uSD reader, on this board, is looking like it could be a real inconvenience. I have noticed that once you plug in the XBee module, fiddling around, inserting and extracting the uSD card will be a real test of your patience, and it might make a hot load of the uSD card, not feasible. I am already looking around for some rubber tipped needle nose pliers. Also for this project it would have been nice to have some built in IR, just like they have on the QuickStart HIB, I know you can not have everything on a single board. The other possible inconvenience, since I will have the li-ion boebot battery pack on board my boebot, how do you determine the charge status, via software, of the battery pack? I do not see a real solution for this, at this time. So, it looks like this project may have some very real limitations of usage. Now onto testing of the uSD reader.

    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-18 13:28
    I got my new replacement PropBOE, ran the HUB_RAM_Test, all Cogs are OK. I ran the filetest.c program in CMM mode, that works as expected. I also ran my threaded cognew program in CMM mode, and that worked as expected. I should get my boebot and related materials today, so, all systems are a go, back to my RemoteBot project.

    I wonder if anybody is working on a diagnostic suite for the Propeller and related boards, so the next time a glitch shows up it could be narrowed down very quickly to find out if it is hardware or software related. I guess it would have to be done in PropGCC, I do not see Spin as a viable alternative for something like that. Maybe those tools are already available, but hidden somewhere on the forum.


    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-20 08:28
    Since this project is RemoteBot, I am testing out the communication between RemoteBot and a base unit, using XBee. Below is a program for the base unit, to send out some characters it works as expected, but as soon as I put in the 'inbuff = fgetc(Xbee);' the program stops working, or a least it no longer gets the next keypress. There is something with fgetc() that I am not understanding.

    On the RemoteBot I have 0,1, 2 commands that the base unit should respond to. 0 - Sends out "RemoteBot\n", 1 - Turns on an LED, 2 - Turns off the LED. On the RemoteBot program I am using a spin2cpp converted XBee.spin program, that seems to be working pretty good. On the base unit I thought I would try to develop a C utility that would control the XBee module. So, any help would be appreciated.

    Thanks

    Ray

    /**
     * @file Xbase.c
     * This is the main Xbase program start point.
     */
    #include <propeller.h>
    #include <stdio.h>
    
    extern _Driver _SimpleSerialDriver;
    extern _Driver _FullDuplexSerialDriver;
    
    _Driver *_driverlist[] = {
        &_SimpleSerialDriver,
        &_FullDuplexSerialDriver,
        NULL
    };
    
    
    /**
     * Main program function.
     */
    int main(void)
    {
        FILE *Xbee = fopen("FDS:9600,7,6","r+"); // Init Xbee
        usleep(250);
        fprintf(Xbee,"ATMY",0);  // Init Xbee
        
        char coutput;
        char inbuff;
        while(1)
        {
    
            coutput = getchar(); //gets keypress
    
            fprintf(Xbee,"%c",coutput); //Sends it out XBee
            usleep(250);
           // inbuff = fgetc(Xbee);
           // printf("%c",inbuff);
    
            //usleep(2500);
        }
        return 0;
    }
    
  • jazzedjazzed Posts: 11,803
    edited 2012-12-20 09:46
    Turn off buffering and echo.
    void makeraw()
    {
      setvbuf(stdin, NULL, _IONBF, 0); // no buffering stdin
      setvbuf(stdout, NULL, _IONBF, 0); // no buffering stdout
      stdin->_flag &= ~_IOCOOKED; // turn off echo [URL="http://propgcc.googlecode.com/hg/doc/Library.html#cooked"]
    [/URL]}
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-21 04:06
    I am getting close, but I am not there yet. In the program below I am using makeraw() with some interesting things happening. I am using '.' to break out of the first do ... while loop, but when I use '\n' or '13', they do not work to break out of the loop. I can not seem to get the right combination for a break out on 'CR'. Is there some other way to accomplish this?

    Ray
    /**
     * @file Xbase.c
     * This is the main Xbase program start point.
     */
    #include <propeller.h>
    #include <stdio.h>
    
    extern _Driver _SimpleSerialDriver;
    extern _Driver _FullDuplexSerialDriver;
    
    _Driver *_driverlist[] = {
        &_SimpleSerialDriver,
        &_FullDuplexSerialDriver,
        NULL
    };
    
    void makeraw()
    {
      setvbuf(stdin, NULL, _IONBF, 0); // no buffering stdin
      setvbuf(stdout, NULL, _IONBF, 0); // no buffering stdout
      stdin->_flag &= ~_IOCOOKED; // turn off echo 
    }
    
    /**
     * Main program function.
     */
    int main(void)
    {
        FILE *Xbee = fopen("FDS:9600,7,6","r+"); // Init Xbee
       
        usleep(250);
        fprintf(Xbee,"ATMY",0);  // Init Xbee
    
        makeraw();
            
        char coutput;
        char inbuff;
        while(1)
        {
    
            do {
            coutput = getchar(); //gets keypress
            fprintf(stdout,"%c",coutput);
            fprintf(Xbee,"%c",coutput); //Sends it out XBee
            fflush(Xbee);
            //usleep(250);
            } while (coutput != '.');
    //        printf("CR");
    //        fflush(stdout);
            fprintf(Xbee,"%c",coutput);
            fflush(Xbee);
            do {
            inbuff = fgetc(Xbee);               
            printf("%c",inbuff);
            fflush(stdout);
            fflush(Xbee);
            } while (inbuff != '\n');
            //usleep(2500);
            
        }
        return 0;
    }
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-21 06:30
    While I am trying to figure out how to make '\n' work in the do ... while loop, the program below has some pthread code. When I run the program in CMM, it runs as expected, the LED flashes. The problem is when I switch it to LMM, XMMC, or XMM-Single, the LED just lights up and stays lit, no flashing. I thought the pthreads were supposed to work in LMM and XMMC modes?

    Ray
    /**
     * @file Xbase.c
     * This is the main Xbase program start point.
     */
    #include <propeller.h>
    #include <stdio.h>
    #include <pthread.h>
    #include <unistd.h>
    
    
    extern _Driver _SimpleSerialDriver;
    extern _Driver _FullDuplexSerialDriver;
    
    _Driver *_driverlist[] = {
        &_SimpleSerialDriver,
        &_FullDuplexSerialDriver,
        NULL
    };
    
    void *do_job1(void *arg)
    {
        pthread_set_affinity_thiscog_np();
        pthread_detach(pthread_self());
        
    
        while(1)
        {
            high(27);
            usleep(500000);
            low(27);
            usleep(500000);
    //        sleep(2);
        }
    }
    
    void makeraw()
    {
      setvbuf(stdin, NULL, _IONBF, 0); // no buffering stdin
      setvbuf(stdout, NULL, _IONBF, 0); // no buffering stdout
      stdin->_flag &= ~_IOCOOKED; // turn off echo 
    }
    
    int high(int WCpin)
    {
        unsigned int bits = 1 << WCpin;
        DIRA |= bits;
        OUTA |= bits;
    }
    
    int low(int WCpin)
    {
        unsigned int mask = 1 << WCpin;
        DIRA |= mask;
        OUTA &= ~mask;
    }
    
    pthread_t thr[1];
    
    /**
     * Main program function.
     */
    int main(void)
    {
        int i;
        pthread_create(&thr[i], NULL, do_job1, NULL);
    
        FILE *Xbee = fopen("FDS:9600,7,6","r+"); // Init Xbee
       
        usleep(250);
        fprintf(Xbee,"ATMY",0);  // Init Xbee
    
        makeraw();
            
        char coutput;
        char inbuff;
    
    //    high(27);
    //    usleep(2000000);
    //    low(27);
            
        waitcnt(CLKFREQ + CNT);
        printf("Start of Program\n");
        while(1)
        {
    
            do {
            coutput = getchar(); //gets keypress
            fprintf(stdout,"%c",coutput);
            fprintf(Xbee,"%c",coutput); //Sends it out XBee
            fflush(Xbee);
           // usleep(250);
            } while (coutput != '.');
    //        printf("CR");
    //        fflush(stdout);
            fprintf(Xbee,"%c",coutput);
            fflush(Xbee);
            printf("\n");
            fflush(stdout);
            do {
            inbuff = fgetc(Xbee);               
            printf("%c",inbuff);
            fflush(stdout);
            fflush(Xbee);
            } while (inbuff != '\n'); 
            //usleep(2500);
            
        }
        return 0;
    }
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-21 09:08
    I sort of narrowed down the problem with the LED not flashing in the pthread. By removing the 'extern _Driver _SimpleSerialDriver;' and the reference in the driverlist, the LED is back to flashing again. I am not sure what 'extern _Driver _SimpleSerialDriver;' has in it that would make the pthread misbehave. I have still not found a solution for the '\n' not working in the first do ... while loop. It seems I can not find a way of doing a CR to break out of the do .. while loop.

    Ray

    //extern _Driver _SimpleSerialDriver;
    extern _Driver _FullDuplexSerialDriver;
    
    _Driver *_driverlist[] = {
    //    &_SimpleSerialDriver,
        &_FullDuplexSerialDriver,
        NULL
    };
    
  • jazzedjazzed Posts: 11,803
    edited 2012-12-21 10:37
    There seems to be an issue with pthread_detach() between reprogramming. It can happen in any mode. Please remove the call to pthread_detach().

    As far as '\n' goes, different programs send different characters for enter. In the SimpleIDE, the terminal can be set to force using '\n' for enter instead of '\r'. I do not have xbee set up yet to test this. I'll have to turn my office upside down to find it :)
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-21 14:04
    Well, I just got my goodie box from Parallax. I purchased a couple of their Xmas stockings, which are now hanging above the fireplace, will check it out on Xmas day. I also finally got my boebot, so tomorrow I will probably try to zero in the servo drives. I would imagine the quickest way will be to convert, using spin2cpp, some existing Spin files, and go from there.

    I also picked up an XBee PC module, which I tested with my personal terminal program, that worked without any problems. I will probably have to develop a specific terminal program so I can talk to the boebot, although the terminal program that I have will probably work for the short term.

    The project for tomorrow will be to zero in the servo drives, and come up with some commands for making the boebot move back and forth. Anybody have any C code examples for doing this?

    The other stuff that I got, Digital Wheel Encoder, a PING, and a Sensirion temp module, I think my boebot will be a working robot. Man am I going to need a lot of C code examples.

    Ray
  • jazzedjazzed Posts: 11,803
    edited 2012-12-21 15:12
    Here is my Propeller-GCC servo code. Press 's' will send the stop PWM. Align servos so they don't move.
    /**
     * @file pboeservo.c
     * This is the main program start point.
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/thread.h>
    #include <propeller.h>
    
    
    #include "propboe1.h"
    
    
    /* These numbers define servo stop pulse width */
    #define LEFT_CENTER 1500
    #define RIGHT_CENTER 1500
    
    
    /* stacks for COGs */
    static int LeftServoStack  [STACK_SIZE];
    static int RightServoStack [STACK_SIZE];
    
    
    /* per-thread library variables */
    static _thread_state_t LeftThreadData;
    static _thread_state_t RightThreadData;
    
    
    /* WheelServo COG variables */
    int LeftServoSpeed;
    int RightServoSpeed;
    int LeftRotation;
    int RightRotation;
    
    
    static int MaxServoSpeed = 100;
    
    
    /*
     * Servo COG function
     */
    void LeftServoThread(void *arg __attribute__((unused)))
    {
        int pinmask = (1<<LEFT_SERVO_PIN);
        int center = LEFT_CENTER;
        int ustime = CLKFREQ/1000000;
    
    
        DIRA |= pinmask;
    
    
        for(;;) {
            /* start with signal off */
            OUTA &= ~pinmask;
    
    
            if(LeftServoSpeed == 0) {
                waitcnt(ustime*center+CNT);
                LeftRotation = 0;
                continue;
            }
    
    
            if(LeftServoSpeed > MaxServoSpeed)
                LeftServoSpeed = MaxServoSpeed;
            if(LeftServoSpeed < -MaxServoSpeed)
                LeftServoSpeed = -MaxServoSpeed;
    
    
            /* move servo */
            LeftRotation = (-LeftServoSpeed/2*center)/MaxServoSpeed+center;
            waitcnt(ustime*center+CNT);
            OUTA |=  pinmask;
            waitcnt(ustime*LeftRotation+CNT);
            OUTA ^=  pinmask;
        }
    }
    
    
    /*
     * Servo COG function
     */
    void RightServoThread(void *arg __attribute__((unused)))
    {
        int pinmask = (1<<RIGHT_SERVO_PIN);
        int center = RIGHT_CENTER;
        int ustime = CLKFREQ/1000000;
    
    
        DIRA |= pinmask;
    
    
        for(;;) {
            /* start with signal off */
            OUTA &= ~pinmask;
    
    
            if(RightServoSpeed == 0) {
                waitcnt(ustime*center+CNT);
                RightRotation = 0;
                continue;
            }
    
    
            if(RightServoSpeed > MaxServoSpeed)
                RightServoSpeed = MaxServoSpeed;
            if(RightServoSpeed < -MaxServoSpeed)
                RightServoSpeed = -MaxServoSpeed;
    
    
            /* move servo */
            RightRotation = (RightServoSpeed/2*center)/MaxServoSpeed+center;
            waitcnt(ustime*center+CNT);
            OUTA |=  pinmask;
            waitcnt(ustime*RightRotation+CNT);
            OUTA ^=  pinmask;
        }
    }
    
    
    
    
    void startServoThreads(void)
    {
        int n;
        n = _start_cog_thread(LeftServoStack + STACK_SIZE, LeftServoThread, NULL, &LeftThreadData);
        dprintf("Left Servo COG thread %d\n", n);
        n = _start_cog_thread(RightServoStack + STACK_SIZE, RightServoThread, NULL, &RightThreadData);
        dprintf("Right Servo COG thread %d\n", n);
    }
    
    
    void botStop(void)
    {
        LeftServoSpeed = 0;
        RightServoSpeed = 0;
    }
    
    
    void botForward(int rate)
    {
        LeftServoSpeed = rate;
        RightServoSpeed = rate;
    }
    
    
    void botReverse(int rate)
    {
        LeftServoSpeed = -rate;
        RightServoSpeed = -rate;
    }
    
    
    void botLeftTurn(int rate)
    {
        LeftServoSpeed = 0;
        RightServoSpeed = rate;
    }
    
    
    void botRightTurn(int rate)
    {
        LeftServoSpeed = rate;
        RightServoSpeed = 0;
    }
    
    
    void botLeftSpin(int rate)
    {
        LeftServoSpeed = rate;
        RightServoSpeed = -rate;
    }
    
    
    void botRightSpin(int rate)
    {
        LeftServoSpeed = -rate;
        RightServoSpeed = rate;
    }
    
    
    /**
     * Main program function.
     */
    int propBoeServoTest(void)
    {
        int move = 's';
        int speed = 100;
        int ustime = CLKFREQ/1000000;
    
    
        /* keep QuickStart TX quiet. */
        DIRA |= (1<<30);
    
    
        setbuf(stdout, 0);
        setbuf(stdin, 0);
        waitcnt(500*(CLKFREQ/1000)+CNT);
    
    
        startServoThreads();
        botStop();
    
    
        for(;;) {
            putchar(0);
            printf("PropBOE Servo Test\n");
            printf("Last Command '%c'. Speed %d\n", move, speed);
            printf("LeftRotation = %d ",LeftRotation);
            printf("RightRotation = %d\n",RightRotation);
            printf("LeftServoSpeed = %d ",LeftServoSpeed);
            printf("RightServoSpeed = %d\n",RightServoSpeed);
            printf("\n$ ");
            move = getchar();
            getchar();
            switch(move) {
                case 'f':
                    botForward(speed);
                    printf("forward %d\n", speed);
                break;
                case 'b':
                    botReverse(speed);
                    printf("backward %d\n", speed);
                break;
                case 'l':
                    botLeftTurn(speed);
                    printf("left  turn %d\n", speed);
                break;
                case 'r':
                    botRightTurn(speed);
                    printf("right turn %d\n", speed);
                break;
                case 'L':
                    botLeftSpin(speed);
                    printf("left  spin %d\n", speed);
                break;
                case 'R':
                    botRightSpin(speed);
                    printf("right spin %d\n", speed);
                break;
                case 's':
                    botStop();
                    printf("stop\n");
                break;
                case '+':
                    speed += 100;
                    printf("speed %d\n", speed);
                break;
                case '-':
                    speed -= 100;
                    printf("speed %d\n", speed);
                break;
            }
    
    
        }
    
    
        return 0;
    }
    
    
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-22 06:20
    Below is a program that uses the XBee for communication with propboe. It works, but it is having a lot of problems with the buffer, when I access from a terminal program I get a few unwanted characters showing up on the screen. I do an fflush(Xbee), but that does not seem to help, so I am not sure where the fix would be. Generally speaking the program works as expected, except for the unexpected characters appearing on the external terminal screen. I am using my personal terminal program, and I double check with the PST program, the results are always the same.

    I want to get this XBee interaction sorted out before I start to zero in the servo drives.

    I gave up on the pthread version, it was also having problems with the buffer, plus when I started up another pthread the program compiled but it crashed when I tried to use it. I guess I want to get something somewhat reliable to work with before I start driving the boebot around from a remote terminal.

    Ray
    /**
     * @file RemBot2.c
     * This is the main RemBot2 program start point.
     */
    #include <propeller.h>
    #include <stdio.h>
    
    extern _Driver _FullDuplexSerialDriver;
    
    _Driver *_driverlist[] = {
        &_FullDuplexSerialDriver,
        NULL
    };
    
    int high(int WCpin)
    {
        unsigned int bits = 1 << WCpin;
        DIRA |= bits;
        OUTA |= bits;
    }
    
    int low(int WCpin)
    {
        unsigned int mask = 1 << WCpin;
        DIRA |= mask;
        OUTA &= ~mask;
    }
    
    /**
     * Main program function.
     */
    int main(void)
    {
    
        uint8_t buffer[40];
        
        FILE *Xbee = fopen("FDS:9600,13,12","r+");
        usleep(250);
    
        while(1)
        {
            fprintf(Xbee,":");
            fflush(Xbee);
            fscanf(Xbee, "%s", buffer);
            if (!strcmp(buffer, "ledon"))
                high(6);
            else if (!strcmp(buffer, "ledoff"))
                low(6);
            else
            {
                fprintf(Xbee,"Invalid Command\n");
                fflush(Xbee);
            }
        }
        return 0;
    }
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-22 14:37
    Below is a working as expected program that jazzed provided, what I did was add an XBee component. On your PropBOE you need an XBee installed, and on your PC you need an XBee attached, on the terminal program use the 'echo on' feature.

    A couple of things, I am not sure if the speed adjustment is working correctly, when I tried it, seemed like the speed was not being affected. The other thing, I can not figure out what kind of threading the program uses. When I run the program in CMM and LMM it works as expected, but when I tried it in XMMC, the program did not work. So, it seems that the program is not using pthreads, but what do I know.

    Ray
  • jazzedjazzed Posts: 11,803
    edited 2012-12-22 14:53
    Ray, the program uses LMM/CMM cogs (which is basically cogstart using a different function) and is not available with XMM/C modes.
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-23 04:06
    I noticed that the starting point for servo speed is set at 100, and if I increase the speed value to 600/-600 the servos behave badly. I was trying to create a governor on the speed control so it does not exceed 500/-500 but my code below is not working as expected. I think when I was using the '+' control, the servos started to go backwards, not sure why that is occurring. Anybody see what the problem is?

    Ray
                case '+':
                    if (speed == 500) // Speed governer
                    {
                        MaxServoSpeed = speed;
                    }
                    else
                    {
                    speed += 50;  // Used to be += 100
                    MaxServoSpeed = MaxServoSpeed + speed;
                    }
                    
                break;
                /* Robot decrease speed. */
                case '-':
                    if (speed == 50)  // Speed governer
                    {
                        MaxServoSpeed = speed;
                    }
                    else
                    {
                        speed -= 50;  // Used to be -= 100
                        MaxServoSpeed = MaxServoSpeed - speed;
                    }
                break;
    
  • jazzedjazzed Posts: 11,803
    edited 2012-12-23 10:08
    Sorry I didn't mention it in the .c file. Speed or rate is a percentage (0 to 100).

    From the header for example ....
    /**
     * move bot forward at %rate
     */
    void botForward(int rate);
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-25 10:39
    I was doing some experimenting with pthreads, again, trying to come up with a program that would run the servos in a thread instead of a cog. And the big problem is trying to get around the waitcnt() commands in the function. The question is, is there another way of coding the thread, and still be able to have a functioning servo? The example that they have in the documentation for the servo, for Spin programs, uses waitcnt() commands to get the servo to work. I was trying to get it down to the simplest C code structure, but those waitcnt() commands are doing me in. I am not seeing a solution to the problem.

    Ray
    void LeftServoThread(void *arg __attribute__((unused)))
    {
        int pinmask = (1<<LEFT_SERVO_PIN);
        int center = LEFT_CENTER;
        int ustime = CLKFREQ/1000000;
        
        DIRA |= pinmask;
        
        for(;;) {
            OUTA &= ~pinmask;
        
            if(LeftServoSpeed == 0) {
                waitcnt(ustime*center+CNT);
                LeftRotation = 0;
                continue;
            }
            if(LeftServoSpeed > MaxServoSpeed)
                LeftServoSpeed = MaxServoSpeed;
            if(LeftServoSpeed < -MaxServoSpeed)
                LeftServoSpeed = -MaxServoSpeed;
                
            LeftRotation = (-LeftServoSpeed/2*center)/MaxServoSpeed+center;
            waitcnt(ustime*center+CNT);
            OUTA |= pinmask;
            waitcnt(ustime*LeftRotation+CNT);
            OUTA ^= pinmask;
        }
    }
    
  • jazzedjazzed Posts: 11,803
    edited 2012-12-25 13:07
    Rsadeika wrote: »
    ... I was trying to get it down to the simplest C code structure, but those waitcnt() commands are doing me in. I am not seeing a solution to the problem.

    There is no solution.

    Pthreads is designed to be used for general computing purposes. You can not use waitcnt() with pthreads because it breaks scheduling since the thread will hog the processor. Even if pthreads was implemented using pre-emptive multi-tasking, pthreads would not be deterministic enough to run a servo.

    So, you see, there is no timing deterministic solution using pthreads. However, one could use usleep() and test for CNT to be a certain value. However, there is no guarantee that you will end up with exactly the wait time that you want though, and it gets worse with more pthreads. So, it's better to do what's natural with Propeller.

    This situation highlights what Propeller is all about: I.E. Separate COGs doing deterministic things.

    Similar things can be done with timers in other MCUs but there is always the possibility of over-running the time allowed for a task (processor hogging) in that situation.

    --Steve
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-29 08:58
    The program I have below is trying to figure out how to implement the speed control. The problem that I am having is the implementation of '-' and '+' commands, it seems the only affect that it is showing is the change in the speed variable. As far as I can tell it is not having an affect on the RightRotation variable, which is supposed to reduce the value of 1500, which in turn reduces the rotation speed of the servo. All the different things that I have tried so far, nothing seems to change the value of RightRoation, so it just stays at 1400, which means full speed.

    I guess another explanation that I need is what the heck is this doing:
    DIRA |= pinmask;
    OUTA &= ~pinmask;
    OUTA |= pinmask;
    OUTA ^= pinmask;
    Is this changing the value of pinmask? Since I have pinmask = 18, is it changing it to 0? I sort of figured out the use of waitcnt() as a method of doing pulse width modulation, I think, but the bitwise stuff is really got me stumped. Once I get the speed control issue resolved, I may try the encoder stuff that I bought.

    Ray
    /**
     * @file TestRemBot.c
     * This is the main TestRemBot program start point.
     */
    #include <propeller.h>
    #include <stdio.h>
    //#include <stdlib.h>
    #include <sys/thread.h>
    
    #define STACK_SIZE 32
    
    #define RIGHT_SERVO_PIN 18
    
    #define RIGHT_CENTER 1500
    
    static int RightServoStack [STACK_SIZE];
    
    static _thread_state_t RightThreadData;
    
    int RightServoSpeed;
    int RightRotation;
    
    static int MaxServoSpeed = 100;
    
    void RightServoThread(void *arg __attribute__((unused)))
    {
        int pinmask = (1<<RIGHT_SERVO_PIN);
        int center = RIGHT_CENTER;
        int ustime = CLKFREQ/1000000;
        
        DIRA |= pinmask;
        
        for(;;) {
            OUTA &= ~pinmask;
            /* This holds the servo quiet */
            if(RightServoSpeed == 0) {
                waitcnt(ustime*center+CNT);
                RightRotation = 0;
                continue;
            }
            /*                 100      -100                                 */
            /*          ( 0 or rate or -rate / 2 * 1500)/ 100        + 1500  */
            /* 1500 or if 100 {1875 or - 1875} or variations on  + or - 100 */
    //        RightRotation = (-RightServoSpeed/2*center)/MaxServoSpeed+center;
            RightRotation = (-RightServoSpeed) + 1500;
            
               /* Set servo to center */
            waitcnt(ustime*center+CNT); /* CLKFREQ/1000000 * 1500 + CNT */
      /* Output bitwise pin    */
     /*  state   OR      18    */
            OUTA |= pinmask; /* Affects pin number  */
               /* Set servo to 1300 or less to go forward */
            waitcnt(ustime*RightRotation+CNT);  /* CLKFREQ/1000000 * RR + CNT */
            OUTA ^= pinmask;       
        }
    }
    
    
    void startServoThreads(void)
    {
        int n;
        n = _start_cog_thread(RightServoStack + STACK_SIZE, RightServoThread, NULL, &RightThreadData);
    }
    
    void botStop(void)
    {
        RightServoSpeed = 0;
    }
    
    void botForward(int rate)
    {
        RightServoSpeed = rate;
    }
    
    void botReverse(int rate)
    {
        RightServoSpeed = -rate;
    }
    
    /**
     * Main program function.
     */
    int main(void)
    {
        int move = 's';
        int speed = 100;
        int ustime = CLKFREQ/1000000;
        
        setbuf(stdout, 0);
        setbuf(stdin, 0);
        waitcnt(CLKFREQ + CNT);
        startServoThreads();
        botStop;
        
        for(;;) {
    //        putchar(0);
            printf("\n$ ");
            move = getchar();
            getchar();
            switch(move) {
                case 'f':
                    botForward(speed);
                break;
                case 's':
                    botStop();
                break;
                case '+':
                    speed += 100;
                break;
                case '-':
                    //speed -= 100;               
                    speed -= 100;
                    RightRotation = RightServoSpeed + speed;
                    printf("speed %d\n",speed);
                    printf("RightSpeed %d",RightRotation);
                break;
            }
        }
        return 0;
    }
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-30 04:49
    I made some modifications to the jazzed program. I added two commands MspeedAdj, and PspeedAdj, that seems to be working to affect the rotation speed. I also put in some control code in the '-', and '+' commands to keep the rotation from coming to a complete stop. A problem that I came across is when you keep pressing the '+' command, at some point, I start to get a lot of gibberish characters on the screen, but it does stop at some point, and the program runs as expected, not sure what is causing that.

    Now I will be adding the code for the left wheel, and hopefully the program will run as expected.

    Ray
    /**
     * @file TestRemBot.c
     * This is the main TestRemBot program start point.
     */
    #include <propeller.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/thread.h>
    
    #define STACK_SIZE 32
    
    #define RIGHT_SERVO_PIN 18
    
    #define RIGHT_CENTER 1500
    
    static int RightServoStack [STACK_SIZE];
    
    static _thread_state_t RightThreadData;
    
    int RightServoSpeed;
    int RightRotation;
    
    
    static int MaxServoSpeed = 100;
    
    void RightServoThread(void *arg __attribute__((unused)))
    {
        int pinmask = (1<<RIGHT_SERVO_PIN);
        int center = RIGHT_CENTER;
        int ustime = CLKFREQ/1000000;
        
        DIRA |= pinmask;
        
        for(;;) {
            OUTA &= ~pinmask;
            /* This holds the servo quiet */
            if(RightServoSpeed == 0) {
                waitcnt(ustime*center+CNT);
                RightRotation = 0;
                continue;
            }
            if (RightRotation > 1300) RightRotation = 1300;
            /*                 100      -100                                 */
            /*          ( 0 or rate or -rate / 2 * 1500)/ 100        + 1500  */
            /* 1500 or if 100 {1875 or - 1875} or variations on  + or - 100 */
    //        RightRotation = (-RightServoSpeed/2*center)/MaxServoSpeed+center;
            RightRotation = (-RightServoSpeed) + 1500;
            
               /* Set servo to center */
            waitcnt(ustime*center+CNT); /* CLKFREQ/1000000 * 1500 + CNT */
      /* Output bitwise pin    */
     /*  state   OR      18    */
            OUTA |= pinmask; /* Affects pin number  */
               /* Set servo to 1300 or less to go forward */
            waitcnt(ustime*RightRotation+CNT);  /* CLKFREQ/1000000 * RR + CNT */
            OUTA ^= pinmask;       
        }
    }
    
    
    void startServoThreads(void)
    {
        int n;
        n = _start_cog_thread(RightServoStack + STACK_SIZE, RightServoThread, NULL, &RightThreadData);
    }
    
    void botStop(void)
    {
        RightServoSpeed = 0;
    }
    
    void botForward(int rate)
    {
        RightServoSpeed = rate;
    }
    
    void botReverse(int rate)
    {
        RightServoSpeed = -rate;
    }
    
    void MspeedAdj(int rate)
    {
        RightServoSpeed = rate;
        
    }
    
    void PspeedAdj(int rate)
    {
        RightServoSpeed = rate;
    }
    
    /**
     * Main program function.
     */
    int main(void)
    {
        int move = 's';
        int speed = 100;
        int ustime = CLKFREQ/1000000;
        
        setbuf(stdout, 0);
        setbuf(stdin, 0);
        waitcnt(CLKFREQ + CNT);
        startServoThreads();
        botStop();
        
        for(;;) {
    //        putchar(0);
            printf("\n$ ");
            move = getchar();
            getchar();
            switch(move) {
                case 'f':
                    botForward(speed);
                    printf("speed %d\n",speed);
                    printf("RightSpeed %d",RightRotation);
                break;
                case 's':
                    botStop();
                break;
                case '+':
                    //speed += 100;
                    if (speed == 100)
                    {
                        speed = 100;
                    }
                    else
                    {
                        speed  = speed - 100;
                        PspeedAdj(speed);
                        printf("speed %d\n",speed);
                        printf("RightSpeed %d",RightRotation);
                    }
                break;
                case '-':
                    //speed -= 100;
                    if (speed < 100)
                    {
                        speed = 0;
                    }
                    else if (speed >= 1300) speed = 1300; 
                    else
                    {               
                        speed = speed + 100;                
                        MspeedAdj(speed);
                        printf("speed -%d\n",speed);
                        printf("RightSpeed %d",RightRotation);
                    }
                break;
            }
        }
        return 0;
    }
    
  • jazzedjazzed Posts: 11,803
    edited 2012-12-30 14:50
    Hi Ray,

    Attached is a better version of my original program.

    It provides a reasonable speed control. As is, the slowest speed is 10 percent of maximum. The speed control in the cog threads is much improved.
    If you want to calibrate your servos, set variable StopNoPulse = 0 first.

    I changed the command set a little and have added code to demonstrate a good way to do character at a time input.
    Note that I moved the pin numbers to the PropBoeServos.c file. Also the API function botSpeed(int rate); has been added.

    The new command set using the SimpleIDE terminal is:

    Normal Keys
    + = increase speed by 10 percent
    - = decrease speed by 10 percent (stops if speed goes to zero - change this if you like)
    f = go forward
    b = go back
    l = turn left
    r = turn right
    L = spin left
    R = spin right
    s = stop

    Keypad Keys (may behave differently with non SimpleIDE terminal)

    up arrow = go forward
    down arrow = go back
    left arrow = turn left
    right arrow = turn right
    home = spin left
    page up = spin right
    end = stop
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-31 04:06
    jazzed, I like the new improvements. I noticed in your board selection you had it set for HUB, not sure what that is. I am using a PropBOE, and I have my servos configured for LEFT_SEVO_PIN = 19 and RIGHT_SERVO_PIN = 18, just the opposite of what the program has. The first run using your program WITHOUT changing any settings, pressing 'f', the robot moves forward. Not sure why that is happening, since my pin settings are just the opposite of the program settings. With the pin settings being opposite, the robot should go in reverse, right?

    The biggest problem that I noticed was, when the robot starts, it is in a speed of 20, but the robot has a very significant pull to the left side. As you increase the speed the left pull lessens and at the speed of 70, in a short distance, it starts to run straight. I think that once it is run at full speed, probably a long distance run will be pretty much straight. I did not try any of the other commands like 'l', I do not know which way it will turn, or how it will turn left. Not sure how or where that left pull got introduced with the new program. Could it be something different with the HUB board?

    The "new thing" is the use of dprintf(), is this a new addition to the PropGCC? What is the difference between printf() and dprintf()? Not sure why you would want to use dprintf(). I also noticed you are using the "no buffering" setting, which works nice, eliminates the use of hitting the enter key. This will work very nicely with my C# robot terminal program, will not have to double click the GUI buttons.

    On a more general observation of using the PropBOE and the boebot, using C, I think the robot setup needs two boards. One board would run the servos and any other peripheral device(s) that need(s) a deterministic control, and uses the separate cog setup. The second board could be setup using threads, maximizing the use of flash RAM, for a much larger program, which would enable the robot to do much more stuff, and perhaps have a better chance of running in auto mode. And of course what would the code look like that would be necessary for communication between the two boards?

    Ray
  • jazzedjazzed Posts: 11,803
    edited 2012-12-31 09:47
    Rsadeika wrote: »
    jazzed, I like the new improvements. I noticed in your board selection you had it set for HUB, not sure what that is. I am using a PropBOE, and I have my servos configured for LEFT_SEVO_PIN = 19 and RIGHT_SERVO_PIN = 18, just the opposite of what the program has. The first run using your program WITHOUT changing any settings, pressing 'f', the robot moves forward. Not sure why that is happening, since my pin settings are just the opposite of the program settings. With the pin settings being opposite, the robot should go in reverse, right?

    I'm looking at the bot from the front. HUB board is a generic Propeller+80MHz+32KB configuration.
    Rsadeika wrote: »
    The biggest problem that I noticed was, when the robot starts, it is in a speed of 20, but the robot has a very significant pull to the left side. As you increase the speed the left pull lessens and at the speed of 70, in a short distance, it starts to run straight. I think that once it is run at full speed, probably a long distance run will be pretty much straight. I did not try any of the other commands like 'l', I do not know which way it will turn, or how it will turn left. Not sure how or where that left pull got introduced with the new program. Could it be something different with the HUB board?

    I notice a slight pull on my bot. Servos may behave differently with different settings.

    You could try calibrating your servos:

    1) set StopNoPulse = 0 ... maybe that should be default but i was thinking not sending any pulse would save battery
    2) rebuild and run
    3) verify servos don't move
    Rsadeika wrote: »
    The "new thing" is the use of dprintf(), is this a new addition to the PropGCC? What is the difference between printf() and dprintf()? Not sure why you would want to use dprintf(). I also noticed you are using the "no buffering" setting, which works nice, eliminates the use of hitting the enter key. This will work very nicely with my C# robot terminal program, will not have to double click the GUI buttons.

    I used dprintf (which is a #define printf ... see propboe.h) so I could turn off printing with a one line change.

    Printing will be turned off if you change propboe.h line 8 as follows:

    #define dprintf // printf


    Rsadeika wrote: »
    On a more general observation of using the PropBOE and the boebot, using C, I think the robot setup needs two boards. One board would run the servos and any other peripheral device(s) that need(s) a deterministic control, and uses the separate cog setup. The second board could be setup using threads, maximizing the use of flash RAM, for a much larger program, which would enable the robot to do much more stuff, and perhaps have a better chance of running in auto mode. And of course what would the code look like that would be necessary for communication between the two boards?

    We can use COG code for driving servos instead of LMM/CMM threads. Then you can use XMMC, etc....
    I'm not really interested in adding another propeller to my bot, but serial ports are easiest to use.
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-31 10:27
    1) set StopNoPulse = 0 ... maybe that should be default but i was thinking not sending any pulse would save battery
    I just tried that, the servo is moving, the right side forward and the left side backward. So, for my bot it stays at 1. I also tried the HUB board setting, that did not make a difference in the pull to the left. On my setup the pull is very significant, it is like making a left turn, looking at the bot from the rear, the left wheel is probably going at 20, while the right wheel is going at about 40.

    Ray
  • jazzedjazzed Posts: 11,803
    edited 2012-12-31 11:34
    Rsadeika wrote: »
    I just tried that, the servo is moving, the right side forward and the left side backward. So, for my bot it stays at 1. I also tried the HUB board setting, that did not make a difference in the pull to the left. On my setup the pull is very significant, it is like making a left turn, looking at the bot from the rear, the left wheel is probably going at 20, while the right wheel is going at about 40.

    Ray

    The point I was trying to make is that the servos should be calibrated (adjust using parallax screwdriver phillips end in the hole) so that the servos don't move at all. Then they should behave much better. If the servos are not calibrated, they will never work the way they should. The BOE-BOT manual recommends following such directions.

    I found my xbee stuff. Here is my main file. To use it, make a new project and add PropBoeServos.c. Don't define TEST.

    This works pretty good. I added a C calibrate command incase you want to tinker with it - it will set StopNoPulse to 1 for other commands.

    I'm off to buy a classical guitar now.

    --Steve
    /**
     * This is the main PropBoeXbee program start point.
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/thread.h>
    #include <propeller.h>
    
    /* declare xbee here so we can use dprintf */
    FILE *xbee;
    
    /* this is a special version of dprintf that lets us do IO with xbee */
    #define dprintf(p1,p2) fprintf(xbee,p1,p2)
    
    #include "propboe.h"
    #include "PropBoeServos.h"
    
    /**
     * Main program function.
     */
    int main(void)
    {
        int mstime = (CLKFREQ/1000);
        int speed = 80;
    
        char cmdstr[2];
        int cmd;
    
        extern int StopNoPulse;
    
        xbee = fopen("SSER:9600,0,1", "r+");
    
        /* keep QuickStart TX quiet. */
        DIRA |= (1<<30);
    
        setvbuf(xbee, NULL, _IONBF, 0);    // no buffering stdin
        setvbuf(xbee, NULL, _IONBF, 0);   // no buffering stdout
        xbee->_flag |= _IOCOOKED;          // turn on echo 
    
        waitcnt(50*mstime+CNT);
    
        startServoThreads();
        botStop();
        botSpeed(0);
    
        for(;;) {
    
            extern int LeftServoSpeed;
            extern int RightServoSpeed;
            extern int LeftRotation;
            extern int RightRotation;
    
            waitcnt(CLKFREQ/5+CNT);
    
            dprintf("%c", 0);
    
            dprintf("LR = %d ",LeftRotation);
            dprintf("RR = %d\n",RightRotation);
            dprintf("LS = %d ",LeftServoSpeed);
            dprintf("RS = %d\n",RightServoSpeed);
            dprintf("SPEED = %d\n",speed);
    
            dprintf("%c",'>');
    
            fgets(cmdstr, 2, xbee);
            cmd = cmdstr[0];
            if(!cmd) {
                continue;
            }
    
            dprintf(" cmd (%d)\n",cmd);
            StopNoPulse = 1; // no calibration unless told
            
            switch(cmd) {
                case '-':
                    if(speed >= 10) speed -= 10;
                    dprintf("speed- %d\n", speed);
                    botSpeed(speed);
                break;
                case '+':
                    if(speed <= 90) speed += 10;
                    dprintf("speed+ %d\n", speed);
                    botSpeed(speed);
                break;
    
                case 'C':
                    botStop();
                    StopNoPulse = 0;
                    dprintf("calibrate\n", 0);
                break;
    
                case UP_ARROW: // fall through
                case 'f':
                    botForward(speed);
                    dprintf("forward %d\n", speed);
                break;
                case DN_ARROW: // fall through
                case 'b':
                    botReverse(speed);
                    dprintf("backward %d\n", speed);
                break;
                case LEFT_ARROW: // fall through
                case 'l':
                    botLeftTurn(speed);
                    dprintf("left  turn %d\n", speed);
                break;
                case RIGHT_ARROW: // fall through
                case 'r':
                    botRightTurn(speed);
                    dprintf("right turn %d\n", speed);
                break;
                case HOME_KEY: // fall through
                case 'L':
                    botLeftSpin(speed);
                    dprintf("left  spin %d\n", speed);
                break;
                case PAGE_UP: // fall through
                case 'R':
                    botRightSpin(speed);
                    dprintf("right spin %d\n", speed);
                break;
                case END_KEY: // fall through
                case 's':
                    botStop();
                    dprintf("stop\n",0);
                break;
            }
        }
    
        return 0;
    }
    
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-12-31 13:27
    The point I was trying to make is that the servos should be calibrated (adjust using parallax screwdriver phillips end in the hole) so that the servos don't move at all.
    I wanted to try a software fix first. I am using the li-ion boebot battery pack, when it sits on the spacers it completely blocks the access to the adjustment pots. So, what that means, I basically have to take the boebot completely apart to get to adjustments pots. If I have to disassemble the boebot then I guess it is time to install the wheel encoder gizmo that I also purchased. I wonder if that will require a cog of its own to run? I also bought a PING, plus I got two more in the Xmas mystery sock, but I will probably use one, although two would be nice, one for the front, and one for the back. I guess that will probably be another cog, and if I run the XBee that also will be another cog. Plus if I try to use the uSD then maybe another cog, I have to start thinking about cog consolidation, it would be a real disappointment if I ran out of cogs.

    Ray
  • jazzedjazzed Posts: 11,803
    edited 2013-01-01 15:18
    Happy new year Ray and everyone else.

    I had the same problem with the servo adjustments and had to pull apart and reassemble the bot. The approach is generic, however I see your point about using software to fix it. Most likely it would be easy to add some commands to adjust a "trim" variable in the servo code.

    However, I've also been considering another servo approach using one cog for both servos written in pasm. That would mean only two cogs in use for the same functionality.

    My son and grandson are enjoying playing with the xbee controlled bot right now. When they are tired of it, i'll program more.

    --Steve
  • jazzedjazzed Posts: 11,803
    edited 2013-01-01 19:31
    I found a tiny battery powered Wifi CAM that should fit nicely on my bot. It's on order now. No idea of delivery schedule yet - could be weeks. Should make a nice remote CAM for navigation - we'll see.

    http://www.newspycam.com/Mini_Wireless_WIFI_Portable_WIFI_IP_SPY_Camera_2b_Stand_26_Adaptor_for_Iphone_Ipad_26_Androids/p1090014_4988830.aspx
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-01-02 08:08
    Since I was looking into the basics of servo drives, I created a chart for myself, to better understand the pulse stuff. I looked at the docs for the servo drive that are provided by Parallax, and I tried to derive some straight forward information, for somebody that is new to servos, like myself. This is a very simplistic approach, so use as you see fit.



    FORWARD FORWARD
    Counterclockwise Clockwise
    (CCW) (CW)
    Left Side Right Side
    Center
    1.6ms(1600) Fast 1.5ms(1500) No Move 1.4ms(1400) Fast
    . .
    2.0ms(2000) 1.0ms(1000)
    . .
    2.8ms(2800) Slow .3ms(300) Slow
    Rotation Rotation
    Pulse increases 0ms(0) Stop Pulse decreases

    I notice that this chart looks like Smile, but maybe somebody will get some use out of it.

    I found a tiny battery powered Wifi CAM that should fit nicely on my bot. It's on order now. No idea of delivery schedule yet - could be weeks. Should make a nice remote CAM for navigation - we'll see.
    I looked at it, looks very nice, waiting to see how that works out for you. I noticed Parallax sells a contraption for rotating a PING around, I wonder if that little CAM would fit on there instead of or with the PING. Not sure how I would go about adding video streaming to my C# robot terminal program.

    Once I get the servos centered, and the wheel encoder mounted, I think I will look into maybe adding a compass. Taking a glance at the encoder docs, it looks like they cover using the EEPROM for storing some of the data that the encoder provides, I wonder if this would be a good time to start thinking about adding access to the uSD, in the program now?

    Ray
  • RsadeikaRsadeika Posts: 3,837
    edited 2013-01-04 04:11
    The last couple of days I have been having a lot of trouble with the servos. One servo would work, sometimes, and then it would quit working, I thought I had a bad servo. It seems like the problem is with the li-ion battery pack, because it is such a tight fit, I noticed that the edge of the pcb was pushing against the wires coming out of the servo, and in the case of one servo, it has made it a bad connection. I verified this by taking out the li-ion pack, and the servos ran as expected, when I moved the wire around, on the back of the servo, that was working inconsistently, sure enough the servo would turn on and off. I think the regular battery pack that comes with the boebot lays flat on the frame, so it will not push up against the wires from the servos. I guess I might have to start using the regular battery pack. Anybody know of any li-ion batteries that would fit in there?

    The other thing that I noticed, on the PropBOE, are the servo pins, it seems that they are pretty flimsy, at least on the board that I have. I have my servo wires on p18 and p19, and I noticed that they were bent over, enough that it concerned me that something was not right. I did have to straighten them out with some needle nose pliers. Now I am not sure as to how reliable those pins are. I think I am going backwards with this project.

    Ray
Sign In or Register to comment.