Shop OBEX P1 Docs P2 Docs Learn Events
FlexProp working with legacy code — Parallax Forums

FlexProp working with legacy code

I was starting to resurrect my old ActivityBot project, and looking through my archive programs, I came across the program listed below.

I did do a modification for a SimpleIDE application, which ran as expected. The program listed below, when I ran it with FlexC P1, came up with an error. Not sure what the cure is.

The program below is for a PropBoe, I thought it would be nice to have it modified to run an AcitivityBot, using the regular servos. And of course some C pros could, maybe, modify the code so it could run the new servo360. I also have some old Spin code for the calibration setup, did not come across any C code for that.

Looking at the code below, I think it is a straight C code, and not a Spin code translation. Not sure on that point. I also ran the code with FlexC P2, came up with the same error. It would take a lot of hardware work work to get a P2 to run an ActivityBot.

Since the code below came up with an error, I have no idea how much memory it is using, when run with FlexC P1.

Maybe this code code be modified to maybe run in FlexBASIC? Not sure how that would work though.

Ray

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

#include "propboe.h"
#include "PropBoeServos.h"

/* if defined differently in board type file, use those pin definitions */
int LEFT_SERVO_PIN = 19;  //18
int RIGHT_SERVO_PIN = 18;  //19

/* These numbers define servo stop pulse width */
#define LEFT_CENTER 1500
#define RIGHT_CENTER 1500

#define PAUSE_DIVISOR 50

/* 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;

int StopNoPulse = 1;
static int MaxServoSpeed = 500;

/*
 * 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(StopNoPulse && LeftServoSpeed == 0) {
            waitcnt(CLKFREQ/PAUSE_DIVISOR+CNT);
            LeftRotation = 0;
            continue;
        }

        if(LeftServoSpeed > MaxServoSpeed)
            LeftServoSpeed = MaxServoSpeed;
        if(LeftServoSpeed < -MaxServoSpeed)
            LeftServoSpeed = -MaxServoSpeed;

        /* move servo */
        LeftRotation = (-LeftServoSpeed/2*center)/MaxServoSpeed+center;
        waitcnt(CLKFREQ/PAUSE_DIVISOR+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(StopNoPulse && RightServoSpeed == 0) {
            waitcnt(CLKFREQ/PAUSE_DIVISOR+CNT);
            RightRotation = 0;
            continue;
        }

        if(RightServoSpeed > MaxServoSpeed)
            RightServoSpeed = MaxServoSpeed;
        if(RightServoSpeed < -MaxServoSpeed)
            RightServoSpeed = -MaxServoSpeed;

        /* move servo */
        RightRotation = (RightServoSpeed/2*center)/MaxServoSpeed+center;
        waitcnt(CLKFREQ/PAUSE_DIVISOR+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;
}

void botSpeed(int rate)
{
    LeftServoSpeed = LeftServoSpeed >= 0 ? rate : -rate;
    RightServoSpeed = RightServoSpeed >= 0 ? rate : -rate;
}

#ifdef TEST
/**
 * Main program function.
 */
int main(void)
{
    int mstime = (CLKFREQ/1000);
    int speed = 20;

    char cmdstr[2];
    int cmd;

    /* keep QuickStart TX quiet. */
    DIRA |= (1<<30);

    setvbuf(stdin, NULL, _IONBF, 0);    // no buffering stdin
    setvbuf(stdout, NULL, _IONBF, 0);   // no buffering stdout
    stdin->_flag |= _IOCOOKED;          // turn on echo 

    //setbuf(stdout, 0);
    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);

        putchar(0);

        dprintf("LR = %d ",LeftRotation);
        dprintf("RR = %d\n",RightRotation);
        dprintf("LS = %d ",LeftServoSpeed);
        dprintf("RS = %d\n",RightServoSpeed);
        dprintf("SPEED = %d\n",speed);

        putchar('>');

        fgets(cmdstr, 2, stdin);
        cmd = cmdstr[0];
        if(!cmd) {
            continue;
        }

        dprintf(" cmd (%d)\n",cmd);

        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 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");
            break;
        }
    }

    return 0;
}
#endif


/*
Steve Denson (jazzed) code
*/

Error(s)
"/home/pi/flexprop/bin/flexspin" -2 -l -D_BAUD=230400 -O1 -I "/home/pi/flexprop/include" "/home/pi/programs/flexprop/boebot_c/PropBoeServos.c"
Propeller Spin/PASM Compiler 'FlexSpin' (c) 2011-2021 Total Spectrum Software Inc.
Version 5.3.1 Compiled on: Mar 27 2021
/home/pi/programs/flexprop/boebot_c/PropBoeServos.c:43: error: syntax error, unexpected attribute, expecting ')'
PropBoeServos.c
child process exited abnormally
Finished at Thu Apr 15 06:50:00 2021

Comments

  • Well, the error message tells you all there is to tell: Flex C doesn't like the __attribute__ on a parameter. In this case it's just to make gcc shut up about it being unused, so you can just remove it.

  • I went a little further with this, just to get it to compile in FlexC. I removed the attribute, not knowing what the cahnge would be to the function.

    The next big error was "unknown identifier _start_cog_thread and Unknown symbol _start_cog_thread". I think this particular code needs threads, not sure how to manipulate the code so it would run in just a COG and not a thread.

    By removing "startServoThreads()", the program did compile, and it was showing "Program size is 17028 bytes", which is more than half of available memory that is being used.

  • Yes, FlexC is less memory efficient than PropGCC. If everything works fine with PropGCC/SimpleID, I'd just stick with that.

Sign In or Register to comment.