Basit bir Arduino kodu Proton a çevirince neden çalışmaz?

Başlatan dyonizos, 01 Kasım 2012, 11:02:45

dyonizos

selam arkadaşlar,
nette bulduğum ve çalışan aşağıdaki arduino kodunu protona çevirmek istedim ama çalıştıramadım nerede hata yapıyor olabilirim acaba?.

Arduino Kodu
/*
Send a Start/Sop Recording command to the LANC port of a video camera.
Tested with a Canon XF300 camcorder
This code requires a simple interface see http://micro.arocholl.com
Feel free to use this code in any way you want.

Comprehensive LANC info: [url=http://www.boehmel.de/lanc.htm]www.boehmel.de/lanc.htm[/url]

"LANC" is a registered trademark of SONY.
CANON calls their LANC compatible port "REMOTE".

2011, Martin Koch
http://controlyourcamera.blogspot.com/2011/02/arduino-controlled-video-recording-over.html
*/

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

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
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 till the end of each bit
}

void loop() {
if (!digitalRead(recButton)) {
REC(); //send REC command to camera
delay(1000); //debounce button
}
}



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, LOW);  //Write bit 0. 
delayMicroseconds(bitDuration); 
digitalWrite(cmdPin, LOW);  //Write bit 1 
delayMicroseconds(bitDuration);  
digitalWrite(cmdPin, LOW);  //Write bit 2
delayMicroseconds(bitDuration); 
digitalWrite(cmdPin, HIGH);  //Write bit 3
delayMicroseconds(bitDuration);  
digitalWrite(cmdPin, HIGH);  //Write bit 4
delayMicroseconds(bitDuration);
digitalWrite(cmdPin, LOW);  //Write bit 5 
delayMicroseconds(bitDuration);
digitalWrite(cmdPin, LOW);  //Write bit 6
delayMicroseconds(bitDuration); 
digitalWrite(cmdPin, LOW);  //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, HIGH);  //Write bit 0 
delayMicroseconds(bitDuration);
digitalWrite(cmdPin, HIGH);  //Write bit 1 
delayMicroseconds(bitDuration); 
digitalWrite(cmdPin, LOW);  //Write bit 2
delayMicroseconds(bitDuration); 
digitalWrite(cmdPin, LOW);  //Write bit 3
delayMicroseconds(bitDuration);
digitalWrite(cmdPin, HIGH);  //Write bit 4 
delayMicroseconds(bitDuration); 
digitalWrite(cmdPin, HIGH);  //Write bit 5
delayMicroseconds(bitDuration);
digitalWrite(cmdPin, LOW);  //Write bit 6
delayMicroseconds(bitDuration);
digitalWrite(cmdPin, LOW);  //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
}



Çevirdiğim Kod :
Device 12F629
Config INTRC_OSC_NOCLKOUT, MCLRE_OFF, WDT_OFF, PWRTE_ON
Xtal 4

Set_OSCCAL
GPIO=%00000000
TRISIO=%00000101

CMCON = 7
OPTION_REG.7=0

Dim bitDuration As Byte
Dim tekrar As Byte
Dim syncbyte As Word

Symbol LancPIN =GPIO.0  
Symbol cmdPIN =GPIO.5 
Symbol buton = GPIO.2  

bitDuration = 104 

cmdPIN=0
DelayMS 5000
bitDuration = bitDuration - 8

basla:
If buton=0 Then tekrar=0 : GoSub start
GoTo basla

start:

While tekrar < 5

While syncbyte < 5000
PulsIn LancPIN, 1, syncbyte
Wend


DelayUS bitDuration

Low cmdPIN 
DelayUS bitDuration
Low cmdPIN 
DelayUS bitDuration
Low cmdPIN 
DelayUS bitDuration
High cmdPIN 
DelayUS bitDuration
High cmdPIN 
DelayUS bitDuration
Low cmdPIN 
DelayUS bitDuration
Low cmdPIN 
DelayUS bitDuration
Low cmdPIN 
DelayUS bitDuration

Low cmdPIN 
DelayUS 10

While LancPIN=1:Wend

DelayUS bitDuration


High cmdPIN
DelayUS bitDuration
High cmdPIN
DelayUS bitDuration
Low cmdPIN 
DelayUS bitDuration
Low cmdPIN 
DelayUS bitDuration
High cmdPIN
DelayUS bitDuration
High cmdPIN
DelayUS bitDuration
Low cmdPIN 
DelayUS bitDuration
Low cmdPIN 
DelayUS bitDuration

