Skip to content

Commit 0931f88

Browse files
committed
User Manual writing commit 16
1 parent 2a69cce commit 0931f88

File tree

3 files changed

+288
-1
lines changed

3 files changed

+288
-1
lines changed
26.7 MB
Loading
118 KB
Loading

content/hardware/05.pro-solutions/solutions-and-kits/edge-control/tutorials/user-manual/content.md

Lines changed: 288 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1097,4 +1097,291 @@ To test the example code, press the Edge Control Enclosure Kit button to set the
10971097

10981098
![RealTimeClock example output](assets/rtc-output.png)
10991099

1100-
## Communication
1100+
## Communication
1101+
The Edge Control communication peripherals are not accessible to the user as a normal development board because it isn't.
1102+
1103+
For example the `SPI` communication is reserved for the micro SD card and external memory ICs
1104+
1105+
### I2C
1106+
1107+
The pins used in the Edge Control for the I2C communication protocol are the ones on the MKR slots. Refer to the [board pinout section](#pinout) of the user manual to find them on the board.
1108+
1109+
The Edge Control supports I2C communication, which allows data transmission between the board and other I2C-compatible devices. Internal components like the LCD driver, the Real Time Clock and the I/O expanders use this protocol.
1110+
1111+
The NINA-B306 has two I2C ports, the I2C_1 is the one shared with the internal components and the MKR1 header, and the I2C_2 is exclusively connected to the MKR2 header.
1112+
1113+
To use I2C communication, include the `Wire` library at the top of your sketch. The `Wire` library provides functions for I2C communication:
1114+
1115+
```cpp
1116+
#include <Wire.h>
1117+
```
1118+
In the setup() function, initialize the I2C library:
1119+
1120+
```cpp
1121+
// Initialize the I2C communication
1122+
Wire.begin();
1123+
```
1124+
1125+
To transmit data to an I2C-compatible device, you can use the following commands:
1126+
1127+
```cpp
1128+
// Replace with the target device's I2C address
1129+
byte deviceAddress = 0x05;
1130+
1131+
// Replace with the appropriate instruction byte
1132+
byte instruction = 0x00;
1133+
1134+
// Replace with the value to send
1135+
byte value = 0xFF;
1136+
1137+
// Begin transmission to the target device
1138+
Wire.beginTransmission(deviceAddress);
1139+
1140+
// Send the instruction byte
1141+
Wire.write(instruction);
1142+
1143+
// Send the value
1144+
Wire.write(value);
1145+
1146+
// End transmission
1147+
Wire.endTransmission();
1148+
```
1149+
To read data from an I2C-compatible device, you can use the `requestFrom()` function to request data from the device and the `read()` function to read the received bytes:
1150+
1151+
```cpp
1152+
// The target device's I2C address
1153+
byte deviceAddress = 0x05;
1154+
1155+
// The number of bytes to read
1156+
int numBytes = 2;
1157+
1158+
// Request data from the target device
1159+
Wire.requestFrom(deviceAddress, numBytes);
1160+
1161+
// Read while there is data available
1162+
while (Wire.available()) {
1163+
byte data = Wire.read();
1164+
}
1165+
```
1166+
1167+
In the example code below, we are going to communicate the Edge Control with a MKR WiFi 1010. With a potentiometer connected to the Edge Control, the onboard LED of the MKR board will be controlled, so we will be sending the brightness value through I2C to it.
1168+
1169+
![Demo wiring - MKR WiFi 1010 on slot 1 of the Edge Control](assets/i2c-wiring.png)
1170+
1171+
#### Edge Control Code
1172+
1173+
```cpp
1174+
#include <Arduino_EdgeControl.h>
1175+
1176+
// The MKR1 board I2C address
1177+
#define EDGE_I2C_ADDR 0x05
1178+
1179+
constexpr unsigned int adcResolution{ 12 };
1180+
1181+
typedef struct
1182+
{
1183+
1184+
int LED = 0; //shared variable
1185+
1186+
} SensorValues_t;
1187+
1188+
SensorValues_t vals;
1189+
1190+
void setup() {
1191+
EdgeControl.begin();
1192+
Wire.begin();
1193+
delay(500);
1194+
Serial.begin(115200);
1195+
Serial.println("Init begin");
1196+
1197+
// Enable power lines
1198+
Power.on(PWR_3V3);
1199+
Power.on(PWR_VBAT);
1200+
Power.on(PWR_MKR1);
1201+
delay(5000);
1202+
1203+
// Init Edge Control IO Expander
1204+
Serial.print("IO Expander initializazion ");
1205+
if (!Expander.begin()) {
1206+
Serial.println("failed.");
1207+
Serial.println("Please, be sure to enable gated 3V3 and 5V power rails");
1208+
Serial.println("via Power.enable3V3() and Power.enable5V().");
1209+
} else Serial.println("succeeded.");
1210+
1211+
Input.begin();
1212+
Input.enable();
1213+
1214+
analogReadResolution(adcResolution);
1215+
}
1216+
1217+
void loop() {
1218+
1219+
vals.LED = Input.analogRead(INPUT_05V_CH01); // read the analog input
1220+
Serial.println(vals.LED);
1221+
sendValues(&vals); // send the brightness value to the MKR
1222+
delay(100);
1223+
1224+
}
1225+
1226+
1227+
/**
1228+
Function that sends the local sensors values through I2C to the MKR
1229+
@param values The I2C communicated sensors values
1230+
*/
1231+
void sendValues(SensorValues_t *values) {
1232+
writeBytes((uint8_t *)values, sizeof(SensorValues_t));
1233+
}
1234+
1235+
/**
1236+
Function that transport the sensors data through I2C to the MKR
1237+
@param buf store the structured sensors values
1238+
@param len store the buffer lenght
1239+
*/
1240+
void writeBytes(uint8_t *buf, uint8_t len) {
1241+
1242+
Wire.beginTransmission(EDGE_I2C_ADDR);
1243+
1244+
for (uint8_t i = 0; i < len; i++) {
1245+
Wire.write(buf[i]);
1246+
}
1247+
1248+
Wire.endTransmission();
1249+
}
1250+
```
1251+
1252+
#### MKR WiFi Code
1253+
1254+
```cpp
1255+
#include <Wire.h>
1256+
#include <WiFiNINA.h>
1257+
#include <utility/wifi_drv.h>
1258+
1259+
// The MKR1 board I2C address
1260+
#define SELF_I2C_ADDR 0x05
1261+
1262+
#define GREEN 26
1263+
1264+
// I2C communication flow control variables
1265+
int ctrlRec = 0;
1266+
int ctrlReq = 0;
1267+
1268+
typedef struct
1269+
{
1270+
1271+
int LED = 0; //zone 1 valve status
1272+
1273+
} SensorValues_t;
1274+
1275+
SensorValues_t vals;
1276+
1277+
void setup() {
1278+
Serial.begin(115200);
1279+
// put your setup code here, to run once:
1280+
// Init I2C coomunication
1281+
Wire.begin(SELF_I2C_ADDR);
1282+
Wire.onReceive(receiveEvent); // I2C receive callback
1283+
1284+
WiFiDrv::pinMode(GREEN, OUTPUT);
1285+
1286+
}
1287+
1288+
void loop() {
1289+
// put your main code here, to run repeatedly:
1290+
1291+
}
1292+
1293+
/**
1294+
Function that handles when the Edge Control sends data to the MKR.
1295+
@param bytes The I2C communicated sensors raw values
1296+
*/
1297+
void receiveEvent(int bytes) {
1298+
uint8_t buf[200];
1299+
uint8_t *ptr = &buf[0];
1300+
1301+
SensorValues_t *vals;
1302+
1303+
Serial.println("Receive event");
1304+
ctrlRec = 1;
1305+
while (Wire.available() > 0) {
1306+
*ptr = Wire.read();
1307+
ptr++;
1308+
}
1309+
1310+
vals = (SensorValues_t *)buf;
1311+
1312+
if (ctrlRec - ctrlReq) {
1313+
LEDControl(vals);
1314+
}
1315+
1316+
ctrlRec = 0;
1317+
ctrlReq = 0;
1318+
}
1319+
1320+
void LEDControl(SensorValues_t *vals) {
1321+
1322+
int brightness = map(vals->LED, 0, 3891, 0, 255);
1323+
Serial.println(brightness);
1324+
WiFiDrv::analogWrite(GREEN, brightness);
1325+
}
1326+
1327+
```
1328+
![I2C LED brightness control demo](assets/I2C_2.gif)
1329+
1330+
### UART
1331+
1332+
The pins used in the Edge Control for the UART communication protocol are the ones on the MKR slots. Refer to the [board pinout section](#pinout) of the user manual to find them on the board.
1333+
1334+
To begin with UART communication, you'll need to configure it first. In the `setup()` function, set the baud rate (bits per second) for UART communication:
1335+
1336+
```arduino
1337+
// Start UART communication at 115200 baud
1338+
Serial1.begin(115200);
1339+
```
1340+
1341+
To read incoming data, you can use a `while()` loop to continuously check for available data and read individual characters. The code shown above stores the incoming characters in a String variable and process the data when a line-ending character is received:
1342+
1343+
```arduino
1344+
// Variable for storing incoming data
1345+
String incoming = "";
1346+
void loop() {
1347+
// Check for available data and read individual characters
1348+
while (Serial1.available()) {
1349+
// Allow data buffering and read a single character
1350+
delay(2);
1351+
char c = Serial1.read();
1352+
1353+
// Check if the character is a newline (line-ending)
1354+
if (c == '\n') {
1355+
// Process the received data
1356+
processData(incoming);
1357+
// Clear the incoming data string for the next message
1358+
incoming = "";
1359+
} else {
1360+
// Add the character to the incoming data string
1361+
incoming += c;
1362+
}
1363+
}
1364+
}
1365+
```
1366+
1367+
To transmit data to another device via UART, you can use the `write()` function:
1368+
1369+
```arduino
1370+
// Transmit the string "Hello world!
1371+
Serial1.write("Hello world!");
1372+
```
1373+
1374+
You can also use the `print` and `println()` to send a string without a newline character or followed by a newline character:
1375+
1376+
```arduino
1377+
// Transmit the string "Hello world!"
1378+
Serial1.print("Hello world!");
1379+
// Transmit the string "Hello world!" followed by a newline character
1380+
Serial1.println("Hello world!");
1381+
```
1382+
1383+
To learn more about how to communicate the Edge Control through UART with other devices, we will use the example code below that can be found on **File > Examples > Arduino_EdgeControl > RPC > BlinkOverSerial**
1384+
1385+
1386+
1387+
### Bluetooth® Low Energy

0 commit comments

Comments
 (0)