stream functions

Hopeless newbie question. I have defined a 5-character array: volatile char command[5]={0,0,0,0,0}; How in heck do I fill the array using : Serial.readBytes(command,5); I get errors if I use command[], command[0], etc. Obviously there is some arcane rule(s) about how to specify the first argument, probably something stupid I'm doing. Seems to me this oughta be REALLY SIMPLE, which probably means it is going to be abstruse, calling for insight into the occult. :P Thanks for the help. Don the bewildered

Post your code and the errors you're getting

Here’s the code:

#include <Streaming.h>
#include <Button.h>
//string output handling eg Serial <<"stuff"<<var<<"more stuff"; etc.
//eases contact sensing
//Antenna drive controller 
//
//*********************Set up all pins************************************
//
const int azA = 2; //az and el encodeers. will use interrupt service
const int azB = 4; //routines and counters to service.
const int elA = 3;
const int elB = 5;
const int azDir = 7;  //azimuth motor direction
const int azSpd = 9;  //azimuth speed pwm pin 255 max
const int elDir = 8;  //elevation motor direction
const int elSpd = 10; //elevation speed pwm pin 255 max
//*************variables for pad drive*********************
//
volatile byte padBits = 0;
int spdPotPin= 6;
byte nowSpd = 0;
int spdPot = 0;
//
//***************encoder variables******************
//****assumes az and el at home on reset!!!*********
//
const int encTicks = 8192; // total number of encoder ticks
volatile int azCount = 4096; //returned from interrupt.
volatile int elCount = 2048; //Don't mess with these.
//Make sure to use pads to put ant at az=180 and el-90
//before a reset or do a double reset.
volatile int azTarget = 4096;//where to go
volatile int elTarget = 2048;//where to go 
//
//**************interrupt service routines*****
  //!!!!!!CONTINUOUS UPDATE!!!!!!!!!!!
  //there are no critical timing needs in the program
  void azInt() //interrupt 0 attach in setup
  {
    if (digitalRead(azB)==HIGH) 
    {azCount = --azCount;}
    else 
    {azCount = ++azCount;}
  }
  void elInt() //interrupt1 attach in setup
  {
    if (digitalRead(elB)==HIGH)
    {elCount = ++elCount;}
    else
    {elCount = --elCount;}
  }

