Camera Lens Functions accessing with Arduino

I have this one lens >> http://www.verrents.com/products/cameras/cine-accessories/hd-lenses/wide/ha13x45berm-m48.htm and it has a RS232 port which im going to use with a cable and serial to ttl converter like this >> Mini MAX3232 RS232 Shield - emartee.com.

The point is that i want to write to the RS232 port of this lens using the Arduino

i have previously successfully used the following code with a Canon LANC control and its working smooth

#define cmdPin 14 
#define lancPin 15
//#define recButton 2
int cmdRepeatCount;
int bitDuration = 104; //Duration of one LANC bit in microseconds. 

void setup() {
Serial.begin(9600);
pinMode(lancPin, INPUT); //listens to the LANC line
pinMode(cmdPin, OUTPUT); //writes to the LANC line
//pinMode(recButton, INPUT); //start-stop recording button
//digitalWrite(recButton, HIGH); //turn on an internal pull up resistor
digitalWrite(cmdPin, HIGH); //set LANC line to +5V
delay(5000); //Wait for camera to power up completly
digitalWrite(cmdPin, LOW);
bitDuration = bitDuration - 8; //Writing to the digital port takes about 8 microseconds so only 96 microseconds are left till the end of each bit
}

void loop() {
if (Serial.available() > 0) {
    char cmd = Serial.read();
    if (cmd == 'a') {
      Serial.print("called REC");
    REC(); //send REC command to camera
    }
  }
}



void REC() {

cmdRepeatCount = 0;

while (cmdRepeatCount < 5) {  //repeat 5 times to make sure the camera accepts the command

                while (pulseIn(lancPin, HIGH) < 5000) {   
                  //"pulseIn, HIGH" catches any 0V TO +5V TRANSITION and waits until the LANC line goes back to 0V 
                  //"pulseIn" also returns the pulse duration so we can check if the previous +5V duration was long enough (>5ms) to be the pause before a new 8 byte data packet
//Loop till pulse duration is >5ms
}

//LOW after long pause means the START bit of Byte 0 is here
delayMicroseconds(bitDuration);  //wait START bit duration

//Write the 8 bits of byte 0 
//"18hex" or “00011000”  tells the camera that there will be a normal command to camera in the next byte
//Note that the command bits have to be put out in reverse order with the least significant, right-most bit (bit 0) first
digitalWrite(cmdPin, 0);  //Write bit 0. 
delayMicroseconds(bitDuration); 
digitalWrite(cmdPin, 0);  //Write bit 1 
delayMicroseconds(bitDuration);  
digitalWrite(cmdPin, 0);  //Write bit 2
delayMicroseconds(bitDuration); 
digitalWrite(cmdPin, 1);  //Write bit 3
delayMicroseconds(bitDuration);  
digitalWrite(cmdPin, 0);  //Write bit 4
delayMicroseconds(bitDuration);
digitalWrite(cmdPin, 1);  //Write bit 5 
delayMicroseconds(bitDuration);
digitalWrite(cmdPin, 0);  //Write bit 6
delayMicroseconds(bitDuration); 
digitalWrite(cmdPin, 0);  //Write bit 7
delayMicroseconds(bitDuration);
//Byte 0 is written now put LANC line back to +5V
digitalWrite(cmdPin, LOW);
delayMicroseconds(10); //make sure to be in the stop bit before byte 1

while (digitalRead(lancPin)) { 
//Loop as long as the LANC line is +5V during the stop bit
}

//0V after the previous stop bit means the START bit of Byte 1 is here
delayMicroseconds(bitDuration);  //wait START bit duration

//Write the 8 bits of Byte 1
//"33hex" or “00110011” sends the  Record Start/Stop command
//Note that the command bits have to be put out in reverse order with the least significant, right-most bit (bit 0) first
digitalWrite(cmdPin, 0);  //Write bit 0 
delayMicroseconds(bitDuration);
digitalWrite(cmdPin, 0);  //Write bit 1 
delayMicroseconds(bitDuration); 
digitalWrite(cmdPin, 1);  //Write bit 2
delayMicroseconds(bitDuration); 
digitalWrite(cmdPin, 0);  //Write bit 3
delayMicroseconds(bitDuration);
digitalWrite(cmdPin, 0);  //Write bit 4 
delayMicroseconds(bitDuration); 
digitalWrite(cmdPin, 0);  //Write bit 5
delayMicroseconds(bitDuration);
digitalWrite(cmdPin, 0);  //Write bit 6
delayMicroseconds(bitDuration);
digitalWrite(cmdPin, 0);  //Write bit 7
delayMicroseconds(bitDuration);
//Byte 1 is written now put LANC line back to +5V
digitalWrite(cmdPin, LOW);

cmdRepeatCount++;  //increase repeat count by 1

/*Control bytes 0 and 1 are written, now don’t care what happens in Bytes 2 to 7
and just wait for the next start bit after a long pause to send the first two command bytes again.*/


}//While cmdRepeatCount < 5
}

