So I solved the problem of emulating a PS/2 keyboard, using this code
#include "ps2dev.h" // to emulate a PS/2 device
PS2dev keyboard(3,2); // PS2dev object (2:data, 3:clock)
int enabled = 0; // pseudo variable for state of "keyboard"
void ack() {
//acknowledge commands
while(keyboard.write(0xFA));
}
int keyboardcommand(int command) {
unsigned char val;
switch (command) {
case 0xFF: //reset
ack();
//the while loop lets us wait for the host to be ready
while(keyboard.write(0xAA)!=0);
break;
case 0xFE: //resend
ack();
break;
case 0xF6: //set defaults
//enter stream mode
ack();
break;
case 0xF5: //disable data reporting
//FM
enabled = 0;
ack();
break;
case 0xF4: //enable data reporting
//FM
enabled = 1;
ack();
break;
case 0xF3: //set typematic rate
ack();
keyboard.read(&val); //do nothing with the rate
ack();
break;
case 0xF2: //get device id
ack();
keyboard.write(0xAB);
keyboard.write(0x83);
break;
case 0xF0: //set scan code set
ack();
keyboard.read(&val); //do nothing with the rate
ack();
break;
case 0xEE: //echo
//ack();
keyboard.write(0xEE);
break;
case 0xED: //set/reset LEDs
ack();
keyboard.read(&val); //do nothing with the rate
ack();
break;
}
}
void setup() {
// send the keyboard start up
while(keyboard.write(0xAA)!=0);
delay(10);
}
void loop() {
unsigned char c;
//if host device wants to send a command:
if( (digitalRead(3)==LOW) || (digitalRead(2) == LOW)) {
while(keyboard.read(&c)) ;
keyboardcommand(c);
}
else{ //send keypresses accordingly using scancodes
// secancodes: http://www.computer-engineering.org/ps2keyboard/scancodes2.html
keyboard.write(0x1C); // \
keyboard.write(0xF0); // |- send 'a'
keyboard.write(0x1C); // /
delay (1000); // wait 1 second
}
}
and the lanc controller using this code
/*
SIMPLE LANC REMOTE
Version 1.0
Sends LANC commands to the LANC port of a video camera.
Tested with a BMCC and BMPCC.
For the interface circuit interface see
http://controlyourcamera.blogspot.com/2011/02/arduino-controlled-video-recording-over.html
Feel free to use this code in any way you want.
2011, Martin Koch, adapted for Blackmagic cameras by klaus erharter
"LANC" is a registered trademark of SONY.
CANON calls their LANC compatible port "REMOTE".
*/
#define cmdPin 7
#define lancPin 11
#define recButton 6
#define irisDecrementButton 5
#define IrisIncrementButton 4
#define focusNearButton 3
#define focusFarButton 2
int cmdRepeatCount;
int bitDuration = 104; //Duration of one LANC bit in microseconds.
//LANC commands byte 0 + byte 1
//Tested with Canon XF300
//Start-stop video recording
boolean REC[] = {LOW,LOW,LOW,HIGH,HIGH,LOW,LOW,LOW, LOW,LOW,HIGH,HIGH,LOW,LOW,HIGH,HIGH}; //18 33
//Iris increment
boolean IRIS_INCREMENT[] = {LOW,LOW,HIGH,LOW,HIGH,LOW,LOW,LOW, LOW,HIGH,LOW,HIGH,LOW,HIGH,LOW,HIGH}; //28 55
//Iris decrement
boolean IRIS_DECREMENT[] = {LOW,LOW,HIGH,LOW,HIGH,LOW,LOW,LOW, LOW,HIGH,LOW,HIGH,LOW,LOW,HIGH,HIGH}; //28 53
//Focus control. Camera must be switched to manual focus
boolean FOCUS_NEAR[] = {LOW,LOW,HIGH,LOW,HIGH,LOW,LOW,LOW, LOW,HIGH,LOW,LOW,LOW,HIGH,HIGH,HIGH}; //28 47
boolean FOCUS_FAR[] = {LOW,LOW,HIGH,LOW,HIGH,LOW,LOW,LOW, LOW,HIGH,LOW,LOW,LOW,HIGH,LOW,HIGH}; //28 45
//boolean FOCUS_AUTO[] = {LOW,LOW,HIGH,LOW,HIGH,LOW,LOW,LOW, LOW,HIGH,LOW,LOW,LOW,LOW,HIGH,HIGH}; //28 43
void setup() {
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
pinMode(irisDecrementButton, INPUT);
digitalWrite(irisDecrementButton, HIGH);
pinMode(IrisIncrementButton, INPUT);
digitalWrite(IrisIncrementButton, HIGH);
pinMode(focusNearButton, INPUT);
digitalWrite(focusNearButton, HIGH);
pinMode(focusFarButton, INPUT);
digitalWrite(focusFarButton, HIGH);
digitalWrite(cmdPin, LOW); //set LANC line to +5V
delay(5000); //Wait for camera to power up completly
bitDuration = bitDuration - 8; //Writing to the digital port takes about 8 microseconds so only 96 microseconds are left for each bit
}
void loop() {
if (!digitalRead(recButton)) {
lancCommand(REC);
}
if (!digitalRead(IrisIncrementButton)) {
lancCommand(IRIS_INCREMENT);
}
if (!digitalRead(irisDecrementButton)) {
lancCommand(IRIS_DECREMENT);
}
if (!digitalRead(focusNearButton)) {
lancCommand(FOCUS_NEAR);
}
if (!digitalRead(focusFarButton)) {
lancCommand(FOCUS_FAR);
}
}
void lancCommand(boolean lancBit[]) {
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
//Note that the command bits have to be put out in reverse order with the least significant, right-most bit (bit 0) first
for (int i=7; i>-1; i--) {
digitalWrite(cmdPin, lancBit[i]); //Write bits.
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
//Note that the command bits have to be put out in reverse order with the least significant, right-most bit (bit 0) first
for (int i=15; i>7; i--) {
digitalWrite(cmdPin,lancBit[i]); //Write bits
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
}
Now my question: is it possible to run these two codes at the sometime?
How should that be accomplished?
Or should I post in the programming section?
Many thanks
Klaus