//****************PC interface variables*************
long serial_timeout = 3000;
int serial_timer = 0;
volatile char command[5]={0,0,0,0,0};
volatile char sendbuffer[5]={0,0,0,0,0};
//*****************Hard Limit definitions*******************
Button crash = Button(6,PULLUP); // if the inhibit switch is flipped
Button lim1 = Button (18,PULLUP);//AZ CCW
Button lim2 = Button (19, PULLUP);// AZ CW
Button lim3 = Button (11, PULLUP);//EL low limit 20 deg
Button lim4 = Button (12, PULLUP);//EL hi limit 160 deg
//hard limit tripped is in a sub
//
//***************Setup**************************************
//
void setup()
{
  Serial.begin(19200);
  Serial.flush();
  //
  //***initialize the drive pins for KBWD interface***
  //
  pinMode (azDir,OUTPUT);
  pinMode (azSpd,OUTPUT);
  pinMode (elDir,OUTPUT);
  pinMode (elSpd,OUTPUT);
  digitalWrite (azDir,LOW);
  digitalWrite (azSpd,LOW);
  digitalWrite (elDir,LOW);
  digitalWrite (elSpd,LOW);
//
//****encoder ports, LS7184 glue interfaces ****
//
  pinMode (azA,INPUT);
  pinMode (azB,INPUT);
  pinMode (elA,INPUT);
  pinMode (elB,INPUT);
  attachInterrupt(0,azInt,FALLING);
  attachInterrupt(1,elInt,FALLING);
  nowSpd = (analogRead(spdPotPin))/4; //default to start
}
//
//***************  get 'er done   ******************
//
void loop()
{ 
  //
  //!!!!!!!!!ALWAYS test for a HardLimit!!!!!!!!!!!
   if (hardLim>0) stopAll();  
  //do handpad moves.
    padBits = PINC & B00001111;// pad connected to analog ports
    if (!padBits) stopAll;
    else parsePad(padBits);
 //
 //************************end of handpad move*******************
 //
 //***************************REMOTE CONTROL*********************
  //otherwise obey pc commands
  if(Serial.available() > 0) getCommand();
  if(command[0] > 0) doCommand();
} // <<*********END of LOOP***********************
//
//************what is the pad command?*********
//  
void parsePad(byte inBits)
{
  switch (inBits)
  {
    case 3: nowSpd = nowSpd-10; //Top left switch    
    break;
    case 12: nowSpd = nowSpd + 10; //top right
    break;
    case 8: //UP increasing el angle
          digitalWrite(elDir, LOW);
          analogWrite (elSpd,nowSpd);
    break;
    case 4: //DN decreasing el angle
          digitalWrite(elDir, HIGH);
          analogWrite (elSpd,nowSpd);
    break;
    case 1: //CW switch, decreasing az
          digitalWrite(azDir,LOW);
          analogWrite(azSpd, nowSpd);
    break;
    case 2: //CCW switch, increase az
          digitalWrite(azDir,HIGH);
          analogWrite(azSpd, nowSpd);
    break;
    case 14: nowSpd = (analogRead(spdPotPin))/4;
    break;
    case 6: //spare switch
    break;
    //default: if needed
  }
  return;
}
//
//****************STOP EVERYTHING*******************
//
void stopAll()// provides a hard instant stop
// resets drivers. Also reached with the inhibit crash
{
  digitalWrite(azDir,LOW);
  digitalWrite(azSpd,LOW);
  digitalWrite(elDir,LOW);
  digitalWrite(elSpd,LOW);
  return;
}
//
//***************** CHECK FOR HARD LIMIT *****************
//
byte hardLim()
{
    byte result = 0;
    if(crash.isPressed())result = 1; //1 = stop panel switch
    if(lim1.isPressed()) result = 2;  //2 = CCW
    if(lim2.isPressed()) result = 3;  //3 = CW
    if(lim3.isPressed()) result = 4;  //4 = LOW
    if(lim4.isPressed()) result = 5;  //5 = HIGH
//report the limit switch here!
    return result;
}
//
// ***************return data to PC******************
//
void sendBuffer() //if we need it.
{
  Serial.write((unsigned char *)sendbuffer,5); 
  // cleanup for the next command
  cleanup(); 
}
//
//********************Command loop*********************
//
void getCommand()
{ 
  byte received_bytecount = 0;
  Serial.setTimeout(serial_timeout);//set timeout
  received_bytecount = Serial.readBytes(command,5);
  return;
}
//
//****************************carry out the command************
//command and param have arrived
void doCommand()
{
  switch(command[0]) //execute the command
  {
  case 2: stopAll();break;
  case 3: sendAz();break;
  case 4: sendEl();break;
  case 5: movetoAz();break;
  case 6: movetoEl();break;
  }
  return;
}
//
//*****************************************************
//
void cleanup()
{
  command[0]=command[1]=command[2]=command[3]=command[4]=0;
  Serial.flush();
  return;
}
//
//*******************************************************
//
void sendAz() //3,B,b,AZ
{
  byte BazCount= highByte(azCount);
  byte LazCount= lowByte(azCount);
  Serial<<"3"<<BazCount<<LazCount<<"AZ";
  return;
}
//*******************************************************
void sendEl() //4,B,b,EL
{
  byte BelCount = highByte(elCount);
  byte LelCount = lowByte(elCount);
  Serial<<"4"<<BelCount<<LelCount<<"EL";
  return;
}
//********************************************************
void movetoAz()  //5,B,b,AZ
{
  int band = 5;  // for now, a fuzzy for mechanical slop
  byte movto = 0;
  azTarget = (command[2]*256)+command[3];  //target value 
  int azDif = azCount - azTarget; //if positive, move CCW
  if (azDif > 0) movto = 2;
  else movto = 1; // CW
// now do the az move. may be asked for updates
  while (abs(azDif) > band)  //note azCount by interrupt, whee
  {
    nowSpd = (analogRead(spdPotPin))/4; //might want to change
    parsePad(movto);             //here we go
    azDif = azCount - azTarget;  //get error
    if (hardLim()>0) azDif = 0; //always check, while over
    if(Serial.available() > 0) getCommand();
    if(command[0] == 3) 
     { sendAz();
       cleanup(); }
  }
  stopAll(); // insure stop
  cleanup(); //just in case!
  return;
}
//*******************************************************
void movetoEl() //6,B,b,EL
{
  byte movto = 0;
  int band = 5;
  elTarget = (command[2]*256)+command[3]; //target value
  int elDif = elCount - elTarget;  //if positive, move DN
   if (elDif > 0) movto = 4;//DN
  else movto = 8; // UP
// now do the el move. may be asked for updates
  while (abs(elDif) > band)  //note elCount by interrupt, whee
  {
    nowSpd = (analogRead(spdPotPin))/4; //might want to change
    parsePad(movto);             //here we go
    elDif = elCount - elTarget;  //get error
    if (hardLim() > 0) elDif = 0;  //end while
    if(Serial.available() > 0) getCommand();
    if(command[0] == 4) 
     { sendEl();
       cleanup(); }
  }
  stopAll();  //move is done!
  cleanup(); //just in case!
  return;
}
//******************************************************

