I have an X Drive that is coded in ROBOTC. My team and I have the integrated motor encoders already on the robot (for the autonomous period). However the code for them to run is incorrect. The current autonomous code is below. When I run it, it just goes forward forever and at different speeds.
I have looked at multiple tutorials, but none of them work. Does anyone have the code to make the motors (393 Motors) go at a count of 720?
#pragma config(I2C_Usage, I2C1, i2cSensors)
#pragma config(Sensor, I2C_1, sensorQuadEncoderOnI2CPort, AutoAssign)
#pragma config(Motor, port2, FL, tmotorVex393_MC29, PIDControl, encoderPort, I2C_1)
#pragma config(Motor, port3, BR, tmotorVex393_MC29, PIDControl, reversed, encoderPort, I2C_1)
#pragma config(Motor, port8, BL, tmotorVex393_MC29, PIDControl, encoderPort, I2C_1)
#pragma config(Motor, port9, FR, tmotorVex393_MC29, PIDControl, reversed, encoderPort, I2C_1)
//*!!Code automatically generated by 'ROBOTC' configuration wizard !!*//
task main()
{
// Autonomous with Integrated Encoders
nMotorPIDSpeedCtrl[FL] = mtrSpeedReg;
nMotorPIDSpeedCtrl[FR] = mtrSpeedReg;
nMotorPIDSpeedCtrl[BL] = mtrSpeedReg;
nMotorPIDSpeedCtrl[BR] = mtrSpeedReg;
//Clears motor values
nMotorEncoder[FL] = 0;
nMotorEncoder[FR] = 0;
nMotorEncoder[BL] = 0;
nMotorEncoder[BR] = 0;
//Forward
motor[FL] = 63;
motor[FR] = 63;
motor[BL] = 63;
motor[BR] = 63;
while(nMotorEncoder[FL] < 720) {
}
//Clears motor values
nMotorEncoder[FL] = 0;
nMotorEncoder[FR] = 0;
nMotorEncoder[BL] = 0;
nMotorEncoder[BR] = 0;
}
You need to explicitly stop the motors (not just zero out the encoders) after the while loop. Otherwise the robot doesn't know to stop; it just knows that it passed the encoder target.
So this code should work for you:
//Clears motor values
nMotorEncoder[FL] = 0;
nMotorEncoder[FR] = 0;
nMotorEncoder[BL] = 0;
nMotorEncoder[BR] = 0;
motor[FL] = 63;
motor[FR] = 63;
motor[BL] = 63;
motor[BR] = 63;
//Forward
while(nMotorEncoder[FL] < 720) {
}
//stops motors
motor[FL] = 0;
motor[FR] = 0;
motor[BL] = 0;
motor[BR] = 0;
//Clears motor encoder values
nMotorEncoder[FL] = 0;
nMotorEncoder[FR] = 0;
nMotorEncoder[BL] = 0;
nMotorEncoder[BR] = 0;
Related
First off all I am a beginner regarding embedded programming.
For an application I do want to use the MLX90621 thermo pixel array togehter with an STM32G431KB. On the Melexis Website is an example Code with some sort off abstraction. I moddified the lowlevel part of the code to work with the HAL library of the MCU.
For some reason I can read the EEPROM and write to it, get an acknowledge... But when trying to read from the adress 0x60, the RAM, where the sensorvalues are stored i do not get an acknowledge. I do have checkt with an logic analyer and I am sending the correct messages. Just for refference I do have added the code part of the read function.
Has anybody an idea regarding some very dump timing error or something like that.
P.S. Allready tried an different sensor of my order with the exact same result.
int MLX90621_I2CRead(uint8_t slaveAddr,uint8_t command, uint8_t startAddress, uint8_t addressStep, uint8_t nMemAddressRead, uint16_t *data)
{
uint8_t sa = slaveAddr << 1;
int cnt = 0;
int i = 0;
uint8_t cmd[4] = {0,0,0,0};
uint8_t i2cData[132] = {0};
uint16_t *p;
p = data;
cmd[0] = command;
cmd[1] = startAddress;
cmd[2] = addressStep;
cmd[3] = nMemAddressRead;
if (HAL_I2C_Master_Transmit(&hi2c2, sa, cmd, 4, HAL_MAX_DELAY) != HAL_OK)
return -1;
HAL_Delay(1);
//sa = sa | 0x01;
//ack = i2c.read(sa, i2cData, 2*nMemAddressRead, 0);
if (HAL_I2C_Master_Receive(&hi2c2, sa, i2cData, 2*nMemAddressRead, HAL_MAX_DELAY) != HAL_OK)
return -1;
for (cnt = 0; cnt < nMemAddressRead; cnt++) {
i = cnt << 1;
*p++ = (uint16_t)i2cData[i+1]*256 + (uint16_t)i2cData[i];
}
return 0;
}
Porting from PIC32MX to MZ (PIC32MZ2048EFG100) and am banging head against wall trying to generate a simple RX interrupt on UART3. Please see code below.
void main(void} {
__builtin_disable_interrupts();
//Ensuring all pins config as digital
ANSELA = 0x0000;
ANSELB = 0x0000;
ANSELC = 0x0000;
ANSELD = 0x0000;
ANSELE = 0x0000;
ANSELF = 0x0000;
ANSELG = 0x0000;
//Convenient macrso to do IOUNLOCK
#define PPSUnLock() {SYSKEY=0x0;SYSKEY=0xAA996655;SYSKEY=0x556699AA;CFGCONbits.IOLOCK=0;}
#define PPSLock() {SYSKEY=0x0;SYSKEY=0xAA996655;SYSKEY=0x556699AA;CFGCONbits.IOLOCK=1;}
//Peripheral Pin Select (PPS) Settings for UART3
PPSUnLock();
U3RXRbits.U3RXR = 0b1010;
RPA14Rbits.RPA14R = 0b0001;
PPSLock();
//Config UART3
U3MODEbits.UEN0 = 0; //no flow control
U3MODEbits.UEN1 = 0;
U3MODEbits.LPBACK = 0; // no loopback
U3MODEbits.ABAUD = 0; //no autobaud
U3MODEbits.BRGH = 0;
U3MODEbits.PDSEL0 = 0; //8 data bits, no parity
U3MODEbits.PDSEL1 = 0;
U3MODEbits.STSEL = 0; // 1 stop bit
U3STAbits.URXISEL0 = 0; //RX Interrupt on first byte in FIFO
U3STAbits.URXISEL1 = 0;
U3BRG = CLOSEST_UBRG_VALUE115200; //Macro defined elsewhere, but it works
//Int priorities
IPC39bits.U3EIP = 6;
IPC39bits.U3EIS = 3;
//Int flags
IFS4bits.U3RXIF = 0;
//Int enable/disable
IEC4bits.U3EIE = 0;
IEC4bits.U3TXIE = 0;
IEC4bits.U3RXIE = 1; //Enable int on RX
//Enable multi-vector interrupts
INTCONSET = _INTCON_MVEC_MASK;
__builtin_enable_interrupts();
//Turn on UART3
U3STAbits.URXEN = 1;
U3STAbits.UTXEN = 1;
U3MODEbits.ON = 1;
UART_txEXTCOMandWait('A'); //Function defined elsewhere - I get successful byte "A" sent to my terminal. So TX works.
while(1){Nop();}; //wait in endless loop for interrupt to occur on keystroke
}
Below is my ISR:
void __ISR_AT_VECTOR (_UART3_RX_VECTOR, IPL6SOFT) U3Interrupt(void) {
unsigned int test=0;
Nop(); //Setting a breakpoint here
}
I successfully see an "A" on my terminal screen when running the program, so settings are correct for TX. Typing in text in my terminal screen yields no interrupts. Have verified with scope that signal is making it to the PIC32.
What am I missing here? I'm burning a ton of time on something that should be trivial.
Thanks guys.
Figured it out... It should be:
//Int priorities
IPC39bits.U3EIP = 6;
IPC39bits.U3EIS = 3;
Interesting how this had been working in production on PIC32MX for years.
what should be the parameters of VkImageBlit.dstOffsets and VkImageBlit.srcOffsets when we are doing dynamic generation of mipmaps?
I am doing layer by layer and for each mipmap level but somewhere it is going wrong, mostly i think offsets. So i have data which has all the six faces with 0th mipmap level.
for(int j=0; j< bufferCopyRegions.size(); j++) {
for (int32_t i = 1; i < mipLevels; i++)
{
VkImageBlit imageBlit{};
// Source
imageBlit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageBlit.srcSubresource.layerCount = 1;
imageBlit.srcSubresource.mipLevel = 0;
imageBlit.srcOffsets[1].x = bitmapInfos[j].width;
imageBlit.srcOffsets[1].y = bitmapInfos[j].height;
imageBlit.srcOffsets[1].z = 1;
// Destination
imageBlit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageBlit.dstSubresource.layerCount = 1;
imageBlit.dstSubresource.mipLevel = i;
imageBlit.dstOffsets[1].x = int32_t(bitmapInfos[j].width >> (i) == 0 ? 1 : int32_t(bitmapInfos[j].width >> (i )));
imageBlit.dstOffsets[1].y = int32_t(bitmapInfos[j].height >> (i) == 0 ? 1 : int32_t(bitmapInfos[j].height >> (i)));
imageBlit.dstOffsets[1].z = 1;
VkImageMemoryBarrier imageMemoryBarrier = {};
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
imageMemoryBarrier.pNext = NULL;
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageMemoryBarrier.subresourceRange.baseMipLevel = i;
imageMemoryBarrier.subresourceRange.levelCount = 1;
imageMemoryBarrier.subresourceRange.baseArrayLayer = j;
imageMemoryBarrier.subresourceRange.layerCount = 1;
// change layout of current mip level to transfer dest
setImageLayout(imageMemoryBarrier,
blitCmd,
image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, imageMemoryBarrier.subresourceRange,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_HOST_BIT);
// Do blit operation from previous mip level
vkCmdBlitImage(blitCmd, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageBlit, VK_FILTER_LINEAR);
setImageLayout(imageMemoryBarrier, blitCmd, image, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, imageMemoryBarrier.subresourceRange,
VK_PIPELINE_STAGE_HOST_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT);
}
}
I don't see baseArrayLayer of the imageBlit.srcSubresource and imageBlit.dstSubresource set to j. Which is probably your immediate problem.
Also your barriers seem bad to me. Only the top mip needs to be synchronized with host. But even so VK_PIPELINE_STAGE_HOST_BIT should not be necessary, because there is an exception for vkQueueSubmit saying it does this kind of synchronization implicitly if host writes ended before it being called (6.9. Host Write Ordering Guarantees and reminded in the Note in 6.1.3. Access Types).
I'm developing a project with dsPIC33EV256GM002 and I want to use its UART.
So I decided to use PIN18 as RX and PIN17 as TX so I programed PPS as follow:
// UART1 RX1 18 RP41 RPINR18 010 1001 (41)
// UART1 TX1 17 RP40 RPOR3.RP40R 000 0001 (1)
RPINR18bits.U1RXR=41;
RPOR3bits.RP40R = 1;
and I put PIN18 (RB 9) as input setting the bit9 of TRISB.
I used an external 8M XTAL and I set M,N1 and N2 parameter as follow:
// Configure Oscillator to operate the device at 80MHz/40MIPs
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 8M*40/(2*2)=80Mhz for 8M input clock
// To be safe, always load divisors before feedback
CLKDIVbits.PLLPOST = 0; // N1=2
CLKDIVbits.PLLPRE = 0; // N2=2
PLLFBD = 38; // M=(40-2), Fcyc = 40MHz for ECAN baud timer
// Disable Watch Dog Timer
RCONbits.SWDTEN = 0;
I want to configure the TX/RX port as 31250,N,8,1 (standard MIDI parameters)
// configure U1MODE
U1MODEbits.UARTEN = 0; // Bit15 TX, RX DISABLED, ENABLE at end of func
//U1MODEbits.notimplemented; // Bit14
U1MODEbits.USIDL = 0; // Bit13 Continue in Idle
U1MODEbits.IREN = 0; // Bit12 No IR translation
U1MODEbits.RTSMD = 0; // Bit11 Simplex Mode
//U1MODEbits.notimplemented; // Bit10
U1MODEbits.UEN = 0; // Bits8,9 TX,RX enabled, CTS,RTS not
U1MODEbits.WAKE = 0; // Bit7 No Wake up (since we don't sleep here)
U1MODEbits.LPBACK = 0; // Bit6 No Loop Back
U1MODEbits.ABAUD = 0; // Bit5 No Autobaud (would require sending '55')
U1MODEbits.URXINV = 0; // Bit4 IdleState = 1 (for dsPIC)
U1MODEbits.BRGH = 0; // Bit3 16 clocks per bit period
U1MODEbits.PDSEL = 0; // Bits1,2 8bit, No Parity
U1MODEbits.STSEL = 0; // Bit0 One Stop Bit
// U1BRG = (Fcy/(16*BaudRate))-1
// Fcy=40
// U1BRG = (40000000/(16*BaudRate))-1
// U1BRG = (40000000/(16*31250))-1 = 79
U1BRG = 79; // 40Mhz osc, 31250 Baud
// Load all values in for U1STA SFR
U1STAbits.UTXISEL1 = 0; //Bit15 Int when Char is transferred (1/2 config!)
U1STAbits.UTXINV = 0; //Bit14 N/A, IRDA config
U1STAbits.UTXISEL0 = 0; //Bit13 Other half of Bit15
//U1STAbits.notimplemented = 0; //Bit12
U1STAbits.UTXBRK = 0; //Bit11 Disabled
U1STAbits.UTXEN = 0; //Bit10 TX pins controlled by periph
U1STAbits.UTXBF = 0; //Bit9 *Read Only Bit*
U1STAbits.TRMT = 0; //Bit8 *Read Only bit*
U1STAbits.URXISEL = 0; //Bits6,7 Int. on character recieved
U1STAbits.ADDEN = 0; //Bit5 Address Detect Disabled
U1STAbits.RIDLE = 0; //Bit4 *Read Only Bit*
U1STAbits.PERR = 0; //Bit3 *Read Only Bit*
U1STAbits.FERR = 0; //Bit2 *Read Only Bit*
U1STAbits.OERR = 0; //Bit1 *Read Only Bit*
U1STAbits.URXDA = 0; //Bit0 *Read Only Bit*
IPC2bits.U1RXIP = 1; // Mid Range Interrupt Priority level, no urgent reason
IPC3bits.U1TXIP = 1; // Mid Range Interrupt Priority level, no urgent reason
IFS0bits.U1TXIF = 0; // Clear the Transmit Interrupt Flag
IEC0bits.U1TXIE = 1; // Enable Transmit Interrupts
IFS0bits.U1RXIF = 0; // Clear the Recieve Interrupt Flag
IEC0bits.U1RXIE = 1; // Enable Recieve Interrupts
U1MODEbits.UARTEN = 1; // And turn the peripheral on
for your reference this is the OSC configuration
_FOSCSEL(FNOSC_PRIPLL);
_FOSC(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMD_XT);
// Startup directly into XT + PLL
// OSC2 Pin Function: OSC2 is Clock Output
// Primary Oscillator Mode: XT Crystal
_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software
_FICD(ICS_PGD1); // PGD3 for external PK3/ICD3/RealIce, use PGD2 for PKOB
_FDEVOPT( PWMLOCK_OFF );
_FOSCSEL(FNOSC_PRIPLL);
_FOSC(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMD_XT);
// Startup directly into XT + PLL
// OSC2 Pin Function: OSC2 is Clock Output
// Primary Oscillator Mode: XT Crystal
Since I can't detect data from serial RX because I detect a framing error, I would know if the setting that I used are correct.
Have you similar experience ?
I have got the UART TX working on one pic but cannot get the UART RX working on another PIC. My plan is to have the first PIC send data to the second PIC.
My initialisation code for the first PIC TX is,
Code:
void configure_TX_port(){
/*Port configurations*/
OSCCON = 0X68;
//Push button
TRISC3 = 1;
INLVLC3 = 0;
ANSC3 = 0;
//Led output
TRISC2 = 0;
//TX output
TRISA2 = 0;
ANSA2 = 0;
/*PPS setup for RA2*/
PPSLOCK = 0x55;
PPSLOCK = 0xAA;
PPSLOCK = 0;
RA2PPS = 0x14;
PPSLOCK = 0x55;
PPSLOCK = 0xAA;
PPSLOCK = 1;
/*UART configuration*/
TXEN = 1;
SYNC = 0;
SPEN = 1;
TXSTA = (0x4|0x20);
SPBRG = (int)(4000000L/(16UL * 9600) -1);
}
My send data to the tx code is
Code:
void putch(unsigned char byte) {
/* output one byte */
while (!TXIF) /* set when register is empty */
TXREG = byte;
}
My initialisation code for the second PIC RX is,
void configure_RX_port(){
/*Port configurations*/
OSCCON = 0X68;
//Led output
TRISC3 = 0;
//RX input
TRISC5 = 1;
ANSC5 = 0;
/*UART configuration*/
CREN = 1;
SYNC = 0;
SPEN = 1;
TXSTA = (0x4|0x20);
RCSTA = 0x90;
SPBRG = (int)(4000000L/(16UL * 9600) -1);
}
My receive data code is,
unsigned char getch(void) {
/* retrieve one byte */
unsigned char ret;
while (!RCIF) { /* set when register is not empty */
}
ret = RCREG;
return ret;
}
When I debug the code the getch function gets blocked waiting on a character but my other PIC is sending data. On this PIC RC5 is a designated RX pin so I dont think I have to do any pps configuration.
Rahul
TX1STA = 0b00100100; This enablex TX (TXEN=1) and high baud rate (BRGH = 1)
RC1STA = 0b10000000; This enable the serial port (SPEN = 1)
The only important missing part is your Clock setting and the baudrate you want to have.
I saw 4000000 in the formula, means 4MHz, and /9600, so assume 9600BDS).
Result = 0x25.
SPBRGL = 0x25;
SPBRGH = 0;
This way, your TX should work. Your tx function is good.
Be sure to configure RX and TX pins as DIGITAL by disabling ANSELA, ANSELB and ANSELC.
Your PIC also use PPS, so be sure to configure it the right way.
*********EDITED POST, RECEIVE CONDITION************
The only difference here to get a working receiver is to enable the continuous receiver
bit, CREN.
RC1STA = 0b10010000; //Enable serial port(SPEN) and continuous receive(CREN).
Be sure to set RX pin (RC5 in your case) as an INPUT (TRISC5 = 1) so that it can read any entering data. You should also consider doing an interrupt routine instead of polling the receiver flag bit. That way you're sure not to skip any entering data.
By default at reset all pins on PIC16F1704 are set as analog.
So clear coresponding bits of RX and TX pins in registers ANSELA, ANSELB and ANSELC to set tham as digital.
You look to be using asynchronous mode with SYNC = 0, but do not set TXEN = 1.
Setting CREN = 1 only overrides TXEN in synchronous mode. Try setting TXEN = 1.
I added the following line, TXSTA = (0x4|0x20); to the receiver PIC code and it works now. There is no need for
CREN = 1;
SYNC = 0;
SPEN = 1;
as its setting the same bits.