Soru:
Arduino'lar arasında iletişim için seçenekler
waspinator
2016-03-18 01:22:41 UTC
view on stackexchange narkive permalink

Arduinolar arasında komut ve veri göndermek için ~ 5-10 Arduino arasında iletişim kurmaya çalışıyorum. "Arduino" ile, Arduino programlama çerçevesi kullanılarak programlanan ATmega328'i kastediyorum.

Her cihaz aynı PCB üzerinde olacaktır.

I2C ve SPI'nin bir dereceye kadar iletişim kurabildiğini biliyorum. , ancak bunların birden çok mikro denetleyiciyi birbirine bağlamak yerine bir mikro denetleyiciye bağlı çevre aygıtları için amaçlandığını ve genellikle bir seferde yalnızca birkaç bayt veri gönderdiklerini. Öte yandan, LCD ekranların bunları kullanarak çalıştırılabileceğini biliyorum ve bu durumlarda çok fazla veri aktarıldığını hayal ediyorum.

I2C gibi bir şey var mı (multi-master, multi- mikro denetleyiciler arasında iletişim kurmak için bağımlı, tek uçlu, seri bilgisayar veri yolu)? Her cihazın istenmeden birbirlerine veri göndermesine izin verme. Örneğin, A cihazında bir anahtara basılırsa, bir anahtara basılırsa, B cihazının A'ya her zaman sormasına gerek kalmadan B cihazına söylerdi. ve tam tersi.

Düzenleme : RS-485 ile istediğimi yapabilecek bazı kitaplıklar buldum. Bu, 5-10 cihaz arasında ~ 1k bps aktarım için tek uygun seçenek mi? Ethernet üzerinden TCP / IP'nin de çalışacağını düşünürdüm, ancak bu çok fazla görünüyor. Yalnızca ana cihazlar arasında bu miktarda veri gönderilmesine izin veren herhangi bir I2C kitaplığı var mı?