Low cmdPIN 

tekrar=tekrar+1
Wend
DelayMS 200
Return

Maxim


dyonizos

Sony nin cihazlarını kontrol etmek için kullandığı kumanda protokolu. Kablo ile komut gonderıp cihazları bu protokol üzerinden kontrol edebiliyorsun.

http://www.boehmel.de/lanc.htm

mesaj birleştirme:: 01 Kasım 2012, 13:28:56

buda farklı bir link belki daha açıklayıcı olur.
Kodu neredeyse satır satır çevirdim ve çok kritik bir noktası yok gibi geldi ama çalışmıyor.

http://controlyourcamera.blogspot.com/2011/02/arduino-controlled-video-recording-over.html

Kazım

Arkadaşım kodlarını kontrol etmedim Protonu iyi bilmiyorum ancak;

delay(5000);  //Wait for camera to power up completly


burada delay,  ms cinsinden mi?  5sn power up time baya uzun bir süre bu dikkatimi çekti.

dyonizos

5000ms arduinoda. zaten o bölüm sadece makineyi açmak için kullanılıyor. O bölümü kullanmaya gerek yok eğer makine zaten açıksa o bölüm zaten bir işe yarmıyor. Asıl çalışması gereken yer zaten sonrası ama deli etti çalışmıyor.

kodları tekrar tekrar gözden geçirdim ama ya artık ben göremiyorum yada başka bir şey var.

Alıntı yapılan: graski - 01 Kasım 2012, 15:14:04
Arkadaşım kodlarını kontrol etmedim ama ;

delay(5000);  //Wait for camera to power up completly


kodu varya sen buna 5000ms olarak yazmışsın power up time 'ı 5000ms bana fazla geldi.Bu gecikmeler ms cinsinden olduğuna eminmisin us olmasın...

Maxim

nasıl test ediyorsunuz bunu ?
proteus dosyası bilmem nesi yokmudur?

dyonizos

Yukarida verdigim linkteki devre semasini yaptim elimdeki sony kamera ile denedim.
Arduino ile calisiyor ama benim cevirdigim kod ile calismiyor.
Teorik olarak sanki ayni kodlari yazdim saniyorum ama neden olmuyor cozemedim.

Alıntı yapılan: Maxim - 01 Kasım 2012, 19:35:13
nasıl test ediyorsunuz bunu ?
proteus dosyası bilmem nesi yokmudur?

mehmet

Pic ile yaptığın uygulamada aralıkları
104us okuyabiliyor musun, ölçebildin mi?

Saygılar...

Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

dyonizos

Arduinoda da araliklar yaklasik 200us. Logic analyzer ile olctum. Pic ile olanda da araliklar ayni ama ikisindede bir tuhaflik var zaten. Logic analyzer ikisindede tuhaf grafik gosteriyor.

Sizce kodlarda bir problem varmi. Yani cevrimde ?

Alıntı yapılan: mehmet - 01 Kasım 2012, 21:01:34
Pic ile yaptığın uygulamada aralıkları
104us okuyabiliyor musun, ölçebildin mi?

Saygılar...

mehmet

Arduino ile çalışıyorsa başka bir sıkıntı olmalı...

Saygılar...

Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

dyonizos

Sanırım sorun burada.
arduino da yazılı olan kod

while (pulseIn(lancPin, HIGH) < 5000) {   
}


Protonda yazdığım kod

While syncbyte < 5000
PulsIn LancPIN, 1, syncbyte
Wend


Bu iki kod arasında bir fark varmı? bu iki koduda kaldırıp logiz analyzer la baktıgımda birebir aynı sinyali görüyorum. Ancak bu kodları aktif yaptığımda arduinoda çalışıyor protonda çalışmıyor. Frekans ile bir alakası varmı bu kodun? arduino sonuçta 16Mhz çalışıyor pic 4 Mhz


bocek

TRISIO=%00000101

satırı ile
Symbol LancPIN =GPIO.0  
Symbol cmdPIN =GPIO.5 
Symbol buton = GPIO.2

satırları tutarlı mı?
sanki cmdPIN = GPIO.1 olmalı gibi
Not : PIC'ten de protondan da anlamam etmem..
1 ya da 0. işte 'bit'ün mesele..

dyonizos

