Подключение нескольких устройств по SPI

mitekg
Offline
Зарегистрирован: 14.05.2013

Гуглил и читал (_http://robocraft.ru/blog/arduino/541.html), но так и не понял до конца логику работы нескольких устройств по SPI

предположим у меня есть

1. uno/mega

2. sd module

3. nrf21

4. lcd 5110

5. enc28j60

все они (2-5) подключаются по SPI

обязательно ли использовать сдвиговый регистр или есть какие-то тонкости для подключения без этого огорода?

Спасибо.

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

никаких сдивговых регистров не надо... 3 линии общие для всех устройств и допольнительно по одной   для выбора активного устройства

нето гуглите.... SPI интерфейс погуглите

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

я бы не советовал столько устройств вешать на SPI.. поищите варианты без SPI... работать то оно конечно будет... но все это будет медленно и печально... 

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

чему там тормозить

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Michal пишет:

чему там тормозить

думаю самым заметным тормозом будет экран :) хотя конечно от размера экрана будет зависить.. но я не настаиваю, каждый имеет право сам наступить на грабли :)

mitekg
Offline
Зарегистрирован: 14.05.2013

Michal пишет:

никаких сдивговых регистров не надо... 3 линии общие для всех устройств и допольнительно по одной   для выбора активного устройства

нето гуглите.... SPI интерфейс погуглите

смотрю на сайте http://arduino.cc/en/Reference/SPI

SS на 10(uno) и 53(mega) ... таки это можно как-то поменять или

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

вопрос в чем?

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

mitekg пишет:

смотрю на сайте http://arduino.cc/en/Reference/SPI

SS на 10(uno) и 53(mega) ... таки это можно как-то поменять или

на что поменять? зачем?  

53 пин это что бы сказать меге что она будет подчиненой на SPI и зачем его куда то менять?

mitekg
Offline
Зарегистрирован: 14.05.2013

могу я подключить SS на:

2. sd module - 3 pin

3. nrf21 - 4 pin

4. lcd 5110 - 5 pin

5. enc28j60 - 6 pin

и получится им так рулить?

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

получится

axill
Offline
Зарегистрирован: 05.09.2011

SPI есть железный, есть софтверный

все перечисленные вами устройства отлично работают и так и так.

смотрите не только на модули, но и на библиотеки, которые есть - некоторые библиотеки работают только по железному SPI, некоторые только по софтверному. В случае с жедезным SPI цепляться нужно обязательно на выводы MISO/MOSI/SCK которые обозначены на MCU (и привязаны к конктртеным выводам ардуино). В случае софтверного SPI в качестве MISO/MOSI/SCK можно назначить практически любые порты ввода-вывода, в этом случае при необходимости разные устройства можно подключать к разным выводам MCU

наиболее правильный вариант вам уже порекомендовали - MISO/MOSI/SCK всех устройств подключить паралелльно к MCU, выводы Chip Select к каждому устройству - отдельный вывод MCU

но могут быть нюансы - некоторые SPI устройства не поддерживают в полной мере SPI и могут не работать с другими устройствами SPI на той же шине

axill
Offline
Зарегистрирован: 05.09.2011

Puhlyaviy пишет:

я бы не советовал столько устройств вешать на SPI.. поищите варианты без SPI... работать то оно конечно будет... но все это будет медленно и печально... 

от количества устройств на шине SPI его производительность не зависит! В любом случае МК в один момент времени осушествляет обмен только с одним устройством, остальные находятся в спящем режиме

axill
Offline
Зарегистрирован: 05.09.2011

Puhlyaviy пишет:

думаю самым заметным тормозом будет экран :) хотя конечно от размера экрана будет зависить.. но я не настаиваю, каждый имеет право сам наступить на грабли :)

5110 отлично работает как небольшой дисплейчик. конечно видео на него не получится выводить, но для более менее статических задач никаких тормозов не заметно

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

axill пишет:

от количества устройств на шине SPI его производительность не зависит! В любом случае МК в один момент времени осушествляет обмен только с одним устройством, остальные находятся в спящем режиме

Вы выворачиваете не в ту сторону....  и многие могут вас понять не правильно.. 

Попробуем аналогии...

Это из серии что если взять одну трубу и подключить к ней краны.... от количества кранов производительность трубы не зависит... но вот производительность кранов зависит от размера трубы и количества подлюченых кранов...

