Подключение нескольких устройств по SPI
- Войдите на сайт для отправки комментариев
Вс, 14/07/2013 - 17:51
Гуглил и читал (_http://robocraft.ru/blog/arduino/541.html), но так и не понял до конца логику работы нескольких устройств по SPI
предположим у меня есть
1. uno/mega
2. sd module
3. nrf21
4. lcd 5110
5. enc28j60
все они (2-5) подключаются по SPI
обязательно ли использовать сдвиговый регистр или есть какие-то тонкости для подключения без этого огорода?
Спасибо.
никаких сдивговых регистров не надо... 3 линии общие для всех устройств и допольнительно по одной для выбора активного устройства
нето гуглите.... SPI интерфейс погуглите
я бы не советовал столько устройств вешать на SPI.. поищите варианты без SPI... работать то оно конечно будет... но все это будет медленно и печально...
чему там тормозить
чему там тормозить
думаю самым заметным тормозом будет экран :) хотя конечно от размера экрана будет зависить.. но я не настаиваю, каждый имеет право сам наступить на грабли :)
никаких сдивговых регистров не надо... 3 линии общие для всех устройств и допольнительно по одной для выбора активного устройства
нето гуглите.... SPI интерфейс погуглите
смотрю на сайте http://arduino.cc/en/Reference/SPI
SS на 10(uno) и 53(mega) ... таки это можно как-то поменять или
вопрос в чем?
смотрю на сайте http://arduino.cc/en/Reference/SPI
SS на 10(uno) и 53(mega) ... таки это можно как-то поменять или
на что поменять? зачем?
53 пин это что бы сказать меге что она будет подчиненой на SPI и зачем его куда то менять?
могу я подключить SS на:
2. sd module - 3 pin
3. nrf21 - 4 pin
4. lcd 5110 - 5 pin
5. enc28j60 - 6 pin
и получится им так рулить?
получится
SPI есть железный, есть софтверный
все перечисленные вами устройства отлично работают и так и так.
смотрите не только на модули, но и на библиотеки, которые есть - некоторые библиотеки работают только по железному SPI, некоторые только по софтверному. В случае с жедезным SPI цепляться нужно обязательно на выводы MISO/MOSI/SCK которые обозначены на MCU (и привязаны к конктртеным выводам ардуино). В случае софтверного SPI в качестве MISO/MOSI/SCK можно назначить практически любые порты ввода-вывода, в этом случае при необходимости разные устройства можно подключать к разным выводам MCU
наиболее правильный вариант вам уже порекомендовали - MISO/MOSI/SCK всех устройств подключить паралелльно к MCU, выводы Chip Select к каждому устройству - отдельный вывод MCU
но могут быть нюансы - некоторые SPI устройства не поддерживают в полной мере SPI и могут не работать с другими устройствами SPI на той же шине
я бы не советовал столько устройств вешать на SPI.. поищите варианты без SPI... работать то оно конечно будет... но все это будет медленно и печально...
от количества устройств на шине SPI его производительность не зависит! В любом случае МК в один момент времени осушествляет обмен только с одним устройством, остальные находятся в спящем режиме
думаю самым заметным тормозом будет экран :) хотя конечно от размера экрана будет зависить.. но я не настаиваю, каждый имеет право сам наступить на грабли :)
5110 отлично работает как небольшой дисплейчик. конечно видео на него не получится выводить, но для более менее статических задач никаких тормозов не заметно
от количества устройств на шине SPI его производительность не зависит! В любом случае МК в один момент времени осушествляет обмен только с одним устройством, остальные находятся в спящем режиме
Вы выворачиваете не в ту сторону.... и многие могут вас понять не правильно..
Попробуем аналогии...
Это из серии что если взять одну трубу и подключить к ней краны.... от количества кранов производительность трубы не зависит... но вот производительность кранов зависит от размера трубы и количества подлюченых кранов...
просто экран 320х240 на 16 битной шине и мегой 2560, заметно как промаргивается когда несколько строк переписываеш, не то что бы это выглядело страшно, но создается впечатление чего то собраного на коленке.. а SPI помноженый даже на мегу2560 скорее всего будет жалкое зрелище, особенно если кроме дисплея там еще будет висет куча всего... но возможно что кого то это устроит, хозяин барин...
Вы выворачиваете не в ту сторону.... и многие могут вас понять не правильно..
Попробуем аналогии...
Это из серии что если взять одну трубу и подключить к ней краны.... от количества кранов производительность трубы не зависит... но вот производительность кранов зависит от размера трубы и количества подлюченых кранов...
производительность SPI не завсит от количества подключенных устройств - ваш пример с кранами не совсем подходит, тут скорее надо говорить о том, что есть три крана с водой, пивом и квасом и одна труба. Смешивать нельзя)) количество воды через трубу в секунду не зависит от того, что есть еще квас и пиво, но если в течении часа проливать все три, то воды можно пролить только 1/3 объма :)
в конце концов все упирается в производительность МК - это ему через SPI пропихивать данные. Зависит от задачи, для многих задач можно все на SPI повесить, для каких то задач в таком варианте не хватит производительности МК
производительность SPI не завсит от количества подключенных устройств - ваш пример с кранами не совсем подходит, тут скорее надо говорить о том, что есть три крана с водой, пивом и квасом и одна труба. Смешивать нельзя)) количество воды через трубу в секунду не зависит от того, что есть еще квас и пиво, но если в течении часа проливать все три, то воды можно пролить только 1/3 объма :)
Хых, пишите проще.. а то многие вас не поймут... мой пример с трубами подходит идеально. вы его просто расширили что в каждый кран нужно прокачивать свой вид жидкости... и SPI это очень маааааленькая труба... обьем прокачки через нее все же сильно ограничен и чем больше кранов прикручиваеш тем меньше прокачать можно в каждый отдельный кран... :)
Но в целом как бы, если есть возможность выбрать другие шины, то зачем все пихать в одну?
мы отвлеклись от изначального вопроса - у человека устройства с SPI - это данность. Предлагать ему поменять устройства на другие не совсем правильно. Собственно ответы дал выше michail
мы отвлеклись от изначального вопроса - у человека устройства с SPI - это данность. Предлагать ему поменять устройства на другие не совсем правильно. Собственно ответы дал выше michail
согласен про отвлеклись.. но тут как бы звучало ПРЕДПОЛОЖИМ.. теость устройст еще нет и человек раздумывает брать или что то заменить...
Да все ясно SCK MISO MOSI паралельно, а CS отдельно. Просто нужно перед обращением к устройству дергать его CS (установив на всех 1 на нужном 0).
А регистр только если у вас не достаточно свободных ног на все устройства.
Итак, я подключил к меге nrf21 и ENC28J60
что имеем, были практически в лоб объеденены 2 примера (результат приведен ниже). Проблема очень странная и для меня не понятная. В строке 449 формируется ответ на запрос, дык вот как мне его сформировать в строке на основе данных от nrf21 и передать в браузер.
При попыте засунуть туда переменную char[]/string падает...
Что я делаю не так?
спасибо
/* Copyright (C) 2011 James Coliz, Jr. <maniacbug@ymail.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. */ /** * Example of a sensor network * * This sketch demonstrates how to use the RF24Network library to * manage a set of low-power sensor nodes which mostly sleep but * awake regularly to send readings to the base. * * The example uses TWO sensors, a 'temperature' sensor and a 'voltage' * sensor. * * To see the underlying frames being relayed, compile RF24Network with * #define SERIAL_DEBUG. * * The logical node address of each node is set in EEPROM. The nodeconfig * module handles this by listening for a digit (0-9) on the serial port, * and writing that number to EEPROM. */ #include <avr/pgmspace.h> #include <RF24Network.h> #include <RF24.h> #include <SPI.h> #include <Tictocs.h> #include <Button.h> #include <TictocTimer.h> #include "nodeconfig.h" #include "sleep.h" #include "S_message.h" #include "printf.h" #include <EtherCard.h> //-----eth #define STATIC 0 // set to 1 to disable DHCP (adjust myip/gwip values below) #if STATIC // ethernet interface ip address static byte myip[] = { 192,168,1,200 }; // gateway ip address static byte gwip[] = { 192,168,1,1 }; #endif // ethernet mac address - must be unique on your network static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; byte Ethernet::buffer[500]; // tcp/ip send and receive buffer //-----eth char page[] = "test123123efwasdf a asdf asdfq23r ewfadfw efqwef asdfa w"; // This is for git version tracking. Safe to ignore #ifdef VERSION_H #include "version.h" #else const char program_version[] = "Unknown"; #endif // Pin definitions #ifndef PINS_DEFINED #define __PLATFORM__ "Getting Started board" // Pins for Eth + Nrf21 const int SS_nrf21 = 14; const int SS_eth = 1; // Pins for radio const int rf_ce = 8; const int rf_csn = 7; // Pins for sensors const int temp_pin = A2; const int voltage_pin = A3; // Pins for status LED, or '0' for no LED connected const int led_red = 22; const int led_yellow = 23; const int led_green = 25; // Button to cont=rol modes const int button_a = 4; // What voltage is a reading of 1023? const unsigned voltage_reference = 5 * 256; // 5.0V #endif RF24 radio(rf_ce,rf_csn); RF24Network network(radio); // Our node configuration eeprom_info_t this_node; // How many measurements to take. 64*1024 = 65536, so 64 is the max we can fit in a uint16_t. const int num_measurements = 64; // Sleep constants. In this example, the watchdog timer wakes up // every 4s, and every single wakeup we power up the radio and send // a reading. In real use, these numbers which be much higher. // Try wdt_8s and 7 cycles for one reading per minute.> 1 const wdt_prescalar_e wdt_prescalar = wdt_4s; const int sleep_cycles_per_transmission = 1; // Non-sleeping nodes need a timer to regulate their sending interval Timer send_timer(2000); // Button controls functionality of the unit Button ButtonA(button_a); // Long-press button Button ButtonLong(button_a,1000); /** * Convenience class for handling LEDs. Handles the case where the * LED may not be populated on the board, so always checks whether * the pin is valid before setting a value. */ class LED { private: int pin; public: LED(int _pin): pin(_pin) { if (pin > 0) { pinMode(pin,OUTPUT); digitalWrite(pin,LOW); } } void write(bool state) const { if (pin > 0) digitalWrite(pin,state?HIGH:LOW); } void operator=(bool state) { write(state); } }; /** * Startup LED sequence. Lights up the LEDs in sequence first, then dims * them in the same sequence. */ class StartupLEDs: public Timer { private: const LED** leds; const LED** current; const LED** end; bool state; protected: virtual void onFired(void) { (*current)->write(state); ++current; if ( current >= end ) { if ( state ) { state = false; current = leds; } else disable(); } } public: StartupLEDs(const LED** _leds, int _num): Timer(250), leds(_leds), current(_leds), end(_leds+_num), state(true) { } }; /** * Calibration LED sequence. Flashes all 3 in unison */ class CalibrationLEDs: public Timer { const LED** leds; const LED** end; bool state; protected: void write() { const LED** current = end; while (current-- > leds) (*current)->write(state); } virtual void onFired() { state = ! state; write(); } public: CalibrationLEDs(const LED** _leds, int _num, unsigned long duration = 500): Timer(duration), leds(_leds), end(_leds+_num), state(false) { Timer::disable(); } void begin() { Updatable::begin(); } void reset() { state = true; write(); Timer::reset(); } void disable() { state = false; write(); Timer::disable(); } }; LED Red(led_red), Yellow(led_yellow), Green(led_green); const LED* leds[] = { &Red, &Yellow, &Green }; const int num_leds = sizeof(leds)/sizeof(leds[0]); StartupLEDs startup_leds(leds,num_leds); CalibrationLEDs calibration_leds(leds,num_leds); // Nodes in test mode do not sleep, but instead constantly try to send bool test_mode = false; // Nodes in calibration mode are looking for temperature calibration bool calibration_mode = false; void setup(void) { // // Print preamble // Serial.begin(57600); // --eth-- Serial.println("\n[backSoon]"); if (ether.begin(sizeof Ethernet::buffer, mymac, 53) == 0) Serial.println( "Failed to access Ethernet controller"); #if STATIC ether.staticSetup(myip, gwip); #else if (!ether.dhcpSetup()) Serial.println("DHCP failed"); #endif ether.printIp("IP: ", ether.myip); ether.printIp("GW: ", ether.gwip); ether.printIp("DNS: ", ether.dnsip); // --eth-- printf_begin(); printf_P(PSTR("\n\rRF24Network/examples/sensornet/\n\r")); printf_P(PSTR("PLATFORM: " __PLATFORM__ "\n\r"),program_version); printf_P(PSTR("VERSION: %s\n\r"),program_version); // // Pull node address out of eeprom // // Which node are we? this_node = nodeconfig_read(); // // Prepare sleep parameters // // Only the leaves sleep. Nodes 01-05 are presumed to be relay nodes. if ( ! this_node.relay ) Sleep.begin(wdt_prescalar,sleep_cycles_per_transmission); // // Set up board hardware // ButtonA.begin(); ButtonLong.begin(); // Sensors use the stable internal 1.1V voltage #ifdef INTERNAL1V1 analogReference(INTERNAL1V1); #else analogReference(INTERNAL); #endif // Prepare the startup sequence send_timer.begin(); startup_leds.begin(); calibration_leds.begin(); // // Bring up the RF network // SPI.begin(); radio.begin(); network.begin(/*channel*/ 92, /*node address*/ this_node.address); } void NRF21(void) { // Update objects theUpdater.update(); // Pump the network regularly network.update(); // If we are the base, is there anything ready for us? while ( network.available() ) { // If so, grab it and print it out RF24NetworkHeader header; S_message message; network.read(header,&message,sizeof(message)); printf_P(PSTR("%lu: APP Received #%u %s from 0%o\n\r"),millis(),header.id,message.toString(),header.from_node); } // If we are the kind of node that sends readings, AND it's time to send // a reading AND we're in the mode where we send readings... if ( this_node.address > 0 && ( ( Sleep && ! test_mode ) || send_timer.wasFired() ) && ! calibration_mode && ! startup_leds ) { // Transmission beginning, TX LED ON Yellow = true; if ( test_mode ) { Green = false; Red = false; } int i; S_message message; // Take the temp reading i = num_measurements; uint32_t reading = 0; while(i--) reading += analogRead(temp_pin); // Convert the reading to celcius*256 // This is the formula for MCP9700. // C = reading * 1.1 // C = ( V - 1/2 ) * 100 message.temp_reading = ( ( ( reading * 0x120 ) - 0x800000 ) * 0x64 ) >> 16; // Take the voltage reading i = num_measurements; reading = 0; while(i--) reading += analogRead(voltage_pin); // Convert the voltage reading to volts*256 message.voltage_reading = ( reading * voltage_reference ) >> 16; printf_P(PSTR("---------------------------------\n\r")); printf_P(PSTR("%lu: APP Sending %s to 0%o...\n\r"),millis(),message.toString(),0); // Send it to the base RF24NetworkHeader header(/*to node*/ 0, /*type*/ test_mode ? 's' : 'S'); bool ok = network.write(header,&message,sizeof(message)); if (ok) { if ( test_mode ) Green = true; printf_P(PSTR("%lu: APP Send ok\n\r"),millis()); } else { if ( test_mode ) Red = true; printf_P(PSTR("%lu: APP Send failed\n\r"),millis()); } // Transmission complete, TX LED OFF Yellow = false; if ( Sleep && ! test_mode ) { // Power down the radio. Note that the radio will get powered back up // on the next write() call. radio.powerDown(); // Be sure to flush the serial first before sleeping, so everything // gets printed properly Serial.flush(); // Sleep the MCU. The watchdog timer will awaken in a short while, and // continue execution here. Sleep.go(); } } // Button unsigned a = ButtonA.wasReleased(); if ( a && a < 500 ) { // Pressing the button during startup sequences engages test mode. // Pressing it after turns off test mode. if ( startup_leds ) test_mode = true; else if ( test_mode ) { test_mode = false; Green = false; Red = false; } else if ( calibration_mode ) { calibration_mode = false; test_mode = true; calibration_leds.disable(); } } // Long press if ( ButtonLong.wasPressed() && test_mode ) { test_mode = false; calibration_mode = true; calibration_leds.reset(); } // Listen for a new node address nodeconfig_listen(); } void Eth(void) { /*String test1 = "<hr>asd</hr>"; char test[1000]; test1.toCharArray(test, sizeof(test1));*/ // wait for an incoming TCP packet, but ignore its contents if (ether.packetLoop(ether.packetReceive())) { memcpy_P(ether.tcpOffset(), PSTR("fgnsghhsth strhsbrsersdgsd dfgsdfg dsfg sdfgsdf gsdfg sdfg sdfgs dfgs dfg sdfgs dfgs dfgsdfgert ergserr123") , sizeof page); ether.httpServerReply(sizeof page - 1); } } void loop(void) { digitalWrite(SS_eth, HIGH); digitalWrite(SS_nrf21, LOW); NRF21(); digitalWrite(SS_eth, LOW); digitalWrite(SS_nrf21, HIGH); Eth(); } // vim:ai:cin:sts=2 sw=2 ft=cppmitekg,
1. Какая мега? 2560?
2. Два примера успешно работают по отдельности?
3. Какая ошибка-то? "Переменная ether не определена" ?
1. мега 2560
2. Да, по отдельности все ок. Пример который я привел работает. Проблема в том что оно ругается при попытке определить переменную
charpage[]PROGMEM="test123123efwasdf a asdf asdfq23r ewfadfw efqwef asdfa w";и выдает ошибку, только когда объединяю скетчи.
3. ругается на 449 строку, если попытаться вместо строки скормить переменную.
спасибо
2. как ругается? какую ошибку?
3. как ругается?
https://github.com/maniacbug/RF24/blob/master/RF24_config.h
Ругается на 45 строку. Как я понял в ней переопределена схема работы с PROGMEM.
И как с ней правильно работать после этого?
Попробуйте убрать все PROGMEM из скетча. Памяти у такой меги должно хватить ещё на многое.
Не так просто убрать весь PROGMEM, он в куче библиотек прошит.
А как можно его правильно использовать с учетом того как оно переопределено?
Не получается. У кого есть опыт объединения в одной меге работу с nrf21 и ENC28J60 на базе
RF24Network иEtherCard.hhttp://arduino.ru/forum/obshchii/podklyuchenie-neskolkikh-ustroistv-po-spi
Конфликтует переопределнный PROGMEM.
Очень прошу помощи. Спасибо
Товарищ, что такое "nrf21"? На самом деле, ты имел в виду слово RF24 (название библиотеки) или nrf24l01+ (название чипа). Вероятное решение твоей проблемы: http://forum.jeelabs.net/node/1531.html
toc, Спасибо!! помогло. то что надо))
да, конечно, имел ввиду nrf24.
Еще раз, спасибо!
Помогите. Таже проблема, но немогу понять что нуждно зделать.
Почитал тему и понял, что меня эта проблема тоже посетила.
Собираю Server_Nrf24l01 с возможность трансляции Ethernet.
Столкнулся с проблемой переключения между W5100 и Nrf24l01.
Хочу чтобы 2 устройства откликались максимально быстро.
Поможет вот такая схемка:
Вот думаю сделать следующую связку:
Nrf24l01+Arduino(клиент_1) <-- беспроводная -->
Nrf24l01+Arduino(клиент_2) <-- беспроводная --> Nrf24l01+Arduino(сервер)
Nrf24l01+Arduino(клиент_3) <-- беспроводная -->
и т.д.
Тут вроде все понятно.
Это все сделано сервер прикрасно управляет и получает данные с клиентов.
Самое интересное начинается дальше...
Если на сервер вешать 2 SPI устройства скорость опроса шилдов жутко падает. Сервер не успевает послушать клиентов и обрабатывать запросы с Ethernet.
Вот думаю стоит ли делать такую связку???
Nrf24l01+Arduino(сервер) <-- rx/tx --> W5100+Arduino(web-сервер) <=== запросы
или данная схема не даст эффекта:
- постоянная прослушка клиентов?
- постоянная прослушка Ethernet?
Или может есть готовые решения и я зря ломаю голову
Или может есть готовые решения и я зря ломаю голову
конечно есть. возмите процесор помощней :)
У меня связка на одной ардуине нормально работали вместе и nrf24 и wiznet5100
У меня связка на одной ардуине нормально работали вместе и nrf24 и wiznet5100
можно взглянуть на скетч если не жалко?
Или может есть готовые решения и я зря ломаю голову
конечно есть. возмите процесор помощней :)
А готовые решения на Arduino???
А готовые решения на Arduino???
ну я могу только гадать что именно вы там используете..
попробуйте хотя бы мега 2560
Использую в домашней автоматизации.
Куча беспроводных клиентов (планирую более 5 клиентов) скидывают/получают данные на беспроводной сервер.
В свою очередь беспроводной сервер должен передавать данные по Ethernet на сервер на компе и получать данные для управления клиентами через Ethernet
Вот саму беспроводную связь организовал, а дальше начинаю нагружать беспроводной сервер Ethernet протоколом и появляются баги, то страница недоступна (сервер получает данные от клиентов, то наоборот)
для тех кто в танке..
http://arduino.ru/Hardware
эх ты сколько разных ардуино бывает :)
да Arduino 2560 + W5100 Ethernet
У меня связка на одной ардуине нормально работали вместе и nrf24 и wiznet5100
можно взглянуть на скетч если не жалко?
на телефоне под рукой нет кода
вы выложите свой и еще опишите признаки/критерии того, что ваша программа не справляется, так же условия при которых это происходит
могу предположить, что у вас есть участки кода с долгим ожиданием. Случаем на mega2560 временные задержки не используете? Датчика типа ds18b20 нет?
Приемник на базе mega2560+w5100+nfr24l01 должен только слушать радиоканал (передавать полученые данные через Ethernet) и управлять беспроводными клиентами из локальной сети и все!
Доброго дня!
Собираю контроллер для автомойки самообслуживания. В принципе уже есть рабочий вариант, но решил добавить запись логов на SD карту.
В составе рабочего модуля:
arduino Leonardo.
7segment shield - 2шт - каждый на отдельной плате с процессором
RC522 - RFID считыватель для карт
Купюроприёмник - выдаёт имульсы.
Все шилды подключены по "железному" SPI паралельно т.к. на леонардо они не дублируются на выводы и вообще чтоб пины не забивать У каждого свой SS.
Вот работающий скетч:
Теперь подключил Data logging shield v1.0 (на нём шина SPI заточена под UNO, я перепаял ноги 11,12,13 на железные выводы miso/mosi/sck)
Написал отдельный скетч на базе примера из библиотеки SD для сохранения в файл данных переменной Fullsumm и чтения этих данных из файла при перезагрузке контроллера.
вот скетч:
/* SD card read/write This example shows how to read and write data to and from an SD card file The circuit: * SD card attached to SPI bus as follows: ** UNO: MOSI - pin 11, MISO - pin 12, CLK - pin 13, CS - pin 4 (CS pin can be changed) and pin #10 (SS) must be an output ** Mega: MOSI - pin 51, MISO - pin 50, CLK - pin 52, CS - pin 4 (CS pin can be changed) and pin #52 (SS) must be an output ** Leonardo: Connect to hardware SPI via the ICSP header created Nov 2010 by David A. Mellis modified 9 Apr 2012 by Tom Igoe This example code is in the public domain. */ #include <SPI.h> #include <SD.h> File myFile; // change this to match your SD shield or module; // Arduino Ethernet shield: pin 4 // Adafruit SD shields and modules: pin 10 // Sparkfun SD shield: pin 8 const int chipSelect = 10; //byte FullSumm = 3000; int FullSumm = 30000; byte t1; byte t2; int t3; // byte start; int start; void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } Serial.print("Initializing SD card..."); // On the Ethernet Shield, CS is pin 4. It's set as an output by default. // Note that even if it's not used as the CS pin, the hardware SS pin // (10 on most Arduino boards, 53 on the Mega) must be left as an output // or the SD library functions will not work. pinMode(SS, OUTPUT); if (!SD.begin(chipSelect)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. // мои код myFile = SD.open("test.txt"); //открывает файл test.txt //Money = buffer[0]*256+buffer[1]; //считывание денег из блока А и записть их в переменную Money // myFile.seek(0); // t1 = myFile.read(); // Serial.println(t1); // t2 = myFile.read(); // Serial.println(t2); //t3 = t1*256 + t2 ; // start = t3; start = (myFile.read())*256 + myFile.read() ; //читаем первый и второй байт в переменную start Serial.println(start); //выводим на серийный порт значение переменной старт myFile.close(); //мой код myFile = SD.open("test.txt", FILE_WRITE); // if the file opened okay, write to it: if (myFile) { Serial.print("Writing to test.txt..."); myFile.seek(0); //чтобы записывать с позиции 0 myFile.write( byte (FullSumm/256)); myFile.write( byte (FullSumm%256)); // byte(Money/256),byte(Money%256) // close the file: myFile.close(); Serial.println("done."); } else { // if the file didn't open, print an error: Serial.println("error opening test.txt"); } // re-open the file for reading: myFile = SD.open("test.txt"); if (myFile) { Serial.write("test.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 test.txt"); } } void loop() { // nothing happens after setup }По отдельности два скетча работают.
При обединении компилятор ошибок не выдаёт, но вот устройства по SPI перестают работать. :( Экран выдаёт кракозябры, считыватель карт не работает, Serial выдаёт тишину.
Опытным путём, добавляя в основной скетч по отдельности разные строики из скетча чтение\запись, выяснил что проблемы начинаются после добавления строки:
#include <SD.h>
Открыв данную библиотеку и почитав её описание обнаружил:
1.для леонардо есть особая версия библиотеки в которой в ручную виртуально привязываются выводы SPI к 11,12,13 пину. Я эту проблему решил перепайкой данных портов на железную шину SPI (которая сбоку из шести контактов)
2.в теле библиотеки есть строчка return card.init(SPI_HALF_SPEED, csPin, mosi, miso, sck) && volume.init(card) && root.openRoot(volume);
предполагаю что модуль для SD карт работает на другой частоте шины SPI. но вот как разрешить проблему работы нескольких устройств по одной шине SPI ума не приожу... Они ведь все нужны.
Читал про продвинутые натройки шины SPI на DUO... но вот приобрести DUO по ка нет возможности...
Уважаемые Гуру, прошу подсказать:
1. Верны ли мои предположения?
2. Какие пути выхода из ситуации возможны?
Если нужна какая то дополнительная информация - готов предоставить. Спасибо.
поправьте меня пож. если я не правильно понял работу SPI.
1)Рассмотрим ситуацию когда ведомое устройство только принимает данные, в ответ ничего не передает. Выходом СS1, СS2 и т.д контроллер сообщает какому конуретно ведомому устройству предназначена порция данных. Перед передачей порции данных я должен сам выставить низкий уровень на соответствующем адрессуемому устройству СS, и передать данные. Далее, при необходимости, я могу поменять параметры передачи данных (например скорость), выставить СS в 0 для соответствующего устройстви и передать ему данные. И т.к далее
2)если я хочу адресовать несколько ведомых устройств, у которых нету входа СS, то я могу выход MOSI (с ардуины) завести на ведомое устройство через быстродействующий элемент "И", на второй вход которого будет подаваться CS для соответствующео ведомого устройства. Выход элемента "И" будет подключен ко входу данных соответствующего ведомого устройства. В этой ситуации тоже можно играться со скоростями передачи, если ведомые работают на разных скоростях
2 - мультиплексор лучше
Коллеги, коментарии мне кажутся весьма полезными. Буду гуглить тему мультиплексоров и читать как программно менять скорость. Но хотелось бы уточнить.
1. Верны ли мои предположения по поводу разной скорости работы устройств?
2.Что такое быстродействующий элемент "И". Это железяка как я понимаю. Где бы её найти. Или это программный код (процедура).
P.S. CS - есть на всех устройствах.
P.P.S. - все устройства ведомые
И если можно примеры фунций которые стоит использовать для решения данной проблемки.
Логический элемент "И" - микросхема. Но то что я написал не претендует на правильность. Это был тоже вопрос.
Коллеги, коментарии мне кажутся весьма полезными. Буду гуглить тему мультиплексоров и читать как программно менять скорость. Но хотелось бы уточнить.
1. Верны ли мои предположения по поводу разной скорости работы устройств?
2.Что такое быстродействующий элемент "И". Это железяка как я понимаю. Где бы её найти. Или это программный код (процедура).
P.S. CS - есть на всех устройствах.
P.P.S. - все устройства ведомые
И если можно примеры фунций которые стоит использовать для решения данной проблемки.
2.Что такое быстродействующий элемент "И". Это железяка как я понимаю. Где бы её найти. Или это программный код (процедура).
мультиплексор на четыре ведомых устройства SPI без /CS строится на одной микросхеме К155/555ЛЛ1 аналог SN74LS32N ( 4 х 2 ИЛИ ) = 20р.
Друзья помогите пожалуйста подключить sd модуль и rfid считыватель и простой 8 омный динамик от компьютера одновременно к ардуино мега 2560 для воспроизведения аудио файлов с sd карты выполненой операции при поднесении карты rfid. RFID считыватель у меня уже подключен соответственно к 50,51,52,53 и к10 пинам, а куда воткнуть еще и sd ридер незнаю
К 50, 51, 52, 49.
Что за RFId такой, что ему и 53, и 10 надо? Всю жизнь SPI по 4м проводам работал.
виноват к 5 пину
MFRC-522 RC522
Подскажите, на данный момент изучаю SPI. Возможно ли по SPI подключить к примеру 20-30 семисегментных 4хразрядных индикаторов - на которых будет выведена одновременно различная числовая информация?!.... или будут тормоза с обновлением - индикаторы я так понимаю все динамические в основном..
Спасибо!
Тема хоть и старая, но поделюcь своим опытом - 2 устройства на шине, дисплей и SD читалка - проблем со скоростью нет. Все сделано через аппаратный SPI.