<< return to Pixycam.com

PIXY 2 interfacing via SPI using STM32F7

Hello Everyone,

I am using PIXY 2 to interface with STM32F7 using SPI with SS.

I am following this request response given in this link

https://docs.pixycam.com/wiki/doku.php?id=wiki:v2:porting_guide

I have few things which i need to understand regarding pixy2.

  1. While receiving version from pixy2 i noticed that it sends first 9 bytes as garbage. Is that suppose to be normal? I checked this thing for other cases like Toggling lamp and encountered with the same issue.

  2. While trying to read blocks from pixy i get following kind of data which is not supposed to be.

REQUEST:
uint8_t getBlocks[] = {
0xae,
0xc1,
32,
2,
7,
2
};

Response in decimal:
175 193 33 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1

Have i missed something while initializing???
I can perfectly read the version and toggle the lamp. But i can’t read the blocks. Using pixyMon i have set the signature 1(RED).

Here is the code for version and its response:

  uint8_t versionRequest[] =
  {
    0xae,  // first byte of no_checksum_sync (little endian -> least-significant byte first)
    0xc1,  // second byte of no_checksum_sync
    0x0e,  // this is the version request type
    0x00,   // data_length is 0
  };
	  CS_Low;

	  HAL_SPI_Transmit(&hspi1, versionRequest, 4, 1000);
	  HAL_Delay(1);
	  HAL_SPI_Receive(&hspi1, dataReceived, 9, 1000);  //first 9 garbage data
	  HAL_SPI_Receive(&hspi1, dataReceived, 22, 1000);
	  HAL_UART_Transmit(&huart3, (uint8_t*)"DATA RECEIVED: \r\n", strlen("DATA RECEIVED: \r\n"), 1000);
	  for (int i = 0; i < 22; i++)	{
		  if (i < 12)
			  sprintf((char*)printBuff, "%d ", dataReceived[i]);
		  else
			  sprintf((char*)printBuff, "%c", dataReceived[i]);
		  HAL_UART_Transmit(&huart3, printBuff, strlen((char*)printBuff), 1000);
	  }
	  HAL_UART_Transmit(&huart3, (uint8_t*)"\r\n\r\n", strlen("\r\n\r\n"), 1000);

	  CS_High;

	  for (int i = 0; i < 26; i++)
		  dataReceived[i] = 0;

	  HAL_Delay(1000);

RESPONSE FOR VERSION REQUEST:

175 193 15 16 14 3 0 34 3 0 11 0 general

CODE FOR GET BLOCKS:

  uint8_t getBlocks[] = {
		  0xae,
		  0xc1,
		  32,
		  2,
		  7,
		  2
  };

	  CS_Low;

	  HAL_SPI_Transmit(&hspi1, getBlocks, 5, 1000);
	  HAL_Delay(1);
	  HAL_SPI_Receive(&hspi1, dataReceived, 9, 1000); //garbage values
	  HAL_SPI_Receive(&hspi1, dataReceived, 18, 1000);
	  HAL_UART_Transmit(&huart3, (uint8_t*)"DATA RECEIVED: \r\n", strlen("DATA RECEIVED: \r\n"), 1000);
	  for (int i = 0; i < 18; i++)	{
		  sprintf((char*)printBuff, "%d ", dataReceived[i]);
		  HAL_UART_Transmit(&huart3, printBuff, strlen((char*)printBuff), 1000);
	  }
	  HAL_UART_Transmit(&huart3, (uint8_t*)"\r\n\r\n", strlen("\r\n\r\n"), 1000);

	  CS_High;

	  for (int i = 0; i < 26; i++)
		  dataReceived[i] = 0;

	  HAL_Delay(1000);

RESPONSE FOR GET BLOCKS:

175 193 33 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1

I am using SPI at around 1.7 MHz But i have tried increasing the speed and the result is same.
I am using CPOL = 0 and CPHA = 2nd EDGE 1.

I have tried using Mode 3 i.e CPOL = 1 and CPHA = 1. But it results the same.

Datasize of SPI is 8 bit and First bit is MSB