просто экран 320х240 на 16 битной шине и мегой 2560, заметно как промаргивается когда несколько строк переписываеш, не то что бы это выглядело страшно, но создается впечатление чего то собраного на коленке.. а SPI помноженый даже на мегу2560 скорее всего будет жалкое зрелище, особенно если кроме дисплея там еще будет висет куча всего... но возможно что кого то это устроит, хозяин барин...

axill
Offline
Зарегистрирован: 05.09.2011

Puhlyaviy пишет:

Вы выворачиваете не в ту сторону....  и многие могут вас понять не правильно.. 

Попробуем аналогии...

Это из серии что если взять одну трубу и подключить к ней краны.... от количества кранов производительность трубы не зависит... но вот производительность кранов зависит от размера трубы и количества подлюченых кранов...

производительность SPI не завсит от количества подключенных устройств - ваш пример с кранами не совсем подходит, тут скорее надо говорить о том, что есть три крана с водой, пивом и квасом и одна труба. Смешивать нельзя)) количество воды через трубу в секунду не зависит от того, что есть еще квас и пиво, но если в течении часа проливать все три, то воды можно пролить только 1/3 объма :)

в конце концов все упирается в производительность МК - это ему через SPI пропихивать данные. Зависит от задачи, для многих задач можно все на SPI повесить, для каких то задач в таком варианте не хватит производительности МК

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

axill пишет:

производительность SPI не завсит от количества подключенных устройств - ваш пример с кранами не совсем подходит, тут скорее надо говорить о том, что есть три крана с водой, пивом и квасом и одна труба. Смешивать нельзя)) количество воды через трубу в секунду не зависит от того, что есть еще квас и пиво, но если в течении часа проливать все три, то воды можно пролить только 1/3 объма :)

Хых, пишите проще.. а то многие вас не поймут... мой пример с трубами подходит идеально. вы его просто расширили что в каждый кран нужно прокачивать свой вид жидкости...  и SPI это очень маааааленькая труба...  обьем прокачки через нее все же сильно ограничен и чем больше кранов прикручиваеш тем меньше прокачать можно в каждый отдельный кран... :) 

Но в целом как бы, если есть возможность выбрать другие шины, то зачем все пихать в одну?

axill
Offline
Зарегистрирован: 05.09.2011

мы отвлеклись от изначального вопроса - у человека устройства с SPI - это данность. Предлагать ему поменять устройства на другие не совсем правильно. Собственно ответы дал выше michail

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

axill пишет:

мы отвлеклись от изначального вопроса - у человека устройства с SPI - это данность. Предлагать ему поменять устройства на другие не совсем правильно. Собственно ответы дал выше michail

согласен про отвлеклись.. но тут как бы звучало ПРЕДПОЛОЖИМ.. теость устройст еще нет и человек раздумывает брать или что то заменить...

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Да все ясно SCK MISO MOSI паралельно, а CS отдельно. Просто нужно перед обращением к устройству дергать его  CS (установив на всех 1 на нужном 0).

А регистр только если у вас не достаточно свободных ног на все устройства.

mitekg
Offline
Зарегистрирован: 14.05.2013

Итак, я подключил к меге 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=cpp

 

toc
Offline
Зарегистрирован: 09.02.2013

mitekg,

1. Какая мега? 2560?

2. Два примера успешно работают по отдельности?

3. Какая ошибка-то?  "Переменная ether не определена" ?

 

mitekg
Offline
Зарегистрирован: 14.05.2013

1. мега 2560

2. Да, по отдельности все ок. Пример который я привел работает. Проблема в том что оно ругается при попытке определить переменную char page[] PROGMEM = "test123123efwasdf a asdf asdfq23r ewfadfw efqwef asdfa w";

и выдает ошибку, только когда объединяю скетчи.

3. ругается на 449 строку, если попытаться вместо строки скормить переменную.

 

спасибо

 

toc
Offline
Зарегистрирован: 09.02.2013

2. как ругается? какую ошибку?

3. как ругается?

mitekg
Offline
Зарегистрирован: 14.05.2013

https://github.com/maniacbug/RF24/blob/master/RF24_config.h

Ругается на 45 строку. Как я понял в ней переопределена схема работы с PROGMEM.

И как с ней правильно работать после этого?

toc
Offline
Зарегистрирован: 09.02.2013

Попробуйте убрать все PROGMEM из скетча. Памяти у такой меги должно хватить ещё на многое.

mitekg
Offline
Зарегистрирован: 14.05.2013

