Teensy 2++ processing and Serial >=4

by MisterT on Thu Dec 06, 2012 2:11 pm

Hi

I post here because i have a problem with teensy 2++, processing and Serial.
I follow this tutorial to make a ambilight with my teensy but i have a problem with autodetection of colour of the screen
http://siliconrepublic.blogspot.fr/2011/02/arduino-based-pc-ambient-lighting.html

my arduino code
Code: Select all | TOGGLE FULL SIZE
//Developed by Rajarshi Roy
int red, green, blue; //red, green and blue values
int RedPin = 25; //Red pin 25 has a PWM
int GreenPin = 26; //Green pin 26 has a PWM
int BluePin = 24; //Blue pin 24 has a PWM
unsigned long lastTime;
void setup()
{
  Serial.begin(9600);
  //initial values (no significance)
  int red = 255;
  int blue = 255;
  int green = 255;
 
  analogWrite (RedPin, 255);
  analogWrite (GreenPin, 0);
  analogWrite (BluePin, 0);
  delay(1000);
 
  analogWrite (RedPin, 0);
  analogWrite (GreenPin, 255);
  analogWrite (BluePin, 0);
  delay(1000);
 
  analogWrite (RedPin, 0);
  analogWrite (GreenPin, 0);
  analogWrite (BluePin, 255);
  delay(1000);
 
  analogWrite (RedPin, 0);
  analogWrite (GreenPin, 0);
  analogWrite (BluePin, 0);

}

void loop()
{
 
  //protocol expects data in format of 4 bytes
  //(xff) as a marker to ensure proper synchronization always
  //followed by red, green, blue bytes

  if (Serial.available()>=4) {
    if(Serial.read() == 0xff){
      red = Serial.read();
      green= Serial.read();
      blue = Serial.read();
     
      Serial.print("r");
      Serial.print(red);
      Serial.print("g");
      Serial.print(green);
      Serial.print("b");
      Serial.println(blue);
    }

  }
 
  //finally control led brightness through pulse-width modulation
  analogWrite (RedPin, red);
  analogWrite (GreenPin, green);
  analogWrite (BluePin, blue);
  delay(10); //just to be safe
}



my processing code
Code: Select all | TOGGLE FULL SIZE
//Developed by Rajarshi Roy
import java.awt.Robot; //java library that lets us take screenshots
import java.awt.AWTException;
import java.awt.event.InputEvent;
import java.awt.image.BufferedImage;
import java.awt.Rectangle;
import java.awt.Dimension;
import processing.serial.*; //library for serial communication


Serial port; //creates object "port" of serial class
Robot robby; //creates object "robby" of robot class

void setup()
{
  println(Serial.list());
  port = new Serial(this, Serial.list()[1],9600); //set baud rate
  size(100, 100); //window size (doesn't matter) 
  try //standard Robot class error check
  {
    robby = new Robot();
  }
  catch (AWTException e)
  {
    println("Robot class not supported by your system!");
    exit();
  }
}

void draw()
{
  int pixel; //ARGB variable with 32 int bytes where
  //sets of 8 bytes are: Alpha, Red, Green, Blue
  float r=0;
  float g=0;
  float b=0;
 
  //get screenshot into object "screenshot" of class BufferedImage
  BufferedImage screenshot = robby.createScreenCapture(new Rectangle(new Dimension(1280,1024)));
  //1368*928 is the screen resolution 
  int i=0;
  int j=0;
  //1368*928
  //I skip every alternate pixel making my program 4 times faster
  for(i =0;i<1280; i=i+2){
    for(j=0; j<1024;j=j+2){
      pixel = screenshot.getRGB(i,j); //the ARGB integer has the colors of pixel (i,j)
      r = r+(int)(255&(pixel>>16)); //add up reds
      g = g+(int)(255&(pixel>>8)); //add up greens
      b = b+(int)(255&(pixel)); //add up blues
    }
  }
  r=r/(640*512); //average red (remember that I skipped ever alternate pixel)
  g=g/(640*512); //average green
  b=b/(640*512); //average blue
  setStripColor((int)r,(int)g,(int)b);
  background(r,g,b); //make window background average color
}

void setStripColor(int r,int g, int b){
 
  port.write(0xff); //write marker (0xff) for synchronization
  port.write((byte)(r)); //write red value
  port.write((byte)(g)); //write green value
  port.write((byte)(b)); //write blue value
  delay(10); //delay for safety
 

}

Th Arduino IDE works and my strip led light (i add a initilization program like red during 2 seconds, then green then blue). But when i run processing for autodetection, my strip led don't light.

I verify a lot of things:
Serial port is ok
I choose the good port on processing
Rxtx is ok on processing
On arduino IDE, teensy2++ is select, Serial Port is good and USB type is serial

I found one thing. If i modify this line on arduino IDE:
if (Serial.available()>=4) { by this line if (Serial.available()>=0) {
my Strip led light but only in white colour with glitter

have you a solution in order to read 4 bytes or more ?

thanks for next answers
MisterT
 
Posts: 1
Joined: Thu Dec 06, 2012 1:50 pm

Re: Teensy 2++ processing and Serial >=4

by paulstoffregen on Thu Dec 13, 2012 4:47 pm

This problem is a combination of 2 factors.

On the Teensy side, Serial.available() is reporting the number of unread bytes in the currently buffered USB packet.

On the Processing side, data is being sent one byte at a time. On Windows and Linux, the USB drivers are not smart enough to combine multiple writes into a larger packet (and on Mac it sometimes does, sometimes does not, depending on factors probably only driver developers at Apple really know).

To fix this on the processing side, change the code to put 4 bytes in a buffer, and then use a single write to send it all at once. You'll need to create an array of 4 bytes, put the 4 bytes into the array, then use port.write() to send the array.

I have considered rewriting Teensy's USB code to add an additional layer of buffering. That's quite a lot of extra overhead, to copy the data out of packets to RAM, and then copy from RAM to RAM again when Serial.read() is called. But occasionally people do write code using Serial.available() assuming the buffer is at least some minimum size. Together with "simple" languages like Processing and Visual Basic, where code often sends data one byte at a time and the drivers are not nearly as sophisticaed as other packet-based protocols (like TCP/IP), this issue comes up occasionally.
paulstoffregen
 
Posts: 287
Joined: Sun Oct 11, 2009 10:23 am
Location: Portland, Oregon, USA