Using Serial Peripheral Interface (SPI) to talk to several slaves simultaneously - serial-port

I have four Atmega328p in a single board and I want one of them send the same data (i.e. sensor readings) to the other three simultaneously. I'm not interested in a bidirectional communication. I read this thread (How can I broadcast data to multiple SPI slaves and how it works?) about SPI broadcasting, and someone mentioned not being possible because in SPI communication is full duplex and MISO and MOSI lines are active at the same time. However, I was wondering if I could just let the MISO lines unconnected and all SS pins pulled low, so I could broadcast a message to all slaves simultaneosly, taking into account that I do not need any type of response from the slaves to the master.
So, is this possible? Or how else could I work around this problem? I was also considering on using UART's Tx line and connect all the receivers in parallel to it, but I'm not sure that would work too.
Thanks for your attention.

Related

Advice needed for connecting multiple arduinos as slave to raspberry pi

I have a project in hand where I need to connect 5 or more arduinos as slaves to Raspberry Pi. Load Cells, Reed Switch, Solenoid lock will be connected to each of the arduino. The arduinos need to send the weight readings when a communication is started by the raspberry pi(master). Only a single arduino will be activated at a time. The arduinos will be placed at a maximum of 6ft distance from the raspberry pi. I need advice regarding how to make this connection. I read that I2C cannot be used for long distances so I am unsure if 6 ft is a long distance for I2C. Next, I am trying to see if a USB would work for my case but the issue is the Pi has only 4 USB slots. So can I use a external USB hub with an external power supply and connected each of the arduinos to the USB hub and provide individual power supply to the arduinos? Will this arrangement work or should I be looking at any other protocol apart from I2C and USB?? Any advice on this will be much appreciated. Thanks a lot for your time.
Arduino (Nano, Uno, Mega etc.) can communicate via SPI, I2C or UART.
Long story short, SPI is not suitable for your application. It is used for fast data transfer over short distances (usually milimeters or centimeters), so mainly for communication between chips mounted on the same PCB or PCBs close together (e.g. display shields).
Using I2C is perfectly fine (let's say up to 10 meters) and in your case it is a way to go. The maximum possible length depends on baud rate, for 10 meters a 9600 baud rate would be OK. The big advantage is that you need only 2 wires to connect all Arduinos, the disadvantage is that only one device can transfer data at the time – in your case, that does not matter.
UART is used for communication with many external modules (GSM, GPS, HMI, ...) and also in combination with USB-TTL chip for communication via USB (virtual COM port). In your case, you can use UART e.g. in combination with external UART-RS485 converter module, but there is no need since you can use I2C.

Communication between 2 arduinos

I am working with Arduino yun, and I would like to know how can I access sensor values from one arduino using another arduino. Which ways of comunication they are between arduinos? Can I access data from another arduino through wireless? Do I need additional hardware to accomplish this, or its possible with just two arduinos and one computer?
It is possible. Arduinos, depending on the model, can usually communicate via SPI, I2C, etc. Both Arduinos can send and receive data via SPI, for example, so you can hook them up to each other.
It also depends on the type of sensor data you have as well as how many open pins you have: if you really wanted to, you could set 8 bits of data to 8 different pins, and simply connect those pins to 8 pins on the receiving Arduino. That's a rather barbaric way to do it considering you have SPI at your disposal, though.
There are a couple of ways, without any external hardware you have :
SPI
I2C
Serial communication/UART
Serial is the easiest to use among these 3.
And for any other kind of communication you will require external hardware, so if you want to go wireless, then you have cheap RF modules, XBee, etc..
That said that's more appropriate question for Arduino SE site ;)
Check this page. https://www.arduino.cc/en/Tutorial/MasterWriter
I used the I2C to trigger sound from on one arduino and play it on the other. There was no noticeable delay. If you want to stream a lot of data then SPI should be used.

multiple i2c can't work with arduino uno

I am trying to connect 2 I2C modules to arduino uno. GY86(HMC5883L,MS5611,MPU6050) and BMP085 or any other I2C module. When i test each one separately it works ok but when both are connected to the I2C bus port, Every thing ruins. th moment i connect the BMP module, GY86 starts to output wrong numbers. I also tested my GY86 with DS1307 module. same thing happens and the moment i connect them, the DS starts to output wrong random output. i tried to apply a pull up resistor for SDA and SCL but didn't work. Whats the problem?
I2C at the Hardware Level
Signals
Each I2C bus consists of two signals: SCL and SDA. SCL is the clock signal, and SDA is the data signal. The clock signal is always generated by the current bus master; some slave devices may force the clock low at times to delay the master sensing more data.
Unlike UART or SPI connections, the I2C bus drivers are "open drain", meaning that they can pull the corresponding signal low, but cannot drive it high. Thus, there can be no bus contention where one device is trying to drive the line high while another tries to pull it low, eliminating the potential for damage to the drivers or excessive power dissipation in the system. Each signal line has a pull_up resistor on it, to restore the signal to high when no device is asserting it low.
Resistor selection varies with devices on the bus, but a good rule of thumb is to start with 4.7k and adjust down.
Signal Levels
Since the devices on the bus don't actually drive the signals high, I2C allows for some flexibility in connecting devices with different I/O voltages. In general, in a system where one device is at a higher voltage level than another, it may be possible to connect the two devices via I2C without any level shifting circuitry in between them. The trick is to connect the pull_up resistor to the lower of the two voltages. This only work in some cases, where the lower of the two system voltages exceeds the high-level input voltage of the higher voltage system - for example, a 5V Arduino and a 3.3V accelerometer.
Protocol
Communication via I2C is more complex that with UART or SPI solution. The signalling must adhere to a certain protocol for the devices on the bus to recognize it as valid I2C communications.
Basics
Messages are broken up into two types of frame: an address frame, where the master indicates the slave to which the message is being sent, and one or more data frames, which are 8-bit data messages passed from master to slave or vice versa. Data is placed on the SDA line after SCL goes low, and is sampled after the SCL line goes high. The time between clock edge and data read/write is defined by the devices on the bus and will vary from chip to chip.
Start Condition
To initiate the address frame, the master device leaves SCL high and pulls SDA low. This puts all slave devices on notice that a transmission is about to start. If two master devices wish to take ownership of the bus at one time, whichever device pulls the SDA low first wins the race and gains control of the bus. It is possible to issue repeated starts, initiating a new communication sequence without relinquishing control of the bus to other masters.
Address Frame
The address frame is always first in any new communication sequence. For a 7-but address, the address is clocked out most significant bit (MSB) first, followed by a R/W bit indicating whether this is a read (1) or write (0) operation.
The 9th bit of the frame is the NACK/ACK bit. This is the case for all frames (data or address).
Once the 8 bit of the frame are sent, the receiving device is given control over SDA. If the receiving device does not pull the SDA line low before the 9th clock pulse, it can be inferred that the receiving device either did not receive the data or did not know how to parse the message. In that case, the exchange halts, and it's up to the master of the system to decide how to proceed.
Data Frames
After the address frame has been sent, data can begin being transmitted. The master will simply continue generating clock pulses at a regular interval, and the data will be placed on SDA by either the master or the slave, depending on whether the R/W bit indicated a read or write operation. The number of data frames is arbitrary, and most slave devices will auto-increment the internal register, meaning that subsequent reads or writes come from the next register in line.
Stop Condition
Once all the data frames have been sent, the master will generate a stop condition. Stop conditions are defined by a 0->1 (low to high) transition an SDA after a 0->1 transition on SCL, with SCL remaining high. During normal data writing operation, the value on SDA should not change when SCL is high, to avoid stop condition.
I think several devices have same address. That's why you receive bad data. Usually I2C devices have extra pins to setup lower bits of addr. Do it and don't forget to change corresponding software definitions.
Update:
MPU6050 has input pin, which specifies LSB of I2C addr. You need tie this pin to high level 3.3V. Otherwise MPU6050 will have same addr as DS1307. I know it for sure, because work with both ICs a lot. To do it you need broke wire between 9nth pin of MPU6050 and Gnd. And solder it through resistor >3k to 3,3V. Or not use DS1307. From memory there is ds1302 rtc module.
You should find datasheets for all ICs you use and check what are their I2C addresses. The board consists of three parts, so you must know those 3 addresses.

Connect several COM ports into one

I will have several devices with atmel microcontrollers which Im going to connect to PC using COM. Is there any way to connect several devices into one COM? (Let's assume COM can handle amounts of data I need to transmit and I can choose the way of sending data using COM)
Sure, chain the ATmegas together via serial, and use a single USB-serial device. Combine all the data you need to send, and send it out of the single serial port. In each ATmega, you can either relay all the data to the next one, or use a little more intelligent scheme and only forward data meant for other ATmegas.
The standard RS232 COM port does not allow to connect several devices to one port. Because parallel connection of several devices may change electrical signal characteristics such as voltage levels. You may build a chain of ATmegas as uint128_t suggested or change the physical interface type to RS485.
RX pins: you can connect more RX pins together.
TX pins: you can connect more TX pins together if you ensure that only one is active at any time. Others pins must be configured as input or high impedance. This can be done with a suitable protocol.
The parasitic capacitances of pins connected together sum up - this can eventually limit the transfer speed.

Arduino: Packet loss on Serial communication

I am trying connect multiple Arduino Mega Boards via their Serial pins to allow communication between the boards. I want to be able to connect an arbitrary amount of arduinos by daisy-chaning them and I want one board to be the master, taking control over the actions of the other boards. The master should be determined dynamically by the boards. I am aware that the daisy chaining method introduces delays to the communication due to the forwarding of packets, but so far I am planning on connection 4 boards at most. In the future this might increase to maybe 10 boards. My boards all have a separate power source, since they are connected to some other hardware which has its own power source.
My idea was to connect the boards in such a way, that the master would be determined by the wireing of the boards. I thought about having the "Serial" port as 'To-Master' serial port and the "Serial1" port as "To-Child" serial port. The boards send hello messages on the "To-Master" serial port and the master replies if it received such a message on the "To-Child" serial port. If no answer is received after some seconds, the board determines itself to be the master.
I wired the boards up by connecting the ground pins, and wiring RX1 of the master to TX0 of the child and TX1 of the master to RX0 of the child:
Basically my setup is working, since the boards do detect each other and exchange hello messages and replies. There is however a significant amount of packet loss or corruption which I would like to eliminate.
As a simple measure of packet verification, I begin each packet with a "magic number". The receiving board looks for this byte and only tries to read a packet after receiving this byte. Any other bytes received are simply discarded.
As it seems, it happens quite often that something is received on either serial port that does not start with the magic number and is therefore discarded. The timestamps of these events are however consistent with the timestamps of sending of the other board meaning that the packet was at least partially transmitted but somehow the magic byte got corrupted or discarded.
Is this a known problem with the arduinos serial ports?
Can it be related to my wiring?
Are there any measures I can take to ensure a save delivery of the packets?
Can it be a problem of the boards not reading the signal at the correct time (I used a baud rate of 9600)?
I also looked into I2C communication, but I did not find any resource or information if it is possible to dynamically choose the master for this type of communication. Also in the documentation it stated, that it is important that all devices share a common power source which is not possible in my scenario. However, the basic master-slave principle of this I2C conforms with my requirements, as I have a master that sends commands to all other boards. Could I2C be utilized in my case?
Thank you for your thoughts!
Here is a discussion about multi-master I2C topology of Arduinos, seems that it is supported (haven't tested it myself). - http://forum.arduino.cc/index.php/topic,13579.0.html
You can test SPI as well, here is a comparison between the two - http://components.about.com/od/Theory/a/Selecting-Between-I2c-And-Spi.htm.
Slave might be selected with generic GPIOs
I don't know any known implementation of multi-clients on top of Serial bus (usually it is intended for peer2peer communication only) - even though, your configuration seems reasonable, I would be considering other options.
BTW, from your comment about different power sources, I assume your boards are away from each-other. Have you considered very cheap ($2) RF modules, such as nRF24L01+ (http://maniacbug.wordpress.com/2011/11/02/getting-started-rf24/). THere is a library for networking those in multi-node network
Might be better off with I2C or SPI like people have suggested here.
However, to address your question directly, it is most likely wiring. I am assuming you are using cheap jumper wires to plug directly into the Arduino Headers. Noise on this connection is the most likely problem or garbled serial messages. Try implementing with twisted pair cables and connecting directly to the board.
SPI or I2C might have better error correction than your customer serial protocol. I would see the other answers for that.

Resources