Shop OBEX P1 Docs P2 Docs Learn Events
Just can't get ColorPAL sensor to work reliably — Parallax Forums

Just can't get ColorPAL sensor to work reliably

Azure FlashAzure Flash Posts: 6
edited 2014-01-19 20:50 in Accessories
Greetings, I've been trying to use the ColorPAL sensor to sort ping-pong balls, but it's been a real nightmare so far. I've tried example code from this forum and little variations from all over the place, but I've seen the following issues so far:

1) The most common issue: the sensor just won't start executing its program. Nine times out of 10 it just blinks blue and then falls silent.
2) Another frequent issue: after rigging up the code to try resetting over and over again until the readings start to look real (i.e. not giving zero constantly), the sensor gives readings but gradually starts to lag and return nonsense.
3) Sometimes while it was running it seemed to just stop cold. I haven't observed this very often, though.

Whatever the problems are with my full ping-pong sorting program, I've decided to attack the first problem by going back to basics and trying to produce a minimal working example... which, well, still doesn't work. It's probably one or several silly rookie mistakes, but I can't see the bugs clearly anymore and I would greatly appreciate the input of someone who knows better.

Here's the code for my minimal example:
#include <SoftwareSerial.h>

// ColorPAL sensor communication data
const int sio = 12;
const int unused = 255;
const int sioBaud = 4800;
SoftwareSerial serin(sio, unused);
SoftwareSerial serout(unused, sio);
// Take red light and ambient measurements in a loop, separated by dollar signs
const char programme[] = "= (00 $ R s X s) !";
char sig;


// Subroutine that's supposed to reset the ColorPAL and send it its program
void reset()
{
  delay(200); // The Arduino is already powered by this point, do we need to wait?
  pinMode(sio, INPUT);
  digitalWrite(sio, HIGH);
  pinMode(sio, OUTPUT);
  digitalWrite(sio, LOW);
  pinMode(sio, INPUT);
  while (digitalRead(sio) != HIGH);
  pinMode(sio, OUTPUT);
  digitalWrite(sio, LOW);
  delay(100); // Documentation says 50, some people use 80 or 100...
  pinMode(sio, INPUT);
  delay(10); // Some people put 10ms delay here, some 100, some 200...
  
  // Send the program
  pinMode(sio, OUTPUT);
  serout.begin(sioBaud);
  // Maybe we need to wait before sending data? Is that what the previous delay does?
  serout.print(programme);
  serout.end();
  
  // From here on out we're listening to the ColorPAL and the pin is kept in INPUT mode
  serin.begin(sioBaud);
  pinMode(sio, INPUT);
}


void setup()
{
  Serial.begin(9600);
  
  reset();
}


