<< return to Pixycam.com

Pixy doesnt't see things in different code

Hi,

this is more of a coding question:

I have made a working code for pixy. With this code, it sends specific information to me every half second.
I now wanted to expand the code by using not only pixy, but GPS as well. For this, I use several tabs in Arduino, so it stays simple to read. I copied the working sketch in the new one and the only changes I made to the pixy code is that it should compare to the results from the GPS sketch. The problem is, that now Pixy doesn’t find any blocks at all most of the time. About once every minute there is a usable output, but most of the time I get “No blocks” in about two times as fast as in the working sketch. I really don’t understand the problem. It would be really nice if someone knew what to do.

The board I use is a LinkIt one with the GPS antenna and Pixy

Hi Annika,

could you post your code?

Thanks,
Jesse

Here is my code:

GPS part

[code]
gpsSentenceInfoStruct info;
char buff[256];
double latitude;
double longitude;
int zielbahn=2; //where the runner should be
double latitudealt;
  


static unsigned char getComma(unsigned char num,const char *str)
{
  unsigned char i,j = 0;
  int len=strlen(str);
  for(i = 0;i < len;i ++)
  {
     if(str[i] == ',')
      j++;
     if(j == num)
      return i + 1; 
  }
  return 0; 
}

static double getDoubleNumber(const char *s)
{
  char buf[10];
  unsigned char i;
  double rev;
  
  i=getComma(1, s);
  i = i - 1;
  strncpy(buf, s, i);
  buf[i] = 0;
  rev=atof(buf);
  return rev; 
}

static double getIntNumber(const char *s)
{
  char buf[10];
  unsigned char i;
  double rev;
  
  i=getComma(1, s);
  i = i - 1;
  strncpy(buf, s, i);
  buf[i] = 0;
  rev=atoi(buf);
  return rev; 
}

void parseGPGGA(const char* GPGGAstr)
{
  /* Refer to http://www.gpsinformation.org/dale/nmea.htm#GGA
   * Sample data: $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
   * Where:
   *  GGA          Global Positioning System Fix Data
   *  123519       Fix taken at 12:35:19 UTC
   *  4807.038,N   Latitude 48 deg 07.038' N
   *  01131.000,E  Longitude 11 deg 31.000' E
   *  1            Fix quality: 0 = invalid
   *                            1 = GPS fix (SPS)
   *                            2 = DGPS fix
   *                            3 = PPS fix
   *                            4 = Real Time Kinematic
   *                            5 = Float RTK
   *                            6 = estimated (dead reckoning) (2.3 feature)
   *                            7 = Manual input mode
   *                            8 = Simulation mode
   *  08           Number of satellites being tracked
   *  0.9          Horizontal dilution of position
   *  545.4,M      Altitude, Meters, above mean sea level
   *  46.9,M       Height of geoid (mean sea level) above WGS84
   *                   ellipsoid
   *  (empty field) time in seconds since last DGPS update
   *  (empty field) DGPS station ID number
   *  *47          the checksum data, always begins with *
   */
  /*double latitude;
  double longitude;*/
  int tmp, hour, minute, second, num ;
  if(GPGGAstr[0] == '$')
  {
    tmp = getComma(1, GPGGAstr);
    hour     = (GPGGAstr[tmp + 0] - '0') * 10 + (GPGGAstr[tmp + 1] - '0');
    minute   = (GPGGAstr[tmp + 2] - '0') * 10 + (GPGGAstr[tmp + 3] - '0');
    second    = (GPGGAstr[tmp + 4] - '0') * 10 + (GPGGAstr[tmp + 5] - '0');
    
    sprintf(buff, "UTC timer %2d-%2d-%2d", hour, minute, second);
   // Serial.println(buff);
    
    tmp = getComma(2, GPGGAstr);
    latitude = getDoubleNumber(&GPGGAstr[tmp]);
    tmp = getComma(4, GPGGAstr);
    longitude = getDoubleNumber(&GPGGAstr[tmp]);
    sprintf(buff, "latitude = %10.4f, longitude = %10.4f", latitude, longitude);
   // Serial.println(buff); 
    
    tmp = getComma(7, GPGGAstr);
    num = getIntNumber(&GPGGAstr[tmp]);    
    sprintf(buff, "satellites number = %d", num);
   // Serial.println(buff); 
  }
  else
  {
   // Serial.println("Not get data"); 
  }
}