Не так просто убрать весь PROGMEM, он в куче библиотек прошит.

А как можно его правильно использовать с учетом того как оно переопределено?

toc
Offline
Зарегистрирован: 09.02.2013

mitekg пишет:

Не получается. У кого есть опыт объединения в одной меге работу с nrf21 и ENC28J60 на базе RF24Network и EtherCard.h

http://arduino.ru/forum/obshchii/podklyuchenie-neskolkikh-ustroistv-po-spi

Конфликтует переопределнный PROGMEM.

Очень прошу помощи. Спасибо

Товарищ, что такое "nrf21"? На самом деле, ты имел в виду слово RF24 (название библиотеки) или nrf24l01+ (название чипа). Вероятное решение твоей проблемы: http://forum.jeelabs.net/node/1531.html

mitekg
Offline
Зарегистрирован: 14.05.2013

toc, Спасибо!! помогло. то что надо))

да, конечно, имел ввиду nrf24.

Еще раз, спасибо!

bolotin.denis
bolotin.denis аватар
Offline
Зарегистрирован: 15.09.2013

Помогите. Таже проблема, но немогу понять что нуждно зделать.

9ser
Offline
Зарегистрирован: 18.11.2012

 Почитал тему и понял, что меня эта проблема тоже посетила.

Собираю 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?

Или может есть готовые решения и я зря ломаю голову :)

 

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

9ser пишет:

 Или может есть готовые решения и я зря ломаю голову :)

конечно есть. возмите процесор помощней :)

axill
Offline
Зарегистрирован: 05.09.2011

У меня связка на одной ардуине нормально работали вместе и nrf24 и wiznet5100

9ser
Offline
Зарегистрирован: 18.11.2012

axill пишет:

У меня связка на одной ардуине нормально работали вместе и nrf24 и wiznet5100

можно взглянуть на скетч если не жалко?

9ser
Offline
Зарегистрирован: 18.11.2012

Puhlyaviy пишет:

9ser пишет:

 Или может есть готовые решения и я зря ломаю голову :)

конечно есть. возмите процесор помощней :)

А готовые решения на Arduino???

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

9ser пишет:

А готовые решения на Arduino???

ну я могу только гадать что именно вы там используете..

попробуйте хотя бы мега 2560

9ser
Offline
Зарегистрирован: 18.11.2012

Использую в домашней автоматизации.

Куча беспроводных клиентов (планирую более 5 клиентов) скидывают/получают данные на беспроводной сервер.

В свою очередь беспроводной сервер должен передавать данные по Ethernet на сервер на компе и получать данные для управления клиентами через Ethernet

Вот саму беспроводную связь организовал, а дальше начинаю нагружать беспроводной сервер Ethernet протоколом и появляются баги, то страница недоступна (сервер получает данные от клиентов, то наоборот)

 

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

для тех кто в танке..
http://arduino.ru/Hardware

эх ты сколько разных ардуино бывает :)

9ser
Offline
Зарегистрирован: 18.11.2012

да Arduino 2560 + W5100 Ethernet

axill
Offline
Зарегистрирован: 05.09.2011

9ser пишет:

axill пишет:

У меня связка на одной ардуине нормально работали вместе и nrf24 и wiznet5100

можно взглянуть на скетч если не жалко?

на телефоне под рукой нет кода

вы выложите свой и еще опишите признаки/критерии того, что ваша программа не справляется, так же условия при которых это происходит

могу предположить, что у вас есть участки кода с долгим ожиданием. Случаем на mega2560 временные задержки не используете? Датчика типа ds18b20 нет?

9ser
Offline
Зарегистрирован: 18.11.2012

Приемник на базе mega2560+w5100+nfr24l01 должен только слушать радиоканал (передавать полученые данные через Ethernet) и управлять беспроводными клиентами из локальной сети и все!

byzon
Offline
Зарегистрирован: 22.03.2015

Доброго дня!

Собираю контроллер для автомойки самообслуживания. В принципе уже есть рабочий вариант, но решил добавить запись логов на SD карту. 

В составе рабочего модуля:

arduino Leonardo.

7segment shield - 2шт - каждый на отдельной плате с процессором

RC522 - RFID считыватель для карт

Купюроприёмник - выдаёт имульсы.

Все шилды подключены по "железному" SPI паралельно т.к. на леонардо они не дублируются на выводы и вообще чтоб пины не забивать У каждого свой SS.

Вот работающий скетч:

