<< return to Pixycam.com

Arduino mega <-> pixy2 / why performance is divided by two while using two pixy?


#1

Hello,

I’m toying with the idea to use two pixies: one that looks on the ground and does the line following. And another one on the side to identify barcodes that may be there or removed. It’s a typicaly case that if you want the robot to stop, then you position a stand on the side with a barcode. the robot will stop when it passes nearby. Now I want the system to detect when the user removes the stand in order to resume the moving robot movements.

I do have two pixy2 connected to an arduino mega. One using the default connexion (ISP ?) and the other using I2C.

It does work but i’m concerned with one thing.

While using one pixy for the line following on the floor, I observed a typical loop duration of about 16ms. (about 61 fps). but when i use two pixies, then I see a typical loop duration at about 32ms (31 fps)
the performance of the overall system is divided by two.

It may sounds silly but i dont understand why.
Surely all the time cannot go through the mega <-> pixy communication decoding under the hood?
(i did not notice any difference between using getMainFeatures / getAllFeatures by the way)

What do I wrong? How can i get my 16ms again ?

see code below

// tested on arduino mega
// as is the loop duration is about 16ms
// but if i uncomment the code for the second pixy => then it drops to 31ms
// how come?

#include <Pixy2.h>
Pixy2 pixy_front;



#include <Pixy2I2C.h>
Pixy2I2C pixy_side;

unsigned long previous_tick = 0;
unsigned long current_tick = 0;

void setup() {
  previous_tick = millis();
  Serial.begin(115200);
  Serial.print("init pixy_front...");
  pixy_front.init();
  //pixy.init(0x58); // 0x58 is i2C address
  pixy_front.setLED(255, 255, 255); // white
  // Change to line tracking program
  pixy_front.changeProg("line");
  Serial.print("ok\n");
  Serial.print("init pixy_side...");
  pixy_side.init();
  //pixy.init(0x58); // 0x58 is i2C address
  pixy_side.setLED(255, 255, 255); // white
  // Change to line tracking program
  pixy_side.changeProg("line");
  Serial.print("ok\n");
  delay(50);
}

void loop() {

  current_tick = millis();
  long duration = current_tick - previous_tick;
  previous_tick = current_tick;
  Serial.print("d:");
  Serial.print(duration);
  Serial.print("\t");
  
  
  // put your main code here, to run repeatedly:
  int8_t res;
  res = pixy_front.line.getMainFeatures();
  if (res > 0)
  { 
    int32_t x1 = 0xFFFF;
    if (res & LINE_VECTOR) {
      x1 = (int32_t)pixy_front.line.vectors->m_x1;
    }
    Serial.print("x:");
    Serial.print(x1);
    Serial.print("\t");
    int32_t b0 = 0xFF00;
    if (res & LINE_BARCODE) {
      b0 = (int32_t)pixy_front.line.barcodes->m_code;
      Serial.print("b0:");
      Serial.print(b0);
    }
    Serial.print("\t");
  } else {
    Serial.print("pixy_front_getAllFeatures error\t");
  }


/*  res = pixy_side.line.getMainFeatures();
  if (res > 0)
  { 
    int32_t x1 = 0xFFFF;
    x1 = 0xFFFF;
    if (res & LINE_VECTOR) {
      x1 = (int32_t)pixy_side.line.vectors->m_x1;
    }
    Serial.print("x1:");
    Serial.print(x1);
    Serial.print("\t");
    int32_t b0 = 0xFF00;
    if (res & LINE_BARCODE) {
      b0 = (int32_t)pixy_side.line.barcodes->m_code;
      Serial.print("b1:");
      Serial.print(b0);
    }
  } else {
    Serial.print("pixy_side_getAllFeatures error\t");
  }
*/  
  Serial.print("\n");

}

#2

Hello,
I’m not exactly sure why it would be slower, but doing all of the Serial.print’s can really slow things down. Have you tried removing these?

Edward


#3

not tried yet but i really doubt it.
at 112500bits/s, I can send ~14000bytes/sec over serial.
in over words a simple line made of
x1:45\tb1:65535\n
makes 17bytes
17/14000*1000 = 1.2 millisec

+1.2ms does not explain the observed +16 ms

I suspect the way I connected the pixies (default thinkg (ISP?) and I2C) uses some shared resource that force one to wait prior to use the other. something like that.

==> what is the “recommended” way to connect two pixies on arduino mega so that I am sure – in theory – there is no performance impact? (like I could put 4 or 6 pixies without any noticeable difference?)

Something else that I suspect. The first pixy is looking towards the ground. the image is rather flat (all grey expect the line). whereas the second pixy2 is mounted on the side, sideways with barcode positionned vertically (so that motion blur does not impact the barcode reading, like we do on the floor). Here, i noticed that depending on the background, the pixy2 is faster or slower (maybe not 61fps all the time… dunno).

two things I will try

  • put a black tape on the second pixy2 to make sure it sees nothing and goes at 61fps
  • observe the fps while using only the pixy2 on the side instead of the one looking on the floor

#4

Hello,
At 115Kbaud things print fast, agreed. What might be happening (I don’t know) is something might be throwing the timing off. The frame is ready, [print some serial message], wait 16ms for the next frame. I don’t know what is causing your issue, but some experimenting is needed, evidence needs to be collected.

When faced with these kinds of issues, I (personally) start disabling sections of my code until the problem goes away and then try to narrow things down a specific line/call that causes the issue. With the line/call, the issue is present. Without the line/call the issue goes away completely. What if I move the line/call somewhere else in the program/loop?

Talking to multiple Pixys can be done by sharing either the i2c or SPI with slave select signals. I2C can be easier because it doesn’t need slave select signals, but you need to configure the i2c addresses for each device. SPI is faster in general, but not so much that it’s a big advantage. This guide can help:

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

Sharing an interface will simplify your wiring, perhaps simplify your program – you’ll be using the same pixy class/type for each pixy, and you’ll save program space, but I since I don’t know what’s going on with the timing, I don’t know if it will fix your issue.

Edward