Community Question

I am trying to connect my IoTiny to an Arduino Pro Mini via I2C. I am able to successfully write for the IoTiny to the Arduino but when I try to request a response from the Arduino the data see corrupt.

I've tried very basic ez-script:

Code:

print(i2cRead( 0, 0xA,1 ))



And Arduino code:

Code:


String outtoezb;

outtoezb = "R";

char tempout[outtoezb.length() + 1];
outtoezb.toCharArray(tempout,outtoezb.length() + 1);

Wire.write(tempout);
Serial.print("Response Sent: ");
Serial.println(outtoezb);



When executed I get the follow on the IoTiny:

Code:


Start
>
Done (00:00:00.0230307)



And I see that the request get through to the arduion:

Code:


My i2c address: 10
Response Sent: R




Any thoughts?

ptp
Commented July 2017
@DJ,

Correct,
let's wait to see if it works for the OP. I would like to share more details.

Like you said before I2C is not a serial protocol and is very sensitive.

I2C protocol is inherently half-duplex, basically the master controls the clock and sends the first byte (7 addr bit) with 1 bit (read/write).
So the slave obey promptly to the master and performs two different and isolated operations: receiving and sending data.
DJ Sures
Commented July 2017
Why do I see people use delay() in the arduino loop when there's no code? I see it everywhere but I don't know why it's there - it creates extra processing, and the stack nests. So when the interrupts raise, the stack has to be backed up and stopping the demay() anyway. Which slows down the interrupt from starting.
ptp
Commented July 2017
@DJ,

There
is no need/excuse for a delay an empty loop function is enough for this particular example.

The original code before the cut, is a man-in-middle implementation to debug a micro-controller firmware. So i used a micro-controller with my code to simulate the same behavior and every 2 seconds sends a serial debug message.
So the delay is left overs :)

BUT

I was lazy... the correct way is to measure time deltas and execute when the condition is true.
msriddle68
Commented July 2017
Awesome guys! This sample works and releases the wire correctly. I can break it down to figure out my implementation. I really appreciate all the support!
:) :) :)
ptp
Commented July 2017
@msriddle68,

Arduino
hides some code complexity, and sometimes creates an illusion of event programming, simple call back functions, nice code abstraction etc.

BUT

you can't forget you are not coding for the PC, although it seems stupid simple, the things can break easily.

All details are important, so i'll share some details:

1) Interrupt/Callback functions use the KISS rule, keep it simple, objective, pragmatic.
1.1) Don't use delays or other similar mechanisms, you need to hurry up.
1.2) Avoid Serial.Print code. If you need for debug purposes check if is not slowing you down, even if is working remove it from the production/final code.

===============================
2) I2C

2.1) The protocol is half duplex expect read/write individual operations

2.2) Arduino and EZRobot makes your life easy, but under the hood there are some limits, for example there are buffers and the buffers have fixed limits. So if you want to send 100 bytes or 1000 bytes you need first check if EZ-Robot firmware has a limitation and secondly if your Arduino code uses a library (e.g. Wire) with limits.

2.3) CLOCK

2.3.1) The master controls the clock, the default EZ-Builder frequency is 100K. High frequency means faster bus. You can change adjust the clock speed via project settings or ez-script.

2.3.1) If you noticed my code slows down to 10K on IoTinty, but i got it working with 50K on the EZB, so the question is why not 50k or 100K.

2.3.1.1) You have an Arduino mini with atmel chip, 5 Volts version is 16MHZ, 3.3v
is 8 Mhz.So running your code in Atmel 8MHZ half speed is not the same for example running in a Teensyduino (ARM Cortex M4) 3.3.v, Arduino Cortex M0 different micro-controllers same framework "Arduino".

2.3.1.2) Iotiny 10K frequency vs EZB 50K.
Iotinty is a STM32F4 (Cortex M4) 100 Mhz clock
EZB is a STM32F205 (Cortex M3) 120 Mhz clock.

***edited***

ARM instructions are compatible

I don't know if the firmware code is relevant or not, DJ's mentioned the Iotiny has a RTOS, and i believe uses a vendor specific framework. Although iotiny has a more powerful core (M4), EZB has a faster clock.

Something makes the difference.

2.3.2) The I2C implementation allows a slave to slow down the I2C bus to allow some extra processing that process is called "clock stretching".

Arduino Wire library does that while you are in the call back function, some sensors (IMUs) do that too, but not all the masters will support clock stretching.

I believe (I'm not 100% sure) EZB/Iotiny does not support clock stretching, so you need to answer faster as you can otherwise you lose the BUS.

Supporting clock stretching does not mean waiting milliseconds, we are talking microseconds, for example the Arduino Wire library has a timeout limit (wait for the slave) when Arduino is playing the master.

Even in those scenarios you need to increase the timeout, or change the slave implementation.

Some people will say this work, others will blame the hardware, but the success relies on a good hardware/software marriage and attention to the tiny details.
Question
Avatarby msriddle68
Published Monday, July 3, 2017