why is the serial writing more than 256 bytes?

I’m trying (and failing hard) to use an a2051 optical sensor as a camera. This for loop is quite apparently asking for 256 values to be written over serial, but on the other end (Processing) it’s picking up 512 (and sometimes an odd number like 1008).

void sendImage()
{
  byte val;
  byte adr;
  //Serial.print (">IMG:");
  
  writeRegister (0x0a, 0x09);
  for (int i=0; i<256; i++)
  {
    do {
      adr = readRegister (0x0d);
      val = readRegister (0x0c);
    } while (val & 0x80);
//    Serial.print (adr, HEX);
//    Serial.print ('>', BYTE);
    Serial.println (val);
//    Serial.print (13, BYTE);
  } 
  
  //Serial.println ();
  writeRegister (0x0a, 0x00);
}

And in the end I get an image that looks like this …

Post your code.

Serial.println (val); will append a newline character after the val

The command you want is Serial.write(val);

    Serial.println (val);

If val=90 then the println will send '9' '0' and a linefeed (or maybe even CR and LF) - i.e. it will send three characters, not one.

If you want to write the raw byte use:

    Serial.write(val);

Pete

oh man, such a face palm. looking forward to trying this out. thank you.

for posterity, the whole code:

/*******************************/
/* OptiMouse, Benoît ROUSSEAU  */
/* - dialoguer avec un ADS2051 */
/* récupérer sur une souris    */
/* optique                     */
/*******************************/

#define PIN_CLOCK 2
#define PIN_DATA 3
#define _BV(bit) (1 << (bit))

byte readRegister (byte adresse)
{
  int i = 7;
  byte retour = 0;
  
  pinMode (PIN_DATA, OUTPUT);
  for (; i>=0; i--)
  {

     digitalWrite (PIN_CLOCK, LOW);
     digitalWrite (PIN_DATA, adresse & (1 << i));
     digitalWrite (PIN_CLOCK, HIGH);
  }
  
  pinMode (PIN_DATA, INPUT);
  delayMicroseconds(100);
 
  for (i=7; i>=0; i--)
  {
    digitalWrite (PIN_CLOCK, LOW);
    digitalWrite (PIN_CLOCK, HIGH);
    retour |= (digitalRead (PIN_DATA) << i);
  }
  delayMicroseconds(100);
  
  return retour;
}

void writeRegister (byte adresse, byte donnee)
{
  int i = 7;
  
  adresse |= 0x80;
  
  pinMode (PIN_DATA, OUTPUT);
  for (; i>=0; i--)
  {

     digitalWrite (PIN_CLOCK, LOW);
     digitalWrite (PIN_DATA, adresse & (1 << i));
     digitalWrite (PIN_CLOCK, HIGH);
  }
 
  for (i=7; i>=0; i--)
  {
    digitalWrite (PIN_CLOCK, LOW);
     digitalWrite (PIN_DATA, donnee & (1 << i));
     digitalWrite (PIN_CLOCK, HIGH);
  }

}

void sendImage()
{
  byte val;
  byte adr;
  //Serial.print (">IMG:");
  
  writeRegister (0x0a, 0x09);
  for (int i=0; i<256; i++)
  {
    do {
      adr = readRegister (0x0d);
      val = readRegister (0x0c);
    } while (val & 0x80);
//    Serial.print (adr, HEX);
//    Serial.print ('>', BYTE);
    Serial.println (val);
//    Serial.print (13, BYTE);
  } 
  
  //Serial.println ();
  writeRegister (0x0a, 0x00);
}

void setup()
{
  pinMode (PIN_CLOCK, OUTPUT);
  pinMode (PIN_DATA, INPUT);
  Serial.begin(19200);
}

void loop ()
{
  // this stuff only matters for the mouse moving
  /*
  if (readRegister (0x02))
  {
    Serial.print ('>');
    Serial.print (readRegister (0x00), DEC);
    Serial.print ('-');
    Serial.print (readRegister (0x01), DEC);
    Serial.print ('-');
    Serial.print (readRegister (0x03), DEC);
    Serial.print ('-');
    Serial.print (readRegister (0x04), DEC);
    Serial.println ();
  }
  */
  if (Serial.available())
  {
    Serial.read();
    sendImage();
  }
}

EDIT: Really, the whole code :wink:

import processing.serial.*;