int positionBahn(){ //I use hard coded coordinates because I wanted to test if GPS is exact enough...Later on I will use other resources
  double m1=-0.7782127;
  double m2=-0.7869476;
  double m3=-0.7890227;
  double m4=-0.7909229;
  double n1=56.656417;
  double n2=56.752804;
  double n3=56.775716;
  double n4=56.796697;
  double korrektur=0.000005;
  int RechtsLinks;

  int welchebahn; //which track is the runner on
  bool nachnorden; //does he go north
  if (latitudealt>latitude){
    nachnorden=true;
  }
  else{
    nachnorden=false;
  }
  
  if(longitude*m1+n1latitude - korrektur){
    welchebahn=1;
   }
   
  else if ( longitude*m2+n2latitude - korrektur){
    welchebahn=2;
  }
  
  else if(longitude*m3+n3latitude - korrektur){
    welchebahn=3;
  }
  
  else if (longitude*m4+n4latitude - korrektur){
    welchebahn=4;
  }

  else{
    welchebahn=-1;
  }

  if(welchebahn>0){
    if(zielbahn>welchebahn){
      if(nachnorden){
        RechtsLinks=2;      
      }
      else{
        RechtsLinks=1;
      }
    }
    else if(zielbahn<welchebahn){
      if(nachnorden){
  
        RechtsLinks=1;
      }
      else{
        RechtsLinks=2;
      }
    }
    else{
      RechtsLinks=0;
    }
  }
  else{
    RechtsLinks=-1;
  }

  latitudealt=latitude;
  return(RechtsLinks);
}@

Pixy and Bluetooth part:

[code]
@
#include   
#include 

#include 
#include 
#include 

// This is the main Pixy object 
Pixy pixy;

byte rechts2[]={0x2B, 0x41, 0x02, 0x64, 0x59};
byte rechts3[]={0x2B, 0x41, 0x03, 0x64, 0x58};  
byte links5[]={0x2B, 0x41, 0x05, 0x64, 0x56};
byte links6[]={0x2B, 0x41, 0x06, 0x64, 0x87};
byte oben1[]={0x2B, 0x41, 0x01, 0x64, 0x5A};
byte unten4[]={0x2B, 0x41, 0x04, 0x64, 0x57};
byte aus[]={0x2B, 0x41, 0xFF, 0x00, 0xC0};
byte alle[]={0x2B, 0x41, 0xFF, 0x20, 0xA0}; 

  
void setup()
{
  Serial.begin(9600);
  Serial.print("Starting...\n");

  pixy.init();
  if(!LBTClient.begin()){
    Serial.println("Bluetooth Client kann nicht starten");
    while(true){
      digitalWrite(13, HIGH);
      delay(50);
      digitalWrite(13, LOW);
      delay(50);
    }
  }
  else
  {
      Serial.println("Bluetooth Client begins successfully");
      // start scan, at most scan 15 seconds
      int num = LBTClient.scan(15);
 
      if(num > 0)
      {
          LBTDeviceInfo info = {0};
          bool conn_result = LBTClient.connect("00:13:43:0A:DB:F0");//bool conn_result = LBTClient.connect("12:34:56:ab:cd:ef", "1234");
          if( !conn_result )
          {
              Serial.println("Cannot connect to SPP Server successfully");
              // Do nothing.
              while(true){
                digitalWrite(13, HIGH);
                delay(20);
                digitalWrite(13, LOW);
                delay(20);
              }
          }
          else
          {
            //Signalisiert erfolgreiche Verbindung
             Serial.println("Connect to SPP Server successfully");
             for(int i=0; i<1; i++){
             LBTClient.write(oben1, sizeof(oben1));
             LBTClient.write(unten4, sizeof(unten4));
             digitalWrite(13, HIGH);
             delay(500);
             LBTClient.write(aus, sizeof(aus));
             digitalWrite(13,LOW);
             delay(500);
             }
          }
      } 
  }
}

