Доброго времени! Решил поэксперементировать с Arduino. Прикупил SD card shield v4 http://amperka.ru/collection/boards/product/arduino-sd-card-shield NFC Shield v2 http://amperka.ru/collection/boards/product/arduino-nfc-shield Возникли вопросы при подключении этих устройств: 1) В большинстве примеров SD подключается к цифровым пинам ардуино 8-13, но так же на плате присутствует дополнительные 6-пин( они находятся на противоположной стороне от портов USB и питания и обозначается ICSP ) На картинке справа по середине платы http://arduino.cc/en/uploads/Main/ArduinoUno_R3_Front.jpg Правильно ли я понял что ICSP порт это по сути те же 8-13 цифровые входы/выходы + питание и просто сгруппированы по другому? То есть если я подключу SD к ICSP то 8-13 так же будут не доступны для других целей кроме как организация шины SPI? 2) По SPI(ICSP) можно подключать несколько устройств параллельно. То есть будет похоже вся система на бутерброд из плат Arduino <= SD <= NFC. Единственно что нужно отдельно от каждого устройства прокинуть контакт(SS Slave Select) на цифровые выходы Arduino. Для управления с каким устройством в данный момент общается Arduino. Низкий уровень на SS соответствует активному устройству. Здесь всё правильно понял?
В общем почти правильно. Но только почти. На этот шестиконтактный разъем выведены только пины 11-13 (MOSI, MISO и SCK), +5, земля и Reset. Соответственно, после подключения к ним SPI, для других целей 11-13 лучше не использовать.. А если использовать, то озаботиться, чтобы при этом все SPI устройства имели HIGH на своих пинах SS. И еще вопрос, гарантирует ли это все устройства от приема "мусора", особенно если задействовать 13 - SCK Насколько я помню, только у Arduino Micro и Leonardo для SPI отдельные выходы, не связанные с цифровыми пинами. Вроде все верно
Спасибо, за ответ. У меня UNO. MOSI, MISO и SCK лучше не трогать на цифровых пинах ардуино. Завтра попробую это дело законектить через ICSP(кроме SS больше же ничего не нужно?). Надеюсь ничего не сгорит. Тут кстати ещё небольшая проблемка: паял я последний раз в классе 9. Посоветуйте мне паяльник для пайки колодок к плате. Бюджетный вариант с тонким жалом иначе запаяю всё нахрен. Спасибо.
Про паяльник - это уже не ко мне. Я такой "специалист" в пайке, что аж самому страшно, на свое дело глядючи. Но, как ни странно, в результате все работает. Пользуюсь китайским "пистолетом" от известной фирмы Noname на 25-100W с кнопкой включения большей мощности и заостренным жалом. Может быть оно неправильно, но паяю так: подношу одновременно тонкую "проволоку" припоя (припой сразу с флюсом) и острие жала паяльника к ноге, которую собираюсь запаять , давлю на кнопку мощности, подаю за секунду несколько миллиметров припоя в точку пайки, и он сам распределяется каплей (иногда даже аккуратной) на ножке и отверстии.
помогите пожалуйста на меге подключаю sd card и nrf24l01 по шине spi начинает конфликтовать nrf24l01 а отдельно все работает что надо при этом сделать
У меня на меге то же самое не конфликтует (SD на Mega IO Shield). Для корректной работы нужно в один момент времени подавать LOW только на одну из линий селектора (CS, SS, CSN), соответствующую устройству, с которым и идет в данный момент обмен по SPI. На остальных должен быть HIGH. Линии эти, естественно, должны быть подключены к отличным друг от друга пинам, и подозреваю, что желательно, чтобы они были отличны от 10-го пина. который (как пишут для SD должен быть обязательно настроен как OUTPUT, но не использоваться). Пока устройства не используются, желательно, чтобы на всех линиях селектора был HIGH, дабы устройства "знали", что в данный момент не обмениваются данными про SPI. Кстати, теоретически возможно, что проблема совсем не в SPI, а в питании по 3.3 В, на которое непосредственно на NRF24L01 рекомендуют напаять конденсатор (особенно на меге), или следует все запитать от отдельного источника (или регулятора) .
кондер запаял отдельно работают передатчик #include <SPI.h> #include <SD.h> #include <Wire.h> #include <DS1307.h> // written by mattt on the Arduino forum and modified by D. Sjunnesson #include "DHT.h" #include <nRF24L01.h> #include <RF24.h> File myFile; // SD CARD #define DHTPIN 13 #define DHTTYPE DHT11 // DHT 11 DHT dht(DHTPIN, DHTTYPE); int SaveTemperature; // Для фиксации температуры. #define JOYSTICK_X A0 #define JOYSTICK_Y A1 // const uint64_t pipe = 0xE8E8F0F0E1LL; // Define the transmit pipe const uint64_t pipes[2] = { 0xF0F0F0F000LL, 0xF0F0F0F0FFLL};// адреса каналов приема и передачи радио сигнала #define CE_PIN 48 #define CSN_PIN 47 RF24 radio(CE_PIN, CSN_PIN); // Create a Radio //переменная для радио кодов int radiocode[1]; int joystick[2]; // 2 element array holding Joystick readings void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); pinMode(53, OUTPUT); if (!SD.begin(53)) { Serial.println("initialization failed!"); return; } // radio.begin(); // radio.openWritingPipe(pipe); //настройки для радио модуля NRF24L01+ 2.4GHz radio.begin(); radio.setDataRate(RF24_250KBPS); // Скорость передачи radio.setChannel(100); // Номер канала от 0 до 127 radio.setRetries(15,15); // Кол-во попыток и время между попытками radio.openWritingPipe(pipes[1]); // Открываем канал передачи radio.openReadingPipe(1, pipes[0]); // Открываем один из 6-ти каналов приема radio.startListening(); // Начинаем слушать эфир SDcardWrite(); // Запускаем функцию записи на SD card. // Установка часов если надо // RTC.stop(); // RTC.set(DS1307_SEC,1); //set the seconds // RTC.set(DS1307_MIN,37); //set the minutes // RTC.set(DS1307_HR,11); //set the hours // RTC.set(DS1307_DOW,4); //set the day of the week // RTC.set(DS1307_DATE,29); //set the date // RTC.set(DS1307_MTH,9); //set the month // RTC.set(DS1307_YR,14); //set the year // RTC.start(); // проверка сенсора температуры Serial.println("DHT11 test!"); dht.begin(); SaveTemperature = dht.readTemperature(); // Фиксируем текущую температуру. } // *************************************** // ------------------- // Делаем функцию для чтения с SD card и вывода в Serial монитор. void SDcardRead() { // re-open the file for reading: myFile = SD.open("dimasens.txt"); if (myFile) { Serial.println("dimasens.txt:"); // read from the file until there's nothing else in it: while (myFile.available()) { Serial.write(myFile.read()); } // close the file: myFile.close(); } else { // if the file didn't open, print an error: Serial.println("error opening dimasens.txt"); } } void SDcardWrite() // Делаем функцию, для записи на SD card. { myFile = SD.open("dimasens.txt", FILE_WRITE); if (myFile) { Serial.print("Writing to dimasens.txt..."); myFile.print("\nActual time : "); myFile.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true myFile.print(":"); myFile.print(RTC.get(DS1307_MIN,true));//read minutes without update (false) myFile.print(":"); myFile.print(RTC.get(DS1307_SEC,true));//read seconds myFile.print(" "); // some space for a more happy life myFile.print(" -- "); myFile.print(RTC.get(DS1307_DATE,true));//read date myFile.print("/"); myFile.print(RTC.get(DS1307_MTH,true));//read month myFile.print("/"); myFile.println(RTC.get(DS1307_YR,true)); //read year myFile.print(" -- "); myFile.print("Humidity: "); myFile.print(dht.readHumidity()); // Значения влажности. myFile.print(" %\t"); myFile.print("Temperature: "); myFile.print(dht.readTemperature()); // Значения температуры. myFile.println(" *C"); myFile.close(); // close the file: Serial.println("done."); } else { // if the file didn't open, print an error: Serial.println("error opening dimasens.txt"); } } void Joy() { // radio.begin(); // radio.openWritingPipe(pipe); // joystick[0] = analogRead(JOYSTICK_X); // joystick[1] = analogRead(JOYSTICK_Y); // radio.write( joystick, sizeof(joystick) ); radiocode[0] = 140; radio.stopListening(); radio.write(radiocode, 1); radio.startListening(); } // ************************************ void loop() { Joy(); //SDcardWrite(); if (SaveTemperature != dht.readTemperature()) { // Serial.println("pered zapis'u"); SDcardWrite(); // Запускаем функцию записи на SD card. // Снова фиксируем текущее значение температуры. // Serial.println("posle zapisi"); SaveTemperature = dht.readTemperature(); // Serial.println("save temp"); } // Для вывода в Serial монитор данных с SD card. if (Serial.available() > 0) { // Если отправляем через Serial монитор цифру 1 // запускаем функцию SDcardRead. // То есть выводим в Serial монитор всё содержимое файла dimasens.txt if (Serial.read()-48 == 1)SDcardRead(); } // nothing happens after setup*/ } приемник #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> /*-----( Declare Constants and Pin Numbers )-----*/ #define CE_PIN 9 #define CSN_PIN 10 // NOTE: the "LL" at the end of the constant is "LongLong" type const uint64_t pipes[2] = { 0xF0F0F0F000LL, 0xF0F0F0F0FFLL};// адреса каналов приема и передачи радио сигнала //переменная для радио кода int radiocode[1]; /*-----( Declare objects )-----*/ RF24 radio(CE_PIN, CSN_PIN); // Create a Radio /*-----( Declare Variables )-----*/ int joystick[2]; // 2 element array holding Joystick readings void setup() /****** SETUP: RUNS ONCE ******/ { Serial.begin(9600); delay(1000); Serial.println("Nrf24L01 Receiver Starting"); // radio.begin(); // radio.openReadingPipe(1,pipe); // radio.startListening();; radio.begin(); radio.setDataRate(RF24_250KBPS); // Скорость передачи radio.setChannel(100); // Номер канала от 0 до 127 radio.setRetries(15,15); // Кол-во попыток и время между попытками radio.openWritingPipe(pipes[0]); // Открываем канал передачи radio.openReadingPipe(1, pipes[1]); // Открываем один из 6-ти каналов приема radio.startListening(); // Начинаем слушать эфир }//--(end setup )--- void loop() /****** LOOP: RUNS CONSTANTLY ******/ { /* if ( radio.available() ) { // Read the data payload until we've received everything bool done = false; while (!done) { // Fetch the data payload done = radio.read( joystick, sizeof(joystick) ); Serial.print("X = "); Serial.print(joystick[0]); Serial.print(" Y = "); Serial.println(joystick[1]); } } else { Serial.println("No radio available"); } */ // начинаем слушать радио эфир if (radio.available()); bool done = false; while (!done)done = radio.read(radiocode, 1); // если пришёл радио код 101 то digitalWrite(ledPin2, HIGH); if (radiocode[0] == 140) { // Read the data payload until we've received everything bool done = false; while (!done) { // Fetch the data payload done = radio.read( joystick, sizeof(joystick) ); Serial.print("X = "); Serial.print(joystick[0]); Serial.print(" Y = "); Serial.println(joystick[1]); } } else { Serial.println("No radio available"); } }//--(end main loop )--- /*-----( Declare User-written Functions )-----*/ //NONE //*********( THE END )***********
Код (Text): pinMode(53, OUTPUT); if (!SD.begin(53)) { Чисто теоретически проблема может быть в этом. 53 - это штатный CS для меги. Как это работает при использование нескольких устройств на SPI, сказать не могу. Где-то в сети наткнулся, что для SD его лучше не использовать (обоснованно или нет, не знаю, у меня вариантов нет, поскольку для моего SD CS жестко подключен на 4-й пин, ибо Mega IO Shield). Если есть возможность подключить CS SD карты на другой пин, то можно попробовать такой вариант. Но pinMode(53, OUTPUT); лучше в любом случае оставить (тоже почему-то рекомендуется для библиотеки SD всегда делать штатный CS ардуины на OUTPUT вне зависимости от того, используется он, или нет). Если искать другие из "десяти отличий", то еще могу отметить следующее: У себя в коде в начале в качестве профилактики поставил установку обоих CS пинов в OUTPUT и уровня на них HIGH. Код (Text): pinMode(SD_CS_PIN,OUTPUT); digitalWrite(SD_CS_PIN,HIGH); pinMode(RF_CSN_PIN,OUTPUT); digitalWrite(RF_CSN_PIN,HIGH); И еще. Не знаю, влияет ли это на что-либо, но у меня radio.begin вызывается до SD.begin
Большую часть публиковал тут: http://forum.amperka.ru/threads/attiny45-и-nrf24l01.2810/ Но следует учитывать, что мой "передатчик" на ATTiny45 Выкладываю также полный код "приемника"
И еще вопрос на засыпку. SD как подключена и от чего питается? Если они с радиомодулем питаются от контакта 3.3 В на ардуино, то 50 мА им вместе может и не хватить.