Uno + nrf24l01 + MicroSD module: конфликт по SPI
- Войдите на сайт для отправки комментариев
Пнд, 22/08/2016 - 18:29
Добрый день!
Аналогичная тема поднималась про мегу, но там все зашло в тупик.
Имеется связка Uno + nrf24l01 + MicroSD module.
Вот ссылка на схемотехнику модуля: http://www.dfrobot.com/image/data/DFR0229/MicroSD%20ModuleV1.0_Sch.pdf
По отдельности все работает. Но, стоит установить в слот SD карту, как nrf24l01 затыкается. Карта при этом нормально инициализируется.
Ниже проверочный код:
#include <SPI.h> #include <SdFat.h> #include <RF24.h> // пины радиомодуля #define CE_PIN 3 #define CSN_PIN 2 // пин карты #define SD_CARD_PIN A1 typedef unsigned char uchar; const uint64_t pipe = 0xE8E8F0F0E1LL; // структура приемника (внешний датчик шлет посылки в таком формате) struct { uchar addr; // +1 = 1 uchar info; // +1 = 2 float param1; // +4 = 6 float param2; // +4 = 10 float param3; // +4 = 14 float param4; // +4 = 18 float param5; // +4 = 22 float param6; // +4 = 26 uchar err; // +1 = 27 uchar rsrv1; // +1 = 28 unsigned int rsrv2; // +2 = 30 unsigned int rsrv3; // +2 = 32 } data_packet; RF24 radio(CE_PIN, CSN_PIN); // File system object. SdFat sd; void setup() { delay(1000); // на всякий случай настраиваем пины, хотя библиотеки сами все делать умеют pinMode(CE_PIN, OUTPUT); pinMode(CSN_PIN, OUTPUT); pinMode(SCK, OUTPUT); pinMode(MOSI, OUTPUT); pinMode(MISO, INPUT); pinMode(SD_CARD_PIN, OUTPUT); delay(50); Serial.begin(115200); Serial.println("Start"); radio.begin(); // Включение модуля; radio.setAutoAck(true); // Не ждем подтверждения приема radio.setChannel(76); // Установка канала вещания; radio.setRetries(15, 15); // Установка интервала и количества попыток "дозвона" до приемника; radio.setDataRate(RF24_250KBPS); // Установка минимальной скорости; radio.setPALevel(RF24_PA_MAX); // Установка максимальной мощности; radio.openReadingPipe(1, pipe); // Активация данных для приема radio.startListening(); // Слушаем эфир // лишнее, но мало ли digitalWrite(CSN_PIN, HIGH); delay(50); uint32_t t = millis(); if (!sd.cardBegin(SD_CARD_PIN, SPI_HALF_SPEED)) { Serial.println("Card failed"); } else { t = millis() - t; Serial.print("Card init time: "); Serial.print(t); Serial.println("ms"); } // лишнее, но мало ли digitalWrite(SD_CARD_PIN, HIGH); delay(50); } void loop() { if (radio.available()) { // Что-то пришло radio.read(&data_packet, sizeof(data_packet)); // Читаем данные Serial.print(" T1 = "); Serial.print(data_packet.param1, 1); Serial.print("C T2 = "); Serial.print(data_packet.param2, 1); Serial.print("C Us = "); Serial.print(data_packet.param3, 2); Serial.print("V U1 = "); Serial.print(data_packet.param4, 2); Serial.print("V Tint = "); Serial.print(data_packet.param5, 1); Serial.println("C"); } if (millis() % 1000 == 0) { delay(1); // от повтороного срабатывания Serial.println("next second"); } }
Пробовал подтягивать выводы MISO и пины выбора устройств резисторами к 5В (правда номинал великоват 50 кОм) - ничего не поменялось.
Подскажите куда копать, плис.
SPI может использоваться либо одним устройством, либо другим, но не обеими одновременно.
SPI может использоваться либо одним устройством, либо другим, но не обеими одновременно.
Я это прекрасно понимаю. Но у меня в коде как раз все раздельно и используется. К карте я вообще обращаюсь только при ее инциализации. В дальнейшем идет опрос только радиомодуля. Чипселекты у карты и радиомодуля разные.
А по вроемени их развести никак нельзя?
Ну как же, в 61 строке Вы включили слушание, а в 68 лезете к карте. Во время слушания.
Можно ли по логике задачи развести так, чтобы в каждый момент времени работал кто-то один. Если можно. то и сделайте. А нельзя - переводите кого-нибудь в софт-SPI
А по вроемени их развести никак нельзя?
Так я там даже задержки на 50 мсек воткнул между инициализацией радиомодуля и SD-карты.
После инициализации карты я к ней вообще больше не обращаюсь. Только радиомодуль в loop() опрашиваю.
Вот и выясните, зачем карта лезет не в свое время.
Ну как же, в 61 строке Вы включили слушание, а в 68 лезете к карте. Во время слушания.
Можно ли по логике задачи развести так, чтобы в каждый момент времени работал кто-то один. Если можно. то и сделайте. А нельзя - переводите кого-нибудь в софт-SPI
Так я радиомодуль в режим прослушки включил и все. Чипселект возводится у него в "1". Он слушает же независисмо от состояния шины SPI. Только когда я вызываю radio.available(), контроллер вновь к нему обращается по SPI. Или я себе это не правильно представляю?
К тому же карта инициализируется уже после радиомодуля. И инициализация проходит успешно.
Вот и выясните, зачем карта лезет не в свое время.
Осциллограф утверждает, что чипселект карты только на этапе ее инициализации падает в "0". В дальнейшем всегда в "1" возведен.
Дергается только чипселект карты при попытке ее опроса.
В общем все заработало.
А косяк был в том, что при инициализации портов на вывод они устанавливались "0". И конфликт был на этапе инициализации радиомодуля. А не при опросе модуля в дальнейшем.
Всем спасибо!