UNO и несколько устройств на шине SPI

Тема в разделе "Arduino & Shields", создана пользователем snake32, 22 апр 2014.

  1. snake32

    snake32 Нерд

    Доброго времени!
    Решил поэксперементировать с 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 соответствует активному устройству.
    Здесь всё правильно понял?
     
  2. geher

    geher Гуру

    В общем почти правильно. Но только почти.
    На этот шестиконтактный разъем выведены только пины 11-13 (MOSI, MISO и SCK), +5, земля и Reset. Соответственно, после подключения к ним SPI, для других целей 11-13 лучше не использовать.. А если использовать, то озаботиться, чтобы при этом все SPI устройства имели HIGH на своих пинах SS. И еще вопрос, гарантирует ли это все устройства от приема "мусора", особенно если задействовать 13 - SCK

    Насколько я помню, только у Arduino Micro и Leonardo для SPI отдельные выходы, не связанные с цифровыми пинами.

    Вроде все верно
     
    snake32 нравится это.
  3. snake32

    snake32 Нерд

    Спасибо, за ответ. У меня UNO. MOSI, MISO и SCK лучше не трогать на цифровых пинах ардуино. Завтра попробую это дело законектить через ICSP(кроме SS больше же ничего не нужно?). Надеюсь ничего не сгорит.
    Тут кстати ещё небольшая проблемка: паял я последний раз в классе 9. Посоветуйте мне паяльник для пайки колодок к плате. Бюджетный вариант с тонким жалом иначе запаяю всё нахрен. Спасибо.
     
  4. geher

    geher Гуру

    Про паяльник - это уже не ко мне. Я такой "специалист" в пайке, что аж самому страшно, на свое дело глядючи.
    Но, как ни странно, в результате все работает.
    Пользуюсь китайским "пистолетом" от известной фирмы Noname на 25-100W с кнопкой включения большей мощности и заостренным жалом.
    Может быть оно неправильно, но паяю так: подношу одновременно тонкую "проволоку" припоя (припой сразу с флюсом) и острие жала паяльника к ноге, которую собираюсь запаять , давлю на кнопку мощности, подаю за секунду несколько миллиметров припоя в точку пайки, и он сам распределяется каплей (иногда даже аккуратной) на ножке и отверстии.
     
    snake32 нравится это.
  5. derver

    derver Нуб

    помогите пожалуйста

    на меге подключаю sd card и nrf24l01 по шине spi начинает конфликтовать nrf24l01 а отдельно все работает

    что надо при этом сделать
     
  6. geher

    geher Гуру

    У меня на меге то же самое не конфликтует (SD на Mega IO Shield).
    Для корректной работы нужно в один момент времени подавать LOW только на одну из линий селектора (CS, SS, CSN), соответствующую устройству, с которым и идет в данный момент обмен по SPI. На остальных должен быть HIGH.
    Линии эти, естественно, должны быть подключены к отличным друг от друга пинам, и подозреваю, что желательно, чтобы они были отличны от 10-го пина. который (как пишут для SD должен быть обязательно настроен как OUTPUT, но не использоваться).
    Пока устройства не используются, желательно, чтобы на всех линиях селектора был HIGH, дабы устройства "знали", что в данный момент не обмениваются данными про SPI.

    Кстати, теоретически возможно, что проблема совсем не в SPI, а в питании по 3.3 В, на которое непосредственно на NRF24L01 рекомендуют напаять конденсатор (особенно на меге), или следует все запитать от отдельного источника (или регулятора) .
     
  7. derver

    derver Нуб

    кондер запаял
    отдельно работают
    передатчик

    #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 )***********
     
  8. derver

    derver Нуб

    но вместе не работают
     
  9. geher

    geher Гуру

    Код (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
     
  10. derver

    derver Нуб

    все попробовал не помогает
    geher может скинешь твои передатчики и приемники
     
  11. geher

    geher Гуру

    Вложения:

    • megaclock.zip
      Размер файла:
      6,3 КБ
      Просмотров:
      591
  12. derver

    derver Нуб

    спасибо за файл можно и другой файл чтоб попробовать запустить оба
     
  13. geher

    geher Гуру

    Другой - это какой?
     
  14. geher

    geher Гуру

    И еще вопрос на засыпку. SD как подключена и от чего питается?
    Если они с радиомодулем питаются от контакта 3.3 В на ардуино, то 50 мА им вместе может и не хватить.
     
  15. derver

    derver Нуб

    пробовал sd подключить как на 5 вольт и на 3.3 вольта эфект тот же
     
  16. derver

    derver Нуб

    ваш файл перелапатил и переделал немножко есть изминения но всеравно с ошибкой