/*
 * MFRC522 - Library to use ARDUINO RFID MODULE KIT 13.56 MHZ WITH TAGS SPI W AND R BY COOQROBOT.
 * The library file MFRC522.h has a wealth of useful info. Please read it.
 * The functions are documented in MFRC522.cpp.
 *
 * Based on code Dr.Leong   ( WWW.B2CQSHOP.COM )
 * Created by Miguel Balboa (circuitito.com), Jan, 2012.
 * Rewritten by Søren Thing Andersen (access.thing.dk), fall of 2013 (Translation to English, refactored, comments, anti collision, cascade levels.)
 * 
 * Released into the public domain.
 *
 * This sample shows how to setup a block on a MIFARE Classic PICC to be in "Value Block" mode.
 * In Value Block mode the operations Increment/Decrement/Restore and Transfer can be used.
 * 
 ----------------------------------------------------------------------------- empty_skull 
 
 - Aggiunti pin per arduino Mega
 - Scritto semplice codice per la scrittura e lettura 
 
 - add pin configuration for arduino mega
 - write simple read/write Code for new entry user
 
 http://mac86project.altervista.org/
 
 ----------------------------------------------------------------------------- Nicola Coppola
 * Pin layout should be as follows:
 * Signal     Pin              Pin               Pin
 *            Arduino Uno      Arduino Mega      MFRC522 board
 * ------------------------------------------------------------
 * Reset      9                5                 RST
 * SPI SS     10               53                SDA
 * SPI MOSI   11               51                MOSI
 * SPI MISO   12               50                MISO
 * SPI SCK    13               52                SCK
 *
 * The reader can be found on eBay for around 5 dollars. Search for "mf-rc522" on ebay.com. 
 */
// в этой версии деньги списывалсь сами при подключении к плате SD1
#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 6
#define RST_PIN 5



//ОБЪЯВЛЯЕМ ПЕРЕМЕННЫЕ
int ON = LOW;                    //Переопределяем значения цифровых входов
int OFF = HIGH;                  //Переопределяем значения цифровых входов
int Money;                       //переменная для подсчёта денег на карте
int FullSumm = 0;                //Сумма денег на мойке
int WaterCost = 125 ;            //"Цена" воды (миллисекунд на рубль)
int FoamCost = 25;             //"Цена" пены (миллисекунд на рубль)
byte LastCardUid[10];            //Идентификатор последней карты - массив из 10ти переменных типа byte
boolean CardsIdentical;          //Новая карта 
int tmpmoney = OFF;              //Временная переменная для счетчика импульсов
int impMoney = 0;                //Импульсы от купюроприемника
long oldtime = 0;                //Время, прошедшее с последнего импульса
int tmpPump = OFF;               //Временная переменная работы НВД
long oldMillis = 0;              //Временная переменная для списывания денег
long WorkingTime = 0;            //Время работы НВД
boolean SummMustShow = false;    //Флаг обновления экрана для показа суммы
boolean IsFoam = false;          //Флаг вода/пена
int tmp = 0;
int led4 = 9;
int led3 = 11;
//int led2 = 3;  // отключил для экранов
//int led1 = 2;  // отключил для экранов
int tmp2 = 0;

MFRC522 mfrc522(SS_PIN, RST_PIN);        // Create MFRC522 instance.

int Disp1 = 3; //экран



void setup() {
  
  
  //подтягиваем резисторы. теперь что бы подать сигнал на 11 и 13 нужно замкнуть их на землю
  digitalWrite(12, HIGH); 
  digitalWrite(13, HIGH); 
  digitalWrite(8, HIGH); 
  
  
  
        Serial.begin(9600);        // Initialize serial communications with the PC
        SPI.begin();                // Init SPI bus
        mfrc522.PCD_Init();        // Init MFRC522 card
        //Serial.println("Scan a MIFARE Classic PICC to demonstrate Value Blocks.");
        
        //Для купюроприемника    
        pinMode(7, OUTPUT);            //команда разрешения на прием купюр
        digitalWrite(7, HIGH);         //Подтягиваем резистор теперь отсутствие сигнала - HIGH, присутствие - LOW 
        pinMode(4, INPUT);            //Счетчик купюр
        digitalWrite(4, HIGH);        //Подтягиваем резистор теперь отсутствие сигнала - HIGH, присутствие - LOW
        
        //Датчики протока пены
        pinMode(8, INPUT);            //Датчик протекания воды
        //digitalWrite(2, HIGH);        //Подтягиваем резистор теперь отсутствие сигнала - HIGH, присутствие - LOW
        
        //Датчики работы насоса
        pinMode(2, INPUT);            //Датчик протекания воды
        //digitalWrite(2, HIGH);        //Подтягиваем резистор теперь отсутствие сигнала - HIGH, присутствие - LOW
        
//pinMode(led1, OUTPUT);
//pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT); 
pinMode(led4, OUTPUT);        
 
 //экран--------------
  pinMode(Disp1, OUTPUT);    //Экран №1
  digitalWrite(Disp1, HIGH); //Отключаем пока
  SPI.setClockDivider(SPI_CLOCK_DIV64);
  ShowString("-00-", Disp1);
}