void loop()
{
  if(serin.available() > 0)
  {
    sig = serin.read();
    Serial.print(sig);
    Serial.print(" ");
  }
}

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-12-21 00:14
    Try using 7200 baud, instead of 4800 baud.

    -Phil
  • Azure FlashAzure Flash Posts: 6
    edited 2013-12-21 00:49
    Thanks for the quick reply, I'm surprised since it's 4AM where I live! I will try that tomorrow and report back.

    The thought crossed my mind to try and mess with the baud rate, but I had no basis upon which to have any confidence it could work :tongue:
  • GordonMcCombGordonMcComb Posts: 3,366
    edited 2013-12-21 11:41
    7200 baud isn't a supported bit rate for the updated (v1.0+) Arduino Software Serial library. You might have to look around for an alternative library. I've seen some variations of Software Serial that support other speeds.

    I encountered this problem, too. See a variation, here. It wasn't hard-tested (hours and hours of data), but it seemed to work more often than not. Note the very last paragraphs regarding the order of setup when using the Color Matching program.

    http://www.learn.parallax.com/colorpal-arduino-demo
  • Azure FlashAzure Flash Posts: 6
    edited 2013-12-21 12:18
    I'm afraid that didn't change anything. I tried 7200 bauds, then tried different combination of initial delays (0 or 200ms), resetting delay (80 or 100) and post-reset delay (10, 100 or 200ms). I'm not sure whether it's significant, but between my first post and this version I also put all the pinMode() calls before the calls to SoftwareSerial begin(). (P.S. using Arduino 1.0.5 with an Arduino Mega 2560)

    I also tried switching to 5 volts. I've read that people had some success booting and running it at 3.3 volts, and it did seem to make a difference in stability. I know it makes the LEDs dimmer, but we don't need an accurate color reading, just enough to tell white apart from orange (our current approach is using just red readings).

    Furthermore I've tried our second ColorPal, at 5 volts still, with the program below, to no avail.
    #include <SoftwareSerial.h>
    
    // ColorPAL sensor communication data
    const int sio = 12;
    const int unused = 255;
    const int sioBaud = 7200;
    SoftwareSerial serin(sio, unused);
    SoftwareSerial serout(unused, sio);
    char sig;
    
    
    // Subroutine that's supposed to reset the ColorPAL and send it its program
    void reset()
    {
      delay(200); // Still don't know whether that delay is necessary
      pinMode(sio, OUTPUT);
      digitalWrite(sio, LOW);
      pinMode(sio, INPUT);
      while (digitalRead(sio) != HIGH);
      pinMode(sio, OUTPUT);
      digitalWrite(sio, LOW);
      delay(100); // Documentation says 50, some people use 80 or 100...
      pinMode(sio, INPUT);
      delay(200); // Some people put 10ms delay here, some 100, some 200...
      
      // Send the program
      pinMode(sio, OUTPUT);
      serout.begin(sioBaud);
      // Maybe we need to wait before sending data? Is that what the previous delay does?
      serout.print("= (00 $ R s X s) !");
      serout.end();
      
      // From here on out we're listening to the ColorPAL and the pin is kept in INPUT mode
      pinMode(sio, INPUT);
      serin.begin(sioBaud);
    }
    
    
    void setup()
    {
      Serial.begin(9600);
      
      reset();
    }
    
    
    void loop()
    {
      if(serin.available() > 0)
      {
        sig = serin.read();
        Serial.print(sig);
        Serial.print(" ");
      }
    }
    
  • Azure FlashAzure Flash Posts: 6
    edited 2013-12-21 12:38
    Our initials attempts were based on that example, actually. Doesn't it use SoftwareSerial at 4800 bauds? Maybe I could try AltSoftwareSerial...

    As for the last section, I don't really understand how this relates to our use case, but why does it say the waitDelay determines the speed of the return values, when the waitDelay variable is only used in the reset() function? Was that waitDelay supposed to be in the readData() function instead? We do have that 10ms delay in our readData function, hard-coded like in the demo code.
  • GordonMcCombGordonMcComb Posts: 3,366
    edited 2013-12-21 16:14
    The code in the example was developed with the Uno. Don't know if a Mega will make a difference. If you have a spare Uno around, it might be worthwhile to test with it. Also try 1.0 or 1.0.1 IDE, as for reference that's what was used for the Learn site demo.

    The bit about waitDelay is in error, probably crept in during revisions. You'd alter the last statement in readData to change the update speed. I mention the order of events when using the color matching exe in case your application used it. If the order is not followed it behaves exactly as you first described.

    You'll have to ask Phil if the ColorPAL can reliably operate at 3.3V. It's his design, and he knows it better than anyone here.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-12-21 16:42
    You'll have to ask Phil if the ColorPAL can reliably operate at 3.3V. It's his design, and he knows it better than anyone here.
    The onboard AVR will run at 3.3V, but the limiting resistors for the LED are spec'd for brightness and color balance at 5V. It's also possible that the blue LED will be extremely dim at 3.3V. So I would definitely recommend running it at 5V.

    One thing you need to make sure of is that your serial drive is open-collector. You should not drive the data pin high. Also, if your micro's input and output pins are separate, use the circuit posted here:

    -Phil
  • Azure FlashAzure Flash Posts: 6
    edited 2013-12-21 17:15
    I'm very much a beginner in electronics, my background is more in computer science, so far anyway (I switched to EE last year), so that's a bit of chinese for me, but I will ask around.

    What I can tell you about our setup is that we are using only one pin to communicate in serial with the sensor, and using two SoftwareSerial objects for transmitting and receiving. We're not too concerned about a dim blue LED or even color accuracy, we're really just trying to tell something that's white apart from something that's orange.

    The Arduino Mega has three hardware serial pairs of pins, so it might be a good idea for us to use that instead, along with the circuit Phil posted (I was googling for it, but couldn't find it). I will report back in a day or two once we've tried your suggestions.
  • GordonMcCombGordonMcComb Posts: 3,366
    edited 2013-12-21 17:23
    One thing you need to make sure of is that your serial drive is open-collector. You should not drive the data pin high.

    That's probably one of the issues. I don't think the AVR in the Arduino Uno is open collector, though technically as an input (for receiving) the pin should not be driving anything. I don't know about the Mega.
    Also, if your micro's input and output pins are separate

    This particular setup uses simplex comm only, to simplify. Once the setup string is sent to the ColorPAL the same pin is used for the stream of incoming serial.
  • Azure FlashAzure Flash Posts: 6
    edited 2014-01-19 20:50
    Sorry for the extremely late follow-up. We ended up using a DFRobot TCS3200 sensor instead of the ColorPal. Thanks anyway. Will remove the unsolved tag from this thread.
Sign In or Register to comment.