Seri bağlantıya baktınız mı?
RS-485 mi demek istiyorsun?
Burada çok benzer bir soru var: [Ev ışıklarını / anahtarları kontrol etmek için birden fazla Arduino'yu bir Rpi ile nasıl birbirine bağlayabilirsiniz] (http://arduino.stackexchange.com/questions/15834/how-to-interconnect-multiple-arduinos- ev ışıklarını kontrol etmek için rpi ile) - Rpi bölümünü görmezden gelerek (soruyla gerçekten alakalı değildi) Bunu yapmak istediğiniz şeyle neredeyse aynı sayıyorum. Orada bir "yuvarlanma ustası" sistemi yapma konusunda uzun bir yanıt verdim. Lütfen diğer soruyu / cevabı okuyun ve ne düşündüğünüzü görün.
Fiziksel bir katmana (kablolama veya kart), RS-485 gibi elektronik "standart" a ihtiyacınız var, ancak 5V TTL de iyidir. O zaman ne tür bir veri yolu tahkimi (round-robin, master-slave veya yayın mesajları) seçmeniz ve muhtemelen bazı adresleme veya hata kontrollerini uygulamanız gerekir.
Bir devre tahtasında, alıcı vericilere ihtiyacı olduğu için RS485'i kullanmam. Mantık 1 için sadece 5v ve mantık 0 için 0v. Ancak bu noktadan itibaren olasılıklar sonsuzdur. Aynı zamanda hız gereksinimlerine vb. Bağlı olacaktır.
Neden böyle bir şey yaratmak istediğinizi söylemediniz. IO pinlerinde kısaysanız, IO genişleticileri kullanabilirsiniz. Daha iyi çözümler olabilir. Bu bir hobi / kavram kanıtıysa, bunun gibi diğer projeleri inceleyebilir ve "geliştirmeye / ayarlamaya" çalışabilirsiniz.
@Paul Endişelerimi birbirinden ayırmak istiyorum. Daha fazla kesinti ve G / Ç içeren daha büyük bir denetleyici alabileceğimi biliyorum, ancak işleri cihaz düzeyinde basit tutmayı tercih ederim. Ayrıca, her alt sistem bağımsız olarak tasarlanabildiği ve hatta inşa edilebildiği ve daha sonra birbirine bağlanabildiği için başkalarıyla işbirliği yaparken de yardımcı olur. Ayrıca, birim testi yapmak ve değiştirmek / yükseltmek daha kolay olabilir.
Belki sadece bulmadım ama temel soruyu da okumadım, "ihtiyacınız olan topoloji nedir"? Herkesin herkesle konuşmasına ihtiyacınız var mı? Merkezi erişim (yani herkes biriyle konuşuyor)? Karışık bir çözüm mü?
@frarugi87 Başka herhangi bir cihazla iletişim kuran ve bağlantıyı başlatan herhangi bir cihazla bir veri yolu topolojisinin en iyi şekilde çalışacağını düşünüyorum. Yani köle yok.
Peki, otobüs topolojisi için tamam, ancak bir otobüs kaptanı ve diğer tüm köleleri yapmanızı şiddetle tavsiye ederim. Aksi takdirde çarpışmalar yaşarsınız ve çarpışmaları tespit etmek / önlemek "zor" bir iştir. Eğer sadece bir efendiniz varsa bundan kaçınabilirsiniz, çünkü sadece o konuşmaya izin verebilir. Master'ın TX'sini her bir slave RX'e bağlayan bir kabloyla ve slave TX'i (belki 3 durumlu bir tamponla) master RX'e bağlayan bir kabloyla bir seri (UART) veriyolu yapabilirsiniz. Aksi takdirde, bir papatya zinciri oluşturabilirsiniz: TX1, RX2'ye, TX2'den RX3'e ... TXn'den RX1'e. Bu biraz daha az verimli, çünkü konuşmak
başka bir mikro, n atlama yapmanız gerekiyor, ama işe yarıyor. Son çözüm söylediğiniz şey, yani herkes aynı otobüste konuşuyor, ancak çarpışma algılamaya ihtiyacınız olacak. Bu durumda, çarpışmaları halihazırda ele aldığı için size CAN veriyolunu öneririm (ancak bunu kodunuza uygulamanız gerekecektir).
Dört yanıtlar:
Majenko
2016-03-18 04:01:36 UTC
view on stackexchange narkive permalink

Hayalinizi gerçekleştirmenize yardımcı olabilecek bir dizi kavram vardır. Bu cevabın alanında size istediğinizi tam olarak nasıl uygulayacağınızı söyleyemem, ancak bunu uygulamanıza yardımcı olacak kavramları size gösterebilirim.

Öncelikle kavramı veri yolu yöneticisi . Bu, mutlaka iletişimi başlatan cihaz değildir; bunun yerine, veri yolunun sahibi olan ve kontrol eden cihazdır.

Olmayan bir cihaz olduğunda t Bus master veri yolu üzerinde iletişim kurmak ister, önce veri yolu yöneticisinden izin ister. Eski Z80 (evet, ben "eski" diyorum, ancak bugün hala birçok biçimde kullanılıyorlar) bu konsepti, diğer yongaların verileri kullanmasına ve veri yollarını adreslemesine izin vermek için kullandı. İki sinyalden oluşur - BUSRQ ve BUSACK. Bir cihaz önce BUSRQ veya BUSACK'ten herhangi birinin aktif olup olmadığına bakar ve eğer ikisi de aktif değilse BUSRQ'yu etkinleştirir. Veri yolu yöneticisi diğer aygıta veriyolundan vazgeçmeye istekliyse (o anda kullanmıyorsa), BUSACK'i etkinleştirir ve diğer aygıt veri yolunu kullanabileceğini bilir. Hem BUSRQ hem de BUSACK serbest bırakılıncaya kadar başka hiçbir şey onu kullanamaz. Güzel, sade ve zarif.

Ama mükemmel değil. İki cihaz da aynı anda veri yolunu istemeye karar verirse, bir çarpışma yaşarsınız. Bu, bunun gibi paylaşılan veri yolu sistemleri arasında yaygın bir sorundur ve nasıl düzgün bir şekilde ele alınacağını bilmediğiniz sürece anlatılamayan sorunlara neden olur.

Konuşurken dinle kavramını girin. Bu, otobüste gönderen cihazı, ayrıca ayrı bir alıcı aracılığıyla otobüste gönderilenleri dinlemeyi içerir. Daha sonra, otobüse gönderdiği şeyin aslında otobüse ne olduğunu anlayabilir. Örneğin, iki cihaz aynı anda konuşursa ve biri 10011001 gönderir ve diğeri 11001100 gönderirse, otobüste görünen sonuç aslında başka bir şey olarak sonuçlanabilir, örneğin Veriyolu sinyallerinin nasıl oluşturulduğuna bağlı olarak 11011101 veya belki 10001000 . Dolayısıyla, gönderdiğiniz şeyin bozulduğunu biliyorsanız, şimdi bununla ilgili bir şeyler yapabilirsiniz.

Sonraki konsept: geri adım atmak . Bu, her iki göndericinin de kısa bir süre beklediği ve tekrar denediği ve gönderdiği yerdir. Her ikisi de farklı bir süre geciktikleri sürece ilk denenecek kişi otobüse binecek ve iletişim kurabilecektir. Ama ikisinin de farklı zamanlar için erteleneceğini nasıl garanti edersiniz? Cevabın basit olduğunu düşünebilirsiniz: rand () veya random () gibi rastgele bir sayı kullanın. Ancak bu da sorunludur:

Başka bir kavram: Sözde rasgele sayı üreteci

Arduino rasgele sayılar üretmez . Bize rastgele görünen bir sayı dizisi oluşturmak için karmaşık bir matematiksel formül kullanır. Gerçi değiller. 10 rastgele sayıyı seri yoluyla yazdırmak için küçük bir program yazın ve birkaç kez çalıştırın (sıfırlama düğmesine basın). Her seferinde aynı sırayla aynı "rasgele" sayıları bulacaksınız. Başka bir Arduino'da deneyin ve aynı sayıları tekrar elde edin. Her zaman aynı.

Peki ne yapmalı? Cevap, rastgele sayı oluşturucu tohumlama olarak adlandırılır. rand () ve diğerleri tarafından oluşturulan bir sonraki sayı, en son oluşturulan sayıya bağlıdır. Bu nedenle ilk numarayı değiştirirseniz, kalan tüm numaralar değişecektir. Ancak, bir yakalama durumunuz var. Rastgele sayı üretecini tohumlamak için rastgele bir sayı üretebilmek için rastgele sayı üretecini tohumlamak için rastgele bir sayıya ihtiyacınız var ... ad sonsuz. Bunun nereye gittiğini görüyor musun? Rastgele bir kaynaktan tohumlama yapana kadar rand () rastgele olmadığından rand () 'dan tohumlama yapamazsınız. Bu yüzden rastgele bir kaynak bulmanız gerekiyor.

Bu kolay bir iş değil. Bilindiği gibi entropinin en iyi kaynağı beyaz gürültüdür . Bu, bir diyot bağlantısının bozulmasından dirençteki termal dalgalanmaların çok yüksek kazançlı amplifikasyonuna kadar bir dizi farklı devre ile çeşitli şekillerde üretilebilir.

Hepsi gerçekten istediğiniz şey için oldukça karmaşıktır, ancak biraz daha az rastgele de olsa daha basit bir yöntem vardır - hiçbir şeye bağlı olmayan bir analog girişi okuyun. Uygun bir entropi oluşturucu kadar geniş bir menzile sahip olmayacak, ancak her cihazın farklı bir tohum elde etmesi için makul bir şans vermek için yeterli rastgelelik sağlamalıdır.

Bir başka yararlı kavram da kesmedir.

Bu, tüm çarpışmalarla birlikte çok ana yollu bir veriyolunun karmaşıklığını istemediğiniz bir durumda iyidir. Tüm işi otobüste yapan tek bir ana biriminiz olduğunda ve cihaz, ana bilgisayarı bir kesinti ile dürttüğünü söyleyecek önemli bir şeye sahiptir. Usta daha sonra "Evet? Ne istiyorsun?" kölenin "Biri düğmeme bastı" yanıtını veriyor.

Bu şekilde, usta, düğmeye basılıp basılmadığını görmek için sürekli olarak köleyi sorgulamaz. Genellikle SPI gibi veri yolu düzenlemelerinde kullanılır ve giriş pinlerinden birinin durumunu değiştirdiğinde bir kesinti olduğunu iddia edebilen IO genişletici çipler gibi birçok çip vardır.

Ancak 20 cihazınız varsa bunu yapar 20 kesinti pininiz olduğu anlamına mı geliyor? Şart değil. Yeni konsept: kablolu VEYA .

Hepsi aynı kesme pinini kullanan birden fazla farklı slave'e sahip olmak tamamen mümkündür. Pim normalde bir dirençle YÜKSEK tutulur (dahili bir pullup direnci olabilir) ve her ikincil öğenin o pime bağlı bir açık boşaltma çıkışı vardır. Açık bir tahliye çıkışı, "kapalı" olduğunda hiçbir şeye bağlı değildir - pin giriş modundaymış gibidir (aslında giriş ve çıkış modu arasında geçiş yapılarak açık tahliyesi olmayan yongalarda taklit edilebilir). Çıkış "açık" olduğunda, tıpkı bir düğmenin yapacağı gibi IO pinini aşağı çekerek pimi toprağa bağlar.

Daha sonra, olduğunu bildiği köleler arasında yol almak ana kişinin sorumluluğundadır. Kimin ilgiye ihtiyacı olduğunu görmek için o kesmeye ekli. Elbette, her birinde farklı slave gruplarına sahip bir dizi farklı kesme pini uygulayabilirsiniz - örneğin, yalnızca bir cihaza sahip yüksek öncelikli ve her birinde birden fazla cihaz bulunan daha düşük öncelikli olanlar.

Aynı kablolu VEYA ve açık kanal kavramı, birden fazla cihazın aynı fiziksel kabloları paylaşmasına izin vermek için kullanılabilir. I2C tam olarak böyle çalışır - iki bara hattı dirençler tarafından yukarı çekilir ve üzerindeki cihazlar, farklı mantık seviyelerini oluşturmak için tekrar yüksek seviyeye çıkarmak için hattı aşağı çekmek için açık tahliye çıkışlarını kullanır. İki cihaz birlikte aşağı çekerse, sadece düşük olacaktır. Açık tahliye yöntemi olmasaydı, bir cihazınız 1 çıktı verirken diğeri 0 çıktıysa, temelde ikisi arasında kısa devre olur ve yongalara zarar verirsiniz.

Ve tabii ki eşzamanlı ve eşzamansız iletişim kavramına sahipsiniz, ancak bu tamamen farklı bir balık su ısıtıcısıdır. Basitçe söylemek gerekirse, SPI ve I2C gibi bir saate sahip protokoller, bu saati üreten bir ana makineye sahip, senkrondur. UART ve RS-232, RS-485 vb. Gibi protokoller eşzamansızdır - her iki uca da verinin ne kadar hızlı gönderildiği (baud hızı) konusunda hemfikir olurlar, böylece geldiklerinde sinyalleri nasıl yorumlayacaklarını bilirler.

I2C'nin teorik olarak çoklu ana özellikli olduğunu ve rastgele sayılara ihtiyaç duymayan bir tahkim planına sahip olduğunu eklemek isterim. Ancak, Atmel'in uygulamasında bir sorun var gibi görünüyor. C.f. örneğin [TWI modülü çoklu ana iletişimde hatalı görünüyor] (http://www.avrfreaks.net/forum/twi-module-seems-buggy-multi-master-communications) ve [Atmel AVR Mikroişlemcilerle Çoklu Ana Sorun] (http://www.robotroom.com/Atmel-AVR-TWI-I2C-Multi-Master-Problem.html). Tek ana + kesintiler bana en kolay çözüm gibi görünüyor.
@EdgarBonet Bir çeşit veriyolu tahkim sistemi uygulandığında hemen hemen tüm protokoller çoklu yönetici yapılabilir. Bazıları buna diğerlerinden daha uygundur ve I2C gibi bazıları bunu yapmanın "resmi" yollarına sahiptir, bazıları diğerlerinden daha iyi çalışır. En güvenilir yol elbette çoklu ana sisteme hiç ihtiyaç duymamaktır :)
@EdgarBonet, tel kitaplığının çoklu ana kopyayı destekleyip desteklemediğini biliyor musunuz? Bu kadar kolay mı https://michael.bouvy.net/blog/en/2013/05/25/arduino-multi-master-to-master-i2c/
@waspinator: Hiç denemediğim için söyleyemem. Görünüşe göre [Wire kütüphanesi otobüs tahkimini ele alıyor] (https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/libraries/Wire/src/utility/twi.c#L439), ancak Daha önce işaret ettiğim konularla baş edip edemeyeceğini bilmiyorum.
EllisGL
2016-04-15 09:34:53 UTC
view on stackexchange narkive permalink

PJON'a bakın - https://github.com/gioblu/PJON. Tek kablolu bir alternatif.

Lütfen cevabınızı, muhtemelen bir kullanım örneği veya artıları ve eksileri hakkında ayrıntılı olarak açıklayabilir misiniz, çünkü bu şu anda gerçekten yalnızca bir bağlantı cevabıdır.
Lütfen neden alternatiflerden daha iyi olduğu / onu öne çıkaran şey hakkında biraz bilgi ekleyin. Teşekkürler!
PJON, yalnızca Arduino için değil, birden çok platform için kullanıma sunulmuştur. I2C / tek telden daha basittir. Gürültüyü daha iyi idare eder. Çoklu ana desteği vardır. Bağlantıdan wiki'yi okuyun.
AMADANON Inc.
2016-03-18 08:37:35 UTC
view on stackexchange narkive permalink

@ Majenko'nun mükemmel cevabına ek olarak, ne ilettiğiniz hakkında da düşünmeniz gerekiyor.

Görünüşe göre biraz iletişim kurmak istiyorsunuz - belki de bireysel pinlerden kurtulabilirsiniz? Bir master'ınız ve 13 adede kadar slave'iniz varsa, her slave üzerindeki bir pime (bir direnç aracılığıyla) bağlı ana üzerinde bir pime sahip olabilirsiniz. Bağımlı A sinyali sinyal vermek isterse, pimi kaldırır; daha sonra usta, kimin ne dediğini bulmak için sırayla her bir iğneyi oylayabilir.

Maalesef bu son bit, cihazların verileri sorgulamak yerine birbirine "aktarmasını" nasıl istediğimin bir örneğiydi. Aslında ben daha fazla veri göndermek istiyorum. ~ 100 bayt saniyede 10 kez.
AMADANON Inc.
2016-03-18 09:09:12 UTC
view on stackexchange narkive permalink

Diğer bir seçenek de SPI'dır.

SPI, bir halkada herhangi bir sayıda cihazla kullanılabilir. Bana şu şekilde açıklanmıştı: herhangi bir katılımcı, baytı kendi arabelleğindeki bir sonraki aygıtın arabelleğine, bir halka halinde taşımak için saat satırını 8 kez değiştirebilir; cihaz önceki cihazdan bir bayt alır. Bir başkası saati 8 kez değiştirirse, yeni baytın hazır olduğu size bildirilir (bu donanımda yapılır).

Bunun için bir protokol - bir "adres" hakkında dikkatlice düşünmeniz gerekir. uzunluk "," komut "ve ardından herhangi bir sayıda parametre. Gönderen, "adres" baytını gönderir, arabellekteki "uzunluk" baytını ayarlar ve geri kalanını hazır tutar. Sonraki cihaz "adres" baytını aldı ve hedeflenen alıcı olup olmadığını anlar. Değilse, bunu not eder ve zinciri iter, uzunluğu not eder ve BAŞKA birisinin bu kadar baytı itmesini bekler. Size aitse, geri kalan verileri okuyun, verileri itin ve ilerledikçe boşaltın (geri gelmesini durdurmak için). Boş bir adres (ör. 0) rezerve edilir, yani "bununla hiçbir şey yapmayın, başka birinin onu itmesini bekleyin ve bir sonraki baytı sonraki adres olarak okuyun" anlamına gelir. Tüm cihazların başlangıçta 0'a başlaması gerekir.

Adresleri dinamik olarak ayarlamanız gerekiyorsa, "cihaz numaranız X" anlamına gelen bir komutla "tüm istasyonlar" özel bir bayt ayarlayın ve sonraki cihazın cihaz numarası X + 1 ". Elbette birisinin bunu başlatması gerekir.

Ayrıca, iki cihaz aynı anda göndermeye başlarsa veya bir şey olması gerekeni aktarmazsa (ör. Bir yonga) çarpışma riskiyle karşı karşıya kalırsınız. gücü kapalıdır). Bunu nasıl tespit edeceğinizi / kurtaracağınızı düşünmeniz gerekiyor.



Bu Soru-Cevap, otomatik olarak İngilizce dilinden çevrilmiştir.Orijinal içerik, dağıtıldığı cc by-sa 3.0 lisansı için teşekkür ettiğimiz stackexchange'ta mevcuttur.
Loading...