void loop() {
 if (FullSumm > 0) {
   digitalWrite(led3, HIGH); //если на мойке есть деньги, замыкаем цепь разрешение работы насоса
   }
  else digitalWrite(led3, LOW);
  
  tmp2 =  digitalRead(2); //
 Serial.print(tmp2);
   //if (digitalRead(10)==ON){
  //   Serial.print("pena");
 //  } 
   
 
  
  tmp = digitalRead(4); //считываем значение порта 4 к которому подключён pulse с купюроприёмника считаем деньгу
  
  if (tmp != tmpmoney){ //если значение на входе 4 менялось
    impMoney++;          //увеличиваем счётчик изменений на 1
    tmpmoney = tmp;      //отмечаем на какое значение менялось значение на входе 4
    oldtime = millis();  //запоминаем когда было последнее изменение
    
  }
  //Serial.print(impMoney);
    if ((millis()-oldtime) > 500 && (millis()-oldtime) < 530){    
    FullSumm = FullSumm+(impMoney*5); //?если импульсы с купюроприёмника не поступают 500 милисекунд то добавляем сосчитанные импульсы к сумме....
       
    impMoney = 0;  //обнуляем счётчик импульсов т.к. всё посчетали
   SummMustShow = true; //разрешаем показать сумму
   }
   
   
  //Показываем сумму
  if (SummMustShow == true){ //если показать сумму можно
  Serial.print(FullSumm);
    ShowValue(FullSumm, Disp1); //вывод на дисплей
   SummMustShow = false;       //запрет показа суммы
   
    //Serial.println("Full summ is: "+FullSumm); //?увеличивает значение на дисплее на FullSumm - сколько зачислили в купюроприёмник
  }
  
 //Смотрим переключатель вода/пена
  if (digitalRead(8) == OFF){ //данный переключатель почемуто работает наоборот а на 13-м не работает наверное это связано со втроеным резистором на 13-м
    IsFoam = false;
  }
  else IsFoam = true;   
  
 //Списываем деньги
  if ((digitalRead(12)== ON)&&(FullSumm > 0)){ //? если реле потока даёт сигнал и на мойке ещё есть деньги 
    if (oldMillis < millis()){                 // то
      WorkingTime++;
      oldMillis = millis();
    }

    if ((WorkingTime%WaterCost == 0) && (IsFoam==false)) { //если прошло ещё достаточно милисекунд для списания рублика за воду и пена выключена то списываем рублик за воду
      FullSumm--;
      SummMustShow = true;
      WorkingTime = 1;
    }

    if ((WorkingTime%FoamCost == 0) && (IsFoam==true)) { //если прошло ещё достаточно милисекунд для списания рублика за пену и пена влючена то списываем рублик за пену
      FullSumm--;
      SummMustShow = true;
      WorkingTime = 1;
    }
  } 


//Работа с картами___________________________________________________________________
  
        
        // Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
        MFRC522::MIFARE_Key key;
        for (byte i = 0; i < 6; i++) {
                key.keyByte[i] = 0xFF;
        }
        // Look for new cards
        if ( ! mfrc522.PICC_IsNewCardPresent()) {
                return;
        }

        // Select one of the cards
        if ( ! mfrc522.PICC_ReadCardSerial()) {
                return;
        }
        // Now a card is selected. The UID and SAK is in mfrc522.uid.
        
        // Dump UID
        Serial.print("Card UID:");
        for (byte i = 0; i < mfrc522.uid.size; i++) {
                Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
                Serial.print(mfrc522.uid.uidByte[i], HEX);
        } 
        Serial.println();

        // Dump PICC type
        byte piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
        Serial.print("PICC type: ");
        Serial.println(mfrc522.PICC_GetTypeName(piccType));
        if (        piccType != MFRC522::PICC_TYPE_MIFARE_MINI 
                &&        piccType != MFRC522::PICC_TYPE_MIFARE_1K
                &&        piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
                //Serial.println("This sample only works with MIFARE Classic cards.");
                return;
        }
               
        // In this sample we use the second sector (ie block 4-7). the first sector is = 0
        // scegliere settore di lettura da 0 = primo settore 
        byte sector         = 1;
        // block sector 0-3(sector0) 4-7(sector1) 8-11(sector2)
        // blocchi di scrittura da 0-3(sector0) 4-7(sector1) 8-11(sector2)
        byte valueBlockA    = 4;
        byte valueBlockB    = 5;
        byte valueBlockC    = 6;
        byte trailerBlock   = 7;
        byte status;
        
        
        // Authenticate using key A.
        // avvio l'autentificazione A
        //Serial.println("Authenticating using key A...");
        status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
        if (status != MFRC522::STATUS_OK) {
                Serial.print("PCD_Authenticate() failed: ");
                Serial.println(mfrc522.GetStatusCodeName(status));
                return;
        }
        // Authenticate using key B.
        // avvio l'autentificazione B
        //Serial.println("Authenticating again using key B...");
        status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));
        if (status != MFRC522::STATUS_OK) {
                Serial.print("PCD_Authenticate() failed: ");
                Serial.println(mfrc522.GetStatusCodeName(status));
                return;
        }
       
       /* 
        // Writing new value block A
        // Scrivo i valori per il settore A
        Serial.println("Writing new value block A(4) : the first of the sector TWO ");
                byte value1Block[] = { 1,2,3,4,  5,6,7,8, 9,10,255,12,  13,14,15,16,   valueBlockA,~valueBlockA,valueBlockA,~valueBlockA };
                status = mfrc522.MIFARE_Write(valueBlockA, value1Block, 16);
                if (status != MFRC522::STATUS_OK) {
                        Serial.print("MIFARE_Write() failed: ");
                        Serial.println(mfrc522.GetStatusCodeName(status));
                }
        /*
        
        // Writing new value block B
        // Scrivo i valori per il settore B
        Serial.println("Writing new value block B");
                byte value2Block[] = { 255,255,255,255,  0,0,0,0, 0,0,0,0,  255,255,255,255,   valueBlockB,~valueBlockB,valueBlockB,~valueBlockB };
                status = mfrc522.MIFARE_Write(valueBlockB, value2Block, 16);
                if (status != MFRC522::STATUS_OK) {
                        Serial.print("MIFARE_Write() failed: ");
                        Serial.println(mfrc522.GetStatusCodeName(status));
                }
        
        // Writing new value block D
        // Scrivo i valori per il settore C
        Serial.println("Writing new value block C");
                byte value3Block[] = { 255,255,255,255,  0,0,0,0, 0,0,0,0,  255,255,255,255,   valueBlockC,~valueBlockC,valueBlockC,~valueBlockC };
                status = mfrc522.MIFARE_Write(valueBlockC, value3Block, 16);
                if (status != MFRC522::STATUS_OK) {
                        Serial.print("MIFARE_Write() failed: ");
                        Serial.println(mfrc522.GetStatusCodeName(status));
                }
                
        */
        
        
        Serial.println("Read block A(4) : the first of the sector TWO");        
        byte buffer[18];
        byte size = sizeof(buffer);
        // change this: valueBlockA , for read anather block
        // cambiate valueBlockA per leggere un altro blocco
        status = mfrc522.MIFARE_Read(valueBlockA, buffer, &size);
      
       Money = buffer[0]*256+buffer[1]; //считывание денег из блока А и записть их в переменную Money
       
       
        Serial.print("Money on card: ");
        Serial.println(Money);             //вывод на порт суммы денег на карте
        
        Serial.println("Read cardholder name:");
    status = mfrc522.MIFARE_Read(valueBlockB, buffer, &size);
    for (byte i = 0; i < 16; i++){    
      Serial.print(char(buffer[i]));   //вывод на порт имени держателя карты поэлементно из массива buffer
      } 
      Serial.println();   // перенос cтрочки при выводе данных на порт
      
  /*   
    if (FullSumm == 0){
      //Сумма в мойке равна 0
      if (!CardsIdentical){
        //Карта уже отмечалась перед этим
        FullSumm = Money;//забрали деньги с карты на мойку можно написать FullSumm = FullSumm + Money; тогда деньги на мойке и на карте сложаться
        Money = 0;
      //  SummMustShow = true;
      }
    }
    else {
      //Сумма в мойке больше 0
      if (!CardsIdentical){
        //Карта уже отмечалась перед этим
       //так было FullSumm =  Money; //забрали деньги с карты на мойку можно написать FullSumm = FullSumm + Money; тогда деньги на мойке и на карте сложаться
       FullSumm = FullSumm + Money;
        Money = 0;    //деньги на карте обнулили
      }
      else{
        Money = FullSumm; //забрали деньги с мойки на карту
        FullSumm = 0;      //обнулли деньги на мойке
      }
      SummMustShow = true; //флаг обновления данных на дисплее
    }
  
   */
   Serial.print("FullSumm do:");
   Serial.print(FullSumm);
   Serial.println();
     Serial.print("Money do:");
   Serial.print(Money);
   Serial.println(); 
   
   if (FullSumm >= 0 && Money > 0 && SummMustShow != true ){ //флаг SummMustShow используется для того что бы выполнялось только одно из условий для перевода денег с карты на мойку или наоборот
      FullSumm = FullSumm + Money;
      Money = 0;
      SummMustShow = true;
      Serial.println("skinuli dengi s karti");
   }
     if (FullSumm > 0 && Money == 0 && SummMustShow != true ){ //флаг SummMustShow используется для того что бы выполнялось только одно из условий для перевода денег с карты на мойку или наоборот
      Money = FullSumm ; 
      FullSumm = 0;
      SummMustShow = true;
      Serial.println("skinuli dengi na kartu");
   }

  Serial.print("FullSumm posle:");
   Serial.print(FullSumm);
   Serial.println();
     Serial.print("Money posle:");
   Serial.print(Money);
   Serial.println();    
   
    //Записываем на карту сумму  либо добавляя то что осталось на карту, либо пишем ноль если забирали деньги с карты
    Serial.println("Writing ");
    byte value1Block[] = {byte(Money/256),byte(Money%256),0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, valueBlockA,~valueBlockA,valueBlockA,~valueBlockA };
    status = mfrc522.MIFARE_Write(valueBlockA, value1Block, 16);
    if (status != MFRC522::STATUS_OK) {
      Serial.print("MIFARE_Write() failed: ");
      Serial.println(mfrc522.GetStatusCodeName(status));
    }
      
           Serial.println("pobitno blok A:");
    status = mfrc522.MIFARE_Read(valueBlockA, buffer, &size);
    for (byte i = 0; i < 16; i++){    
      Serial.print(byte(buffer[i]));   //вывод на порт побитно значений из блока А
      } 
      Serial.println();   // перенос cтрочки при выводе данных на порт  
     
        
        // risponde successo
        //Serial.println(mfrc522.GetStatusCodeName(status));
        
        // Dump the result
        //mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
        
        // Halt PICC
        mfrc522.PICC_HaltA();

        // Stop encryption on PCD
        mfrc522.PCD_StopCrypto1();
        
        
}


