SPI в режиме SLAVE
- Войдите на сайт для отправки комментариев
Всем добрый день!
Возникла задача передать данные от Arduino Nano на Jetson TX2 по SPI. SPI на Jetson удалось запустить только в режиме мастер. Поэтому Arduino стал слэйвом. С помощью кода ниже удалось получить данные в обратную сторону (Jetson --> Arduino).
Вопрос: как передать данные от Arduino (SPI Slave) в Jetson (SPI Master)? Насколько я понимаю, во время транзакции одновременно передаются данные и по MISO и по MOSI и мастер может принять данные от слэйва. Но всё, что ни пробовал, результата не дало. Вот код Ардуино:
#include <SPI.h> #define SPI_SS 10 void slaveSPI_Setup() { SPI.setDataMode(SPI_MODE0); //не влияет на работу SPI.setBitOrder(MSBFIRST); //не влияет на работу SPI.setClockDivider(SPI_CLOCK_DIV4); //не влияет на работу //pinMode(MISO, OUTPUT); //при добавлении приводит к искажению принятых данных //pinMode(SPI_SS, INPUT); //не влияет на работу SPCR |= _BV(SPE); // включение SPI в режиме SLAVE } /// Функция для чтения данных unsigned char slaveSPI_read() { while(!(SPSR & (1<<SPIF))); return SPDR; } void setup() { Serial.begin(112500); slaveSPI_Setup(); } void loop() { unsigned char ch = slaveSPI_read(); Serial.println(ch); }
Интересно, что настройки "SPI.set..." никак не влияют на работу, если их закомментить. А вот если раскомментить "pinMode(MISO, OUTPUT)" - начинаю принимать не те числа, что отправляю, хотя в описании SPI везде написано, что в режиме SLAVE MISO нужно обязательно определить как OUTPUT.
В общем, прошу подсказать, что нужно добавить в этот код, чтобы Arduino ещё и отправлял данные мастеру.
Есть пример двустороннего обмена между двумя ардуинами. Одна - мастер, а другая слейв. В примере слейв возвращает мастеру длину принятой на данный момент строки.
Но если Вам это трудно понимать, поищите библиотеку SPI которая понимает режим slave, их много и они легко ищутся.
Есть пример двустороннего обмена между двумя ардуинами. Одна - мастер, а другая слейв. В примере слейв возвращает мастеру длину принятой на данный момент строки.
Спасибо! Немного подредактировал под свою задачу Ваш код (по сути убрал лишнее, чтобы проще было воспринимать). Я убрал всю обработку строк, т.к. принимаю от мастера число (и число же хочу отправить мастеру обратно) . Вот, что получилось:
С помощью такой программы я отлично принимаю от Master устройства биты, но в ответ Slave устройство ничего не передаёт. Проверил это в том числе осциллографом - на выводе MISO пусто (а точнее какой-то один импульс, вне зависимости от того, что я присваиваю SPDR).
Так вот мой изначальный вопрос вот в чём: как сделать так, чтобы Slave начал отвечать мастеру?
1.
запустите мою программу прямо как она есть - безо всяких переделок и убедитесь в том, что там слейв нормально отвечает и мастер принимает ответы
2.
после этого, начинайте вносить свои правки, но все сразу, а "по чайной ложке", после каждой ложки проверяя не сломалось ли, по прежнему ли работает.
3.
Таким образом Вы поймёте где Вы её ломаете, локализуете до мельчайшего шага: вот так ещё работало, а вот тут дунул и ...
4.
думаю, Вы тогда сумеете победить, а не сумеете - выкладывайте два скетча "ещё работающий" и "уже не работающий" разница между которыми минимальна - посмотрим что там.
ТС разберись, что такое SPI и тогда поймёшь как это реализовать.
Подскажу , ключевое слово "сдвиговый регистр"
https://youtu.be/85Lhi_824ks
1.
запустите мою программу прямо как она есть - безо всяких переделок и убедитесь в том, что там слейв нормально отвечает и мастер принимает ответы
Согласен. Прошу для чистоты эксперимента поделиться библиотекой "Printing.h", не получилось её найти.
Kakmyc, спасибо, видео очень хорошее. Хотя, это я уже знал.
Если использовать вот такой простой код (см. ниже), то SLAVE отвечает мастеру. Казалось бы - работает, НО! Примерно 5-10% посылок приходят не верными (например, вместо "10" приходит "5" - похоже на сдвиг посылки на 1 бит). Пробовал пару Arduino-Arduino, Arduino (slave)-Jetson(master) - результат тот же. Причём периодичность "кривых" посылок не закономерная.
Ни в одном описании на SPI не удалось найти информации, что я делаю не так, и во всех примерах код примерно такой же.
Судя по Вашему комментарию, Вы уже очень хорошо разобрались в вопросе касательно SPI. Можете подсказать, что не так с моим кодом? В виде подсказки с ключевым словом, или, может, просто скажете, что я делаю не так.
Разве прежде чем писать в регистр не надо проверять готовность SPI? Там, в регистре статуса вроде какой-то битик везде ещё проверяют.
Согласен. Прошу для чистоты эксперимента поделиться библиотекой "Printing.h", не получилось её найти.
https://github.com/elilitko/ArduinoStuff/tree/master/Printing
Разве прежде чем писать в регистр не надо проверять готовность SPI? Там, в регистре статуса вроде какой-то битик везде ещё проверяют.
Перед чтением - да, обязательно. Но при ответе слэйва это не помогает. Странно именно то, что в целом-то работает, если не считать процент кривых посылок. А как эти кривые посылки лечить - пока не понятно.
https://github.com/elilitko/ArduinoStuff/tree/master/Printing
Вопрос решён! Большое спасибо за помощь. Ваша программа так же не стабильно работала, пока я не объединил GND контроллеров. Раньше я не встречал на то прямых указаний. В общем, ещё раз спасибо!
P.S.: ранее я пробовал объединить пины GND у Ардуино и у Jetson, но у меня в тот момент почему-то сразу погас экран монитора, подсоединённого к Jetson, и я отказался от этой идеи. В этот раз объединил - и всё норм. Ура.
Да, уж, блин! "Уж", если чё, - это зверь такой.
Леонид Филатов как-то писал:
:-)
Какая устойчивая система. Нет одного провода из четырех, а процент ошибок всего лишь 10%.
...пока я не объединил GND контроллеров. Раньше я не встречал на то прямых указаний.
В любом случае, если ты хочешь заниматься Ардуино, тебе нужно прочитать учебник физики за 8 класс. Без этого - никак.
PS. Для ученика средних/младших классов у тебя очень хороший русский.
Все 4 провода на месте, GND - пятый.
...пока я не объединил GND контроллеров. Раньше я не встречал на то прямых указаний.
В любом случае, если ты хочешь заниматься Ардуино, тебе нужно прочитать учебник физики за 8 класс. Без этого - никак.
PS. Для ученика средних/младших классов у тебя очень хороший русский.
Да, я мало работал с контроллерами, и могу не знать каких-то вещей, кому-то кажущихся элементарными. И предположил, что подобные форумы существуют как раз для того, чтобы общаться по возникающим вопросам, какими бы они не были.
Но, вижу, что многие тут предпочитают выражать надменность и собственную важность.
Спасибо за ваши советы и мнения по поводу того, что мне нужно прочитать. Было бы лучше, если бы так активно выражались по теме вопроса.
Есть пример двустороннего обмена между двумя ардуинами. Одна - мастер, а другая слейв. В примере слейв возвращает мастеру длину принятой на данный момент строки.
Жалко, что для каких то таких ответов на вопрос не создан FAQ на форуме.
P.S. Посмотрел сколько созданных топиков в разделе Программирования - около 500! Карл.
Кто их будет просматривать и при таком дизайне поисковика на форуме.
Да, я мало работал с контроллерами, и могу не знать каких-то вещей, кому-то кажущихся элементарными.
Тот факт, что электрический ток может протекать только по замкнутой цепи, никакого отношения к специфики контроллеров отношения не имеет.
Спасибо за ваши советы и мнения по поводу того, что мне нужно прочитать. Было бы лучше, если бы так активно выражались по теме вопроса.
Но скажу честно, откровенная ложь меня всегда шокирует. Особенно в тех случаях, когда лжец в принципе не получает каких-либо "бонусов" от своей лжи. Возникает вопрос: "Зачем!?!"
PS. "-1" на Вашем сообщении - не мой. Делайте выводы.