RAK811 I2C using new compiler

I am moving some of the sample code I originally created over to the new compiler, using a WisNode RAK811 for convenience as it has pins I can access & a serial port.

I have the LED flashing (aka Hello World of embedded) working just fine.

I’ve hit a road block for I2C. I have a BME280 temp/humidity/pressure sensor that I have working on an Arduino and at present I would be happy to just read the chip id.

#define ADDR 0x76
#include <Wire.h>

void setup() {
Serial.println("\nI2C Tester");

void loop() {
byte result = 0;

result = Wire.endTransmission();
if (result == 0) {
Serial.println(“I2C device found”);
} else {
Serial.println(“Unknown error”);


result = Wire.endTransmission();
Serial.print("Write result = ");
Serial.println(result, HEX);

Wire.requestFrom(ADDR, 1);
while ( Wire.available() ) {
result = Wire.read();
Serial.print("Response = ");
Serial.println(result, HEX);


These are the I2C parts from the RUI RAK811 template from the v2 Git repository:

#define I2C_SCL 18
#define I2C_SDA 19
RUI_I2C_ST appI2C;

#define BME280_ADDR 0x76


if(rui_i2c_init(&appI2C) != RUI_STATUS_OK)
RUI_LOG_PRINTF(“I2C init error.\r\n”);

uint8_t t = 0;

// Chip ID as this is JUST a read
result = rui_i2c_rw(&appI2C, RUI_IF_READ, BME280_ADDR, 0xD0, &t, 1);
RUI_LOG_PRINTF(“BME280read = %d\r\n”, result);
RUI_LOG_PRINTF(“BME280_ChipId = %d\r\n”, t);

I have also tried this as a write before read to mirror the Arduino style:

result = rui_i2c_rw(&appI2C, RUI_IF_WRITE, BME280_ADDR, 0xD0, &t, 1);
RUI_LOG_PRINTF(“BME280write = %d\r\n”, result);
result = rui_i2c_rw(&appI2C, RUI_IF_READ, BME280_ADDR, 0xD0, &t, 1);
RUI_LOG_PRINTF(“BME280read = %d\r\n”, result);
RUI_LOG_PRINTF(“BME280_ChipId = %d\r\n”, t);

The intern who said they’d got this working can’t find the code now (and they are in isolation at university, so I can’t go and talk to them).

What I don’t know is if the RUI read sends the reg address.

Either way, both versions return error code 6.

A simple I2C sample that is NOT a whole library of Bosch commands would be much appreciated.

Is @ZhuQI the RUI expert?

Hi @nmcc, The devaddr parameter in the rui_i2c_rw() interface is an 8-bit address, and the read/write bit needs to be considered.

I’m not clear how to act on this information.

I’ve reviewed the RUI code for the RAK5205 & RAK7204 that have an I2C interface and I see the devaddr being used as the one published, and I’m using the published one on a module that has been tested using the Arduino code that I’ve shown above. In the forum post I2c, initialization @Nicholas says that the address is already shifted.

Is the Read/Write bit not handled by the RUI_IF_READ/WRITE?

I can “just” go and do this in STM so I’m not a beginner but as I’m trying to get setup as a reseller that supports the product, it would be useful if I could get to grips with RUI.

Mindful of time zones and that it is now 5pm or thereabouts over in the RAK main office, it would appear that I’ve lost Monday to work on this now. Can I ask that someone applies themselves to this thread by taking ten minutes to produce a working example so that I can get on with things Tuesday.

I need to ship a prototype, preferably based on RAK4200, later this week or this project will die like the WisNode one did and my wife, project manager, will be upset.

@Sucre, @Nicholas, @ZhuQI, @Fomi, @makahernandez, @velev, @nero, @Hobo

Hi @nmcc,Sorry to reply you so late. I have a DS3231 module in my hand. Below is the driver example of the module in RAK4200. The time register is read and written normally.

For some other reasons, using the rui_i2c_rw() interface on RAK811 requires the use of 8-bit addresses, namely DA3231_ADDR_WRITE and DS3231_ADDR_READ.

#define I2C_SCL 9
#define I2C_SDA 10
RUI_I2C_ST appI2C;


uint8_t data[16];
uint16_t data_len = 16;

#define DS3231_ADDR 0x68
#define DS3231_ADDR_WRITE (DS3231_ADDR<<1)
#define DS3231_ADDR_READ (DS3231_ADDR<<1 | 0x01)

void setup(void)

ret_code = rui_i2c_init(&appI2C);
if (ret_code != RUI_STATUS_OK)
    RUI_LOG_PRINTF("I2C init error.\r\n");

ret_code = rui_i2c_rw(&appI2C, RUI_IF_READ, DS3231_ADDR, 0x00, data, data_len);
if (ret_code != RUI_STATUS_OK)
    RUI_LOG_PRINTF("I2C read error.\r\n");
    RUI_LOG_PRINTF("I2C read success.\r\n");

memset(data, 0x00, 3);
ret_code = rui_i2c_rw(&appI2C, RUI_IF_WRITE, DS3231_ADDR, 0x00, data, 3);
if (ret_code != RUI_STATUS_OK)
    RUI_LOG_PRINTF("I2C write error.\r\n");
    RUI_LOG_PRINTF("I2C write success.\r\n");


void loop(void)
ret_code = rui_i2c_rw(&appI2C, RUI_IF_READ, DS3231_ADDR, 0x00, data, data_len);
if (ret_code != RUI_STATUS_OK)
RUI_LOG_PRINTF(“I2C read error.\r\n”);
RUI_LOG_PRINTF("%02X:%02X:%02X\r\n", data[2], data[1], data[0]);



OK, thanks, I’ll try this out this afternoon - I’ve a DS3231 in the bits box so I can try on both modules.

Perhaps useful to document the address shift required on RAK811!

Shifting the bits for the RAK811 works just fine - who do I send my timesheet to for this undocumented “feature” as the client’s not going to pay for that debugging?

So, according the the RUI theory, I can migrate the code straight across to the RAK4200. But unfortunately not.

To build a local smoke-test compile, I have my code in appMain.c with a corresponding appMain.h. This allows me, using a fake set of RUI functions, to do a local compile to make sure I haven’t introduced any seplling errors or dangling braces. This works fine for RAK811.

But errors on any line that uses RUI_LOG_PRINTF with undefined reference to UartPrint’` when I move it over to the RAK4200 template and compile with that.

It does work if I dump all of the code in to the app_RAK4200.c

I can live with it this in the short term, but it would appear that creating separate files for different sensors isn’t going to be able to use the RUI functions for RAK4200

Additionally, if I don’t define the level / high / low block in the appMain.c, I get an error and if I do include it, I get a duplication error.

Hopefully someone can unravel this so that RAK4200 works like RAK811 compilation?

Hi @nmcc, Thank you for your feedback, which promotes us to make our products better.

We also know that the documentation and examples in the RUI part need to be rich. So in the recent period, developers have been focusing on developing RUI API examples and updating the documentation corresponding to the examples. It is not just a description of a single API. In the example, several related APIs will be combined to complete one function. Including LoRaWAN related automatic Join and data transmission, LoRa P2P examples, peripheral driver examples (including I2C), etc.
We want customers to have reference codes for functional modules, not just API comments.

Given that I can code without using RUI and indeed, many of my PIC projects 15 years ago were, and consequently still are in assembly and that my first assembly was on the Z80 of a TRS-DOS II which is 40 years back now, I’m confident that I can debug semi-working code. So I’ll happily review / test the output as it becomes available rather than wait for some future date.

It’s details that we can not even begin to guess like pin numbers or shifted addresses etc that should be prioritised please.

And as for the RAK4200, I can live with dumping all the code in to one file for now and it doesn’t have enough IO for much more than I2C so this will keep me going.

My main development target is the RAK4260, but it’s good to keep the clients happy with the RUI on RAK4200.

The difference in device address parameters in the I2C interface brings an unfriendly experience, and this update will fix it.

The log interface in the two files app_RAK4200.c and app_RAK811.c is also RUI_LOG_PRINTF, and the local test is normal.

The test adds the following code to RAK811 and RAK4200, and there is no error in compiling.
#define low 0
#define high 1
#define level low

I saw the following code in app_7204.c in the RAK7204 directory. Do you include them in your code?Could this be the cause?

I can get that to work, but not in an external file for the RAK4200 - so I have appMain.c with logging for the RAK811 compiling and working on device, but not compiling for RAK4200 unless I move all the code in to app_RAK4200.c.

The current calls to RUI appear to require pointers to the values, not the values themselves, which is a whole bag of why. Due to the time it takes to create a test and then upload it and then have it try to compile, I do not have a definitive answer as to how this does or doesn’t work, but it does trip things up. I assume that the levels are defined somewhere else and if I put mine in the wrong place, they clash.

For RAK811, I have them in my appMain.c and that compiles just fine.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.