Week 11. Networking and Communications¶
Group Assignment
¶
This week, we connected my board and Zhirayr’s board using the I2C protocol. At first, we sent data and received it on Zhirayr’s board through the Serial Monitor. Then, we connected a motor, and by sending 0 or 1, we were able to turn it on and off. Here is the code I used on my board.
#include <Wire.h>
void setup() {
Wire.begin(); // Initialize I2C as master
Serial.begin(9600); // Initialize Serial Monitor
}
void loop() {
if (Serial.available()) {
String message = Serial.readStringUntil('\n');
Wire.beginTransmission(0x08);
Wire.write(message.c_str());
Wire.endTransmission();
Serial.println("Message sent: " + message);
}
delay(100);
}
Individual Assignmet¶
This week I made my second board for the submarine. I will have two boards — one with the ESP32-S3, which will be inside the submarine and connected by a wire to the bottom to provide a Wi-Fi signal, and the other with the ATtiny3216. They will be connected through I2C.
And yes, it will be double-sided again.
In KiCad, I designed it to include a DC-DC converter because the submarine will have a 12V battery.
Here is how the final board looks. But since I ordered a DC-DC converter and it hasn’t arrived yet, for now I will use 5V from USB-C to power it. When it arrives, I will also make a box with labels for it in the end.
After getting the two boards, I decided to first connect them and simply try to send some text.
Here is connection.
Board with Attiny3216 | Board with ESP32-S3 |
---|---|
GND | GND |
SCL (Pin 9) | SCL (Pin 4) |
SDA (Pin 8) | SDA (Pin 5) |
Then I uploaded a very simple code for the sender and receiver to test the connection.
Master’s Code:
#include <Wire.h>
void setup() {
Wire.begin();
}
void loop() {
Wire.beginTransmission(0x08);
Wire.write("Communication");
Wire.endTransmission();
delay(1000);
}
Reciver’s code:
#include <Wire.h>
void receiveEvent(int howMany) {
Serial.print("Received: ");
while (Wire.available()) {
char c = Wire.read();
Serial.print(c);
}
Serial.println();
}
void setup() {
Serial.begin(115200);
Wire.begin(0x08);
Wire.onReceive(receiveEvent);
}
void loop() {
delay(100);
}
Here is the result:
After establishing communication, I decided to use an input device to read data on one board and receive the data on the other board. I used a joystick module (KY-023), and here’s how I connected it.
Pin Name | ATtiny3216 Pin | ESP32-S3 Pin |
---|---|---|
VRY (Y-axis) | PA6(2) | - |
VRX (X-axis) | PA5(1) | - |
SDA (I2C) | PB0 | D4 |
SCL (I2C) | PB1 | D5 |
GND | GND | GND |
VCC | VCC | 3.3V |
Master’s Code:
#include <Wire.h>
#define VRX 2 // X-ось
#define VRY 1 // Y-ось
void setup() {
Wire.begin();
}
void loop() {
byte x = map(analogRead(VRX), 0, 1023, 0, 255);
byte y = map(analogRead(VRY), 0, 1023, 0, 255);
Wire.beginTransmission(0x08);
Wire.write(x);
Wire.write(y);
Wire.endTransmission();
delay(20);
}
Reciver’s Code:
#include <Wire.h>
byte x = 0, y = 0;
void receiveEvent(int howMany) {
if (Wire.available() >= 2) {
x = Wire.read();
y = Wire.read();
}
}
void setup() {
Wire.begin(0x08);
Wire.onReceive(receiveEvent);
Serial.begin(115200);
}
void loop() {
Serial.print("X: ");
Serial.print(x);
Serial.print(" Y: ");
Serial.println(y);
delay(20);
}
Result:
In the end, I connected a servo motor to the ESP32 board and controlled it using the joystick, which was connected to the ATtiny3216 board.
Master’s Code:
#include <Wire.h>
void setup() {
Wire.begin(); // SDA: PA2, SCL: PA3
}
void loop() {
int val = analogRead(2);
int pulse = map(val, 0, 1023, 500, 2500);
byte highByte = (pulse >> 8) & 0xFF;
byte lowByte = pulse & 0xFF;
Wire.beginTransmission(0x08);
Wire.write(highByte);
Wire.write(lowByte);
Wire.endTransmission();
delay(20);
}
Reciver’s Code:
#include <Wire.h>
#include <ESP32Servo.h>
#define I2C_ADDR 0x08
#define SERVO_PIN 2
Servo myServo;
int targetUS = 1500;
int currentUS = 1500;
void receiveEvent(int numBytes) {
if (numBytes >= 2) {
byte highByte = Wire.read();
byte lowByte = Wire.read();
targetUS = (highByte << 8) | lowByte;
targetUS = constrain(targetUS, 500, 2500);
}
}
void setup() {
Wire.begin(I2C_ADDR);
Wire.onReceive(receiveEvent);
myServo.setPeriodHertz(50);
myServo.attach(SERVO_PIN, 500, 2500);
myServo.writeMicroseconds(currentUS);
}
void loop() {
if (abs(currentUS - targetUS) > 5) {
currentUS += (targetUS - currentUS) * 0.2;
myServo.writeMicroseconds(currentUS);
}
delay(60);
}
Here is the final result.