Structure of arrays.

Hello all.

//Protocol global variables.
byte pelcoD[7] = {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //Synch Byte, Address, Command 1, Command 2, Data 1, Data 2, Checksum.
byte pelcoP[8] = {0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x00}; //STX, Address, Data 1, Data 2, Data 3, Data 4, ETX, Checksum.

I am creating a sketch to control dome cameras with Pelco telemetry of P & D types and the code above is how i am creating my data packets for each protocol. Is it possible to place byte pelcoD and pelcoP into the same structure even tho the arrays are of different sizes? And if so how would i write it?

Thanks.

This code below is far from complete but it's my start on trying to create a multi protocol controller.

/*------------------------------------------------------------
Created by - Andrew Hughes
------------------------------------------------------------*/
//Define pin names.
#define pin_joystickButton 2 //Joystick button connected to this pin.
#define pin_xAxis A0 //Joystick connected to this pin, pan.
#define pin_yAxis A1 //Joystick connected to this pin, tilt.
#define pin_zAxis A2 //Joystick connected to this pin, twist.

//Joystick global variables.
byte joystickButton = 1; //Button on top of the joystick to be used for switching between zoom & focus.
unsigned int xyzAxis;
unsigned int xCenter;
unsigned int yCenter;
unsigned int zCenter;
unsigned int xAxisMin; //Pan rigt.
unsigned int xAxisMax; //Pan left.
unsigned int yAxisMin; //Tilt up.
unsigned int yAxisMax; //Tilt down.
unsigned int zAxisMin; //Anitclockwise.
unsigned int zAxisMax; //Clockwise.
unsigned int threshold; //Used for increasing the center area(dead zone).

byte joystickValues[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //Pan right, pan left, tilt up, tilt down, zoom in, zoom out, focus far, focus near, iris open, iris close.

//Protocol global variables.
byte pelcoD[7] = {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //Synch Byte, Address, Command 1, Command 2, Data 1, Data 2, Checksum.
byte pelcoP[8] = {0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x00}; //STX, Address, Data 1, Data 2, Data 3, Data 4, ETX, Checksum.

//Other global variables.
byte address = 0x01; //Stores address selection number from a switch. To be impilmented.
byte newControl; //Used to determin control state. 
byte oldControl; //Used to determin control state.

void setup() {
  //Initialise the hardware serial port.
  Serial.begin(9600);
  while (!Serial)
  {
    ; // Wait for serial port to connect. Needed for Leonardo only.
  }
  joystickCalabration();
}

void loop() {
  //joystickButton = digitalRead(pin_joystickButton); //Not connected yet.
  
  xyzAxis = analogRead(pin_xAxis);
  //Pan right.
  threshold = xCenter - 25;
  if(xyzAxis < threshold) {
    xyzAxis = map(xyzAxis, threshold, xAxisMin, 1, 8);
    Serial.print(F("PR"));
    Serial.println(xyzAxis);
    joystickValues[0] = xyzAxis;
  }
  else {
    joystickValues[0] = 0; //Clears the last stored value.
  }
  //Pan left.
  threshold = xCenter + 25;
  if(xyzAxis > threshold) {
    xyzAxis = map(xyzAxis, threshold, xAxisMax, 1, 8);
    Serial.print(F("PL"));
    Serial.println(xyzAxis);
    joystickValues[1] = xyzAxis;
  }
  else {
    joystickValues[1] = 0; //Clears the last stored value.
  }
  xyzAxis = analogRead(pin_yAxis);
  //Tilt up.
  threshold = yCenter - 25;
  if(xyzAxis < threshold) {
    xyzAxis = map(xyzAxis, threshold, yAxisMin, 1, 8);
    Serial.print(F("TU"));
    Serial.println(xyzAxis);
    joystickValues[2] = xyzAxis;
  }
  else {
    joystickValues[2] = 0; //Clears the last stored value.
  }
  //Tilt down.
  threshold = yCenter + 25;
  if(xyzAxis > threshold) {
    xyzAxis = map(xyzAxis, threshold, yAxisMax, 1, 8);
    Serial.print(F("TD"));
    Serial.println(xyzAxis);
    joystickValues[3] = xyzAxis;
  }
  else {
    joystickValues[3] = 0; //Clears the last stored value.
  }
  xyzAxis = analogRead(pin_zAxis);
  //Anticlockwise.
  threshold = zCenter - 25;
  if(xyzAxis < threshold) {
    xyzAxis = map(xyzAxis, threshold, zAxisMin, 1, 8);
    if(joystickButton == 1) {
      joystickValues[4] = 1; //Zoom mode.
      Serial.print(F("ZI"));
      Serial.println(1);
    }
    else if(joystickButton == 2){
      joystickValues[6] = 1; //Focus mode.
      Serial.print(F("FF"));
      Serial.println(1);
    }
    else if(joystickButton == 3){
      joystickValues[8] = 1; //Iris mode.
      Serial.print(F("IO"));
      Serial.println(1);
    }
  }
  else {
    joystickValues[4] = 0; //Clears the last stored value.
    joystickValues[6] = 0; //Clears the last stored value.
    joystickValues[8] = 0; //Clears the last stored value.
  }
  //Clockwise.
  threshold = yCenter + 25;
  if(xyzAxis > threshold) {
    xyzAxis = map(xyzAxis, threshold, zAxisMax, 1, 8);
    if(joystickButton == 1) {
      joystickValues[5] = 1; //Zoom mode.
      Serial.print(F("ZO"));
      Serial.println(1);
    }
    else if(joystickButton == 2){
      joystickValues[7] = 1; //Focus mode.
      Serial.print(F("FN"));
      Serial.println(1);
    }
  }
  else if(joystickButton == 3){
      joystickValues[9] = 1; //Iris mode.
      Serial.print(F("IC"));
      Serial.println(1);
    }
  else {
    joystickValues[5] = 0; //Clears the last stored value.
    joystickValues[7] = 0; //Clears the last stored value.
    joystickValues[9] = 0; //Clears the last stored value.
  }
  delay(1000);
  protocol_pelcoD();
}

// Reads the min, max and center values of the joystick.
void joystickCalabration() {
  delay(3000);
  Serial.println(F("Calabrate Joystick"));
  Serial.print(F("Pan Right      "));
  delay(3000);
  xAxisMin = analogRead(pin_xAxis);
  Serial.println(xAxisMin);
  Serial.print(F("Pan Left       "));
  delay(3000);
  xAxisMax = analogRead(pin_xAxis);
  Serial.println(xAxisMax);
  Serial.print(F("Tilt Up        "));
  delay(3000);
  yAxisMin = analogRead(pin_yAxis);
  Serial.println(yAxisMin);
  Serial.print(F("Tilt Down      "));
  delay(3000);
  yAxisMax = analogRead(pin_yAxis);
  Serial.println(yAxisMax);
  Serial.print(F("Anticlockwise  "));
  delay(3000);
  zAxisMin = analogRead(pin_zAxis);
  Serial.println(zAxisMin);
  Serial.print(F("Clockwise      "));
  delay(3000);
  zAxisMax = analogRead(pin_zAxis);
  Serial.println(zAxisMax);
  Serial.println(F(".Release Joystick."));
  delay(3000);
  Serial.print(F("xCenter        "));
  xCenter = analogRead(pin_xAxis);
  Serial.println(xCenter);
  Serial.print(F("yCenter        "));
  yCenter = analogRead(pin_yAxis);
  Serial.println(yCenter);
  Serial.print(F("zCenter        "));
  zCenter = analogRead(pin_zAxis);
  Serial.println(zCenter);
  Serial.println(F("Calabrate Complete"));
}
void protocol_pelcoP() {
  byte i;
  
  newControl = 0;
  pelcoP[1] = address;
  
  for(i = 0; i <= 9; i++) {
    newControl += joystickValues[i];
  }
  
  if(newControl != oldControl) {
    //Pan.
    if(joystickValues[0] > 0) {
      bitWrite(pelcoP[3], 1, 1); //Sets pan right on.
      pelcoP[4] = map(joystickValues[0], 1, 8, 0x01, 0x3F);
    }
    else if(bitRead(pelcoP[3], 1) == 1) {
      bitWrite(pelcoP[3], 1, 0); //Sets pan right off.
    }
    if(joystickValues[1] > 0) {
      bitWrite(pelcoP[3], 2, 1); //Sets pan left on.
      pelcoP[4] = map(joystickValues[1], 1, 8, 0x01, 0x3F);
    }
    else if(bitRead(pelcoP[3], 2) == 1) {
      bitWrite(pelcoP[3], 2, 0); //Sets pan left off.
    }
    if(!joystickValues[0] && !joystickValues[1]) {
      pelcoP[4] = 0x00; //Sets pan speed to 0.
    }
    //Tilt.
    if(joystickValues[2] > 0) {
      bitWrite(pelcoP[3], 3, 1); //Sets tilt up on.
      pelcoP[5] = map(joystickValues[2], 1, 8, 0x01, 0x3F);
    }
    else if(bitRead(pelcoP[3], 3) == 1) {
    bitWrite(pelcoP[3], 3, 0); //Sets tilt up off.
    }
    if(joystickValues[3] > 0) {
      bitWrite(pelcoP[3], 4, 1); //Sets tilt down on.
      pelcoP[5] = map(joystickValues[3], 1, 8, 0x01, 0x3F);
    }
    else if(bitRead(pelcoP[3], 4) == 1) {
      bitWrite(pelcoP[3], 4, 0); //Sets tilt up off.
    }
    if(!joystickValues[2] && !joystickValues[3]) {
      pelcoP[5] = 0x00; //Sets tilt speed to 0.
    }
    //Twist (zoom, focus & iris).
    if(joystickButton == 1) {
      if(joystickValues[4] > 0) {
        bitWrite(pelcoP[3], 5, 1); //Sets zoom in on.
      }
      else if(bitRead(pelcoP[3], 5) == 1) {
        bitWrite(pelcoP[3], 5, 0); //Sets zoom in off.
      }
      if(joystickValues[5] > 0) {
        bitWrite(pelcoP[3], 6, 1); //Sets zoom out on.
      }
      else if(bitRead(pelcoP[3], 6) == 1) {
        bitWrite(pelcoP[3], 6, 0); //Sets zoom out off.
      }
    }
    else if(joystickButton == 2){
      if(joystickValues[6] > 0) {
        bitWrite(pelcoP[2], 0, 1); //Sets focus far on.
      }
      else if(bitRead(pelcoP[2], 0) == 1) {
        bitWrite(pelcoP[2], 0, 0); //Sets focus far off.
      }
      if(joystickValues[7] > 0) {
        bitWrite(pelcoP[2], 1, 1); //Sets focus far on.
      }
      else if(bitRead(pelcoP[2], 1) == 1) {
        bitWrite(pelcoP[2], 1, 0); //Sets focus far off.
      }
    }
    else if(joystickButton == 3){
      if(joystickValues[6] > 0) {
        bitWrite(pelcoP[2], 2, 1); //Sets iris open on.
      }
      else if(bitRead(pelcoP[2], 0) == 1) {
        bitWrite(pelcoP[2], 2, 0); //Sets iris open off.
      }
      if(joystickValues[7] > 0) {
        bitWrite(pelcoP[2], 3, 1); //Sets iris close on.
      }
      else if(bitRead(pelcoP[2], 1) == 1) {
        bitWrite(pelcoP[2], 3, 0); //Sets iris close off.
      }
    }
    
    //Checksum calculation XOR (Last byte is not inculed).
    pelcoP[7] = 0x00; //Clears last calculated checksum byte.
    pelcoP[7] = (pelcoP[0] ^ pelcoP[1] ^ pelcoP[2] ^ pelcoP[3] ^ pelcoP[4] ^ pelcoP[5] ^ pelcoP[6]); //Checksum Calculation.
  
    //Transmit the data out.
    for(i = 0; i <= 7; i++) {
      Serial.print(pelcoD[i], HEX);
      Serial. print(" ");
    }
    oldControl = newControl;
  }
  else {
    oldControl = newControl;
    return;
  }
}

void protocol_pelcoD() {
  byte i;
  
  newControl = 0;
  pelcoD[1] = address;
  
  for(i = 0; i <= 9; i++) {
    newControl += joystickValues[i];
  }
  
  if(newControl != oldControl) {
    //Pan.
    if(joystickValues[0] > 0) {
      bitWrite(pelcoD[3], 1, 1); //Sets pan right on.
      pelcoD[4] = map(joystickValues[0], 1, 8, 0x01, 0x3F);
    }
    else if(bitRead(pelcoD[3], 1) == 1) {
      bitWrite(pelcoD[3], 1, 0); //Sets pan right off.
    }
    if(joystickValues[1] > 0) {
      bitWrite(pelcoD[3], 2, 1); //Sets pan left on.
      pelcoD[4] = map(joystickValues[1], 1, 8, 0x01, 0x3F);
    }
    else if(bitRead(pelcoD[3], 2) == 1) {
      bitWrite(pelcoD[3], 2, 0); //Sets pan left off.
    }
    if(!joystickValues[0] && !joystickValues[1]) {
      pelcoD[4] = 0x00; //Sets pan speed to 0.
    }
    //Tilt.
    if(joystickValues[2] > 0) {
      bitWrite(pelcoD[3], 3, 1); //Sets tilt up on.
      pelcoD[5] = map(joystickValues[2], 1, 8, 0x01, 0x3F);
    }
    else if(bitRead(pelcoD[3], 3) == 1) {
    bitWrite(pelcoD[3], 3, 0); //Sets tilt up off.
    }
    if(joystickValues[3] > 0) {
      bitWrite(pelcoD[3], 4, 1); //Sets tilt down on.
      pelcoD[5] = map(joystickValues[3], 1, 8, 0x01, 0x3F);
    }
    else if(bitRead(pelcoD[3], 4) == 1) {
      bitWrite(pelcoD[3], 4, 0); //Sets tilt up off.
    }
    if(!joystickValues[2] && !joystickValues[3]) {
      pelcoD[5] = 0x00; //Sets tilt speed to 0.
    }
    //Twist (zoom, focus & iris).
    if(joystickButton == 1) {
      if(joystickValues[4] > 0) {
        bitWrite(pelcoD[3], 5, 1); //Sets zoom in on.
      }
      else if(bitRead(pelcoD[3], 5) == 1) {
        bitWrite(pelcoD[3], 5, 0); //Sets zoom in off.
      }
      if(joystickValues[5] > 0) {
        bitWrite(pelcoD[3], 6, 1); //Sets zoom out on.
      }
      else if(bitRead(pelcoD[3], 6) == 1) {
        bitWrite(pelcoD[3], 6, 0); //Sets zoom out off.
      }
    }
    else if(joystickButton == 2){
      if(joystickValues[6] > 0) {
        bitWrite(pelcoD[3], 7, 1); //Sets focus far on.
      }
      else if(bitRead(pelcoD[3], 7) == 1) {
        bitWrite(pelcoD[3], 7, 0); //Sets focus far off.
      }
      if(joystickValues[7] > 0) {
        bitWrite(pelcoD[2], 0, 1); //Sets focus far on.
      }
      else if(bitRead(pelcoD[2], 0) == 1) {
        bitWrite(pelcoD[2], 0, 0); //Sets focus far off.
      }
    }
    else if(joystickButton == 3){
      if(joystickValues[8] > 0) {
        bitWrite(pelcoD[2], 1, 1); //Sets iris open on.
      }
      else if(bitRead(pelcoD[2], 1) == 1) {
        bitWrite(pelcoD[2], 1, 0); //Sets iris open off.
      }
      if(joystickValues[9] > 0) {
        bitWrite(pelcoD[2], 2, 1); //Sets iris close on.
      }
      else if(bitRead(pelcoD[2], 2) == 1) {
        bitWrite(pelcoD[2], 2, 0); //Sets iris close off.
      }
    }
    
    //Checksum calculation modulo 256 (first byte and last byte is not inculed).
    pelcoD[6] = 0x00; //Clears last calculated checksum byte.
    pelcoD[6] = (pelcoD[1] + pelcoD[2] + pelcoD[3] + pelcoD[4] + pelcoD[5]); //Checksum calculation.
  
    //Transmit the data out.
    for(i = 0; i <= 6; i++) {
      Serial.print(pelcoD[i], HEX);
      Serial. print(" ");
    }
    oldControl = newControl;
  }
  else {
    oldControl = newControl;
    return;
  }
}

I am not clear what you are trying to achieve, but you could combine both arrays into one with 15 elements if you wanted to. After all you know where each starts and ends, so you could reference them appropriately. Why the desire to combine them ?

Pavilion1984:
Is it possible to place byte pelcoD and pelcoP into the same structure even tho the arrays are of different sizes? And if so how would i write it?

The question doesn't make a lot of sense taking every word literally. Can you explain what you are trying to achieve? I'm certain it will be possible once we know what 'it' is.

Thanks for the replies. Hope this helps.

Am looking at using a rotary switch for a way of selecting each protocol and thought i need a way of indexing the protocol global variables. Switch position 1 = PelcoP & switch position 2 = PelcoD. (Will be adding more protocols in the future).

(read joystick -> read protocol switch -> update the selected protocol data packet according to the switch position -> transmit the data packet according to the switch position).

I was thinking maybe a structure would be ok for this.

If the arrays/packets are of similar size you can use a two-dimensional array where the second dimension is the size of the largest packet. It will waste a few bytes but unless there is a large difference in packet sizes that's usually not a big deal.

Otherwise have an array of pointers to the packet arrays.


Rob

You could use an array of 8 bytes, if the device which only uses 7 bytes will just ignore the last byte which it doesn't need.

Pavilion1984:
Thanks for the replies. Hope this helps.

Am looking at using a rotary switch for a way of selecting each protocol and thought i need a way of indexing the protocol global variables. Switch position 1 = PelcoP & switch position 2 = PelcoD. (Will be adding more protocols in the future).

(read joystick -> read protocol switch -> update the selected protocol data packet according to the switch position -> transmit the data packet according to the switch position).

I was thinking maybe a structure would be ok for this.

If you don't fancy a 2 dimensional array then use a 1 dimensional array to hold the protocols in series and a second one to hold the starting positions of the protocols in the array. Once thing that would help either way would be to have 'end of protocol' markers in the protocol array so that you can read the bytes out and know when to stop reading when you encounter the marker.

Hi Pavilion84,

How did you get on with this project?

I have stubbled across arduino as a way to solve a similar but less difficult problem to yours.

I would like to send a specific set of commands in Pelco D to move a camera.

Other than blinking the pin13 on my newly purchased uno board I have no experience!!!

If you can help with the basic structure of how to code this I would be very grateful.

What hardware are you using to control your dome. Max485 chip?