ColorPAL arduino problem >.

KomuriKomuri Posts: 4
edited March 2012 in Accessories Vote Up0Vote Down
Hi! I am trying to get a ColorPAL working with my Arduino Nano. Basically I connected the pins 2 and 3 to the signal pin in the ColorPAL and use this code to display colors to test:
#include <SoftwareSerial.h>  
SoftwareSerial Color90(2, 3);  
/*====================================================  
/ Connect ColorPAL SIG signal to Arduino pin 2 and 3  
/ Baud Rate = 9600 kbps  /  
/====================================================*/  
void setup() {   
    Serial.begin(9600);   
    Color90.begin(4800);    
    pinMode(2,INPUT);   
    pinMode(3,INPUT);   
    digitalWrite(2,HIGH); // Enable the pull-up resistor   
    digitalWrite(3,HIGH); // Enable the pull-up resistor    
    pinMode(2,OUTPUT);   
    pinMode(3,OUTPUT);   
    digitalWrite(2,LOW);   
    digitalWrite(3,LOW);      
    pinMode(2,INPUT);  
    pinMode(3,INPUT);      
    Serial.println("Pass 1");      
    while( digitalRead(2) != HIGH || digitalRead(3) != HIGH ) {     
       Serial.println("In the loop");     
       delay(50);   
    }      
    Serial.println("Pass 2");    
    pinMode(2,OUTPUT);   
    pinMode(3,OUTPUT);   
    digitalWrite(2,LOW);   
    digitalWrite(3,LOW);   
    delay(80);      
    pinMode(2,INPUT);   
    pinMode(3,OUTPUT);   
    delay(100);   
}  

//---------------------------------  

void loop() {   
   char rByte[9];      
   Color90.begin(4800);   Color90.print("= V !");   delay(500);
   Color90.print("= R !");
   delay(500); 
} 

First it didn´t do anything, but then I read somewhere that powering the ColorPAL with 5V was wrong, instead it should be with 3.3V, so I changed it and the code above worked. The ColorPAL started flashing violet and red. Next I tried to put the ColorPAL to constantly measure a color with the following code:
#include <SoftwareSerial.h>  
SoftwareSerial Color90(2, 3);  
/*====================================================  
/ Connect ColorPAL SIG signal to Arduino pin 2 and 3  
/ Baud Rate = 9600 kbps  /  
/====================================================*/  
void setup() {   
   Serial.begin(9600);   
   Color90.begin(4800);    
   pinMode(2,INPUT);   
   pinMode(3,INPUT);   
   digitalWrite(2,HIGH); // Enable the pull-up resistor   
   digitalWrite(3,HIGH); // Enable the pull-up resistor    
   pinMode(2,OUTPUT);   
   pinMode(3,OUTPUT);   
   digitalWrite(2,LOW);   
   digitalWrite(3,LOW);      
   pinMode(2,INPUT);   
   pinMode(3,INPUT);      
   Serial.println("Pass 1");      
   while( digitalRead(2) != HIGH || digitalRead(3) != HIGH ) {     
      Serial.println("In the loop");     
      delay(50);  
   }      
   Serial.println("Pass 2");    
   pinMode(2,OUTPUT);   
   pinMode(3,OUTPUT);   
   digitalWrite(2,LOW);   
   digitalWrite(3,LOW);   
   delay(80);      
   pinMode(2,INPUT);   
   pinMode(3,OUTPUT);   
   delay(100);  
 }  

//---------------------------------  

void loop() {   
   char rByte[9];      
   Color90.begin(4800);   
   Color90.print("= (00 $ m) !");   
   pinMode(3,INPUT);    
   rByte[0] = Color90.read();   
   if( rByte[0] == '$' ) {     
      for(int i=0; i<9; i++) {       
         rByte[i] = Color90.read();        
         Serial.print(rByte[i]);     
      }     
      Serial.println();   
   }      
   delay(500);
 } 

