This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Overlapping values sent through UART to PuTTY

Hello,

I am having a problem when I send a variable of type "long" over UART.

I send the value twice one when the motor is at one position and another when the motor returns back to the original position.

The value I am showing is the encoder count, when the motor goes to the first position the encoder count would be something like 3120, but

when it goes back to the original position it decrements the value back down to like 11. The problem is, is that when the value gets printed on the PuTTY screen

the first values last 2 digits get overlapped into the second value so it would show: 1120.

This is the Stellaris Launchpad btw.


#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/timer.h"
#include "inc/hw_ints.h"
#include "driverlib/interrupt.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/rom.h"
#include "utils/uartstdio.h"


//Timer variables
unsigned long g_ulFlags;

#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif


//Variables
unsigned long ulPeriod_A, dutyCycle_A,ulPeriod_B, dutyCycle_B;
volatile unsigned long encoderCount;
unsigned long delayRight;
unsigned int lastPos;
volatile unsigned char goingRight;

//Prototypes
void goLeft(unsigned long ulSpeed, float ulLength);
void goRight(unsigned long ulSpeed, float ulLength);
void position(unsigned long speed, float pos);



int main(void)
{

    ulPeriod_A = 3000;
    dutyCycle_A = 2000;
    ulPeriod_B = 3000;
    dutyCycle_B = 2000;
    encoderCount = 0;

    ROM_FPULazyStackingEnable();



    //40 MHz system clock
    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

    //Uart stuff
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTStdioInit(0);


    //timer stuff
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
    ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, ROM_SysCtlClockGet() / 2);
   // ROM_IntEnable(INT_TIMER1A);
   // ROM_TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    ROM_TimerEnable(TIMER1_BASE, TIMER_A);

    //Set the peripherals that will be used
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    //Configure GPIO Pins for timer
    GPIOPinConfigure(GPIO_PB6_T0CCP0);
    GPIOPinConfigure(GPIO_PB7_T0CCP1);
    GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_6|GPIO_PIN_7);

    //Configure outputs
    GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_7);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_4);

    //Clear output pins
    GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_7|GPIO_PIN_6, 0x00);
    GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_7, 0x00);
    GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_4, 0x00);

    //Timer configuration
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PWM|TIMER_CFG_B_PWM);
    TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod_A -1);
    TimerMatchSet(TIMER0_BASE, TIMER_A, dutyCycle_A); //Duty Cycle
    TimerLoadSet(TIMER0_BASE, TIMER_B, ulPeriod_B -1);
    TimerMatchSet(TIMER0_BASE, TIMER_B, dutyCycle_B); //Duty Cycle
    TimerEnable(TIMER0_BASE, TIMER_A|TIMER_B);



    // use PC7 as external interrupt:
    GPIOPinTypeGPIOInput(GPIO_PORTC_BASE, GPIO_PIN_7|GPIO_PIN_6);
    GPIOPinIntClear(GPIO_PORTC_BASE,GPIO_PIN_7|GPIO_PIN_6);
    GPIOIntTypeSet(GPIO_PORTC_BASE, GPIO_PIN_7|GPIO_PIN_6, GPIO_BOTH_EDGES );
    GPIOPinIntEnable(GPIO_PORTC_BASE, GPIO_PIN_7|GPIO_PIN_6);
    IntEnable(INT_GPIOC);
    // Enable processor interrupts.
    IntMasterEnable();
    delayRight = 40000000;

    float home = 0.1;
    
        while(1)
        {
    
            while(1){
    
                position(2250,5.5);
                UARTprintf("\rEncoderCount: %d", encoderCount);
                SysCtlDelay(delayRight);
                position(2250, home);
                SysCtlDelay(400000);
                UARTprintf("\rEncoderCount: %d", encoderCount);
        
                while(1){        
                    
                }
            }

}
}
//Absolute Position of motor
void position(unsigned long speed, float pos){

    if(pos >lastPos){
        goRight(speed,pos);
    }else{
        goLeft(speed,pos);
    }
    lastPos = pos;
}
void goLeft(unsigned long ulSpeed, float ulLength){

    goingRight = 0;
    while(encoderCount >= ulLength * 600){
    //UARTprintf("\rEncoderCount: %d", encoderCount);
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 0x00);
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_7, 0x80);
    dutyCycle_A = ulSpeed;
    TimerMatchSet(TIMER0_BASE, TIMER_A, dutyCycle_A -1);
    }
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_7, 0x00);
}

