Questions regarding I2C communication from OpenLog Artemis

Hello all,

I am working on a system that uses the SparkFun OpenLog Artemis with the IMU built-in (DEV-16832). The OLA is taking the input data from the IMU and running it through a bunch of algorithms to achieve a few desired parameters. Now the part where I’m stuck at is the communications – specifically I2C.

The data is being transmitted without any errors over UART on the RX and TX pins on the OLA. I need to send the data over I2C. In my use case, the OLA needs to work as a peripheral/slave device. However I’m unable to do get I2C communication going.

I have tried to start from the basics and tried connecting two OLAs together using the qwiic connectors and the appripriate cables. I have gone through the examples mentioned [here. However I have not been able to get any of them working. I even tried I2C bus scanner sketches, but I’m not able to find any I2C devices.

Below are my questions:

  1. Is it possible to send data out of the OLA over the I2C protocol?

  2. If yes, should I be using the in-built qwiic connector for it? Or should I use a software library like SoftWire that can establish I2C over the GPIO pins?

  3. I need to verify if the communication is working properly or not using another Arduino-based microcontroller. How would I go about doing that?

I don’t know if it is my limited understanding of the working of the I2C protocol itself or something else, so your help would be highly appreciated.

Thank you.](https://docs.arduino.cc/learn/communication/wire/)

I’m not sure connecting 2 OLA’s together will work without some kind of address virtualizer in between (a mux or similar); you *might( be able to add the default OLA’s i2c address for one of them as a “sensor” using this guide https://github.com/sparkfun/OpenLog_Art … SENSORS.md but I’d give that a 30% chance of working :-/

  1. Yes, see qwiic/i2c section here (sub-section of ‘configure attached devices’) https://learn.sparkfun.com/tutorials/op … figuration

  2. Yes, just use the qwiic connector (you could also use the PTH i2c/qwiic ones https://learn.sparkfun.com/tutorials/op … e-overview)

  3. Hook up a sensor following the guide in #1 and verify its detected/working

Thank you so much for your reply!

TS-Russell:
I’m not sure connecting 2 OLA’s together will work without some kind of address virtualizer in between (a mux or similar); you *might( be able to add the default OLA’s i2c address for one of them as a “sensor” using this guide https://github.com/sparkfun/OpenLog_Art … SENSORS.md but I’d give that a 30% chance of working :-/

I looked through it once, but I didn't find anything mentioning the default I2C address. However I'll take another deeper look and try to find it.

TS-Russell:

  1. Yes, see qwiic/i2c section here (sub-section of ‘configure attached devices’) https://learn.sparkfun.com/tutorials/op … figuration

  2. Yes, just use the qwiic connector (you could also use the PTH i2c/qwiic ones https://learn.sparkfun.com/tutorials/op … e-overview)

Thank you for the confirmation on those!

TS-Russell:
3. Hook up a sensor following the guide in #1 and verify its detected/working

I will try that with a few of the qwiic-based sensors that I have access to!

Here are some of the examples that I’ve been trying to get working to verify if communication over I2C is working or not. One OLA is running the Controller sketch while the other one is running the Peripheral sketch. However, I’m not able to get them to work. Could you please tell me what I’m doing wrong here?

Controller sketch:

const byte PIN_QWIIC_SCL = 8;
const byte PIN_QWIIC_SDA = 9;

#include <Wire.h>

TwoWire myWire(PIN_QWIIC_SDA, PIN_QWIIC_SCL);

void setup() {
  //delay(2000);
  myWire.begin();        // join i2c bus (address optional for master)
  Serial.begin(115200);  // start serial for output
  Serial.println("Serial started");
}

void loop() {
  myWire.requestFrom(0x48, 6);    // request 6 bytes from peripheral device 0x48

  if (myWire.available()) { 
    while (myWire.available()) { // peripheral may send less than requested
      char c = myWire.read(); // receive a byte as character
      Serial.print(c);         // print the character
    }
  }
  else Serial.println("No I2C devices found!");

  delay(500);
}

Peripheral sketch:

const byte PIN_QWIIC_SCL = 8;
const byte PIN_QWIIC_SDA = 9;

#include <Wire.h>

TwoWire myWire(PIN_QWIIC_SDA, PIN_QWIIC_SCL);

void setup() {
  myWire.begin(0x48);                // join i2c bus with address 0x48
  myWire.onRequest(requestEvent); // register event
}

void loop() {
  delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
  myWire.write("hello "); // respond with message of 6 bytes
  // as expected by master
}

I have also tried using just Wire object instead of the TwoWire myWire object and the result is the same. Could you tell me what I’ve done wrong here?

The Sparkfun Apollo3/Artemis library does NOT support working as slave/peripheral device. There is NO code, it is NOT implemented. As such the OLA can only work as master/central.

paulvha:
The Sparkfun Apollo3/Artemis library does NOT support working as slave/peripheral device. There is NO code, it is NOT implemented. As such the OLA can only work as master/central.

Thank you for that information! That is very helpful. However, for now, my usage technically doesn’t really require bidirectional communication and the OLA doesn’t have to strictly behave as a peripheral device.

Basically, my OLA will be communicating with another device like a National Instruments myRIO and it needs to continuously stream the required data over the I2C connection. In a way, it needs to act almost like a Serial connection, for now at least. Would something like that be possible? If yes, what would the code for that look like?

I don’t know myRio, but after a quick look-up, it seems it can only work as master/central. Given the I2C protocol, each byte sent needs to get an ACK from the receiver (either peripheral or Master) so you can not just stream data.

If you are not using Serial1 (pin 12/13 on the OLA), that might be a consideration else BLE might be an option.

If Serial1 is already used, the last potential option could be software serial. This is NOT part of the standard Sparkfun Apollo3/Artemis library, but I created a version last year. It has limitations and you can find it on https://github.com/paulvha/apollo3/tree … wareSerial

paulvha:
I don’t know myRio, but after a quick look-up, it seems it can only work as master/central. Given the I2C protocol, each byte sent needs to get an ACK from the receiver (either peripheral or Master) so you can not just stream data.

I will look into the myRIO acting as a slave. However that would only serve my purpose of testing and wouldn't work in the actual scenario. Also thanks for that explanation of the I2C protocol. I admit I had very little knowledge of it before I started this thread.

paulvha:
If you are not using Serial1 (pin 12/13 on the OLA), that might be a consideration else BLE might be an option.

Yes, it indeed seems like this is my only option. I can use the RX and TX pin on my OLA. However, I found it interesting that I have to use the following declaration: ``` UART mySerial(12,13); ``` Using Serial1 doesn't seem to work.

paulvha:
If Serial1 is already used, the last potential option could be software serial. This is NOT part of the standard Sparkfun Apollo3/Artemis library, but I created a version last year. It has limitations and you can find it on https://github.com/paulvha/apollo3/tree … wareSerial

If I'm understanding this correctly, your software serial library just allows for serial communication on pins other than the RX and TX pins, right?

Also, just out of curiosity, why is the OLA not able to work as a peripheral over I2C? Is it a hardware limitation, or is it something that might be possible by making appropriate libraries?

Serial1 is already declared in the OLA, so no need to do extra. In the OLA menu, you can select Serial1 for output.

SoftwareSerial is functionally the same as a UART, but sending and receiving are under the control of the processor and not a separate module. it works with bit-banging and the load on the processor and timing has a high impact on the stability and maximum speed.

The Apollo3 chip has 6 IOM (master/central) modules and 1 IOS (slave /peripheral) module. The IOS is ‘a bit’ special and can only be assigned to pad 0,1,2. None of the others. There is only one board that could be used (the ATP). Pure out of interest I created an IOS library and got that to work but again… it does not help you on the OLA as the D0,D1 and D2 from the Apollo3 chip are not connected.

paulvha:
Serial1 is already declared in the OLA, so no need to do extra. In the OLA menu, you can select Serial1 for output.

Are you referring to the configuration menus in the default firmware? If yes, then it is not applicable in my case as I'm running my own firmware that is processing the IMU data and giving me the desired output. For some reason, Serial1 wasn't working in my case. So I had to use a UART object specifying the correct pin numbers instead, as shown in my previous post.

paulvha:
The Apollo3 chip has 6 IOM (master/central) modules and 1 IOS (slave /peripheral) module. The IOS is ‘a bit’ special and can only be assigned to pad 0,1,2. None of the others. There is only one board that could be used (the ATP). Pure out of interest I created an IOS library and got that to work but again… it does not help you on the OLA as the D0,D1 and D2 from the Apollo3 chip are not connected.

That is very interesting and extremely useful! I was able to find the pin mapping and their functions in the Apollo3 datasheet, but could not find any such detailed documentation regarding the OLA that talked about the points you mentioned. Could you please guide me towards any such documentation or any other resource where the above points have been discussed? This is purely for referencing and reporting reasons on my end.

Thank you for your help!

I was under the impression you use the OLA for it’s firmware, but if you use your own software, you could consider maybe an ATP. The Serial1 is defined for SERIAL1_TX = D24, SERIAL1_RX = D25.

If you want to know more about IOS see attached Zip

Ios.zip (167 KB)