But that didn´t work at all :(. In some other webpages people said it did worked with them. Basically the serial monitor only showed Pass 1 and Pass 2. I tried other reading codes across the web but none worked :(. Help please!!
«1

Comments

  • 37 Comments sorted by Date Added Votes
  • Martin_HMartin_H Posts: 4,015
    edited March 2012 Vote Up0Vote Down
    I have a ColorPal and an Arduino and can try to get the two working together this weekend. I probably won't have a chance before then.
  • KomuriKomuri Posts: 4
    edited March 2012 Vote Up0Vote Down
    Thanks! It will be much appreciated. So, is it ok to power up the ColorPAL with 3.3V instead of the 5V that come in the manual? o.O
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 21,350
    edited March 2012 Vote Up0Vote Down
    No, follow the specs (that's what they're there for) and use 5V. The LED needs the higher voltage to obtain the best color balance.

    -Phil
    “Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away. -Antoine de Saint-Exupery
  • PublisonPublison Posts: 9,774
    edited March 2012 Vote Up0Vote Down
    Komuri wrote: »
    Thanks! It will be much appreciated. So, is it ok to power up the ColorPAL with 3.3V instead of the 5V that come in the manual? o.O

    The documentation states that the module needs 5V to operate:
    The ColorPAL requires three connections: regulated +5V supply, ground, and open-collector serial data.

    I'm not sure it will work at 3.3V. Although the Sensor and ATtiny are speced at a lower voltages, The LED's may not operate at 3.3V.

    I'd stick to the documentation.

    Jim

    EDIT: Phil got to it before me again! He must not be typing with the broken foot. :)
    Infernal Machine
  • KomuriKomuri Posts: 4
    edited March 2012 Vote Up0Vote Down
    The thing is, that if I power it with 5V it doesn't do anything. But if I power it with 3.3V the led flashes and it does receive the commands sent from the arduino (and displays any color with the rgb led it has). I spent nearly 2 hours following the specs with no success, until I saw a post on the internet saying that with 3.3V it did work, tried it and Voal
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 21,350
    edited March 2012 Vote Up0Vote Down
    Try the circuit shown here with the ColorPAL running at 5V. If you're driving the Arduino's output line high (which you shouldn't be) the ColorPAL may not be seeing a high enough voltage for a logic "high".

    -Phil
    “Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away. -Antoine de Saint-Exupery
  • Martin_HMartin_H Posts: 4,015
    edited March 2012 Vote Up0Vote Down
    I actually hooked all this up today and I am able to turn on the ColorPal, but when I read from it I don't get the $ back. I am still working on it.

    I hooked it up to a single pin and I'm using the software serial object to transmit and receive on the same pin. I did a line by line translation of PBASIC to C and I think I am close.
  • KomuriKomuri Posts: 4
    edited March 2012 Vote Up0Vote Down
    I got it working!! I was already using that circuit but the code was a little bit wrong. After some work I came up with the following code:
    #include <SoftwareSerial.h> 
    #define rxPin 2
    #define txPin 8
    SoftwareSerial colorPal = SoftwareSerial(rxPin, txPin);  
     
    void setup() {   
        Serial.begin(9600);   
        colorPal.begin(4800);    
        pinMode(rxPin,INPUT);   
        pinMode(txPin,INPUT);   
        digitalWrite(rxPin,HIGH); // Enable the pull-up resistor   
        digitalWrite(txPin,HIGH); // Enable the pull-up resistor    
        pinMode(rxPin,OUTPUT);   
        pinMode(txPin,OUTPUT);   
        digitalWrite(rxPin,LOW);   
        digitalWrite(txPin,LOW);      
        pinMode(rxPin,INPUT);  
        pinMode(txPin,INPUT);      
        Serial.println("Pass 1");      
        while( digitalRead(rxPin) != HIGH || digitalRead(txPin) != HIGH ) {     
           Serial.println("In the loop");     
           delay(50);   
        }      
        Serial.println("Pass 2");    
        pinMode(rxPin,OUTPUT);   
        pinMode(txPin,OUTPUT);   
        digitalWrite(rxPin,LOW);   
        digitalWrite(txPin,LOW);   
        delay(80);      
        pinMode(rxPin,INPUT);   
        pinMode(txPin,OUTPUT);   
        delay(100);
    }  
    
    //---------------------------------  
    
    void loop() {
      colorPal.print("= $ m !");
       char rByte[9];
       rByte[0] = colorPal.read();   
       if(rByte[0] == '$'){     
          for(int i=0; i < 9; i++){       
             rByte[i] = colorPal.read();        
             Serial.print(rByte[i]);     
          }     
          Serial.println();   
       }    
       delay(500);
    }
    

    Still the sensor only works with 3.3V. I've made many tests but with 5V it never ever worked.

    Being that aside, a quick question: The 9 hex values represent RGB html hex like colors? I got readings like 0470A2032, so red would be 047, green 0A2 and blue 032. But it doesn't matter what color I put it to read, those values never pass the 0FF value. So is that 0 just for separating the values?

    Thanks for the help :).
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 21,350
    edited March 2012 Vote Up0Vote Down
    Yes, with 0470A2032, red would be 047, green 0A2, and blue 032. The reason you don't get very high values is that the LEDs are not bright enough from running at only 3.3V.

    -Phil
    “Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away. -Antoine de Saint-Exupery
  • Martin_HMartin_H Posts: 4,015
    edited March 2012 Vote Up0Vote Down
    I'm using 5 volts for everything. Here's my code so far:
    /* ColorPal Sensor Example
     * Author.... Martin Heeermance based upon Phil Pilgrim's PBASIC example
     *
     * This program drives the Parallax ColorPAL color sensor and provides
     * serial RGB data to the PC-hosted TCS230_ColorPAL_match.exe color
     * matching program.
     */
    
    #include <SoftwareSerial.h>
    
    // I/O Pin definitions.
    const int sio = 2;
    const int unused = 3;
    const int sioBaud = 4800;
    
    // Received RGB values from ColorPAL.
    int red;
    int grn;
    int blu;
    
    // Set up two software serials on the same pin.
    // This mimic PBASIC's serin and serout function.
    SoftwareSerial serin(sio, unused);
    SoftwareSerial serout(unused, sio);
    
    // -----[ Initialization ]--------------------------------------------------
    void setup()
    {
      // initialize serial communication:
      Serial.begin(9600);
      Serial.println("ColorPal Demo start"); 
      serin.begin(sioBaud);
      
      // Reset the ColorPAL and enter direct command mode.
      Reset();
      
      // Program ColorPAL to send $ then color data.
      serout.begin(sioBaud);
      pinMode(sio, OUTPUT);
      serout.print("= (00 $ m) !");
      pinMode(sio, INPUT);
      serin.begin(sioBaud);
      
      // serout is unused from this point forwards
    }
    
    // -----[ Program Code ]----------------------------------------------------
    // SERIN sio, baud, [WAIT("$"), HEX3 red, HEX3 grn, HEX3 blu] ' Receive RGB data back.
    void loop()
    {
      char buffer[32];
    
      // Wait for a $ and then read three 3 digit hex numbers
      buffer[0] = serin.read();
      //Serial.print(buffer[0]);
      if( buffer[0] == '$' )
      {
        for(int i = 0; i < 9; i++)
        {
          buffer[i] = serin.read();
          Serial.print(buffer[i]);
        }
        Serial.println();
        // format using the format expected by the windows program and output it.
        //sprintf(buffer, "R%4.4d G%4.4d B%4.4d", red, grn, blu);
        //Serial.println(buffer); 
      }
    }  
    
    // -----[ Subroutines ]-----------------------------------------------------
    
    // Reset: Sends a long break to reset ColorPAL and enter direct command mode.
    void Reset()
    {
      Serial.println("Reset ColorPal");
      pinMode(sio, OUTPUT);
      digitalWrite(sio, LOW);  // Pull sio low to eliminate any residual charge.
      pinMode(sio, INPUT);     // Return pin to input.
      while (digitalRead(sio) != HIGH); // Wait for pin to be pulled high by ColorPAL.
      pinMode(sio, OUTPUT);
      digitalWrite(sio, LOW);  // Pull pin low.
      delay(80);               // Keep low for 80ms to enter Direct mode.
      pinMode(sio, INPUT);     // Return pin to input.
      delay(10);               // Pause another 10ms
    }
    
  • GordonMcCombGordonMcComb Posts: 3,147
    edited March 2012 Vote Up0Vote Down
    Martin, Try starting the serial service to the ColorPAL after you've reset. Not that it'll necessarily fix the problem, but if you're toggling pins of a software serial port you might as well not define it first.

    Your use of the two software serials is a bit unusual. I've found a single SoftwareSerial and Phil's circuit to always work with these open drain single-line jobbies.

    -- Gordon
  • Martin_HMartin_H Posts: 4,015
    edited March 2012 Vote Up0Vote Down
    Gordon, I'll try that. I'm really using three pins. That's how I use it on the Stamp and I'm trying to exactly translate over to the Arduino.

    I'm definitely getting data back, but instead of a $ it looks like a y with an umlaut over it. Almost what you would expect if the baud rate didn't match.

    Update! Got it working!
  • GordonMcCombGordonMcComb Posts: 3,147
    edited March 2012 Vote Up0Vote Down
    I don't have a ColorPAL, but Phil did the SoundPAL somewhat the same in regards to interfacing to the Arduino, sending command bytes, etc. Here's a working SoundPAL sketch for Arduino 1.0 (so SoftwareSerial is the old NewSoftSerial), in case it helps. When connected using the diode and resistor as Phil shows above, the one serial port behaves like an ordinary full duplex serial port.

    The sketch demonstrates a couple of ways to play the SoundPAL's built-in tunes, but the general idea is there for you.

    -- Gordon
  • Martin_HMartin_H Posts: 4,015
    edited March 2012 Vote Up0Vote Down
    OK Thanks I will take a look. Moving the serin.begin worked wonders. It's still not quite there, but it is really close.
    /* ColorPal Sensor Example
     * Author.... Martin Heeermance based upon Phil Pilgrim's PBASIC example
     *
     * This program drives the Parallax ColorPAL color sensor and provides
     * serial RGB data to the PC-hosted TCS230_ColorPAL_match.exe color
     * matching program.
     */
    
    #include <SoftwareSerial.h>
    
    // I/O Pin definitions.
    const int sio = 2;
    const int unused = 3;
    const int sioBaud = 4800;
    
    // Received RGB values from ColorPAL.
    int red;
    int grn;
    int blu;
    
    // Set up two software serials on the same pin.
    // This mimic PBASIC's serin and serout function.
    SoftwareSerial serin(sio, unused);
    SoftwareSerial serout(unused, sio);
    
    // -----[ Initialization ]--------------------------------------------------
    void setup()
    {
      // initialize serial communication:
      Serial.begin(9600);
      Serial.println("ColorPal Demo start"); 
    
      // Reset the ColorPAL and enter direct command mode.
      Reset();
      
      // Program ColorPAL to send $ then color data.
      serout.begin(sioBaud);
      pinMode(sio, OUTPUT);
      serout.print("= (00 $ m) !"); // buffer commmands, loop print $ and data end_loop now execute
      pinMode(sio, INPUT);
      serin.begin(sioBaud);
    
      // serout is unused from this point forwards
    }
    
    // -----[ Program Code ]----------------------------------------------------
    // SERIN sio, baud, [WAIT("$"), HEX3 red, HEX3 grn, HEX3 blu] ' Receive RGB data back.
    void loop()
    {
      char buffer[32];
    
      // Wait for a $ and then read three 3 digit hex numbers
      buffer[0] = serin.read();
      if (buffer[0] == '$')
      {
        for(int i = 0; i < 9; i++)
        {
          buffer[i] = serin.read();
          Serial.print(buffer[i]);
        }
        Serial.println();
        // format using the format expected by the windows program and output it.
        //sprintf(buffer, "R%4.4d G%4.4d B%4.4d", red, grn, blu);
        //Serial.println(buffer); 
      }
      delay(100);
    }  
    
    // -----[ Subroutines ]-----------------------------------------------------
    
    // Reset: Sends a long break to reset ColorPAL and enter direct command mode.
    void Reset()
    {
      Serial.println("Reset ColorPal");
      pinMode(sio, OUTPUT);
      digitalWrite(sio, LOW);  // Pull sio low to eliminate any residual charge.
      pinMode(sio, INPUT);     // Return pin to input.
      while (digitalRead(sio) != HIGH); // Wait for pin to be pulled high by ColorPAL.
      pinMode(sio, OUTPUT);
      digitalWrite(sio, LOW);  // Pull pin low.
      delay(80);               // Keep low for 80ms to enter Direct mode.
      pinMode(sio, INPUT);     // Return pin to input.
      delay(10);               // Pause another 10ms
    }
    

    BTW I've been doing a lot of BS2 work lately and have gotten spoiled by its IDE. It files and works really smoothly. The Arduino IDE is a tad cumbersome by comparison.
  • GordonMcCombGordonMcComb Posts: 3,147
    edited March 2012 Vote Up0Vote Down
    Are you using the steering circuit Phil shows?

    Since your code indicates that you're not using the "serout" serial port after you've set up serin, you could try simply ending that port -- serout.end(). Do that first, then start serin. This is because ending a serial port will reset its pins to inputs.

    A problem I see here is that by having serin and serout virtual serial ports tied to the same physical pins, but in reverse, one pin has to be an OUTPUT and the other pin has to be an INPUT. It seems to me the pin direction is set by the last serial.begin() you've set for those pins. Therefore, kill the port you no longer need. With the new SoftwareSerial, the Arduino will capture bytes from the software serial port most recently defined, or the one toggled to with the listen method.

    -- Gordon
  • Martin_HMartin_H Posts: 4,015
    edited March 2012 Vote Up0Vote Down
    Gordon, adding the serout.end() made a big difference. I think that was definitely the cause of some weirdness. I know it is a bit strange to try and insist on a single pin interface, but I'm actually learning quite a bit by knock my head against the keyboard. You've been a wealth of knowledge with the software serial internals, it saved me from having to read though the library file.
  • GordonMcCombGordonMcComb Posts: 3,147
    edited March 2012 Vote Up0Vote Down
    Martin_H wrote: »
    but I'm actually learning quite a bit by knock my head against the keyboard.

    Yes, I do that, too. Only it tends to make me look like these guys:

    this-island-earth1.jpg


    -- Gordon
    337 x 305 - 28K
  • Martin_HMartin_H Posts: 4,015
    edited March 2012 Vote Up1Vote Down
    OK This is at 99% correct. It turns on the color pal, scans the data and prints it back to the PC as decimal delimited by RGB. I've noticed every so often a glitch gets into the data stream, but then it goes back to normal. I put one filter in there for a premature $ and that reduced the incidence, but it still happens now and then. Not sure what's up with that.
    /* ColorPal Sensor Example
     * Author.... Martin Heeermance based upon Phil Pilgrim's PBASIC example
     *
     * This program drives the Parallax ColorPAL color sensor and provides
     * serial RGB data to the PC-hosted TCS230_ColorPAL_match.exe color
     * matching program.
     */
    
    #include <SoftwareSerial.h>
    
    // I/O Pin definitions.
    const int sio = 2;
    const int unused = 3;
    const int sioBaud = 4800;
    
    // Received RGB values from ColorPAL.
    int red;
    int grn;
    int blu;
    
    // Set up two software serials on the same pin.
    // This mimic PBASIC's serin and serout function.
    // A bit non-standard for the Arduino.
    SoftwareSerial serin(sio, unused);
    SoftwareSerial serout(unused, sio);
    
    // -----[ Initialization ]--------------------------------------------------
    void setup()
    {
      // initialize serial communication:
      Serial.begin(9600);
      Serial.println("ColorPal Demo start"); 
      
      // Reset the ColorPAL and enter direct command mode.
      reset();
      
      // Program ColorPAL to send $ then color data.
      serout.begin(sioBaud);
      pinMode(sio, OUTPUT);
      serout.print("= (00 $ m) !"); // buffer commmands, loop print $ and data end_loop now execute
      // serout is unused from this point forwards
      serout.end();
    
      // Now turn the sio pin into an input to read data from the color pal.
      serin.begin(sioBaud);
      pinMode(sio, INPUT);
    }
    
    // -----[ Program Code ]----------------------------------------------------
    // SERIN sio, baud, [WAIT("$"), HEX3 red, HEX3 grn, HEX3 blu] ' Receive RGB data back.
    void loop()
    {
      readData();
    }  
    
    // -----[ Subroutines ]-----------------------------------------------------
    
    // reset: Sends a long break to reset ColorPAL and enter direct command mode.
    void reset()
    {
      Serial.println("Reset ColorPal");
      pinMode(sio, OUTPUT);
      digitalWrite(sio, LOW);  // Pull sio low to eliminate any residual charge.
      pinMode(sio, INPUT);     // Return pin to input.
      while (digitalRead(sio) != HIGH); // Wait for pin to be pulled high by ColorPAL.
      pinMode(sio, OUTPUT);
      digitalWrite(sio, LOW);  // Pull pin low.
      delay(80);               // Keep low for 80ms to enter Direct mode.
      pinMode(sio, INPUT);     // Return pin to input.
      delay(10);               // Pause another 10ms
    }
    
    void readData()
    {
      char buffer[32];
    
      // Wait for a $ and then read three 3 digit hex numbers
      buffer[0] = serin.read();
      if (buffer[0] == '$')
      {
        for(int i = 0; i < 9; i++)
        {
          buffer[i] = serin.read();
          
          // every so often the data terminates early.  If this happen return
          if (buffer[i] == '$')
            return;
        }
        parseAndPrint(buffer);
        delay(100); 
      }
    }
    
    void parseAndPrint(char * data)
    {
      // parse the hex data into integers.
      sscanf (data, "%3x%3x%3x", &red, &grn, &blu);
    
      // format using the format expected by the windows program and output it.
      char buffer[32];
      sprintf(buffer, "R%4.4d G%4.4d B%4.4d", red, grn, blu);
      Serial.println(buffer);
    }
    

    Doing this exercise really made me appreciate the Basic Stamp 2. The serin command is really powerful and my sscanf is something CS majors would be comfortable doing, but not the average non-programmer.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 21,350
    edited March 2012 Vote Up0Vote Down
    Martin, can your Arduino work at non-standard baud rates? If so, try it at 7200 baud, and see if the glitches go away.

    -Phil
    “Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away. -Antoine de Saint-Exupery
  • Martin_HMartin_H Posts: 4,015
    edited March 2012 Vote Up0Vote Down
    Phil, I tried 7200 and it was a no go, but I think that is a limitation of the software serial implementation and not the hardware itself. If I did a lift and move of the library code and re-wrote it into my own serin and serout I bet I could hit 100%. I just ran out of time last night and I'm doing this on a lark to see if I can do it.
  • GordonMcCombGordonMcComb Posts: 3,147
    edited March 2012 Vote Up0Vote Down
    You may want to add some while loops (ideally with timeout escapes). At 4800 (even 7200), that's pretty slow data and the Arduino can easily finish a couple of statement lines before receiving the next character. Add a short delay in the interior of the for loop between each iteration. The Arduino will try to read the next character in the buffer far faster than the ColorPAL can send it.

    The new SoftwareSerial in Arduino 1.0 handles serial.available, so you can use that to check for, and as necessary wait for, the serial buffer to start filling up. That's an overall better approach than hard-coded delays.

    You might try a variation where you stay in a loop first checking if the buffer has anything, then checking if whatever that is is a $. Then begin reading each byte in the for loop. In a sketch that does more than this you'd put in a timeout if nothing is ever received, but that can be left out for basic demo code.

    -- Gordon
  • Martin_HMartin_H Posts: 4,015
    edited March 2012 Vote Up0Vote Down
    Gordon, that makes sense I was thinking that the read call was blocking until new data arrives, but I will definitely take a look at trying serial.available and adding some delays if needed.
  • GordonMcCombGordonMcComb Posts: 3,147
    edited March 2012 Vote Up0Vote Down
    Martin, I'm still not sure what version of the IDE you're using (maybe you said, but I might have missed it), but if it's 1.0, then SoftwareSerial is not blocking. It will also not collect data to a buffer in the background unless it's "listening," and with your setup I'm not sure that's happening. (I only surmised Arduino might automatically listen to the new port because it was started second, but that may not be true.) You might add an explicit listen() method after the begin() for serin, just to make sure.

    Lots of little buglets with can get squashed if you put the receiver code in a fairly tight loop, using available() to test if there's anything in the buffer, then read (and as necessary discard bytes) until the $, and then collect the array. You can put in a timeout with the usual construct if there's a chance the ColorPAL will ever be unresponsive. That all depends on what else the sketch is supposed to do. And of course be sure that serin is the currently active software serial port; that allows it to trigger the proper interrupts for background buffering.

    I'll have to get one of these ColorPAL jobbies someday to try it out. Looks interesting.

    -- Gordon
  • Martin_HMartin_H Posts: 4,015
    edited March 2012 Vote Up0Vote Down
    I upgraded to 1.0 right before trying this because I was using a year old version before this. Non blocking I/O calls are a bit unusual, but that also explains what I am seeing.
  • Martin_HMartin_H Posts: 4,015
    edited March 2012 Vote Up0Vote Down
    The addition of serin.available() > 0, a wait until more data is available, plus a shorter delay between samples solved all the glitches. This sample is now at 100%! The TCS3200_ColorPAL_match.exe program responds to it as if it were the Basic Stamp sample. I imagine that I could possibly get rid of my premature $ error check now, because I think that was caused by buffer over or underflow, but I left it in as it is harmless.
    /* ColorPal Sensor Example
     * Author.... Martin Heermance based upon Phil Pilgrim's PBASIC example
     * with some assistance from Gordon McComb.
     * This program drives the Parallax ColorPAL color sensor and provides
     * serial RGB data to the PC-hosted TCS230_ColorPAL_match.exe color
     * matching program.
     */
    
    #include <SoftwareSerial.h>
    
    // I/O Pin definitions.
    const int sio = 2;
    const int unused = 255; // non-existant pin value
    const int sioBaud = 4800;
    
    // Received RGB values from ColorPAL.
    int red;
    int grn;
    int blu;
    
    // Set up two software serials on the same pin.
    // This mimic PBASIC's serin and serout function.
    SoftwareSerial serin(sio, unused);
    SoftwareSerial serout(unused, sio);
    
    // -----[ Initialization ]--------------------------------------------------
    void setup()
    {
      // initialize serial communication:
      Serial.begin(9600);
      
      // Reset the ColorPAL and enter direct command mode.
      reset();
      
      // Program ColorPAL to send $ then color data.
      serout.begin(sioBaud);
      pinMode(sio, OUTPUT);
      serout.print("= (00 $ m) !"); // buffer commmands, loop print $ and data end_loop now execute
      // serout is unused from this point forwards
      serout.end();
    
      // Now turn the sio pin into an input to read data from the color pal.
      serin.begin(sioBaud);
      pinMode(sio, INPUT);
    }
    
    // -----[ Program Code ]----------------------------------------------------
    // SERIN sio, baud, [WAIT("$"), HEX3 red, HEX3 grn, HEX3 blu] ' Receive RGB data back.
    void loop()
    {
      readData();
    }  
    
    // -----[ Subroutines ]-----------------------------------------------------
    
    // reset: Sends a long break to reset ColorPAL and enter direct command mode.
    void reset()
    {
      pinMode(sio, OUTPUT);
      digitalWrite(sio, LOW);  // Pull sio low to eliminate any residual charge.
      pinMode(sio, INPUT);     // Return pin to input.
      while (digitalRead(sio) != HIGH); // Wait for pin to be pulled high by ColorPAL.
      pinMode(sio, OUTPUT);
      digitalWrite(sio, LOW);  // Pull pin low.
      delay(80);               // Keep low for 80ms to enter Direct mode.
      pinMode(sio, INPUT);     // Return pin to input.
      delay(10);               // Pause another 10ms
    }
    
    void readData()
    {
      char buffer[32];
      
      if (serin.available() > 0)
      {
        // Wait for a $ and then read three 3 digit hex numbers
        buffer[0] = serin.read();
        if (buffer[0] == '$')
        {
          for(int i = 0; i < 9; i++)
          {
            // Wait for the next input character.
            while (serin.available() == 0);     
            buffer[i] = serin.read();
    
            // every so often the data terminates early.  If this happens return
            if (buffer[i] == '$')
              return;
          }
          parseAndPrint(buffer);
          delay(10);
        }
      }
    }
    
    void parseAndPrint(char * data)
    {
      // parse the hex data into integers.
      sscanf (data, "%3x%3x%3x", &red, &grn, &blu);
    
      // format using the format expected by the windows program and output it.
      char buffer[32];
      sprintf(buffer, "R%4.4d G%4.4d B%4.4d", red, grn, blu);
      Serial.println(buffer);
    }
    
  • GordonMcCombGordonMcComb Posts: 3,147
    edited March 2012 Vote Up0Vote Down
    Looking good.

    BTW, do you really spell your name with four e's? That's a lot of vowels!

    -- Gordon
  • Martin_HMartin_H Posts: 4,015
    edited March 2012 Vote Up0Vote Down
    BTW, do you really spell your name with four e's? That's a lot of vowels!

    Thanks for pointing out that spelling error. The triple e should have been a double e for a total of three. It's a Dutch surname and they go overboard with vowels. I'm just glad there is no umlaut I have to deal with.
  • GordonMcCombGordonMcComb Posts: 3,147
    edited March 2012 Vote Up0Vote Down
    That's what I thought, but I wondered if you maintained a "regular" spelling and a real spelling. Some years ago a friend of mine with an Armenian surname went by an informal shortened version out of convenience, though his legal name had about three or four extra syllables. I see he still alternates between the two.

    In Holy Grail Monty Python had some fun during the opening credits with all those funny accented characters. Who could forget "Als
  • I have a problem wiht these sensorcolorpal i got to genered color, and syncronize, but when i want to get the values of colors, the portserial
    does not show me anything, this is my code, could someone help me please

    #include <SoftwareSerial.h>
    #define rxPin 2
    #define txPin 3
    SoftwareSerial colorPal = SoftwareSerial(rxPin, txPin);

    void setup() {
    Serial.begin(9600);
    colorPal.begin(4800);
    pinMode(rxPin,INPUT);
    pinMode(txPin,INPUT);
    digitalWrite(rxPin,HIGH); // Enable the pull-up resistor
    digitalWrite(txPin,HIGH); // Enable the pull-up resistor
    pinMode(rxPin,OUTPUT);
    pinMode(txPin,OUTPUT);
    digitalWrite(rxPin,LOW);
    digitalWrite(txPin,LOW);
    pinMode(rxPin,INPUT);
    pinMode(txPin,INPUT);
    Serial.println("Pass 1");
    while( digitalRead(rxPin) != HIGH || digitalRead(txPin) != HIGH ) {
    Serial.println("In the loop");
    delay(50);
    }
    Serial.println("Pass 2");
    pinMode(rxPin,OUTPUT);
    pinMode(txPin,OUTPUT);
    digitalWrite(rxPin,LOW);
    digitalWrite(txPin,LOW);
    delay(80);
    pinMode(rxPin,INPUT);
    pinMode(txPin,OUTPUT);
    delay(100);
    }

    //

    void loop() {
    colorPal.print("= $ m !");
    char rByte[9];
    rByte[0] = colorPal.read();
    if(rByte[0] == '$'){
    for(int i=0; i < 9; i++){
    rByte = colorPal.read();
    Serial.print(rByte);
    }
    Serial.println();
    }
    delay(500);
    }
  • How do you have this wired up? It looks like you are using two pins to interface, so make sure they're set up correctly. Also your code isn't formatted so I am having a hard time reading it.

    A few post up is code I posted which works with the colorPal and Arduino, and only uses a single pin. You might want to try that.
Sign In or Register to comment.