2011-05-18 19 views
9

Arduino projesinde çalışıyorum ve bellek sınırlamaları nedeniyle bir Python betiğiyle çalışıyorum. Python tarafında, koordinatlar için ilgili x, y değerlerini içeren 2 boyutlu bir matrisim var ve bu listede 26000 koordinat çifti var. Bu nedenle, hepiniz için veri yapısını açıklığa kavuşturmak amacıyla, pathlist[0][0], listemin ilk koordinatının X değerini döndürür. Python'daki bu listede farklı işlemler, vb. Işlemler yapmak hiç sorun değil. Başım belaya girdiğim yerde, bu değerleri faydalı bir şekilde Arduino'ya seri üzerinden gönderiyor.Python seri iletişimi

Seri iletişimin doğası gereği (en azından bunun böyle olduğunu düşünüyorum) her bir tam sayıyı bir dize olarak ve her seferinde yalnızca bir rakam olarak göndermeliyim. Yani, 345 gibi bir sayı, 3, 4, sonra 5 olan 3 ayrı karakter olarak gönderilecektir.

Ne ile uğraştığım Arduino üzerinde bu tam sayıları yeniden oluşturmak için bir yol bulmaktır. Ben üzerinden bir değer yollanır ise

, veri aldığını ve böylece gibi çıktısı oluyor:

//Python is sending over the number '25' 
    2ÿÿ52 
    //Python is sending the number 431. 
    4ÿÿ321ÿÿÿ2 

Arduino kodu:

String str; 
int ds = 4; 

void setup() { 
    Serial.begin(9600); 
} 

void loop(){ 
    if (Serial.available()>0) { 
     for (int i=0; i<4; i=i+1) { 
      char d= Serial.read(); 
      str.concat(d); 
     } 

     char t[str.length()+1]; 
     str.toCharArray(t, (sizeof(t))); 
     int intdata = atoi(t); 
     Serial.print(intdata); 
    } 
} 

Ve Python kodu şöyle:

import serial 

s = serial.Serial(port='/dev/tty.usbmodemfd131', baudrate=9600) 

s.write(str(25)) 

Sorunun çıkış yönteminden kaynaklanmadığından neredeyse eminim (Serial.print), başka bir int bildirdiğim gibi görünce, çıktıda iyi biçimlendiriyor, bu yüzden sorunun intdata değişkeninin nasıl oluşturulduğuna bağlı olduğunu farz ediyorum.

Bu sorunu tanılamanıza yardımcı olabilecek bir not şudur: Serial.print(intdata)'u Serial.print(intdata+5) olarak değiştirirsem sonuç 2ÿÿ57 olur; burada 30 (25 + 5) beklerim. Bu 7, girişten bağımsız olarak mevcut. Mesela ben seri için 271 yazabilirsiniz gibi görünecektir benim sonuç şu:

//For input 271. 
2ÿÿ771ÿÿÿ7 

Arduino iki çiftler halinde değerlerini chunking ve sonuna kadar uzunluğu ekleme olduğunu bana görünür. Bunun neden olduğunu anlayamıyorum.

Ayrıca, ÿ for döngüsüne ekleniyor gibi görünüyor. Eklendikleri anlamı, o anda şu anda hiçbir şey gönderilmiyor. Ancak, bunu başka bir if(Serial.available()>0) koşullu ekleyerek bile düzeltmek, sonuç hala bir tamsayı gibi ele alınmaz.

Ayrıca, Pickle kullanıyor musunuz? Neyi yanlış yapıyorum?

+0

neden şudur:

s.write(str(25)+'\n') 

ve sonra alıcı tarafında 'java' etiketli? – NPE

+0

@aix Peki, Arduino'nun java'ya bağlı olduğunu düşündüm ve bu yüzden Java bilgisi bunun için geçerli olacaktı. Yine de hatalıysam memnun olurum: D – danem

+1

Sadece Java'da yazılan Arduino IDE'sidir. Arduino’da çalışan kodunuz C’de. Bu yüzden Java soruyla alakalı değil. – NPE

cevap

5

Seri verilerin gelmesi için biraz beklemeniz gerekir.

Arduino kodu olmalıdır:

if (Serial.available()){ 
    delay(100); // Wait for all data. 
    while (Serial.available()) { 
     char d = Serial.read(); 
     str.concat(d); 
    } 
} 

Ayrıca yeniden kullanmadan önce dizeyi temizlemek zorunda.

[Düzenle]

i y söylemeyi unutmuşum == -1 == buna bir şey okuyamaz söylediğini Serial.read() anlamına 255.piton sayılar arasındaki yeni satır gönderir, böylece

+1

Gah. Bunun basit bir problem için gereksiz yere karmaşık bir görev olduğunu düşünüyorum. Heh, aptalım. Peki işe yarıyor! Çok teşekkürler, gerçekten takdir ediyorum. – danem

+0

Çalıştığım bir sorun, bunu dev koordinatlar listesinde kullanmaya çalıştığımda başarısız olmalarıdır. Mesela sadece ilk 40 x ve y vals üzerinden gönderildiyse, sonuç -5062'yi elde ettim. Girdi mi yoksa bir şeyle mi yüklüyorum? – danem

+0

Bu sorunu bir kez yaşadım. Çok fazla veri gönderdiğinizde, Arduino'nun bu döngüyü sonlandırmamış olabileceğini düşünüyorum (gecikme çağrısı yaparak işlem süresine ekstra 100ms ekledim). Bir çözüm, bir bitiş çizgisi karakteri eklemek ve gelene kadar döngüyü işlemektir. – JBernardo

5

Ben iletişimi değiştirecek, böylece zamanlama olarak bağımlı değiliz:

void loop(){ 
    while (Serial.available() > 0) { 
     char d = Serial.read(); 
     if (d == '\n') { 
      char t[str.length()+1]; 
      str.toCharArray(t, (sizeof(t))); 
      int intdata = atoi(t); 
      Serial.print(intdata); 
      str = String(); 
     } 
     else { 
      str.concat(d); 
     } 
    } 
}