Komunikacja SPI
(Wpis ten jest reaktywacją wpisu z 2017 r. Okazało się, że warto podzielić oryginalny wpis na dwie mniejsze części – jedna dotycząca komunikacji I2C, druga SPI właśnie).
Tutaj https://www.arduino.cc/en/reference/SPI można poczytać czym jest protokół SPI. Nam wystarczy, że jest to szybka komunikacja synchroniczna na krótki dystans, wykorzystująca przynajmniej 3 linie nazwane MISO, MOSI i SCK. Dodatkowo są jeszcze linie CE i SCN. Jeśli więc w jakimś module zobaczymy tak nazwane piny – to znak, że działa w standardzie SPI właśnie.
Specjalne piny SPI w Arduino to MISO (12 w Arduino), MOSI (11 w Arduino) oraz SCK (13 w Arduin0). Inne piny – CE i CSN są dowolne cyfrowe (występuje różne nazewnictwo – SS to Slave Select i odpowiada CE, który musi działać jako OUTPUT, w odróżnieniu od CSN). W poniższym przykładzie wybrałem 9 i 10 – a dlaczego? okaże się to później (na kolejnych spotkaniach naszego koła).
nRF24L01+
Bardzo fajny moduł (no i bardzo tani – około 5 zł, co w porównaniu do modułów Bluetooth jest 1/5 ceny) – ale najpierw trzeba wiedzieć, jak podłączać go do Arduino:
UWAGA: zasilanie VCC jest z przedziału 3.3V-3.6V – podłączając do Arduino 5V USZKODZISZ moduł.
Oprogramowanie? Ponownie jest kilka bibliotek, ja użyłem nRF24L01.h by TMRh20. Jak poprzednio – doinstalowujemy do naszego Arduino IDE i tworzymy program odbierający dane:
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> RF24 radio(9, 10);//CE, CS const byte rxAddr[6] = "grzyb"; void setup() { Serial.begin(9600); Serial.print("nRF24 INIT="); bool ok=radio.begin(); Serial.println(ok); radio.openReadingPipe(0, rxAddr); radio.startListening(); } char text[32]; void loop() { if (radio.available()) { radio.read(&text, sizeof(text)); Serial.print("t="); Serial.print(millis()/1000); Serial.print("s, text="); Serial.println(text); } }
W linii 6 nadalismy nazwę naszemu strumieniowi – dowolne 5 znaków, niekoniecznie musi być tak jak u mnie… Ale nadajnik też musi nadawać na tym samym „paśmie”:
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include <printf.h> RF24 radio(9, 10);//CE, CS uint8_t rxAddr[6] = "grzyb"; void setup() { Serial.begin(9600); Serial.print("nRF24 INIT="); bool ok=radio.begin(); Serial.println(ok); printf_begin; radio.printDetails(); radio.setRetries(15, 15); radio.openWritingPipe(rxAddr); radio.stopListening(); } char text[] = "Fiza: OK!"; void loop() { radio.write(&text, sizeof(text)); text[7]=48+rand()%10; text[8]=48+rand()%10; text[9]=48+rand()%10; text[10]=48+rand()%10; text[11]=48+rand()%10; Serial.println(text); delay(3000); }
Maksymalna długość jednorazowo przesłanego napisu wynosi 32 bajty, a inne ważne rzeczy – w dokumentacji (zachęcam do czytania).
Problemy? Modyfikacje?
Np. problem ze zrywaniem połączenia – ludzie piszą o niestabilnym napięciu z pinu 3.3V Arduino oraz o problemie z prądem (pin 3.3V może maksymalnie dać tylko 50mA), dlatego dodają dodatkowy kondensator (mały, np 4.7 μF, 10 μF) do zasilania modułu:
Mogą pojawić się też problemy z anteną, więc albo kupujemy moduł z „wypasioną antenką”:
albo samodzielnie robimy sobie antenkę:
Polecam zajrzeć tutaj aby poczytać o problemach i różnych sposobach ich rozwiązywania, a także o oprogramowywaniu tego moduły.
(c) K.G. 2017, 2019