void goRight(unsigned long ulSpeed, float ulLength){


    goingRight = 1;
    while(encoderCount <= ulLength * 600){
    //UARTprintf("\rEncoderCount: %d", encoderCount);
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_7, 0x00);
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 0x10);
    dutyCycle_B = ulSpeed;
    TimerMatchSet(TIMER0_BASE, TIMER_B, dutyCycle_B -1);
    }
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 0x00);

}
void chAHandler(void){


    unsigned int newEnc = GPIOPinIntStatus(GPIO_PORTC_BASE, true) ;


    if(goingRight == 1){
        if(newEnc & 0x80){
            encoderCount++;
        GPIOPinIntClear(GPIO_PORTC_BASE,GPIO_PIN_7);
        }
        if(newEnc & 0x40){
            encoderCount++;
        GPIOPinIntClear(GPIO_PORTC_BASE,GPIO_PIN_6);
        }
    }else{
        if(newEnc & 0x80){
            encoderCount--;
        GPIOPinIntClear(GPIO_PORTC_BASE,GPIO_PIN_7);
        }
        if(newEnc & 0x40){
            encoderCount--;
        GPIOPinIntClear(GPIO_PORTC_BASE,GPIO_PIN_6);
        }

    }
    if(encoderCount > 7500){
        encoderCount == 1;
    }

}

/*
void
Timer1IntHandler(void)
{
    //
    // Clear the timer interrupt.
    //
    ROM_TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);

    //
    // Toggle the flag for the second timer.
    //
    HWREGBITW(&g_ulFlags, 1) ^= 1;

    //
    // Use the flags to Toggle the LED for this timer
    //
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, g_ulFlags << 1);

    //
    // Update the interrupt status on the display.
    //
    ROM_IntMasterDisable();
    UARTprintf("\rEncoderCount: %d", encoderCount);
    ROM_IntMasterEnable();
}

*/

  •  UARTprintf("\rEncoderCount: %d", encoderCount);
                    SysCtlDelay(delayRight);
                    position(2250, home);
                    SysCtlDelay(400000);
                    UARTprintf("\rEncoderCount: %d", encoderCount);


    How about clearing the space before writing again if you are only going to do a carriage return... "\r" as opposed to a "\n" new line...

    Lots of people get caught on this one... it's working exactly as programmed -- but, not as intended...


  • Hi Dave,

    Thanks for the reply. I am curious, is there a command that I can send over UART that will clear the line before I print the new value? I know that you can clear the value in PuTTY but that I would rather not have to do it that way.

  • Actually after some good advice from you and a bit of googling I found the solution.

    To clear the line I had to use UARTprintf("\033[2J");

    Thank you.

    Erik

  • Some of us with grey hair remember the days when "programmable terminals" seemed "oh so futuristic"... That's your hint...

    More directly, you can set PuTTY to be a programmable terminal and send a clear line command or put the start and stop positions in specific X-Y coordinates and then fill the entire "field space" as you see fit.

    If you choose the Serial Connection you can look under Terminal --> Keyboard and choose VT100 or VT400 -- programming is quite extensive for "Smart Terminals".

  • That is a "Clear Screen Command" -- it may work this time... but...

    See here: ascii-table.com/ansi-escape-sequences-vt-100.php

    Esc[K Clear line from cursor right

    EL0

    The ESC K command may be more suitable... after positioning the cursor