Page 1 of 2

Reading PORTB to Terminal

PostPosted: Sun Jul 21, 2019 3:56 pm
by GettinBetter
Having trouble peeps... as a noob, I've done the flashing LEDs, the PWM, and the LED on/off by Keyboard inputs. Now I'd like to have a user input i.e. push the little buttons on my dev board and have the pin position sent to terminal.
Here's the code at comments as to what I think it should be doing....
Setup:
EasyPIC V7 board/ICD3/MCC
Using PIC18F45K22/8MHz
XC8/C90

Code: Select all
    volatile uint8_t rxData;
    volatile uint8_t PinData;

void EUSART1_Initialize(void);
{
   
    printf("\r EasyPIC V7 - Date 21/07/2019\r\n"); 
    printf("UART Communications 8-bit Rx and Tx\r\n\n");
    printf("Read PORT B Pins \r\n");
    printf("using Port B Buttons, set to pull down. \r\n\n");
   
}

    while (1)
    {       
     PinData = PORTB;       // save PortB To PinData
     __delay_ms(500);        // wait for TXREG to fill bit excessive but hey..
     
     if(EUSART1_is_tx_ready())  //if transmit buffer is ready
    {   
   
    EUSART1_Write(PinData);  // send a byte to TX (Terminal from PortB)
   
    }
   
}
}


The first bit of text comes onto terminal window fine but no input from the pins...

Any comments would be appreciated.

Regards
Les

Re: Reading PORTB to Terminal

PostPosted: Sun Jul 21, 2019 6:47 pm
by Roche
It's quite likely your PinData value is not an ASCII printable value. You might have to tweak it a bit to see it.

Re: Reading PORTB to Terminal

PostPosted: Sun Jul 21, 2019 8:52 pm
by GettinBetter
Ok...I'm thinking its a binary value if all buttons are low i.e. roughly 0 volts, so I need to convert to an ASCII value to get it to print? Can It not just printout the binary value?

Re: Reading PORTB to Terminal

PostPosted: Sun Jul 21, 2019 10:24 pm
by jtemples
Remove everything from the while loop, and put

printf("Pin data: %02X\n", PORTB);

before the while loop.

Re: Reading PORTB to Terminal

PostPosted: Mon Jul 22, 2019 11:09 am
by ric
GettinBetter wrote:... Can It not just printout the binary value?

That is what it's sending, but that is NOT what your terminal program is expecting.
Do what jtemples suggested if you want to see an ASCII representation of the value. (It will be in hex, but at least you can read that)

Re: Reading PORTB to Terminal

PostPosted: Mon Jul 22, 2019 6:16 pm
by GettinBetter
Excellent, thanks guys, :D that did it. Here's what I used...
Not pretty but it's a result...

Code: Select all
    volatile uint8_t rxData;

void EUSART1_Initialize(void);
{
   
    printf("\r EasyPIC V7 - Date 22/07/2019\r\n"); 
    printf("USART Communications 8-bit Rx and Tx\r\n\n");
    printf("Read PORT B Pins \r\n");
    printf("using Port B Buttons, set to pull down. \r\n\n");
   
}

    while (1)
    {       
      printf("Pin data: %02X\r", PORTB);
     __delay_ms(300);
     
    } 
}


When I push buttons the value changes as expected, when I release it goes back to zero, values being in hex as you said.

Now onto the next step...
Is it possible to read the pins and get a binary output to terminal?

Re: Reading PORTB to Terminal

PostPosted: Mon Jul 22, 2019 7:44 pm
by jtemples
printf doesn't have any built-in support to generate an ASCII string of binary. You'll have to do that yourself, then call printf. Something like:
Code: Select all
void    main(void)
{
    uint8_t value = 0x42;
    uint8_t mask = 1 << 7;
    uint8_t bits;
    char string[8+1];
   
    for (bits = 0; bits < 8; bits++, mask >>= 1)
        string[bits] = (value & mask) ? '1' : '0';

    string[bits] = 0;                   /* null terminate */

    printf("0b%s\n", string);
}

Re: Reading PORTB to Terminal

PostPosted: Tue Jul 23, 2019 7:30 pm
by GettinBetter
Great, :D I'll have a play tonight... appreciate your help. I'll post back if I get anything to work 8-)

Regards
Les

Re: Reading PORTB to Terminal

PostPosted: Sat Jul 27, 2019 7:14 pm
by GettinBetter
So I wrote the lookup table for the Bournes 8bit Encoder I was using and got a consistent output to 127 in the terminal window.
I didn't do the binary thing as I couldn't see why I actually needed it, least not yet.

Code: Select all
    while (1)
    {   
       
      DecimalOutput = PORTB;
       
         switch(DecimalOutput){    // check command 
        case 0x7F:{
                printf("Pin Position:  0\r");           
                break;
                }
        case 0x3F:{
                printf("Pin Position:  1\r");           
                break;
                }
        //continues for all 127 cases


Which is great for my 8bit test encoder, but the one I really want to us is a 10bit encoder, but can I use two variables to collect the pin data form two ports then using formatting print them using printf?
I eventually want to drive a motor into position x and have the encoder provide feedback and verify actual position to enable acceleration/deceleration of the motor
at some stage I want the output from the 10bit encoder to determine the motor position. Is the 8bit MCU up to this?

Regards
Les

Re: Reading PORTB to Terminal

PostPosted: Sat Jul 27, 2019 11:05 pm
by ric
GettinBetter wrote:Which is great for my 8bit test encoder, but the one I really want to us is a 10bit encoder, but can I use two variables to collect the pin data form two ports

Why not just copy the data into a 16 bit variable?
e.g. if it's on PORTB and 2 bits of PORTC
Code: Select all
unsigned int DecimalOutput;    //16 bit variable
DecimalOutput = PORTB | ((PORTC & 0b0011) << 8);    //merge 8 bits from PORTB and 2 bits from PORTC


You only showed two possible values from your encoder, so it's not possible to guess how it's encoded.
I'm sure there's much more efficient ways to interpret it than a huge switch statement.