Serial port;  // Create object from Serial class

int[] frame;

int frameX = 16;
int frameY = 16;
int sz = 20;
void setup() 
{
  size(sz*frameX, sz*frameY);
  String portName = Serial.list()[5];
  port = new Serial(this, portName, 19200);

  frame = new int[512];
}

void draw()
{
}

void keyPressed() {
  if (keyCode == UP) {
    port.write('1');

    delay(100);

    // Expand array size to the number of bytes you expect
    byte[] inBuffer = new byte[256];
    while (port.available () > 255) {
      inBuffer = port.readBytes();
    }

    println(inBuffer);

    background(0);

    for ( int i = 0; i < 256; i++ )
    {
      // data seems to be in 0-63 range...
      float col = map(inBuffer[i], 0, 63, 0, 255);
      fill(col);
      rect((i % frameX * sz), (i / frameY * sz), sz, sz);

      //fill(255, 0, 0);
      //text(int(col), (i % frameX * sz) + sz, (i / frameY * sz) + sz);
    }
  }
}

for posterity, the whole code

Minus the equally important bit at the other end of the serial link.

OKAY I figured it out. It was mainly the “write” command that got things going, thanks all. THEN, I re-checked the datasheet and found out that the chip needed at least 100ms to put the data into a buffer before being asked to write it via serial.

Fixed code:

/*******************************/
/* OptiMouse, Benoît ROUSSEAU  */
/* - dialoguer avec un ADS2051 */
/* récupérer sur une souris    */
/* optique                     */
/*******************************/

#define PIN_CLOCK 2
#define PIN_DATA 3
#define _BV(bit) (1 << (bit))

byte readRegister (byte adresse)
{
  int i = 7;
  byte retour = 0;
  
  pinMode (PIN_DATA, OUTPUT);
  for (; i>=0; i--)
  {

     digitalWrite (PIN_CLOCK, LOW);
     digitalWrite (PIN_DATA, adresse & (1 << i));
     digitalWrite (PIN_CLOCK, HIGH);
  }
  
  pinMode (PIN_DATA, INPUT);
  delayMicroseconds(100);
 
  for (i=7; i>=0; i--)
  {
    digitalWrite (PIN_CLOCK, LOW);
    digitalWrite (PIN_CLOCK, HIGH);
    retour |= (digitalRead (PIN_DATA) << i);
  }
  delayMicroseconds(100);
  
  return retour;
}

void writeRegister (byte adresse, byte donnee)
{
  int i = 7;
  
  adresse |= 0x80;
  
  pinMode (PIN_DATA, OUTPUT);
  for (; i>=0; i--)
  {

     digitalWrite (PIN_CLOCK, LOW);
     digitalWrite (PIN_DATA, adresse & (1 << i));
     digitalWrite (PIN_CLOCK, HIGH);
  }
 
  for (i=7; i>=0; i--)
  {
    digitalWrite (PIN_CLOCK, LOW);
     digitalWrite (PIN_DATA, donnee & (1 << i));
     digitalWrite (PIN_CLOCK, HIGH);
  }

}

void sendImage()
{
  byte val;
  byte adr;
  //Serial.print (">IMG:");
  
  writeRegister (0x0a, 0x09);
  
  delay(110);
  
  for (int i=0; i<256; i++)
  {
    do {
      adr = readRegister (0x0d);
      val = readRegister (0x0c);
    } while (val & 0x80);
//    Serial.print (adr, HEX);
//    Serial.print ('>', BYTE);
    Serial.write (val);
//    Serial.print (13, BYTE);
  } 
  
  //Serial.println ();
  writeRegister (0x0a, 0x00);
}

void setup()
{
  pinMode (PIN_CLOCK, OUTPUT);
  pinMode (PIN_DATA, INPUT);
  Serial.begin(19200);
}

void loop ()
{
  // this stuff only matters for the mouse moving
  /*
  if (readRegister (0x02))
  {
    Serial.print ('>');
    Serial.print (readRegister (0x00), DEC);
    Serial.print ('-');
    Serial.print (readRegister (0x01), DEC);
    Serial.print ('-');
    Serial.print (readRegister (0x03), DEC);
    Serial.print ('-');
    Serial.print (readRegister (0x04), DEC);
    Serial.println ();
  }
  */
  if (Serial.available())
  {
    Serial.read();
    sendImage();
  }
}