Here is the initialization of SPI for STM32F7 using HAL

void MX_SPI1_Init(void)
{

  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }

}

What i am doing wrong while trying to getBlocks from pixy2

Any suggestions will be appreciated.

Hello Devjeet,
Make sure you are using the correct SPI mode:

https://docs.pixycam.com/wiki/doku.php?id=wiki:v2:porting_guide#spi

In particular, Pixy2 uses SPI mode 3. You will need to consult the datasheet for your processor.

Edward

According to the link it says

  • SPI SCK is low when idle
  • Data bits are latched on the falling edge of SPI SCK

And also says SPI Mode 3 where CPOL = 1(High) and CPHA = 1(2nd Edge)

Moreover i have tried all the SPI Modes i.e combination of CPOL and CPHA and end up with same result.

Further i could easily read version then i don’t think for reading blocks i need to change SPI Mode.

Regards.

Hello Devjeet,
Try this —

uint8_t getBlocks[] = {
0xae,
0xc1,
32,
2,
0xff,
0xff
}

Thanks Edge, i just found the solution… it was

I was sending 5 bytes in spi

HAL_SPI_Transmit(&hspi1, getBlocks, 5, 1000);

But after your answer i found there are 6 bytes and this was my mistake. It should be

HAL_SPI_Transmit(&hspi1, getBlocks, 6, 1000);

What a silly mistake.

Thanks for your help.

1 Like

I have a last question, If i select tow signature say RED and GREEN and i get the both blocks in frame. Then what will be my response pattern? How many bytes do i need to read through SPI.

And moreover if i have one signature say RED and have 10 blocks of RED visible on my frame then what will be the response ? What will be the procedure of reading those blocks?

Hello Devjeet,
The response packet will always have a length field that will tell you how much data to read. Within the packet is the block data that you will parse.

This is from the Arduino code (PIxy2CCC.h) —

if (m_pixy->recvPacket()==0)
{
  if (m_pixy->m_type==CCC_RESPONSE_BLOCKS)
  {
    blocks = (Block *)m_pixy->m_buf;
    numBlocks = m_pixy->m_length/sizeof(Block);
    return numBlocks;
 }

So take the length field and divide by the sizeof(Block) (14) to get the number of blocks. And Blocks are stacked in the buffer memory as such—

uint16_t m_signature;
uint16_t m_x;
uint16_t m_y;
uint16_t m_width;
uint16_t m_height;
int16_t m_angle;
uint8_t m_index;
uint8_t m_age;

Edward

Could you share the code sir i will learn it ?

Hello,
I’m not sure which code you are seeking. Please be more specific.

Edward

code for stm32 because only code arduino which 's open source so i have difficult to convert all code arduino to stm32 because different languages between arduino and stm32

Hello mr.edge, I’m having a lot of trouble coding pixy2cam on stm32. can you send sample code to get signature, x, and y values?

Hello,
I don’t have stm32 code (sorry). We have a porting guide that is helpful when using a different platform:

https://docs.pixycam.com/wiki/doku.php?id=wiki:v2:porting_guide

Edward

hello dev, i have been researching about pixy2 on stm32 for a long time , but i keep failing. can you share the full code for me please? i will be very grateful

Hello,
We don’t have an stm32 port, but please tell us which platform you are using. If enough users are request support for this platform it helps make our decision to support sooner. :slight_smile:

Edward

thanks for the response, lastly i tried this method from youtube, https://www.youtube.com/watch?v=QzR0UCLsbRU , the platform that i used is different from the video, i use stm32f411ceu6 (Blackpill) and i also use some software such as stm32cubemx and keil uvision 5 to program Pixycam2. but it still didn’t work. My final goal in this research is just to get the x value of the object detected by pixy. There was one time when the value appeared but it didn’t change when I moved the object :upside_down_face:

Hello,
If you can print the characters you receive and compare them to the responses on this page:
https://docs.pixycam.com/wiki/doku.php?id=wiki:v2:porting_guide#getblocks-sigmap-maxblocks

You should be able to track down where things are going wrong in your code (with some debugging).

Hope this helps :slight_smile:

Edward