void ShowValue(int tempCycles, int Pin)
{
  char Str[4];
  boolean ShowZeros = false;
    
  if (tempCycles >= 10000){
    return;
  }
  
  if (tempCycles/1000 > 0){
    Str[0] = tempCycles/1000;
    ShowZeros = true;
  }
  else Str[0] = 32;
  tempCycles %= 1000;

  if ((tempCycles/100 > 0)||(ShowZeros)){
    Str[1] = tempCycles/100;
    ShowZeros = true;
  }
  else Str[1] = 32;
  tempCycles %= 100;
  
  if ((tempCycles/10 > 0)||(ShowZeros)){
    Str[2] = tempCycles/10;
    ShowZeros = true;
  }
  else Str[2] = 32;
  tempCycles %= 10;
  Str[3] = tempCycles;

  ShowString(Str, Pin);
}

void ShowString(char *toSend, int Pin){
  digitalWrite(Pin, LOW); //Включаем передачу для выбранного пина
  SPI.transfer('v');
  for(byte x = 0; x < 4; x++)
    SPI.transfer(toSend[x]); //Send a character from the array out over SPI
  digitalWrite(Pin, HIGH); //Выключаем передачу для выбранного пина
}

 

 

Теперь подключил 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. Какие пути выхода из ситуации возможны?