void loop()
{ 
  static int i = 0;
  int j;
  uint16_t blocks;
  char buf[32]; 

int anzahlrot=0; //Anzahl rote Blocks
  int mittebreite=160;
  /*int abstandMitteLinks;
  int abstandMitteRechts;*/
  /*int countRechts=0;
  int countLinks=0;
  int countGut=0;*/
  int flaeche1=0; //Flächeninhalt des aktuellen Blocks
  int flaeche2=0; //Flächeninhalt des bisher größten Blocks
  int groessterblock; //Nummer des größten Blocks
  int mittekorrlinks=130;
  int mittekorrrechts=190;
  int RechtsLinks=-1; //Zeigt an ob zu weit rechts, links oder gut (0:nichts, 1:rechts, 2:links)
  int idrechts=-1;
  int idlinks=-1;
  int arrayhilfe=0;
  int x0;
  int x1;
  int x2;
  double welchercase;

  // grab blocks!
  blocks = pixy.getBlocks();

  // If there are detect blocks, print them!
  if (blocks)
  {
    i++;
    /*Serial.println("ping");*/
    // do this (print) every 50 frames because printing every
    // frame would bog down the Arduino
   if(i%50==0)
   {
      for (j=0;j<blocks;j++){
       if(pixy.blocks[j].signature==1){
         anzahlrot++;
       }
      } 
      int roteblocks[anzahlrot];
      for (j=0;j0){
              RechtsLinks=2;
            }
           }
           else if(pixy.blocks[roteblocks[0]].x-/*mittebreite*/mittekorrrechts>0){
            RechtsLinks=1;
           }
           else{
            RechtsLinks=0;
           }
           break;
           
          case 2: 
          welchercase=2;
          RechtsLinks=-1;
            if(pixy.blocks[roteblocks[0]].x mittekorrrechts){
              welchercase=2.1;
              if(mittekorrlinks /*mittebreite*/-pixy.blocks[roteblocks[0]].x mittekorrrechts){
              welchercase=2.2;
              if(mittekorrlinks /*mittebreite*/-pixy.blocks[roteblocks[1]].x<pixy.blocks[roteblocks[0]].x-/*mittebreite*/ mittekorrrechts){
                welchercase=2.21;
                RechtsLinks=1;
              }
              else{
                welchercase=2.22;
                RechtsLinks=2;
              }
            }
            else{
              RechtsLinks=0;
            }
            break;
            
          case 3: 
          welchercase=3;
            x0=pixy.blocks[roteblocks[0]].x;
            x1=pixy.blocks[roteblocks[1]].x;
            x2=pixy.blocks[roteblocks[2]].x;
            if((x1<x0 && x0<x2)||(x2<x0 && x00){
                 RechtsLinks=2;
              }
              else if(x0-/*mittebreite*/mittekorrrechts>0){
                RechtsLinks=1;
              }
              else {
                RechtsLinks=0;
              }
            }
            else if( (x0<x1 && x1<x2)||(x2<x1 && x10){
                RechtsLinks=2;
              }
              else if(x1-/*mittebreite*/mittekorrrechts>0){
                RechtsLinks=1;
              }
              else {
                RechtsLinks=0;
              }
            }
            else if((x0<x2 && x2<x1)||(x1<x2 && x20){
                RechtsLinks=2;
              }
              else if(x2-/*mittebreite*/mittekorrrechts>0){
                RechtsLinks=1;
              }
              else {
                RechtsLinks=0;
              }
            }
            break;
            
          default:
          welchercase=4;
            for(j=0; jflaeche2){
                flaeche2=flaeche1;
                groessterblock=roteblocks[j];
              }
            }
              if(mittekorrlinks /*mittebreite*/-pixy.blocks[groessterblock].x>0){
                RechtsLinks=2;
              }
              else if(pixy.blocks[groessterblock].x-/*mittebreite*/mittekorrrechts>0){
                RechtsLinks=1;
              }
              else{
                RechtsLinks=0;
              }
            
            break;
            
        }
  
            
          

      
   }
  }
           //Serial.println("LGPS loop"); 
  LGPS.getData(&info);
  //Serial.println((char*)info.GPGGA); 
  parseGPGGA((const char*)info.GPGGA);
  //int RechtsLinksPixy=positionLinien();
  int RechtsLinksGPS=positionBahn();
  if(RechtsLinksGPS>=0 && RechtsLinks>=0){
    ausgabe(RechtsLinks);
  }
  else if(RechtsLinksGPS>=0 && RechtsLinks<0){
    ausgabe(RechtsLinksGPS);
    Serial.println("gps");
  }
  else if(RechtsLinks>=0 && RechtsLinksGPS<0){
    ausgabe(RechtsLinks);
    Serial.println("pixy");
    Serial.println(welchercase);
  }
  else{
    ausgabe(-2);
  }   
  }  