SO as such IM mainly looking for a solution that works by modifying this already written code because i think the hex values are there and their corresponding binaries have to written in the same way.

Anyone?!

NI$HANT:
Anyone?!

Since you haven't asked any questions, all I can say is: good idea, go for it.

@ PeterH thanks for coming , actually

im looking for a solution that works by modifying this already written code because i think the hex values are there and their corresponding binaries have to written in the same way.

I mean how to go about that? and since its a RS232 connection i think this code will not work now and it needs Serial commands like printing the HEX codes directly in Serial.println statements to send them over to the camera lens? am i correct or im loosing something?

Anything you do over the serial port will be completely separate from the existing LANC stuff. You would need a TTL-to-RS232 level converter, connect it via hardware serial or soft serial, and write access functions to send (and receive if necessary) the messages in that protocol. If it's a binary protocol (it probably is) then you would be writing binary bytes rather than ascii characters but you would do this via the Serial API, conceptually it's similar to printing character strings. I haven't looked at the protocol so I don't know how difficult it would be to write that, but it doesn't sounds as if it ought to be too complex.

If I were you, start with a clean new sketch for the serial lens control, get that hardware and software working as you intend, extract the software into a separate library (extract the LANC software into a separate library too) and then integrate them into your combined sketch that uses both functions (I assume that you intend to use them together).