LancPIN devrede giriş olarak kullanılmış. Yani protonda da 1 (giriş olarak) tanımlı aynı şekilde GPIO.2 de de buton bağlı o da giriş olarak tanımlı.
Ben GPIO.5 pinini de 0 (çıkış olarak) tanımladım. GPIO.1 de kullanılabilir tabiki. Ancak devre breadboard üzerinde bu şekilde daha rahat kuruldu bende GPIO.5 i çıkış yapmıştım. Zaten cmdPIN den analyzer ile ölçümüm arduino çıkış pini ile aynı sonucu veriyor.

Zaten Arduino da da
LancPIN Giriş
Buton Giriş
cmdPIN Çıkış
olarak tanımlanmış yanılmıyorsam.

Delirmek üzereyim :):)


Alıntı yapılan: bocek - 03 Kasım 2012, 07:03:25
TRISIO=%00000101

satırı ile
Symbol LancPIN =GPIO.0  
Symbol cmdPIN =GPIO.5 
Symbol buton = GPIO.2

satırları tutarlı mı?
sanki cmdPIN = GPIO.1 olmalı gibi
Not : PIC'ten de protondan da anlamam etmem..

bocek

arduino'da buton pininin dahili pull-up direncini aktif etmiş.

digitalWrite(recButton, HIGH); //turn on an internal pull up resistor


protonda bu kodun karşılığını göremedim ama belki sen dışardan pull-up bağlamışsınıdır..
1 ya da 0. işte 'bit'ün mesele..

Maxim

şuraya proteus simulasyonu ekleseydin delirmezdin
şimdi ben birşey denemek için şema çizip simulasyonmu kurucam ? olduu

bu arada pulsin komutu osc frekansına bağımlıdır
yani frekans değişince sonuçta değişir
ayrıca arduinodaki pulsin ile protondaki pulsin komut detayları aynı olmak zorunda değil

ve baktımda pulsin komut satırında yanlış
kısacası hem frekanstan hatalı hemde kullanımı hatalı gözüküyor
PulsIn LancPIN, 1, syncbyte
doğrusu: syncbyte=PulsIn LancPIN, 1


Proton Compiler. Development Suite. 

PulseIn 

Syntax 
Variable = PulseIn Pin, State 

Overview 
Change the specified pin to input and measure an input pulse. 

Operators 
Variable is a user defined variable. This may be a word variable with a range of 1 to 65535, or 
a byte variable with a range of 1 to 255. 
Pin is a Port.Pin constant that specifies the I/O pin to use. 
State is a constant (0 or 1) or name  High -  Low that specifies which edge must occur before 
beginning the measurement. 

Example 
    Dim Var1 as Byte 
Loop: 
    Var1 = PulseIn PORTB.0, 1 ' Measure a pulse on pin 0 of PortB. 
    Print Dec Var1, " "                  ' Display the reading 
    Goto Loop                            ' Repeat the process. 

Notes 
PulseIn acts as a fast clock that is triggered by a change in state (0 or 1) on the specified pin. 
When the state on the pin changes to the state specified, the clock starts counting. When the 
state on the pin changes again, the clock stops. If the state of the pin doesn't change (even if it 
is already in the state specified in the PulseIn instruction), the clock won't trigger. PulseIn waits 
a maximum of 0.65535 seconds for a trigger, then returns with 0 in variable. 

The variable can be either a Word or a  Byte . If the variable is a word, the value returned by 
PulseIn can range from 1 to 65535 units. 

The units are dependant on the frequency of the crystal used. If a 4MHz crystal is used, then 
each unit is 10us, while a 20MHz crystal produces a unit length of 2us. 

If the variable is a byte and the crystal is 4MHz, the value returned can range from 1 to 255 
units of 10µs. Internally, PulseIn always uses a 16-bit timer. When your program specifies a 
byte,  PulseIn stores the lower 8 bits of the internal  counter into it. Pulse   widths   longer   than 
2550µs will give false, low readings with a byte variable. For example, a 2560µs pulse returns a 
reading of 256 with a word variable and 0 with a byte variable.



mesaj birleştirme:: 03 Kasım 2012, 09:25:34

ek:

şimdi 4mhz de pulsin komutu 16mhz osc ye göre 4 katı daha düşük okuma yapıyor
yani While syncbyte < 5000 değilde
While syncbyte < 20000 dersek bu değeri yakalamış oluruz

(tabi kesin değil genede, bakmak ölçmek lazım)