I've been working to program an RF module to control a motor which has a rotary encoder attached.
The RF module receives signals from a keyfob remote and sends a serial 10 byte output which is read as UART on the launchpad. I have it configured to evaluate the third byte (which is the unique button ID on the keyfob) in a case block to then activate the motor. The motor rotates clockwise and counter-clockwise without issue in this setup.
If I try using the QEIPositionGet() from the QEI driver library I get a reading, but following that function call my serial data from the RF module suddenly shifts. Byte 3 is now byte 9, byte 0 is now byte 6 etc.
Does anyone know why this might be happening? I've included my code for reference.
/* * main.c * * Created on: Mar 14, 2021 * Author: dfnewell */ #include <stdint.h> #include <stdbool.h> #include <string.h> #include "inc/tm4c123gh6pm.h" #include "inc/hw_gpio.h" #include "inc/hw_types.h" #include "inc/hw_memmap.h" #include "driverlib/debug.h" #include "driverlib/sysctl.h" #include "driverlib/pin_map.h" #include "driverlib/gpio.h" #include "driverlib/pwm.h" #include "driverlib/timer.h" #include "driverlib/adc.h" #include "driverlib/uart.h" #include "driverlib/interrupt.h" #include "driverlib/qei.h" #include "utils/uartstdio.h" #define SIZE_OF_BUFFER 10 int bufferLength = 0; int readIndex = 0; int writeIndex = 0; static uint32_t RFin[10]; static uint8_t RFconvert[8]; uint8_t endline = 0x0A; void MotorRotation(uint32_t x); uint32_t MOTOR = QEI0_BASE; uint32_t motorHome = 0; uint32_t UNLOAD_POS = 2388/4; uint32_t FRONT_FACING = 2388/2; uint32_t MOTOR_CTL_PINS = GPIO_PORTE_BASE; uint32_t CWPIN = GPIO_PIN_1; uint32_t CCWPIN = GPIO_PIN_2; uint32_t MOTOR_ENABLE = GPIO_PIN_3; int LOADSTATUS = 0; uint32_t x = 0; uint8_t RCVFLAG = 0; // INITIALIZE BOARD COMPONENTS: void InitPCUART(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); UARTStdioConfig(0,19200,16000000); } void InitRFModuleUART(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1); GPIOPinConfigure(GPIO_PB0_U1RX); GPIOPinConfigure(GPIO_PB1_U1TX); GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTClockSourceSet(UART1_BASE, UART_CLOCK_PIOSC); UARTConfigSetExpClk(UART1_BASE, 16000000, 19200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); UARTEnable(UART1_BASE); } void MotorEnable(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI0); //Unlock GPIOD7 - Like PF0 its used for NMI - Without this step it doesn't work HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY; //In Tiva include this is the same as "_DD" in older versions (0x4C4F434B) HWREG(GPIO_PORTD_BASE + GPIO_O_CR) |= 0x80; HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = 0; //Set Pins to be PHA0 and PHB0 GPIOPinConfigure(GPIO_PD6_PHA0); GPIOPinConfigure(GPIO_PD7_PHB0); //Set GPIO pins for QEI. PhA0 -> PD6, PhB0 ->PD7. I believe this sets the pull up and makes them inputs GPIOPinTypeQEI(GPIO_PORTD_BASE, GPIO_PIN_6 | GPIO_PIN_7); //DISable peripheral and int before configuration QEIDisable(QEI0_BASE); QEIIntDisable(QEI0_BASE,QEI_INTERROR | QEI_INTDIR | QEI_INTTIMER | QEI_INTINDEX); QEIConfigure(QEI0_BASE,QEI_CONFIG_CAPTURE_A_B|QEI_CONFIG_QUADRATURE|QEI_CONFIG_NO_RESET|QEI_CONFIG_NO_SWAP,800); QEIEnable(QEI0_BASE); QEIIntEnable(QEI0_BASE,QEI_INTINDEX); QEIPositionSet(QEI0_BASE,0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); GPIOPinWrite(MOTOR_CTL_PINS,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3,0x00); } //----------------------------------------------------------------- // RF Recieved Parsing FOR ZPT4RD: void char2byte(char *chars, uint8_t *ints) { for (int i =0; i < 8; i++){ ints[i] = chars[i]; } } //------------------------------------------------------------------------------------------------------------------------------------ int main(void) { SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); // LEDs Enable SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0x02); GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0x00); GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0x00); InitPCUART(); InitRFModuleUART(); MotorEnable(); UARTprintf("Program Ready \n"); while(1){ GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, 0x02); GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, 0x00); GPIOPinWrite(MOTOR_CTL_PINS,MOTOR_ENABLE,0x00); // Make sure the enable pin is off to begin with. // Wait for RF transmission if(UARTCharsAvail(UART1_BASE)){ GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, 0x00); // Change LED colors to indicate transmission rcvd GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3,GPIO_PIN_3);// and the motor is on GPIOPinWrite(MOTOR_CTL_PINS,MOTOR_ENABLE,MOTOR_ENABLE); // Write the motor pin enable high //while((UARTCharGet(UART1_BASE) != 10)){ // Read the UART buffer and wait for the EoL flag RFin[writeIndex] = UARTCharGet(UART1_BASE); // this stores the last 8 bytes before the EoL flag writeIndex++; if (writeIndex == SIZE_OF_BUFFER) {writeIndex = 0; for (int i=0;i<10;i++){ UARTprintf("%4d",RFin[i]);} UARTprintf("\n"); MotorRotation(RFin[3]); // and process the command on the motor } //} } } } void MotorRotation(uint32_t x) { // Check received packet and assign motor actions // The remote only sends out signal packets in 2**n, // where n is the selected remote button switch(x) { // Button 1: turn CCW case 1: GPIOPinWrite(MOTOR_CTL_PINS,CCWPIN,CCWPIN); break; // Button 2: turn CW case 2: GPIOPinWrite(MOTOR_CTL_PINS,CWPIN,CWPIN); break; // Button 3: Home position (rear facing) case 4: UARTprintf("Motor position: %d",QEIPositionGet(MOTOR)); //while(QEIPositionGet(MOTOR) > motorHome){ //GPIOPinWrite(MOTOR_CTL_PINS,CWPIN,CWPIN); //} SysCtlDelay(10); break; // Button 4: Front Facing case 8: while(QEIPositionGet(MOTOR) < FRONT_FACING) GPIOPinWrite(MOTOR_CTL_PINS,CWPIN,CWPIN); SysCtlDelay(10); break; // Button 5: Load/Unload position case 16: if(LOADSTATUS==1){ while(QEIPositionGet(MOTOR) < UNLOAD_POS){ GPIOPinWrite(MOTOR_CTL_PINS,CCWPIN,CCWPIN); } LOADSTATUS = 0; } else{ while(QEIPositionGet(MOTOR) > motorHome){ GPIOPinWrite(MOTOR_CTL_PINS,CWPIN,CWPIN); } LOADSTATUS = 1; } SysCtlDelay(10); break; // Button 6: Set Home Position (Rear facing) case 32: QEIPositionSet(MOTOR,0); motorHome = QEIPositionGet(MOTOR); SysCtlDelay(10); break; break*/ default: GPIOPinWrite(MOTOR_CTL_PINS,CCWPIN|CWPIN,0); } return; }