I2C, pullup resistors (STM32 discovery) - microcontroller

I am sending my data trought I2C (using DMA every 1s).
I´ve added two pullup-resistors to SCK and SDATA.
There are now slaves, so because no respond, master send only slave adress and thats all.
Its testboard so sometimes happend thats I loose these pullup resistors for a while.
When this happend I get no data more and SCK ticks so fast as posible for this frequency.
There is no way how to fix it, pullpups back didnt help, I have to reset my board.
I cant explain this behaviour and its totally kill the bus.

As you have seen already by yourself, pullup resistors are vital for the i2c bus, both in the sda and scl lines. It is usually obvious that the sda line is bidirectional, what is not so obvious is that the scl is also somewhat bidirectional, since slaves can maintain the line low to throttle down the speed of the bus.
In many cases the bus can become locked because of a collision or other physical problem like loosing your pullups, in such a case, some slaves don't release the bus properly because they understand that they are still being addressed. This situation can be fixed by the master sending output SCL pulses and finally a stop condition when the lines are released. However if you say that there are no slaves, this probably is not your case.
I'm afraid that your problem might have to do with the master's i2c peripheral not seeing the lines go high when expected because the pullups are disconnected temporarily. The best solution I can think in your case is that you should make sure that you don't loose those pull ups. The best way to achieve this is to connect two or three resistors in parallel in each line, this way all two/three would have to be disconnected to leave the bus "unpulled". Use two 10k resistors in parallel for SDA and another two for SCL.

Related

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

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.

Raspberry Pi and Arduino Mega 2560 UART behaviour difference

I've been trying to establish serial (UART) communication between a Raspberry Pi Model B Revision 2.0 (checked the model like described on this page) and Arduino Mega 2560. I made a service on the Pi that writes to UART and then expects a message and a coworker programmed the Arduino with an echo program. While they were communicating, I had trouble receiving data, meaning that it was clustered in 8 byte pieces and I had to introduce a timeout for waiting between them (I was actually as much as available and calling select()for the next cluster but it turned to be 8bytes a cluster, except for maybe the last one. As explained in a question I found on this site, the programmer is the one to take care of the protocol and can not rely that the whole message will be ready to read at once (that is logical).
However, when I just connected Pi's TXD and RXD pins, no matter how much bytes I tried sending, it sends them in one go (I've gone up to a bit more than 256, that's more than enough for my purposes). I also have around 50 milliseconds of duration difference, measured directly from within the program, using gettimeofday() function.
So, could anybody clear things for me:
Why is this happening?
Is this difference in behaviour expected?
Is there a potential problem in either of the devices (if that can even be concluded from the given information).
Of course, any additional information is welcome, in case I forgot asking something that is deemed important.
Why is this happening?
I tried some time back communicating Arduino-Arduino and Arduino-Pi. I faced some problems with UART communication. However, you might want to keep same Baud rate on both the devices. With Pi, you might need to trigger an event if you receive data from Arduino. On the other side, if you code runs longer, then you might lose some data i.e. your Arduino code is running something else while Pi sends data over UART.
Is this difference in behaviour expected?
Yes. Arduino is a microcontroller based device while Pi is microprocessor based (runs on OS)
Is there a potential problem in either of the devices (if that can even be concluded from the given information).
I don't think there could be any hardware problem unless it is not functioning at all.
Also, because of this issues, I switched from UART communication to SPI communication. This solved my problem completely.

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.

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