Если нужна какая то дополнительная информация - готов предоставить. Спасибо.

 

RainMan
Offline
Зарегистрирован: 21.06.2011

поправьте меня пож. если я не правильно понял работу SPI.

1)Рассмотрим ситуацию когда ведомое устройство только принимает данные, в ответ ничего не передает.  Выходом СS1, СS2  и т.д  контроллер сообщает какому конуретно ведомому устройству предназначена порция данных.  Перед передачей порции данных я должен сам выставить низкий уровень на соответствующем адрессуемому  устройству  СS, и передать данные.  Далее, при необходимости, я могу поменять параметры передачи данных (например скорость), выставить СS в 0 для соответствующего устройстви и передать ему данные. И т.к далее

2)если я хочу адресовать несколько ведомых устройств, у которых нету входа СS, то я могу выход MOSI (с ардуины) завести на ведомое устройство через быстродействующий элемент "И", на второй вход которого будет подаваться CS для соответствующео ведомого устройства.  Выход элемента "И" будет подключен ко входу данных соответствующего ведомого устройства. В этой ситуации тоже можно играться со скоростями передачи, если ведомые работают на разных скоростях

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

2 - мультиплексор лучше

byzon
Offline
Зарегистрирован: 22.03.2015

Коллеги, коментарии мне кажутся весьма полезными. Буду гуглить тему мультиплексоров и читать как программно менять скорость. Но хотелось бы уточнить. 