void ausgabe(int RechtsLinks){     
  switch(RechtsLinks){
        case -2:
        Serial.println("Keine Daten vorhanden");
        LBTClient.write(alle, sizeof(alle));
        delay(100);
        break;
        case -1: 
        Serial.println("Keine Bahn vorhanden");
        LBTClient.write(alle, sizeof(alle));
        delay(400);
        break;
        case 0:
        Serial.println("gut");
        break;
        case 1: 
        Serial.println("zu weit rechts");
        LBTClient.write(rechts3, sizeof(rechts3));
        break;
        case 2:
        Serial.println("zu weit links");
        LBTClient.write(links5, sizeof(links5));
        break;
      }
      /*Serial.println(welchercase);*/
      RechtsLinks=-1;
      delay(100);
      LBTClient.write(aus, sizeof(aus));
      delay(100);
}@
[/code]

I’m sorry my variables are partly german, but I don’t think it matters here. It is the code I spoke about in this thread: http://cmucam.org/boards/9/topics/7445 .

The output only says “No Data” with occasionally “cserror” and “reorder”, but this is very rare. Also, the output is much faster as in the working programm.
Thank you for your help.

This is the basic code which I use for the GPS/ Pixy part. It works


#include   
#include 

#include 
#include 
#include 

// This is the main Pixy object 
Pixy pixy;

byte rechts2[]={0x2B, 0x41, 0x02, 0x64, 0x59};
byte rechts3[]={0x2B, 0x41, 0x03, 0x64, 0x58};  
byte links5[]={0x2B, 0x41, 0x05, 0x64, 0x56};
byte links6[]={0x2B, 0x41, 0x06, 0x64, 0x87};
byte oben1[]={0x2B, 0x41, 0x01, 0x64, 0x5A};
byte unten4[]={0x2B, 0x41, 0x04, 0x64, 0x57};
byte aus[]={0x2B, 0x41, 0xFF, 0x00, 0xC0};
byte alle[]={0x2B, 0x41, 0xFF, 0x20, 0xA0}; 

  
void setup()
{
  Serial.begin(9600);
  Serial.print("Starting...\n");

  pixy.init();
  if(!LBTClient.begin()){
    Serial.println("Bluetooth Client kann nicht starten");
    while(true){
      digitalWrite(13, HIGH);
      delay(50);
      digitalWrite(13, LOW);
      delay(50);
    }
  }
  else
  {
      Serial.println("Bluetooth Client begins successfully");
      // start scan, at most scan 15 seconds
      int num = LBTClient.scan(15);
 
      if(num > 0)
      {
          LBTDeviceInfo info = {0};
          bool conn_result = LBTClient.connect("00:13:43:0A:DB:F0");//bool conn_result = LBTClient.connect("12:34:56:ab:cd:ef", "1234");
          if( !conn_result )
          {
              Serial.println("Cannot connect to SPP Server successfully");
              // Do nothing.
              while(true){
                digitalWrite(13, HIGH);
                delay(20);
                digitalWrite(13, LOW);
                delay(20);
              }
          }
          else
          {
            //Signalisiert erfolgreiche Verbindung
             Serial.println("Connect to SPP Server successfully");
             for(int i=0; i<1; i++){
             LBTClient.write(oben1, sizeof(oben1));
             LBTClient.write(unten4, sizeof(unten4));
             digitalWrite(13, HIGH);
             /*byte ex2[]={0x2B, 0x43, 0x00, 0x00, 0x64, 0x64, 0x00, 0x00, 0x64, 0x00, 0x84, 0x03, 0x05, 0x01, 0x04};
             LBTClient.write(ex2, sizeof(ex2));*/
             delay(500);
             LBTClient.write(aus, sizeof(aus));
             digitalWrite(13,LOW);
             delay(500);
             }
          }
      } 
  }
}