Design the two libraries so that they can be used together (e.g. don't allow either of them to block for long enough to disrupt the other) but implement and test them separately before you try to integrate them.

If it's a binary protocol (it probably is) then you would be writing binary bytes rather than ascii characters

It uses HEX commands but eventually everything goes converted in binary and i do not think that this lens will be able to modulate hex into binary at the end i have to supply it commands in binary only? so i think i need to use the Hardware serial and simply utilise the Serial prints to print the stuff(BINARY values) over the serial to control the lens? Am i correct here? Am i going the correct way?

(I assume that you intend to use them together)

No Sir , i do not want to use them together i just listed that previous code of mine from another project of mine that has a camera that uses LANC so i thought that might help me get somewhat near.

You would need a TTL-to-RS232 level converter

Yes Sir, Im using the same stuff for it.

The only MAIN problem is the protocol functioning and i think you understand why im here all the other stuff is already doable or done by me in the previous projects but this one is different only in respect of the protocol and depends on cracking the protocol and puts stuff as such it functions.

so the main problem boils down to breaking the HEX into Binaries(which is easy) and then KNOWING the TIMING between the 8 Bit's that when one needs to be send and in what intervals .

simply utilise the Serial prints to print the stuff(BINARY values) over the serial to control the lens? Am i correct here?

You would need Serial.write(), not Serial.print().

You would need Serial.write(), not Serial.print().

I was talking about Serial.println , is it different from write? If yes then in what respect, please tell me?

Serial.print()/println() are for sending human readable ascii strings representing the value inside the parentheses, so Serial.print(27) sends the character '2' followed by the character '7'. Using Serial.println() would add the carriage-return/linefeed characters.

Serial.write is used for machine to machine communication, so no conversion is carried out. Serial.write(27) sends a byte with the value decimal 27 (or 0x1B, or 0b11011).

yes ok thanks

So in order to send the respective HEX values i need to do Serial.write(0x1b);

That would be fine. The following statements all send the same value.

Serial.write(27);
Serial.write(0x1b);
Serial.write(0b11011);

Im thinking further as i did LANC control too and that worked with some delay until the start and stop bits and also between individual bits as you can see in my programme in my first post on this topic.

so in case i need to give some respective delay as such this system will not work, but then i think there is a difference between LANC 2.5mm communicating port working and the RS232 communicating port working.

dxw00d:
That would be fine. The following statements all send the same value.

Serial.write(27);

Serial.write(0x1b);
Serial.write(0b11011);

NI$HANT:
So in order to send the respective HEX values i need to do Serial.write(0x1b);

If you were writing a string, and wanted a hex or octal value as one of the bytes, you could do:

Serial.write("abc" "\x1b" "def")
Serial.write("abc\033ef")

The \0 sequence takes 1-3 octal digits (0-7) to form a constant.

The \x sequence stops when it encounters a non-hex digit (0-9, a-f). Since I wanted to have 'd' after the \x1b, I used string pasting where adjacent strings are merged together by the compiler into long string.

NI$HANT:
It uses HEX commands but eventually everything goes converted in binary and i do not think that this lens will be able to modulate hex into binary at the end i have to supply it commands in binary only? so i think i need to use the Hardware serial and simply utilise the Serial prints to print the stuff(BINARY values) over the serial to control the lens? Am i correct here? Am i going the correct way?

Yes, you're on the right lines. But you may be at cross purposes talking about hex and binary and so on.

The RS232 protocol provides a sequence of octets transferred via a bit stream. You can choose to represent that octet as a decimal number, or a number in hex or in any other number base, or as an ASCII character, or any other type of character encoding you like. Presumably the protocol spec uses some convention for describing the format and content of messages passed over the link. But that is only a representation of the value. The value itself is still just eight bits and does not have any inherent 'type'. The recipient won't care how you put those bits on the wire as long as the bits it gets match what it expects as documented in the spec.

Given that the data link is RS232 in this case I will assume the baud rate and framing will be a standard setting so I don't see any point writing your own bit-wobbling code when you can just pass the byte values directly to the hardware serial or software serial devices.

(I'd have thought the same was true of the LANC protocol, although to be fair I haven't looked into that so maybe there is some reason why you can't produce it using the standard serial drivers.)

(I'd have thought the same was true of the LANC protocol, although to be fair I haven't looked into that so maybe there is some reason why you can't produce it using the standard serial drivers.)

THanks! for all that coming back and posting ,Healthy! :slight_smile:

I have understood all that you said very clearly and about LANC im going to say that it does not happens to be acting on simply supplying it the Binary in the form of HEX, Decimal or anything else because simply as you said it expects some bits only at some regular predefined intervals that is why the delay'Microsends is there in the programme , even between the 8 bit Octals a time lag is needed.

But i think as compared to LANC ,RS232 communication is very well defined and more of a standard communication method so you do not need to do that low level mods as you do with LANC.

Im going to read more today and implement the code finally and lets see with a basic RS232 link what happens!

Finally im configuring the RS232 module(Mini MAX3232 RS232 Shield - emartee.com) to link with the Arduino and camera in the respectively way.

HR10G-10R-10S Pin assignment
Pin Designation
1 OPEN
2 RxD (RD)
3 TxD (SD)
4 DTR (ER)
5 GND (SG)
6 DSR (DR)
7 RTS (RS)
8 CTS (CS)
9 OPEN
10 OPEN

the RS232 module whoes link is shown has RX /TX/RTS/CTS so the above pin designation goes like RxD to TxD of rs232 ,TxD to RxD of rs232 ,RTS to RTS and CTS to CTS , I think this configuration and linkage is fine, the remaining pin's untouched.

Though the standard way to connect the RS232 communication with the Arduino may work but i have read the following Information of controlling the lens also is utilising the DSR pin mainly so when its high then camera is on etc so this way it works THE FOLLOWING IS THE INSTRUCTION SET for the SAME:

  1. Specifications for communications-related operation
  1. A host computer for external control (hereinafter called "host") leads communications. The lens responds to
    a command received from the host. No commands can be sent from the lens first.
  2. After the power is turned ON, the lens confirms that DSR is ON and readies for communications. DSR must
    be continuously ON while connecting to the lens. DTR loops back DSR and RTS loops back CTS. Even when
    CTS is OFF the lens responds to a command from the host, if any.
  3. After the power is turned ON and a receiving error and/or other communications errors occur for the lens, the
    host sends a connecting request command having no data to the lens. The host then confirms that the lens
    has responded to the command and communicates with the lens in the normal manner. Data from the
    command block in which errors occurred for both host and lens is not used.
  4. On receiving the first connecting request command from the host after the power is turned ON, the lens is
    reset to cover the external control. During resetting, the lens returns a resetting response command having
    one piece of data (Data contents: 0) to the host computer. While the lens is in a resetting operation, the host
    sends a connecting request command to the lens repeatedly. The host confirms that the lens has been reset
    when the lens responds to the host computer by means of the command having no data. The host can force
    the lens to be reset by sending a reset request command having one piece of data (Data contents: 0) to the
    lens even during normal operations. However the lens without reset function responds by sending a
    command having data (data length: 0) when receiving a command having data (data length: 1).
  5. The host cannot send the next command to the lens until the lens responds to the host except if there is no
    response from the lens in 10 msec or more.
  6. The function code of the command the host sends to the lens is the same as that of the command the lens
    sends back to the host. On receiving a command from the host during resetting, the lens sends back a
    connecting response command having one piece of data to the host.
  7. When receiving an undefined command or a non-corresponding command from the host, the lens sends back
    ACKNOWLEDGE (same function code, data length: 0) to the host. In some cases the lens responds to a
    command not indicated in the Specifications.
  8. Both lens and host judge that there is an error if the data contains an error such as an overrun, framing or
    check sum or if the length of the command block differs from the data length designated in data length bytes
  1. The host judges that there is an error if the lens does not respond to the host within 10 msec after the host
    sends a command to the lens.
  2. For both lens and host, the byte intervals in the same command block must not be 1 msec or more. Both lens
    and host judge that there is an error if the byte intervals in the receiving command block are 1 msec or more.
  3. If there is no command from the host in 5 seconds or more, the lens judges that the control from the host has
    finished and switches individual controls to local or camera. By the time the lens detects a change in local
    control signal or control signal from the camera, the position before switching is maintained.
  4. If the lens or DSR is turned OFF, however, individual controls are switched to local or camera in spite of the
    settings made at that point. The position before switching is not maintained.

but then Isn't it enough to loop the DSR using the DTR pin but in my module >> Mini MAX3232 RS232 Shield - emartee.com
there is no DTR also.

After connecting to the lens directly the arduino mega serial1 port with the rx from arduino to tx of lens and tx of arduino to rx of lens and matching the grounds I wrote the following code:

void setup() {

  Serial1.begin(38400);
}

void loop() {

  Serial1.write(0x02);
  Serial1.write(0x20);
  Serial1.write(0x80);
  Serial1.write(0x80);
  delay(1);
  Serial1.write(0xDE);
  delay(20);
}

I have selected the speed and code on the basis of following attached protocol sheet which defined info like the baud rate at which the lens will talk to the uC or any other computer.

can you tell me what's wrong with the code?

08_11_ver. 1,40 27 L10 protocol (DIGI POWER ENG-EFP.pdf (850 KB)

We can't see what you can see; can you tell us what you think is wrong with the code?

We can't see what you can see; can you tell us what you think is wrong with the code?

If you will open the attached document on PAGE - 4 you will get to see how one can make the code for driving the lens , I mean timing of various bits/inputs and for what particular feature So I think if anything is wrong it will be there only, I think I'm not able to send the write values and they should be or I'm missing the 1mS (milisecond delay)delay?

Moderator edit: code tag replaced with quote tag