1. Верны ли мои предположения по поводу разной скорости работы устройств?

2.Что такое быстродействующий элемент "И". Это железяка как я понимаю. Где бы её найти. Или это программный код (процедура).

P.S. CS - есть на всех устройствах.

P.P.S. - все устройства ведомые

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

RainMan
Offline
Зарегистрирован: 21.06.2011

Логический элемент "И" - микросхема. Но то что я написал не претендует на правильность. Это был тоже вопрос. 

byzon пишет:

Коллеги, коментарии мне кажутся весьма полезными. Буду гуглить тему мультиплексоров и читать как программно менять скорость. Но хотелось бы уточнить. 

1. Верны ли мои предположения по поводу разной скорости работы устройств?

2.Что такое быстродействующий элемент "И". Это железяка как я понимаю. Где бы её найти. Или это программный код (процедура).

P.S. CS - есть на всех устройствах.

P.P.S. - все устройства ведомые

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

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

2.Что такое быстродействующий элемент "И". Это железяка как я понимаю. Где бы её найти. Или это программный код (процедура).

мультиплексор на четыре ведомых устройства SPI без /CS строится на одной микросхеме К155/555ЛЛ1 аналог SN74LS32N ( 4 х 2 ИЛИ ) = 20р.

mortalmoroz
Offline
Зарегистрирован: 16.03.2016

Друзья помогите пожалуйста подключить sd модуль и rfid считыватель и простой 8 омный динамик от компьютера одновременно к ардуино мега 2560 для воспроизведения аудио файлов с sd карты выполненой операции при поднесении карты rfid. RFID считыватель у меня уже подключен соответственно к 50,51,52,53 и к10 пинам, а куда воткнуть еще и sd ридер незнаю

std
Offline
Зарегистрирован: 05.01.2012

К 50, 51, 52, 49.

Что за RFId такой, что ему и 53, и 10 надо? Всю жизнь SPI по 4м проводам работал.

mortalmoroz
Offline
Зарегистрирован: 16.03.2016

виноват к 5 пину

MFRC-522 RC522

 * Pin layout should be as follows:
 * Signal     Pin              Pin               Pin
 *            Arduino Uno      Arduino Mega      MFRC522 board
 * ------------------------------------------------------------
 * Reset      9                5                 RST
 * SPI SS     10               53                SDA
 * SPI MOSI   11               51                MOSI
 * SPI MISO   12               50                MISO
 * SPI SCK    13               52                SCK
Amstel32
Offline
Зарегистрирован: 22.09.2016

Подскажите, на данный момент изучаю SPI. Возможно ли по SPI подключить к примеру 20-30 семисегментных 4хразрядных индикаторов - на которых будет выведена одновременно различная числовая информация?!.... или будут тормоза с обновлением - индикаторы я так понимаю все динамические в основном..

 

Спасибо!

compdue
Offline
Зарегистрирован: 23.04.2020

Тема хоть и старая, но поделюcь своим опытом - 2 устройства на шине, дисплей и SD читалка - проблем со скоростью нет. Все сделано через аппаратный SPI.