void loop()
{ 
  static int i = 0;
  int j;
  uint16_t blocks;
  char buf[32]; 

int anzahlrot=0; //Anzahl rote Blocks
  int mittebreite=160;
  /*int abstandMitteLinks;
  int abstandMitteRechts;*/
  /*int countRechts=0;
  int countLinks=0;
  int countGut=0;*/
  int flaeche1=0; //Flächeninhalt des aktuellen Blocks
  int flaeche2=0; //Flächeninhalt des bisher größten Blocks
  int groessterblock; //Nummer des größten Blocks
  int mittekorrlinks=130;
  int mittekorrrechts=190;
  int RechtsLinks; //Zeigt an ob zu weit rechts, links oder gut (0:nichts, 1:rechts, 2:links)
  int idrechts=-1;
  int idlinks=-1;
  int arrayhilfe=0;
  int x0;
  int x1;
  int x2;
  double welchercase;

  // grab blocks!
  blocks = pixy.getBlocks();

  // If there are detect blocks, print them!
  if (blocks)
  {
    i++;
    /*Serial.println("ping");*/
    // do this (print) every 50 frames because printing every
    // frame would bog down the Arduino
   if(i%50==0)
   {
      for (j=0;j<blocks;j++){
       if(pixy.blocks[j].signature==1){
         anzahlrot++;
       }
      } 
      int roteblocks[anzahlrot];
      for (j=0;j0){
              RechtsLinks=2;
            }
           }
           else if(pixy.blocks[roteblocks[0]].x-/*mittebreite*/mittekorrrechts>0){
            RechtsLinks=1;
           }
           else{
            RechtsLinks=0;
           }
           break;
           
          case 2: 
          welchercase=2;
          RechtsLinks=-1;
            if(pixy.blocks[roteblocks[0]].x mittekorrrechts){
              welchercase=2.1;
              if(mittekorrlinks /*mittebreite*/-pixy.blocks[roteblocks[0]].x mittekorrrechts){
              welchercase=2.2;
              if(mittekorrlinks /*mittebreite*/-pixy.blocks[roteblocks[1]].x<pixy.blocks[roteblocks[0]].x-/*mittebreite*/ mittekorrrechts){
                welchercase=2.21;
                RechtsLinks=1;
              }
              else{
                welchercase=2.22;
                RechtsLinks=2;
              }
            }
            else{
              RechtsLinks=0;
            }
            break;
            
          case 3: 
          welchercase=3;
            x0=pixy.blocks[roteblocks[0]].x;
            x1=pixy.blocks[roteblocks[1]].x;
            x2=pixy.blocks[roteblocks[2]].x;
            if((x1<x0 && x0<x2)||(x2<x0 && x00){
                 RechtsLinks=2;
              }
              else if(x0-/*mittebreite*/mittekorrrechts>0){
                RechtsLinks=1;
              }
              else {
                RechtsLinks=0;
              }
            }
            else if( (x0<x1 && x1<x2)||(x2<x1 && x10){
                RechtsLinks=2;
              }
              else if(x1-/*mittebreite*/mittekorrrechts>0){
                RechtsLinks=1;
              }
              else {
                RechtsLinks=0;
              }
            }
            else if((x0<x2 && x2<x1)||(x1<x2 && x20){
                RechtsLinks=2;
              }
              else if(x2-/*mittebreite*/mittekorrrechts>0){
                RechtsLinks=1;
              }
              else {
                RechtsLinks=0;
              }
            }
            break;
            
          default:
          welchercase=4;
            for(j=0; jflaeche2){
                flaeche2=flaeche1;
                groessterblock=roteblocks[j];
              }
            }
              if(mittekorrlinks /*mittebreite*/-pixy.blocks[groessterblock].x>0){
                RechtsLinks=2;
              }
              else if(pixy.blocks[groessterblock].x-/*mittebreite*/mittekorrrechts>0){
                RechtsLinks=1;
              }
              else{
                RechtsLinks=0;
              }
            
            break;
            
        }
            
            
          
      switch(RechtsLinks){
        case -1: 
        Serial.println("Fehler");
        LBTClient.write(alle, sizeof(alle));
        delay(400);
        break;
        case 0:
        Serial.println("gut");
        break;
        case 1: 
        Serial.println("zu weit rechts");
        LBTClient.write(rechts3, sizeof(rechts3));
        break;
        case 2:
        Serial.println("zu weit links");
        LBTClient.write(links5, sizeof(links5));
        break;
      }
      Serial.println(welchercase);
      RechtsLinks=-1;
      delay(100);
      LBTClient.write(aus, sizeof(aus));
      
   }
  }
  }  



Short Update:
I found the source of all evil:

while

void loop(){
  int i=0;
  if(blocks){
   i++;
   if(i%50==0)
   {
    .....
   }
  }
}

works fine if it is in the main and only sketch in void loop(), it doesn’t in a sketch with several tabs. I deleted the if(i%50==0) part and I don’t get any more “no Data”. Though the sketch is still buggy, this problem is solved.

Though if anyone has remarks about the code and how to improve it I’m happy to hear :slight_smile:

Hello Annika,
The condition

if (i%50==0)

is added to the hello_world demo because printing to the console 50 times a second can overwhelm the Arduino (it spends all of it’s time printing). The code will make the Arduino only print every 50th reading. It makes sense that it can cause problems when merging the code with other sensors and events. Good work!

Edward