The error message:
driver1.cpp: In function ‘void getCommand()’:
driver1.pde:-1: error: invalid conversion from ‘volatile char*’ to ‘char*’
driver1.pde:-1: error: initializing argument 1 of ‘size_t Stream::readBytes(char*, size_t)’

if I put (volatile command,5) in the argument, I get:
driver1.cpp: In function ‘void getCommand()’:
driver1.pde:-1: error: expected primary-expression before ‘volatile’

I obvoiusly don’t know what I’m doing.
the instructions simply say to use a buffer.
Thanks
Don

What version of the IDE are you using? Up to 22, there is no Serial.readBytes() method. With 1.0, the extension changes to ino, instead of pde.

Hi Paul: I'm using 1.0, just installed. The 0023 did not recognize String.readBytes at all. I did update buttons and streaming4 to Arduino.h according to the clues in a previous post. I'm sure I'm having some kind of syntax problem involving the specs of the buffer[] to put the serial in. I'm also not sure what happens if there is a timeout before 5 bytes are read from the serial stream, but one thing at a time... Don

driver1.pde:-1: error: invalid conversion from 'volatile char*' to 'char*'

is correct. The Serial.readBytes() function expects the first argument to be of type char *. The argument you are supplying is:

volatile char command[5]={0,0,0,0,0};

which is not of type char *. It is of type volatile char *. You might get away with casting the argument to the correct type:

int n = Serial.readBytes = ((char *)command, 5);

Well, folks, I found it, I think. I needed (char *) in Serial.readBytes((char *) command,5); BUT I'M DARNED IF I KNOW WHY!!!!!!!! Don

BUT I’M DARNED IF I KNOW WHY!

Go back and read reply #5.

Thanks, Paul. our posts crossed. I'm not very used to strong typing... Don

Hilarious. The Serial.write statement demands: Serial.write((unsigned byte *) sendbuffer,5); and gives an error if I leave out the unsigned part. OTH, .readByte gives an error if I use (unsigned byte *) and works with (byte *) But the definitions of the arrays are identical! Go figure... Am I right that the * refers to the address of the buffer rather than the content? I may be getting the hang of it... Don

But the definitions of the arrays are identical!

From Stream.h:

  int readBytes( char *buffer, size_t length); // read chars from stream into buffer

From Print.h:

   virtual size_t write(const uint8_t *buffer, size_t size);

Go figure...

I did. The functions are not identical.

No, I meant the definitions of the arrays in my program: volatile char command[5]={0,0,0,0,0}; volatile char sendbuffer[5]={0,0,0,0,0};

but, as you point out, the functions are not. wise are the ways of the developer... XD

thanks. Don